@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
|
@@ -908,7 +908,7 @@ import { Hono } from "hono";
|
|
|
908
908
|
// package.json
|
|
909
909
|
var package_default = {
|
|
910
910
|
name: "@posthog/agent",
|
|
911
|
-
version: "2.3.
|
|
911
|
+
version: "2.3.73",
|
|
912
912
|
repository: "https://github.com/PostHog/code",
|
|
913
913
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
914
914
|
exports: {
|
|
@@ -995,8 +995,8 @@ var package_default = {
|
|
|
995
995
|
vitest: "^2.1.8"
|
|
996
996
|
},
|
|
997
997
|
dependencies: {
|
|
998
|
-
"@agentclientprotocol/sdk": "0.
|
|
999
|
-
"@anthropic-ai/claude-agent-sdk": "0.2.
|
|
998
|
+
"@agentclientprotocol/sdk": "0.16.1",
|
|
999
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.76",
|
|
1000
1000
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
1001
1001
|
"@hono/node-server": "^1.19.9",
|
|
1002
1002
|
"@opentelemetry/api-logs": "^0.208.0",
|
|
@@ -1382,12 +1382,14 @@ function formatGatewayModelName(model) {
|
|
|
1382
1382
|
}
|
|
1383
1383
|
|
|
1384
1384
|
// src/adapters/base-acp-agent.ts
|
|
1385
|
+
var DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
1385
1386
|
var BaseAcpAgent = class {
|
|
1386
1387
|
session;
|
|
1387
1388
|
sessionId;
|
|
1388
1389
|
client;
|
|
1389
1390
|
logger;
|
|
1390
1391
|
fileContentCache = {};
|
|
1392
|
+
gatewayModels = [];
|
|
1391
1393
|
constructor(client) {
|
|
1392
1394
|
this.client = client;
|
|
1393
1395
|
this.logger = new Logger({ debug: true, prefix: "[BaseAcpAgent]" });
|
|
@@ -1440,8 +1442,8 @@ var BaseAcpAgent = class {
|
|
|
1440
1442
|
throw new Error("Method not implemented.");
|
|
1441
1443
|
}
|
|
1442
1444
|
async getModelConfigOptions(currentModelOverride) {
|
|
1443
|
-
|
|
1444
|
-
const options = gatewayModels.filter((model) => isAnthropicModel(model)).map((model) => ({
|
|
1445
|
+
this.gatewayModels = await fetchGatewayModels();
|
|
1446
|
+
const options = this.gatewayModels.filter((model) => isAnthropicModel(model)).map((model) => ({
|
|
1445
1447
|
value: model.id,
|
|
1446
1448
|
name: formatGatewayModelName(model),
|
|
1447
1449
|
description: `Context: ${model.context_window.toLocaleString()} tokens`
|
|
@@ -1462,6 +1464,10 @@ var BaseAcpAgent = class {
|
|
|
1462
1464
|
}
|
|
1463
1465
|
return { currentModelId, options };
|
|
1464
1466
|
}
|
|
1467
|
+
getContextWindowForModel(modelId) {
|
|
1468
|
+
const match = this.gatewayModels.find((m) => m.id === modelId);
|
|
1469
|
+
return match?.context_window ?? DEFAULT_CONTEXT_WINDOW;
|
|
1470
|
+
}
|
|
1465
1471
|
};
|
|
1466
1472
|
|
|
1467
1473
|
// src/adapters/claude/conversion/acp-to-sdk.ts
|
|
@@ -2637,7 +2643,7 @@ function streamEventToAcpNotifications(message, sessionId, toolUseCache, fileCon
|
|
|
2637
2643
|
}
|
|
2638
2644
|
}
|
|
2639
2645
|
async function handleSystemMessage(message, context) {
|
|
2640
|
-
const { sessionId, client, logger } = context;
|
|
2646
|
+
const { session, sessionId, client, logger } = context;
|
|
2641
2647
|
switch (message.subtype) {
|
|
2642
2648
|
case "init":
|
|
2643
2649
|
break;
|
|
@@ -2645,7 +2651,8 @@ async function handleSystemMessage(message, context) {
|
|
|
2645
2651
|
await client.extNotification("_posthog/compact_boundary", {
|
|
2646
2652
|
sessionId,
|
|
2647
2653
|
trigger: message.compact_metadata.trigger,
|
|
2648
|
-
preTokens: message.compact_metadata.pre_tokens
|
|
2654
|
+
preTokens: message.compact_metadata.pre_tokens,
|
|
2655
|
+
contextSize: session.contextSize
|
|
2649
2656
|
});
|
|
2650
2657
|
break;
|
|
2651
2658
|
case "hook_response":
|
|
@@ -2817,21 +2824,6 @@ function filterMessageContent(content) {
|
|
|
2817
2824
|
async function handleUserAssistantMessage(message, context) {
|
|
2818
2825
|
const { session, sessionId, client, toolUseCache, fileContentCache, logger } = context;
|
|
2819
2826
|
if (shouldSkipUserAssistantMessage(message)) {
|
|
2820
|
-
const content2 = message.message.content;
|
|
2821
|
-
if (typeof content2 === "string" && hasLocalCommandStdout(content2) && content2.includes("Context Usage")) {
|
|
2822
|
-
const stripped = content2.replace("<local-command-stdout>", "").replace("</local-command-stdout>", "");
|
|
2823
|
-
for (const notification of toAcpNotifications(
|
|
2824
|
-
stripped,
|
|
2825
|
-
"assistant",
|
|
2826
|
-
sessionId,
|
|
2827
|
-
toolUseCache,
|
|
2828
|
-
fileContentCache,
|
|
2829
|
-
client,
|
|
2830
|
-
logger
|
|
2831
|
-
)) {
|
|
2832
|
-
await client.sessionUpdate(notification);
|
|
2833
|
-
}
|
|
2834
|
-
}
|
|
2835
2827
|
logSpecialMessages(message, logger);
|
|
2836
2828
|
if (isLoginRequiredMessage(message)) {
|
|
2837
2829
|
return { shouldStop: true, error: RequestError.authRequired() };
|
|
@@ -3091,8 +3083,17 @@ function buildPermissionOptions(toolName, toolInput, cwd, suggestions) {
|
|
|
3091
3083
|
}
|
|
3092
3084
|
return permissionOptions("Yes, always allow");
|
|
3093
3085
|
}
|
|
3086
|
+
var ALLOW_BYPASS2 = !IS_ROOT || !!process.env.IS_SANDBOX;
|
|
3094
3087
|
function buildExitPlanModePermissionOptions() {
|
|
3095
|
-
|
|
3088
|
+
const options = [];
|
|
3089
|
+
if (ALLOW_BYPASS2) {
|
|
3090
|
+
options.push({
|
|
3091
|
+
kind: "allow_always",
|
|
3092
|
+
name: "Yes, bypass all permissions",
|
|
3093
|
+
optionId: "bypassPermissions"
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
options.push(
|
|
3096
3097
|
{
|
|
3097
3098
|
kind: "allow_always",
|
|
3098
3099
|
name: "Yes, and auto-accept edits",
|
|
@@ -3109,7 +3110,8 @@ function buildExitPlanModePermissionOptions() {
|
|
|
3109
3110
|
optionId: "reject_with_feedback",
|
|
3110
3111
|
_meta: { customInput: true }
|
|
3111
3112
|
}
|
|
3112
|
-
|
|
3113
|
+
);
|
|
3114
|
+
return options;
|
|
3113
3115
|
}
|
|
3114
3116
|
|
|
3115
3117
|
// src/adapters/claude/permissions/permission-handlers.ts
|
|
@@ -3183,7 +3185,7 @@ async function requestPlanApproval(context, updatedInput) {
|
|
|
3183
3185
|
}
|
|
3184
3186
|
async function applyPlanApproval(response, context, updatedInput) {
|
|
3185
3187
|
const { session } = context;
|
|
3186
|
-
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "default" || response.outcome.optionId === "acceptEdits")) {
|
|
3188
|
+
if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "default" || response.outcome.optionId === "acceptEdits" || response.outcome.optionId === "bypassPermissions")) {
|
|
3187
3189
|
session.permissionMode = response.outcome.optionId;
|
|
3188
3190
|
await session.query.setPermissionMode(response.outcome.optionId);
|
|
3189
3191
|
await context.client.sessionUpdate({
|
|
@@ -3256,8 +3258,7 @@ async function handleAskUserQuestionTool(context) {
|
|
|
3256
3258
|
context.logger.warn("[AskUserQuestion] No questions found in input");
|
|
3257
3259
|
return {
|
|
3258
3260
|
behavior: "deny",
|
|
3259
|
-
message: "No questions provided"
|
|
3260
|
-
interrupt: true
|
|
3261
|
+
message: "No questions provided"
|
|
3261
3262
|
};
|
|
3262
3263
|
}
|
|
3263
3264
|
const { client, sessionId, toolUseID, toolInput } = context;
|
|
@@ -3288,16 +3289,14 @@ async function handleAskUserQuestionTool(context) {
|
|
|
3288
3289
|
const customMessage = response._meta?.message;
|
|
3289
3290
|
return {
|
|
3290
3291
|
behavior: "deny",
|
|
3291
|
-
message: typeof customMessage === "string" ? customMessage : "User cancelled the questions"
|
|
3292
|
-
interrupt: true
|
|
3292
|
+
message: typeof customMessage === "string" ? customMessage : "User cancelled the questions"
|
|
3293
3293
|
};
|
|
3294
3294
|
}
|
|
3295
3295
|
const answers = response._meta?.answers;
|
|
3296
3296
|
if (!answers || Object.keys(answers).length === 0) {
|
|
3297
3297
|
return {
|
|
3298
3298
|
behavior: "deny",
|
|
3299
|
-
message: "User did not provide answers"
|
|
3300
|
-
interrupt: true
|
|
3299
|
+
message: "User did not provide answers"
|
|
3301
3300
|
};
|
|
3302
3301
|
}
|
|
3303
3302
|
return {
|
|
@@ -3364,8 +3363,7 @@ async function handleDefaultPermissionFlow(context) {
|
|
|
3364
3363
|
await emitToolDenial(context, message);
|
|
3365
3364
|
return {
|
|
3366
3365
|
behavior: "deny",
|
|
3367
|
-
message
|
|
3368
|
-
interrupt: true
|
|
3366
|
+
message
|
|
3369
3367
|
};
|
|
3370
3368
|
}
|
|
3371
3369
|
}
|
|
@@ -3479,16 +3477,6 @@ var GATEWAY_TO_SDK_MODEL = {
|
|
|
3479
3477
|
function toSdkModelId(modelId) {
|
|
3480
3478
|
return GATEWAY_TO_SDK_MODEL[modelId] ?? modelId;
|
|
3481
3479
|
}
|
|
3482
|
-
var MODELS_WITH_1M_CONTEXT = /* @__PURE__ */ new Set([
|
|
3483
|
-
"claude-opus-4-6",
|
|
3484
|
-
"claude-sonnet-4-6"
|
|
3485
|
-
]);
|
|
3486
|
-
function supports1MContext(modelId) {
|
|
3487
|
-
return MODELS_WITH_1M_CONTEXT.has(modelId);
|
|
3488
|
-
}
|
|
3489
|
-
function getDefaultContextWindow(modelId) {
|
|
3490
|
-
return supports1MContext(modelId) ? 1e6 : 2e5;
|
|
3491
|
-
}
|
|
3492
3480
|
var MODELS_WITH_EFFORT = /* @__PURE__ */ new Set([
|
|
3493
3481
|
"claude-opus-4-5",
|
|
3494
3482
|
"claude-opus-4-6",
|
|
@@ -3513,6 +3501,56 @@ function getEffortOptions(modelId) {
|
|
|
3513
3501
|
}
|
|
3514
3502
|
return options;
|
|
3515
3503
|
}
|
|
3504
|
+
var MODEL_CONTEXT_HINT_PATTERN = /\[(\d+m)\]$/i;
|
|
3505
|
+
function tokenizeModelPreference(model) {
|
|
3506
|
+
const lower = model.trim().toLowerCase();
|
|
3507
|
+
const contextHint = lower.match(MODEL_CONTEXT_HINT_PATTERN)?.[1]?.toLowerCase();
|
|
3508
|
+
const normalized = lower.replace(MODEL_CONTEXT_HINT_PATTERN, " $1 ");
|
|
3509
|
+
const rawTokens = normalized.split(/[^a-z0-9]+/).filter(Boolean);
|
|
3510
|
+
const tokens = rawTokens.map((token) => {
|
|
3511
|
+
if (token === "opusplan") return "opus";
|
|
3512
|
+
if (token === "best" || token === "default") return "";
|
|
3513
|
+
return token;
|
|
3514
|
+
}).filter((token) => token && token !== "claude").filter((token) => /[a-z]/.test(token) || token.endsWith("m"));
|
|
3515
|
+
return { tokens, contextHint };
|
|
3516
|
+
}
|
|
3517
|
+
function scoreModelMatch(model, tokens, contextHint) {
|
|
3518
|
+
const haystack = `${model.value} ${model.name ?? ""}`.toLowerCase();
|
|
3519
|
+
let score = 0;
|
|
3520
|
+
for (const token of tokens) {
|
|
3521
|
+
if (haystack.includes(token)) {
|
|
3522
|
+
score += token === contextHint ? 3 : 1;
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
return score;
|
|
3526
|
+
}
|
|
3527
|
+
function resolveModelPreference(preference, options) {
|
|
3528
|
+
const trimmed2 = preference.trim();
|
|
3529
|
+
if (!trimmed2) return null;
|
|
3530
|
+
const lower = trimmed2.toLowerCase();
|
|
3531
|
+
const directMatch = options.find(
|
|
3532
|
+
(o) => o.value === trimmed2 || o.value.toLowerCase() === lower || o.name && o.name.toLowerCase() === lower
|
|
3533
|
+
);
|
|
3534
|
+
if (directMatch) return directMatch.value;
|
|
3535
|
+
const includesMatch = options.find((o) => {
|
|
3536
|
+
const value = o.value.toLowerCase();
|
|
3537
|
+
const display = (o.name ?? "").toLowerCase();
|
|
3538
|
+
return value.includes(lower) || display.includes(lower) || lower.includes(value);
|
|
3539
|
+
});
|
|
3540
|
+
if (includesMatch) return includesMatch.value;
|
|
3541
|
+
const { tokens, contextHint } = tokenizeModelPreference(trimmed2);
|
|
3542
|
+
if (tokens.length === 0) return null;
|
|
3543
|
+
let bestMatch = null;
|
|
3544
|
+
let bestScore = 0;
|
|
3545
|
+
for (const model of options) {
|
|
3546
|
+
const score = scoreModelMatch(model, tokens, contextHint);
|
|
3547
|
+
if (0 < score && (!bestMatch || bestScore < score)) {
|
|
3548
|
+
bestMatch = model;
|
|
3549
|
+
bestScore = score;
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
return bestMatch?.value ?? null;
|
|
3553
|
+
}
|
|
3516
3554
|
|
|
3517
3555
|
// src/adapters/claude/session/options.ts
|
|
3518
3556
|
import { spawn } from "child_process";
|
|
@@ -3993,6 +4031,7 @@ var SettingsManager = class {
|
|
|
3993
4031
|
// src/adapters/claude/claude-agent.ts
|
|
3994
4032
|
var SESSION_VALIDATION_TIMEOUT_MS = 1e4;
|
|
3995
4033
|
var MAX_TITLE_LENGTH = 256;
|
|
4034
|
+
var LOCAL_ONLY_COMMANDS = /* @__PURE__ */ new Set(["/context", "/heapdump", "/extra-usage"]);
|
|
3996
4035
|
function sanitizeTitle(text2) {
|
|
3997
4036
|
const sanitized = text2.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
3998
4037
|
if (sanitized.length <= MAX_TITLE_LENGTH) {
|
|
@@ -4029,7 +4068,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4029
4068
|
sessionCapabilities: {
|
|
4030
4069
|
list: {},
|
|
4031
4070
|
fork: {},
|
|
4032
|
-
resume: {}
|
|
4071
|
+
resume: {},
|
|
4072
|
+
close: {}
|
|
4033
4073
|
},
|
|
4034
4074
|
_meta: {
|
|
4035
4075
|
posthog: {
|
|
@@ -4069,6 +4109,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4069
4109
|
);
|
|
4070
4110
|
}
|
|
4071
4111
|
async unstable_resumeSession(params) {
|
|
4112
|
+
const existing = this.getExistingSessionState(params.sessionId);
|
|
4113
|
+
if (existing) return existing;
|
|
4072
4114
|
const response = await this.createSession(
|
|
4073
4115
|
{
|
|
4074
4116
|
cwd: params.cwd,
|
|
@@ -4082,6 +4124,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4082
4124
|
return response;
|
|
4083
4125
|
}
|
|
4084
4126
|
async loadSession(params) {
|
|
4127
|
+
const existing = this.getExistingSessionState(params.sessionId);
|
|
4128
|
+
if (existing) return existing;
|
|
4085
4129
|
const response = await this.createSession(
|
|
4086
4130
|
{
|
|
4087
4131
|
cwd: params.cwd,
|
|
@@ -4098,7 +4142,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4098
4142
|
configOptions: response.configOptions
|
|
4099
4143
|
};
|
|
4100
4144
|
}
|
|
4101
|
-
async
|
|
4145
|
+
async listSessions(params) {
|
|
4102
4146
|
const sdkSessions = await listSessions({ dir: params.cwd ?? void 0 });
|
|
4103
4147
|
const sessions = [];
|
|
4104
4148
|
for (const session of sdkSessions) {
|
|
@@ -4114,6 +4158,9 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4114
4158
|
sessions
|
|
4115
4159
|
};
|
|
4116
4160
|
}
|
|
4161
|
+
async unstable_listSessions(params) {
|
|
4162
|
+
return this.listSessions(params);
|
|
4163
|
+
}
|
|
4117
4164
|
async prompt(params) {
|
|
4118
4165
|
this.session.cancelled = false;
|
|
4119
4166
|
this.session.interruptReason = void 0;
|
|
@@ -4124,17 +4171,37 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4124
4171
|
cachedWriteTokens: 0
|
|
4125
4172
|
};
|
|
4126
4173
|
const userMessage = promptToClaude(params);
|
|
4174
|
+
const promptUuid = randomUUID();
|
|
4175
|
+
userMessage.uuid = promptUuid;
|
|
4176
|
+
let promptReplayed = false;
|
|
4177
|
+
let isLocalOnlyCommand = false;
|
|
4178
|
+
const msgContent = userMessage.message.content;
|
|
4179
|
+
let firstTextPart = "";
|
|
4180
|
+
if (typeof msgContent === "string") {
|
|
4181
|
+
firstTextPart = msgContent;
|
|
4182
|
+
} else if (Array.isArray(msgContent)) {
|
|
4183
|
+
for (const block of msgContent) {
|
|
4184
|
+
if ("type" in block && block.type === "text" && "text" in block) {
|
|
4185
|
+
firstTextPart = block.text;
|
|
4186
|
+
break;
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
const commandMatch = firstTextPart.match(/^(\/\S+)/);
|
|
4191
|
+
if (commandMatch && LOCAL_ONLY_COMMANDS.has(commandMatch[1])) {
|
|
4192
|
+
isLocalOnlyCommand = true;
|
|
4193
|
+
promptReplayed = true;
|
|
4194
|
+
}
|
|
4127
4195
|
if (this.session.promptRunning) {
|
|
4128
|
-
const uuid = randomUUID();
|
|
4129
|
-
userMessage.uuid = uuid;
|
|
4130
4196
|
this.session.input.push(userMessage);
|
|
4131
4197
|
const order = this.session.nextPendingOrder++;
|
|
4132
4198
|
const cancelled = await new Promise((resolve4) => {
|
|
4133
|
-
this.session.pendingMessages.set(
|
|
4199
|
+
this.session.pendingMessages.set(promptUuid, { resolve: resolve4, order });
|
|
4134
4200
|
});
|
|
4135
4201
|
if (cancelled) {
|
|
4136
4202
|
return { stopReason: "cancelled" };
|
|
4137
4203
|
}
|
|
4204
|
+
promptReplayed = true;
|
|
4138
4205
|
} else {
|
|
4139
4206
|
this.session.input.push(userMessage);
|
|
4140
4207
|
}
|
|
@@ -4142,6 +4209,16 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4142
4209
|
this.session.promptRunning = true;
|
|
4143
4210
|
let handedOff = false;
|
|
4144
4211
|
let lastAssistantTotalUsage = null;
|
|
4212
|
+
if (this.session.lastContextWindowSize == null) {
|
|
4213
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
4214
|
+
this.session.modelId ?? ""
|
|
4215
|
+
);
|
|
4216
|
+
this.logger.debug("Initial context window size from gateway", {
|
|
4217
|
+
modelId: this.session.modelId,
|
|
4218
|
+
contextWindowSize: this.session.lastContextWindowSize
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
let lastContextWindowSize = this.session.lastContextWindowSize;
|
|
4145
4222
|
const supportsTerminalOutput = this.clientCapabilities?._meta?.terminal_output === true;
|
|
4146
4223
|
const context = {
|
|
4147
4224
|
session: this.session,
|
|
@@ -4168,10 +4245,21 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4168
4245
|
case "system":
|
|
4169
4246
|
if (message.subtype === "compact_boundary") {
|
|
4170
4247
|
lastAssistantTotalUsage = 0;
|
|
4248
|
+
promptReplayed = true;
|
|
4249
|
+
}
|
|
4250
|
+
if (message.subtype === "local_command_output") {
|
|
4251
|
+
promptReplayed = true;
|
|
4171
4252
|
}
|
|
4172
4253
|
await handleSystemMessage(message, context);
|
|
4173
4254
|
break;
|
|
4174
4255
|
case "result": {
|
|
4256
|
+
if (!promptReplayed) {
|
|
4257
|
+
this.logger.debug(
|
|
4258
|
+
"Skipping background task result before prompt replay",
|
|
4259
|
+
{ sessionId: params.sessionId }
|
|
4260
|
+
);
|
|
4261
|
+
break;
|
|
4262
|
+
}
|
|
4175
4263
|
if (this.session.cancelled) {
|
|
4176
4264
|
return { stopReason: "cancelled" };
|
|
4177
4265
|
}
|
|
@@ -4182,8 +4270,19 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4182
4270
|
const contextWindows = Object.values(message.modelUsage).map(
|
|
4183
4271
|
(m) => m.contextWindow
|
|
4184
4272
|
);
|
|
4185
|
-
|
|
4186
|
-
|
|
4273
|
+
if (contextWindows.length > 0) {
|
|
4274
|
+
const sdkContextWindow = Math.min(...contextWindows);
|
|
4275
|
+
if (sdkContextWindow > lastContextWindowSize) {
|
|
4276
|
+
lastContextWindowSize = sdkContextWindow;
|
|
4277
|
+
}
|
|
4278
|
+
}
|
|
4279
|
+
this.session.lastContextWindowSize = lastContextWindowSize;
|
|
4280
|
+
this.logger.debug("Context window size from result", {
|
|
4281
|
+
sdkReported: contextWindows,
|
|
4282
|
+
resolved: lastContextWindowSize,
|
|
4283
|
+
modelId: this.session.modelId
|
|
4284
|
+
});
|
|
4285
|
+
this.session.contextSize = lastContextWindowSize;
|
|
4187
4286
|
if (lastAssistantTotalUsage !== null) {
|
|
4188
4287
|
this.session.contextUsed = lastAssistantTotalUsage;
|
|
4189
4288
|
}
|
|
@@ -4193,7 +4292,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4193
4292
|
update: {
|
|
4194
4293
|
sessionUpdate: "usage_update",
|
|
4195
4294
|
used: lastAssistantTotalUsage,
|
|
4196
|
-
size:
|
|
4295
|
+
size: lastContextWindowSize,
|
|
4197
4296
|
cost: {
|
|
4198
4297
|
amount: message.total_cost_usd,
|
|
4199
4298
|
currency: "USD"
|
|
@@ -4220,6 +4319,15 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4220
4319
|
};
|
|
4221
4320
|
const result = handleResultMessage(message);
|
|
4222
4321
|
if (result.error) throw result.error;
|
|
4322
|
+
if (isLocalOnlyCommand && message.subtype === "success" && message.result) {
|
|
4323
|
+
await this.client.sessionUpdate({
|
|
4324
|
+
sessionId: params.sessionId,
|
|
4325
|
+
update: {
|
|
4326
|
+
sessionUpdate: "agent_message_chunk",
|
|
4327
|
+
content: { type: "text", text: message.result }
|
|
4328
|
+
}
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4223
4331
|
return { stopReason: result.stopReason ?? "end_turn", usage };
|
|
4224
4332
|
}
|
|
4225
4333
|
case "stream_event":
|
|
@@ -4231,6 +4339,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4231
4339
|
break;
|
|
4232
4340
|
}
|
|
4233
4341
|
if (message.type === "user" && "uuid" in message && message.uuid) {
|
|
4342
|
+
if (message.uuid === promptUuid) {
|
|
4343
|
+
promptReplayed = true;
|
|
4344
|
+
break;
|
|
4345
|
+
}
|
|
4234
4346
|
const pending = this.session.pendingMessages.get(
|
|
4235
4347
|
message.uuid
|
|
4236
4348
|
);
|
|
@@ -4246,7 +4358,16 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4246
4358
|
}
|
|
4247
4359
|
if ("usage" in message.message && message.parent_tool_use_id === null) {
|
|
4248
4360
|
const usage = message.message.usage;
|
|
4249
|
-
lastAssistantTotalUsage = usage.input_tokens + usage.
|
|
4361
|
+
lastAssistantTotalUsage = usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens;
|
|
4362
|
+
await this.client.sessionUpdate({
|
|
4363
|
+
sessionId: params.sessionId,
|
|
4364
|
+
update: {
|
|
4365
|
+
sessionUpdate: "usage_update",
|
|
4366
|
+
used: lastAssistantTotalUsage,
|
|
4367
|
+
size: lastContextWindowSize,
|
|
4368
|
+
cost: null
|
|
4369
|
+
}
|
|
4370
|
+
});
|
|
4250
4371
|
}
|
|
4251
4372
|
const result = await handleUserAssistantMessage(message, context);
|
|
4252
4373
|
if (result.error) throw result.error;
|
|
@@ -4276,6 +4397,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4276
4397
|
this.logger.error(`Process died: ${msg}`, {
|
|
4277
4398
|
sessionId: this.sessionId
|
|
4278
4399
|
});
|
|
4400
|
+
this.session.settingsManager.dispose();
|
|
4279
4401
|
this.session.input.end();
|
|
4280
4402
|
throw RequestError2.internalError(
|
|
4281
4403
|
void 0,
|
|
@@ -4303,9 +4425,11 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4303
4425
|
await this.session.query.interrupt();
|
|
4304
4426
|
}
|
|
4305
4427
|
async unstable_setSessionModel(params) {
|
|
4306
|
-
|
|
4307
|
-
await this.session.query.setModel(sdkModelId);
|
|
4428
|
+
await this.session.query.setModel(toSdkModelId(params.modelId));
|
|
4308
4429
|
this.session.modelId = params.modelId;
|
|
4430
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(
|
|
4431
|
+
params.modelId
|
|
4432
|
+
);
|
|
4309
4433
|
this.rebuildEffortConfigOption(params.modelId);
|
|
4310
4434
|
await this.updateConfigOption("model", params.modelId);
|
|
4311
4435
|
return {};
|
|
@@ -4322,42 +4446,55 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4322
4446
|
if (!option) {
|
|
4323
4447
|
throw new Error(`Unknown config option: ${params.configId}`);
|
|
4324
4448
|
}
|
|
4449
|
+
if (typeof params.value !== "string") {
|
|
4450
|
+
throw new Error(
|
|
4451
|
+
`Invalid value type for config option ${params.configId}`
|
|
4452
|
+
);
|
|
4453
|
+
}
|
|
4325
4454
|
const allValues = "options" in option && Array.isArray(option.options) ? option.options.flatMap(
|
|
4326
4455
|
(o) => "options" in o && Array.isArray(o.options) ? o.options : [o]
|
|
4327
4456
|
) : [];
|
|
4328
|
-
|
|
4457
|
+
let validValue = allValues.find((o) => o.value === params.value);
|
|
4458
|
+
if (!validValue && params.configId === "model") {
|
|
4459
|
+
const resolved = resolveModelPreference(params.value, allValues);
|
|
4460
|
+
if (resolved) {
|
|
4461
|
+
validValue = allValues.find((o) => o.value === resolved);
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4329
4464
|
if (!validValue) {
|
|
4330
4465
|
throw new Error(
|
|
4331
4466
|
`Invalid value for config option ${params.configId}: ${params.value}`
|
|
4332
4467
|
);
|
|
4333
4468
|
}
|
|
4469
|
+
const resolvedValue = validValue.value;
|
|
4334
4470
|
if (params.configId === "mode") {
|
|
4335
|
-
await this.applySessionMode(
|
|
4471
|
+
await this.applySessionMode(resolvedValue);
|
|
4336
4472
|
await this.client.sessionUpdate({
|
|
4337
4473
|
sessionId: this.sessionId,
|
|
4338
4474
|
update: {
|
|
4339
4475
|
sessionUpdate: "current_mode_update",
|
|
4340
|
-
currentModeId:
|
|
4476
|
+
currentModeId: resolvedValue
|
|
4341
4477
|
}
|
|
4342
4478
|
});
|
|
4343
4479
|
} else if (params.configId === "model") {
|
|
4344
|
-
const sdkModelId = toSdkModelId(
|
|
4480
|
+
const sdkModelId = toSdkModelId(resolvedValue);
|
|
4345
4481
|
await this.session.query.setModel(sdkModelId);
|
|
4346
|
-
this.session.modelId =
|
|
4347
|
-
this.
|
|
4482
|
+
this.session.modelId = resolvedValue;
|
|
4483
|
+
this.session.lastContextWindowSize = this.getContextWindowForModel(resolvedValue);
|
|
4484
|
+
this.rebuildEffortConfigOption(resolvedValue);
|
|
4348
4485
|
} else if (params.configId === "effort") {
|
|
4349
|
-
const newEffort =
|
|
4486
|
+
const newEffort = resolvedValue;
|
|
4350
4487
|
this.session.effort = newEffort;
|
|
4351
4488
|
this.session.queryOptions.effort = newEffort;
|
|
4352
4489
|
}
|
|
4353
4490
|
this.session.configOptions = this.session.configOptions.map(
|
|
4354
|
-
(o) => o.id === params.configId ? { ...o, currentValue:
|
|
4491
|
+
(o) => o.id === params.configId && typeof o.currentValue === "string" ? { ...o, currentValue: resolvedValue } : o
|
|
4355
4492
|
);
|
|
4356
4493
|
return { configOptions: this.session.configOptions };
|
|
4357
4494
|
}
|
|
4358
4495
|
async updateConfigOption(configId, value) {
|
|
4359
4496
|
this.session.configOptions = this.session.configOptions.map(
|
|
4360
|
-
(o) => o.id === configId ? { ...o, currentValue: value } : o
|
|
4497
|
+
(o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o
|
|
4361
4498
|
);
|
|
4362
4499
|
await this.client.sessionUpdate({
|
|
4363
4500
|
sessionId: this.sessionId,
|
|
@@ -4424,7 +4561,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4424
4561
|
sessionId,
|
|
4425
4562
|
isResume,
|
|
4426
4563
|
forkSession,
|
|
4427
|
-
additionalDirectories:
|
|
4564
|
+
additionalDirectories: [
|
|
4565
|
+
...meta?.claudeCode?.options?.additionalDirectories ?? [],
|
|
4566
|
+
...meta?.additionalRoots ?? []
|
|
4567
|
+
],
|
|
4428
4568
|
disableBuiltInTools: meta?.disableBuiltInTools,
|
|
4429
4569
|
settingsManager,
|
|
4430
4570
|
onModeChange: this.createOnModeChange(),
|
|
@@ -4501,11 +4641,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4501
4641
|
const modelOptions = await this.getModelConfigOptions();
|
|
4502
4642
|
const resolvedModelId = settingsModel || modelOptions.currentModelId;
|
|
4503
4643
|
session.modelId = resolvedModelId;
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
}
|
|
4644
|
+
session.lastContextWindowSize = this.getContextWindowForModel(resolvedModelId);
|
|
4645
|
+
const resolvedSdkModel = toSdkModelId(resolvedModelId);
|
|
4646
|
+
if (!isResume && resolvedSdkModel !== DEFAULT_MODEL) {
|
|
4647
|
+
await this.session.query.setModel(resolvedSdkModel);
|
|
4509
4648
|
}
|
|
4510
4649
|
const availableModes2 = getAvailableModes();
|
|
4511
4650
|
const modes = {
|
|
@@ -4568,6 +4707,35 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4568
4707
|
await this.updateConfigOption("mode", newMode);
|
|
4569
4708
|
};
|
|
4570
4709
|
}
|
|
4710
|
+
getExistingSessionState(sessionId) {
|
|
4711
|
+
if (this.sessionId !== sessionId || !this.session) return null;
|
|
4712
|
+
const availableModes2 = getAvailableModes();
|
|
4713
|
+
const modes = {
|
|
4714
|
+
currentModeId: this.session.permissionMode,
|
|
4715
|
+
availableModes: availableModes2.map((mode) => ({
|
|
4716
|
+
id: mode.id,
|
|
4717
|
+
name: mode.name,
|
|
4718
|
+
description: mode.description ?? void 0
|
|
4719
|
+
}))
|
|
4720
|
+
};
|
|
4721
|
+
const modelOptions = this.session.configOptions.find(
|
|
4722
|
+
(o) => o.id === "model"
|
|
4723
|
+
);
|
|
4724
|
+
const models = {
|
|
4725
|
+
currentModelId: this.session.modelId ?? DEFAULT_MODEL,
|
|
4726
|
+
availableModels: modelOptions && "options" in modelOptions ? modelOptions.options.map((opt) => ({
|
|
4727
|
+
modelId: opt.value,
|
|
4728
|
+
name: opt.name,
|
|
4729
|
+
description: opt.description
|
|
4730
|
+
})) : []
|
|
4731
|
+
};
|
|
4732
|
+
return {
|
|
4733
|
+
sessionId,
|
|
4734
|
+
modes,
|
|
4735
|
+
models,
|
|
4736
|
+
configOptions: this.session.configOptions
|
|
4737
|
+
};
|
|
4738
|
+
}
|
|
4571
4739
|
buildConfigOptions(currentModeId, modelOptions, currentEffort = "high") {
|
|
4572
4740
|
const modeOptions = getAvailableModes().map((mode) => ({
|
|
4573
4741
|
value: mode.id,
|
|
@@ -4623,7 +4791,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
4623
4791
|
}
|
|
4624
4792
|
return;
|
|
4625
4793
|
}
|
|
4626
|
-
const
|
|
4794
|
+
const rawCurrentValue = existingEffort?.currentValue;
|
|
4795
|
+
const currentValue = typeof rawCurrentValue === "string" ? rawCurrentValue : "high";
|
|
4627
4796
|
const isValidValue = effortOptions.some((o) => o.value === currentValue);
|
|
4628
4797
|
const resolvedValue = isValidValue ? currentValue : "high";
|
|
4629
4798
|
if (resolvedValue !== currentValue && this.session.effort) {
|