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..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,6 +2818,14 @@ describe("CodexAppServerAgent", () => { _meta: {}, } as unknown as NewSessionRequest); + // 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 }, + modelContextWindow: 200000, + }, + }); + // The compaction item brackets it: started → in progress, completed → boundary. stub.emit("item/started", { item: { type: "contextCompaction", id: "c1" }, @@ -2830,7 +2838,12 @@ describe("CodexAppServerAgent", () => { 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..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 @@ -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(), + 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; + } }