fix(tool-pair-validator): continue after synthetic repairs

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
SpencerJung
2026-05-22 16:36:12 +09:00
parent cb205e1479
commit 28569307eb
3 changed files with 31 additions and 2 deletions
@@ -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" }] },
+16 -2
View File
@@ -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,
},
],
}
}
+4
View File
@@ -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({