fix(prompt-gate): harden sync and team prompt dispatch
This commit is contained in:
@@ -33,6 +33,7 @@ function createContext(promptAsync: ReturnType<typeof mock>) {
|
||||
return {
|
||||
client: {
|
||||
session: {
|
||||
prompt: promptAsync,
|
||||
promptAsync,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -87,6 +87,7 @@ function createContext(
|
||||
return {
|
||||
client: {
|
||||
session: {
|
||||
prompt: promptAsync,
|
||||
promptAsync,
|
||||
...(status ? { status } : {}),
|
||||
},
|
||||
@@ -142,7 +143,7 @@ describe("executeSync", () => {
|
||||
expect(promptInput?.body.agent).toBe("Sisyphus - Ultraworker")
|
||||
})
|
||||
|
||||
test("#given subagent_type is the lowercase config key 'hephaestus' #when executeSync runs #then promptAsync receives the registered display name 'Hephaestus - Deep Agent'", async () => {
|
||||
test("#given subagent_type is the lowercase config key 'hephaestus' #when executeSync runs #then prompt receives the registered display name 'Hephaestus - Deep Agent'", async () => {
|
||||
//#given
|
||||
const executeSync = await importExecuteSync()
|
||||
const deps = createDependencies()
|
||||
@@ -163,7 +164,7 @@ describe("executeSync", () => {
|
||||
expect(promptInput?.body.agent).toBe("Hephaestus - Deep Agent")
|
||||
})
|
||||
|
||||
test("#given subagent_type is the lowercase config key 'sisyphus-junior' #when executeSync runs #then promptAsync receives the registered display name 'Sisyphus-Junior'", async () => {
|
||||
test("#given subagent_type is the lowercase config key 'sisyphus-junior' #when executeSync runs #then prompt receives the registered display name 'Sisyphus-Junior'", async () => {
|
||||
//#given
|
||||
const executeSync = await importExecuteSync()
|
||||
const deps = createDependencies()
|
||||
@@ -184,7 +185,7 @@ describe("executeSync", () => {
|
||||
expect(promptInput?.body.agent).toBe("Sisyphus-Junior")
|
||||
})
|
||||
|
||||
test("#given subagent_type is already a display name like 'explore' (config key == display name) #when executeSync runs #then promptAsync receives 'explore' unchanged", async () => {
|
||||
test("#given subagent_type is already a display name like 'explore' (config key == display name) #when executeSync runs #then prompt receives 'explore' unchanged", async () => {
|
||||
//#given a same-keyed agent must not be double-translated
|
||||
const executeSync = await importExecuteSync()
|
||||
const deps = createDependencies()
|
||||
@@ -536,7 +537,7 @@ describe("executeSync", () => {
|
||||
|
||||
//#then
|
||||
expect(first).toContain("agent response")
|
||||
expect(second).toContain("promptAsync skipped by gate: reserved")
|
||||
expect(second).toContain("prompt skipped by gate: reserved")
|
||||
expect(recorder.promptAsync).toHaveBeenCalledTimes(1)
|
||||
expect(deps.waitForCompletion).toHaveBeenCalledTimes(1)
|
||||
expect(deps.processMessages).toHaveBeenCalledTimes(1)
|
||||
@@ -576,6 +577,7 @@ describe("executeSync", () => {
|
||||
const ctx = {
|
||||
client: {
|
||||
session: {
|
||||
prompt: mock(async () => ({ data: {} })),
|
||||
promptAsync: mock(async () => ({ data: {} })),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -16,12 +16,12 @@ import { processMessages } from "./message-processor"
|
||||
import { createOrGetSession } from "./session-creator"
|
||||
import type { CallOmoAgentArgs } from "./types"
|
||||
|
||||
type SessionWithPromptAsync = {
|
||||
promptAsync: (opts: { path: { id: string }; body: Record<string, unknown> }) => Promise<unknown>
|
||||
type SessionWithPrompt = {
|
||||
prompt: (opts: { path: { id: string }; body: Record<string, unknown> }) => Promise<unknown>
|
||||
}
|
||||
|
||||
function hasPromptAsync(session: PluginInput["client"]["session"]): session is PluginInput["client"]["session"] & SessionWithPromptAsync {
|
||||
return "promptAsync" in session && typeof session.promptAsync === "function"
|
||||
function hasPrompt(session: PluginInput["client"]["session"]): session is PluginInput["client"]["session"] & SessionWithPrompt {
|
||||
return "prompt" in session && typeof session.prompt === "function"
|
||||
}
|
||||
|
||||
type ExecuteSyncDeps = {
|
||||
@@ -130,12 +130,12 @@ export async function executeSync(
|
||||
})
|
||||
|
||||
try {
|
||||
if (!hasPromptAsync(ctx.client.session)) {
|
||||
return `Error: Failed to send prompt: promptAsync is not available on this OpenCode client.\n\n<task_metadata>\nsession_id: ${sessionID}\n</task_metadata>`
|
||||
if (!hasPrompt(ctx.client.session)) {
|
||||
return `Error: Failed to send prompt: prompt is not available on this OpenCode client.\n\n<task_metadata>\nsession_id: ${sessionID}\n</task_metadata>`
|
||||
}
|
||||
|
||||
const promptResult = await dispatchInternalPrompt({
|
||||
mode: "async",
|
||||
mode: "sync",
|
||||
client: ctx.client,
|
||||
sessionID,
|
||||
source: "call-omo-agent:sync",
|
||||
@@ -157,7 +157,7 @@ export async function executeSync(
|
||||
throw promptResult.error
|
||||
}
|
||||
if (!isInternalPromptDispatchAccepted(promptResult)) {
|
||||
throw new Error(`promptAsync skipped by gate: ${promptResult.status}`)
|
||||
throw new Error(`prompt skipped by gate: ${promptResult.status}`)
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
|
||||
Reference in New Issue
Block a user