@posthog/agent 2.3.703 → 2.3.727

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/types.d.ts CHANGED
@@ -26,7 +26,8 @@ interface Task {
26
26
  slug?: string;
27
27
  title: string;
28
28
  description: string;
29
- origin_product: "error_tracking" | "eval_clusters" | "user_created" | "support_queue" | "session_summaries" | "signal_report";
29
+ origin_product: "error_tracking" | "eval_clusters" | "user_created" | "support_queue" | "session_summaries" | "signal_report" | "slack";
30
+ signal_report?: string | null;
30
31
  github_integration?: number | null;
31
32
  repository: string;
32
33
  json_schema?: Record<string, unknown> | null;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n GitHandoffCheckpoint,\n HandoffLocalGitState as GitHandoffLocalGitState,\n} from \"@posthog/git/handoff\";\n\n/**\n * Stored custom notification following ACP extensibility model.\n * Custom notifications use underscore-prefixed methods (e.g., `_posthog/phase_start`).\n * See: https://agentclientprotocol.com/docs/extensibility\n */\nexport interface StoredNotification {\n type: \"notification\";\n /** When this notification was stored */\n timestamp: string;\n /** JSON-RPC 2.0 notification (no id field = notification, not request) */\n notification: {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n };\n}\n\n/**\n * Type alias for stored log entries.\n */\nexport type StoredEntry = StoredNotification;\n\n// PostHog Task model (matches PostHog Code's OpenAPI schema)\nexport interface Task {\n id: string;\n task_number?: number;\n slug?: string;\n title: string;\n description: string;\n origin_product:\n | \"error_tracking\"\n | \"eval_clusters\"\n | \"user_created\"\n | \"support_queue\"\n | \"session_summaries\"\n | \"signal_report\";\n github_integration?: number | null;\n repository: string; // Format: \"organization/repository\" (e.g., \"posthog/posthog-js\")\n json_schema?: Record<string, unknown> | null; // JSON schema for task output validation\n internal?: boolean;\n created_at: string;\n updated_at: string;\n created_by?: {\n id: number;\n uuid: string;\n distinct_id: string;\n first_name: string;\n email: string;\n };\n latest_run?: TaskRun;\n}\n\n// Log entry structure for TaskRun.log\n\nexport type ArtifactType =\n | \"plan\"\n | \"context\"\n | \"reference\"\n | \"output\"\n | \"artifact\"\n | \"user_attachment\";\n\nexport interface TaskRunArtifact {\n id?: string;\n name: string;\n type: ArtifactType;\n source?: string;\n size?: number;\n content_type?: string;\n storage_path?: string;\n uploaded_at?: string;\n}\n\nexport type TaskRunStatus =\n | \"not_started\"\n | \"queued\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport type TaskRunEnvironment = \"local\" | \"cloud\";\n\n// TaskRun model - represents individual execution runs of tasks\nexport interface TaskRun {\n id: string;\n task: string; // Task ID\n team: number;\n branch: string | null;\n stage: string | null; // Current stage (e.g., 'research', 'plan', 'build')\n environment: TaskRunEnvironment;\n status: TaskRunStatus;\n log_url: string;\n error_message: string | null;\n output: Record<string, unknown> | null; // Structured output (PR URL, commit SHA, etc.)\n state: Record<string, unknown>; // Intermediate run state (defaults to {}, never null)\n artifacts?: TaskRunArtifact[];\n created_at: string;\n updated_at: string;\n completed_at: string | null;\n}\n\nexport interface ProcessSpawnedCallback {\n onProcessSpawned?: (info: {\n pid: number;\n command: string;\n sessionId?: string;\n }) => void;\n onProcessExited?: (pid: number) => void;\n onMcpServersReady?: (serverNames: string[]) => void;\n}\n\nexport interface TaskExecutionOptions {\n repositoryPath?: string;\n adapter?: \"claude\" | \"codex\";\n model?: string;\n gatewayUrl?: string;\n codexBinaryPath?: string;\n instructions?: string;\n processCallbacks?: ProcessSpawnedCallback;\n /** Callback invoked when the agent calls the create_output tool for structured output */\n onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;\n /** Additional directories the agent process can access beyond cwd. */\n additionalDirectories?: string[];\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport type OnLogCallback = (\n level: LogLevel,\n scope: string,\n message: string,\n data?: unknown,\n) => void;\n\nexport interface PostHogAPIConfig {\n apiUrl: string;\n getApiKey: () => string | Promise<string>;\n refreshApiKey?: () => string | Promise<string>;\n projectId: number;\n userAgent?: string;\n}\n\nexport interface OtelTransportConfig {\n /** PostHog ingest host, e.g., \"https://us.i.posthog.com\" */\n host: string;\n /** Project API key */\n apiKey: string;\n /** Override the logs endpoint path (default: /i/v1/logs) */\n logsPath?: string;\n}\n\nexport interface AgentConfig {\n posthog?: PostHogAPIConfig;\n /** OTEL transport config for shipping logs to PostHog Logs */\n otelTransport?: OtelTransportConfig;\n /** Skip session log persistence (e.g. for preview sessions with no real task) */\n skipLogPersistence?: boolean;\n /** Local cache path for instant log loading (e.g., ~/.posthog-code) */\n localCachePath?: string;\n /**\n * Annotate files the agent reads with PostHog enrichment (event volume,\n * flag rollout/staleness, experiment links). Defaults to enabled when\n * `posthog` config is present; set `{ enabled: false }` to opt out.\n */\n enricher?: { enabled?: boolean };\n debug?: boolean;\n onLog?: OnLogCallback;\n}\n\n// Device info for tracking where work happens\nexport interface DeviceInfo {\n type: \"local\" | \"cloud\";\n name?: string;\n}\n\n// Agent execution mode - for tracking interactive vs background runs, when backgrounded an agent will continue working without asking questions\nexport type AgentMode = \"interactive\" | \"background\";\n\n// Git file status codes\nexport type FileStatus = \"A\" | \"M\" | \"D\";\n\nexport interface FileChange {\n path: string;\n status: FileStatus;\n}\n\nexport type HandoffLocalGitState = GitHandoffLocalGitState;\n\nexport interface GitCheckpoint extends GitHandoffCheckpoint {\n artifactPath?: string;\n indexArtifactPath?: string;\n}\n\nexport interface GitCheckpointEvent extends GitCheckpoint {\n device?: DeviceInfo;\n}\n\n/**\n * Keeps the emitted `@posthog/agent/types` entrypoint as a runtime ESM module.\n *\n * `export {}` is stripped by tsup in this package, which leaves `dist/types.js`\n * empty and breaks downstream type resolution for the exported subpath.\n */\nexport const AGENT_TYPES_MODULE = true;\n"],"mappings":";AAiNO,IAAM,qBAAqB;","names":[]}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n GitHandoffCheckpoint,\n HandoffLocalGitState as GitHandoffLocalGitState,\n} from \"@posthog/git/handoff\";\n\n/**\n * Stored custom notification following ACP extensibility model.\n * Custom notifications use underscore-prefixed methods (e.g., `_posthog/phase_start`).\n * See: https://agentclientprotocol.com/docs/extensibility\n */\nexport interface StoredNotification {\n type: \"notification\";\n /** When this notification was stored */\n timestamp: string;\n /** JSON-RPC 2.0 notification (no id field = notification, not request) */\n notification: {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n };\n}\n\n/**\n * Type alias for stored log entries.\n */\nexport type StoredEntry = StoredNotification;\n\n// PostHog Task model (matches PostHog Code's OpenAPI schema)\nexport interface Task {\n id: string;\n task_number?: number;\n slug?: string;\n title: string;\n description: string;\n origin_product:\n | \"error_tracking\"\n | \"eval_clusters\"\n | \"user_created\"\n | \"support_queue\"\n | \"session_summaries\"\n | \"signal_report\"\n | \"slack\";\n signal_report?: string | null; // Inbox report UUID when origin_product is \"signal_report\"\n github_integration?: number | null;\n repository: string; // Format: \"organization/repository\" (e.g., \"posthog/posthog-js\")\n json_schema?: Record<string, unknown> | null; // JSON schema for task output validation\n internal?: boolean;\n created_at: string;\n updated_at: string;\n created_by?: {\n id: number;\n uuid: string;\n distinct_id: string;\n first_name: string;\n email: string;\n };\n latest_run?: TaskRun;\n}\n\n// Log entry structure for TaskRun.log\n\nexport type ArtifactType =\n | \"plan\"\n | \"context\"\n | \"reference\"\n | \"output\"\n | \"artifact\"\n | \"user_attachment\";\n\nexport interface TaskRunArtifact {\n id?: string;\n name: string;\n type: ArtifactType;\n source?: string;\n size?: number;\n content_type?: string;\n storage_path?: string;\n uploaded_at?: string;\n}\n\nexport type TaskRunStatus =\n | \"not_started\"\n | \"queued\"\n | \"in_progress\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\nexport type TaskRunEnvironment = \"local\" | \"cloud\";\n\n// TaskRun model - represents individual execution runs of tasks\nexport interface TaskRun {\n id: string;\n task: string; // Task ID\n team: number;\n branch: string | null;\n stage: string | null; // Current stage (e.g., 'research', 'plan', 'build')\n environment: TaskRunEnvironment;\n status: TaskRunStatus;\n log_url: string;\n error_message: string | null;\n output: Record<string, unknown> | null; // Structured output (PR URL, commit SHA, etc.)\n state: Record<string, unknown>; // Intermediate run state (defaults to {}, never null)\n artifacts?: TaskRunArtifact[];\n created_at: string;\n updated_at: string;\n completed_at: string | null;\n}\n\nexport interface ProcessSpawnedCallback {\n onProcessSpawned?: (info: {\n pid: number;\n command: string;\n sessionId?: string;\n }) => void;\n onProcessExited?: (pid: number) => void;\n onMcpServersReady?: (serverNames: string[]) => void;\n}\n\nexport interface TaskExecutionOptions {\n repositoryPath?: string;\n adapter?: \"claude\" | \"codex\";\n model?: string;\n gatewayUrl?: string;\n codexBinaryPath?: string;\n instructions?: string;\n processCallbacks?: ProcessSpawnedCallback;\n /** Callback invoked when the agent calls the create_output tool for structured output */\n onStructuredOutput?: (output: Record<string, unknown>) => Promise<void>;\n /** Additional directories the agent process can access beyond cwd. */\n additionalDirectories?: string[];\n}\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport type OnLogCallback = (\n level: LogLevel,\n scope: string,\n message: string,\n data?: unknown,\n) => void;\n\nexport interface PostHogAPIConfig {\n apiUrl: string;\n getApiKey: () => string | Promise<string>;\n refreshApiKey?: () => string | Promise<string>;\n projectId: number;\n userAgent?: string;\n}\n\nexport interface OtelTransportConfig {\n /** PostHog ingest host, e.g., \"https://us.i.posthog.com\" */\n host: string;\n /** Project API key */\n apiKey: string;\n /** Override the logs endpoint path (default: /i/v1/logs) */\n logsPath?: string;\n}\n\nexport interface AgentConfig {\n posthog?: PostHogAPIConfig;\n /** OTEL transport config for shipping logs to PostHog Logs */\n otelTransport?: OtelTransportConfig;\n /** Skip session log persistence (e.g. for preview sessions with no real task) */\n skipLogPersistence?: boolean;\n /** Local cache path for instant log loading (e.g., ~/.posthog-code) */\n localCachePath?: string;\n /**\n * Annotate files the agent reads with PostHog enrichment (event volume,\n * flag rollout/staleness, experiment links). Defaults to enabled when\n * `posthog` config is present; set `{ enabled: false }` to opt out.\n */\n enricher?: { enabled?: boolean };\n debug?: boolean;\n onLog?: OnLogCallback;\n}\n\n// Device info for tracking where work happens\nexport interface DeviceInfo {\n type: \"local\" | \"cloud\";\n name?: string;\n}\n\n// Agent execution mode - for tracking interactive vs background runs, when backgrounded an agent will continue working without asking questions\nexport type AgentMode = \"interactive\" | \"background\";\n\n// Git file status codes\nexport type FileStatus = \"A\" | \"M\" | \"D\";\n\nexport interface FileChange {\n path: string;\n status: FileStatus;\n}\n\nexport type HandoffLocalGitState = GitHandoffLocalGitState;\n\nexport interface GitCheckpoint extends GitHandoffCheckpoint {\n artifactPath?: string;\n indexArtifactPath?: string;\n}\n\nexport interface GitCheckpointEvent extends GitCheckpoint {\n device?: DeviceInfo;\n}\n\n/**\n * Keeps the emitted `@posthog/agent/types` entrypoint as a runtime ESM module.\n *\n * `export {}` is stripped by tsup in this package, which leaves `dist/types.js`\n * empty and breaks downstream type resolution for the exported subpath.\n */\nexport const AGENT_TYPES_MODULE = true;\n"],"mappings":";AAmNO,IAAM,qBAAqB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.3.703",
