@posthog/agent 2.3.341 → 2.3.346
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 +29 -26
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.d.ts +5 -3
- package/dist/posthog-api.js +9 -20
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +7 -0
- package/dist/server/agent-server.js +185 -38
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +185 -38
- package/dist/server/bin.cjs.map +1 -1
- package/dist/types.d.ts +3 -1
- package/package.json +1 -1
- package/src/adapters/claude/conversion/acp-to-sdk.test.ts +49 -0
- package/src/adapters/claude/conversion/acp-to-sdk.ts +23 -6
- package/src/posthog-api.test.ts +32 -0
- package/src/posthog-api.ts +13 -30
- package/src/server/agent-server.test.ts +96 -0
- package/src/server/agent-server.ts +207 -11
- package/src/server/schemas.test.ts +10 -0
- package/src/server/schemas.ts +25 -6
- package/src/test/mocks/msw-handlers.ts +4 -1
- package/src/types.ts +4 -1
package/dist/posthog-api.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ interface TaskArtifactUploadPayload {
|
|
|
10
10
|
content: string;
|
|
11
11
|
content_type?: string;
|
|
12
12
|
}
|
|
13
|
-
type TaskRunUpdate = Partial<Pick<TaskRun, "status" | "branch" | "stage" | "error_message" | "output" | "state" | "environment"
|
|
13
|
+
type TaskRunUpdate = Partial<Pick<TaskRun, "status" | "branch" | "stage" | "error_message" | "output" | "state" | "environment">> & {
|
|
14
|
+
state_remove_keys?: string[];
|
|
15
|
+
};
|
|
14
16
|
declare class PostHogAPIClient {
|
|
15
17
|
private config;
|
|
16
18
|
constructor(config: PostHogAPIConfig);
|
|
@@ -31,10 +33,10 @@ declare class PostHogAPIClient {
|
|
|
31
33
|
appendTaskRunLog(taskId: string, runId: string, entries: StoredEntry[]): Promise<TaskRun>;
|
|
32
34
|
relayMessage(taskId: string, runId: string, text: string): Promise<void>;
|
|
33
35
|
uploadTaskArtifacts(taskId: string, runId: string, artifacts: TaskArtifactUploadPayload[]): Promise<TaskRunArtifact[]>;
|
|
34
|
-
getArtifactPresignedUrl(taskId: string, runId: string, storagePath: string): Promise<string | null>;
|
|
35
36
|
/**
|
|
36
37
|
* Download artifact content by storage path
|
|
37
|
-
*
|
|
38
|
+
* Streams the file through the PostHog backend so the sandbox does not need
|
|
39
|
+
* direct access to object storage.
|
|
38
40
|
*/
|
|
39
41
|
downloadArtifact(taskId: string, runId: string, storagePath: string): Promise<ArrayBuffer | null>;
|
|
40
42
|
/**
|
package/dist/posthog-api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@posthog/agent",
|
|
4
|
-
version: "2.3.
|
|
4
|
+
version: "2.3.346",
|
|
5
5
|
repository: "https://github.com/PostHog/code",
|
|
6
6
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
7
7
|
exports: {
|
|
@@ -282,32 +282,21 @@ var PostHogAPIClient = class {
|
|
|
282
282
|
);
|
|
283
283
|
return response.artifacts ?? [];
|
|
284
284
|
}
|
|
285
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Download artifact content by storage path
|
|
287
|
+
* Streams the file through the PostHog backend so the sandbox does not need
|
|
288
|
+
* direct access to object storage.
|
|
289
|
+
*/
|
|
290
|
+
async downloadArtifact(taskId, runId, storagePath) {
|
|
286
291
|
const teamId = this.getTeamId();
|
|
287
292
|
try {
|
|
288
|
-
const response = await this.
|
|
289
|
-
`/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/
|
|
293
|
+
const response = await this.performRequestWithRetry(
|
|
294
|
+
`/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/download/`,
|
|
290
295
|
{
|
|
291
296
|
method: "POST",
|
|
292
297
|
body: JSON.stringify({ storage_path: storagePath })
|
|
293
298
|
}
|
|
294
299
|
);
|
|
295
|
-
return response.url;
|
|
296
|
-
} catch {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Download artifact content by storage path
|
|
302
|
-
* Gets a presigned URL and fetches the content
|
|
303
|
-
*/
|
|
304
|
-
async downloadArtifact(taskId, runId, storagePath) {
|
|
305
|
-
const url = await this.getArtifactPresignedUrl(taskId, runId, storagePath);
|
|
306
|
-
if (!url) {
|
|
307
|
-
return null;
|
|
308
|
-
}
|
|
309
|
-
try {
|
|
310
|
-
const response = await fetch(url);
|
|
311
300
|
if (!response.ok) {
|
|
312
301
|
throw new Error(`Failed to download artifact: ${response.status}`);
|
|
313
302
|
}
|
package/dist/posthog-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/utils/gateway.ts","../src/posthog-api.ts"],"sourcesContent":["{\n \"name\": \"@posthog/agent\",\n \"version\": \"2.3.341\",\n \"repository\": \"https://github.com/PostHog/code\",\n \"description\": \"TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/agent.d.ts\",\n \"import\": \"./dist/agent.js\"\n },\n \"./gateway-models\": {\n \"types\": \"./dist/gateway-models.d.ts\",\n \"import\": \"./dist/gateway-models.js\"\n },\n \"./posthog-api\": {\n \"types\": \"./dist/posthog-api.d.ts\",\n \"import\": \"./dist/posthog-api.js\"\n },\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"import\": \"./dist/types.js\"\n },\n \"./adapters/claude/questions/utils\": {\n \"types\": \"./dist/adapters/claude/questions/utils.d.ts\",\n \"import\": \"./dist/adapters/claude/questions/utils.js\"\n },\n \"./adapters/claude/permissions/permission-options\": {\n \"types\": \"./dist/adapters/claude/permissions/permission-options.d.ts\",\n \"import\": \"./dist/adapters/claude/permissions/permission-options.js\"\n },\n \"./adapters/claude/tools\": {\n \"types\": \"./dist/adapters/claude/tools.d.ts\",\n \"import\": \"./dist/adapters/claude/tools.js\"\n },\n \"./adapters/claude/conversion/tool-use-to-acp\": {\n \"types\": \"./dist/adapters/claude/conversion/tool-use-to-acp.d.ts\",\n \"import\": \"./dist/adapters/claude/conversion/tool-use-to-acp.js\"\n },\n \"./adapters/claude/session/jsonl-hydration\": {\n \"types\": \"./dist/adapters/claude/session/jsonl-hydration.d.ts\",\n \"import\": \"./dist/adapters/claude/session/jsonl-hydration.js\"\n },\n \"./adapters/claude/session/models\": {\n \"types\": \"./dist/adapters/claude/session/models.d.ts\",\n \"import\": \"./dist/adapters/claude/session/models.js\"\n },\n \"./adapters/reasoning-effort\": {\n \"types\": \"./dist/adapters/reasoning-effort.d.ts\",\n \"import\": \"./dist/adapters/reasoning-effort.js\"\n },\n \"./execution-mode\": {\n \"types\": \"./dist/execution-mode.d.ts\",\n \"import\": \"./dist/execution-mode.js\"\n },\n \"./server\": {\n \"types\": \"./dist/server/agent-server.d.ts\",\n \"import\": \"./dist/server/agent-server.js\"\n }\n },\n \"bin\": {\n \"agent-server\": \"./dist/server/bin.cjs\"\n },\n \"type\": \"module\",\n \"keywords\": [\n \"posthog\",\n \"claude\",\n \"agent\",\n \"ai\",\n \"git\",\n \"typescript\"\n ],\n \"author\": \"PostHog\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"scripts\": {\n \"build\": \"node ../../scripts/rimraf.mjs dist && tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm exec tsc --noEmit\",\n \"prepublishOnly\": \"pnpm run build\",\n \"clean\": \"node ../../scripts/rimraf.mjs dist .turbo\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"devDependencies\": {\n \"@posthog/shared\": \"workspace:*\",\n \"@posthog/git\": \"workspace:*\",\n \"@types/bun\": \"latest\",\n \"@types/tar\": \"^6.1.13\",\n \"msw\": \"^2.12.7\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.5.0\",\n \"vitest\": \"^2.1.8\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"0.19.0\",\n \"ajv\": \"^8.17.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.112\",\n \"@anthropic-ai/sdk\": \"0.89.0\",\n \"@hono/node-server\": \"^1.19.9\",\n \"@opentelemetry/api-logs\": \"^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"^0.208.0\",\n \"@opentelemetry/resources\": \"^2.0.0\",\n \"@opentelemetry/sdk-logs\": \"^0.208.0\",\n \"@opentelemetry/semantic-conventions\": \"^1.28.0\",\n \"@posthog/enricher\": \"workspace:*\",\n \"@types/jsonwebtoken\": \"^9.0.10\",\n \"commander\": \"^14.0.2\",\n \"hono\": \"^4.11.7\",\n \"jsonwebtoken\": \"^9.0.2\",\n \"minimatch\": \"^10.0.3\",\n \"tar\": \"^7.5.0\",\n \"uuid\": \"13.0.0\",\n \"yoga-wasm-web\": \"^0.3.3\",\n \"zod\": \"^4.2.0\"\n },\n \"files\": [\n \"dist/**/*\",\n \"src/**/*\",\n \"README.md\",\n \"CLAUDE.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","export type GatewayProduct = \"posthog_code\" | \"background_agents\";\n\nfunction getGatewayBaseUrl(posthogHost: string): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308`;\n }\n\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308`;\n }\n\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com`;\n}\n\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/${product}`;\n}\n\nexport function getGatewayUsageUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/v1/usage/${product}`;\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\nimport type {\n ArtifactType,\n PostHogAPIConfig,\n StoredEntry,\n Task,\n TaskRun,\n TaskRunArtifact,\n} from \"./types\";\nimport { getGatewayUsageUrl, getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { getGatewayUsageUrl, getLlmGatewayUrl };\n\nconst DEFAULT_USER_AGENT = `posthog/agent.hog.dev; version: ${packageJson.version}`;\n\nexport interface TaskArtifactUploadPayload {\n name: string;\n type: ArtifactType;\n content: string;\n content_type?: string;\n}\n\nexport type TaskRunUpdate = Partial<\n Pick<\n TaskRun,\n | \"status\"\n | \"branch\"\n | \"stage\"\n | \"error_message\"\n | \"output\"\n | \"state\"\n | \"environment\"\n >\n>;\n\nexport class PostHogAPIClient {\n private config: PostHogAPIConfig;\n\n constructor(config: PostHogAPIConfig) {\n this.config = config;\n }\n\n private get baseUrl(): string {\n const host = this.config.apiUrl.endsWith(\"/\")\n ? this.config.apiUrl.slice(0, -1)\n : this.config.apiUrl;\n return host;\n }\n\n private isAuthFailure(status: number): boolean {\n return status === 401 || status === 403;\n }\n\n private async resolveApiKey(forceRefresh = false): Promise<string> {\n if (forceRefresh && this.config.refreshApiKey) {\n return this.config.refreshApiKey();\n }\n\n return this.config.getApiKey();\n }\n\n private async buildHeaders(\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Headers> {\n const headers = new Headers(options.headers);\n headers.set(\n \"Authorization\",\n `Bearer ${await this.resolveApiKey(forceRefresh)}`,\n );\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"User-Agent\", this.config.userAgent ?? DEFAULT_USER_AGENT);\n return headers;\n }\n\n private async performRequest(\n endpoint: string,\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Response> {\n const url = `${this.baseUrl}${endpoint}`;\n\n return fetch(url, {\n ...options,\n headers: await this.buildHeaders(options, forceRefresh),\n });\n }\n\n private async performRequestWithRetry(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<Response> {\n let response = await this.performRequest(endpoint, options);\n\n if (!response.ok && this.isAuthFailure(response.status)) {\n response = await this.performRequest(endpoint, options, true);\n }\n\n return response;\n }\n\n private async apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const response = await this.performRequestWithRetry(endpoint, options);\n\n if (!response.ok) {\n let errorMessage: string;\n try {\n const errorResponse = await response.json();\n errorMessage = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;\n } catch {\n errorMessage = `Failed request: [${response.status}] ${response.statusText}`;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n private getTeamId(): number {\n return this.config.projectId;\n }\n\n async getApiKey(forceRefresh = false): Promise<string> {\n return this.resolveApiKey(forceRefresh);\n }\n\n getLlmGatewayUrl(): string {\n return getLlmGatewayUrl(this.baseUrl);\n }\n\n async getTask(taskId: string): Promise<Task> {\n const teamId = this.getTeamId();\n return this.apiRequest<Task>(`/api/projects/${teamId}/tasks/${taskId}/`);\n }\n\n async getTaskRun(taskId: string, runId: string): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n );\n }\n\n async updateTaskRun(\n taskId: string,\n runId: string,\n payload: TaskRunUpdate,\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(payload),\n },\n );\n }\n\n async setTaskRunOutput(\n taskId: string,\n runId: string,\n output: Record<string, unknown>,\n ): Promise<TaskRun> {\n return this.apiRequest(\n `/api/projects/${this.getTeamId()}/tasks/${taskId}/runs/${runId}/set_output/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(output),\n },\n );\n }\n\n async appendTaskRunLog(\n taskId: string,\n runId: string,\n entries: StoredEntry[],\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/append_log/`,\n {\n method: \"POST\",\n body: JSON.stringify({ entries }),\n },\n );\n }\n\n async relayMessage(\n taskId: string,\n runId: string,\n text: string,\n ): Promise<void> {\n const teamId = this.getTeamId();\n await this.apiRequest<{ status: string }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/relay_message/`,\n {\n method: \"POST\",\n body: JSON.stringify({ text }),\n },\n );\n }\n\n async uploadTaskArtifacts(\n taskId: string,\n runId: string,\n artifacts: TaskArtifactUploadPayload[],\n ): Promise<TaskRunArtifact[]> {\n if (!artifacts.length) {\n return [];\n }\n\n const teamId = this.getTeamId();\n const response = await this.apiRequest<{ artifacts: TaskRunArtifact[] }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/`,\n {\n method: \"POST\",\n body: JSON.stringify({ artifacts }),\n },\n );\n\n return response.artifacts ?? [];\n }\n\n async getArtifactPresignedUrl(\n taskId: string,\n runId: string,\n storagePath: string,\n ): Promise<string | null> {\n const teamId = this.getTeamId();\n try {\n const response = await this.apiRequest<{\n url: string;\n expires_in: number;\n }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/presign/`,\n {\n method: \"POST\",\n body: JSON.stringify({ storage_path: storagePath }),\n },\n );\n return response.url;\n } catch {\n return null;\n }\n }\n\n /**\n * Download artifact content by storage path\n * Gets a presigned URL and fetches the content\n */\n async downloadArtifact(\n taskId: string,\n runId: string,\n storagePath: string,\n ): Promise<ArrayBuffer | null> {\n const url = await this.getArtifactPresignedUrl(taskId, runId, storagePath);\n if (!url) {\n return null;\n }\n\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download artifact: ${response.status}`);\n }\n return response.arrayBuffer();\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch logs for a task run via the logs API endpoint\n * @param taskRun - The task run to fetch logs for\n * @returns Array of stored entries, or empty array if no logs available\n */\n async fetchTaskRunLogs(taskRun: TaskRun): Promise<StoredEntry[]> {\n const teamId = this.getTeamId();\n const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;\n\n try {\n const response = await this.performRequestWithRetry(endpoint);\n\n if (!response.ok) {\n if (response.status === 404) {\n return [];\n }\n throw new Error(\n `Failed to fetch logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const content = await response.text();\n\n if (!content.trim()) {\n return [];\n }\n\n // Parse newline-delimited JSON\n return content\n .trim()\n .split(\"\\n\")\n .map((line) => JSON.parse(line) as StoredEntry);\n } catch (error) {\n throw new Error(\n `Failed to fetch task run logs: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n"],"mappings":";AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,YAAc;AAAA,EACd,aAAe;AAAA,EACf,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,MACf,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,qCAAqC;AAAA,MACnC,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,oDAAoD;AAAA,MAClD,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,2BAA2B;AAAA,MACzB,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,gDAAgD;AAAA,MAC9C,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,6CAA6C;AAAA,MAC3C,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,oCAAoC;AAAA,MAClC,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,+BAA+B;AAAA,MAC7B,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,MACV,OAAS;AAAA,MACT,QAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,KAAO;AAAA,IACL,gBAAgB;AAAA,EAClB;AAAA,EACA,MAAQ;AAAA,EACR,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAU;AAAA,EACV,SAAW;AAAA,EACX,SAAW;AAAA,IACT,OAAS;AAAA,IACT,KAAO;AAAA,IACP,MAAQ;AAAA,IACR,cAAc;AAAA,IACd,WAAa;AAAA,IACb,gBAAkB;AAAA,IAClB,OAAS;AAAA,EACX;AAAA,EACA,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,iBAAmB;AAAA,IACjB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,cAAc;AAAA,IACd,KAAO;AAAA,IACP,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,YAAc;AAAA,IACd,QAAU;AAAA,EACZ;AAAA,EACA,cAAgB;AAAA,IACd,4BAA4B;AAAA,IAC5B,KAAO;AAAA,IACP,kCAAkC;AAAA,IAClC,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,2BAA2B;AAAA,IAC3B,0CAA0C;AAAA,IAC1C,4BAA4B;AAAA,IAC5B,2BAA2B;AAAA,IAC3B,uCAAuC;AAAA,IACvC,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,cAAgB;AAAA,IAChB,WAAa;AAAA,IACb,KAAO;AAAA,IACP,MAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,KAAO;AAAA,EACT;AAAA,EACA,OAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,eAAiB;AAAA,IACf,QAAU;AAAA,EACZ;AACF;;;ACjIA,SAAS,kBAAkB,aAA6B;AACtD,QAAM,MAAM,IAAI,IAAI,WAAW;AAC/B,QAAM,WAAW,IAAI;AAErB,MAAI,aAAa,eAAe,aAAa,aAAa;AACxD,WAAO,GAAG,IAAI,QAAQ;AAAA,EACxB;AAEA,MAAI,aAAa,wBAAwB;AACvC,WAAO,GAAG,IAAI,QAAQ;AAAA,EACxB;AAEA,QAAM,SAAS,SAAS,MAAM,yBAAyB,IAAI,CAAC,KAAK;AACjE,SAAO,mBAAmB,MAAM;AAClC;AAEO,SAAS,iBACd,aACA,UAA0B,gBAClB;AACR,SAAO,GAAG,kBAAkB,WAAW,CAAC,IAAI,OAAO;AACrD;AAEO,SAAS,mBACd,aACA,UAA0B,gBAClB;AACR,SAAO,GAAG,kBAAkB,WAAW,CAAC,aAAa,OAAO;AAC9D;;;ACjBA,IAAM,qBAAqB,mCAAmC,gBAAY,OAAO;AAsB1E,IAAM,mBAAN,MAAuB;AAAA,EACpB;AAAA,EAER,YAAY,QAA0B;AACpC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAY,UAAkB;AAC5B,UAAM,OAAO,KAAK,OAAO,OAAO,SAAS,GAAG,IACxC,KAAK,OAAO,OAAO,MAAM,GAAG,EAAE,IAC9B,KAAK,OAAO;AAChB,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,QAAyB;AAC7C,WAAO,WAAW,OAAO,WAAW;AAAA,EACtC;AAAA,EAEA,MAAc,cAAc,eAAe,OAAwB;AACjE,QAAI,gBAAgB,KAAK,OAAO,eAAe;AAC7C,aAAO,KAAK,OAAO,cAAc;AAAA,IACnC;AAEA,WAAO,KAAK,OAAO,UAAU;AAAA,EAC/B;AAAA,EAEA,MAAc,aACZ,SACA,eAAe,OACG;AAClB,UAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,YAAQ;AAAA,MACN;AAAA,MACA,UAAU,MAAM,KAAK,cAAc,YAAY,CAAC;AAAA,IAClD;AACA,YAAQ,IAAI,gBAAgB,kBAAkB;AAC9C,YAAQ,IAAI,cAAc,KAAK,OAAO,aAAa,kBAAkB;AACrE,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eACZ,UACA,SACA,eAAe,OACI;AACnB,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AAEtC,WAAO,MAAM,KAAK;AAAA,MAChB,GAAG;AAAA,MACH,SAAS,MAAM,KAAK,aAAa,SAAS,YAAY;AAAA,IACxD,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,wBACZ,UACA,UAAuB,CAAC,GACL;AACnB,QAAI,WAAW,MAAM,KAAK,eAAe,UAAU,OAAO;AAE1D,QAAI,CAAC,SAAS,MAAM,KAAK,cAAc,SAAS,MAAM,GAAG;AACvD,iBAAW,MAAM,KAAK,eAAe,UAAU,SAAS,IAAI;AAAA,IAC9D;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,WACZ,UACA,UAAuB,CAAC,GACZ;AACZ,UAAM,WAAW,MAAM,KAAK,wBAAwB,UAAU,OAAO;AAErE,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI;AACJ,UAAI;AACF,cAAM,gBAAgB,MAAM,SAAS,KAAK;AAC1C,uBAAe,oBAAoB,SAAS,MAAM,KAAK,KAAK,UAAU,aAAa,CAAC;AAAA,MACtF,QAAQ;AACN,uBAAe,oBAAoB,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,MAC5E;AACA,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEQ,YAAoB;AAC1B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,MAAM,UAAU,eAAe,OAAwB;AACrD,WAAO,KAAK,cAAc,YAAY;AAAA,EACxC;AAAA,EAEA,mBAA2B;AACzB,WAAO,iBAAiB,KAAK,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,QAAQ,QAA+B;AAC3C,UAAM,SAAS,KAAK,UAAU;AAC9B,WAAO,KAAK,WAAiB,iBAAiB,MAAM,UAAU,MAAM,GAAG;AAAA,EACzE;AAAA,EAEA,MAAM,WAAW,QAAgB,OAAiC;AAChE,UAAM,SAAS,KAAK,UAAU;AAC9B,WAAO,KAAK;AAAA,MACV,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,QACA,OACA,SACkB;AAClB,UAAM,SAAS,KAAK,UAAU;AAC9B,WAAO,KAAK;AAAA,MACV,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACrD;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,QACA,OACA,QACkB;AAClB,WAAO,KAAK;AAAA,MACV,iBAAiB,KAAK,UAAU,CAAC,UAAU,MAAM,SAAS,KAAK;AAAA,MAC/D;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,QACA,OACA,SACkB;AAClB,UAAM,SAAS,KAAK,UAAU;AAC9B,WAAO,KAAK;AAAA,MACV,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACrD;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,QACA,OACA,MACe;AACf,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,KAAK;AAAA,MACT,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACrD;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,oBACJ,QACA,OACA,WAC4B;AAC5B,QAAI,CAAC,UAAU,QAAQ;AACrB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACrD;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,EAAE,UAAU,CAAC;AAAA,MACpC;AAAA,IACF;AAEA,WAAO,SAAS,aAAa,CAAC;AAAA,EAChC;AAAA,EAEA,MAAM,wBACJ,QACA,OACA,aACwB;AACxB,UAAM,SAAS,KAAK,UAAU;AAC9B,QAAI;AACF,YAAM,WAAW,MAAM,KAAK;AAAA,QAI1B,iBAAiB,MAAM,UAAU,MAAM,SAAS,KAAK;AAAA,QACrD;AAAA,UACE,QAAQ;AAAA,UACR,MAAM,KAAK,UAAU,EAAE,cAAc,YAAY,CAAC;AAAA,QACpD;AAAA,MACF;AACA,aAAO,SAAS;AAAA,IAClB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBACJ,QACA,OACA,aAC6B;AAC7B,UAAM,MAAM,MAAM,KAAK,wBAAwB,QAAQ,OAAO,WAAW;AACzE,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,gCAAgC,SAAS,MAAM,EAAE;AAAA,MACnE;AACA,aAAO,SAAS,YAAY;AAAA,IAC9B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAiB,SAA0C;AAC/D,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,WAAW,iBAAiB,MAAM,UAAU,QAAQ,IAAI,SAAS,QAAQ,EAAE;AAEjF,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,wBAAwB,QAAQ;AAE5D,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,KAAK;AAC3B,iBAAO,CAAC;AAAA,QACV;AACA,cAAM,IAAI;AAAA,UACR,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QACjE;AAAA,MACF;AAEA,YAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,UAAI,CAAC,QAAQ,KAAK,GAAG;AACnB,eAAO,CAAC;AAAA,MACV;AAGA,aAAO,QACJ,KAAK,EACL,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAAgB;AAAA,IAClD,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/utils/gateway.ts","../src/posthog-api.ts"],"sourcesContent":["{\n \"name\": \"@posthog/agent\",\n \"version\": \"2.3.346\",\n \"repository\": \"https://github.com/PostHog/code\",\n \"description\": \"TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./agent\": {\n \"types\": \"./dist/agent.d.ts\",\n \"import\": \"./dist/agent.js\"\n },\n \"./gateway-models\": {\n \"types\": \"./dist/gateway-models.d.ts\",\n \"import\": \"./dist/gateway-models.js\"\n },\n \"./posthog-api\": {\n \"types\": \"./dist/posthog-api.d.ts\",\n \"import\": \"./dist/posthog-api.js\"\n },\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"import\": \"./dist/types.js\"\n },\n \"./adapters/claude/questions/utils\": {\n \"types\": \"./dist/adapters/claude/questions/utils.d.ts\",\n \"import\": \"./dist/adapters/claude/questions/utils.js\"\n },\n \"./adapters/claude/permissions/permission-options\": {\n \"types\": \"./dist/adapters/claude/permissions/permission-options.d.ts\",\n \"import\": \"./dist/adapters/claude/permissions/permission-options.js\"\n },\n \"./adapters/claude/tools\": {\n \"types\": \"./dist/adapters/claude/tools.d.ts\",\n \"import\": \"./dist/adapters/claude/tools.js\"\n },\n \"./adapters/claude/conversion/tool-use-to-acp\": {\n \"types\": \"./dist/adapters/claude/conversion/tool-use-to-acp.d.ts\",\n \"import\": \"./dist/adapters/claude/conversion/tool-use-to-acp.js\"\n },\n \"./adapters/claude/session/jsonl-hydration\": {\n \"types\": \"./dist/adapters/claude/session/jsonl-hydration.d.ts\",\n \"import\": \"./dist/adapters/claude/session/jsonl-hydration.js\"\n },\n \"./adapters/claude/session/models\": {\n \"types\": \"./dist/adapters/claude/session/models.d.ts\",\n \"import\": \"./dist/adapters/claude/session/models.js\"\n },\n \"./adapters/reasoning-effort\": {\n \"types\": \"./dist/adapters/reasoning-effort.d.ts\",\n \"import\": \"./dist/adapters/reasoning-effort.js\"\n },\n \"./execution-mode\": {\n \"types\": \"./dist/execution-mode.d.ts\",\n \"import\": \"./dist/execution-mode.js\"\n },\n \"./server\": {\n \"types\": \"./dist/server/agent-server.d.ts\",\n \"import\": \"./dist/server/agent-server.js\"\n }\n },\n \"bin\": {\n \"agent-server\": \"./dist/server/bin.cjs\"\n },\n \"type\": \"module\",\n \"keywords\": [\n \"posthog\",\n \"claude\",\n \"agent\",\n \"ai\",\n \"git\",\n \"typescript\"\n ],\n \"author\": \"PostHog\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"scripts\": {\n \"build\": \"node ../../scripts/rimraf.mjs dist && tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm exec tsc --noEmit\",\n \"prepublishOnly\": \"pnpm run build\",\n \"clean\": \"node ../../scripts/rimraf.mjs dist .turbo\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"devDependencies\": {\n \"@posthog/shared\": \"workspace:*\",\n \"@posthog/git\": \"workspace:*\",\n \"@types/bun\": \"latest\",\n \"@types/tar\": \"^6.1.13\",\n \"msw\": \"^2.12.7\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.5.0\",\n \"vitest\": \"^2.1.8\"\n },\n \"dependencies\": {\n \"@agentclientprotocol/sdk\": \"0.19.0\",\n \"ajv\": \"^8.17.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.112\",\n \"@anthropic-ai/sdk\": \"0.89.0\",\n \"@hono/node-server\": \"^1.19.9\",\n \"@opentelemetry/api-logs\": \"^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"^0.208.0\",\n \"@opentelemetry/resources\": \"^2.0.0\",\n \"@opentelemetry/sdk-logs\": \"^0.208.0\",\n \"@opentelemetry/semantic-conventions\": \"^1.28.0\",\n \"@posthog/enricher\": \"workspace:*\",\n \"@types/jsonwebtoken\": \"^9.0.10\",\n \"commander\": \"^14.0.2\",\n \"hono\": \"^4.11.7\",\n \"jsonwebtoken\": \"^9.0.2\",\n \"minimatch\": \"^10.0.3\",\n \"tar\": \"^7.5.0\",\n \"uuid\": \"13.0.0\",\n \"yoga-wasm-web\": \"^0.3.3\",\n \"zod\": \"^4.2.0\"\n },\n \"files\": [\n \"dist/**/*\",\n \"src/**/*\",\n \"README.md\",\n \"CLAUDE.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","export type GatewayProduct = \"posthog_code\" | \"background_agents\";\n\nfunction getGatewayBaseUrl(posthogHost: string): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308`;\n }\n\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308`;\n }\n\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com`;\n}\n\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/${product}`;\n}\n\nexport function getGatewayUsageUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n return `${getGatewayBaseUrl(posthogHost)}/v1/usage/${product}`;\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\nimport type {\n ArtifactType,\n PostHogAPIConfig,\n StoredEntry,\n Task,\n TaskRun,\n TaskRunArtifact,\n} from \"./types\";\nimport { getGatewayUsageUrl, getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { getGatewayUsageUrl, getLlmGatewayUrl };\n\nconst DEFAULT_USER_AGENT = `posthog/agent.hog.dev; version: ${packageJson.version}`;\n\nexport interface TaskArtifactUploadPayload {\n name: string;\n type: ArtifactType;\n content: string;\n content_type?: string;\n}\n\nexport type TaskRunUpdate = Partial<\n Pick<\n TaskRun,\n | \"status\"\n | \"branch\"\n | \"stage\"\n | \"error_message\"\n | \"output\"\n | \"state\"\n | \"environment\"\n >\n> & {\n state_remove_keys?: string[];\n};\n\nexport class PostHogAPIClient {\n private config: PostHogAPIConfig;\n\n constructor(config: PostHogAPIConfig) {\n this.config = config;\n }\n\n private get baseUrl(): string {\n const host = this.config.apiUrl.endsWith(\"/\")\n ? this.config.apiUrl.slice(0, -1)\n : this.config.apiUrl;\n return host;\n }\n\n private isAuthFailure(status: number): boolean {\n return status === 401 || status === 403;\n }\n\n private async resolveApiKey(forceRefresh = false): Promise<string> {\n if (forceRefresh && this.config.refreshApiKey) {\n return this.config.refreshApiKey();\n }\n\n return this.config.getApiKey();\n }\n\n private async buildHeaders(\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Headers> {\n const headers = new Headers(options.headers);\n headers.set(\n \"Authorization\",\n `Bearer ${await this.resolveApiKey(forceRefresh)}`,\n );\n headers.set(\"Content-Type\", \"application/json\");\n headers.set(\"User-Agent\", this.config.userAgent ?? DEFAULT_USER_AGENT);\n return headers;\n }\n\n private async performRequest(\n endpoint: string,\n options: RequestInit,\n forceRefresh = false,\n ): Promise<Response> {\n const url = `${this.baseUrl}${endpoint}`;\n\n return fetch(url, {\n ...options,\n headers: await this.buildHeaders(options, forceRefresh),\n });\n }\n\n private async performRequestWithRetry(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<Response> {\n let response = await this.performRequest(endpoint, options);\n\n if (!response.ok && this.isAuthFailure(response.status)) {\n response = await this.performRequest(endpoint, options, true);\n }\n\n return response;\n }\n\n private async apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const response = await this.performRequestWithRetry(endpoint, options);\n\n if (!response.ok) {\n let errorMessage: string;\n try {\n const errorResponse = await response.json();\n errorMessage = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;\n } catch {\n errorMessage = `Failed request: [${response.status}] ${response.statusText}`;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n private getTeamId(): number {\n return this.config.projectId;\n }\n\n async getApiKey(forceRefresh = false): Promise<string> {\n return this.resolveApiKey(forceRefresh);\n }\n\n getLlmGatewayUrl(): string {\n return getLlmGatewayUrl(this.baseUrl);\n }\n\n async getTask(taskId: string): Promise<Task> {\n const teamId = this.getTeamId();\n return this.apiRequest<Task>(`/api/projects/${teamId}/tasks/${taskId}/`);\n }\n\n async getTaskRun(taskId: string, runId: string): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n );\n }\n\n async updateTaskRun(\n taskId: string,\n runId: string,\n payload: TaskRunUpdate,\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(payload),\n },\n );\n }\n\n async setTaskRunOutput(\n taskId: string,\n runId: string,\n output: Record<string, unknown>,\n ): Promise<TaskRun> {\n return this.apiRequest(\n `/api/projects/${this.getTeamId()}/tasks/${taskId}/runs/${runId}/set_output/`,\n {\n method: \"PATCH\",\n body: JSON.stringify(output),\n },\n );\n }\n\n async appendTaskRunLog(\n taskId: string,\n runId: string,\n entries: StoredEntry[],\n ): Promise<TaskRun> {\n const teamId = this.getTeamId();\n return this.apiRequest<TaskRun>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/append_log/`,\n {\n method: \"POST\",\n body: JSON.stringify({ entries }),\n },\n );\n }\n\n async relayMessage(\n taskId: string,\n runId: string,\n text: string,\n ): Promise<void> {\n const teamId = this.getTeamId();\n await this.apiRequest<{ status: string }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/relay_message/`,\n {\n method: \"POST\",\n body: JSON.stringify({ text }),\n },\n );\n }\n\n async uploadTaskArtifacts(\n taskId: string,\n runId: string,\n artifacts: TaskArtifactUploadPayload[],\n ): Promise<TaskRunArtifact[]> {\n if (!artifacts.length) {\n return [];\n }\n\n const teamId = this.getTeamId();\n const response = await this.apiRequest<{ artifacts: TaskRunArtifact[] }>(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/`,\n {\n method: \"POST\",\n body: JSON.stringify({ artifacts }),\n },\n );\n\n return response.artifacts ?? [];\n }\n\n /**\n * Download artifact content by storage path\n * Streams the file through the PostHog backend so the sandbox does not need\n * direct access to object storage.\n */\n async downloadArtifact(\n taskId: string,\n runId: string,\n storagePath: string,\n ): Promise<ArrayBuffer | null> {\n const teamId = this.getTeamId();\n\n try {\n const response = await this.performRequestWithRetry(\n `/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/download/`,\n {\n method: \"POST\",\n body: JSON.stringify({ storage_path: storagePath }),\n },\n );\n if (!response.ok) {\n throw new Error(`Failed to download artifact: ${response.status}`);\n }\n return response.arrayBuffer();\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch logs for a task run via the logs API endpoint\n * @param taskRun - The task run to fetch logs for\n * @returns Array of stored entries, or empty array if no logs available\n */\n async fetchTaskRunLogs(taskRun: TaskRun): Promise<StoredEntry[]> {\n const teamId = this.getTeamId();\n const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;\n\n try {\n const response = await this.performRequestWithRetry(endpoint);\n\n if (!response.ok) {\n if (response.status === 404) {\n return [];\n }\n throw new Error(\n `Failed to fetch logs: ${response.status} ${response.statusText}`,\n );\n }\n\n const content = await response.text();\n\n if (!content.trim()) {\n return [];\n }\n\n // Parse newline-delimited JSON\n return content\n .trim()\n .split(\"\\n\")\n .map((line) => JSON.parse(line) as StoredEntry);\n } catch (error) {\n throw new Error(\n `Failed to fetch task run logs: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -83,6 +83,13 @@ declare class AgentServer {
|
|
|
83
83
|
private formatConversationForResume;
|
|
84
84
|
private getInitialPromptOverride;
|
|
85
85
|
private getPendingUserPrompt;
|
|
86
|
+
private getClearedPendingUserState;
|
|
87
|
+
private clearPendingInitialPromptState;
|
|
88
|
+
private buildPromptFromContentAndArtifacts;
|
|
89
|
+
private getArtifactsById;
|
|
90
|
+
private hydrateArtifactsToPrompt;
|
|
91
|
+
private hydrateArtifactToPromptBlock;
|
|
92
|
+
private getSafeArtifactName;
|
|
86
93
|
private getResumeRunId;
|
|
87
94
|
private buildSessionSystemPrompt;
|
|
88
95
|
private buildCodexInstructions;
|
|
@@ -3784,6 +3784,9 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
3784
3784
|
});
|
|
3785
3785
|
|
|
3786
3786
|
// src/server/agent-server.ts
|
|
3787
|
+
import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
|
|
3788
|
+
import { basename as basename2, join as join11 } from "path";
|
|
3789
|
+
import { pathToFileURL } from "url";
|
|
3787
3790
|
import {
|
|
3788
3791
|
ClientSideConnection as ClientSideConnection2,
|
|
3789
3792
|
ndJsonStream as ndJsonStream3,
|
|
@@ -8574,7 +8577,7 @@ import { Hono } from "hono";
|
|
|
8574
8577
|
// package.json
|
|
8575
8578
|
var package_default = {
|
|
8576
8579
|
name: "@posthog/agent",
|
|
8577
|
-
version: "2.3.
|
|
8580
|
+
version: "2.3.346",
|
|
8578
8581
|
repository: "https://github.com/PostHog/code",
|
|
8579
8582
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8580
8583
|
exports: {
|
|
@@ -12384,16 +12387,12 @@ var BaseAcpAgent = class {
|
|
|
12384
12387
|
|
|
12385
12388
|
// src/adapters/claude/conversion/acp-to-sdk.ts
|
|
12386
12389
|
import * as path5 from "path";
|
|
12390
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
12387
12391
|
function sdkText(value) {
|
|
12388
12392
|
return { type: "text", text: value };
|
|
12389
12393
|
}
|
|
12390
12394
|
function formatUriAsLink(uri) {
|
|
12391
12395
|
try {
|
|
12392
|
-
if (uri.startsWith("file://")) {
|
|
12393
|
-
const filePath = uri.slice(7);
|
|
12394
|
-
const name2 = path5.basename(filePath) || filePath;
|
|
12395
|
-
return `[@${name2}](${uri})`;
|
|
12396
|
-
}
|
|
12397
12396
|
if (uri.startsWith("zed://")) {
|
|
12398
12397
|
const name2 = path5.basename(uri) || uri;
|
|
12399
12398
|
return `[@${name2}](${uri})`;
|
|
@@ -12403,6 +12402,20 @@ function formatUriAsLink(uri) {
|
|
|
12403
12402
|
return uri;
|
|
12404
12403
|
}
|
|
12405
12404
|
}
|
|
12405
|
+
function formatFileAttachment(uri) {
|
|
12406
|
+
try {
|
|
12407
|
+
const filePath = fileURLToPath2(uri);
|
|
12408
|
+
const name2 = path5.basename(filePath) || filePath;
|
|
12409
|
+
return [
|
|
12410
|
+
"Attached file available in the workspace:",
|
|
12411
|
+
`- name: ${name2}`,
|
|
12412
|
+
`- path: ${filePath}`,
|
|
12413
|
+
"Use the available tools to inspect this file if needed."
|
|
12414
|
+
].join("\n");
|
|
12415
|
+
} catch {
|
|
12416
|
+
return `Attached file available at ${uri}`;
|
|
12417
|
+
}
|
|
12418
|
+
}
|
|
12406
12419
|
function transformMcpCommand(text2) {
|
|
12407
12420
|
const mcpMatch = text2.match(/^\/mcp:([^:\s]+):(\S+)(\s+.*)?$/);
|
|
12408
12421
|
if (mcpMatch) {
|
|
@@ -12417,7 +12430,11 @@ function processPromptChunk(chunk, content, context) {
|
|
|
12417
12430
|
content.push(sdkText(transformMcpCommand(chunk.text)));
|
|
12418
12431
|
break;
|
|
12419
12432
|
case "resource_link":
|
|
12420
|
-
content.push(
|
|
12433
|
+
content.push(
|
|
12434
|
+
sdkText(
|
|
12435
|
+
chunk.uri.startsWith("file://") ? formatFileAttachment(chunk.uri) : formatUriAsLink(chunk.uri)
|
|
12436
|
+
)
|
|
12437
|
+
);
|
|
12421
12438
|
break;
|
|
12422
12439
|
case "resource":
|
|
12423
12440
|
if ("text" in chunk.resource) {
|
|
@@ -17379,32 +17396,21 @@ var PostHogAPIClient = class {
|
|
|
17379
17396
|
);
|
|
17380
17397
|
return response.artifacts ?? [];
|
|
17381
17398
|
}
|
|
17382
|
-
|
|
17399
|
+
/**
|
|
17400
|
+
* Download artifact content by storage path
|
|
17401
|
+
* Streams the file through the PostHog backend so the sandbox does not need
|
|
17402
|
+
* direct access to object storage.
|
|
17403
|
+
*/
|
|
17404
|
+
async downloadArtifact(taskId, runId, storagePath) {
|
|
17383
17405
|
const teamId = this.getTeamId();
|
|
17384
17406
|
try {
|
|
17385
|
-
const response = await this.
|
|
17386
|
-
`/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/
|
|
17407
|
+
const response = await this.performRequestWithRetry(
|
|
17408
|
+
`/api/projects/${teamId}/tasks/${taskId}/runs/${runId}/artifacts/download/`,
|
|
17387
17409
|
{
|
|
17388
17410
|
method: "POST",
|
|
17389
17411
|
body: JSON.stringify({ storage_path: storagePath })
|
|
17390
17412
|
}
|
|
17391
17413
|
);
|
|
17392
|
-
return response.url;
|
|
17393
|
-
} catch {
|
|
17394
|
-
return null;
|
|
17395
|
-
}
|
|
17396
|
-
}
|
|
17397
|
-
/**
|
|
17398
|
-
* Download artifact content by storage path
|
|
17399
|
-
* Gets a presigned URL and fetches the content
|
|
17400
|
-
*/
|
|
17401
|
-
async downloadArtifact(taskId, runId, storagePath) {
|
|
17402
|
-
const url = await this.getArtifactPresignedUrl(taskId, runId, storagePath);
|
|
17403
|
-
if (!url) {
|
|
17404
|
-
return null;
|
|
17405
|
-
}
|
|
17406
|
-
try {
|
|
17407
|
-
const response = await fetch(url);
|
|
17408
17414
|
if (!response.ok) {
|
|
17409
17415
|
throw new Error(`Failed to download artifact: ${response.status}`);
|
|
17410
17416
|
}
|
|
@@ -18875,8 +18881,16 @@ var userMessageParamsSchema = z3.object({
|
|
|
18875
18881
|
content: z3.union([
|
|
18876
18882
|
z3.string().min(1, "Content is required"),
|
|
18877
18883
|
z3.array(z3.record(z3.string(), z3.unknown())).min(1, "Content is required")
|
|
18878
|
-
])
|
|
18879
|
-
|
|
18884
|
+
]).optional(),
|
|
18885
|
+
artifacts: z3.array(z3.record(z3.string(), z3.unknown())).optional()
|
|
18886
|
+
}).refine(
|
|
18887
|
+
(params) => {
|
|
18888
|
+
const hasContent = typeof params.content === "string" ? params.content.trim().length > 0 : Array.isArray(params.content) && params.content.length > 0;
|
|
18889
|
+
const hasArtifacts = Array.isArray(params.artifacts) && params.artifacts.length > 0;
|
|
18890
|
+
return hasContent || hasArtifacts;
|
|
18891
|
+
},
|
|
18892
|
+
{ error: "Either content or artifacts are required" }
|
|
18893
|
+
);
|
|
18880
18894
|
var permissionResponseParamsSchema = z3.object({
|
|
18881
18895
|
requestId: z3.string().min(1, "requestId is required"),
|
|
18882
18896
|
optionId: z3.string().min(1, "optionId is required"),
|
|
@@ -19131,7 +19145,7 @@ var AgentServer = class _AgentServer {
|
|
|
19131
19145
|
});
|
|
19132
19146
|
},
|
|
19133
19147
|
cancel: () => {
|
|
19134
|
-
this.logger.
|
|
19148
|
+
this.logger.debug("SSE connection closed");
|
|
19135
19149
|
if (this.session?.sseController) {
|
|
19136
19150
|
this.session.sseController = null;
|
|
19137
19151
|
}
|
|
@@ -19299,9 +19313,22 @@ var AgentServer = class _AgentServer {
|
|
|
19299
19313
|
switch (method) {
|
|
19300
19314
|
case POSTHOG_NOTIFICATIONS.USER_MESSAGE:
|
|
19301
19315
|
case "user_message": {
|
|
19302
|
-
|
|
19303
|
-
params.content
|
|
19304
|
-
|
|
19316
|
+
this.logger.info("Received user_message command", {
|
|
19317
|
+
hasContent: typeof params.content === "string" ? params.content.trim().length > 0 : Array.isArray(params.content) && params.content.length > 0,
|
|
19318
|
+
artifactCount: Array.isArray(params.artifacts) ? params.artifacts.length : 0
|
|
19319
|
+
});
|
|
19320
|
+
const prompt = await this.buildPromptFromContentAndArtifacts({
|
|
19321
|
+
content: params.content,
|
|
19322
|
+
artifacts: Array.isArray(params.artifacts) ? params.artifacts : [],
|
|
19323
|
+
taskId: this.session.payload.task_id,
|
|
19324
|
+
runId: this.session.payload.run_id
|
|
19325
|
+
});
|
|
19326
|
+
if (prompt.length === 0) {
|
|
19327
|
+
throw new Error("User message cannot be empty");
|
|
19328
|
+
}
|
|
19329
|
+
this.logger.info("Built user_message prompt", {
|
|
19330
|
+
blockTypes: prompt.map((block) => block.type)
|
|
19331
|
+
});
|
|
19305
19332
|
const promptPreview = promptBlocksToText(prompt);
|
|
19306
19333
|
this.logger.info(
|
|
19307
19334
|
`Processing user message (detectedPrUrl=${this.detectedPrUrl ?? "none"}): ${promptPreview.substring(0, 100)}...`
|
|
@@ -19659,7 +19686,7 @@ var AgentServer = class _AgentServer {
|
|
|
19659
19686
|
try {
|
|
19660
19687
|
const task = await this.posthogAPI.getTask(payload.task_id);
|
|
19661
19688
|
const initialPromptOverride = taskRun ? this.getInitialPromptOverride(taskRun) : null;
|
|
19662
|
-
const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
|
|
19689
|
+
const pendingUserPrompt = await this.getPendingUserPrompt(taskRun);
|
|
19663
19690
|
let initialPrompt = [];
|
|
19664
19691
|
if (pendingUserPrompt?.length) {
|
|
19665
19692
|
initialPrompt = pendingUserPrompt;
|
|
@@ -19686,6 +19713,7 @@ var AgentServer = class _AgentServer {
|
|
|
19686
19713
|
this.logger.info("Initial task message completed", {
|
|
19687
19714
|
stopReason: result.stopReason
|
|
19688
19715
|
});
|
|
19716
|
+
await this.clearPendingInitialPromptState(payload, taskRun);
|
|
19689
19717
|
if (result.stopReason === "end_turn") {
|
|
19690
19718
|
void this.syncCloudBranchMetadata(payload);
|
|
19691
19719
|
}
|
|
@@ -19707,7 +19735,7 @@ var AgentServer = class _AgentServer {
|
|
|
19707
19735
|
const conversationSummary = this.formatConversationForResume(
|
|
19708
19736
|
this.resumeState.conversation
|
|
19709
19737
|
);
|
|
19710
|
-
const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
|
|
19738
|
+
const pendingUserPrompt = await this.getPendingUserPrompt(taskRun);
|
|
19711
19739
|
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.`;
|
|
19712
19740
|
let resumePromptBlocks;
|
|
19713
19741
|
if (pendingUserPrompt?.length) {
|
|
@@ -19818,15 +19846,134 @@ ${toolSummary}`);
|
|
|
19818
19846
|
const trimmed2 = override.trim();
|
|
19819
19847
|
return trimmed2.length > 0 ? trimmed2 : null;
|
|
19820
19848
|
}
|
|
19821
|
-
getPendingUserPrompt(taskRun) {
|
|
19849
|
+
async getPendingUserPrompt(taskRun) {
|
|
19822
19850
|
if (!taskRun) return null;
|
|
19823
19851
|
const state = taskRun.state;
|
|
19824
19852
|
const message = state?.pending_user_message;
|
|
19825
|
-
|
|
19853
|
+
const artifactIds = Array.isArray(state?.pending_user_artifact_ids) ? state.pending_user_artifact_ids.filter(
|
|
19854
|
+
(artifactId) => typeof artifactId === "string" && artifactId.trim().length > 0
|
|
19855
|
+
) : [];
|
|
19856
|
+
const prompt = await this.buildPromptFromContentAndArtifacts({
|
|
19857
|
+
content: typeof message === "string" ? message : void 0,
|
|
19858
|
+
artifacts: this.getArtifactsById(taskRun.artifacts, artifactIds),
|
|
19859
|
+
taskId: taskRun.task,
|
|
19860
|
+
runId: taskRun.id
|
|
19861
|
+
});
|
|
19862
|
+
this.logger.info("Built pending user prompt", {
|
|
19863
|
+
hasMessage: typeof message === "string" && message.trim().length > 0,
|
|
19864
|
+
requestedArtifactCount: artifactIds.length,
|
|
19865
|
+
blockTypes: prompt.map((block) => block.type)
|
|
19866
|
+
});
|
|
19867
|
+
return prompt.length > 0 ? prompt : null;
|
|
19868
|
+
}
|
|
19869
|
+
getClearedPendingUserState(taskRun) {
|
|
19870
|
+
const state = taskRun?.state && typeof taskRun.state === "object" ? taskRun.state : null;
|
|
19871
|
+
if (!state) {
|
|
19826
19872
|
return null;
|
|
19827
19873
|
}
|
|
19828
|
-
const
|
|
19829
|
-
|
|
19874
|
+
const pendingKeys = [
|
|
19875
|
+
"pending_user_message",
|
|
19876
|
+
"pending_user_artifact_ids",
|
|
19877
|
+
"pending_user_message_ts"
|
|
19878
|
+
].filter((key) => key in state);
|
|
19879
|
+
return pendingKeys.length > 0 ? pendingKeys : null;
|
|
19880
|
+
}
|
|
19881
|
+
async clearPendingInitialPromptState(payload, taskRun) {
|
|
19882
|
+
const stateRemoveKeys = this.getClearedPendingUserState(taskRun);
|
|
19883
|
+
if (!stateRemoveKeys) {
|
|
19884
|
+
return;
|
|
19885
|
+
}
|
|
19886
|
+
await this.posthogAPI.updateTaskRun(payload.task_id, payload.run_id, {
|
|
19887
|
+
state_remove_keys: stateRemoveKeys
|
|
19888
|
+
});
|
|
19889
|
+
}
|
|
19890
|
+
async buildPromptFromContentAndArtifacts({
|
|
19891
|
+
content,
|
|
19892
|
+
artifacts,
|
|
19893
|
+
taskId,
|
|
19894
|
+
runId
|
|
19895
|
+
}) {
|
|
19896
|
+
const contentBlocks = content ? normalizeCloudPromptContent(content) : [];
|
|
19897
|
+
const artifactBlocks = await this.hydrateArtifactsToPrompt(
|
|
19898
|
+
taskId,
|
|
19899
|
+
runId,
|
|
19900
|
+
artifacts ?? []
|
|
19901
|
+
);
|
|
19902
|
+
return [...contentBlocks, ...artifactBlocks];
|
|
19903
|
+
}
|
|
19904
|
+
getArtifactsById(artifacts, artifactIds) {
|
|
19905
|
+
if (!artifacts?.length || artifactIds.length === 0) {
|
|
19906
|
+
return [];
|
|
19907
|
+
}
|
|
19908
|
+
const artifactsById = new Map(
|
|
19909
|
+
artifacts.filter(
|
|
19910
|
+
(artifact) => typeof artifact.id === "string" && artifact.id.trim().length > 0
|
|
19911
|
+
).map((artifact) => [artifact.id, artifact])
|
|
19912
|
+
);
|
|
19913
|
+
return artifactIds.flatMap((artifactId) => {
|
|
19914
|
+
const artifact = artifactsById.get(artifactId);
|
|
19915
|
+
if (!artifact) {
|
|
19916
|
+
this.logger.warn("Pending artifact missing from run manifest", {
|
|
19917
|
+
artifactId
|
|
19918
|
+
});
|
|
19919
|
+
return [];
|
|
19920
|
+
}
|
|
19921
|
+
return [artifact];
|
|
19922
|
+
});
|
|
19923
|
+
}
|
|
19924
|
+
async hydrateArtifactsToPrompt(taskId, runId, artifacts) {
|
|
19925
|
+
if (artifacts.length === 0) {
|
|
19926
|
+
return [];
|
|
19927
|
+
}
|
|
19928
|
+
this.logger.debug("Hydrating prompt artifacts", {
|
|
19929
|
+
taskId,
|
|
19930
|
+
runId,
|
|
19931
|
+
artifactCount: artifacts.length,
|
|
19932
|
+
artifactNames: artifacts.map((artifact) => artifact.name)
|
|
19933
|
+
});
|
|
19934
|
+
return (await Promise.all(
|
|
19935
|
+
artifacts.map(
|
|
19936
|
+
(artifact) => this.hydrateArtifactToPromptBlock(taskId, runId, artifact)
|
|
19937
|
+
)
|
|
19938
|
+
)).flatMap((artifactBlock) => artifactBlock ? [artifactBlock] : []);
|
|
19939
|
+
}
|
|
19940
|
+
async hydrateArtifactToPromptBlock(taskId, runId, artifact) {
|
|
19941
|
+
if (!artifact.storage_path) {
|
|
19942
|
+
this.logger.warn("Skipping artifact without storage path", {
|
|
19943
|
+
taskId,
|
|
19944
|
+
runId,
|
|
19945
|
+
artifactName: artifact.name
|
|
19946
|
+
});
|
|
19947
|
+
return null;
|
|
19948
|
+
}
|
|
19949
|
+
const data = await this.posthogAPI.downloadArtifact(
|
|
19950
|
+
taskId,
|
|
19951
|
+
runId,
|
|
19952
|
+
artifact.storage_path
|
|
19953
|
+
);
|
|
19954
|
+
if (!data) {
|
|
19955
|
+
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
19956
|
+
}
|
|
19957
|
+
const safeName = this.getSafeArtifactName(artifact.name);
|
|
19958
|
+
const artifactDir = join11(
|
|
19959
|
+
this.config.repositoryPath ?? "/tmp/workspace",
|
|
19960
|
+
".posthog",
|
|
19961
|
+
"attachments",
|
|
19962
|
+
runId,
|
|
19963
|
+
artifact.id ?? safeName
|
|
19964
|
+
);
|
|
19965
|
+
await mkdir5(artifactDir, { recursive: true });
|
|
19966
|
+
const artifactPath = join11(artifactDir, safeName);
|
|
19967
|
+
await writeFile5(artifactPath, Buffer.from(data));
|
|
19968
|
+
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
19969
|
+
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|
|
19970
|
+
...typeof artifact.size === "number" ? { size: artifact.size } : {}
|
|
19971
|
+
});
|
|
19972
|
+
}
|
|
19973
|
+
getSafeArtifactName(name2) {
|
|
19974
|
+
const baseName = basename2(name2).trim();
|
|
19975
|
+
const normalizedName = baseName.replace(/[^\w.-]/g, "_");
|
|
19976
|
+
return normalizedName.length > 0 ? normalizedName : "attachment";
|
|
19830
19977
|
}
|
|
19831
19978
|
getResumeRunId(taskRun) {
|
|
19832
19979
|
const envRunId = process.env.POSTHOG_RESUME_RUN_ID;
|