fix(prompt): treat post-dispatch failures as accepted

This commit is contained in:
YeonGyu-Kim
2026-05-20 11:42:32 +09:00
parent f540249838
commit d3e218f912
31 changed files with 503 additions and 76 deletions
@@ -479,6 +479,39 @@ describe("executeSync", () => {
expect(deps.processMessages).not.toHaveBeenCalled()
})
test("#given sync prompt returns ambiguous EOF after dispatch #when executeSync runs #then it waits for the existing session result", async () => {
//#given
const executeSync = await importExecuteSync()
const deps = createDependencies({
createOrGetSession: mock(async () => ({ sessionID: "ses-ambiguous-prompt", isNew: true })),
waitForCompletion: mock(async () => {}),
processMessages: mock(async () => "accepted response"),
})
const toolContext = createToolContext()
const recorder = createPromptAsyncRecorder(async () => {
throw new Error("JSON Parse error: Unexpected EOF")
})
const args = {
subagent_type: "librarian",
description: "ambiguous prompt",
prompt: "find docs",
run_in_background: false,
}
//#when
const result = await executeSync(args, toolContext, createContext(recorder.promptAsync) as never, deps)
//#then
expect(result).toContain("accepted response")
expect(result).toContain("session_id: ses-ambiguous-prompt")
expect(deps.waitForCompletion).toHaveBeenCalledWith(
"ses-ambiguous-prompt",
toolContext,
expect.objectContaining({ client: expect.anything() }),
)
expect(deps.processMessages).toHaveBeenCalledTimes(1)
})
test("does not send a duplicate sync prompt when a reused session is active", async () => {
//#given
const executeSync = await importExecuteSync()
+12 -3
View File
@@ -1,7 +1,7 @@
import type { PluginInput } from "@opencode-ai/plugin"
import { clearSessionAgent, setSessionAgent, subagentSessions, syncSubagentSessions } from "../../features/claude-code-session-state"
import { dispatchInternalPrompt, isInternalPromptDispatchAccepted } from "../../hooks/shared/prompt-async-gate"
import { getAgentToolRestrictions, log } from "../../shared"
import { getAgentToolRestrictions, isAmbiguousPostDispatchPromptFailure, log } from "../../shared"
import { getAgentDisplayName, stripAgentListSortPrefix } from "../../shared/agent-display-names"
import {
clearDelegatedChildSessionBootstrap,
@@ -153,10 +153,19 @@ export async function executeSync(
},
},
})
const promptMayHaveBeenAccepted = promptResult.status === "failed"
&& isAmbiguousPostDispatchPromptFailure(promptResult)
if (promptResult.status === "failed") {
throw promptResult.error
if (promptMayHaveBeenAccepted) {
log("[call_omo_agent] Prompt returned an ambiguous error after dispatch; waiting for completion", {
sessionID,
error: promptResult.error instanceof Error ? promptResult.error.message : String(promptResult.error),
})
} else {
throw promptResult.error
}
}
if (!isInternalPromptDispatchAccepted(promptResult)) {
if (!promptMayHaveBeenAccepted && !isInternalPromptDispatchAccepted(promptResult)) {
throw new Error(`prompt skipped by gate: ${promptResult.status}`)
}
} catch (error) {