137c2459f7
Tool return values contained CTAs ("Use background_output to check") that
caused models to immediately poll instead of waiting for <system-reminder>
notifications. Unified all 5 tool return messages with explicit "Do NOT call
background_output now" guard, added pre-notification warning to BackgroundOutput
tool description, and strengthened Background Result Collection sections across
all 3 Sisyphus prompt variants (default, gpt-5-4, main) with BLOCKING
anti-pattern enforcement.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import type { BackgroundManager } from "../../features/background-agent"
|
|
import type { PluginInput } from "@opencode-ai/plugin"
|
|
import { resolveMessageContext } from "../../features/hook-message-injector"
|
|
import { getSessionAgent } from "../../features/claude-code-session-state"
|
|
import { log } from "../../shared"
|
|
import type { CallOmoAgentArgs } from "./types"
|
|
import type { ToolContextWithMetadata } from "./tool-context-with-metadata"
|
|
import { getMessageDir } from "./message-storage-directory"
|
|
import { getSessionTools } from "../../shared/session-tools-store"
|
|
|
|
export async function executeBackgroundAgent(
|
|
args: CallOmoAgentArgs,
|
|
toolContext: ToolContextWithMetadata,
|
|
manager: BackgroundManager,
|
|
client: PluginInput["client"],
|
|
): Promise<string> {
|
|
try {
|
|
const messageDir = getMessageDir(toolContext.sessionID)
|
|
const { prevMessage, firstMessageAgent } = await resolveMessageContext(
|
|
toolContext.sessionID,
|
|
client,
|
|
messageDir
|
|
)
|
|
|
|
const sessionAgent = getSessionAgent(toolContext.sessionID)
|
|
const parentAgent =
|
|
toolContext.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent
|
|
|
|
log("[call_omo_agent] parentAgent resolution", {
|
|
sessionID: toolContext.sessionID,
|
|
messageDir,
|
|
ctxAgent: toolContext.agent,
|
|
sessionAgent,
|
|
firstMessageAgent,
|
|
prevMessageAgent: prevMessage?.agent,
|
|
resolvedParentAgent: parentAgent,
|
|
})
|
|
|
|
const task = await manager.launch({
|
|
description: args.description,
|
|
prompt: args.prompt,
|
|
agent: args.subagent_type,
|
|
parentSessionID: toolContext.sessionID,
|
|
parentMessageID: toolContext.messageID,
|
|
parentAgent,
|
|
parentTools: getSessionTools(toolContext.sessionID),
|
|
})
|
|
|
|
const waitStart = Date.now()
|
|
const waitTimeoutMs = 30_000
|
|
const waitIntervalMs = 50
|
|
|
|
let sessionId = task.sessionID
|
|
while (!sessionId && Date.now() - waitStart < waitTimeoutMs) {
|
|
const updated = manager.getTask(task.id)
|
|
if (updated?.status === "error" || updated?.status === "cancelled" || updated?.status === "interrupt") {
|
|
return `Task failed to start (status: ${updated.status}).\n\nTask ID: ${task.id}`
|
|
}
|
|
sessionId = updated?.sessionID
|
|
if (sessionId) {
|
|
break
|
|
}
|
|
if (toolContext.abort?.aborted) {
|
|
break
|
|
}
|
|
await new Promise<void>((resolve) => {
|
|
setTimeout(resolve, waitIntervalMs)
|
|
})
|
|
}
|
|
|
|
await toolContext.metadata?.({
|
|
title: args.description,
|
|
metadata: { sessionId: sessionId ?? "pending" },
|
|
})
|
|
|
|
return `Background agent task launched successfully.
|
|
|
|
Task ID: ${task.id}
|
|
Session ID: ${sessionId ?? "pending"}
|
|
Description: ${task.description}
|
|
Agent: ${task.agent} (subagent)
|
|
Status: ${task.status}
|
|
|
|
System notifies on completion. Use \`background_output\` with task_id="${task.id}" to check.
|
|
|
|
Do NOT call background_output now. Wait for <system-reminder> notification first.`
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error)
|
|
return `Failed to launch background agent task: ${message}`
|
|
}
|
|
}
|