fix(hook): add tool_use/tool_result pair validator to prevent API errors
Adds a defensive tool-pair-validator hook that runs as the final step in the messages transform pipeline. When compaction or context-window recovery removes user messages containing tool_result blocks without removing the preceding assistant message with tool_use blocks, this validator detects the mismatch and either: 1. Injects missing tool_result parts into the next user message, or 2. Creates a synthetic user message with placeholder tool_results This prevents Anthropic API errors like 'tool_use ids found without tool_result blocks immediately after'. Fixes #3014
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
createClaudeCodeHooksHook,
|
||||
createKeywordDetectorHook,
|
||||
createThinkingBlockValidatorHook,
|
||||
createToolPairValidatorHook,
|
||||
} from "../../hooks"
|
||||
import {
|
||||
contextCollector,
|
||||
@@ -17,6 +18,7 @@ export type TransformHooks = {
|
||||
keywordDetector: ReturnType<typeof createKeywordDetectorHook> | null
|
||||
contextInjectorMessagesTransform: ReturnType<typeof createContextInjectorMessagesTransformHook>
|
||||
thinkingBlockValidator: ReturnType<typeof createThinkingBlockValidatorHook> | null
|
||||
toolPairValidator: ReturnType<typeof createToolPairValidatorHook> | null
|
||||
}
|
||||
|
||||
export function createTransformHooks(args: {
|
||||
@@ -63,10 +65,19 @@ export function createTransformHooks(args: {
|
||||
)
|
||||
: null
|
||||
|
||||
const toolPairValidator = isHookEnabled("tool-pair-validator")
|
||||
? safeCreateHook(
|
||||
"tool-pair-validator",
|
||||
() => createToolPairValidatorHook(),
|
||||
{ enabled: safeHookEnabled },
|
||||
)
|
||||
: null
|
||||
|
||||
return {
|
||||
claudeCodeHooks,
|
||||
keywordDetector,
|
||||
contextInjectorMessagesTransform,
|
||||
thinkingBlockValidator,
|
||||
toolPairValidator,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,5 +20,9 @@ export function createMessagesTransformHandler(args: {
|
||||
await args.hooks.thinkingBlockValidator?.[
|
||||
"experimental.chat.messages.transform"
|
||||
]?.(input, output)
|
||||
|
||||
await args.hooks.toolPairValidator?.[
|
||||
"experimental.chat.messages.transform"
|
||||
]?.(input, output)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user