fix: comprehensive tool argument normalization hardening
- Remove all { raw: ... } returns that caused InputValidationError with
z.strictObject schemas — return {} instead for clean Zod errors
- Extend normalizeAtStop buffering to all mapped tools (Read, Write,
Edit, Glob, Grep) so streaming paths also get normalized
- Make repairPossiblyTruncatedObjectJson generic — repair any valid
JSON object, not just ones with a command field
- Export hasToolFieldMapping for streaming normalizeAtStop decision
- Skip normalization on finish_reason: length to preserve raw truncated
buffer
- Update all test expectations to match new behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@ import { sanitizeSchemaForOpenAICompat } from '../../utils/schemaSanitizer.js'
|
||||
import { redactSecretValueForDisplay } from '../../utils/providerProfile.js'
|
||||
import {
|
||||
normalizeToolArguments,
|
||||
hasToolFieldMapping,
|
||||
} from './toolArgumentNormalization.js'
|
||||
|
||||
type SecretValueSource = Partial<{
|
||||
@@ -486,7 +487,7 @@ const JSON_REPAIR_SUFFIXES = [
|
||||
function repairPossiblyTruncatedObjectJson(raw: string): string | null {
|
||||
try {
|
||||
const parsed = JSON.parse(raw)
|
||||
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) && typeof (parsed as Record<string, unknown>).command === 'string'
|
||||
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
||||
? raw
|
||||
: null
|
||||
} catch {
|
||||
@@ -494,12 +495,7 @@ function repairPossiblyTruncatedObjectJson(raw: string): string | null {
|
||||
try {
|
||||
const repaired = raw + combo
|
||||
const parsed = JSON.parse(repaired)
|
||||
if (
|
||||
parsed &&
|
||||
typeof parsed === 'object' &&
|
||||
!Array.isArray(parsed) &&
|
||||
typeof (parsed as Record<string, unknown>).command === 'string'
|
||||
) {
|
||||
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
||||
return repaired
|
||||
}
|
||||
} catch {}
|
||||
@@ -619,7 +615,7 @@ async function* openaiStreamToAnthropic(
|
||||
|
||||
const toolBlockIndex = contentBlockIndex
|
||||
const initialArguments = tc.function.arguments ?? ''
|
||||
const normalizeAtStop = tc.function.name === 'Bash'
|
||||
const normalizeAtStop = hasToolFieldMapping(tc.function.name)
|
||||
activeToolCalls.set(tc.index, {
|
||||
id: tc.id,
|
||||
name: tc.function.name,
|
||||
|
||||
Reference in New Issue
Block a user