@posthog/agent 1.28.0 → 1.30.0

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/index.d.ts CHANGED
@@ -37,6 +37,8 @@ declare const POSTHOG_NOTIFICATIONS: {
37
37
  readonly CONSOLE: "_posthog/console";
38
38
  /** SDK session ID notification (for resumption) */
39
39
  readonly SDK_SESSION: "_posthog/sdk_session";
40
+ /** Sandbox execution output (stdout/stderr from Modal or Docker) */
41
+ readonly SANDBOX_OUTPUT: "_posthog/sandbox_output";
40
42
  };
41
43
  type PostHogNotificationType = (typeof POSTHOG_NOTIFICATIONS)[keyof typeof POSTHOG_NOTIFICATIONS];
42
44
  interface ArtifactNotificationPayload {
@@ -92,7 +94,16 @@ interface SdkSessionPayload {
92
94
  sessionId: string;
93
95
  sdkSessionId: string;
94
96
  }
95
- type PostHogNotificationPayload = ArtifactNotificationPayload | PhaseNotificationPayload | BranchCreatedPayload | PrCreatedPayload | RunStartedPayload | TaskCompletePayload | ErrorNotificationPayload | ConsoleNotificationPayload | SdkSessionPayload;
97
+ /**
98
+ * Sandbox execution output
99
+ */
100
+ interface SandboxOutputPayload {
101
+ sessionId: string;
102
+ stdout: string;
103
+ stderr: string;
104
+ exitCode: number;
105
+ }
106
+ type PostHogNotificationPayload = ArtifactNotificationPayload | PhaseNotificationPayload | BranchCreatedPayload | PrCreatedPayload | RunStartedPayload | TaskCompletePayload | ErrorNotificationPayload | ConsoleNotificationPayload | SdkSessionPayload | SandboxOutputPayload;
96
107
 
97
108
  /**
98
109
  * Stored custom notification following ACP extensibility model.
@@ -217,7 +228,7 @@ type OnLogCallback = (level: LogLevel$1, scope: string, message: string, data?:
217
228
  interface AgentConfig {
218
229
  workingDirectory?: string;
219
230
  posthogApiUrl?: string;
220
- posthogApiKey?: string;
231
+ getPosthogApiKey?: () => string;
221
232
  posthogProjectId?: number;
222
233
  posthogMcpUrl?: string;
223
234
  mcpServers?: Record<string, McpServerConfig>;
@@ -227,7 +238,7 @@ interface AgentConfig {
227
238
  }
228
239
  interface PostHogAPIConfig {
229
240
  apiUrl: string;
230
- apiKey: string;
241
+ getApiKey: () => string;
231
242
  projectId: number;
232
243
  }
233
244
  type ResourceType = "error" | "experiment" | "insight" | "feature_flag" | "generic";
@@ -454,7 +465,7 @@ declare class Agent {
454
465
  */
455
466
  setDebug(enabled: boolean): void;
456
467
  /**
457
- * Configure LLM gateway environment variables for Claude Code CLI
468
+ * Configure LLM gateway environment variables for Claude Code CLI.
458
469
  */
459
470
  private _configureLlmGateway;
460
471
  private getOrCreateConnection;
@@ -482,6 +493,7 @@ declare class Agent {
482
493
  getTaskExecutionStatus(taskId: string): string | null;
483
494
  private prepareTaskBranch;
484
495
  private ensureOpenAIGatewayEnv;
496
+ private ensureGeminiGatewayEnv;
485
497
  runTaskCloud(taskId: string, taskRunId: string, options?: TaskExecutionOptions): Promise<void>;
486
498
  private ensurePullRequest;
487
499
  }
@@ -1234,6 +1246,8 @@ declare class ToolRegistry {
1234
1246
  getByCategory(category: string): Tool[];
1235
1247
  }
1236
1248
 
1249
+ declare function getLlmGatewayUrl(posthogHost: string): string;
1250
+
1237
1251
  interface WorktreeConfig {
1238
1252
  mainRepoPath: string;
1239
1253
  worktreeBasePath?: string;
@@ -1255,7 +1269,9 @@ declare class WorktreeManager {
1255
1269
  ensureArrayDirIgnored(): Promise<void>;
1256
1270
  private generateUniqueWorktreeName;
1257
1271
  private getDefaultBranch;
1258
- createWorktree(): Promise<WorktreeInfo>;
1272
+ createWorktree(options?: {
1273
+ baseBranch?: string;
1274
+ }): Promise<WorktreeInfo>;
1259
1275
  deleteWorktree(worktreePath: string): Promise<void>;
1260
1276
  getWorktreeInfo(worktreePath: string): Promise<WorktreeInfo | null>;
1261
1277
  listWorktrees(): Promise<WorktreeInfo[]>;
@@ -1271,4 +1287,4 @@ declare class WorktreeManager {
1271
1287
  }>;
1272
1288
  }
1273
1289
 
1274
- export { type AcpConnectionConfig, Agent, type AgentConfig, type AgentEvent, type ArtifactNotificationPayload, type BashOutputTool, type BashTool, type BranchCreatedPayload, type ConsoleEvent, type ConsoleNotificationPayload, type EditTool, type ErrorEvent, type ErrorNotificationPayload, type ExecutionResult, type ExitPlanModeTool, type GlobTool, type GrepTool, type InProcessAcpConnection, type KillShellTool, type KnownTool, LogLevel, type LogLevel$1 as LogLevelType, Logger, type LoggerConfig, type McpServerConfig, type NotebookEditTool, type OnLogCallback, POSTHOG_NOTIFICATIONS, PermissionMode, type PhaseNotificationPayload, type PostHogNotificationPayload, type PostHogNotificationType, type PrCreatedPayload, type ReadTool, type ResearchEvaluation, type RunStartedPayload, type SdkSessionPayload, type SessionPersistenceConfig, SessionStore, type SlashCommandTool, type StatusEvent, type StoredEntry, type StoredNotification, type SupportingFile, type Task, type TaskCompletePayload, type TaskRun, type TaskTool, type TodoItem, type TodoList, TodoManager, type TodoWriteTool, type TokenEvent, type Tool, type ToolCategory, ToolRegistry, type WebFetchTool, type WebSearchTool, type WorktreeConfig, type WorktreeInfo, WorktreeManager, type WriteTool, createAcpConnection, parseAgentEvent, parseAgentEvents };
1290
+ export { type AcpConnectionConfig, Agent, type AgentConfig, type AgentEvent, type ArtifactNotificationPayload, type BashOutputTool, type BashTool, type BranchCreatedPayload, type ConsoleEvent, type ConsoleNotificationPayload, type EditTool, type ErrorEvent, type ErrorNotificationPayload, type ExecutionResult, type ExitPlanModeTool, type GlobTool, type GrepTool, type InProcessAcpConnection, type KillShellTool, type KnownTool, LogLevel, type LogLevel$1 as LogLevelType, Logger, type LoggerConfig, type McpServerConfig, type NotebookEditTool, type OnLogCallback, POSTHOG_NOTIFICATIONS, PermissionMode, type PhaseNotificationPayload, type PostHogNotificationPayload, type PostHogNotificationType, type PrCreatedPayload, type ReadTool, type ResearchEvaluation, type RunStartedPayload, type SdkSessionPayload, type SessionPersistenceConfig, SessionStore, type SlashCommandTool, type StatusEvent, type StoredEntry, type StoredNotification, type SupportingFile, type Task, type TaskCompletePayload, type TaskRun, type TaskTool, type TodoItem, type TodoList, TodoManager, type TodoWriteTool, type TokenEvent, type Tool, type ToolCategory, ToolRegistry, type WebFetchTool, type WebSearchTool, type WorktreeConfig, type WorktreeInfo, WorktreeManager, type WriteTool, createAcpConnection, getLlmGatewayUrl, parseAgentEvent, parseAgentEvents };
package/dist/index.js CHANGED
@@ -65,7 +65,9 @@ var POSTHOG_NOTIFICATIONS = {
65
65
  /** Console/log output */
66
66
  CONSOLE: "_posthog/console",
67
67
  /** SDK session ID notification (for resumption) */
68
- SDK_SESSION: "_posthog/sdk_session"
68
+ SDK_SESSION: "_posthog/sdk_session",
69
+ /** Sandbox execution output (stdout/stderr from Modal or Docker) */
70
+ SANDBOX_OUTPUT: "_posthog/sandbox_output"
69
71
  };
70
72
 
71
73
  // src/adapters/claude/claude.ts
@@ -196,7 +198,7 @@ function createTappedWritableStream(underlying, options) {
196
198
  // package.json
197
199
  var package_default = {
198
200
  name: "@posthog/agent",
199
- version: "1.28.0",
201
+ version: "1.30.0",
200
202
  repository: "https://github.com/PostHog/array",
201
203
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
202
204
  main: "./dist/index.js",
@@ -1729,6 +1731,18 @@ var ClaudeAcpAgent = class {
1729
1731
  }
1730
1732
  const availableCommands = await getAvailableSlashCommands(q);
1731
1733
  const models = await getAvailableModels(q);
1734
+ const requestedModel = params._meta?.model;
1735
+ if (requestedModel) {
1736
+ try {
1737
+ await q.setModel(requestedModel);
1738
+ this.logger.info("Set initial model", { model: requestedModel });
1739
+ } catch (err) {
1740
+ this.logger.warn("Failed to set initial model, using default", {
1741
+ requestedModel,
1742
+ error: err
1743
+ });
1744
+ }
1745
+ }
1732
1746
  setTimeout(() => {
1733
1747
  this.client.sessionUpdate({
1734
1748
  sessionId,
@@ -1901,8 +1915,11 @@ var ClaudeAcpAgent = class {
1901
1915
  throw RequestError.authRequired();
1902
1916
  }
1903
1917
  const content = message.message.content;
1918
+ const contentToProcess = Array.isArray(content) ? content.filter(
1919
+ (block) => block.type !== "text" && block.type !== "thinking"
1920
+ ) : content;
1904
1921
  for (const notification of toAcpNotifications(
1905
- content,
1922
+ contentToProcess,
1906
1923
  message.message.role,
1907
1924
  params.sessionId,
1908
1925
  this.toolUseCache,
@@ -2121,6 +2138,11 @@ var ClaudeAcpAgent = class {
2121
2138
  await this.resumeSession(params);
2122
2139
  return {};
2123
2140
  }
2141
+ if (method === "session/setModel") {
2142
+ const { sessionId, modelId } = params;
2143
+ await this.setSessionModel({ sessionId, modelId });
2144
+ return {};
2145
+ }
2124
2146
  throw RequestError.methodNotFound(method);
2125
2147
  }
2126
2148
  /**
@@ -2860,13 +2882,9 @@ import { promisify } from "util";
2860
2882
  var execAsync = promisify(exec);
2861
2883
  var GitManager = class {
2862
2884
  repositoryPath;
2863
- authorName;
2864
- authorEmail;
2865
2885
  logger;
2866
2886
  constructor(config) {
2867
2887
  this.repositoryPath = config.repositoryPath;
2868
- this.authorName = config.authorName;
2869
- this.authorEmail = config.authorEmail;
2870
2888
  this.logger = config.logger || new Logger({ debug: false, prefix: "[GitManager]" });
2871
2889
  }
2872
2890
  escapeShellArg(str) {
@@ -3040,11 +3058,6 @@ ${error}`);
3040
3058
  if (options?.allowEmpty) {
3041
3059
  command += " --allow-empty";
3042
3060
  }
3043
- const authorName = options?.authorName || this.authorName;
3044
- const authorEmail = options?.authorEmail || this.authorEmail;
3045
- if (authorName && authorEmail) {
3046
- command += ` --author="${authorName} <${authorEmail}>"`;
3047
- }
3048
3061
  return command;
3049
3062
  }
3050
3063
  async getRemoteUrl() {
@@ -3164,7 +3177,6 @@ ${error}`);
3164
3177
  const message = `\u{1F4CB} Add plan for task: ${taskTitle}
3165
3178
 
3166
3179
  Task ID: ${taskId}
3167
- Generated by PostHog Agent
3168
3180
 
3169
3181
  This commit contains the implementation plan and supporting documentation
3170
3182
  for the task. Review the plan before proceeding with implementation.`;
@@ -3181,8 +3193,7 @@ for the task. Review the plan before proceeding with implementation.`;
3181
3193
  }
3182
3194
  let message = `\u2728 Implement task: ${taskTitle}
3183
3195
 
3184
- Task ID: ${taskId}
3185
- Generated by PostHog Agent`;
3196
+ Task ID: ${taskId}`;
3186
3197
  if (planSummary) {
3187
3198
  message += `
3188
3199
 
@@ -3286,6 +3297,18 @@ This commit implements the changes described in the task plan.`;
3286
3297
  }
3287
3298
  };
3288
3299
 
3300
+ // src/utils/gateway.ts
3301
+ function getLlmGatewayUrl(posthogHost) {
3302
+ const url = new URL(posthogHost);
3303
+ const hostname = url.hostname;
3304
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
3305
+ return `${url.protocol}//localhost:3308`;
3306
+ }
3307
+ const regionMatch = hostname.match(/^(us|eu)\.posthog\.com$/);
3308
+ const region = regionMatch ? regionMatch[1] : "us";
3309
+ return `https://gateway.${region}.posthog.com`;
3310
+ }
3311
+
3289
3312
  // src/posthog-api.ts
3290
3313
  var PostHogAPIClient = class {
3291
3314
  config;
@@ -3298,7 +3321,7 @@ var PostHogAPIClient = class {
3298
3321
  }
3299
3322
  get headers() {
3300
3323
  return {
3301
- Authorization: `Bearer ${this.config.apiKey}`,
3324
+ Authorization: `Bearer ${this.config.getApiKey()}`,
3302
3325
  "Content-Type": "application/json"
3303
3326
  };
3304
3327
  }
@@ -3330,11 +3353,10 @@ var PostHogAPIClient = class {
3330
3353
  return this.baseUrl;
3331
3354
  }
3332
3355
  getApiKey() {
3333
- return this.config.apiKey;
3356
+ return this.config.getApiKey();
3334
3357
  }
3335
3358
  getLlmGatewayUrl() {
3336
- const teamId = this.getTeamId();
3337
- return `${this.baseUrl}/api/projects/${teamId}/llm_gateway`;
3359
+ return getLlmGatewayUrl(this.baseUrl);
3338
3360
  }
3339
3361
  async fetchTask(taskId) {
3340
3362
  const teamId = this.getTeamId();
@@ -3725,14 +3747,16 @@ var PromptBuilder = class {
3725
3747
  if (filePaths.length === 0 || !repositoryPath) {
3726
3748
  return { description, referencedFiles };
3727
3749
  }
3750
+ const successfulPaths = /* @__PURE__ */ new Set();
3728
3751
  for (const filePath of filePaths) {
3729
3752
  const content = await this.readFileContent(repositoryPath, filePath);
3730
3753
  if (content !== null) {
3731
3754
  referencedFiles.push({ path: filePath, content });
3755
+ successfulPaths.add(filePath);
3732
3756
  }
3733
3757
  }
3734
3758
  let processedDescription = description;
3735
- for (const filePath of filePaths) {
3759
+ for (const filePath of successfulPaths) {
3736
3760
  const fileName = filePath.split("/").pop() || filePath;
3737
3761
  processedDescription = processedDescription.replace(
3738
3762
  new RegExp(
@@ -4447,7 +4471,7 @@ Placeholder content for ${file.name}`;
4447
4471
  generatePostHogReadme() {
4448
4472
  return `# PostHog Task Files
4449
4473
 
4450
- This directory contains task-related files generated by the PostHog Agent.
4474
+ This directory contains task-related files.
4451
4475
 
4452
4476
  ## Structure
4453
4477
 
@@ -4463,7 +4487,7 @@ Each task has its own subdirectory: \`.posthog/{task-id}/\`
4463
4487
 
4464
4488
  These files are:
4465
4489
  - Version controlled alongside your code
4466
- - Used by the PostHog Agent for context
4490
+ - Used for task context and planning
4467
4491
  - Available for review in pull requests
4468
4492
  - Organized by task ID for easy reference
4469
4493
 
@@ -4473,10 +4497,6 @@ Customize \`.posthog/.gitignore\` to control which files are committed:
4473
4497
  - Include plans and documentation by default
4474
4498
  - Exclude temporary files and sensitive data
4475
4499
  - Customize based on your team's needs
4476
-
4477
- ---
4478
-
4479
- *Generated by PostHog Agent*
4480
4500
  `;
4481
4501
  }
4482
4502
  };
@@ -5633,8 +5653,8 @@ var Agent = class {
5633
5653
  this.debug = config.debug || false;
5634
5654
  const posthogMcpUrl = config.posthogMcpUrl || process.env.POSTHOG_MCP_URL || "https://mcp.posthog.com/mcp";
5635
5655
  const headers = {};
5636
- if (config.posthogApiKey) {
5637
- headers.Authorization = `Bearer ${config.posthogApiKey}`;
5656
+ if (config.getPosthogApiKey) {
5657
+ headers.Authorization = `Bearer ${config.getPosthogApiKey()}`;
5638
5658
  }
5639
5659
  const defaultMcpServers = {
5640
5660
  posthog: {
@@ -5662,10 +5682,10 @@ var Agent = class {
5662
5682
  logger: this.logger.child("GitManager")
5663
5683
  });
5664
5684
  this.templateManager = new TemplateManager();
5665
- if (config.posthogApiUrl && config.posthogApiKey && config.posthogProjectId) {
5685
+ if (config.posthogApiUrl && config.getPosthogApiKey && config.posthogProjectId) {
5666
5686
  this.posthogAPI = new PostHogAPIClient({
5667
5687
  apiUrl: config.posthogApiUrl,
5668
- apiKey: config.posthogApiKey,
5688
+ getApiKey: config.getPosthogApiKey,
5669
5689
  projectId: config.posthogProjectId
5670
5690
  });
5671
5691
  this.sessionStore = new SessionStore(
@@ -5688,7 +5708,7 @@ var Agent = class {
5688
5708
  this.logger.setDebug(enabled);
5689
5709
  }
5690
5710
  /**
5691
- * Configure LLM gateway environment variables for Claude Code CLI
5711
+ * Configure LLM gateway environment variables for Claude Code CLI.
5692
5712
  */
5693
5713
  async _configureLlmGateway() {
5694
5714
  if (!this.posthogAPI) {
@@ -5700,6 +5720,7 @@ var Agent = class {
5700
5720
  process.env.ANTHROPIC_BASE_URL = gatewayUrl;
5701
5721
  process.env.ANTHROPIC_AUTH_TOKEN = apiKey;
5702
5722
  this.ensureOpenAIGatewayEnv(gatewayUrl, apiKey);
5723
+ this.ensureGeminiGatewayEnv(gatewayUrl, apiKey);
5703
5724
  } catch (error) {
5704
5725
  this.logger.error("Failed to configure LLM gateway", error);
5705
5726
  throw error;
@@ -5883,9 +5904,7 @@ var Agent = class {
5883
5904
  **Description**: ${taskDescription}
5884
5905
 
5885
5906
  ## Changes
5886
- This PR implements the changes described in the task.
5887
-
5888
- Generated by PostHog Agent`;
5907
+ This PR implements the changes described in the task.`;
5889
5908
  const prBody = customBody || defaultBody;
5890
5909
  const prUrl = await this.gitManager.createPullRequest(
5891
5910
  branchName,
@@ -6004,6 +6023,16 @@ Generated by PostHog Agent`;
6004
6023
  process.env.OPENAI_API_KEY = resolvedToken;
6005
6024
  }
6006
6025
  }
6026
+ ensureGeminiGatewayEnv(gatewayUrl, token) {
6027
+ const resolvedGatewayUrl = gatewayUrl || process.env.ANTHROPIC_BASE_URL;
6028
+ const resolvedToken = token || process.env.ANTHROPIC_AUTH_TOKEN;
6029
+ if (resolvedGatewayUrl) {
6030
+ process.env.GEMINI_BASE_URL = resolvedGatewayUrl;
6031
+ }
6032
+ if (resolvedToken) {
6033
+ process.env.GEMINI_API_KEY = resolvedToken;
6034
+ }
6035
+ }
6007
6036
  async runTaskCloud(taskId, taskRunId, options = {}) {
6008
6037
  await this._configureLlmGateway();
6009
6038
  const task = await this.fetchTask(taskId);
@@ -7083,7 +7112,7 @@ ${ignorePattern}
7083
7112
  }
7084
7113
  }
7085
7114
  }
7086
- async createWorktree() {
7115
+ async createWorktree(options) {
7087
7116
  if (!this.usesExternalPath()) {
7088
7117
  await this.ensureArrayDirIgnored();
7089
7118
  }
@@ -7094,7 +7123,7 @@ ${ignorePattern}
7094
7123
  const worktreeName = await this.generateUniqueWorktreeName();
7095
7124
  const worktreePath = this.getWorktreePath(worktreeName);
7096
7125
  const branchName = `array/${worktreeName}`;
7097
- const baseBranch = await this.getDefaultBranch();
7126
+ const baseBranch = options?.baseBranch ?? await this.getDefaultBranch();
7098
7127
  this.logger.info("Creating worktree", {
7099
7128
  worktreeName,
7100
7129
  worktreePath,
@@ -7321,6 +7350,7 @@ export {
7321
7350
  ToolRegistry,
7322
7351
  WorktreeManager,
7323
7352
  createAcpConnection,
7353
+ getLlmGatewayUrl,
7324
7354
  parseAgentEvent,
7325
7355
  parseAgentEvents
7326
7356
  };