3
+ "version": "2.3.727",
4
4
  "repository": "https://github.com/PostHog/code",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "exports": {
@@ -107,8 +107,8 @@
107
107
  "typescript": "^5.5.0",
108
108
  "vitest": "^2.1.8",
109
109
  "@posthog/shared": "1.0.0",
110
- "@posthog/enricher": "1.0.0",
111
- "@posthog/git": "1.0.0"
110
+ "@posthog/git": "1.0.0",
111
+ "@posthog/enricher": "1.0.0"
112
112
  },
113
113
  "dependencies": {
114
114
  "@agentclientprotocol/sdk": "0.19.0",
@@ -1,10 +1,12 @@
1
1
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import type { Task } from "../types";
2
3
  import { AgentServer } from "./agent-server";
3
4
 
4
5
  interface TestableServer {
5
6
  configureEnvironment(args?: {
6
7
  isInternal?: boolean;
7
- originProduct?: string | null;
8
+ originProduct?: Task["origin_product"] | null;
9
+ signalReportId?: string | null;
8
10
  taskId?: string | null;
9
11
  taskRunId?: string | null;
10
12
  taskUserId?: number | null;
@@ -124,6 +126,7 @@ describe("AgentServer.configureEnvironment", () => {
124
126
  buildServer("background").configureEnvironment({
125
127
  isInternal: true,
126
128
  originProduct: "signal_report",
129
+ signalReportId: "report-123",
127
130
  taskId: "task-abc",
128
131
  taskRunId: "run-xyz",
129
132
  taskUserId: 42,
@@ -133,6 +136,7 @@ describe("AgentServer.configureEnvironment", () => {
133
136
  [
134
137
  "x-posthog-property-task_origin_product: signal_report",
135
138
  "x-posthog-property-task_internal: true",
139
+ "x-posthog-property-signal_report_id: report-123",
136
140
  "x-posthog-property-task_id: task-abc",
137
141
  "x-posthog-property-task_run_id: run-xyz",
138
142
  "x-posthog-property-task_user_id: 42",
@@ -140,6 +144,17 @@ describe("AgentServer.configureEnvironment", () => {
140
144
  );
141
145
  });
142
146
 
147
+ it("omits signal_report_id from ANTHROPIC_CUSTOM_HEADERS for non-report tasks", () => {
148
+ buildServer("background").configureEnvironment({
149
+ isInternal: false,
150
+ taskId: "task-abc",
151
+ });
152
+
153
+ expect(process.env.ANTHROPIC_CUSTOM_HEADERS).not.toContain(
154
+ "signal_report_id",
155
+ );
156
+ });
157
+
143
158
  it("omits optional task metadata from ANTHROPIC_CUSTOM_HEADERS when not provided", () => {
144
159
  buildServer("background").configureEnvironment({ isInternal: false });
145
160
 
@@ -148,6 +163,43 @@ describe("AgentServer.configureEnvironment", () => {
148
163
  );
149
164
  });
150
165
 
166
+ it("tags as slack_app when the task was initiated from Slack", () => {
167
+ buildServer("interactive").configureEnvironment({
168
+ originProduct: "slack",
169
+ });
170
+
171
+ expect(process.env.LLM_GATEWAY_URL).toBe(
172
+ "https://gateway.us.posthog.com/slack_app",
173
+ );
174
+ expect(process.env.ANTHROPIC_BASE_URL).toBe(
175
+ "https://gateway.us.posthog.com/slack_app",
176
+ );
177
+ expect(process.env.OPENAI_BASE_URL).toBe(
178
+ "https://gateway.us.posthog.com/slack_app/v1",
179
+ );
180
+ });
181
+
182
+ it("prefers slack_app over background_agents when both signals are present", () => {
183
+ buildServer("interactive").configureEnvironment({
184
+ isInternal: true,
185
+ originProduct: "slack",
186
+ });
187
+
188
+ expect(process.env.LLM_GATEWAY_URL).toBe(
189
+ "https://gateway.us.posthog.com/slack_app",
190
+ );
191
+ });
192
+
193
+ it("falls back to posthog_code for non-slack origin products", () => {
194
+ buildServer("background").configureEnvironment({
195
+ originProduct: "user_created",
196
+ });
197
+
198
+ expect(process.env.LLM_GATEWAY_URL).toBe(
199
+ "https://gateway.us.posthog.com/posthog_code",
200
+ );
201
+ });
202
+
151
203
  it("respects the LLM_GATEWAY_URL override regardless of internal flag", () => {
152
204
  process.env.LLM_GATEWAY_URL = "http://ngrok.test/proxy";
153
205
 
@@ -43,6 +43,7 @@ import type {
43
43
  GitCheckpointEvent,
44
44
  HandoffLocalGitState,
45
45
  LogLevel,
46
+ Task,
46
47
  TaskRun,
47
48
  TaskRunArtifact,
48
49
  } from "../types";
@@ -867,6 +868,7 @@ export class AgentServer {
867
868
  this.configureEnvironment({
868
869
  isInternal: preTask?.internal === true,
869
870
  originProduct: preTask?.origin_product,
871
+ signalReportId: preTask?.signal_report,
870
872
  taskId: payload.task_id,
871
873
  taskRunId: payload.run_id,
872
874
  taskUserId: payload.user_id,
@@ -1853,12 +1855,14 @@ ${signedCommitInstructions}
1853
1855
  private configureEnvironment({
1854
1856
  isInternal = false,
1855
1857
  originProduct,
1858
+ signalReportId,
1856
1859
  taskId,
1857
1860
  taskRunId,
1858
1861
  taskUserId,
1859
1862
  }: {
1860
1863
  isInternal?: boolean;
1861
- originProduct?: string | null;
1864
+ originProduct?: Task["origin_product"] | null;
1865
+ signalReportId?: string | null;
1862
1866
  taskId?: string | null;
1863
1867
  taskRunId?: string | null;
1864
1868
  taskUserId?: number | null;
@@ -1877,6 +1881,7 @@ ${signedCommitInstructions}
1877
1881
  const customHeaders = buildGatewayPropertyHeaders({
1878
1882
  task_origin_product: originProduct,
1879
1883
  task_internal: isInternal,
1884
+ signal_report_id: signalReportId,
1880
1885
  task_id: taskId,
1881
1886
  task_run_id: taskRunId,
1882
1887
  task_user_id: taskUserId,
package/src/types.ts CHANGED
@@ -38,7 +38,9 @@ export interface Task {
38
38
  | "user_created"
39
39
  | "support_queue"
40
40
  | "session_summaries"
41
- | "signal_report";
41
+ | "signal_report"
42
+ | "slack";
43
+ signal_report?: string | null; // Inbox report UUID when origin_product is "signal_report"
42
44
  github_integration?: number | null;
43
45
  repository: string; // Format: "organization/repository" (e.g., "posthog/posthog-js")
44
46
  json_schema?: Record<string, unknown> | null; // JSON schema for task output validation
@@ -1,4 +1,8 @@
1
- export type GatewayProduct = "posthog_code" | "background_agents" | "signals";
1
+ export type GatewayProduct =
2
+ | "posthog_code"
3
+ | "background_agents"
4
+ | "signals"
5
+ | "slack_app";
2
6
 
3
7
  export function resolveGatewayProduct({
4
8
  isInternal,
@@ -7,6 +11,9 @@ export function resolveGatewayProduct({
7
11
  isInternal?: boolean;
8
12
  originProduct?: string | null;
9
13
  } = {}): GatewayProduct {
14
+ if (originProduct === "slack") {
15
+ return "slack_app";
16
+ }
10
17
  if (isInternal) {
11
18
  return originProduct === "signal_report" ? "signals" : "background_agents";
12
19
  }