@posthog/agent 2.1.82 → 2.1.85
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/conversion/tool-use-to-acp.js +22 -0
- package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -1
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/tools.js.map +1 -1
- package/dist/agent.js +37 -6
- package/dist/agent.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/agent-server.js +46 -11
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +46 -11
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/acp-connection.ts +5 -4
- package/src/adapters/claude/claude-agent.ts +1 -1
- package/src/adapters/claude/conversion/sdk-to-acp.ts +6 -3
- package/src/adapters/claude/conversion/tool-use-to-acp.ts +25 -0
- package/src/adapters/claude/mcp/tool-metadata.ts +8 -5
- package/src/adapters/claude/permissions/permission-handlers.ts +1 -1
- package/src/adapters/claude/session/options.ts +11 -2
- package/src/agent.ts +2 -2
- package/src/sagas/apply-snapshot-saga.ts +6 -3
- package/src/sagas/capture-tree-saga.test.ts +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/claude/mcp/tool-metadata.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../src/adapters/claude/mcp/tool-metadata.ts"],"sourcesContent":["import type {\n McpHttpServerConfig,\n McpServerConfig,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Tool } from \"@modelcontextprotocol/sdk/types.js\";\nimport { Logger } from \"../../../utils/logger.js\";\n\nexport interface McpToolMetadata {\n readOnly: boolean;\n}\n\nconst mcpToolMetadataCache: Map<string, McpToolMetadata> = new Map();\n\nfunction buildToolKey(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`;\n}\n\nfunction isHttpMcpServer(\n config: McpServerConfig,\n): config is McpHttpServerConfig {\n return config.type === \"http\" && typeof config.url === \"string\";\n}\n\nasync function fetchToolsFromHttpServer(\n _serverName: string,\n config: McpHttpServerConfig,\n): Promise<Tool[]> {\n const transport = new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: {\n headers: config.headers ?? {},\n },\n });\n\n const client = new Client({\n name: \"twig-metadata-fetcher\",\n version: \"1.0.0\",\n });\n\n try {\n await client.connect(transport);\n const result = await client.listTools();\n return result.tools;\n } finally {\n await client.close().catch(() => {});\n }\n}\n\nfunction extractToolMetadata(tool: Tool): McpToolMetadata {\n return {\n readOnly: tool.annotations?.readOnlyHint === true,\n };\n}\n\nexport async function fetchMcpToolMetadata(\n mcpServers: Record<string, McpServerConfig>,\n logger: Logger = new Logger({ debug: false, prefix: \"[McpToolMetadata]\" }),\n): Promise<void> {\n const fetchPromises: Promise<void>[] = [];\n\n for (const [serverName, config] of Object.entries(mcpServers)) {\n if (!isHttpMcpServer(config)) {\n continue;\n }\n\n const fetchPromise = fetchToolsFromHttpServer(serverName, config)\n .then((tools) => {\n const toolCount = tools.length;\n const readOnlyCount = tools.filter(\n (t) => t.annotations?.readOnlyHint === true,\n ).length;\n\n for (const tool of tools) {\n const toolKey = buildToolKey(serverName, tool.name);\n mcpToolMetadataCache.set(toolKey, extractToolMetadata(tool));\n }\n\n logger.info(\"Fetched MCP tool metadata\", {\n serverName,\n toolCount,\n readOnlyCount,\n });\n })\n .catch((error) => {\n logger.error(\"Failed to fetch MCP tool metadata\", {\n serverName,\n error: error instanceof Error ? error.message : String(error),\n });\n });\n\n fetchPromises.push(fetchPromise);\n }\n\n await Promise.all(fetchPromises);\n}\n\nexport function isMcpToolReadOnly(toolName: string): boolean {\n const metadata = mcpToolMetadataCache.get(toolName);\n return metadata?.readOnly === true;\n}\n\nexport function clearMcpToolMetadataCache(): void {\n mcpToolMetadataCache.clear();\n}\n"],"mappings":";AAIA,SAAS,cAAc;AACvB,SAAS,qCAAqC;AAQ9C,IAAM,uBAAqD,oBAAI,IAAI;AAoF5D,SAAS,kBAAkB,UAA2B;AAC3D,QAAM,WAAW,qBAAqB,IAAI,QAAQ;AAClD,SAAO,UAAU,aAAa;AAChC;","names":[]}
|
|
@@ -1183,7 +1183,7 @@ import { v7 as uuidv7 } from "uuid";
|
|
|
1183
1183
|
// package.json
|
|
1184
1184
|
var package_default = {
|
|
1185
1185
|
name: "@posthog/agent",
|
|
1186
|
-
version: "2.1.
|
|
1186
|
+
version: "2.1.85",
|
|
1187
1187
|
repository: "https://github.com/PostHog/twig",
|
|
1188
1188
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
1189
1189
|
exports: {
|
|
@@ -2009,6 +2009,28 @@ function toolUpdateFromToolResult(toolResult, toolUse) {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
return { title: "Question answered" };
|
|
2011
2011
|
}
|
|
2012
|
+
case "WebFetch": {
|
|
2013
|
+
const input = toolUse?.input;
|
|
2014
|
+
const url = input?.url ? String(input.url) : "";
|
|
2015
|
+
const prompt = input?.prompt ? String(input.prompt) : void 0;
|
|
2016
|
+
const resultContent = toAcpContentUpdate(
|
|
2017
|
+
toolResult.content,
|
|
2018
|
+
"is_error" in toolResult ? toolResult.is_error : false
|
|
2019
|
+
);
|
|
2020
|
+
const content = [];
|
|
2021
|
+
if (url) {
|
|
2022
|
+
content.push({
|
|
2023
|
+
type: "content",
|
|
2024
|
+
content: resourceLink(url, url, {
|
|
2025
|
+
description: prompt
|
|
2026
|
+
})
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
if (resultContent.content) {
|
|
2030
|
+
content.push(...resultContent.content);
|
|
2031
|
+
}
|
|
2032
|
+
return { content };
|
|
2033
|
+
}
|
|
2012
2034
|
default: {
|
|
2013
2035
|
return toAcpContentUpdate(
|
|
2014
2036
|
toolResult.content,
|
|
@@ -2475,7 +2497,7 @@ function isHttpMcpServer(config) {
|
|
|
2475
2497
|
async function fetchToolsFromHttpServer(_serverName, config) {
|
|
2476
2498
|
const transport = new StreamableHTTPClientTransport(new URL(config.url), {
|
|
2477
2499
|
requestInit: {
|
|
2478
|
-
headers: config.headers
|
|
2500
|
+
headers: config.headers ?? {}
|
|
2479
2501
|
}
|
|
2480
2502
|
});
|
|
2481
2503
|
const client = new Client({
|
|
@@ -2855,7 +2877,7 @@ async function applyPlanApproval(response, context, updatedInput) {
|
|
|
2855
2877
|
return { behavior: "deny", message, interrupt: false };
|
|
2856
2878
|
}
|
|
2857
2879
|
async function handleEnterPlanModeTool(context) {
|
|
2858
|
-
const { session, toolInput
|
|
2880
|
+
const { session, toolInput } = context;
|
|
2859
2881
|
session.permissionMode = "plan";
|
|
2860
2882
|
await session.query.setPermissionMode("plan");
|
|
2861
2883
|
await context.emitConfigOptionsUpdate();
|
|
@@ -3203,6 +3225,11 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited) {
|
|
|
3203
3225
|
child.kill("SIGTERM");
|
|
3204
3226
|
});
|
|
3205
3227
|
}
|
|
3228
|
+
if (!child.stdin || !child.stdout) {
|
|
3229
|
+
throw new Error(
|
|
3230
|
+
`Failed to get stdio streams for spawned process (pid=${child.pid})`
|
|
3231
|
+
);
|
|
3232
|
+
}
|
|
3206
3233
|
return {
|
|
3207
3234
|
stdin: child.stdin,
|
|
3208
3235
|
stdout: child.stdout,
|
|
@@ -3215,12 +3242,15 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited) {
|
|
|
3215
3242
|
kill(signal) {
|
|
3216
3243
|
return child.kill(signal);
|
|
3217
3244
|
},
|
|
3245
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
3218
3246
|
on(event, listener) {
|
|
3219
3247
|
child.on(event, listener);
|
|
3220
3248
|
},
|
|
3249
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
3221
3250
|
once(event, listener) {
|
|
3222
3251
|
child.once(event, listener);
|
|
3223
3252
|
},
|
|
3253
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
3224
3254
|
off(event, listener) {
|
|
3225
3255
|
child.off(event, listener);
|
|
3226
3256
|
}
|
|
@@ -3901,15 +3931,16 @@ function createClaudeConnection(config) {
|
|
|
3901
3931
|
deviceType: config.deviceType
|
|
3902
3932
|
});
|
|
3903
3933
|
}
|
|
3934
|
+
const taskRunId = config.taskRunId;
|
|
3904
3935
|
agentWritable = createTappedWritableStream(streams.agent.writable, {
|
|
3905
3936
|
onMessage: (line) => {
|
|
3906
|
-
logWriter.appendRawLine(
|
|
3937
|
+
logWriter.appendRawLine(taskRunId, line);
|
|
3907
3938
|
},
|
|
3908
3939
|
logger
|
|
3909
3940
|
});
|
|
3910
3941
|
clientWritable = createTappedWritableStream(streams.client.writable, {
|
|
3911
3942
|
onMessage: (line) => {
|
|
3912
|
-
logWriter.appendRawLine(
|
|
3943
|
+
logWriter.appendRawLine(taskRunId, line);
|
|
3913
3944
|
},
|
|
3914
3945
|
logger
|
|
3915
3946
|
});
|
|
@@ -4105,7 +4136,7 @@ function createCodexConnection(config) {
|
|
|
4105
4136
|
}
|
|
4106
4137
|
});
|
|
4107
4138
|
const shouldTapLogs = config.taskRunId && logWriter;
|
|
4108
|
-
if (shouldTapLogs) {
|
|
4139
|
+
if (shouldTapLogs && config.taskRunId) {
|
|
4109
4140
|
const taskRunId2 = config.taskRunId;
|
|
4110
4141
|
if (!logWriter.isRegistered(taskRunId2)) {
|
|
4111
4142
|
logWriter.register(taskRunId2, {
|
|
@@ -9237,11 +9268,13 @@ var AsyncReaderWriterLock = class {
|
|
|
9237
9268
|
return;
|
|
9238
9269
|
if (this.writeQueue.length > 0) {
|
|
9239
9270
|
const next = this.writeQueue.shift();
|
|
9240
|
-
next
|
|
9271
|
+
if (next)
|
|
9272
|
+
next();
|
|
9241
9273
|
} else {
|
|
9242
9274
|
while (this.readQueue.length > 0 && !this.writerWaiting) {
|
|
9243
9275
|
const next = this.readQueue.shift();
|
|
9244
|
-
next
|
|
9276
|
+
if (next)
|
|
9277
|
+
next();
|
|
9245
9278
|
}
|
|
9246
9279
|
}
|
|
9247
9280
|
}
|
|
@@ -9757,27 +9790,29 @@ var ApplySnapshotSaga = class extends Saga {
|
|
|
9757
9790
|
if (!snapshot.archiveUrl) {
|
|
9758
9791
|
throw new Error("Cannot apply snapshot: no archive URL");
|
|
9759
9792
|
}
|
|
9793
|
+
const archiveUrl = snapshot.archiveUrl;
|
|
9760
9794
|
await this.step({
|
|
9761
9795
|
name: "create_tmp_dir",
|
|
9762
9796
|
execute: () => mkdir3(tmpDir, { recursive: true }),
|
|
9763
9797
|
rollback: async () => {
|
|
9764
9798
|
}
|
|
9765
9799
|
});
|
|
9766
|
-
|
|
9800
|
+
const archivePath = join5(tmpDir, `${snapshot.treeHash}.tar.gz`);
|
|
9801
|
+
this.archivePath = archivePath;
|
|
9767
9802
|
await this.step({
|
|
9768
9803
|
name: "download_archive",
|
|
9769
9804
|
execute: async () => {
|
|
9770
9805
|
const arrayBuffer = await apiClient.downloadArtifact(
|
|
9771
9806
|
taskId,
|
|
9772
9807
|
runId,
|
|
9773
|
-
|
|
9808
|
+
archiveUrl
|
|
9774
9809
|
);
|
|
9775
9810
|
if (!arrayBuffer) {
|
|
9776
9811
|
throw new Error("Failed to download archive");
|
|
9777
9812
|
}
|
|
9778
9813
|
const base64Content = Buffer.from(arrayBuffer).toString("utf-8");
|
|
9779
9814
|
const binaryContent = Buffer.from(base64Content, "base64");
|
|
9780
|
-
await writeFile3(
|
|
9815
|
+
await writeFile3(archivePath, binaryContent);
|
|
9781
9816
|
},
|
|
9782
9817
|
rollback: async () => {
|
|
9783
9818
|
if (this.archivePath) {
|