@posthog/agent 2.3.209 → 2.3.213

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.209",
907
+ version: "2.3.213",
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: {
@@ -5978,6 +5978,27 @@ var PostHogAPIClient = class {
5978
5978
  };
5979
5979
 
5980
5980
  // ../shared/dist/index.js
5981
+ var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
5982
+ function deserializeCloudPrompt(value) {
5983
+ const trimmed2 = value.trim();
5984
+ if (!trimmed2) {
5985
+ return [];
5986
+ }
5987
+ if (!trimmed2.startsWith(CLOUD_PROMPT_PREFIX)) {
5988
+ return [{ type: "text", text: trimmed2 }];
5989
+ }
5990
+ try {
5991
+ const parsed = JSON.parse(trimmed2.slice(CLOUD_PROMPT_PREFIX.length));
5992
+ if (Array.isArray(parsed.blocks) && parsed.blocks.length > 0) {
5993
+ return parsed.blocks;
5994
+ }
5995
+ } catch {
5996
+ }
5997
+ return [{ type: "text", text: trimmed2 }];
5998
+ }
5999
+ function promptBlocksToText(blocks) {
6000
+ return blocks.filter((b) => b.type === "text").map((block) => block.text).join("").trim();
6001
+ }
5981
6002
  var consoleLogger = {
5982
6003
  info: (_message, _data) => {
5983
6004
  },
@@ -12073,6 +12094,14 @@ var AsyncMutex = class {
12073
12094
  }
12074
12095
  };
12075
12096
 
12097
+ // src/server/cloud-prompt.ts
12098
+ function normalizeCloudPromptContent(content) {
12099
+ if (typeof content === "string") {
12100
+ return deserializeCloudPrompt(content);
12101
+ }
12102
+ return content;
12103
+ }
12104
+
12076
12105
  // src/server/jwt.ts
12077
12106
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
12078
12107
  var import_zod2 = require("zod");
@@ -12156,7 +12185,10 @@ var jsonRpcRequestSchema = import_v4.z.object({
12156
12185
  id: import_v4.z.union([import_v4.z.string(), import_v4.z.number()]).optional()
12157
12186
  });
12158
12187
  var userMessageParamsSchema = import_v4.z.object({
12159
- content: import_v4.z.string().min(1, "Content is required")
12188
+ content: import_v4.z.union([
12189
+ import_v4.z.string().min(1, "Content is required"),
12190
+ import_v4.z.array(import_v4.z.record(import_v4.z.string(), import_v4.z.unknown())).min(1, "Content is required")
12191
+ ])
12160
12192
  });
12161
12193
  var commandParamsSchemas = {
12162
12194
  user_message: userMessageParamsSchema,
@@ -12537,14 +12569,17 @@ var AgentServer = class _AgentServer {
12537
12569
  switch (method) {
12538
12570
  case POSTHOG_NOTIFICATIONS.USER_MESSAGE:
12539
12571
  case "user_message": {
12540
- const content = params.content;
12572
+ const prompt = normalizeCloudPromptContent(
12573
+ params.content
12574
+ );
12575
+ const promptPreview = promptBlocksToText(prompt);
12541
12576
  this.logger.info(
12542
- `Processing user message (detectedPrUrl=${this.detectedPrUrl ?? "none"}): ${content.substring(0, 100)}...`
12577
+ `Processing user message (detectedPrUrl=${this.detectedPrUrl ?? "none"}): ${promptPreview.substring(0, 100)}...`
12543
12578
  );
12544
12579
  this.session.logWriter.resetTurnMessages(this.session.payload.run_id);
12545
12580
  const result = await this.session.clientConnection.prompt({
12546
12581
  sessionId: this.session.acpSessionId,
12547
- prompt: [{ type: "text", text: content }],
12582
+ prompt,
12548
12583
  ...this.detectedPrUrl && {
12549
12584
  _meta: {
12550
12585
  prContext: `IMPORTANT \u2014 OVERRIDE PREVIOUS INSTRUCTIONS ABOUT CREATING BRANCHES/PRs.
@@ -12804,20 +12839,29 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12804
12839
  try {
12805
12840
  const task = await this.posthogAPI.getTask(payload.task_id);
12806
12841
  const initialPromptOverride = taskRun ? this.getInitialPromptOverride(taskRun) : null;
12807
- const initialPrompt = initialPromptOverride ?? task.description;
12808
- if (!initialPrompt) {
12842
+ const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
12843
+ let initialPrompt = [];
12844
+ if (pendingUserPrompt?.length) {
12845
+ initialPrompt = pendingUserPrompt;
12846
+ } else if (initialPromptOverride) {
12847
+ initialPrompt = [{ type: "text", text: initialPromptOverride }];
12848
+ } else if (task.description) {
12849
+ initialPrompt = [{ type: "text", text: task.description }];
12850
+ }
12851
+ if (initialPrompt.length === 0) {
12809
12852
  this.logger.warn("Task has no description, skipping initial message");
12810
12853
  return;
12811
12854
  }
12812
12855
  this.logger.info("Sending initial task message", {
12813
12856
  taskId: payload.task_id,
12814
- descriptionLength: initialPrompt.length,
12815
- usedInitialPromptOverride: !!initialPromptOverride
12857
+ descriptionLength: promptBlocksToText(initialPrompt).length,
12858
+ usedInitialPromptOverride: !!initialPromptOverride,
12859
+ usedPendingUserMessage: !!pendingUserPrompt?.length
12816
12860
  });
12817
12861
  this.session.logWriter.resetTurnMessages(payload.run_id);
12818
12862
  const result = await this.session.clientConnection.prompt({
12819
12863
  sessionId: this.session.acpSessionId,
12820
- prompt: [{ type: "text", text: initialPrompt }]
12864
+ prompt: initialPrompt
12821
12865
  });
12822
12866
  this.logger.info("Initial task message completed", {
12823
12867
  stopReason: result.stopReason
@@ -12840,11 +12884,14 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
12840
12884
  const conversationSummary = this.formatConversationForResume(
12841
12885
  this.resumeState.conversation
12842
12886
  );
12843
- const pendingUserMessage = this.getPendingUserMessage(taskRun);
12887
+ const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
12844
12888
  const sandboxContext = this.resumeState.snapshotApplied ? `The workspace environment (all files, packages, and code changes) has been fully restored from where you left off.` : `The workspace files from the previous session were not restored (the file snapshot may have expired), so you are starting with a fresh environment. Your conversation history is fully preserved below.`;
12845
- let resumePrompt;
12846
- if (pendingUserMessage) {
12847
- resumePrompt = `You are resuming a previous conversation. ${sandboxContext}
12889
+ let resumePromptBlocks;
12890
+ if (pendingUserPrompt?.length) {
12891
+ resumePromptBlocks = [
12892
+ {
12893
+ type: "text",
12894
+ text: `You are resuming a previous conversation. ${sandboxContext}
12848
12895
 
12849
12896
  Here is the conversation history from the previous session:
12850
12897
 
@@ -12852,30 +12899,40 @@ ${conversationSummary}
12852
12899
 
12853
12900
  The user has sent a new message:
12854
12901
 
12855
- ${pendingUserMessage}
12856
-
12857
- Respond to the user's new message above. You have full context from the previous session.`;
12902
+ `
12903
+ },
12904
+ ...pendingUserPrompt,
12905
+ {
12906
+ type: "text",
12907
+ text: "\n\nRespond to the user's new message above. You have full context from the previous session."
12908
+ }
12909
+ ];
12858
12910
  } else {
12859
- resumePrompt = `You are resuming a previous conversation. ${sandboxContext}
12911
+ resumePromptBlocks = [
12912
+ {
12913
+ type: "text",
12914
+ text: `You are resuming a previous conversation. ${sandboxContext}
12860
12915
 
12861
12916
  Here is the conversation history from the previous session:
12862
12917
 
12863
12918
  ${conversationSummary}
12864
12919
 
12865
- Continue from where you left off. The user is waiting for your response.`;
12920
+ Continue from where you left off. The user is waiting for your response.`
12921
+ }
12922
+ ];
12866
12923
  }
12867
12924
  this.logger.info("Sending resume message", {
12868
12925
  taskId: payload.task_id,
12869
12926
  conversationTurns: this.resumeState.conversation.length,
12870
- promptLength: resumePrompt.length,
12871
- hasPendingUserMessage: !!pendingUserMessage,
12927
+ promptLength: promptBlocksToText(resumePromptBlocks).length,
12928
+ hasPendingUserMessage: !!pendingUserPrompt?.length,
12872
12929
  snapshotApplied: this.resumeState.snapshotApplied
12873
12930
  });
12874
12931
  this.resumeState = null;
12875
12932
  this.session.logWriter.resetTurnMessages(payload.run_id);
12876
12933
  const result = await this.session.clientConnection.prompt({
12877
12934
  sessionId: this.session.acpSessionId,
12878
- prompt: [{ type: "text", text: resumePrompt }]
12935
+ prompt: resumePromptBlocks
12879
12936
  });
12880
12937
  this.logger.info("Resume message completed", {
12881
12938
  stopReason: result.stopReason
@@ -12935,15 +12992,15 @@ ${toolSummary}`);
12935
12992
  const trimmed2 = override.trim();
12936
12993
  return trimmed2.length > 0 ? trimmed2 : null;
12937
12994
  }
12938
- getPendingUserMessage(taskRun) {
12995
+ getPendingUserPrompt(taskRun) {
12939
12996
  if (!taskRun) return null;
12940
12997
  const state = taskRun.state;
12941
12998
  const message = state?.pending_user_message;
12942
12999
  if (typeof message !== "string") {
12943
13000
  return null;
12944
13001
  }
12945
- const trimmed2 = message.trim();
12946
- return trimmed2.length > 0 ? trimmed2 : null;
13002
+ const prompt = deserializeCloudPrompt(message);
13003
+ return prompt.length > 0 ? prompt : null;
12947
13004
  }
12948
13005
  getResumeRunId(taskRun) {
12949
13006
  const envRunId = process.env.POSTHOG_RESUME_RUN_ID;