Render live omp system-notices as synthetic tool calls (#2218)

Route live OMP custom messages through the existing system-notice mapper so background notices render as task notifications while advisor, hidden, and ordinary custom-message behavior stays intact.
This commit is contained in:
Ethan Greenfeld
2026-07-24 02:02:52 -07:00
committed by GitHub
parent 4b5551d61c
commit 08c522c986
2 changed files with 34 additions and 2 deletions

View File

@@ -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(
[
"<system-notice>",
"Background job DocsSmokeTwo has completed.",
'<task-result id="DocsSmokeTwo" agent="explore" status="completed" duration="21.6s">',
"<output>done</output>",
"</task-result>",
"</system-notice>",
].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();

View File

@@ -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 },
});
}
}