@posthog/agent 2.3.346 → 2.3.351
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 +53 -6
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.js +2 -2
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +53 -6
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +53 -6
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +5 -5
- package/src/adapters/claude/hooks.ts +9 -2
- package/src/adapters/claude/session/options.test.ts +72 -0
- package/src/adapters/claude/session/options.ts +56 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/agent",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.351",
|
|
4
4
|
"repository": "https://github.com/PostHog/code",
|
|
5
5
|
"description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
6
6
|
"exports": {
|
|
@@ -86,8 +86,9 @@
|
|
|
86
86
|
"tsx": "^4.20.6",
|
|
87
87
|
"typescript": "^5.5.0",
|
|
88
88
|
"vitest": "^2.1.8",
|
|
89
|
-
"@posthog/
|
|
90
|
-
"@posthog/
|
|
89
|
+
"@posthog/shared": "1.0.0",
|
|
90
|
+
"@posthog/enricher": "1.0.0",
|
|
91
|
+
"@posthog/git": "1.0.0"
|
|
91
92
|
},
|
|
92
93
|
"dependencies": {
|
|
93
94
|
"@agentclientprotocol/sdk": "0.19.0",
|
|
@@ -108,8 +109,7 @@
|
|
|
108
109
|
"tar": "^7.5.0",
|
|
109
110
|
"uuid": "13.0.0",
|
|
110
111
|
"yoga-wasm-web": "^0.3.3",
|
|
111
|
-
"zod": "^4.2.0"
|
|
112
|
-
"@posthog/enricher": "1.0.0"
|
|
112
|
+
"zod": "^4.2.0"
|
|
113
113
|
},
|
|
114
114
|
"files": [
|
|
115
115
|
"dist/**/*",
|
|
@@ -173,12 +173,12 @@ export const createPostToolUseHook =
|
|
|
173
173
|
*
|
|
174
174
|
* https://github.com/anthropics/claude-agent-sdk-typescript/issues/267
|
|
175
175
|
*/
|
|
176
|
-
const SUBAGENT_REWRITES: Record<string, string> = {
|
|
176
|
+
export const SUBAGENT_REWRITES: Record<string, string> = {
|
|
177
177
|
Explore: "ph-explore",
|
|
178
178
|
};
|
|
179
179
|
|
|
180
180
|
export const createSubagentRewriteHook =
|
|
181
|
-
(logger: Logger): HookCallback =>
|
|
181
|
+
(logger: Logger, registeredAgents: ReadonlySet<string>): HookCallback =>
|
|
182
182
|
async (input: HookInput, _toolUseID: string | undefined) => {
|
|
183
183
|
if (input.hook_event_name !== "PreToolUse") {
|
|
184
184
|
return { continue: true };
|
|
@@ -195,6 +195,13 @@ export const createSubagentRewriteHook =
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
const target = SUBAGENT_REWRITES[subagentType];
|
|
198
|
+
if (!registeredAgents.has(target)) {
|
|
199
|
+
logger.warn(
|
|
200
|
+
`[SubagentRewriteHook] Skipping rewrite ${subagentType} → ${target}: target agent not registered for this session. Falling back to built-in ${subagentType}.`,
|
|
201
|
+
);
|
|
202
|
+
return { continue: true };
|
|
203
|
+
}
|
|
204
|
+
|
|
198
205
|
logger.info(
|
|
199
206
|
`[SubagentRewriteHook] Rewriting subagent_type: ${subagentType} → ${target}`,
|
|
200
207
|
);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { Logger } from "../../../utils/logger";
|
|
5
|
+
import { SUBAGENT_REWRITES } from "../hooks";
|
|
6
|
+
import { buildSessionOptions } from "./options";
|
|
7
|
+
import { SettingsManager } from "./settings";
|
|
8
|
+
|
|
9
|
+
function makeParams() {
|
|
10
|
+
const cwd = path.join(os.tmpdir(), `options-test-${Date.now()}`);
|
|
11
|
+
return {
|
|
12
|
+
cwd,
|
|
13
|
+
mcpServers: {},
|
|
14
|
+
permissionMode: "default" as const,
|
|
15
|
+
canUseTool: async () => ({ behavior: "allow" as const, updatedInput: {} }),
|
|
16
|
+
logger: new Logger(),
|
|
17
|
+
sessionId: "test-session",
|
|
18
|
+
isResume: false,
|
|
19
|
+
settingsManager: new SettingsManager(cwd),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe("buildSessionOptions", () => {
|
|
24
|
+
it.each(Object.entries(SUBAGENT_REWRITES))(
|
|
25
|
+
'registers rewrite target "%s" → "%s" in options.agents',
|
|
26
|
+
(_source, target) => {
|
|
27
|
+
const options = buildSessionOptions(makeParams());
|
|
28
|
+
const registered = new Set(Object.keys(options.agents ?? {}));
|
|
29
|
+
|
|
30
|
+
expect(
|
|
31
|
+
registered.has(target),
|
|
32
|
+
`Rewrite target "${target}" is not registered in options.agents — either register the agent in buildAgents or remove the rewrite.`,
|
|
33
|
+
).toBe(true);
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
it("preserves caller-provided agents alongside defaults", () => {
|
|
38
|
+
const params = makeParams();
|
|
39
|
+
const options = buildSessionOptions({
|
|
40
|
+
...params,
|
|
41
|
+
userProvidedOptions: {
|
|
42
|
+
agents: {
|
|
43
|
+
"custom-agent": {
|
|
44
|
+
description: "Custom",
|
|
45
|
+
prompt: "Custom prompt",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(options.agents?.["custom-agent"]).toBeDefined();
|
|
52
|
+
expect(options.agents?.["ph-explore"]).toBeDefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("lets caller-provided agents override defaults by name", () => {
|
|
56
|
+
const params = makeParams();
|
|
57
|
+
const override = {
|
|
58
|
+
description: "Overridden",
|
|
59
|
+
prompt: "Overridden prompt",
|
|
60
|
+
};
|
|
61
|
+
const options = buildSessionOptions({
|
|
62
|
+
...params,
|
|
63
|
+
userProvidedOptions: {
|
|
64
|
+
agents: {
|
|
65
|
+
"ph-explore": override,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(options.agents?.["ph-explore"]).toEqual(override);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -117,6 +117,7 @@ function buildHooks(
|
|
|
117
117
|
logger: Logger,
|
|
118
118
|
enrichmentDeps: FileEnrichmentDeps | undefined,
|
|
119
119
|
enrichedReadCache: EnrichedReadCache | undefined,
|
|
120
|
+
registeredAgents: ReadonlySet<string>,
|
|
120
121
|
): Options["hooks"] {
|
|
121
122
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange, logger })];
|
|
122
123
|
if (enrichmentDeps && enrichedReadCache) {
|
|
@@ -136,13 +137,62 @@ function buildHooks(
|
|
|
136
137
|
{
|
|
137
138
|
hooks: [
|
|
138
139
|
createPreToolUseHook(settingsManager, logger),
|
|
139
|
-
createSubagentRewriteHook(logger),
|
|
140
|
+
createSubagentRewriteHook(logger, registeredAgents),
|
|
140
141
|
],
|
|
141
142
|
},
|
|
142
143
|
],
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Read-only Haiku-powered exploration agent. Registered under the `ph-explore`
|
|
149
|
+
* name rather than `Explore` to work around a Claude Agent SDK bug where
|
|
150
|
+
* `options.agents` cannot shadow built-in agent definitions. The
|
|
151
|
+
* `createSubagentRewriteHook` rewrites `subagent_type: "Explore"` to
|
|
152
|
+
* `"ph-explore"` so callers don't have to know about the alias.
|
|
153
|
+
*/
|
|
154
|
+
const PH_EXPLORE_AGENT: NonNullable<Options["agents"]>[string] = {
|
|
155
|
+
description:
|
|
156
|
+
'Fast agent for exploring and understanding codebases. Use this when you need to find files by pattern (eg. "src/components/**/*.tsx"), search for code or keywords (eg. "where is the auth middleware?"), or answer questions about how the codebase works (eg. "how does the session service handle reconnects?"). When calling this agent, specify a thoroughness level: "quick" for targeted lookups, "medium" for broader exploration, or "very thorough" for comprehensive analysis across multiple locations.',
|
|
157
|
+
model: "haiku",
|
|
158
|
+
prompt: `You are a fast, read-only codebase exploration agent.
|
|
159
|
+
|
|
160
|
+
Your job is to find files, search code, read the most relevant sources, and report findings clearly.
|
|
161
|
+
|
|
162
|
+
Rules:
|
|
163
|
+
- Never create, modify, delete, move, or copy files.
|
|
164
|
+
- Never use shell redirection or any command that changes system state.
|
|
165
|
+
- Use Glob for broad file pattern matching.
|
|
166
|
+
- Use Grep for searching file contents.
|
|
167
|
+
- Use Read when you know the exact file path to inspect.
|
|
168
|
+
- Use Bash only for safe read-only commands like ls, git status, git log, git diff, find, cat, head, and tail.
|
|
169
|
+
- Adapt your search approach based on the thoroughness level specified by the caller.
|
|
170
|
+
- Return file paths as absolute paths in your final response.
|
|
171
|
+
- Avoid using emojis.
|
|
172
|
+
- Wherever possible, spawn multiple parallel tool calls for grepping and reading files.
|
|
173
|
+
- Search efficiently, then read only the most relevant files.
|
|
174
|
+
- Return findings directly in your final response — do not create files.`,
|
|
175
|
+
tools: [
|
|
176
|
+
"Bash",
|
|
177
|
+
"Glob",
|
|
178
|
+
"Grep",
|
|
179
|
+
"Read",
|
|
180
|
+
"WebFetch",
|
|
181
|
+
"WebSearch",
|
|
182
|
+
"NotebookRead",
|
|
183
|
+
"TodoWrite",
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
function buildAgents(
|
|
188
|
+
userAgents: Options["agents"],
|
|
189
|
+
): NonNullable<Options["agents"]> {
|
|
190
|
+
return {
|
|
191
|
+
"ph-explore": PH_EXPLORE_AGENT,
|
|
192
|
+
...(userAgents || {}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
146
196
|
function getAbortController(
|
|
147
197
|
userProvidedController: AbortController | undefined,
|
|
148
198
|
): AbortController {
|
|
@@ -256,6 +306,9 @@ export function buildSessionOptions(params: BuildOptionsParams): Options {
|
|
|
256
306
|
? []
|
|
257
307
|
: { type: "preset", preset: "claude_code" });
|
|
258
308
|
|
|
309
|
+
const agents = buildAgents(params.userProvidedOptions?.agents);
|
|
310
|
+
const registeredAgentNames = new Set(Object.keys(agents));
|
|
311
|
+
|
|
259
312
|
const options: Options = {
|
|
260
313
|
...params.userProvidedOptions,
|
|
261
314
|
betas: ["context-1m-2025-08-07"],
|
|
@@ -269,6 +322,7 @@ export function buildSessionOptions(params: BuildOptionsParams): Options {
|
|
|
269
322
|
canUseTool: params.canUseTool,
|
|
270
323
|
executable: "node",
|
|
271
324
|
tools,
|
|
325
|
+
agents,
|
|
272
326
|
extraArgs: {
|
|
273
327
|
...params.userProvidedOptions?.extraArgs,
|
|
274
328
|
"replay-user-messages": "",
|
|
@@ -285,6 +339,7 @@ export function buildSessionOptions(params: BuildOptionsParams): Options {
|
|
|
285
339
|
params.logger,
|
|
286
340
|
params.enrichmentDeps,
|
|
287
341
|
params.enrichedReadCache,
|
|
342
|
+
registeredAgentNames,
|
|
288
343
|
),
|
|
289
344
|
outputFormat: params.outputFormat,
|
|
290
345
|
abortController: getAbortController(
|