Prevent subagent repair from corrupting background sessions

Guard the tool-pair validator when transformed assistant messages belong to a tracked subagent session, while keeping normal main-session orphaned tool_use repair intact.

Constraint: code-yeongyu/oh-my-openagent#3996 reports background Oracle sessions hanging after synthetic placeholder tool_result insertion.
Rejected: disable tool-pair-validator globally | would regress main-session compaction/orphaned tool_use repair.
Confidence: high
Scope-risk: narrow
Directive: Keep subagent skip coverage and normal repair coverage together when changing tool-pair validation.
Tested: bun test src/hooks/tool-pair-validator/hook.test.ts src/plugin/messages-transform.test.ts
Tested: bun run typecheck
Not-tested: live Oracle background task e2e; no remote push or PR comment performed.
This commit is contained in:
PeterPonyu
2026-05-14 21:32:48 -04:00
parent c6c7a103dd
commit 17030b9a0d
2 changed files with 59 additions and 2 deletions
+44 -1
View File
@@ -6,6 +6,7 @@ declare const expect: <T>(value: T) => {
}
import { createToolPairValidatorHook } from "./hook"
import { _resetForTesting, subagentSessions } from "../../features/claude-code-session-state/state"
const TOOL_RESULT_PLACEHOLDER = "Tool output unavailable (context compacted)"
@@ -19,7 +20,7 @@ type TestPart = {
}
type TestMessage = {
info: { role: "assistant" | "user" }
info: { role: "assistant" | "user"; sessionID?: string }
parts: TestPart[]
}
@@ -153,4 +154,46 @@ describe("createToolPairValidatorHook", () => {
{ type: "text", text: "continue" },
])
})
it("leaves tracked subagent sessions unchanged while normal sessions still repair", async () => {
//#given
_resetForTesting()
subagentSessions.add("ses_background_1")
const backgroundMessages = [
{
info: { role: "assistant", sessionID: "ses_background_1" },
parts: [{ type: "tool_use", id: "toolu_background_1" }],
},
{
info: { role: "assistant", sessionID: "ses_background_1" },
parts: [{ type: "text", text: "background agent keeps reasoning" }],
},
] satisfies TestMessage[]
const originalBackgroundMessages = JSON.parse(JSON.stringify(backgroundMessages))
const mainMessages = [
{
info: { role: "assistant", sessionID: "ses_main_1" },
parts: [{ type: "tool_use", id: "toolu_main_1" }],
},
{
info: { role: "user", sessionID: "ses_main_1" },
parts: [{ type: "text", text: "continue main session" }],
},
] satisfies TestMessage[]
try {
//#when
await runTransform(backgroundMessages)
await runTransform(mainMessages)
//#then
expect(backgroundMessages).toEqual(originalBackgroundMessages)
expect(mainMessages[1]?.parts).toEqual([
{ type: "tool_result", tool_use_id: "toolu_main_1", content: TOOL_RESULT_PLACEHOLDER },
{ type: "text", text: "continue main session" },
])
} finally {
_resetForTesting()
}
})
})