2440ed9a6f
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
29 lines
807 B
TypeScript
29 lines
807 B
TypeScript
import type { Message, Part } from "@opencode-ai/sdk"
|
|
|
|
import type { CreatedHooks } from "../create-hooks"
|
|
|
|
type MessageWithParts = {
|
|
info: Message
|
|
parts: Part[]
|
|
}
|
|
|
|
type MessagesTransformOutput = { messages: MessageWithParts[] }
|
|
|
|
export function createMessagesTransformHandler(args: {
|
|
hooks: CreatedHooks
|
|
}): (input: Record<string, never>, output: MessagesTransformOutput) => Promise<void> {
|
|
return async (input, output): Promise<void> => {
|
|
await args.hooks.contextInjectorMessagesTransform?.[
|
|
"experimental.chat.messages.transform"
|
|
]?.(input, output)
|
|
|
|
await args.hooks.thinkingBlockValidator?.[
|
|
"experimental.chat.messages.transform"
|
|
]?.(input, output)
|
|
|
|
await args.hooks.toolPairValidator?.[
|
|
"experimental.chat.messages.transform"
|
|
]?.(input, output)
|
|
}
|
|
}
|