@posthog/agent 2.3.209 → 2.3.213
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +1 -1
- 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 +1 -1
- package/dist/server/agent-server.js +82 -25
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +82 -25
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/server/agent-server.test.ts +24 -0
- package/src/server/agent-server.ts +60 -31
- package/src/server/cloud-prompt.ts +13 -0
- package/src/server/question-relay.test.ts +47 -0
- package/src/server/schemas.test.ts +19 -1
- package/src/server/schemas.ts +4 -1
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.213",
|
|
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.209\",\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 \"./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.16.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.76\",\n \"@anthropic-ai/sdk\": \"^0.78.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\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n // Local development (normalize 127.0.0.1 to localhost)\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308/${product}`;\n }\n\n // Docker containers accessing host\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308/${product}`;\n }\n\n // Production - extract region from hostname, default to US\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com/${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 { getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { 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 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":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/utils/gateway.ts","../src/posthog-api.ts"],"sourcesContent":["{\n \"name\": \"@posthog/agent\",\n \"version\": \"2.3.213\",\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 \"./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.16.1\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.2.76\",\n \"@anthropic-ai/sdk\": \"^0.78.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\nexport function getLlmGatewayUrl(\n posthogHost: string,\n product: GatewayProduct = \"posthog_code\",\n): string {\n const url = new URL(posthogHost);\n const hostname = url.hostname;\n\n // Local development (normalize 127.0.0.1 to localhost)\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n return `${url.protocol}//localhost:3308/${product}`;\n }\n\n // Docker containers accessing host\n if (hostname === \"host.docker.internal\") {\n return `${url.protocol}//host.docker.internal:3308/${product}`;\n }\n\n // Production - extract region from hostname, default to US\n const region = hostname.match(/^(us|eu)\\.posthog\\.com$/)?.[1] ?? \"us\";\n return `https://gateway.${region}.posthog.com/${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 { getLlmGatewayUrl } from \"./utils/gateway\";\n\nexport { 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 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":"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","names":[]}
|
|
@@ -73,7 +73,7 @@ declare class AgentServer {
|
|
|
73
73
|
private static TOOL_RESULT_MAX_CHARS;
|
|
74
74
|
private formatConversationForResume;
|
|
75
75
|
private getInitialPromptOverride;
|
|
76
|
-
private
|
|
76
|
+
private getPendingUserPrompt;
|
|
77
77
|
private getResumeRunId;
|
|
78
78
|
private buildSessionSystemPrompt;
|
|
79
79
|
private buildCloudSystemPrompt;
|
|
@@ -908,7 +908,7 @@ import { Hono } from "hono";
|
|
|
908
908
|
// package.json
|
|
909
909
|
var package_default = {
|
|
910
910
|
name: "@posthog/agent",
|
|
911
|
-
version: "2.3.
|
|
911
|
+
version: "2.3.213",
|
|
912
912
|
repository: "https://github.com/PostHog/code",
|
|
913
913
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
914
914
|
exports: {
|
|
@@ -5991,6 +5991,27 @@ var PostHogAPIClient = class {
|
|
|
5991
5991
|
};
|
|
5992
5992
|
|
|
5993
5993
|
// ../shared/dist/index.js
|
|
5994
|
+
var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
|
|
5995
|
+
function deserializeCloudPrompt(value) {
|
|
5996
|
+
const trimmed2 = value.trim();
|
|
5997
|
+
if (!trimmed2) {
|
|
5998
|
+
return [];
|
|
5999
|
+
}
|
|
6000
|
+
if (!trimmed2.startsWith(CLOUD_PROMPT_PREFIX)) {
|
|
6001
|
+
return [{ type: "text", text: trimmed2 }];
|
|
6002
|
+
}
|
|
6003
|
+
try {
|
|
6004
|
+
const parsed = JSON.parse(trimmed2.slice(CLOUD_PROMPT_PREFIX.length));
|
|
6005
|
+
if (Array.isArray(parsed.blocks) && parsed.blocks.length > 0) {
|
|
6006
|
+
return parsed.blocks;
|
|
6007
|
+
}
|
|
6008
|
+
} catch {
|
|
6009
|
+
}
|
|
6010
|
+
return [{ type: "text", text: trimmed2 }];
|
|
6011
|
+
}
|
|
6012
|
+
function promptBlocksToText(blocks) {
|
|
6013
|
+
return blocks.filter((b) => b.type === "text").map((block) => block.text).join("").trim();
|
|
6014
|
+
}
|
|
5994
6015
|
var consoleLogger = {
|
|
5995
6016
|
info: (_message, _data) => {
|
|
5996
6017
|
},
|
|
@@ -12086,6 +12107,14 @@ var AsyncMutex = class {
|
|
|
12086
12107
|
}
|
|
12087
12108
|
};
|
|
12088
12109
|
|
|
12110
|
+
// src/server/cloud-prompt.ts
|
|
12111
|
+
function normalizeCloudPromptContent(content) {
|
|
12112
|
+
if (typeof content === "string") {
|
|
12113
|
+
return deserializeCloudPrompt(content);
|
|
12114
|
+
}
|
|
12115
|
+
return content;
|
|
12116
|
+
}
|
|
12117
|
+
|
|
12089
12118
|
// src/server/jwt.ts
|
|
12090
12119
|
import jwt from "jsonwebtoken";
|
|
12091
12120
|
import { z as z2 } from "zod";
|
|
@@ -12169,7 +12198,10 @@ var jsonRpcRequestSchema = z3.object({
|
|
|
12169
12198
|
id: z3.union([z3.string(), z3.number()]).optional()
|
|
12170
12199
|
});
|
|
12171
12200
|
var userMessageParamsSchema = z3.object({
|
|
12172
|
-
content: z3.
|
|
12201
|
+
content: z3.union([
|
|
12202
|
+
z3.string().min(1, "Content is required"),
|
|
12203
|
+
z3.array(z3.record(z3.string(), z3.unknown())).min(1, "Content is required")
|
|
12204
|
+
])
|
|
12173
12205
|
});
|
|
12174
12206
|
var commandParamsSchemas = {
|
|
12175
12207
|
user_message: userMessageParamsSchema,
|
|
@@ -12550,14 +12582,17 @@ var AgentServer = class _AgentServer {
|
|
|
12550
12582
|
switch (method) {
|
|
12551
12583
|
case POSTHOG_NOTIFICATIONS.USER_MESSAGE:
|
|
12552
12584
|
case "user_message": {
|
|
12553
|
-
const
|
|
12585
|
+
const prompt = normalizeCloudPromptContent(
|
|
12586
|
+
params.content
|
|
12587
|
+
);
|
|
12588
|
+
const promptPreview = promptBlocksToText(prompt);
|
|
12554
12589
|
this.logger.info(
|
|
12555
|
-
`Processing user message (detectedPrUrl=${this.detectedPrUrl ?? "none"}): ${
|
|
12590
|
+
`Processing user message (detectedPrUrl=${this.detectedPrUrl ?? "none"}): ${promptPreview.substring(0, 100)}...`
|
|
12556
12591
|
);
|
|
12557
12592
|
this.session.logWriter.resetTurnMessages(this.session.payload.run_id);
|
|
12558
12593
|
const result = await this.session.clientConnection.prompt({
|
|
12559
12594
|
sessionId: this.session.acpSessionId,
|
|
12560
|
-
prompt
|
|
12595
|
+
prompt,
|
|
12561
12596
|
...this.detectedPrUrl && {
|
|
12562
12597
|
_meta: {
|
|
12563
12598
|
prContext: `IMPORTANT \u2014 OVERRIDE PREVIOUS INSTRUCTIONS ABOUT CREATING BRANCHES/PRs.
|
|
@@ -12817,20 +12852,29 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
|
|
|
12817
12852
|
try {
|
|
12818
12853
|
const task = await this.posthogAPI.getTask(payload.task_id);
|
|
12819
12854
|
const initialPromptOverride = taskRun ? this.getInitialPromptOverride(taskRun) : null;
|
|
12820
|
-
const
|
|
12821
|
-
|
|
12855
|
+
const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
|
|
12856
|
+
let initialPrompt = [];
|
|
12857
|
+
if (pendingUserPrompt?.length) {
|
|
12858
|
+
initialPrompt = pendingUserPrompt;
|
|
12859
|
+
} else if (initialPromptOverride) {
|
|
12860
|
+
initialPrompt = [{ type: "text", text: initialPromptOverride }];
|
|
12861
|
+
} else if (task.description) {
|
|
12862
|
+
initialPrompt = [{ type: "text", text: task.description }];
|
|
12863
|
+
}
|
|
12864
|
+
if (initialPrompt.length === 0) {
|
|
12822
12865
|
this.logger.warn("Task has no description, skipping initial message");
|
|
12823
12866
|
return;
|
|
12824
12867
|
}
|
|
12825
12868
|
this.logger.info("Sending initial task message", {
|
|
12826
12869
|
taskId: payload.task_id,
|
|
12827
|
-
descriptionLength: initialPrompt.length,
|
|
12828
|
-
usedInitialPromptOverride: !!initialPromptOverride
|
|
12870
|
+
descriptionLength: promptBlocksToText(initialPrompt).length,
|
|
12871
|
+
usedInitialPromptOverride: !!initialPromptOverride,
|
|
12872
|
+
usedPendingUserMessage: !!pendingUserPrompt?.length
|
|
12829
12873
|
});
|
|
12830
12874
|
this.session.logWriter.resetTurnMessages(payload.run_id);
|
|
12831
12875
|
const result = await this.session.clientConnection.prompt({
|
|
12832
12876
|
sessionId: this.session.acpSessionId,
|
|
12833
|
-
prompt:
|
|
12877
|
+
prompt: initialPrompt
|
|
12834
12878
|
});
|
|
12835
12879
|
this.logger.info("Initial task message completed", {
|
|
12836
12880
|
stopReason: result.stopReason
|
|
@@ -12853,11 +12897,14 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`
|
|
|
12853
12897
|
const conversationSummary = this.formatConversationForResume(
|
|
12854
12898
|
this.resumeState.conversation
|
|
12855
12899
|
);
|
|
12856
|
-
const
|
|
12900
|
+
const pendingUserPrompt = this.getPendingUserPrompt(taskRun);
|
|
12857
12901
|
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.`;
|
|
12858
|
-
let
|
|
12859
|
-
if (
|
|
12860
|
-
|
|
12902
|
+
let resumePromptBlocks;
|
|
12903
|
+
if (pendingUserPrompt?.length) {
|
|
12904
|
+
resumePromptBlocks = [
|
|
12905
|
+
{
|
|
12906
|
+
type: "text",
|
|
12907
|
+
text: `You are resuming a previous conversation. ${sandboxContext}
|
|
12861
12908
|
|
|
12862
12909
|
Here is the conversation history from the previous session:
|
|
12863
12910
|
|
|
@@ -12865,30 +12912,40 @@ ${conversationSummary}
|
|
|
12865
12912
|
|
|
12866
12913
|
The user has sent a new message:
|
|
12867
12914
|
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12915
|
+
`
|
|
12916
|
+
},
|
|
12917
|
+
...pendingUserPrompt,
|
|
12918
|
+
{
|
|
12919
|
+
type: "text",
|
|
12920
|
+
text: "\n\nRespond to the user's new message above. You have full context from the previous session."
|
|
12921
|
+
}
|
|
12922
|
+
];
|
|
12871
12923
|
} else {
|
|
12872
|
-
|
|
12924
|
+
resumePromptBlocks = [
|
|
12925
|
+
{
|
|
12926
|
+
type: "text",
|
|
12927
|
+
text: `You are resuming a previous conversation. ${sandboxContext}
|
|
12873
12928
|
|
|
12874
12929
|
Here is the conversation history from the previous session:
|
|
12875
12930
|
|
|
12876
12931
|
${conversationSummary}
|
|
12877
12932
|
|
|
12878
|
-
Continue from where you left off. The user is waiting for your response
|
|
12933
|
+
Continue from where you left off. The user is waiting for your response.`
|
|
12934
|
+
}
|
|
12935
|
+
];
|
|
12879
12936
|
}
|
|
12880
12937
|
this.logger.info("Sending resume message", {
|
|
12881
12938
|
taskId: payload.task_id,
|
|
12882
12939
|
conversationTurns: this.resumeState.conversation.length,
|
|
12883
|
-
promptLength:
|
|
12884
|
-
hasPendingUserMessage: !!
|
|
12940
|
+
promptLength: promptBlocksToText(resumePromptBlocks).length,
|
|
12941
|
+
hasPendingUserMessage: !!pendingUserPrompt?.length,
|
|
12885
12942
|
snapshotApplied: this.resumeState.snapshotApplied
|
|
12886
12943
|
});
|
|
12887
12944
|
this.resumeState = null;
|
|
12888
12945
|
this.session.logWriter.resetTurnMessages(payload.run_id);
|
|
12889
12946
|
const result = await this.session.clientConnection.prompt({
|
|
12890
12947
|
sessionId: this.session.acpSessionId,
|
|
12891
|
-
prompt:
|
|
12948
|
+
prompt: resumePromptBlocks
|
|
12892
12949
|
});
|
|
12893
12950
|
this.logger.info("Resume message completed", {
|
|
12894
12951
|
stopReason: result.stopReason
|
|
@@ -12948,15 +13005,15 @@ ${toolSummary}`);
|
|
|
12948
13005
|
const trimmed2 = override.trim();
|
|
12949
13006
|
return trimmed2.length > 0 ? trimmed2 : null;
|
|
12950
13007
|
}
|
|
12951
|
-
|
|
13008
|
+
getPendingUserPrompt(taskRun) {
|
|
12952
13009
|
if (!taskRun) return null;
|
|
12953
13010
|
const state = taskRun.state;
|
|
12954
13011
|
const message = state?.pending_user_message;
|
|
12955
13012
|
if (typeof message !== "string") {
|
|
12956
13013
|
return null;
|
|
12957
13014
|
}
|
|
12958
|
-
const
|
|
12959
|
-
return
|
|
13015
|
+
const prompt = deserializeCloudPrompt(message);
|
|
13016
|
+
return prompt.length > 0 ? prompt : null;
|
|
12960
13017
|
}
|
|
12961
13018
|
getResumeRunId(taskRun) {
|
|
12962
13019
|
const envRunId = process.env.POSTHOG_RESUME_RUN_ID;
|