From 28569307ebbb04902b08eb7a228ac64244bd70a9 Mon Sep 17 00:00:00 2001 From: SpencerJung Date: Fri, 22 May 2026 16:36:12 +0900 Subject: [PATCH] fix(tool-pair-validator): continue after synthetic repairs Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/hooks/tool-pair-validator/hook.test.ts | 11 +++++++++++ src/hooks/tool-pair-validator/hook.ts | 18 ++++++++++++++++-- src/plugin/messages-transform.test.ts | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/hooks/tool-pair-validator/hook.test.ts b/src/hooks/tool-pair-validator/hook.test.ts index af97fa76a..dd2a1fc3b 100644 --- a/src/hooks/tool-pair-validator/hook.test.ts +++ b/src/hooks/tool-pair-validator/hook.test.ts @@ -9,6 +9,7 @@ import { createToolPairValidatorHook } from "./hook" import { _resetForTesting, subagentSessions } from "../../features/claude-code-session-state/state" const TOOL_RESULT_PLACEHOLDER = "Tool output unavailable (context compacted)" +const TOOL_RESULT_RECOVERY_CONTINUATION = "Recovered missing tool results. Continue from the repaired tool output." type TestPart = { type: string @@ -19,6 +20,7 @@ type TestPart = { isError?: boolean content?: string | Array<{ type: "text"; text: string }> text?: string + synthetic?: boolean } type TestMessage = { @@ -121,6 +123,11 @@ describe("createToolPairValidatorHook", () => { isError: true, content: [{ type: "text", text: TOOL_RESULT_PLACEHOLDER }], }, + { + type: "text", + text: TOOL_RESULT_RECOVERY_CONTINUATION, + synthetic: true, + }, ], }, ]) @@ -148,6 +155,10 @@ describe("createToolPairValidatorHook", () => { tool_use_id: "toolu_1", isError: true, content: [{ type: "text", text: TOOL_RESULT_PLACEHOLDER }], + }, { + type: "text", + text: TOOL_RESULT_RECOVERY_CONTINUATION, + synthetic: true, }], }, { info: { role: "assistant" }, parts: [{ type: "text", text: "follow-up" }] }, diff --git a/src/hooks/tool-pair-validator/hook.ts b/src/hooks/tool-pair-validator/hook.ts index 9a4107810..da63504e5 100644 --- a/src/hooks/tool-pair-validator/hook.ts +++ b/src/hooks/tool-pair-validator/hook.ts @@ -4,6 +4,7 @@ import { subagentSessions } from "../../features/claude-code-session-state" import { log } from "../../shared/logger" const TOOL_RESULT_PLACEHOLDER = "Tool output unavailable (context compacted)" +const TOOL_RESULT_RECOVERY_CONTINUATION = "Recovered missing tool results. Continue from the repaired tool output." type ToolUsePart = { type: "tool_use" @@ -20,7 +21,13 @@ type ToolResultPart = { [key: string]: unknown } -type TransformPart = Part | ToolUsePart | ToolResultPart +type TextPart = { + type: "text" + text: string + synthetic: true +} + +type TransformPart = Part | ToolUsePart | ToolResultPart | TextPart type TransformMessageInfo = Message | { role: "user" @@ -138,7 +145,14 @@ function createSyntheticUserMessage(assistantMessage: MessageWithParts, missingT role: "user", ...(sessionID ? { sessionID } : {}), }, - parts: missingToolUseIDs.map((toolUseID) => createToolResultPart(toolUseID)), + parts: [ + ...missingToolUseIDs.map((toolUseID) => createToolResultPart(toolUseID)), + { + type: "text", + text: TOOL_RESULT_RECOVERY_CONTINUATION, + synthetic: true, + }, + ], } } diff --git a/src/plugin/messages-transform.test.ts b/src/plugin/messages-transform.test.ts index 02f6951dd..57ca0eece 100644 --- a/src/plugin/messages-transform.test.ts +++ b/src/plugin/messages-transform.test.ts @@ -157,6 +157,10 @@ describe("createMessagesTransformHandler", () => { tool_use_id: "toolu_01SRMQs3DUtVKWoSxC8bxxVA", isError: true, content: [{ type: "text", text: "Tool output unavailable (context compacted)" }], + }, { + type: "text", + text: "Recovered missing tool results. Continue from the repaired tool output.", + synthetic: true, }], }) expect(messages[4]?.parts[0]).toEqual({