fix(call-omo-agent): gate reused sync prompts
This commit is contained in:
@@ -79,11 +79,15 @@ function createToolContext(): ToolContext {
|
||||
}
|
||||
}
|
||||
|
||||
function createContext(promptAsync: ReturnType<typeof mock>) {
|
||||
function createContext(
|
||||
promptAsync: ReturnType<typeof mock>,
|
||||
status?: () => Promise<unknown>,
|
||||
) {
|
||||
return {
|
||||
client: {
|
||||
session: {
|
||||
promptAsync,
|
||||
...(status ? { status } : {}),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -350,6 +354,41 @@ describe("executeSync", () => {
|
||||
expect(deps.processMessages).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("does not send a duplicate sync prompt when a reused session is active", async () => {
|
||||
//#given
|
||||
const executeSync = await importExecuteSync()
|
||||
const deps = createDependencies({
|
||||
createOrGetSession: mock(async () => ({ sessionID: "ses-active-reuse", isNew: false })),
|
||||
})
|
||||
const toolContext = createToolContext()
|
||||
const recorder = createPromptAsyncRecorder()
|
||||
const args = {
|
||||
subagent_type: "explore",
|
||||
description: "active reuse",
|
||||
prompt: "find something",
|
||||
run_in_background: false,
|
||||
session_id: "ses-active-reuse",
|
||||
}
|
||||
|
||||
//#when
|
||||
const result = await executeSync(
|
||||
args,
|
||||
toolContext,
|
||||
createContext(
|
||||
recorder.promptAsync,
|
||||
async () => ({ data: { "ses-active-reuse": { type: "busy" } } }),
|
||||
) as never,
|
||||
deps,
|
||||
)
|
||||
|
||||
//#then
|
||||
expect(recorder.promptAsync).toHaveBeenCalledTimes(0)
|
||||
expect(result).toContain("Error: Failed to send prompt")
|
||||
expect(result).toContain("session_id: ses-active-reuse")
|
||||
expect(deps.waitForCompletion).not.toHaveBeenCalled()
|
||||
expect(deps.processMessages).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("commits reserved descendant quota after creating a new sync session", async () => {
|
||||
//#given
|
||||
const { executeSync } = require("./sync-executor")
|
||||
|
||||
@@ -6,6 +6,7 @@ import { applySessionPromptParams } from "../../shared/session-prompt-params-hel
|
||||
import type { DelegatedModelConfig } from "../../shared/model-resolution-types"
|
||||
import type { FallbackEntry } from "../../shared/model-requirements"
|
||||
import { stripAgentListSortPrefix } from "../../shared/agent-display-names"
|
||||
import { promptAsyncAfterSessionIdle } from "../../hooks/shared/prompt-async-gate"
|
||||
import { waitForCompletion } from "./completion-poller"
|
||||
import { processMessages } from "./message-processor"
|
||||
import { createOrGetSession } from "./session-creator"
|
||||
@@ -110,21 +111,34 @@ export async function executeSync(
|
||||
return `Error: Failed to send prompt: promptAsync is not available on this OpenCode client.\n\n<task_metadata>\nsession_id: ${sessionID}\n</task_metadata>`
|
||||
}
|
||||
|
||||
await ctx.client.session.promptAsync({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
agent: normalizedSubagentType,
|
||||
tools: {
|
||||
...getAgentToolRestrictions(normalizedSubagentType),
|
||||
task: false,
|
||||
question: false,
|
||||
const promptResult = await promptAsyncAfterSessionIdle({
|
||||
client: ctx.client,
|
||||
sessionID,
|
||||
source: "call-omo-agent:sync",
|
||||
settleMs: 0,
|
||||
postDispatchHoldMs: 0,
|
||||
input: {
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
agent: normalizedSubagentType,
|
||||
tools: {
|
||||
...getAgentToolRestrictions(normalizedSubagentType),
|
||||
task: false,
|
||||
question: false,
|
||||
},
|
||||
parts: [{ type: "text", text: args.prompt }],
|
||||
...(model ? { model: { providerID: model.providerID, modelID: model.modelID } } : {}),
|
||||
...(model?.variant ? { variant: model.variant } : {}),
|
||||
...buildPromptGenerationParams(model),
|
||||
},
|
||||
parts: [{ type: "text", text: args.prompt }],
|
||||
...(model ? { model: { providerID: model.providerID, modelID: model.modelID } } : {}),
|
||||
...(model?.variant ? { variant: model.variant } : {}),
|
||||
...buildPromptGenerationParams(model),
|
||||
},
|
||||
})
|
||||
if (promptResult.status === "failed") {
|
||||
throw promptResult.error
|
||||
}
|
||||
if (promptResult.status !== "dispatched") {
|
||||
throw new Error(`promptAsync skipped by gate: ${promptResult.status}`)
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
log(`[call_omo_agent] Prompt error:`, errorMessage)
|
||||
|
||||
Reference in New Issue
Block a user