@posthog/agent 2.1.120 → 2.1.125
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 +9 -6
- package/dist/agent.js.map +1 -1
- package/dist/claude-cli/cli.js +2420 -2030
- package/dist/posthog-api.js +3 -3
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +11 -8
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +26 -23
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/conversion/sdk-to-acp.ts +2 -0
- package/src/adapters/codex/spawn.ts +4 -3
- package/src/server/agent-server.test.ts +28 -11
- package/src/server/question-relay.test.ts +27 -7
- package/src/test/mocks/claude-sdk.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/agent",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.125",
|
|
4
4
|
"repository": "https://github.com/PostHog/twig",
|
|
5
5
|
"description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
6
6
|
"exports": {
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@agentclientprotocol/sdk": "^0.14.0",
|
|
79
|
-
"@anthropic-ai/claude-agent-sdk": "0.2.
|
|
80
|
-
"@anthropic-ai/sdk": "^0.
|
|
79
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.63",
|
|
80
|
+
"@anthropic-ai/sdk": "^0.78.0",
|
|
81
81
|
"@hono/node-server": "^1.19.9",
|
|
82
82
|
"@opentelemetry/api-logs": "^0.208.0",
|
|
83
83
|
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ChildProcess, spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
import { delimiter, dirname } from "node:path";
|
|
3
4
|
import type { Readable, Writable } from "node:stream";
|
|
4
5
|
import type { ProcessSpawnedCallback } from "../../types.js";
|
|
5
6
|
import { Logger } from "../../utils/logger.js";
|
|
@@ -79,8 +80,8 @@ export function spawnCodexProcess(options: CodexProcessOptions): CodexProcess {
|
|
|
79
80
|
const { command, args } = findCodexBinary(options);
|
|
80
81
|
|
|
81
82
|
if (options.binaryPath && existsSync(options.binaryPath)) {
|
|
82
|
-
const binDir = options.binaryPath
|
|
83
|
-
env.PATH = `${binDir}
|
|
83
|
+
const binDir = dirname(options.binaryPath);
|
|
84
|
+
env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
logger.info("Spawning codex-acp process", {
|
|
@@ -100,7 +101,7 @@ export function spawnCodexProcess(options: CodexProcessOptions): CodexProcess {
|
|
|
100
101
|
});
|
|
101
102
|
|
|
102
103
|
child.stderr?.on("data", (data: Buffer) => {
|
|
103
|
-
logger.
|
|
104
|
+
logger.error("codex-acp stderr:", data.toString());
|
|
104
105
|
});
|
|
105
106
|
|
|
106
107
|
child.on("error", (err) => {
|
|
@@ -7,6 +7,13 @@ import type { TaskRun } from "../types.js";
|
|
|
7
7
|
import { AgentServer } from "./agent-server.js";
|
|
8
8
|
import { type JwtPayload, SANDBOX_CONNECTION_AUDIENCE } from "./jwt.js";
|
|
9
9
|
|
|
10
|
+
interface TestableServer {
|
|
11
|
+
getInitialPromptOverride(run: TaskRun): string | null;
|
|
12
|
+
detectAndAttachPrUrl(payload: unknown, update: unknown): void;
|
|
13
|
+
detectedPrUrl: string | null;
|
|
14
|
+
buildCloudSystemPrompt(prUrl?: string | null): string;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
function createTestJwt(
|
|
11
18
|
payload: JwtPayload,
|
|
12
19
|
privateKey: string,
|
|
@@ -225,14 +232,18 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
225
232
|
const run = {
|
|
226
233
|
state: { initial_prompt_override: "do something else" },
|
|
227
234
|
} as unknown as TaskRun;
|
|
228
|
-
const result = (s as
|
|
235
|
+
const result = (s as unknown as TestableServer).getInitialPromptOverride(
|
|
236
|
+
run,
|
|
237
|
+
);
|
|
229
238
|
expect(result).toBe("do something else");
|
|
230
239
|
});
|
|
231
240
|
|
|
232
241
|
it("returns null when override is absent", () => {
|
|
233
242
|
const s = createServer();
|
|
234
243
|
const run = { state: {} } as unknown as TaskRun;
|
|
235
|
-
const result = (s as
|
|
244
|
+
const result = (s as unknown as TestableServer).getInitialPromptOverride(
|
|
245
|
+
run,
|
|
246
|
+
);
|
|
236
247
|
expect(result).toBeNull();
|
|
237
248
|
});
|
|
238
249
|
|
|
@@ -241,7 +252,9 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
241
252
|
const run = {
|
|
242
253
|
state: { initial_prompt_override: " " },
|
|
243
254
|
} as unknown as TaskRun;
|
|
244
|
-
const result = (s as
|
|
255
|
+
const result = (s as unknown as TestableServer).getInitialPromptOverride(
|
|
256
|
+
run,
|
|
257
|
+
);
|
|
245
258
|
expect(result).toBeNull();
|
|
246
259
|
});
|
|
247
260
|
|
|
@@ -250,7 +263,9 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
250
263
|
const run = {
|
|
251
264
|
state: { initial_prompt_override: 42 },
|
|
252
265
|
} as unknown as TaskRun;
|
|
253
|
-
const result = (s as
|
|
266
|
+
const result = (s as unknown as TestableServer).getInitialPromptOverride(
|
|
267
|
+
run,
|
|
268
|
+
);
|
|
254
269
|
expect(result).toBeNull();
|
|
255
270
|
});
|
|
256
271
|
});
|
|
@@ -274,8 +289,8 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
274
289
|
},
|
|
275
290
|
};
|
|
276
291
|
|
|
277
|
-
(s as
|
|
278
|
-
expect((s as
|
|
292
|
+
(s as unknown as TestableServer).detectAndAttachPrUrl(payload, update);
|
|
293
|
+
expect((s as unknown as TestableServer).detectedPrUrl).toBe(
|
|
279
294
|
"https://github.com/PostHog/posthog/pull/42",
|
|
280
295
|
);
|
|
281
296
|
});
|
|
@@ -295,15 +310,15 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
295
310
|
},
|
|
296
311
|
};
|
|
297
312
|
|
|
298
|
-
(s as
|
|
299
|
-
expect((s as
|
|
313
|
+
(s as unknown as TestableServer).detectAndAttachPrUrl(payload, update);
|
|
314
|
+
expect((s as unknown as TestableServer).detectedPrUrl).toBeNull();
|
|
300
315
|
});
|
|
301
316
|
});
|
|
302
317
|
|
|
303
318
|
describe("buildCloudSystemPrompt", () => {
|
|
304
319
|
it("returns PR-aware prompt when prUrl is provided", () => {
|
|
305
320
|
const s = createServer();
|
|
306
|
-
const prompt = (s as
|
|
321
|
+
const prompt = (s as unknown as TestableServer).buildCloudSystemPrompt(
|
|
307
322
|
"https://github.com/org/repo/pull/1",
|
|
308
323
|
);
|
|
309
324
|
expect(prompt).toContain("Do NOT create a new branch");
|
|
@@ -314,14 +329,16 @@ describe("AgentServer HTTP Mode", () => {
|
|
|
314
329
|
|
|
315
330
|
it("returns default prompt when no prUrl", () => {
|
|
316
331
|
const s = createServer();
|
|
317
|
-
const prompt = (s as
|
|
332
|
+
const prompt = (s as unknown as TestableServer).buildCloudSystemPrompt();
|
|
318
333
|
expect(prompt).toContain("Create a new branch");
|
|
319
334
|
expect(prompt).toContain("Create a pull request");
|
|
320
335
|
});
|
|
321
336
|
|
|
322
337
|
it("returns default prompt when prUrl is null", () => {
|
|
323
338
|
const s = createServer();
|
|
324
|
-
const prompt = (s as
|
|
339
|
+
const prompt = (s as unknown as TestableServer).buildCloudSystemPrompt(
|
|
340
|
+
null,
|
|
341
|
+
);
|
|
325
342
|
expect(prompt).toContain("Create a new branch");
|
|
326
343
|
expect(prompt).toContain("Create a pull request");
|
|
327
344
|
});
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { type SetupServerApi, setupServer } from "msw/node";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import type { PostHogAPIClient } from "../posthog-api.js";
|
|
3
4
|
import { createTestRepo, type TestRepo } from "../test/fixtures/api.js";
|
|
4
5
|
import { createPostHogHandlers } from "../test/mocks/msw-handlers.js";
|
|
6
|
+
import type { Task, TaskRun } from "../types.js";
|
|
5
7
|
import { AgentServer } from "./agent-server.js";
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
interface TestableAgentServer {
|
|
10
|
+
posthogAPI: PostHogAPIClient;
|
|
11
|
+
isQuestionMeta: (value: unknown) => boolean;
|
|
12
|
+
getFirstQuestionMeta: (meta: unknown) => unknown;
|
|
13
|
+
relaySlackQuestion: (payload: Record<string, unknown>, meta: unknown) => void;
|
|
14
|
+
createCloudClient: (payload: Record<string, unknown>) => {
|
|
15
|
+
requestPermission: (opts: {
|
|
16
|
+
options: unknown[];
|
|
17
|
+
toolCall: unknown;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
outcome: { outcome: string };
|
|
20
|
+
_meta?: { message?: string };
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
questionRelayedToSlack: boolean;
|
|
24
|
+
session: unknown;
|
|
25
|
+
relayAgentResponse: (payload: Record<string, unknown>) => Promise<void>;
|
|
26
|
+
sendInitialTaskMessage: (payload: Record<string, unknown>) => Promise<void>;
|
|
27
|
+
}
|
|
8
28
|
|
|
9
29
|
const TEST_PAYLOAD = {
|
|
10
30
|
run_id: "test-run-id",
|
|
@@ -31,7 +51,7 @@ const QUESTION_META = {
|
|
|
31
51
|
|
|
32
52
|
describe("Question relay", () => {
|
|
33
53
|
let repo: TestRepo;
|
|
34
|
-
let server:
|
|
54
|
+
let server: TestableAgentServer;
|
|
35
55
|
let mswServer: SetupServerApi;
|
|
36
56
|
const port = 3098;
|
|
37
57
|
|
|
@@ -52,7 +72,7 @@ describe("Question relay", () => {
|
|
|
52
72
|
mode: "interactive",
|
|
53
73
|
taskId: "test-task-id",
|
|
54
74
|
runId: "test-run-id",
|
|
55
|
-
});
|
|
75
|
+
}) as unknown as TestableAgentServer;
|
|
56
76
|
});
|
|
57
77
|
|
|
58
78
|
afterEach(async () => {
|
|
@@ -291,12 +311,12 @@ describe("Question relay", () => {
|
|
|
291
311
|
id: "test-task-id",
|
|
292
312
|
title: "t",
|
|
293
313
|
description: "original task description",
|
|
294
|
-
} as
|
|
314
|
+
} as unknown as Task);
|
|
295
315
|
vi.spyOn(server.posthogAPI, "getTaskRun").mockResolvedValue({
|
|
296
316
|
id: "test-run-id",
|
|
297
317
|
task: "test-task-id",
|
|
298
318
|
state: { initial_prompt_override: "override instruction" },
|
|
299
|
-
} as
|
|
319
|
+
} as unknown as TaskRun);
|
|
300
320
|
|
|
301
321
|
const promptSpy = vi.fn().mockResolvedValue({ stopReason: "max_tokens" });
|
|
302
322
|
server.session = {
|
|
@@ -318,12 +338,12 @@ describe("Question relay", () => {
|
|
|
318
338
|
id: "test-task-id",
|
|
319
339
|
title: "t",
|
|
320
340
|
description: "original task description",
|
|
321
|
-
} as
|
|
341
|
+
} as unknown as Task);
|
|
322
342
|
vi.spyOn(server.posthogAPI, "getTaskRun").mockResolvedValue({
|
|
323
343
|
id: "test-run-id",
|
|
324
344
|
task: "test-task-id",
|
|
325
345
|
state: {},
|
|
326
|
-
} as
|
|
346
|
+
} as unknown as TaskRun);
|
|
327
347
|
|
|
328
348
|
const promptSpy = vi.fn().mockResolvedValue({ stopReason: "max_tokens" });
|
|
329
349
|
server.session = {
|
|
@@ -99,6 +99,7 @@ export function createMockQuery(
|
|
|
99
99
|
initializationResult: vi.fn().mockResolvedValue({}),
|
|
100
100
|
reconnectMcpServer: vi.fn().mockResolvedValue(undefined),
|
|
101
101
|
toggleMcpServer: vi.fn().mockResolvedValue(undefined),
|
|
102
|
+
supportedAgents: vi.fn().mockResolvedValue([]),
|
|
102
103
|
stopTask: vi.fn().mockResolvedValue(undefined),
|
|
103
104
|
[Symbol.asyncDispose]: vi.fn().mockResolvedValue(undefined),
|
|
104
105
|
_abortController: abortController,
|
|
@@ -176,6 +177,9 @@ export function createSuccessResult(
|
|
|
176
177
|
},
|
|
177
178
|
server_tool_use: { web_search_requests: 0, web_fetch_requests: 0 },
|
|
178
179
|
service_tier: "standard",
|
|
180
|
+
inference_geo: "us",
|
|
181
|
+
iterations: [],
|
|
182
|
+
speed: "standard",
|
|
179
183
|
},
|
|
180
184
|
modelUsage: {},
|
|
181
185
|
permission_denials: [],
|
|
@@ -209,6 +213,9 @@ export function createErrorResult(
|
|
|
209
213
|
},
|
|
210
214
|
server_tool_use: { web_search_requests: 0, web_fetch_requests: 0 },
|
|
211
215
|
service_tier: "standard",
|
|
216
|
+
inference_geo: "us",
|
|
217
|
+
iterations: [],
|
|
218
|
+
speed: "standard",
|
|
212
219
|
},
|
|
213
220
|
modelUsage: {},
|
|
214
221
|
permission_denials: [],
|