@posthog/agent 2.3.351 → 2.3.354
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/adapters/claude/permissions/permission-options.d.ts +1 -1
- package/dist/adapters/claude/permissions/permission-options.js +3 -3
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/agent.js +5936 -135
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +2 -0
- package/dist/server/agent-server.js +222 -54
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +220 -52
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/conversion/sdk-to-acp.ts +31 -1
- package/src/adapters/claude/permissions/permission-handlers.ts +53 -10
- package/src/adapters/claude/permissions/permission-options.ts +3 -3
- package/src/adapters/claude/session/repo-path.ts +22 -0
- package/src/adapters/claude/session/settings.test.ts +159 -0
- package/src/adapters/claude/session/settings.ts +92 -6
- package/src/server/agent-server.ts +54 -3
- package/src/server/question-relay.test.ts +124 -0
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.354",
|
|
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: {
|
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.351\",\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 \"@posthog/enricher\": \"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 \"@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":";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,qBAAqB;AAAA,IACrB,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,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;AAwB1E,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;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,QACA,OACA,aAC6B;AAC7B,UAAM,SAAS,KAAK,UAAU;AAE9B,QAAI;AACF,YAAM,WAAW,MAAM,KAAK;AAAA,QAC1B,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,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.354\",\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 \"@posthog/enricher\": \"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 \"@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":[]}
|
|
@@ -76,6 +76,8 @@ declare class AgentServer {
|
|
|
76
76
|
private executeCommand;
|
|
77
77
|
private initializeSession;
|
|
78
78
|
private _doInitializeSession;
|
|
79
|
+
private extractErrorClassification;
|
|
80
|
+
private classifyAndSignalFailure;
|
|
79
81
|
private sendInitialTaskMessage;
|
|
80
82
|
private sendResumeMessage;
|
|
81
83
|
private static RESUME_HISTORY_TOKEN_BUDGET;
|
|
@@ -8564,6 +8564,32 @@ async function getCurrentBranch(baseDir, options) {
|
|
|
8564
8564
|
return branch === "HEAD" ? null : branch;
|
|
8565
8565
|
}, { signal: options?.abortSignal });
|
|
8566
8566
|
}
|
|
8567
|
+
async function listWorktrees(baseDir, options) {
|
|
8568
|
+
const manager = getGitOperationManager();
|
|
8569
|
+
return manager.executeRead(baseDir, async (git) => {
|
|
8570
|
+
const output = await git.raw(["worktree", "list", "--porcelain"]);
|
|
8571
|
+
const worktrees = [];
|
|
8572
|
+
let current2 = {};
|
|
8573
|
+
for (const line of output.split("\n")) {
|
|
8574
|
+
if (line.startsWith("worktree ")) {
|
|
8575
|
+
if (current2.path) {
|
|
8576
|
+
worktrees.push(current2);
|
|
8577
|
+
}
|
|
8578
|
+
current2 = { path: line.slice(9), branch: null };
|
|
8579
|
+
} else if (line.startsWith("HEAD ")) {
|
|
8580
|
+
current2.head = line.slice(5);
|
|
8581
|
+
} else if (line.startsWith("branch ")) {
|
|
8582
|
+
current2.branch = line.slice(7).replace("refs/heads/", "");
|
|
8583
|
+
} else if (line === "detached") {
|
|
8584
|
+
current2.branch = null;
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
if (current2.path) {
|
|
8588
|
+
worktrees.push(current2);
|
|
8589
|
+
}
|
|
8590
|
+
return worktrees;
|
|
8591
|
+
}, { signal: options?.abortSignal });
|
|
8592
|
+
}
|
|
8567
8593
|
async function getHeadSha(baseDir, options) {
|
|
8568
8594
|
const manager = getGitOperationManager();
|
|
8569
8595
|
return manager.executeRead(baseDir, (git) => git.revparse(["HEAD"]), {
|
|
@@ -8573,11 +8599,12 @@ async function getHeadSha(baseDir, options) {
|
|
|
8573
8599
|
|
|
8574
8600
|
// src/server/agent-server.ts
|
|
8575
8601
|
import { Hono } from "hono";
|
|
8602
|
+
import { z as z4 } from "zod";
|
|
8576
8603
|
|
|
8577
8604
|
// package.json
|
|
8578
8605
|
var package_default = {
|
|
8579
8606
|
name: "@posthog/agent",
|
|
8580
|
-
version: "2.3.
|
|
8607
|
+
version: "2.3.354",
|
|
8581
8608
|
repository: "https://github.com/PostHog/code",
|
|
8582
8609
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8583
8610
|
exports: {
|
|
@@ -13738,6 +13765,17 @@ async function handleSystemMessage(message, context) {
|
|
|
13738
13765
|
break;
|
|
13739
13766
|
}
|
|
13740
13767
|
}
|
|
13768
|
+
function classifyAgentError(result) {
|
|
13769
|
+
if (!result) return "agent_error";
|
|
13770
|
+
const text2 = result.trim();
|
|
13771
|
+
if (/API Error:\s*terminated\b/i.test(text2)) {
|
|
13772
|
+
return "upstream_stream_terminated";
|
|
13773
|
+
}
|
|
13774
|
+
if (/API Error:\s*Connection error\b/i.test(text2)) {
|
|
13775
|
+
return "upstream_connection_error";
|
|
13776
|
+
}
|
|
13777
|
+
return "agent_error";
|
|
13778
|
+
}
|
|
13741
13779
|
function handleResultMessage(message) {
|
|
13742
13780
|
const usage = extractUsageFromResult(message);
|
|
13743
13781
|
switch (message.subtype) {
|
|
@@ -13753,9 +13791,13 @@ function handleResultMessage(message) {
|
|
|
13753
13791
|
return { shouldStop: true, stopReason: "max_tokens", usage };
|
|
13754
13792
|
}
|
|
13755
13793
|
if (message.is_error) {
|
|
13794
|
+
const classification = classifyAgentError(message.result);
|
|
13756
13795
|
return {
|
|
13757
13796
|
shouldStop: true,
|
|
13758
|
-
error: RequestError.internalError(
|
|
13797
|
+
error: RequestError.internalError(
|
|
13798
|
+
{ classification, result: message.result },
|
|
13799
|
+
message.result
|
|
13800
|
+
),
|
|
13759
13801
|
usage
|
|
13760
13802
|
};
|
|
13761
13803
|
}
|
|
@@ -14112,16 +14154,16 @@ function permissionOptions(allowAlwaysLabel) {
|
|
|
14112
14154
|
}
|
|
14113
14155
|
];
|
|
14114
14156
|
}
|
|
14115
|
-
function buildPermissionOptions(toolName, toolInput,
|
|
14157
|
+
function buildPermissionOptions(toolName, toolInput, repoRoot, suggestions) {
|
|
14116
14158
|
if (BASH_TOOLS.has(toolName)) {
|
|
14117
14159
|
const rawRuleContent = suggestions?.flatMap((s) => "rules" in s ? s.rules : []).find((r) => r.toolName === "Bash" && r.ruleContent)?.ruleContent;
|
|
14118
14160
|
const ruleContent = rawRuleContent?.replace(/:?\*$/, "");
|
|
14119
14161
|
const command = toolInput?.command;
|
|
14120
14162
|
const cmdName = command?.split(/\s+/)[0] ?? "this command";
|
|
14121
|
-
const
|
|
14163
|
+
const scopeLabel = repoRoot ? ` in ${repoRoot}` : "";
|
|
14122
14164
|
const label = ruleContent ?? `\`${cmdName}\` commands`;
|
|
14123
14165
|
return permissionOptions(
|
|
14124
|
-
`Yes, and don't ask again for ${label}${
|
|
14166
|
+
`Yes, and don't ask again for ${label}${scopeLabel}`
|
|
14125
14167
|
);
|
|
14126
14168
|
}
|
|
14127
14169
|
if (toolName === "BashOutput") {
|
|
@@ -14407,7 +14449,7 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
14407
14449
|
const options = buildPermissionOptions(
|
|
14408
14450
|
toolName,
|
|
14409
14451
|
toolInput,
|
|
14410
|
-
session
|
|
14452
|
+
session.settingsManager.getRepoRoot(),
|
|
14411
14453
|
suggestions
|
|
14412
14454
|
);
|
|
14413
14455
|
const response = await client.requestPermission({
|
|
@@ -14427,17 +14469,19 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
14427
14469
|
}
|
|
14428
14470
|
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "allow" || response.outcome.optionId === "allow_always")) {
|
|
14429
14471
|
if (response.outcome.optionId === "allow_always") {
|
|
14472
|
+
const rules = extractAllowRules(suggestions, toolName);
|
|
14473
|
+
try {
|
|
14474
|
+
await session.settingsManager.addAllowRules(rules);
|
|
14475
|
+
} catch (error) {
|
|
14476
|
+
context.logger.warn(
|
|
14477
|
+
"[canUseTool] Failed to persist allow rules to repository settings",
|
|
14478
|
+
{ error: error instanceof Error ? error.message : String(error) }
|
|
14479
|
+
);
|
|
14480
|
+
}
|
|
14430
14481
|
return {
|
|
14431
14482
|
behavior: "allow",
|
|
14432
14483
|
updatedInput: toolInput,
|
|
14433
|
-
updatedPermissions: suggestions
|
|
14434
|
-
{
|
|
14435
|
-
type: "addRules",
|
|
14436
|
-
rules: [{ toolName }],
|
|
14437
|
-
behavior: "allow",
|
|
14438
|
-
destination: "localSettings"
|
|
14439
|
-
}
|
|
14440
|
-
]
|
|
14484
|
+
updatedPermissions: buildSessionPermissions(suggestions, rules)
|
|
14441
14485
|
};
|
|
14442
14486
|
}
|
|
14443
14487
|
return {
|
|
@@ -14470,6 +14514,26 @@ function handlePlanFileException(context) {
|
|
|
14470
14514
|
updatedInput: toolInput
|
|
14471
14515
|
};
|
|
14472
14516
|
}
|
|
14517
|
+
function extractAllowRules(suggestions, toolName) {
|
|
14518
|
+
if (!suggestions || suggestions.length === 0) {
|
|
14519
|
+
return [{ toolName }];
|
|
14520
|
+
}
|
|
14521
|
+
return suggestions.filter(
|
|
14522
|
+
(update) => update.type === "addRules" && update.behavior === "allow"
|
|
14523
|
+
).flatMap((update) => "rules" in update ? update.rules : []);
|
|
14524
|
+
}
|
|
14525
|
+
function buildSessionPermissions(suggestions, rules) {
|
|
14526
|
+
const passthrough = (suggestions ?? []).filter(
|
|
14527
|
+
(update) => !(update.type === "addRules" && update.behavior === "allow")
|
|
14528
|
+
).map((update) => ({ ...update, destination: "session" }));
|
|
14529
|
+
if (rules.length === 0) {
|
|
14530
|
+
return passthrough;
|
|
14531
|
+
}
|
|
14532
|
+
return [
|
|
14533
|
+
{ type: "addRules", rules, behavior: "allow", destination: "session" },
|
|
14534
|
+
...passthrough
|
|
14535
|
+
];
|
|
14536
|
+
}
|
|
14473
14537
|
function extractDomainFromUrl(url) {
|
|
14474
14538
|
try {
|
|
14475
14539
|
return new URL(url).hostname;
|
|
@@ -14979,6 +15043,47 @@ import * as fs7 from "fs";
|
|
|
14979
15043
|
import * as os3 from "os";
|
|
14980
15044
|
import * as path9 from "path";
|
|
14981
15045
|
import { minimatch } from "minimatch";
|
|
15046
|
+
|
|
15047
|
+
// src/utils/async-mutex.ts
|
|
15048
|
+
var AsyncMutex = class {
|
|
15049
|
+
locked = false;
|
|
15050
|
+
queue = [];
|
|
15051
|
+
async acquire() {
|
|
15052
|
+
if (!this.locked) {
|
|
15053
|
+
this.locked = true;
|
|
15054
|
+
return;
|
|
15055
|
+
}
|
|
15056
|
+
return new Promise((resolve4) => {
|
|
15057
|
+
this.queue.push(resolve4);
|
|
15058
|
+
});
|
|
15059
|
+
}
|
|
15060
|
+
release() {
|
|
15061
|
+
const next = this.queue.shift();
|
|
15062
|
+
if (next) {
|
|
15063
|
+
next();
|
|
15064
|
+
} else {
|
|
15065
|
+
this.locked = false;
|
|
15066
|
+
}
|
|
15067
|
+
}
|
|
15068
|
+
isLocked() {
|
|
15069
|
+
return this.locked;
|
|
15070
|
+
}
|
|
15071
|
+
get queueLength() {
|
|
15072
|
+
return this.queue.length;
|
|
15073
|
+
}
|
|
15074
|
+
};
|
|
15075
|
+
|
|
15076
|
+
// src/adapters/claude/session/repo-path.ts
|
|
15077
|
+
async function resolveMainRepoPath(cwd) {
|
|
15078
|
+
try {
|
|
15079
|
+
const worktrees = await listWorktrees(cwd);
|
|
15080
|
+
return worktrees[0]?.path ?? cwd;
|
|
15081
|
+
} catch {
|
|
15082
|
+
return cwd;
|
|
15083
|
+
}
|
|
15084
|
+
}
|
|
15085
|
+
|
|
15086
|
+
// src/adapters/claude/session/settings.ts
|
|
14982
15087
|
var ACP_TOOL_NAME_PREFIX = "mcp__acp__";
|
|
14983
15088
|
var acpToolNames = {
|
|
14984
15089
|
read: `${ACP_TOOL_NAME_PREFIX}Read`,
|
|
@@ -15035,7 +15140,7 @@ function matchesGlob(pattern, filePath, cwd) {
|
|
|
15035
15140
|
});
|
|
15036
15141
|
}
|
|
15037
15142
|
function matchesRule(rule, toolName, toolInput, cwd) {
|
|
15038
|
-
const ruleAppliesToTool = rule.toolName === "Bash" && toolName === acpToolNames.bash || rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName) || rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName);
|
|
15143
|
+
const ruleAppliesToTool = rule.toolName === "Bash" && toolName === acpToolNames.bash || rule.toolName === "Edit" && FILE_EDITING_TOOLS.includes(toolName) || rule.toolName === "Read" && FILE_READING_TOOLS.includes(toolName) || rule.toolName === toolName && !rule.argument;
|
|
15039
15144
|
if (!ruleAppliesToTool) {
|
|
15040
15145
|
return false;
|
|
15041
15146
|
}
|
|
@@ -15065,6 +15170,19 @@ function matchesRule(rule, toolName, toolInput, cwd) {
|
|
|
15065
15170
|
}
|
|
15066
15171
|
return matchesGlob(rule.argument, actualArg, cwd);
|
|
15067
15172
|
}
|
|
15173
|
+
function formatRule(rule) {
|
|
15174
|
+
return rule.ruleContent ? `${rule.toolName}(${rule.ruleContent})` : rule.toolName;
|
|
15175
|
+
}
|
|
15176
|
+
async function writeFileAtomic(filePath, data) {
|
|
15177
|
+
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
15178
|
+
await fs7.promises.writeFile(tmpPath, data);
|
|
15179
|
+
try {
|
|
15180
|
+
await fs7.promises.rename(tmpPath, filePath);
|
|
15181
|
+
} catch (error) {
|
|
15182
|
+
await fs7.promises.rm(tmpPath, { force: true });
|
|
15183
|
+
throw error;
|
|
15184
|
+
}
|
|
15185
|
+
}
|
|
15068
15186
|
async function loadSettingsFile(filePath) {
|
|
15069
15187
|
if (!filePath) {
|
|
15070
15188
|
return {};
|
|
@@ -15083,6 +15201,17 @@ async function loadSettingsFile(filePath) {
|
|
|
15083
15201
|
return {};
|
|
15084
15202
|
}
|
|
15085
15203
|
}
|
|
15204
|
+
async function readSettingsFileForUpdate(filePath) {
|
|
15205
|
+
try {
|
|
15206
|
+
const content = await fs7.promises.readFile(filePath, "utf-8");
|
|
15207
|
+
return JSON.parse(content);
|
|
15208
|
+
} catch (error) {
|
|
15209
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
15210
|
+
return {};
|
|
15211
|
+
}
|
|
15212
|
+
throw error;
|
|
15213
|
+
}
|
|
15214
|
+
}
|
|
15086
15215
|
function getManagedSettingsPath() {
|
|
15087
15216
|
switch (process.platform) {
|
|
15088
15217
|
case "darwin":
|
|
@@ -15097,6 +15226,7 @@ function getManagedSettingsPath() {
|
|
|
15097
15226
|
}
|
|
15098
15227
|
var SettingsManager = class {
|
|
15099
15228
|
cwd;
|
|
15229
|
+
repoRoot;
|
|
15100
15230
|
userSettings = {};
|
|
15101
15231
|
projectSettings = {};
|
|
15102
15232
|
localSettings = {};
|
|
@@ -15104,8 +15234,10 @@ var SettingsManager = class {
|
|
|
15104
15234
|
mergedSettings = {};
|
|
15105
15235
|
initialized = false;
|
|
15106
15236
|
initPromise = null;
|
|
15237
|
+
writeMutex = new AsyncMutex();
|
|
15107
15238
|
constructor(cwd) {
|
|
15108
15239
|
this.cwd = cwd;
|
|
15240
|
+
this.repoRoot = cwd;
|
|
15109
15241
|
}
|
|
15110
15242
|
async initialize() {
|
|
15111
15243
|
if (this.initialized) return;
|
|
@@ -15123,10 +15255,16 @@ var SettingsManager = class {
|
|
|
15123
15255
|
getProjectSettingsPath() {
|
|
15124
15256
|
return path9.join(this.cwd, ".claude", "settings.json");
|
|
15125
15257
|
}
|
|
15258
|
+
/**
|
|
15259
|
+
* Local settings are anchored to the primary worktree so every worktree of
|
|
15260
|
+
* the same repository shares a single `.claude/settings.local.json`. This
|
|
15261
|
+
* avoids re-prompting for the same permission in every worktree.
|
|
15262
|
+
*/
|
|
15126
15263
|
getLocalSettingsPath() {
|
|
15127
|
-
return path9.join(this.
|
|
15264
|
+
return path9.join(this.repoRoot, ".claude", "settings.local.json");
|
|
15128
15265
|
}
|
|
15129
15266
|
async loadAllSettings() {
|
|
15267
|
+
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
15130
15268
|
const [userSettings, projectSettings, localSettings, enterpriseSettings] = await Promise.all([
|
|
15131
15269
|
loadSettingsFile(this.getUserSettingsPath()),
|
|
15132
15270
|
loadSettingsFile(this.getProjectSettingsPath()),
|
|
@@ -15183,9 +15321,6 @@ var SettingsManager = class {
|
|
|
15183
15321
|
this.mergedSettings = merged;
|
|
15184
15322
|
}
|
|
15185
15323
|
checkPermission(toolName, toolInput) {
|
|
15186
|
-
if (!toolName.startsWith(ACP_TOOL_NAME_PREFIX)) {
|
|
15187
|
-
return { decision: "ask" };
|
|
15188
|
-
}
|
|
15189
15324
|
const permissions = this.mergedSettings.permissions;
|
|
15190
15325
|
if (!permissions) {
|
|
15191
15326
|
return { decision: "ask" };
|
|
@@ -15216,6 +15351,43 @@ var SettingsManager = class {
|
|
|
15216
15351
|
getCwd() {
|
|
15217
15352
|
return this.cwd;
|
|
15218
15353
|
}
|
|
15354
|
+
getRepoRoot() {
|
|
15355
|
+
return this.repoRoot;
|
|
15356
|
+
}
|
|
15357
|
+
/**
|
|
15358
|
+
* Persists allow rules to `<primary-worktree>/.claude/settings.local.json`.
|
|
15359
|
+
* Because local settings are resolved against the primary worktree, every
|
|
15360
|
+
* worktree of the same repository picks up the new rule on next load.
|
|
15361
|
+
*
|
|
15362
|
+
* Writes are serialised via `writeMutex` to prevent concurrent callers from
|
|
15363
|
+
* clobbering each other, and use a temp-file + rename to keep the file
|
|
15364
|
+
* consistent if the process dies mid-write.
|
|
15365
|
+
*/
|
|
15366
|
+
async addAllowRules(rules) {
|
|
15367
|
+
if (rules.length === 0) return;
|
|
15368
|
+
if (!this.initialized) await this.initialize();
|
|
15369
|
+
await this.writeMutex.acquire();
|
|
15370
|
+
try {
|
|
15371
|
+
const filePath = this.getLocalSettingsPath();
|
|
15372
|
+
const existing = await readSettingsFileForUpdate(filePath);
|
|
15373
|
+
const permissions = {
|
|
15374
|
+
...existing.permissions ?? {}
|
|
15375
|
+
};
|
|
15376
|
+
const current2 = new Set(permissions.allow ?? []);
|
|
15377
|
+
for (const rule of rules) {
|
|
15378
|
+
current2.add(formatRule(rule));
|
|
15379
|
+
}
|
|
15380
|
+
permissions.allow = Array.from(current2);
|
|
15381
|
+
const next = { ...existing, permissions };
|
|
15382
|
+
await fs7.promises.mkdir(path9.dirname(filePath), { recursive: true });
|
|
15383
|
+
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
15384
|
+
`);
|
|
15385
|
+
this.localSettings = next;
|
|
15386
|
+
this.mergeAllSettings();
|
|
15387
|
+
} finally {
|
|
15388
|
+
this.writeMutex.release();
|
|
15389
|
+
}
|
|
15390
|
+
}
|
|
15219
15391
|
async setCwd(cwd) {
|
|
15220
15392
|
if (this.cwd === cwd) return;
|
|
15221
15393
|
if (this.initPromise) await this.initPromise;
|
|
@@ -16571,7 +16743,7 @@ function parseCodexToml(content, cwd) {
|
|
|
16571
16743
|
// src/adapters/codex/spawn.ts
|
|
16572
16744
|
import { spawn as spawn3 } from "child_process";
|
|
16573
16745
|
import { existsSync as existsSync4 } from "fs";
|
|
16574
|
-
import { delimiter, dirname as
|
|
16746
|
+
import { delimiter, dirname as dirname4 } from "path";
|
|
16575
16747
|
function buildConfigArgs(options) {
|
|
16576
16748
|
const args2 = [];
|
|
16577
16749
|
args2.push("-c", `features.remote_models=false`);
|
|
@@ -16622,7 +16794,7 @@ function spawnCodexProcess(options) {
|
|
|
16622
16794
|
}
|
|
16623
16795
|
const { command, args: args2 } = findCodexBinary(options);
|
|
16624
16796
|
if (options.binaryPath && existsSync4(options.binaryPath)) {
|
|
16625
|
-
const binDir =
|
|
16797
|
+
const binDir = dirname4(options.binaryPath);
|
|
16626
16798
|
env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
|
|
16627
16799
|
}
|
|
16628
16800
|
logger.info("Spawning codex-acp process", {
|
|
@@ -18805,35 +18977,6 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
18805
18977
|
}
|
|
18806
18978
|
};
|
|
18807
18979
|
|
|
18808
|
-
// src/utils/async-mutex.ts
|
|
18809
|
-
var AsyncMutex = class {
|
|
18810
|
-
locked = false;
|
|
18811
|
-
queue = [];
|
|
18812
|
-
async acquire() {
|
|
18813
|
-
if (!this.locked) {
|
|
18814
|
-
this.locked = true;
|
|
18815
|
-
return;
|
|
18816
|
-
}
|
|
18817
|
-
return new Promise((resolve4) => {
|
|
18818
|
-
this.queue.push(resolve4);
|
|
18819
|
-
});
|
|
18820
|
-
}
|
|
18821
|
-
release() {
|
|
18822
|
-
const next = this.queue.shift();
|
|
18823
|
-
if (next) {
|
|
18824
|
-
next();
|
|
18825
|
-
} else {
|
|
18826
|
-
this.locked = false;
|
|
18827
|
-
}
|
|
18828
|
-
}
|
|
18829
|
-
isLocked() {
|
|
18830
|
-
return this.locked;
|
|
18831
|
-
}
|
|
18832
|
-
get queueLength() {
|
|
18833
|
-
return this.queue.length;
|
|
18834
|
-
}
|
|
18835
|
-
};
|
|
18836
|
-
|
|
18837
18980
|
// src/server/cloud-prompt.ts
|
|
18838
18981
|
function normalizeCloudPromptContent(content) {
|
|
18839
18982
|
if (typeof content === "string") {
|
|
@@ -18979,6 +19122,14 @@ function validateCommandParams(method, params) {
|
|
|
18979
19122
|
}
|
|
18980
19123
|
|
|
18981
19124
|
// src/server/agent-server.ts
|
|
19125
|
+
var agentErrorClassificationSchema = z4.enum([
|
|
19126
|
+
"upstream_stream_terminated",
|
|
19127
|
+
"upstream_connection_error",
|
|
19128
|
+
"agent_error"
|
|
19129
|
+
]);
|
|
19130
|
+
var errorWithClassificationSchema = z4.object({
|
|
19131
|
+
data: z4.object({ classification: agentErrorClassificationSchema })
|
|
19132
|
+
});
|
|
18982
19133
|
var NdJsonTap = class {
|
|
18983
19134
|
constructor(onMessage) {
|
|
18984
19135
|
this.onMessage = onMessage;
|
|
@@ -19681,6 +19832,23 @@ var AgentServer = class _AgentServer {
|
|
|
19681
19832
|
);
|
|
19682
19833
|
await this.sendInitialTaskMessage(payload, preTaskRun);
|
|
19683
19834
|
}
|
|
19835
|
+
extractErrorClassification(error) {
|
|
19836
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
19837
|
+
const parsed = errorWithClassificationSchema.safeParse(error);
|
|
19838
|
+
if (parsed.success) {
|
|
19839
|
+
return { classification: parsed.data.data.classification, message };
|
|
19840
|
+
}
|
|
19841
|
+
return { classification: classifyAgentError(message), message };
|
|
19842
|
+
}
|
|
19843
|
+
classifyAndSignalFailure(payload, phase, error) {
|
|
19844
|
+
const { classification, message } = this.extractErrorClassification(error);
|
|
19845
|
+
const errorMessage = classification === "upstream_stream_terminated" ? "Upstream LLM stream terminated" : classification === "upstream_connection_error" ? "Upstream LLM connection error" : message || "Agent error";
|
|
19846
|
+
this.logger.error(`send_${phase}_task_message_failed`, {
|
|
19847
|
+
classification,
|
|
19848
|
+
message
|
|
19849
|
+
});
|
|
19850
|
+
return this.signalTaskComplete(payload, "error", errorMessage);
|
|
19851
|
+
}
|
|
19684
19852
|
async sendInitialTaskMessage(payload, prefetchedRun) {
|
|
19685
19853
|
if (!this.session) return;
|
|
19686
19854
|
let taskRun = prefetchedRun ?? null;
|
|
@@ -19773,7 +19941,7 @@ var AgentServer = class _AgentServer {
|
|
|
19773
19941
|
if (this.session) {
|
|
19774
19942
|
await this.session.logWriter.flushAll();
|
|
19775
19943
|
}
|
|
19776
|
-
await this.
|
|
19944
|
+
await this.classifyAndSignalFailure(payload, "initial", error);
|
|
19777
19945
|
}
|
|
19778
19946
|
}
|
|
19779
19947
|
async sendResumeMessage(payload, taskRun) {
|
|
@@ -19847,7 +20015,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
19847
20015
|
if (this.session) {
|
|
19848
20016
|
await this.session.logWriter.flushAll();
|
|
19849
20017
|
}
|
|
19850
|
-
await this.
|
|
20018
|
+
await this.classifyAndSignalFailure(payload, "resume", error);
|
|
19851
20019
|
}
|
|
19852
20020
|
}
|
|
19853
20021
|
static RESUME_HISTORY_TOKEN_BUDGET = 5e4;
|
|
@@ -20205,7 +20373,7 @@ ${attributionInstructions}
|
|
|
20205
20373
|
});
|
|
20206
20374
|
}
|
|
20207
20375
|
}
|
|
20208
|
-
async signalTaskComplete(payload, stopReason) {
|
|
20376
|
+
async signalTaskComplete(payload, stopReason, errorMessage) {
|
|
20209
20377
|
if (this.session?.payload.run_id === payload.run_id) {
|
|
20210
20378
|
try {
|
|
20211
20379
|
await this.session.logWriter.flush(payload.run_id, {
|
|
@@ -20229,7 +20397,7 @@ ${attributionInstructions}
|
|
|
20229
20397
|
try {
|
|
20230
20398
|
await this.posthogAPI.updateTaskRun(payload.task_id, payload.run_id, {
|
|
20231
20399
|
status,
|
|
20232
|
-
error_message:
|
|
20400
|
+
error_message: errorMessage ?? "Agent error"
|
|
20233
20401
|
});
|
|
20234
20402
|
this.logger.info("Task completion signaled", { status, stopReason });
|
|
20235
20403
|
} catch (error) {
|