@posthog/agent 2.1.115 → 2.1.120

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
@@ -276,7 +276,7 @@ import { v7 as uuidv7 } from "uuid";
276
276
  // package.json
277
277
  var package_default = {
278
278
  name: "@posthog/agent",
279
- version: "2.1.115",
279
+ version: "2.1.120",
280
280
  repository: "https://github.com/PostHog/twig",
281
281
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
282
282
  exports: {
@@ -657,6 +657,10 @@ ${chunk.resource.text}
657
657
  function promptToClaude(prompt) {
658
658
  const content = [];
659
659
  const context = [];
660
+ const prContext = prompt._meta?.prContext;
661
+ if (typeof prContext === "string") {
662
+ content.push(sdkText(prContext));
663
+ }
660
664
  for (const chunk of prompt.prompt) {
661
665
  processPromptChunk(chunk, content, context);
662
666
  }
@@ -2103,9 +2107,10 @@ async function handleAskUserQuestionTool(context) {
2103
2107
  }
2104
2108
  });
2105
2109
  if (response.outcome?.outcome !== "selected") {
2110
+ const customMessage = response._meta?.message;
2106
2111
  return {
2107
2112
  behavior: "deny",
2108
- message: "User cancelled the questions",
2113
+ message: typeof customMessage === "string" ? customMessage : "User cancelled the questions",
2109
2114
  interrupt: true
2110
2115
  };
2111
2116
  }
@@ -2490,12 +2495,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2490
2495
  toolUseCache;
2491
2496
  backgroundTerminals = {};
2492
2497
  clientCapabilities;
2493
- logWriter;
2494
2498
  options;
2495
2499
  lastSentConfigOptions;
2496
- constructor(client, logWriter, options) {
2500
+ constructor(client, options) {
2497
2501
  super(client);
2498
- this.logWriter = logWriter;
2499
2502
  this.options = options;
2500
2503
  this.toolUseCache = {};
2501
2504
  this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
@@ -2540,7 +2543,14 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2540
2543
  async newSession(params) {
2541
2544
  this.checkAuthStatus();
2542
2545
  const meta = params._meta;
2546
+ const taskId = meta?.persistence?.taskId;
2543
2547
  const sessionId = uuidv7();
2548
+ this.logger.info("Creating new session", {
2549
+ sessionId,
2550
+ taskId,
2551
+ taskRunId: meta?.taskRunId,
2552
+ cwd: params.cwd
2553
+ });
2544
2554
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
2545
2555
  const mcpServers = parseMcpServers(params);
2546
2556
  const options = buildSessionOptions({
@@ -2569,7 +2579,6 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2569
2579
  options.abortController
2570
2580
  );
2571
2581
  session.taskRunId = meta?.taskRunId;
2572
- this.registerPersistence(sessionId, meta);
2573
2582
  if (meta?.taskRunId) {
2574
2583
  await this.client.extNotification("_posthog/sdk_session", {
2575
2584
  taskRunId: meta.taskRunId,
@@ -2595,6 +2604,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2595
2604
  }
2596
2605
  async resumeSession(params) {
2597
2606
  const meta = params._meta;
2607
+ const taskId = meta?.persistence?.taskId;
2598
2608
  const sessionId = meta?.sessionId;
2599
2609
  if (!sessionId) {
2600
2610
  throw new Error("Cannot resume session without sessionId");
@@ -2602,6 +2612,12 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2602
2612
  if (this.sessionId === sessionId) {
2603
2613
  return {};
2604
2614
  }
2615
+ this.logger.info("Resuming session", {
2616
+ sessionId,
2617
+ taskId,
2618
+ taskRunId: meta?.taskRunId,
2619
+ cwd: params.cwd
2620
+ });
2605
2621
  const mcpServers = parseMcpServers(params);
2606
2622
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
2607
2623
  const { query: q, session } = await this.initializeQuery({
@@ -2614,15 +2630,36 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2614
2630
  isResume: true,
2615
2631
  additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
2616
2632
  });
2633
+ this.logger.info("Session query initialized, awaiting resumption", {
2634
+ sessionId,
2635
+ taskId,
2636
+ taskRunId: meta?.taskRunId
2637
+ });
2617
2638
  session.taskRunId = meta?.taskRunId;
2618
- this.registerPersistence(sessionId, meta);
2619
- const validation = await withTimeout(
2620
- q.initializationResult(),
2621
- SESSION_VALIDATION_TIMEOUT_MS
2622
- );
2623
- if (validation.result === "timeout") {
2624
- throw new Error("Session validation timed out");
2639
+ try {
2640
+ const result = await withTimeout(
2641
+ q.initializationResult(),
2642
+ SESSION_VALIDATION_TIMEOUT_MS
2643
+ );
2644
+ if (result.result === "timeout") {
2645
+ throw new Error(
2646
+ `Session resumption timed out for sessionId=${sessionId}`
2647
+ );
2648
+ }
2649
+ } catch (err) {
2650
+ this.logger.error("Session resumption failed", {
2651
+ sessionId,
2652
+ taskId,
2653
+ taskRunId: meta?.taskRunId,
2654
+ error: err instanceof Error ? err.message : String(err)
2655
+ });
2656
+ throw err;
2625
2657
  }
2658
+ this.logger.info("Session resumed successfully", {
2659
+ sessionId,
2660
+ taskId,
2661
+ taskRunId: meta?.taskRunId
2662
+ });
2626
2663
  this.deferBackgroundFetches(q, sessionId);
2627
2664
  const configOptions = await this.buildConfigOptions();
2628
2665
  return { configOptions };
@@ -2821,12 +2858,6 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
2821
2858
  this.logger.warn("Failed to fetch deferred session data", { err });
2822
2859
  });
2823
2860
  }
2824
- registerPersistence(sessionId, meta) {
2825
- const persistence = meta?.persistence;
2826
- if (persistence && this.logWriter) {
2827
- this.logWriter.register(sessionId, persistence);
2828
- }
2829
- }
2830
2861
  sendAvailableCommandsUpdate(sessionId, availableCommands) {
2831
2862
  setTimeout(() => {
2832
2863
  this.client.sessionUpdate({
@@ -3114,7 +3145,7 @@ function createClaudeConnection(config) {
3114
3145
  const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
3115
3146
  let agent = null;
3116
3147
  const agentConnection = new AgentSideConnection((client) => {
3117
- agent = new ClaudeAcpAgent(client, logWriter, config.processCallbacks);
3148
+ agent = new ClaudeAcpAgent(client, config.processCallbacks);
3118
3149
  logger.info(`Created ${agent.adapterName} agent`);
3119
3150
  return agent;
3120
3151
  }, agentStream);
@@ -3449,6 +3480,16 @@ var PostHogAPIClient = class {
3449
3480
  }
3450
3481
  );
3451
3482
  }
3483
+ async relayMessage(taskId, runId, text2) {
3484
+ const teamId = this.getTeamId();
3485
+ await this.apiRequest(
3486
+ `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/relay_message/`,
3487
+ {
3488
+ method: "POST",
3489
+ body: JSON.stringify({ text: text2 })
3490
+ }
3491
+ );
3492
+ }
3452
3493
  async uploadTaskArtifacts(taskId, runId, artifacts) {
3453
3494
  if (!artifacts.length) {
3454
3495
  return [];
@@ -3554,11 +3595,15 @@ var SessionLogWriter = class _SessionLogWriter {
3554
3595
  }
3555
3596
  async flushAll() {
3556
3597
  const sessionIds = [...this.sessions.keys()];
3557
- const pendingCounts = sessionIds.map((id) => ({
3558
- id,
3559
- pending: this.pendingEntries.get(id)?.length ?? 0,
3560
- messages: this.messageCounts.get(id) ?? 0
3561
- }));
3598
+ const pendingCounts = sessionIds.map((id) => {
3599
+ const session = this.sessions.get(id);
3600
+ return {
3601
+ taskId: session?.context.taskId,
3602
+ runId: session?.context.runId,
3603
+ pending: this.pendingEntries.get(id)?.length ?? 0,
3604
+ messages: this.messageCounts.get(id) ?? 0
3605
+ };
3606
+ });
3562
3607
  this.logger.info("flushAll called", {
3563
3608
  sessions: sessionIds.length,
3564
3609
  pending: pendingCounts
@@ -3574,8 +3619,8 @@ var SessionLogWriter = class _SessionLogWriter {
3574
3619
  return;
3575
3620
  }
3576
3621
  this.logger.info("Session registered", {
3577
- sessionId,
3578
- taskId: context.taskId
3622
+ taskId: context.taskId,
3623
+ runId: context.runId
3579
3624
  });
3580
3625
  this.sessions.set(sessionId, { context });
3581
3626
  this.lastFlushAttemptTime.set(sessionId, Date.now());
@@ -3609,7 +3654,11 @@ var SessionLogWriter = class _SessionLogWriter {
3609
3654
  const count = (this.messageCounts.get(sessionId) ?? 0) + 1;
3610
3655
  this.messageCounts.set(sessionId, count);
3611
3656
  if (count % 10 === 1) {
3612
- this.logger.info("Messages received", { count, sessionId });
3657
+ this.logger.info("Messages received", {
3658
+ count,
3659
+ taskId: session.context.taskId,
3660
+ runId: session.context.runId
3661
+ });
3613
3662
  }
3614
3663
  try {
3615
3664
  const message = JSON.parse(line);
@@ -3626,6 +3675,10 @@ var SessionLogWriter = class _SessionLogWriter {
3626
3675
  return;
3627
3676
  }
3628
3677
  this.emitCoalescedMessage(sessionId, session);
3678
+ const nonChunkAgentText = this.extractAgentMessageText(message);
3679
+ if (nonChunkAgentText) {
3680
+ session.lastAgentMessage = nonChunkAgentText;
3681
+ }
3629
3682
  const entry = {
3630
3683
  type: "notification",
3631
3684
  timestamp,
@@ -3640,7 +3693,8 @@ var SessionLogWriter = class _SessionLogWriter {
3640
3693
  }
3641
3694
  } catch {
3642
3695
  this.logger.warn("Failed to parse raw line for persistence", {
3643
- sessionId,
3696
+ taskId: session.context.taskId,
3697
+ runId: session.context.runId,
3644
3698
  lineLength: line.length
3645
3699
  });
3646
3700
  }
@@ -3655,7 +3709,8 @@ var SessionLogWriter = class _SessionLogWriter {
3655
3709
  const pending = this.pendingEntries.get(sessionId);
3656
3710
  if (!this.posthogAPI || !pending?.length) {
3657
3711
  this.logger.info("flush: nothing to persist", {
3658
- sessionId,
3712
+ taskId: session.context.taskId,
3713
+ runId: session.context.runId,
3659
3714
  hasPosthogAPI: !!this.posthogAPI,
3660
3715
  pendingCount: pending?.length ?? 0
3661
3716
  });
@@ -3676,7 +3731,8 @@ var SessionLogWriter = class _SessionLogWriter {
3676
3731
  );
3677
3732
  this.retryCounts.set(sessionId, 0);
3678
3733
  this.logger.info("Flushed session logs", {
3679
- sessionId,
3734
+ taskId: session.context.taskId,
3735
+ runId: session.context.runId,
3680
3736
  entryCount: pending.length
3681
3737
  });
3682
3738
  } catch (error) {
@@ -3685,7 +3741,11 @@ var SessionLogWriter = class _SessionLogWriter {
3685
3741
  if (retryCount >= _SessionLogWriter.MAX_FLUSH_RETRIES) {
3686
3742
  this.logger.error(
3687
3743
  `Dropping ${pending.length} session log entries after ${retryCount} failed flush attempts`,
3688
- { sessionId, error }
3744
+ {
3745
+ taskId: session.context.taskId,
3746
+ runId: session.context.runId,
3747
+ error
3748
+ }
3689
3749
  );
3690
3750
  this.retryCounts.set(sessionId, 0);
3691
3751
  } else {
@@ -3718,6 +3778,7 @@ var SessionLogWriter = class _SessionLogWriter {
3718
3778
  if (!session.chunkBuffer) return;
3719
3779
  const { text: text2, firstTimestamp } = session.chunkBuffer;
3720
3780
  session.chunkBuffer = void 0;
3781
+ session.lastAgentMessage = text2;
3721
3782
  const entry = {
3722
3783
  type: "notification",
3723
3784
  timestamp: firstTimestamp,
@@ -3740,6 +3801,29 @@ var SessionLogWriter = class _SessionLogWriter {
3740
3801
  this.scheduleFlush(sessionId);
3741
3802
  }
3742
3803
  }
3804
+ getLastAgentMessage(sessionId) {
3805
+ return this.sessions.get(sessionId)?.lastAgentMessage;
3806
+ }
3807
+ extractAgentMessageText(message) {
3808
+ if (message.method !== "session/update") {
3809
+ return null;
3810
+ }
3811
+ const params = message.params;
3812
+ const update = params?.update;
3813
+ if (update?.sessionUpdate !== "agent_message") {
3814
+ return null;
3815
+ }
3816
+ const content = update.content;
3817
+ if (content?.type === "text" && typeof content.text === "string") {
3818
+ const trimmed = content.text.trim();
3819
+ return trimmed.length > 0 ? trimmed : null;
3820
+ }
3821
+ if (typeof update.message === "string") {
3822
+ const trimmed = update.message.trim();
3823
+ return trimmed.length > 0 ? trimmed : null;
3824
+ }
3825
+ return null;
3826
+ }
3743
3827
  scheduleFlush(sessionId) {
3744
3828
  const existing = this.flushTimeouts.get(sessionId);
3745
3829
  if (existing) clearTimeout(existing);
@@ -3774,7 +3858,12 @@ var SessionLogWriter = class _SessionLogWriter {
3774
3858
  fs3.appendFileSync(logPath, `${JSON.stringify(entry)}
3775
3859
  `);
3776
3860
  } catch (error) {
3777
- this.logger.warn("Failed to write to local cache", { logPath, error });
3861
+ this.logger.warn("Failed to write to local cache", {
3862
+ taskId: session.context.taskId,
3863
+ runId: session.context.runId,
3864
+ logPath,
3865
+ error
3866
+ });
3778
3867
  }
3779
3868
  }
3780
3869
  };