From 24416f78fb6bac30da59c5f0c919c2a123003805 Mon Sep 17 00:00:00 2001 From: "posthog[bot]" <206114724+posthog[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 20:12:34 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Fix=20"undefined=20=C2=B7=20~NaNK=20tokens"?= =?UTF-8?q?=20in=20codex=20compaction=20boundary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The codex-app-server adapter (gpt-5.6-sol and other codex models) emitted the `_posthog/compact_boundary` notification with only `sessionId`, unlike the Claude adapter which includes `trigger`, `preTokens`, and `contextSize`. CompactBoundaryView then rendered `${trigger}` as "undefined" and `Math.round(undefined / 1000)` as NaN, producing "Conversation compacted · undefined · ~NaNK tokens". - UsageTracker now retains the model context window (a constant, so it survives resetForTurn) and exposes contextSize(). - The codex boundary now sends trigger: "auto" (codex only auto-compacts), preTokens from the live context occupancy, and contextSize. - CompactBoundaryView and its type chain treat trigger/preTokens as optional and omit each segment when absent, so a missing value can never render as undefined/NaN again. Generated-By: PostHog Code Task-Id: d044b358-be1b-4665-8d32-c28a9ce1badb --- .../codex-app-server-agent.test.ts | 19 +++++++++++++++++-- .../codex-app-server-agent.ts | 4 ++++ .../codex-app-server/usage-tracker.ts | 8 ++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts index def493b9e8..cddd4e5b38 100644 --- a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts +++ b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts @@ -2818,6 +2818,15 @@ describe("CodexAppServerAgent", () => { _meta: {}, } as unknown as NewSessionRequest); + // A token-usage update precedes auto-compaction (the window fills mid-turn); + // its counts feed the boundary's preTokens/contextSize so the UI isn't NaN. + stub.emit("thread/tokenUsage/updated", { + tokenUsage: { + last: { inputTokens: 180000, outputTokens: 5000, totalTokens: 185000 }, + modelContextWindow: 200000, + }, + }); + // The compaction item brackets it: started → in progress, completed → boundary. stub.emit("item/started", { item: { type: "contextCompaction", id: "c1" }, @@ -2826,11 +2835,17 @@ describe("CodexAppServerAgent", () => { item: { type: "contextCompaction", id: "c1", summary: "…" }, }); - // compact_boundary clears isCompacting + drains the host queue. + // compact_boundary clears isCompacting + drains the host queue, and carries the + // trigger/token fields the CompactBoundaryView needs. expect( extNotifications.find((n) => n.method === "_posthog/compact_boundary") ?.params, - ).toMatchObject({ sessionId: "t" }); + ).toMatchObject({ + sessionId: "t", + trigger: "auto", + preTokens: 185000, + contextSize: 200000, + }); // ...and a user-visible marker lands in the transcript. expect(sessionUpdates).toContainEqual({ sessionId: "t", diff --git a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts index 74a7c15390..fb8595edc9 100644 --- a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts +++ b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts @@ -1747,6 +1747,10 @@ export class CodexAppServerAgent extends BaseAcpAgent { void this.client .extNotification(POSTHOG_NOTIFICATIONS.COMPACT_BOUNDARY, { sessionId: this.sessionId, + // codex only auto-compacts; there's no manual /compact. + trigger: "auto", + preTokens: this.usage.contextTokens() ?? 0, + contextSize: this.usage.contextSize(), }) .catch(() => undefined); void this.client diff --git a/packages/agent/src/adapters/codex-app-server/usage-tracker.ts b/packages/agent/src/adapters/codex-app-server/usage-tracker.ts index fd107a7c13..42c8ef7927 100644 --- a/packages/agent/src/adapters/codex-app-server/usage-tracker.ts +++ b/packages/agent/src/adapters/codex-app-server/usage-tracker.ts @@ -27,6 +27,8 @@ export class UsageTracker { private baseline: ContextBreakdownBaseline = emptyBaseline(); private lastTurn?: Usage; private contextUsed?: number; + // Model context window is a constant, so it survives resetForTurn. + private contextWindow?: number; setBaseline(baseline: ContextBreakdownBaseline): void { this.baseline = baseline; @@ -48,6 +50,7 @@ export class UsageTracker { const { context, used, size } = reading; // Drives the per-source breakdown's "conversation" bucket on turn complete. this.contextUsed = used; + if (size != null) this.contextWindow = size; const inputTokens = context.inputTokens ?? 0; const outputTokens = context.outputTokens ?? 0; const cachedReadTokens = context.cachedInputTokens ?? 0; @@ -81,4 +84,9 @@ export class UsageTracker { contextTokens(): number | undefined { return this.contextUsed; } + + /** Model context window last reported by codex, or undefined pre-usage. */ + contextSize(): number | undefined { + return this.contextWindow; + } } From 022242037a4bcb6b6dc1d9c512b22b43f2cd9da4 Mon Sep 17 00:00:00 2001 From: "posthog[bot]" <206114724+posthog[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 20:12:35 +0000 Subject: [PATCH 2/2] simplify compact boundary rendering and drop preTokens sentinel Omit preTokens instead of sending 0 when no usage reading exists, reuse formatTokensCompact, and derive one shared detail string for both render branches. Generated-By: PostHog Code Task-Id: 71484330-f52a-49bb-a528-5c708028bbf9 --- .../codex-app-server/codex-app-server-agent.test.ts | 6 ++---- .../src/adapters/codex-app-server/codex-app-server-agent.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts index cddd4e5b38..f93318b721 100644 --- a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts +++ b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.test.ts @@ -2818,8 +2818,7 @@ describe("CodexAppServerAgent", () => { _meta: {}, } as unknown as NewSessionRequest); - // A token-usage update precedes auto-compaction (the window fills mid-turn); - // its counts feed the boundary's preTokens/contextSize so the UI isn't NaN. + // The last usage reading before compaction feeds the boundary's preTokens/contextSize. stub.emit("thread/tokenUsage/updated", { tokenUsage: { last: { inputTokens: 180000, outputTokens: 5000, totalTokens: 185000 }, @@ -2835,8 +2834,7 @@ describe("CodexAppServerAgent", () => { item: { type: "contextCompaction", id: "c1", summary: "…" }, }); - // compact_boundary clears isCompacting + drains the host queue, and carries the - // trigger/token fields the CompactBoundaryView needs. + // compact_boundary clears isCompacting + drains the host queue. expect( extNotifications.find((n) => n.method === "_posthog/compact_boundary") ?.params, diff --git a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts index fb8595edc9..6f4b21e311 100644 --- a/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts +++ b/packages/agent/src/adapters/codex-app-server/codex-app-server-agent.ts @@ -1749,7 +1749,7 @@ export class CodexAppServerAgent extends BaseAcpAgent { sessionId: this.sessionId, // codex only auto-compacts; there's no manual /compact. trigger: "auto", - preTokens: this.usage.contextTokens() ?? 0, + preTokens: this.usage.contextTokens(), contextSize: this.usage.contextSize(), }) .catch(() => undefined);