@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/package.json
CHANGED
|
@@ -170,16 +170,17 @@ function createClaudeConnection(config: AcpConnectionConfig): AcpConnection {
|
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
const taskRunId = config.taskRunId;
|
|
173
174
|
agentWritable = createTappedWritableStream(streams.agent.writable, {
|
|
174
175
|
onMessage: (line) => {
|
|
175
|
-
logWriter.appendRawLine(
|
|
176
|
+
logWriter.appendRawLine(taskRunId, line);
|
|
176
177
|
},
|
|
177
178
|
logger,
|
|
178
179
|
});
|
|
179
180
|
|
|
180
181
|
clientWritable = createTappedWritableStream(streams.client.writable, {
|
|
181
182
|
onMessage: (line) => {
|
|
182
|
-
logWriter.appendRawLine(
|
|
183
|
+
logWriter.appendRawLine(taskRunId, line);
|
|
183
184
|
},
|
|
184
185
|
logger,
|
|
185
186
|
});
|
|
@@ -425,8 +426,8 @@ function createCodexConnection(config: AcpConnectionConfig): AcpConnection {
|
|
|
425
426
|
|
|
426
427
|
const shouldTapLogs = config.taskRunId && logWriter;
|
|
427
428
|
|
|
428
|
-
if (shouldTapLogs) {
|
|
429
|
-
const taskRunId = config.taskRunId
|
|
429
|
+
if (shouldTapLogs && config.taskRunId) {
|
|
430
|
+
const taskRunId = config.taskRunId;
|
|
430
431
|
if (!logWriter.isRegistered(taskRunId)) {
|
|
431
432
|
logWriter.register(taskRunId, {
|
|
432
433
|
taskId: config.taskId ?? taskRunId,
|
|
@@ -181,7 +181,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
|
|
|
181
181
|
|
|
182
182
|
if (meta?.taskRunId) {
|
|
183
183
|
await this.client.extNotification("_posthog/sdk_session", {
|
|
184
|
-
taskRunId: meta.taskRunId
|
|
184
|
+
taskRunId: meta.taskRunId,
|
|
185
185
|
sessionId,
|
|
186
186
|
adapter: "claude",
|
|
187
187
|
});
|
|
@@ -5,7 +5,10 @@ import type {
|
|
|
5
5
|
} from "@agentclientprotocol/sdk";
|
|
6
6
|
import { RequestError } from "@agentclientprotocol/sdk";
|
|
7
7
|
import type {
|
|
8
|
+
SDKAssistantMessage,
|
|
9
|
+
SDKMessage,
|
|
8
10
|
SDKPartialAssistantMessage,
|
|
11
|
+
SDKResultMessage,
|
|
9
12
|
SDKUserMessage,
|
|
10
13
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
11
14
|
import type { ContentBlockParam } from "@anthropic-ai/sdk/resources";
|
|
@@ -357,7 +360,7 @@ function streamEventToAcpNotifications(
|
|
|
357
360
|
}
|
|
358
361
|
|
|
359
362
|
export async function handleSystemMessage(
|
|
360
|
-
message:
|
|
363
|
+
message: Extract<SDKMessage, { type: "system" }>,
|
|
361
364
|
context: MessageHandlerContext,
|
|
362
365
|
): Promise<void> {
|
|
363
366
|
const { sessionId, client, logger } = context;
|
|
@@ -409,7 +412,7 @@ export async function handleSystemMessage(
|
|
|
409
412
|
}
|
|
410
413
|
|
|
411
414
|
export function handleResultMessage(
|
|
412
|
-
message:
|
|
415
|
+
message: SDKResultMessage,
|
|
413
416
|
context: MessageHandlerContext,
|
|
414
417
|
): { shouldStop: boolean; stopReason?: string; error?: Error } {
|
|
415
418
|
const { session } = context;
|
|
@@ -556,7 +559,7 @@ function filterMessageContent(
|
|
|
556
559
|
}
|
|
557
560
|
|
|
558
561
|
export async function handleUserAssistantMessage(
|
|
559
|
-
message: SDKUserMessage |
|
|
562
|
+
message: SDKUserMessage | SDKAssistantMessage,
|
|
560
563
|
context: MessageHandlerContext,
|
|
561
564
|
): Promise<{ shouldStop?: boolean; error?: Error }> {
|
|
562
565
|
const { session, sessionId, client, toolUseCache, fileContentCache, logger } =
|
|
@@ -554,6 +554,31 @@ export function toolUpdateFromToolResult(
|
|
|
554
554
|
}
|
|
555
555
|
return { title: "Question answered" };
|
|
556
556
|
}
|
|
557
|
+
case "WebFetch": {
|
|
558
|
+
const input = toolUse?.input as Record<string, unknown> | undefined;
|
|
559
|
+
const url = input?.url ? String(input.url) : "";
|
|
560
|
+
const prompt = input?.prompt ? String(input.prompt) : undefined;
|
|
561
|
+
|
|
562
|
+
const resultContent = toAcpContentUpdate(
|
|
563
|
+
toolResult.content,
|
|
564
|
+
"is_error" in toolResult ? toolResult.is_error : false,
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
const content: ToolCallContent[] = [];
|
|
568
|
+
if (url) {
|
|
569
|
+
content.push({
|
|
570
|
+
type: "content",
|
|
571
|
+
content: resourceLink(url, url, {
|
|
572
|
+
description: prompt,
|
|
573
|
+
}),
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
if (resultContent.content) {
|
|
577
|
+
content.push(...resultContent.content);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
return { content };
|
|
581
|
+
}
|
|
557
582
|
default: {
|
|
558
583
|
return toAcpContentUpdate(
|
|
559
584
|
toolResult.content,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
McpHttpServerConfig,
|
|
3
|
+
McpServerConfig,
|
|
4
|
+
} from "@anthropic-ai/claude-agent-sdk";
|
|
2
5
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
6
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
7
|
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -16,17 +19,17 @@ function buildToolKey(serverName: string, toolName: string): string {
|
|
|
16
19
|
|
|
17
20
|
function isHttpMcpServer(
|
|
18
21
|
config: McpServerConfig,
|
|
19
|
-
): config is
|
|
20
|
-
return config.type === "http" && typeof
|
|
22
|
+
): config is McpHttpServerConfig {
|
|
23
|
+
return config.type === "http" && typeof config.url === "string";
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
async function fetchToolsFromHttpServer(
|
|
24
27
|
_serverName: string,
|
|
25
|
-
config:
|
|
28
|
+
config: McpHttpServerConfig,
|
|
26
29
|
): Promise<Tool[]> {
|
|
27
30
|
const transport = new StreamableHTTPClientTransport(new URL(config.url), {
|
|
28
31
|
requestInit: {
|
|
29
|
-
headers:
|
|
32
|
+
headers: config.headers ?? {},
|
|
30
33
|
},
|
|
31
34
|
});
|
|
32
35
|
|
|
@@ -192,7 +192,7 @@ async function applyPlanApproval(
|
|
|
192
192
|
async function handleEnterPlanModeTool(
|
|
193
193
|
context: ToolHandlerContext,
|
|
194
194
|
): Promise<ToolPermissionResult> {
|
|
195
|
-
const { session, toolInput
|
|
195
|
+
const { session, toolInput } = context;
|
|
196
196
|
|
|
197
197
|
session.permissionMode = "plan";
|
|
198
198
|
await session.query.setPermissionMode("plan");
|
|
@@ -152,9 +152,15 @@ function buildSpawnWrapper(
|
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
if (!child.stdin || !child.stdout) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Failed to get stdio streams for spawned process (pid=${child.pid})`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
155
161
|
return {
|
|
156
|
-
stdin: child.stdin
|
|
157
|
-
stdout: child.stdout
|
|
162
|
+
stdin: child.stdin,
|
|
163
|
+
stdout: child.stdout,
|
|
158
164
|
get killed() {
|
|
159
165
|
return child.killed;
|
|
160
166
|
},
|
|
@@ -164,12 +170,15 @@ function buildSpawnWrapper(
|
|
|
164
170
|
kill(signal: NodeJS.Signals) {
|
|
165
171
|
return child.kill(signal);
|
|
166
172
|
},
|
|
173
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
167
174
|
on(event: "exit" | "error", listener: (...args: any[]) => void) {
|
|
168
175
|
child.on(event, listener);
|
|
169
176
|
},
|
|
177
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
170
178
|
once(event: "exit" | "error", listener: (...args: any[]) => void) {
|
|
171
179
|
child.once(event, listener);
|
|
172
180
|
},
|
|
181
|
+
// biome-ignore lint/suspicious/noExplicitAny: ChildProcess event listener types require any[]
|
|
173
182
|
off(event: "exit" | "error", listener: (...args: any[]) => void) {
|
|
174
183
|
child.off(event, listener);
|
|
175
184
|
},
|
package/src/agent.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
DEFAULT_GATEWAY_MODEL,
|
|
8
8
|
fetchArrayModels,
|
|
9
9
|
} from "./gateway-models.js";
|
|
10
|
-
import { PostHogAPIClient } from "./posthog-api.js";
|
|
10
|
+
import { PostHogAPIClient, type TaskRunUpdate } from "./posthog-api.js";
|
|
11
11
|
import { SessionLogWriter } from "./session-log-writer.js";
|
|
12
12
|
import type { AgentConfig, TaskExecutionOptions } from "./types.js";
|
|
13
13
|
import { Logger } from "./utils/logger.js";
|
|
@@ -142,7 +142,7 @@ export class Agent {
|
|
|
142
142
|
throw error;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
const updates:
|
|
145
|
+
const updates: TaskRunUpdate = {
|
|
146
146
|
output: { pr_url: prUrl },
|
|
147
147
|
};
|
|
148
148
|
if (branchName) {
|
|
@@ -33,27 +33,30 @@ export class ApplySnapshotSaga extends Saga<
|
|
|
33
33
|
throw new Error("Cannot apply snapshot: no archive URL");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const archiveUrl = snapshot.archiveUrl;
|
|
37
|
+
|
|
36
38
|
await this.step({
|
|
37
39
|
name: "create_tmp_dir",
|
|
38
40
|
execute: () => mkdir(tmpDir, { recursive: true }),
|
|
39
41
|
rollback: async () => {},
|
|
40
42
|
});
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
const archivePath = join(tmpDir, `${snapshot.treeHash}.tar.gz`);
|
|
45
|
+
this.archivePath = archivePath;
|
|
43
46
|
await this.step({
|
|
44
47
|
name: "download_archive",
|
|
45
48
|
execute: async () => {
|
|
46
49
|
const arrayBuffer = await apiClient.downloadArtifact(
|
|
47
50
|
taskId,
|
|
48
51
|
runId,
|
|
49
|
-
|
|
52
|
+
archiveUrl,
|
|
50
53
|
);
|
|
51
54
|
if (!arrayBuffer) {
|
|
52
55
|
throw new Error("Failed to download archive");
|
|
53
56
|
}
|
|
54
57
|
const base64Content = Buffer.from(arrayBuffer).toString("utf-8");
|
|
55
58
|
const binaryContent = Buffer.from(base64Content, "base64");
|
|
56
|
-
await writeFile(
|
|
59
|
+
await writeFile(archivePath, binaryContent);
|
|
57
60
|
},
|
|
58
61
|
rollback: async () => {
|
|
59
62
|
if (this.archivePath) {
|
|
@@ -583,7 +583,7 @@ describe("CaptureTreeSaga", () => {
|
|
|
583
583
|
});
|
|
584
584
|
|
|
585
585
|
it("handles symlinks", async () => {
|
|
586
|
-
const { symlink
|
|
586
|
+
const { symlink } = await import("node:fs/promises");
|
|
587
587
|
|
|
588
588
|
await repo.writeFile("target.txt", "symlink target content");
|
|
589
589
|
await symlink("target.txt", join(repo.path, "link.txt"));
|