@posthog/agent 2.3.72 → 2.3.74

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.3.72",
3
+ "version": "2.3.74",
4
4
  "repository": "https://github.com/PostHog/code",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "exports": {
@@ -20,6 +20,7 @@ import {
20
20
  DEFAULT_GATEWAY_MODEL,
21
21
  fetchGatewayModels,
22
22
  formatGatewayModelName,
23
+ type GatewayModel,
23
24
  isAnthropicModel,
24
25
  } from "../gateway-models";
25
26
  import { Logger } from "../utils/logger";
@@ -33,6 +34,8 @@ export interface BaseSession {
33
34
  settingsManager: SettingsManager;
34
35
  }
35
36
 
37
+ const DEFAULT_CONTEXT_WINDOW = 200_000;
38
+
36
39
  export abstract class BaseAcpAgent implements Agent {
37
40
  abstract readonly adapterName: string;
38
41
  protected session!: BaseSession;
@@ -40,6 +43,7 @@ export abstract class BaseAcpAgent implements Agent {
40
43
  client: AgentSideConnection;
41
44
  logger: Logger;
42
45
  fileContentCache: { [key: string]: string } = {};
46
+ protected gatewayModels: GatewayModel[] = [];
43
47
 
44
48
  constructor(client: AgentSideConnection) {
45
49
  this.client = client;
@@ -119,9 +123,9 @@ export abstract class BaseAcpAgent implements Agent {
119
123
  currentModelId: string;
120
124
  options: SessionConfigSelectOption[];
121
125
  }> {
122
- const gatewayModels = await fetchGatewayModels();
126
+ this.gatewayModels = await fetchGatewayModels();
123
127
 
124
- const options = gatewayModels
128
+ const options = this.gatewayModels
125
129
  .filter((model) => isAnthropicModel(model))
126
130
  .map((model) => ({
127
131
  value: model.id,
@@ -150,4 +154,9 @@ export abstract class BaseAcpAgent implements Agent {
150
154
 
151
155
  return { currentModelId, options };
152
156
  }
157
+
158
+ getContextWindowForModel(modelId: string): number {
159
+ const match = this.gatewayModels.find((m) => m.id === modelId);
160
+ return match?.context_window ?? DEFAULT_CONTEXT_WINDOW;
161
+ }
153
162
  }
@@ -64,7 +64,6 @@ import { getAvailableSlashCommands } from "./session/commands";
64
64
  import { parseMcpServers } from "./session/mcp-config";
65
65
  import {
66
66
  DEFAULT_MODEL,
67
- getDefaultContextWindow,
68
67
  getEffortOptions,
69
68
  resolveModelPreference,
70
69
  toSdkModelId,
@@ -323,6 +322,16 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
323
322
  this.session.promptRunning = true;
324
323
  let handedOff = false;
325
324
  let lastAssistantTotalUsage: number | null = null;
325
+ if (this.session.lastContextWindowSize == null) {
326
+ this.session.lastContextWindowSize = this.getContextWindowForModel(
327
+ this.session.modelId ?? "",
328
+ );
329
+ this.logger.debug("Initial context window size from gateway", {
330
+ modelId: this.session.modelId,
331
+ contextWindowSize: this.session.lastContextWindowSize,
332
+ });
333
+ }
334
+ let lastContextWindowSize = this.session.lastContextWindowSize;
326
335
 
327
336
  const supportsTerminalOutput =
328
337
  (
@@ -393,16 +402,25 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
393
402
  this.session.accumulatedUsage.cachedWriteTokens +=
394
403
  message.usage.cache_creation_input_tokens;
395
404
 
396
- // Calculate context window size from modelUsage (minimum across all models used)
405
+ // SDK can underreport context window (e.g. 200k for 1M models).
406
+ // Use SDK value only if it's larger than what gateway reported.
397
407
  const contextWindows = Object.values(message.modelUsage).map(
398
408
  (m) => m.contextWindow,
399
409
  );
400
- const contextWindowSize =
401
- contextWindows.length > 0
402
- ? Math.min(...contextWindows)
403
- : getDefaultContextWindow(this.session.modelId ?? "");
410
+ if (contextWindows.length > 0) {
411
+ const sdkContextWindow = Math.min(...contextWindows);
412
+ if (sdkContextWindow > lastContextWindowSize) {
413
+ lastContextWindowSize = sdkContextWindow;
414
+ }
415
+ }
416
+ this.session.lastContextWindowSize = lastContextWindowSize;
417
+ this.logger.debug("Context window size from result", {
418
+ sdkReported: contextWindows,
419
+ resolved: lastContextWindowSize,
420
+ modelId: this.session.modelId,
421
+ });
404
422
 
405
- this.session.contextSize = contextWindowSize;
423
+ this.session.contextSize = lastContextWindowSize;
406
424
  if (lastAssistantTotalUsage !== null) {
407
425
  this.session.contextUsed = lastAssistantTotalUsage;
408
426
  }
@@ -414,7 +432,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
414
432
  update: {
415
433
  sessionUpdate: "usage_update",
416
434
  used: lastAssistantTotalUsage,
417
- size: contextWindowSize,
435
+ size: lastContextWindowSize,
418
436
  cost: {
419
437
  amount: message.total_cost_usd,
420
438
  currency: "USD",
@@ -521,9 +539,18 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
521
539
  };
522
540
  lastAssistantTotalUsage =
523
541
  usage.input_tokens +
524
- usage.output_tokens +
525
542
  usage.cache_read_input_tokens +
526
543
  usage.cache_creation_input_tokens;
544
+
545
+ await this.client.sessionUpdate({
546
+ sessionId: params.sessionId,
547
+ update: {
548
+ sessionUpdate: "usage_update",
549
+ used: lastAssistantTotalUsage,
550
+ size: lastContextWindowSize,
551
+ cost: null,
552
+ },
553
+ });
527
554
  }
528
555
 
529
556
  const result = await handleUserAssistantMessage(message, context);
@@ -595,9 +622,11 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
595
622
  async unstable_setSessionModel(
596
623
  params: SetSessionModelRequest,
597
624
  ): Promise<SetSessionModelResponse | undefined> {
598
- const sdkModelId = toSdkModelId(params.modelId);
599
- await this.session.query.setModel(sdkModelId);
625
+ await this.session.query.setModel(toSdkModelId(params.modelId));
600
626
  this.session.modelId = params.modelId;
627
+ this.session.lastContextWindowSize = this.getContextWindowForModel(
628
+ params.modelId,
629
+ );
601
630
  this.rebuildEffortConfigOption(params.modelId);
602
631
  await this.updateConfigOption("model", params.modelId);
603
632
  return {};
@@ -674,6 +703,8 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
674
703
  const sdkModelId = toSdkModelId(resolvedValue);
675
704
  await this.session.query.setModel(sdkModelId);
676
705
  this.session.modelId = resolvedValue;
706
+ this.session.lastContextWindowSize =
707
+ this.getContextWindowForModel(resolvedValue);
677
708
  this.rebuildEffortConfigOption(resolvedValue);
678
709
  } else if (params.configId === "effort") {
679
710
  const newEffort = resolvedValue as EffortLevel;
@@ -893,12 +924,12 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
893
924
  const modelOptions = await this.getModelConfigOptions();
894
925
  const resolvedModelId = settingsModel || modelOptions.currentModelId;
895
926
  session.modelId = resolvedModelId;
927
+ session.lastContextWindowSize =
928
+ this.getContextWindowForModel(resolvedModelId);
896
929
 
897
- if (!isResume) {
898
- const resolvedSdkModel = toSdkModelId(resolvedModelId);
899
- if (resolvedSdkModel !== DEFAULT_MODEL) {
900
- await this.session.query.setModel(resolvedSdkModel);
901
- }
930
+ const resolvedSdkModel = toSdkModelId(resolvedModelId);
931
+ if (!isResume && resolvedSdkModel !== DEFAULT_MODEL) {
932
+ await this.session.query.setModel(resolvedSdkModel);
902
933
  }
903
934
 
904
935
  const availableModes = getAvailableModes();
@@ -544,7 +544,7 @@ export async function handleSystemMessage(
544
544
  message: Extract<SDKMessage, { type: "system" }>,
545
545
  context: MessageHandlerContext,
546
546
  ): Promise<void> {
547
- const { sessionId, client, logger } = context;
547
+ const { session, sessionId, client, logger } = context;
548
548
 
549
549
  switch (message.subtype) {
550
550
  case "init":
@@ -554,6 +554,7 @@ export async function handleSystemMessage(
554
554
  sessionId,
555
555
  trigger: message.compact_metadata.trigger,
556
556
  preTokens: message.compact_metadata.pre_tokens,
557
+ contextSize: session.contextSize,
557
558
  });
558
559
  break;
559
560
  case "hook_response":
@@ -21,10 +21,6 @@ export function supports1MContext(modelId: string): boolean {
21
21
  return MODELS_WITH_1M_CONTEXT.has(modelId);
22
22
  }
23
23
 
24
- export function getDefaultContextWindow(modelId: string): number {
25
- return supports1MContext(modelId) ? 1_000_000 : 200_000;
26
- }
27
-
28
24
  const MODELS_WITH_EFFORT = new Set([
29
25
  "claude-opus-4-5",
30
26
  "claude-opus-4-6",
@@ -238,6 +238,7 @@ export function buildSessionOptions(params: BuildOptionsParams): Options {
238
238
 
239
239
  const options: Options = {
240
240
  ...params.userProvidedOptions,
241
+ betas: ["context-1m-2025-08-07"],
241
242
  systemPrompt: params.systemPrompt ?? buildSystemPrompt(),
242
243
  settingSources: ["user", "project", "local"],
243
244
  stderr: (err) => params.logger.error(err),
@@ -57,6 +57,8 @@ export type Session = BaseSession & {
57
57
  contextUsed?: number;
58
58
  /** Context window size in tokens */
59
59
  contextSize?: number;
60
+ /** Persists across prompt() calls so SDK-reported values survive turn boundaries */
61
+ lastContextWindowSize?: number;
60
62
  promptRunning: boolean;
61
63
  pendingMessages: Map<string, PendingMessage>;
62
64
  nextPendingOrder: number;