@posthog/agent 2.3.261 → 2.3.267
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/codex/models.d.ts +7 -0
- package/dist/adapters/codex/models.js +13 -0
- package/dist/adapters/codex/models.js.map +1 -0
- package/dist/adapters/reasoning-effort.d.ts +10 -0
- package/dist/adapters/reasoning-effort.js +51 -0
- package/dist/adapters/reasoning-effort.js.map +1 -0
- package/dist/agent.js +16 -2
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/posthog-api.js +5 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +17 -0
- package/dist/server/agent-server.js +199 -28
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +335 -128
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +7 -3
- package/src/acp-extensions.ts +3 -0
- package/src/adapters/claude/permissions/permission-handlers.ts +11 -5
- package/src/adapters/codex/models.ts +16 -0
- package/src/adapters/codex/spawn.ts +5 -0
- package/src/adapters/reasoning-effort.ts +35 -0
- package/src/server/agent-server.test.ts +70 -11
- package/src/server/agent-server.ts +257 -37
- package/src/server/bin.ts +24 -0
- package/src/server/schemas.test.ts +52 -0
- package/src/server/schemas.ts +16 -0
- package/src/server/types.ts +3 -0
- package/src/test/mocks/msw-handlers.ts +24 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/adapters/codex/models.ts
|
|
2
|
+
var CODEX_REASONING_EFFORT_OPTIONS = [
|
|
3
|
+
{ value: "low", name: "Low" },
|
|
4
|
+
{ value: "medium", name: "Medium" },
|
|
5
|
+
{ value: "high", name: "High" }
|
|
6
|
+
];
|
|
7
|
+
function getReasoningEffortOptions(_modelId) {
|
|
8
|
+
return CODEX_REASONING_EFFORT_OPTIONS;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
getReasoningEffortOptions
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/codex/models.ts"],"sourcesContent":["interface ReasoningEffortOption {\n value: string;\n name: string;\n}\n\nconst CODEX_REASONING_EFFORT_OPTIONS: ReasoningEffortOption[] = [\n { value: \"low\", name: \"Low\" },\n { value: \"medium\", name: \"Medium\" },\n { value: \"high\", name: \"High\" },\n];\n\nexport function getReasoningEffortOptions(\n _modelId: string,\n): ReasoningEffortOption[] {\n return CODEX_REASONING_EFFORT_OPTIONS;\n}\n"],"mappings":";AAKA,IAAM,iCAA0D;AAAA,EAC9D,EAAE,OAAO,OAAO,MAAM,MAAM;AAAA,EAC5B,EAAE,OAAO,UAAU,MAAM,SAAS;AAAA,EAClC,EAAE,OAAO,QAAQ,MAAM,OAAO;AAChC;AAEO,SAAS,0BACd,UACyB;AACzB,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type RuntimeAdapter = "claude" | "codex";
|
|
2
|
+
type SupportedReasoningEffort = "low" | "medium" | "high" | "max";
|
|
3
|
+
interface ReasoningEffortOption {
|
|
4
|
+
value: SupportedReasoningEffort;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
declare function getReasoningEffortOptions(adapter: RuntimeAdapter, modelId: string): ReasoningEffortOption[] | null;
|
|
8
|
+
declare function isSupportedReasoningEffort(adapter: RuntimeAdapter, modelId: string, value: string): value is SupportedReasoningEffort;
|
|
9
|
+
|
|
10
|
+
export { type ReasoningEffortOption, type RuntimeAdapter, type SupportedReasoningEffort, getReasoningEffortOptions, isSupportedReasoningEffort };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/adapters/claude/session/models.ts
|
|
2
|
+
var MODELS_WITH_EFFORT = /* @__PURE__ */ new Set([
|
|
3
|
+
"claude-opus-4-5",
|
|
4
|
+
"claude-opus-4-6",
|
|
5
|
+
"claude-sonnet-4-6"
|
|
6
|
+
]);
|
|
7
|
+
var MODELS_WITH_MAX_EFFORT = /* @__PURE__ */ new Set(["claude-opus-4-6"]);
|
|
8
|
+
function supportsEffort(modelId) {
|
|
9
|
+
return MODELS_WITH_EFFORT.has(modelId);
|
|
10
|
+
}
|
|
11
|
+
function supportsMaxEffort(modelId) {
|
|
12
|
+
return MODELS_WITH_MAX_EFFORT.has(modelId);
|
|
13
|
+
}
|
|
14
|
+
function getEffortOptions(modelId) {
|
|
15
|
+
if (!supportsEffort(modelId)) return null;
|
|
16
|
+
const options = [
|
|
17
|
+
{ value: "low", name: "Low" },
|
|
18
|
+
{ value: "medium", name: "Medium" },
|
|
19
|
+
{ value: "high", name: "High" }
|
|
20
|
+
];
|
|
21
|
+
if (supportsMaxEffort(modelId)) {
|
|
22
|
+
options.push({ value: "max", name: "Max" });
|
|
23
|
+
}
|
|
24
|
+
return options;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/adapters/codex/models.ts
|
|
28
|
+
var CODEX_REASONING_EFFORT_OPTIONS = [
|
|
29
|
+
{ value: "low", name: "Low" },
|
|
30
|
+
{ value: "medium", name: "Medium" },
|
|
31
|
+
{ value: "high", name: "High" }
|
|
32
|
+
];
|
|
33
|
+
function getReasoningEffortOptions(_modelId) {
|
|
34
|
+
return CODEX_REASONING_EFFORT_OPTIONS;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/adapters/reasoning-effort.ts
|
|
38
|
+
function getReasoningEffortOptions2(adapter, modelId) {
|
|
39
|
+
const options = adapter === "codex" ? getReasoningEffortOptions(modelId) : getEffortOptions(modelId);
|
|
40
|
+
return options;
|
|
41
|
+
}
|
|
42
|
+
function isSupportedReasoningEffort(adapter, modelId, value) {
|
|
43
|
+
return getReasoningEffortOptions2(adapter, modelId)?.some(
|
|
44
|
+
(option) => option.value === value
|
|
45
|
+
) ?? false;
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
getReasoningEffortOptions2 as getReasoningEffortOptions,
|
|
49
|
+
isSupportedReasoningEffort
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=reasoning-effort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/claude/session/models.ts","../../src/adapters/codex/models.ts","../../src/adapters/reasoning-effort.ts"],"sourcesContent":["export const DEFAULT_MODEL = \"opus\";\n\nconst GATEWAY_TO_SDK_MODEL: Record<string, string> = {\n \"claude-opus-4-5\": \"opus\",\n \"claude-opus-4-6\": \"opus\",\n \"claude-sonnet-4-5\": \"sonnet\",\n \"claude-sonnet-4-6\": \"sonnet\",\n \"claude-haiku-4-5\": \"haiku\",\n};\n\nexport function toSdkModelId(modelId: string): string {\n return GATEWAY_TO_SDK_MODEL[modelId] ?? modelId;\n}\n\nconst MODELS_WITH_1M_CONTEXT = new Set([\n \"claude-opus-4-6\",\n \"claude-sonnet-4-6\",\n]);\n\nexport function supports1MContext(modelId: string): boolean {\n return MODELS_WITH_1M_CONTEXT.has(modelId);\n}\n\nconst MODELS_WITH_EFFORT = new Set([\n \"claude-opus-4-5\",\n \"claude-opus-4-6\",\n \"claude-sonnet-4-6\",\n]);\n\nconst MODELS_WITH_MAX_EFFORT = new Set([\"claude-opus-4-6\"]);\n\nexport function supportsEffort(modelId: string): boolean {\n return MODELS_WITH_EFFORT.has(modelId);\n}\n\nexport function supportsMaxEffort(modelId: string): boolean {\n return MODELS_WITH_MAX_EFFORT.has(modelId);\n}\n\nconst MODELS_TO_EXCLUDE_MCP_TOOLS = new Set([\"claude-haiku-4-5\"]);\n\nexport function supportsMcpInjection(modelId: string): boolean {\n return !MODELS_TO_EXCLUDE_MCP_TOOLS.has(modelId);\n}\n\ninterface EffortOption {\n value: string;\n name: string;\n}\n\nexport function getEffortOptions(modelId: string): EffortOption[] | null {\n if (!supportsEffort(modelId)) return null;\n\n const options: EffortOption[] = [\n { value: \"low\", name: \"Low\" },\n { value: \"medium\", name: \"Medium\" },\n { value: \"high\", name: \"High\" },\n ];\n\n if (supportsMaxEffort(modelId)) {\n options.push({ value: \"max\", name: \"Max\" });\n }\n\n return options;\n}\n\n// Model alias resolution — lets callers use human-friendly aliases like\n// \"opus\" or \"sonnet\" instead of full model IDs like \"claude-opus-4-6\".\n\nconst MODEL_CONTEXT_HINT_PATTERN = /\\[(\\d+m)\\]$/i;\n\nfunction tokenizeModelPreference(model: string): {\n tokens: string[];\n contextHint?: string;\n} {\n const lower = model.trim().toLowerCase();\n const contextHint = lower\n .match(MODEL_CONTEXT_HINT_PATTERN)?.[1]\n ?.toLowerCase();\n\n const normalized = lower.replace(MODEL_CONTEXT_HINT_PATTERN, \" $1 \");\n const rawTokens = normalized.split(/[^a-z0-9]+/).filter(Boolean);\n const tokens = rawTokens\n .map((token) => {\n if (token === \"opusplan\") return \"opus\";\n if (token === \"best\" || token === \"default\") return \"\";\n return token;\n })\n .filter((token) => token && token !== \"claude\")\n .filter((token) => /[a-z]/.test(token) || token.endsWith(\"m\"));\n\n return { tokens, contextHint };\n}\n\ninterface ModelOption {\n value: string;\n name?: string;\n description?: string;\n}\n\nfunction scoreModelMatch(\n model: ModelOption,\n tokens: string[],\n contextHint?: string,\n): number {\n const haystack = `${model.value} ${model.name ?? \"\"}`.toLowerCase();\n let score = 0;\n for (const token of tokens) {\n if (haystack.includes(token)) {\n score += token === contextHint ? 3 : 1;\n }\n }\n return score;\n}\n\nexport function resolveModelPreference(\n preference: string,\n options: ModelOption[],\n): string | null {\n const trimmed = preference.trim();\n if (!trimmed) return null;\n\n const lower = trimmed.toLowerCase();\n\n // Exact match on value or display name\n const directMatch = options.find(\n (o) =>\n o.value === trimmed ||\n o.value.toLowerCase() === lower ||\n (o.name && o.name.toLowerCase() === lower),\n );\n if (directMatch) return directMatch.value;\n\n // Substring match\n const includesMatch = options.find((o) => {\n const value = o.value.toLowerCase();\n const display = (o.name ?? \"\").toLowerCase();\n return (\n value.includes(lower) || display.includes(lower) || lower.includes(value)\n );\n });\n if (includesMatch) return includesMatch.value;\n\n // Tokenized matching for aliases like \"opus[1m]\"\n const { tokens, contextHint } = tokenizeModelPreference(trimmed);\n if (tokens.length === 0) return null;\n\n let bestMatch: ModelOption | null = null;\n let bestScore = 0;\n for (const model of options) {\n const score = scoreModelMatch(model, tokens, contextHint);\n if (0 < score && (!bestMatch || bestScore < score)) {\n bestMatch = model;\n bestScore = score;\n }\n }\n\n return bestMatch?.value ?? null;\n}\n","interface ReasoningEffortOption {\n value: string;\n name: string;\n}\n\nconst CODEX_REASONING_EFFORT_OPTIONS: ReasoningEffortOption[] = [\n { value: \"low\", name: \"Low\" },\n { value: \"medium\", name: \"Medium\" },\n { value: \"high\", name: \"High\" },\n];\n\nexport function getReasoningEffortOptions(\n _modelId: string,\n): ReasoningEffortOption[] {\n return CODEX_REASONING_EFFORT_OPTIONS;\n}\n","import { getEffortOptions as getClaudeEffortOptions } from \"./claude/session/models\";\nimport { getReasoningEffortOptions as getCodexReasoningEffortOptions } from \"./codex/models\";\n\nexport type RuntimeAdapter = \"claude\" | \"codex\";\n\nexport type SupportedReasoningEffort = \"low\" | \"medium\" | \"high\" | \"max\";\n\nexport interface ReasoningEffortOption {\n value: SupportedReasoningEffort;\n name: string;\n}\n\nexport function getReasoningEffortOptions(\n adapter: RuntimeAdapter,\n modelId: string,\n): ReasoningEffortOption[] | null {\n const options =\n adapter === \"codex\"\n ? getCodexReasoningEffortOptions(modelId)\n : getClaudeEffortOptions(modelId);\n\n return options as ReasoningEffortOption[] | null;\n}\n\nexport function isSupportedReasoningEffort(\n adapter: RuntimeAdapter,\n modelId: string,\n value: string,\n): value is SupportedReasoningEffort {\n return (\n getReasoningEffortOptions(adapter, modelId)?.some(\n (option) => option.value === value,\n ) ?? false\n );\n}\n"],"mappings":";AAuBA,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,yBAAyB,oBAAI,IAAI,CAAC,iBAAiB,CAAC;AAEnD,SAAS,eAAe,SAA0B;AACvD,SAAO,mBAAmB,IAAI,OAAO;AACvC;AAEO,SAAS,kBAAkB,SAA0B;AAC1D,SAAO,uBAAuB,IAAI,OAAO;AAC3C;AAaO,SAAS,iBAAiB,SAAwC;AACvE,MAAI,CAAC,eAAe,OAAO,EAAG,QAAO;AAErC,QAAM,UAA0B;AAAA,IAC9B,EAAE,OAAO,OAAO,MAAM,MAAM;AAAA,IAC5B,EAAE,OAAO,UAAU,MAAM,SAAS;AAAA,IAClC,EAAE,OAAO,QAAQ,MAAM,OAAO;AAAA,EAChC;AAEA,MAAI,kBAAkB,OAAO,GAAG;AAC9B,YAAQ,KAAK,EAAE,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,EAC5C;AAEA,SAAO;AACT;;;AC3DA,IAAM,iCAA0D;AAAA,EAC9D,EAAE,OAAO,OAAO,MAAM,MAAM;AAAA,EAC5B,EAAE,OAAO,UAAU,MAAM,SAAS;AAAA,EAClC,EAAE,OAAO,QAAQ,MAAM,OAAO;AAChC;AAEO,SAAS,0BACd,UACyB;AACzB,SAAO;AACT;;;ACHO,SAASA,2BACd,SACA,SACgC;AAChC,QAAM,UACJ,YAAY,UACR,0BAA+B,OAAO,IACtC,iBAAuB,OAAO;AAEpC,SAAO;AACT;AAEO,SAAS,2BACd,SACA,SACA,OACmC;AACnC,SACEA,2BAA0B,SAAS,OAAO,GAAG;AAAA,IAC3C,CAAC,WAAW,OAAO,UAAU;AAAA,EAC/B,KAAK;AAET;","names":["getReasoningEffortOptions"]}
|
package/dist/agent.js
CHANGED
|
@@ -245,7 +245,7 @@ import { v7 as uuidv7 } from "uuid";
|
|
|
245
245
|
// package.json
|
|
246
246
|
var package_default = {
|
|
247
247
|
name: "@posthog/agent",
|
|
248
|
-
version: "2.3.
|
|
248
|
+
version: "2.3.267",
|
|
249
249
|
repository: "https://github.com/PostHog/code",
|
|
250
250
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
251
251
|
exports: {
|
|
@@ -293,6 +293,10 @@ var package_default = {
|
|
|
293
293
|
types: "./dist/adapters/claude/session/models.d.ts",
|
|
294
294
|
import: "./dist/adapters/claude/session/models.js"
|
|
295
295
|
},
|
|
296
|
+
"./adapters/reasoning-effort": {
|
|
297
|
+
types: "./dist/adapters/reasoning-effort.d.ts",
|
|
298
|
+
import: "./dist/adapters/reasoning-effort.js"
|
|
299
|
+
},
|
|
296
300
|
"./execution-mode": {
|
|
297
301
|
types: "./dist/execution-mode.d.ts",
|
|
298
302
|
import: "./dist/execution-mode.js"
|
|
@@ -406,7 +410,9 @@ var POSTHOG_NOTIFICATIONS = {
|
|
|
406
410
|
/** Marks a boundary for log compaction */
|
|
407
411
|
COMPACT_BOUNDARY: "_posthog/compact_boundary",
|
|
408
412
|
/** Token usage update for a session turn */
|
|
409
|
-
USAGE_UPDATE: "_posthog/usage_update"
|
|
413
|
+
USAGE_UPDATE: "_posthog/usage_update",
|
|
414
|
+
/** Response to a relayed permission request (plan approval, question) */
|
|
415
|
+
PERMISSION_RESPONSE: "_posthog/permission_response"
|
|
410
416
|
};
|
|
411
417
|
|
|
412
418
|
// src/utils/common.ts
|
|
@@ -2635,6 +2641,11 @@ async function canUseTool(context) {
|
|
|
2635
2641
|
if (planFileResult) {
|
|
2636
2642
|
return planFileResult;
|
|
2637
2643
|
}
|
|
2644
|
+
if (session.permissionMode === "plan") {
|
|
2645
|
+
const message = `This tool is not available in plan mode. Write your plan to a file in ${getClaudePlansDir()} and call ExitPlanMode when ready.`;
|
|
2646
|
+
await emitToolDenial(context, message);
|
|
2647
|
+
return { behavior: "deny", message, interrupt: false };
|
|
2648
|
+
}
|
|
2638
2649
|
return handleDefaultPermissionFlow(context);
|
|
2639
2650
|
}
|
|
2640
2651
|
|
|
@@ -4442,6 +4453,9 @@ function buildConfigArgs(options) {
|
|
|
4442
4453
|
if (options.model) {
|
|
4443
4454
|
args.push("-c", `model="${options.model}"`);
|
|
4444
4455
|
}
|
|
4456
|
+
if (options.reasoningEffort) {
|
|
4457
|
+
args.push("-c", `model_reasoning_effort="${options.reasoningEffort}"`);
|
|
4458
|
+
}
|
|
4445
4459
|
if (options.instructions) {
|
|
4446
4460
|
const escaped = options.instructions.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/"/g, '\\"');
|
|
4447
4461
|
args.push("-c", `instructions="${escaped}"`);
|