@posthog/agent 2.3.678 → 2.3.696

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ vi.mock("../../enrichment/file-enricher", () => ({
14
14
  }));
15
15
 
16
16
  import { createCodexClient } from "./codex-client";
17
- import { createSessionState } from "./session-state";
17
+ import { createSessionState, resetSessionState } from "./session-state";
18
18
 
19
19
  function makeUpstream(response: ReadTextFileResponse): AgentSideConnection & {
20
20
  readTextFile: ReturnType<typeof vi.fn>;
@@ -288,3 +288,51 @@ describe("createCodexClient onStructuredOutput", () => {
288
288
  expect(upstream.sessionUpdate).toHaveBeenCalledTimes(1);
289
289
  });
290
290
  });
291
+
292
+ describe("createCodexClient usage_update propagation", () => {
293
+ const logger = new Logger({ debug: false, prefix: "[test]" });
294
+
295
+ function makeUpstream(): AgentSideConnection {
296
+ return {
297
+ sessionUpdate: vi.fn(async () => {}),
298
+ requestPermission: vi.fn(),
299
+ readTextFile: vi.fn(),
300
+ writeTextFile: vi.fn(),
301
+ createTerminal: vi.fn(),
302
+ terminalOutput: vi.fn(),
303
+ releaseTerminal: vi.fn(),
304
+ waitForTerminalExit: vi.fn(),
305
+ killTerminal: vi.fn(),
306
+ extMethod: vi.fn(),
307
+ extNotification: vi.fn(),
308
+ } as unknown as AgentSideConnection;
309
+ }
310
+
311
+ // Regression: codex-client closure-captures the sessionState reference in
312
+ // its factory. CodexAcpAgent constructs the client once at startup with the
313
+ // initial "" sessionId state, then resetSessionState() mutates that same
314
+ // object on every newSession/loadSession/etc. If the agent ever reassigned
315
+ // `this.sessionState`, contextUsed writes would land on an orphan and the
316
+ // breakdown notification would never fire.
317
+ test("writes contextUsed to the same state object after resetSessionState", async () => {
318
+ const sessionState = createSessionState("", "/tmp");
319
+ const upstream = makeUpstream();
320
+ const client = createCodexClient(upstream, logger, sessionState);
321
+
322
+ resetSessionState(sessionState, "real-session", "/tmp/repo", {
323
+ taskRunId: "run-1",
324
+ });
325
+
326
+ await client.sessionUpdate?.({
327
+ sessionId: "real-session",
328
+ update: {
329
+ sessionUpdate: "usage_update",
330
+ used: 123_456,
331
+ size: 200_000,
332
+ },
333
+ } as unknown as SessionNotification);
334
+
335
+ expect(sessionState.contextUsed).toBe(123_456);
336
+ expect(sessionState.contextSize).toBe(200_000);
337
+ });
338
+ });
@@ -1,10 +1,6 @@
1
- /**
2
- * Session state tracking for Codex proxy agent.
3
- * Tracks usage accumulation, model/mode state, and config options.
4
- */
5
-
6
1
  import type { SessionConfigOption } from "@agentclientprotocol/sdk";
7
2
  import type { PermissionMode } from "../../execution-mode";
3
+ import type { ContextBreakdownBaseline } from "../claude/context-breakdown";
8
4
 
9
5
  export interface CodexUsage {
10
6
  inputTokens: number;
@@ -22,6 +18,7 @@ export interface CodexSessionState {
22
18
  accumulatedUsage: CodexUsage;
23
19
  contextSize?: number;
24
20
  contextUsed?: number;
21
+ contextBreakdownBaseline?: ContextBreakdownBaseline;
25
22
  permissionMode: PermissionMode;
26
23
  taskRunId?: string;
27
24
  taskId?: string;
@@ -56,6 +53,40 @@ export function createSessionState(
56
53
  };
57
54
  }
58
55
 
56
+ // codex-client closure-captures the original sessionState reference, so we
57
+ // must mutate in place across newSession/loadSession/resumeSession/forkSession
58
+ // — reassigning would orphan it and silently break usage propagation.
59
+ export function resetSessionState(
60
+ state: CodexSessionState,
61
+ sessionId: string,
62
+ cwd: string,
63
+ opts?: {
64
+ taskRunId?: string;
65
+ taskId?: string;
66
+ modeId?: string;
67
+ modelId?: string;
68
+ permissionMode?: PermissionMode;
69
+ },
70
+ ): void {
71
+ state.sessionId = sessionId;
72
+ state.cwd = cwd;
73
+ state.modeId = opts?.modeId ?? "auto";
74
+ state.modelId = opts?.modelId;
75
+ state.configOptions = [];
76
+ state.accumulatedUsage = {
77
+ inputTokens: 0,
78
+ outputTokens: 0,
79
+ cachedReadTokens: 0,
80
+ cachedWriteTokens: 0,
81
+ };
82
+ state.contextSize = undefined;
83
+ state.contextUsed = undefined;
84
+ state.contextBreakdownBaseline = undefined;
85
+ state.permissionMode = opts?.permissionMode ?? "auto";
86
+ state.taskRunId = opts?.taskRunId;
87
+ state.taskId = opts?.taskId;
88
+ }
89
+
59
90
  export function resetUsage(state: CodexSessionState): void {
60
91
  state.accumulatedUsage = {
61
92
  inputTokens: 0,