From 5aede5ade7df37c387c5acf17e9c3954b72112df Mon Sep 17 00:00:00 2001 From: Michael Yong Date: Mon, 10 Aug 2026 20:41:22 -0700 Subject: [PATCH] Ignore Codex raw response completion events --- .../agent-runtime/src/codex/adapter.test.ts | 23 +++++++++++++++++ .../agent-runtime/src/codex/visibility.ts | 10 +++++++- .../src/provider-visibility.test.ts | 25 +++++++++++++++++++ packages/host-daemon-contract/src/commands.ts | 2 +- .../test/contract.test.ts | 9 ++++--- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/packages/agent-runtime/src/codex/adapter.test.ts b/packages/agent-runtime/src/codex/adapter.test.ts index 795d2c42997..422a7de8ee0 100644 --- a/packages/agent-runtime/src/codex/adapter.test.ts +++ b/packages/agent-runtime/src/codex/adapter.test.ts @@ -2692,6 +2692,29 @@ describe("codex provider adapter", () => { expect(events).toEqual([]); }); + it("translateEvent ignores Codex raw response completions", () => { + const adapter = createCodexProviderAdapter(); + const events = adapter.translateEvent({ + jsonrpc: "2.0", + method: "rawResponse/completed", + params: { + threadId: "t1", + turnId: "turn-1", + responseId: "response-1", + usage: { + totalTokens: 19_206, + inputTokens: 18_971, + cachedInputTokens: 11_008, + cacheWriteInputTokens: 0, + outputTokens: 235, + reasoningOutputTokens: 53, + }, + }, + }); + + expect(events).toEqual([]); + }); + it("translateEvent item/mcpToolCall/progress maps to shared tool progress", () => { const adapter = createCodexProviderAdapter(); const events = adapter.translateEvent( diff --git a/packages/agent-runtime/src/codex/visibility.ts b/packages/agent-runtime/src/codex/visibility.ts index cb776668314..e3866111f14 100644 --- a/packages/agent-runtime/src/codex/visibility.ts +++ b/packages/agent-runtime/src/codex/visibility.ts @@ -12,7 +12,11 @@ import { } from "../shared/provider-visibility-helpers.js"; import type { ServerNotification } from "./generated/codex-app-server/schema/ServerNotification.js"; -type CodexServerNotificationMethod = ServerNotification["method"]; +type CodexServerNotificationMethod = + | ServerNotification["method"] + // Visibility can lead the independently refreshed generated schema when a + // newer installed Codex starts emitting a notification. + | "rawResponse/completed"; interface CodexNotificationRawEvent { kind: "notification"; @@ -80,6 +84,7 @@ const CODEX_SERVER_NOTIFICATION_METHODS = { "model/rerouted": true, "process/exited": true, "process/outputDelta": true, + "rawResponse/completed": true, "rawResponseItem/completed": true, "remoteControl/status/changed": true, "serverRequest/resolved": true, @@ -158,6 +163,9 @@ const CODEX_NOTIFICATION_COVERAGE = { // there is nothing to surface — left "unknown" intentionally. "process/exited": "unknown", "process/outputDelta": "unknown", + // Internal per-response accounting; thread/tokenUsage/updated carries the + // user-facing token state. + "rawResponse/completed": "noise", "rawResponseItem/completed": "noise", "remoteControl/status/changed": "noise", "serverRequest/resolved": "noise", diff --git a/packages/agent-runtime/src/provider-visibility.test.ts b/packages/agent-runtime/src/provider-visibility.test.ts index e868cecdc9c..8f1c8d32df7 100644 --- a/packages/agent-runtime/src/provider-visibility.test.ts +++ b/packages/agent-runtime/src/provider-visibility.test.ts @@ -169,4 +169,29 @@ describe("provider visibility raw events", () => { coverage: "noise", }); }); + + it("classifies Codex raw response completions as noise", () => { + expect( + codexVisibilityMetadata.describeRawEvent({ + jsonrpc: "2.0", + method: "rawResponse/completed", + params: { + threadId: "thread-1", + turnId: "turn-1", + responseId: "response-1", + usage: { + totalTokens: 19_206, + inputTokens: 18_971, + cachedInputTokens: 11_008, + cacheWriteInputTokens: 0, + outputTokens: 235, + reasoningOutputTokens: 53, + }, + }, + }), + ).toEqual({ + kind: "rawResponse/completed", + coverage: "noise", + }); + }); }); diff --git a/packages/host-daemon-contract/src/commands.ts b/packages/host-daemon-contract/src/commands.ts index 51eff4ac0d8..e8343f0053a 100644 --- a/packages/host-daemon-contract/src/commands.ts +++ b/packages/host-daemon-contract/src/commands.ts @@ -36,7 +36,7 @@ import { providerCliStatusResponseSchema, } from "./local.js"; -export const HOST_DAEMON_PROTOCOL_VERSION = 96 as const; +export const HOST_DAEMON_PROTOCOL_VERSION = 97 as const; export { BRANCH_LIST_LIMIT_MAX, diff --git a/packages/host-daemon-contract/test/contract.test.ts b/packages/host-daemon-contract/test/contract.test.ts index 59a463aa628..aea42087247 100644 --- a/packages/host-daemon-contract/test/contract.test.ts +++ b/packages/host-daemon-contract/test/contract.test.ts @@ -1051,10 +1051,11 @@ describe("host-daemon local schemas", () => { }); describe("host-daemon command schemas", () => { - // Version 96 adds provider-native skill discovery roots. An older daemon - // returns an incomplete skill catalog, so it must update before connecting. - it("uses protocol version 96 for provider-native skill discovery", () => { - expect(HOST_DAEMON_PROTOCOL_VERSION).toBe(96); + // Version 97 suppresses Codex raw response completion notifications. An + // older daemon emits them as provider/unhandled, so it must update before + // connecting. + it("uses protocol version 97 for Codex raw response completion noise", () => { + expect(HOST_DAEMON_PROTOCOL_VERSION).toBe(97); }); it("binds Plan cancellation to a required turn id and typed result", () => {