diff --git a/packages/server/src/server/agent/providers/omp/agent.test.ts b/packages/server/src/server/agent/providers/omp/agent.test.ts index 35020ca45..f0adadee7 100644 --- a/packages/server/src/server/agent/providers/omp/agent.test.ts +++ b/packages/server/src/server/agent/providers/omp/agent.test.ts @@ -277,6 +277,35 @@ describe("OMP agent client and session", () => { ]); }); + test("renders a live system-notice custom message as a synthetic tool call", async () => { + const omp = new OmpHarness(); + await omp.start(); + + await omp.runPrompt("hello OMP", "done"); + omp + .runtime() + .acceptCustomMessage( + [ + "", + "Background job DocsSmokeTwo has completed.", + '', + "done", + "", + "", + ].join("\n"), + ); + omp.runtime().acceptCustomMessage("plain custom status text"); + + expect(omp.timeline().filter((item) => item.type === "tool_call")).toMatchObject([ + { callId: "omp-notice:DocsSmokeTwo", name: "task_notification", status: "completed" }, + ]); + // Non-notice custom messages still fall through as assistant messages. + expect(omp.timeline().filter((item) => item.type === "assistant_message")).toMatchObject([ + { text: "done" }, + { text: "plain custom status text" }, + ]); + }); + test("does not complete a queued model turn from OMP's local-only hint", async () => { const omp = new OmpHarness(); await omp.start(); diff --git a/packages/server/src/server/agent/providers/omp/agent.ts b/packages/server/src/server/agent/providers/omp/agent.ts index c0654a627..8337c250a 100644 --- a/packages/server/src/server/agent/providers/omp/agent.ts +++ b/packages/server/src/server/agent/providers/omp/agent.ts @@ -68,6 +68,7 @@ export { formatOmpVersionSupport, resolveOmpDiagnosticPaths } from "./provider-c import { OmpSubagentCardTracker, type OmpSubagentCardScheduler } from "./subagent-card-tracker.js"; import { shouldDisplayOmpCustomMessage } from "./custom-message.js"; import { getUserMessageText } from "./message-history.js"; +import { mapOmpSystemNoticeToToolCall } from "./system-notice.js"; import { materializeProviderImage } from "../provider-image-output.js"; import { OmpCliRuntime } from "./cli-runtime.js"; import { listOmpImportableSessions, readOmpImportSessionConfig } from "./session-descriptor.js"; @@ -2068,12 +2069,14 @@ export class OmpAgentSession implements AgentSession { if (shouldDisplayOmpCustomMessage(event.message)) { const text = getUserMessageText(event.message.content); if (text) { - const advisorItem = mapOmpAdvisorMessageToToolCall(event.message, text); + const item = + mapOmpAdvisorMessageToToolCall(event.message, text) ?? + mapOmpSystemNoticeToToolCall(text); this.emit({ type: "timeline", provider: this.provider, turnId, - item: advisorItem ?? { type: "assistant_message", text }, + item: item ?? { type: "assistant_message", text }, }); } }