@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.
package/dist/agent.js CHANGED
@@ -371,7 +371,7 @@ import { v7 as uuidv7 } from "uuid";
371
371
  // package.json
372
372
  var package_default = {
373
373
  name: "@posthog/agent",
374
- version: "2.3.104",
374
+ version: "2.3.116",
375
375
  repository: "https://github.com/PostHog/code",
376
376
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
377
377
  exports: {
@@ -4530,22 +4530,41 @@ var PostHogAPIClient = class {
4530
4530
  const host = this.config.apiUrl.endsWith("/") ? this.config.apiUrl.slice(0, -1) : this.config.apiUrl;
4531
4531
  return host;
4532
4532
  }
4533
- get headers() {
4534
- return {
4535
- Authorization: `Bearer ${this.config.getApiKey()}`,
4536
- "Content-Type": "application/json",
4537
- "User-Agent": this.config.userAgent ?? DEFAULT_USER_AGENT
4538
- };
4533
+ isAuthFailure(status) {
4534
+ return status === 401 || status === 403;
4539
4535
  }
4540
- async apiRequest(endpoint, options = {}) {
4536
+ async resolveApiKey(forceRefresh = false) {
4537
+ if (forceRefresh && this.config.refreshApiKey) {
4538
+ return this.config.refreshApiKey();
4539
+ }
4540
+ return this.config.getApiKey();
4541
+ }
4542
+ async buildHeaders(options, forceRefresh = false) {
4543
+ const headers = new Headers(options.headers);
4544
+ headers.set(
4545
+ "Authorization",
4546
+ `Bearer ${await this.resolveApiKey(forceRefresh)}`
4547
+ );
4548
+ headers.set("Content-Type", "application/json");
4549
+ headers.set("User-Agent", this.config.userAgent ?? DEFAULT_USER_AGENT);
4550
+ return headers;
4551
+ }
4552
+ async performRequest(endpoint, options, forceRefresh = false) {
4541
4553
  const url = `${this.baseUrl}${endpoint}`;
4542
- const response = await fetch(url, {
4554
+ return fetch(url, {
4543
4555
  ...options,
4544
- headers: {
4545
- ...this.headers,
4546
- ...options.headers
4547
- }
4556
+ headers: await this.buildHeaders(options, forceRefresh)
4548
4557
  });
4558
+ }
4559
+ async performRequestWithRetry(endpoint, options = {}) {
4560
+ let response = await this.performRequest(endpoint, options);
4561
+ if (!response.ok && this.isAuthFailure(response.status)) {
4562
+ response = await this.performRequest(endpoint, options, true);
4563
+ }
4564
+ return response;
4565
+ }
4566
+ async apiRequest(endpoint, options = {}) {
4567
+ const response = await this.performRequestWithRetry(endpoint, options);
4549
4568
  if (!response.ok) {
4550
4569
  let errorMessage;
4551
4570
  try {
@@ -4561,8 +4580,8 @@ var PostHogAPIClient = class {
4561
4580
  getTeamId() {
4562
4581
  return this.config.projectId;
4563
4582
  }
4564
- getApiKey() {
4565
- return this.config.getApiKey();
4583
+ async getApiKey(forceRefresh = false) {
4584
+ return this.resolveApiKey(forceRefresh);
4566
4585
  }
4567
4586
  getLlmGatewayUrl() {
4568
4587
  return getLlmGatewayUrl(this.baseUrl);
@@ -4662,11 +4681,9 @@ var PostHogAPIClient = class {
4662
4681
  */
4663
4682
  async fetchTaskRunLogs(taskRun) {
4664
4683
  const teamId = this.getTeamId();
4684
+ const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;
4665
4685
  try {
4666
- const response = await fetch(
4667
- `${this.baseUrl}/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`,
4668
- { headers: this.headers }
4669
- );
4686
+ const response = await this.performRequestWithRetry(endpoint);
4670
4687
  if (!response.ok) {
4671
4688
  if (response.status === 404) {
4672
4689
  return [];
@@ -4713,9 +4730,9 @@ var SessionLogWriter = class _SessionLogWriter {
4713
4730
  this.logger = options.logger ?? new Logger({ debug: false, prefix: "[SessionLogWriter]" });
4714
4731
  }
4715
4732
  async flushAll() {
4716
- const sessionIds = [...this.sessions.keys()];
4717
4733
  const flushPromises = [];
4718
- for (const sessionId of sessionIds) {
4734
+ for (const [sessionId, session] of this.sessions) {
4735
+ this.emitCoalescedMessage(sessionId, session);
4719
4736
  flushPromises.push(this.flush(sessionId));
4720
4737
  }
4721
4738
  await Promise.all(flushPromises);
@@ -4771,7 +4788,11 @@ var SessionLogWriter = class _SessionLogWriter {
4771
4788
  }
4772
4789
  return;
4773
4790
  }
4774
- this.emitCoalescedMessage(sessionId, session);
4791
+ if (this.isDirectAgentMessage(message) && session.chunkBuffer) {
4792
+ session.chunkBuffer = void 0;
4793
+ } else {
4794
+ this.emitCoalescedMessage(sessionId, session);
4795
+ }
4775
4796
  const nonChunkAgentText = this.extractAgentMessageText(message);
4776
4797
  if (nonChunkAgentText) {
4777
4798
  session.lastAgentMessage = nonChunkAgentText;
@@ -4797,7 +4818,13 @@ var SessionLogWriter = class _SessionLogWriter {
4797
4818
  });
4798
4819
  }
4799
4820
  }
4800
- async flush(sessionId) {
4821
+ async flush(sessionId, { coalesce = false } = {}) {
4822
+ if (coalesce) {
4823
+ const session = this.sessions.get(sessionId);
4824
+ if (session) {
4825
+ this.emitCoalescedMessage(sessionId, session);
4826
+ }
4827
+ }
4801
4828
  const prev = this.flushQueues.get(sessionId) ?? Promise.resolve();
4802
4829
  const next = prev.catch(() => {
4803
4830
  }).then(() => this._doFlush(sessionId));
@@ -4815,7 +4842,6 @@ var SessionLogWriter = class _SessionLogWriter {
4815
4842
  this.logger.warn("flush: no session found", { sessionId });
4816
4843
  return;
4817
4844
  }
4818
- this.emitCoalescedMessage(sessionId, session);
4819
4845
  const pending = this.pendingEntries.get(sessionId);
4820
4846
  if (!this.posthogAPI || !pending?.length) {
4821
4847
  return;
@@ -4864,11 +4890,17 @@ var SessionLogWriter = class _SessionLogWriter {
4864
4890
  }
4865
4891
  }
4866
4892
  }
4867
- isAgentMessageChunk(message) {
4868
- if (message.method !== "session/update") return false;
4893
+ getSessionUpdateType(message) {
4894
+ if (message.method !== "session/update") return void 0;
4869
4895
  const params = message.params;
4870
4896
  const update = params?.update;
4871
- return update?.sessionUpdate === "agent_message_chunk";
4897
+ return update?.sessionUpdate;
4898
+ }
4899
+ isDirectAgentMessage(message) {
4900
+ return this.getSessionUpdateType(message) === "agent_message";
4901
+ }
4902
+ isAgentMessageChunk(message) {
4903
+ return this.getSessionUpdateType(message) === "agent_message_chunk";
4872
4904
  }
4873
4905
  extractChunkText(message) {
4874
4906
  const params = message.params;
@@ -4913,6 +4945,15 @@ var SessionLogWriter = class _SessionLogWriter {
4913
4945
  getFullAgentResponse(sessionId) {
4914
4946
  const session = this.sessions.get(sessionId);
4915
4947
  if (!session || session.currentTurnMessages.length === 0) return void 0;
4948
+ if (session.chunkBuffer) {
4949
+ this.logger.warn(
4950
+ "getFullAgentResponse called with non-empty chunk buffer",
4951
+ {
4952
+ sessionId,
4953
+ bufferedLength: session.chunkBuffer.text.length
4954
+ }
4955
+ );
4956
+ }
4916
4957
  return session.currentTurnMessages.join("\n\n");
4917
4958
  }
4918
4959
  resetTurnMessages(sessionId) {
@@ -5036,13 +5077,13 @@ var Agent = class {
5036
5077
  }
5037
5078
  }
5038
5079
  }
5039
- _configureLlmGateway(overrideUrl) {
5080
+ async _configureLlmGateway(overrideUrl) {
5040
5081
  if (!this.posthogAPI) {
5041
5082
  return null;
5042
5083
  }
5043
5084
  try {
5044
5085
  const gatewayUrl = overrideUrl ?? this.posthogAPI.getLlmGatewayUrl();
5045
- const apiKey = this.posthogAPI.getApiKey();
5086
+ const apiKey = await this.posthogAPI.getApiKey();
5046
5087
  process.env.OPENAI_BASE_URL = `${gatewayUrl}/v1`;
5047
5088
  process.env.OPENAI_API_KEY = apiKey;
5048
5089
  process.env.ANTHROPIC_BASE_URL = gatewayUrl;
@@ -5054,7 +5095,7 @@ var Agent = class {
5054
5095
  }
5055
5096
  }
5056
5097
  async run(taskId, taskRunId, options = {}) {
5057
- const gatewayConfig = this._configureLlmGateway(options.gatewayUrl);
5098
+ const gatewayConfig = await this._configureLlmGateway(options.gatewayUrl);
5058
5099
  this.logger.info("Configured LLM gateway", {
5059
5100
  adapter: options.adapter
5060
5101
  });
@@ -5131,7 +5172,7 @@ var Agent = class {
5131
5172
  }
5132
5173
  async cleanup() {
5133
5174
  if (this.sessionLogWriter && this.taskRunId) {
5134
- await this.sessionLogWriter.flush(this.taskRunId);
5175
+ await this.sessionLogWriter.flush(this.taskRunId, { coalesce: true });
5135
5176
  }
5136
5177
  await this.acpConnection?.cleanup();
5137
5178
  }