@posthog/agent 2.3.104 → 2.3.116

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.
@@ -904,7 +904,7 @@ var import_hono = require("hono");
904
904
  // package.json
905
905
  var package_default = {
906
906
  name: "@posthog/agent",
907
- version: "2.3.104",
907
+ version: "2.3.116",
908
908
  repository: "https://github.com/PostHog/code",
909
909
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
910
910
  exports: {
@@ -5433,22 +5433,41 @@ var PostHogAPIClient = class {
5433
5433
  const host = this.config.apiUrl.endsWith("/") ? this.config.apiUrl.slice(0, -1) : this.config.apiUrl;
5434
5434
  return host;
5435
5435
  }
5436
- get headers() {
5437
- return {
5438
- Authorization: `Bearer ${this.config.getApiKey()}`,
5439
- "Content-Type": "application/json",
5440
- "User-Agent": this.config.userAgent ?? DEFAULT_USER_AGENT
5441
- };
5436
+ isAuthFailure(status) {
5437
+ return status === 401 || status === 403;
5442
5438
  }
5443
- async apiRequest(endpoint, options = {}) {
5439
+ async resolveApiKey(forceRefresh = false) {
5440
+ if (forceRefresh && this.config.refreshApiKey) {
5441
+ return this.config.refreshApiKey();
5442
+ }
5443
+ return this.config.getApiKey();
5444
+ }
5445
+ async buildHeaders(options, forceRefresh = false) {
5446
+ const headers = new Headers(options.headers);
5447
+ headers.set(
5448
+ "Authorization",
5449
+ `Bearer ${await this.resolveApiKey(forceRefresh)}`
5450
+ );
5451
+ headers.set("Content-Type", "application/json");
5452
+ headers.set("User-Agent", this.config.userAgent ?? DEFAULT_USER_AGENT);
5453
+ return headers;
5454
+ }
5455
+ async performRequest(endpoint, options, forceRefresh = false) {
5444
5456
  const url = `${this.baseUrl}${endpoint}`;
5445
- const response = await fetch(url, {
5457
+ return fetch(url, {
5446
5458
  ...options,
5447
- headers: {
5448
- ...this.headers,
5449
- ...options.headers
5450
- }
5459
+ headers: await this.buildHeaders(options, forceRefresh)
5451
5460
  });
5461
+ }
5462
+ async performRequestWithRetry(endpoint, options = {}) {
5463
+ let response = await this.performRequest(endpoint, options);
5464
+ if (!response.ok && this.isAuthFailure(response.status)) {
5465
+ response = await this.performRequest(endpoint, options, true);
5466
+ }
5467
+ return response;
5468
+ }
5469
+ async apiRequest(endpoint, options = {}) {
5470
+ const response = await this.performRequestWithRetry(endpoint, options);
5452
5471
  if (!response.ok) {
5453
5472
  let errorMessage;
5454
5473
  try {
@@ -5464,8 +5483,8 @@ var PostHogAPIClient = class {
5464
5483
  getTeamId() {
5465
5484
  return this.config.projectId;
5466
5485
  }
5467
- getApiKey() {
5468
- return this.config.getApiKey();
5486
+ async getApiKey(forceRefresh = false) {
5487
+ return this.resolveApiKey(forceRefresh);
5469
5488
  }
5470
5489
  getLlmGatewayUrl() {
5471
5490
  return getLlmGatewayUrl(this.baseUrl);
@@ -5565,11 +5584,9 @@ var PostHogAPIClient = class {
5565
5584
  */
5566
5585
  async fetchTaskRunLogs(taskRun) {
5567
5586
  const teamId = this.getTeamId();
5587
+ const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;
5568
5588
  try {
5569
- const response = await fetch(
5570
- `${this.baseUrl}/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`,
5571
- { headers: this.headers }
5572
- );
5589
+ const response = await this.performRequestWithRetry(endpoint);
5573
5590
  if (!response.ok) {
5574
5591
  if (response.status === 404) {
5575
5592
  return [];
@@ -11340,9 +11357,9 @@ var SessionLogWriter = class _SessionLogWriter {
11340
11357
  this.logger = options.logger ?? new Logger({ debug: false, prefix: "[SessionLogWriter]" });
11341
11358
  }
11342
11359
  async flushAll() {
11343
- const sessionIds = [...this.sessions.keys()];
11344
11360
  const flushPromises = [];
11345
- for (const sessionId of sessionIds) {
11361
+ for (const [sessionId, session] of this.sessions) {
11362
+ this.emitCoalescedMessage(sessionId, session);
11346
11363
  flushPromises.push(this.flush(sessionId));
11347
11364
  }
11348
11365
  await Promise.all(flushPromises);
@@ -11398,7 +11415,11 @@ var SessionLogWriter = class _SessionLogWriter {
11398
11415
  }
11399
11416
  return;
11400
11417
  }
11401
- this.emitCoalescedMessage(sessionId, session);
11418
+ if (this.isDirectAgentMessage(message) && session.chunkBuffer) {
11419
+ session.chunkBuffer = void 0;
11420
+ } else {
11421
+ this.emitCoalescedMessage(sessionId, session);
11422
+ }
11402
11423
  const nonChunkAgentText = this.extractAgentMessageText(message);
11403
11424
  if (nonChunkAgentText) {
11404
11425
  session.lastAgentMessage = nonChunkAgentText;
@@ -11424,7 +11445,13 @@ var SessionLogWriter = class _SessionLogWriter {
11424
11445
  });
11425
11446
  }
11426
11447
  }
11427
- async flush(sessionId) {
11448
+ async flush(sessionId, { coalesce = false } = {}) {
11449
+ if (coalesce) {
11450
+ const session = this.sessions.get(sessionId);
11451
+ if (session) {
11452
+ this.emitCoalescedMessage(sessionId, session);
11453
+ }
11454
+ }
11428
11455
  const prev = this.flushQueues.get(sessionId) ?? Promise.resolve();
11429
11456
  const next = prev.catch(() => {
11430
11457
  }).then(() => this._doFlush(sessionId));
@@ -11442,7 +11469,6 @@ var SessionLogWriter = class _SessionLogWriter {
11442
11469
  this.logger.warn("flush: no session found", { sessionId });
11443
11470
  return;
11444
11471
  }
11445
- this.emitCoalescedMessage(sessionId, session);
11446
11472
  const pending = this.pendingEntries.get(sessionId);
11447
11473
  if (!this.posthogAPI || !pending?.length) {
11448
11474
  return;
@@ -11491,11 +11517,17 @@ var SessionLogWriter = class _SessionLogWriter {
11491
11517
  }
11492
11518
  }
11493
11519
  }
11494
- isAgentMessageChunk(message) {
11495
- if (message.method !== "session/update") return false;
11520
+ getSessionUpdateType(message) {
11521
+ if (message.method !== "session/update") return void 0;
11496
11522
  const params = message.params;
11497
11523
  const update = params?.update;
11498
- return update?.sessionUpdate === "agent_message_chunk";
11524
+ return update?.sessionUpdate;
11525
+ }
11526
+ isDirectAgentMessage(message) {
11527
+ return this.getSessionUpdateType(message) === "agent_message";
11528
+ }
11529
+ isAgentMessageChunk(message) {
11530
+ return this.getSessionUpdateType(message) === "agent_message_chunk";
11499
11531
  }
11500
11532
  extractChunkText(message) {
11501
11533
  const params = message.params;
@@ -11540,6 +11572,15 @@ var SessionLogWriter = class _SessionLogWriter {
11540
11572
  getFullAgentResponse(sessionId) {
11541
11573
  const session = this.sessions.get(sessionId);
11542
11574
  if (!session || session.currentTurnMessages.length === 0) return void 0;
11575
+ if (session.chunkBuffer) {
11576
+ this.logger.warn(
11577
+ "getFullAgentResponse called with non-empty chunk buffer",
11578
+ {
11579
+ sessionId,
11580
+ bufferedLength: session.chunkBuffer.text.length
11581
+ }
11582
+ );
11583
+ }
11543
11584
  return session.currentTurnMessages.join("\n\n");
11544
11585
  }
11545
11586
  resetTurnMessages(sessionId) {
@@ -12151,7 +12192,9 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12151
12192
  }
12152
12193
  let assistantMessage;
12153
12194
  try {
12154
- await this.session.logWriter.flush(this.session.payload.run_id);
12195
+ await this.session.logWriter.flush(this.session.payload.run_id, {
12196
+ coalesce: true
12197
+ });
12155
12198
  assistantMessage = this.session.logWriter.getFullAgentResponse(
12156
12199
  this.session.payload.run_id
12157
12200
  );
@@ -12324,6 +12367,9 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12324
12367
  }
12325
12368
  });
12326
12369
  this.logger.info("Session initialized successfully");
12370
+ this.logger.info(
12371
+ `Agent version: ${this.config.version ?? package_default.version}`
12372
+ );
12327
12373
  this.posthogAPI.updateTaskRun(payload.task_id, payload.run_id, {
12328
12374
  status: "in_progress"
12329
12375
  }).catch(
@@ -12601,7 +12647,9 @@ Important:
12601
12647
  async signalTaskComplete(payload, stopReason) {
12602
12648
  if (this.session?.payload.run_id === payload.run_id) {
12603
12649
  try {
12604
- await this.session.logWriter.flush(payload.run_id);
12650
+ await this.session.logWriter.flush(payload.run_id, {
12651
+ coalesce: true
12652
+ });
12605
12653
  } catch (error) {
12606
12654
  this.logger.warn("Failed to flush session logs before completion", {
12607
12655
  taskId: payload.task_id,
@@ -12710,7 +12758,7 @@ Important:
12710
12758
  return;
12711
12759
  }
12712
12760
  try {
12713
- await this.session.logWriter.flush(payload.run_id);
12761
+ await this.session.logWriter.flush(payload.run_id, { coalesce: true });
12714
12762
  } catch (error) {
12715
12763
  this.logger.warn("Failed to flush logs before Slack relay", {
12716
12764
  taskId: payload.task_id,
@@ -12859,7 +12907,9 @@ Important:
12859
12907
  this.logger.error("Failed to capture final tree state", error);
12860
12908
  }
12861
12909
  try {
12862
- await this.session.logWriter.flush(this.session.payload.run_id);
12910
+ await this.session.logWriter.flush(this.session.payload.run_id, {
12911
+ coalesce: true
12912
+ });
12863
12913
  } catch (error) {
12864
12914
  this.logger.error("Failed to flush session logs", error);
12865
12915
  }