@posthog/agent 2.3.67 → 2.3.73
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/permissions/permission-options.js +12 -2
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/session/jsonl-hydration.js.map +1 -1
- package/dist/agent.js +239 -70
- package/dist/agent.js.map +1 -1
- package/dist/claude-cli/cli.js +4002 -2916
- package/dist/claude-cli/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/arm64-darwin/tree-sitter-bash.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/arm64-linux/tree-sitter-bash.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/arm64-win32/tree-sitter-bash.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/x64-darwin/tree-sitter-bash.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/x64-linux/tree-sitter-bash.node +0 -0
- package/dist/claude-cli/vendor/tree-sitter-bash/x64-win32/tree-sitter-bash.node +0 -0
- package/dist/posthog-api.js +3 -3
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +239 -70
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +239 -70
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/base-acp-agent.ts +11 -2
- package/src/adapters/claude/UPSTREAM.md +3 -4
- package/src/adapters/claude/claude-agent.ts +217 -35
- package/src/adapters/claude/conversion/sdk-to-acp.ts +2 -25
- package/src/adapters/claude/permissions/permission-handlers.ts +5 -7
- package/src/adapters/claude/permissions/permission-options.ts +17 -2
- package/src/adapters/claude/session/models.ts +94 -4
- package/src/adapters/claude/types.ts +3 -0
package/dist/agent.js
CHANGED
|
@@ -281,7 +281,7 @@ import { v7 as uuidv7 } from "uuid";
|
|
|
281
281
|
// package.json
|
|
282
282
|
var package_default = {
|
|
283
283
|
name: "@posthog/agent",
|
|
284
|
-
version: "2.3.
|
|
284
|
+
version: "2.3.73",
|
|
285
285
|
repository: "https://github.com/PostHog/code",
|
|
286
286
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
287
287
|
exports: {
|
|
@@ -368,8 +368,8 @@ var package_default = {
|
|
|
368
368
|
vitest: "^2.1.8"
|
|
369
369
|
},
|
|
370
370
|
dependencies: {
|
|
371
|
-
"@agentclientprotocol/sdk": "0.
|
|
372
|
-
"@anthropic-ai/claude-agent-sdk": "0.2.
|
|
371
|
+
"@agentclientprotocol/sdk": "0.16.1",
|
|
372
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.76",
|
|
373
373
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
374
374
|
"@hono/node-server": "^1.19.9",
|
|
375
375
|
"@opentelemetry/api-logs": "^0.208.0",
|
|
@@ -508,12 +508,14 @@ function formatGatewayModelName(model) {
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
// src/adapters/base-acp-agent.ts
|
|
511
|
+
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
511
512
|
var BaseAcpAgent = class {
|
|
512
513
|
session;
|
|
513
514
|
sessionId;
|
|
514
515
|
client;
|
|
515
516
|
logger;
|
|
516
517
|
fileContentCache = {};
|
|
518
|
+
gatewayModels = [];
|
|
517
519
|
constructor(client) {
|
|
518
520
|
this.client = client;
|
|
519
521
|
this.logger = new Logger({ debug: true, prefix: "[BaseAcpAgent]" });
|
|
@@ -566,8 +568,8 @@ var BaseAcpAgent = class {
|
|
|
566
568
|
throw new Error("Method not implemented.");
|
|
567
569
|
}
|
|
568
570
|
async getModelConfigOptions(currentModelOverride) {
|
|
569
|
-
|
|
570
|
-
const options = gatewayModels.filter((model) => isAnthropicModel(model)).map((model) => ({
|
|
571
|
+
this.gatewayModels = await fetchGatewayModels();
|
|
572
|
+
const options = this.gatewayModels.filter((model) => isAnthropicModel(model)).map((model) => ({
|
|
571
573
|
value: model.id,
|
|
572
574
|
name: formatGatewayModelName(model),
|
|
573
575
|
description: `Context: ${model.context_window.toLocaleString()} tokens`
|
|
@@ -588,6 +590,10 @@ var BaseAcpAgent = class {
|
|
|
588
590
|
}
|
|
589
591
|
return { currentModelId, options };
|
|
590
592
|
}
|
|
593
|
+
getContextWindowForModel(modelId) {
|
|
594
|
+
const match = this.gatewayModels.find((m) => m.id === modelId);
|
|
595
|
+
return match?.context_window ?? DEFAULT_CONTEXT_WINDOW;
|
|
596
|
+
}
|
|
591
597
|
};
|
|
592
598
|
|
|
593
599
|
// src/adapters/claude/conversion/acp-to-sdk.ts
|
|
@@ -1763,7 +1769,7 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
|
|
|
1763
1769
|
}
|
|
1764
1770
|
}
|
|
1765
1771
|
async function handleSystemMessage(message, context) {
|
|
1766
|
-
const { sessionId, client, logger } = context;
|
|
1772
|
+
const { session, sessionId, client, logger } = context;
|
|
1767
1773
|
switch (message.subtype) {
|
|
1768
1774
|
case "init":
|
|
1769
1775
|
break;
|
|
@@ -1771,7 +1777,8 @@ async function handleSystemMessage(message, context) {
|
|
|
1771
1777
|
await client.extNotification("_posthog/compact_boundary", {
|
|
1772
1778
|
sessionId,
|
|
1773
1779
|
trigger: message.compact_metadata.trigger,
|
|
1774
|
-
preTokens: message.compact_metadata.pre_tokens
|
|
1780
|
+
preTokens: message.compact_metadata.pre_tokens,
|
|
1781
|
+
contextSize: session.contextSize
|
|
1775
1782
|
});
|
|
1776
1783
|
break;
|
|
1777
1784
|
case "hook_response":
|
|
@@ -1943,21 +1950,6 @@ function filterMessageContent(content) {
|
|
|
1943
1950
|
async function handleUserAssistantMessage(message, context) {
|
|
1944
1951
|
const { session, sessionId, client, toolUseCache, fileContentCache, logger } = context;
|
|
1945
1952
|
if (shouldSkipUserAssistantMessage(message)) {
|
|
1946
|
-
const content2 = message.message.content;
|
|
1947
|
-
if (typeof content2 === "string" && hasLocalCommandStdout(content2) && content2.includes("Context Usage")) {
|
|
1948
|
-
const stripped = content2.replace("<local-command-stdout>", "").replace("</local-command-stdout>", "");
|
|
1949
|
-
for (const notification of toAcpNotifications(
|
|
1950
|
-
stripped,
|
|
1951
|
-
"assistant",
|
|
1952
|
-
sessionId,
|
|
1953
|
-
toolUseCache,
|
|
1954
|
-
fileContentCache,
|
|
1955
|
-
client,
|
|
1956
|
-
logger
|
|
1957
|
-
)) {
|
|
1958
|
-
await client.sessionUpdate(notification);
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
1953
|
logSpecialMessages(message, logger);
|
|
1962
1954
|
if (isLoginRequiredMessage(message)) {
|
|
1963
1955
|
return { shouldStop: true, error: RequestError.authRequired() };
|
|
@@ -2217,8 +2209,17 @@ function buildPermissionOptions(toolName, toolInput, cwd, suggestions) {
|
|
|
2217
2209
|
}
|
|
2218
2210
|
return permissionOptions("Yes, always allow");
|
|
2219
2211
|
}
|
|
2212
|
+
var ALLOW_BYPASS2 = !IS_ROOT || !!process.env.IS_SANDBOX;
|
|
2220
2213
|
function buildExitPlanModePermissionOptions() {
|
|
2221
|
-
|
|
2214
|
+
const options = [];
|
|
2215
|
+
if (ALLOW_BYPASS2) {
|
|
2216
|
+
options.push({
|
|
2217
|
+
kind: "allow_always",
|
|
2218
|
+
name: "Yes, bypass all permissions",
|
|
2219
|
+
optionId: "bypassPermissions"
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
options.push(
|
|
2222
2223
|
{
|
|
2223
2224
|
kind: "allow_always",
|
|
2224
2225
|
name: "Yes, and auto-accept edits",
|
|
@@ -2235,7 +2236,8 @@ function buildExitPlanModePermissionOptions() {
|
|
|
2235
2236
|
optionId: "reject_with_feedback",
|
|
2236
2237
|
_meta: { customInput: true }
|
|
2237
2238
|
}
|
|
2238
|
-
|
|
2239
|
+
);
|
|
2240
|
+
return options;
|
|
2239
2241
|
}
|
|
2240
2242
|
|
|
2241
2243
|
// src/adapters/claude/permissions/permission-handlers.ts
|
|
@@ -2309,7 +2311,7 @@ async function requestPlanApproval(context, updatedInput) {
|
|
|
2309
2311
|
}
|
|
2310
2312
|
async function applyPlanApproval(response, context, updatedInput) {
|
|
2311
2313
|
const { session } = context;
|
|
2312
|
-
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "default" || response.outcome.optionId === "acceptEdits")) {
|
|
2314
|
+
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "default" || response.outcome.optionId === "acceptEdits" || response.outcome.optionId === "bypassPermissions")) {
|
|
2313
2315
|
session.permissionMode = response.outcome.optionId;
|
|
2314
2316
|
await session.query.setPermissionMode(response.outcome.optionId);
|
|
2315
2317
|
await context.client.sessionUpdate({
|
|
@@ -2382,8 +2384,7 @@ async function handleAskUserQuestionTool(context) {
|
|
|
2382
2384
|
context.logger.warn("[AskUserQuestion] No questions found in input");
|
|
2383
2385
|
return {
|
|
2384
2386
|
behavior: "deny",
|
|
2385
|
-
message: "No questions provided"
|
|
2386
|
-
interrupt: true
|
|
2387
|
+
message: "No questions provided"
|
|
2387
2388
|
};
|
|
2388
2389
|
}
|
|
2389
2390
|
const { client, sessionId, toolUseID, toolInput } = context;
|
|
@@ -2414,16 +2415,14 @@ async function handleAskUserQuestionTool(context) {
|
|
|
2414
2415
|
const customMessage = response._meta?.message;
|
|
2415
2416
|
return {
|
|
2416
2417
|
behavior: "deny",
|
|
2417
|
-
message: typeof customMessage === "string" ? customMessage : "User cancelled the questions"
|
|
2418
|
-
interrupt: true
|
|
2418
|
+
message: typeof customMessage === "string" ? customMessage : "User cancelled the questions"
|
|
2419
2419
|
};
|
|
2420
2420
|
}
|
|
2421
2421
|
const answers = response._meta?.answers;
|
|
2422
2422
|
if (!answers || Object.keys(answers).length === 0) {
|
|
2423
2423
|
return {
|
|
2424
2424
|
behavior: "deny",
|
|
2425
|
-
message: "User did not provide answers"
|
|
2426
|
-
interrupt: true
|
|
2425
|
+
message: "User did not provide answers"
|
|
2427
2426
|
};
|
|
2428
2427
|
}
|
|
2429
2428
|
return {
|
|
@@ -2490,8 +2489,7 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
2490
2489
|
await emitToolDenial(context, message);
|
|
2491
2490
|
return {
|
|
2492
2491
|
behavior: "deny",
|
|
2493
|
-
message
|
|
2494
|
-
interrupt: true
|
|
2492
|
+
message
|
|
2495
2493
|
};
|
|
2496
2494
|
}
|
|
2497
2495
|
}
|
|
@@ -2605,16 +2603,6 @@ var GATEWAY_TO_SDK_MODEL = {
|
|
|
2605
2603
|
function toSdkModelId(modelId) {
|
|
2606
2604
|
return GATEWAY_TO_SDK_MODEL[modelId] ?? modelId;
|
|
2607
2605
|
}
|
|
2608
|
-
var MODELS_WITH_1M_CONTEXT = /* @__PURE__ */ new Set([
|
|
2609
|
-
"claude-opus-4-6",
|
|
2610
|
-
"claude-sonnet-4-6"
|
|
2611
|
-
]);
|
|
2612
|
-
function supports1MContext(modelId) {
|
|
2613
|
-
return MODELS_WITH_1M_CONTEXT.has(modelId);
|
|
2614
|
-
}
|
|
2615
|
-
function getDefaultContextWindow(modelId) {
|
|
2616
|
-
return supports1MContext(modelId) ? 1e6 : 2e5;
|
|
2617
|
-
}
|
|
2618
2606
|
var MODELS_WITH_EFFORT = /* @__PURE__ */ new Set([
|
|
2619
2607
|
"claude-opus-4-5",
|
|
2620
2608
|
"claude-opus-4-6",
|
|
@@ -2639,6 +2627,56 @@ function getEffortOptions(modelId) {
|
|
|
2639
2627
|
}
|
|
2640
2628
|
return options;
|
|
2641
2629
|
}
|
|
2630
|
+
var MODEL_CONTEXT_HINT_PATTERN = /\[(\d+m)\]$/i;
|
|
2631
|
+
function tokenizeModelPreference(model) {
|
|
2632
|
+
const lower = model.trim().toLowerCase();
|
|
2633
|
+
const contextHint = lower.match(MODEL_CONTEXT_HINT_PATTERN)?.[1]?.toLowerCase();
|
|
2634
|
+
const normalized = lower.replace(MODEL_CONTEXT_HINT_PATTERN, " $1 ");
|
|
2635
|
+
const rawTokens = normalized.split(/[^a-z0-9]+/).filter(Boolean);
|
|
2636
|
+
const tokens = rawTokens.map((token) => {
|
|
2637
|
+
if (token === "opusplan") return "opus";
|
|
2638
|
+
if (token === "best" || token === "default") return "";
|
|
2639
|
+
return token;
|
|
2640
|
+
}).filter((token) => token && token !== "claude").filter((token) => /[a-z]/.test(token) || token.endsWith("m"));
|
|
2641
|
+
return { tokens, contextHint };
|
|
2642
|
+
}
|
|
2643
|
+
function scoreModelMatch(model, tokens, contextHint) {
|
|
2644
|
+
const haystack = `${model.value} ${model.name ?? ""}`.toLowerCase();
|
|
2645
|
+
let score = 0;
|
|
2646
|
+
for (const token of tokens) {
|
|
2647
|
+
if (haystack.includes(token)) {
|
|
2648
|
+
score += token === contextHint ? 3 : 1;
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
return score;
|
|
2652
|
+
}
|
|
2653
|
+
function resolveModelPreference(preference, options) {
|
|
2654
|
+
const trimmed = preference.trim();
|
|
2655
|
+
if (!trimmed) return null;
|
|
2656
|
+
const lower = trimmed.toLowerCase();
|
|
2657
|
+
const directMatch = options.find(
|
|
2658
|
+
(o) => o.value === trimmed || o.value.toLowerCase() === lower || o.name && o.name.toLowerCase() === lower
|
|
2659
|
+
);
|
|
2660
|
+
if (directMatch) return directMatch.value;
|
|
2661
|
+
const includesMatch = options.find((o) => {
|
|
2662
|
+
const value = o.value.toLowerCase();
|
|
2663
|
+
const display = (o.name ?? "").toLowerCase();
|
|
2664
|
+
return value.includes(lower) || display.includes(lower) || lower.includes(value);
|
|
2665
|
+
});
|
|
2666
|
+
if (includesMatch) return includesMatch.value;
|
|
2667
|
+
const { tokens, contextHint } = tokenizeModelPreference(trimmed);
|
|
2668
|
+
if (tokens.length === 0) return null;
|
|
2669
|
+
let bestMatch = null;
|
|
2670
|
+
let bestScore = 0;
|
|
2671
|
+
for (const model of options) {
|
|
2672
|
+
const score = scoreModelMatch(model, tokens, contextHint);
|
|
2673
|
+
if (0 < score && (!bestMatch || bestScore < score)) {
|
|
2674
|
+
bestMatch = model;
|
|
2675
|
+
bestScore = score;
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
return bestMatch?.value ?? null;
|
|
2679
|
+
}
|
|
2642
2680
|
|
|
2643
2681
|
// src/adapters/claude/session/options.ts
|
|
2644
2682
|
import { spawn } from "child_process";
|
|
@@ -3119,6 +3157,7 @@ var SettingsManager = class {
|
|
|
3119
3157
|
// src/adapters/claude/claude-agent.ts
|
|
3120
3158
|
var SESSION_VALIDATION_TIMEOUT_MS = 1e4;
|
|
3121
3159
|
var MAX_TITLE_LENGTH = 256;
|
|
3160
|
+
var LOCAL_ONLY_COMMANDS = /* @__PURE__ */ new Set(["/context", "/heapdump", "/extra-usage"]);
|
|
3122
3161
|
function sanitizeTitle(text2) {
|
|
3123
3162
|
const sanitized = text2.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
3124
3163
|
if (sanitized.length <= MAX_TITLE_LENGTH) {
|
|
@@ -3155,7 +3194,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3155
3194
|
sessionCapabilities: {
|
|
3156
3195
|
list: {},
|
|
3157
3196
|
fork: {},
|
|
3158
|
-
resume: {}
|
|
3197
|
+
resume: {},
|
|
3198
|
+
close: {}
|
|
3159
3199
|
},
|
|
3160
3200
|
_meta: {
|
|
3161
3201
|
posthog: {
|
|
@@ -3195,6 +3235,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3195
3235
|
);
|
|
3196
3236
|
}
|
|
3197
3237
|
async unstable_resumeSession(params) {
|
|
3238
|
+
const existing = this.getExistingSessionState(params.sessionId);
|
|
3239
|
+
if (existing) return existing;
|
|
3198
3240
|
const response = await this.createSession(
|
|
3199
3241
|
{
|
|
3200
3242
|
cwd: params.cwd,
|
|
@@ -3208,6 +3250,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3208
3250
|
return response;
|
|
3209
3251
|
}
|
|
3210
3252
|
async loadSession(params) {
|
|
3253
|
+
const existing = this.getExistingSessionState(params.sessionId);
|
|
3254
|
+
if (existing) return existing;
|
|
3211
3255
|
const response = await this.createSession(
|
|
3212
3256
|
{
|
|
3213
3257
|
cwd: params.cwd,
|
|
@@ -3224,7 +3268,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3224
3268
|
configOptions: response.configOptions
|
|
3225
3269
|
};
|
|
3226
3270
|
}
|
|
3227
|
-
async
|
|
3271
|
+
async listSessions(params) {
|
|
3228
3272
|
const sdkSessions = await listSessions({ dir: params.cwd ?? void 0 });
|
|
3229
3273
|
const sessions = [];
|
|
3230
3274
|
for (const session of sdkSessions) {
|
|
@@ -3240,6 +3284,9 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3240
3284
|
sessions
|
|
3241
3285
|
};
|
|
3242
3286
|
}
|
|
3287
|
+
async unstable_listSessions(params) {
|
|
3288
|
+
return this.listSessions(params);
|
|
3289
|
+
}
|
|
3243
3290
|
async prompt(params) {
|
|
3244
3291
|
this.session.cancelled = false;
|
|
3245
3292
|
this.session.interruptReason = void 0;
|
|
@@ -3250,17 +3297,37 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3250
3297
|
cachedWriteTokens: 0
|
|
3251
3298
|
};
|
|
3252
3299
|
const userMessage = promptToClaude(params);
|
|
3300
|
+
const promptUuid = randomUUID();
|
|
3301
|
+
userMessage.uuid = promptUuid;
|
|
3302
|
+
let promptReplayed = false;
|
|
3303
|
+
let isLocalOnlyCommand = false;
|
|
3304
|
+
const msgContent = userMessage.message.content;
|
|
3305
|
+
let firstTextPart = "";
|
|
3306
|
+
if (typeof msgContent === "string") {
|
|
3307
|
+
firstTextPart = msgContent;
|
|
3308
|
+
} else if (Array.isArray(msgContent)) {
|
|
3309
|
+
for (const block of msgContent) {
|
|
3310
|
+
if ("type" in block && block.type === "text" && "text" in block) {
|
|
3311
|
+
firstTextPart = block.text;
|
|
3312
|
+
break;
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
const commandMatch = firstTextPart.match(/^(\/\S+)/);
|
|
3317
|
+
if (commandMatch && LOCAL_ONLY_COMMANDS.has(commandMatch[1])) {
|
|
3318
|
+
isLocalOnlyCommand = true;
|
|
3319
|
+
promptReplayed = true;
|
|
3320
|
+
}
|
|
3253
3321
|
if (this.session.promptRunning) {
|
|
3254
|
-
const uuid = randomUUID();
|
|
3255
|
-
userMessage.uuid = uuid;
|
|
3256
3322
|
this.session.input.push(userMessage);
|
|
3257
3323
|
const order = this.session.nextPendingOrder++;
|
|
3258
3324
|
const cancelled = await new Promise((resolve3) => {
|
|
3259
|
-
this.session.pendingMessages.set(
|
|
3325
|
+
this.session.pendingMessages.set(promptUuid, { resolve: resolve3, order });
|
|
3260
3326
|
});
|
|
3261
3327
|
if (cancelled) {
|
|
3262
3328
|
return { stopReason: "cancelled" };
|
|
3263
3329
|
}
|
|
3330
|
+
promptReplayed = true;
|
|
3264
3331
|
} else {
|
|
3265
3332
|
this.session.input.push(userMessage);
|
|
3266
3333
|
}
|
|
@@ -3268,6 +3335,16 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3268
3335
|
this.session.promptRunning = true;
|
|
3269
3336
|
let handedOff = false;
|
|
3270
3337
|
let lastAssistantTotalUsage = null;
|
|
3338
|
+
if (this.session.lastContextWindowSize == null) {
|
|
3339
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
3340
|
+
this.session.modelId ?? ""
|
|
3341
|
+
);
|
|
3342
|
+
this.logger.debug("Initial context window size from gateway", {
|
|
3343
|
+
modelId: this.session.modelId,
|
|
3344
|
+
contextWindowSize: this.session.lastContextWindowSize
|
|
3345
|
+
});
|
|
3346
|
+
}
|
|
3347
|
+
let lastContextWindowSize = this.session.lastContextWindowSize;
|
|
3271
3348
|
const supportsTerminalOutput = this.clientCapabilities?._meta?.terminal_output === true;
|
|
3272
3349
|
const context = {
|
|
3273
3350
|
session: this.session,
|
|
@@ -3294,10 +3371,21 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3294
3371
|
case "system":
|
|
3295
3372
|
if (message.subtype === "compact_boundary") {
|
|
3296
3373
|
lastAssistantTotalUsage = 0;
|
|
3374
|
+
promptReplayed = true;
|
|
3375
|
+
}
|
|
3376
|
+
if (message.subtype === "local_command_output") {
|
|
3377
|
+
promptReplayed = true;
|
|
3297
3378
|
}
|
|
3298
3379
|
await handleSystemMessage(message, context);
|
|
3299
3380
|
break;
|
|
3300
3381
|
case "result": {
|
|
3382
|
+
if (!promptReplayed) {
|
|
3383
|
+
this.logger.debug(
|
|
3384
|
+
"Skipping background task result before prompt replay",
|
|
3385
|
+
{ sessionId: params.sessionId }
|
|
3386
|
+
);
|
|
3387
|
+
break;
|
|
3388
|
+
}
|
|
3301
3389
|
if (this.session.cancelled) {
|
|
3302
3390
|
return { stopReason: "cancelled" };
|
|
3303
3391
|
}
|
|
@@ -3308,8 +3396,19 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3308
3396
|
const contextWindows = Object.values(message.modelUsage).map(
|
|
3309
3397
|
(m) => m.contextWindow
|
|
3310
3398
|
);
|
|
3311
|
-
|
|
3312
|
-
|
|
3399
|
+
if (contextWindows.length > 0) {
|
|
3400
|
+
const sdkContextWindow = Math.min(...contextWindows);
|
|
3401
|
+
if (sdkContextWindow > lastContextWindowSize) {
|
|
3402
|
+
lastContextWindowSize = sdkContextWindow;
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
this.session.lastContextWindowSize = lastContextWindowSize;
|
|
3406
|
+
this.logger.debug("Context window size from result", {
|
|
3407
|
+
sdkReported: contextWindows,
|
|
3408
|
+
resolved: lastContextWindowSize,
|
|
3409
|
+
modelId: this.session.modelId
|
|
3410
|
+
});
|
|
3411
|
+
this.session.contextSize = lastContextWindowSize;
|
|
3313
3412
|
if (lastAssistantTotalUsage !== null) {
|
|
3314
3413
|
this.session.contextUsed = lastAssistantTotalUsage;
|
|
3315
3414
|
}
|
|
@@ -3319,7 +3418,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3319
3418
|
update: {
|
|
3320
3419
|
sessionUpdate: "usage_update",
|
|
3321
3420
|
used: lastAssistantTotalUsage,
|
|
3322
|
-
size:
|
|
3421
|
+
size: lastContextWindowSize,
|
|
3323
3422
|
cost: {
|
|
3324
3423
|
amount: message.total_cost_usd,
|
|
3325
3424
|
currency: "USD"
|
|
@@ -3346,6 +3445,15 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3346
3445
|
};
|
|
3347
3446
|
const result = handleResultMessage(message);
|
|
3348
3447
|
if (result.error) throw result.error;
|
|
3448
|
+
if (isLocalOnlyCommand && message.subtype === "success" && message.result) {
|
|
3449
|
+
await this.client.sessionUpdate({
|
|
3450
|
+
sessionId: params.sessionId,
|
|
3451
|
+
update: {
|
|
3452
|
+
sessionUpdate: "agent_message_chunk",
|
|
3453
|
+
content: { type: "text", text: message.result }
|
|
3454
|
+
}
|
|
3455
|
+
});
|
|
3456
|
+
}
|
|
3349
3457
|
return { stopReason: result.stopReason ?? "end_turn", usage };
|
|
3350
3458
|
}
|
|
3351
3459
|
case "stream_event":
|
|
@@ -3357,6 +3465,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3357
3465
|
break;
|
|
3358
3466
|
}
|
|
3359
3467
|
if (message.type === "user" && "uuid" in message && message.uuid) {
|
|
3468
|
+
if (message.uuid === promptUuid) {
|
|
3469
|
+
promptReplayed = true;
|
|
3470
|
+
break;
|
|
3471
|
+
}
|
|
3360
3472
|
const pending = this.session.pendingMessages.get(
|
|
3361
3473
|
message.uuid
|
|
3362
3474
|
);
|
|
@@ -3372,7 +3484,16 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3372
3484
|
}
|
|
3373
3485
|
if ("usage" in message.message && message.parent_tool_use_id === null) {
|
|
3374
3486
|
const usage = message.message.usage;
|
|
3375
|
-
lastAssistantTotalUsage = usage.input_tokens + usage.
|
|
3487
|
+
lastAssistantTotalUsage = usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens;
|
|
3488
|
+
await this.client.sessionUpdate({
|
|
3489
|
+
sessionId: params.sessionId,
|
|
3490
|
+
update: {
|
|
3491
|
+
sessionUpdate: "usage_update",
|
|
3492
|
+
used: lastAssistantTotalUsage,
|
|
3493
|
+
size: lastContextWindowSize,
|
|
3494
|
+
cost: null
|
|
3495
|
+
}
|
|
3496
|
+
});
|
|
3376
3497
|
}
|
|
3377
3498
|
const result = await handleUserAssistantMessage(message, context);
|
|
3378
3499
|
if (result.error) throw result.error;
|
|
@@ -3402,6 +3523,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3402
3523
|
this.logger.error(`Process died: ${msg}`, {
|
|
3403
3524
|
sessionId: this.sessionId
|
|
3404
3525
|
});
|
|
3526
|
+
this.session.settingsManager.dispose();
|
|
3405
3527
|
this.session.input.end();
|
|
3406
3528
|
throw RequestError2.internalError(
|
|
3407
3529
|
void 0,
|
|
@@ -3429,9 +3551,11 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3429
3551
|
await this.session.query.interrupt();
|
|
3430
3552
|
}
|
|
3431
3553
|
async unstable_setSessionModel(params) {
|
|
3432
|
-
|
|
3433
|
-
await this.session.query.setModel(sdkModelId);
|
|
3554
|
+
await this.session.query.setModel(toSdkModelId(params.modelId));
|
|
3434
3555
|
this.session.modelId = params.modelId;
|
|
3556
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
3557
|
+
params.modelId
|
|
3558
|
+
);
|
|
3435
3559
|
this.rebuildEffortConfigOption(params.modelId);
|
|
3436
3560
|
await this.updateConfigOption("model", params.modelId);
|
|
3437
3561
|
return {};
|
|
@@ -3448,42 +3572,55 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3448
3572
|
if (!option) {
|
|
3449
3573
|
throw new Error(`Unknown config option: ${params.configId}`);
|
|
3450
3574
|
}
|
|
3575
|
+
if (typeof params.value !== "string") {
|
|
3576
|
+
throw new Error(
|
|
3577
|
+
`Invalid value type for config option ${params.configId}`
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3451
3580
|
const allValues = "options" in option && Array.isArray(option.options) ? option.options.flatMap(
|
|
3452
3581
|
(o) => "options" in o && Array.isArray(o.options) ? o.options : [o]
|
|
3453
3582
|
) : [];
|
|
3454
|
-
|
|
3583
|
+
let validValue = allValues.find((o) => o.value === params.value);
|
|
3584
|
+
if (!validValue && params.configId === "model") {
|
|
3585
|
+
const resolved = resolveModelPreference(params.value, allValues);
|
|
3586
|
+
if (resolved) {
|
|
3587
|
+
validValue = allValues.find((o) => o.value === resolved);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3455
3590
|
if (!validValue) {
|
|
3456
3591
|
throw new Error(
|
|
3457
3592
|
`Invalid value for config option ${params.configId}: ${params.value}`
|
|
3458
3593
|
);
|
|
3459
3594
|
}
|
|
3595
|
+
const resolvedValue = validValue.value;
|
|
3460
3596
|
if (params.configId === "mode") {
|
|
3461
|
-
await this.applySessionMode(
|
|
3597
|
+
await this.applySessionMode(resolvedValue);
|
|
3462
3598
|
await this.client.sessionUpdate({
|
|
3463
3599
|
sessionId: this.sessionId,
|
|
3464
3600
|
update: {
|
|
3465
3601
|
sessionUpdate: "current_mode_update",
|
|
3466
|
-
currentModeId:
|
|
3602
|
+
currentModeId: resolvedValue
|
|
3467
3603
|
}
|
|
3468
3604
|
});
|
|
3469
3605
|
} else if (params.configId === "model") {
|
|
3470
|
-
const sdkModelId = toSdkModelId(
|
|
3606
|
+
const sdkModelId = toSdkModelId(resolvedValue);
|
|
3471
3607
|
await this.session.query.setModel(sdkModelId);
|
|
3472
|
-
this.session.modelId =
|
|
3473
|
-
this.
|
|
3608
|
+
this.session.modelId = resolvedValue;
|
|
3609
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(resolvedValue);
|
|
3610
|
+
this.rebuildEffortConfigOption(resolvedValue);
|
|
3474
3611
|
} else if (params.configId === "effort") {
|
|
3475
|
-
const newEffort =
|
|
3612
|
+
const newEffort = resolvedValue;
|
|
3476
3613
|
this.session.effort = newEffort;
|
|
3477
3614
|
this.session.queryOptions.effort = newEffort;
|
|
3478
3615
|
}
|
|
3479
3616
|
this.session.configOptions = this.session.configOptions.map(
|
|
3480
|
-
(o) => o.id === params.configId ? { ...o, currentValue:
|
|
3617
|
+
(o) => o.id === params.configId && typeof o.currentValue === "string" ? { ...o, currentValue: resolvedValue } : o
|
|
3481
3618
|
);
|
|
3482
3619
|
return { configOptions: this.session.configOptions };
|
|
3483
3620
|
}
|
|
3484
3621
|
async updateConfigOption(configId, value) {
|
|
3485
3622
|
this.session.configOptions = this.session.configOptions.map(
|
|
3486
|
-
(o) => o.id === configId ? { ...o, currentValue: value } : o
|
|
3623
|
+
(o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o
|
|
3487
3624
|
);
|
|
3488
3625
|
await this.client.sessionUpdate({
|
|
3489
3626
|
sessionId: this.sessionId,
|
|
@@ -3550,7 +3687,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3550
3687
|
sessionId,
|
|
3551
3688
|
isResume,
|
|
3552
3689
|
forkSession,
|
|
3553
|
-
additionalDirectories:
|
|
3690
|
+
additionalDirectories: [
|
|
3691
|
+
...meta?.claudeCode?.options?.additionalDirectories ?? [],
|
|
3692
|
+
...meta?.additionalRoots ?? []
|
|
3693
|
+
],
|
|
3554
3694
|
disableBuiltInTools: meta?.disableBuiltInTools,
|
|
3555
3695
|
settingsManager,
|
|
3556
3696
|
onModeChange: this.createOnModeChange(),
|
|
@@ -3627,11 +3767,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3627
3767
|
const modelOptions = await this.getModelConfigOptions();
|
|
3628
3768
|
const resolvedModelId = settingsModel || modelOptions.currentModelId;
|
|
3629
3769
|
session.modelId = resolvedModelId;
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
}
|
|
3770
|
+
session.lastContextWindowSize = this.getContextWindowForModel(resolvedModelId);
|
|
3771
|
+
const resolvedSdkModel = toSdkModelId(resolvedModelId);
|
|
3772
|
+
if (!isResume && resolvedSdkModel !== DEFAULT_MODEL) {
|
|
3773
|
+
await this.session.query.setModel(resolvedSdkModel);
|
|
3635
3774
|
}
|
|
3636
3775
|
const availableModes2 = getAvailableModes();
|
|
3637
3776
|
const modes = {
|
|
@@ -3694,6 +3833,35 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3694
3833
|
await this.updateConfigOption("mode", newMode);
|
|
3695
3834
|
};
|
|
3696
3835
|
}
|
|
3836
|
+
getExistingSessionState(sessionId) {
|
|
3837
|
+
if (this.sessionId !== sessionId || !this.session) return null;
|
|
3838
|
+
const availableModes2 = getAvailableModes();
|
|
3839
|
+
const modes = {
|
|
3840
|
+
currentModeId: this.session.permissionMode,
|
|
3841
|
+
availableModes: availableModes2.map((mode) => ({
|
|
3842
|
+
id: mode.id,
|
|
3843
|
+
name: mode.name,
|
|
3844
|
+
description: mode.description ?? void 0
|
|
3845
|
+
}))
|
|
3846
|
+
};
|
|
3847
|
+
const modelOptions = this.session.configOptions.find(
|
|
3848
|
+
(o) => o.id === "model"
|
|
3849
|
+
);
|
|
3850
|
+
const models = {
|
|
3851
|
+
currentModelId: this.session.modelId ?? DEFAULT_MODEL,
|
|
3852
|
+
availableModels: modelOptions && "options" in modelOptions ? modelOptions.options.map((opt) => ({
|
|
3853
|
+
modelId: opt.value,
|
|
3854
|
+
name: opt.name,
|
|
3855
|
+
description: opt.description
|
|
3856
|
+
})) : []
|
|
3857
|
+
};
|
|
3858
|
+
return {
|
|
3859
|
+
sessionId,
|
|
3860
|
+
modes,
|
|
3861
|
+
models,
|
|
3862
|
+
configOptions: this.session.configOptions
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3697
3865
|
buildConfigOptions(currentModeId, modelOptions, currentEffort = "high") {
|
|
3698
3866
|
const modeOptions = getAvailableModes().map((mode) => ({
|
|
3699
3867
|
value: mode.id,
|
|
@@ -3749,7 +3917,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
3749
3917
|
}
|
|
3750
3918
|
return;
|
|
3751
3919
|
}
|
|
3752
|
-
const
|
|
3920
|
+
const rawCurrentValue = existingEffort?.currentValue;
|
|
3921
|
+
const currentValue = typeof rawCurrentValue === "string" ? rawCurrentValue : "high";
|
|
3753
3922
|
const isValidValue = effortOptions.some((o) => o.value === currentValue);
|
|
3754
3923
|
const resolvedValue = isValidValue ? currentValue : "high";
|
|
3755
3924
|
if (resolvedValue !== currentValue && this.session.effort) {
|