@agentclientprotocol/claude-agent-acp 0.90.1-preview.9 → 0.91.1-preview.1
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/README.md +14 -5
- package/dist/acp-agent.d.ts +94 -11
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +246 -76
- package/dist/air-extension.d.ts +6 -0
- package/dist/air-extension.d.ts.map +1 -1
- package/dist/air-extension.js +6 -0
- package/dist/file-change-audit.d.ts +17 -0
- package/dist/file-change-audit.d.ts.map +1 -1
- package/dist/file-change-audit.js +62 -20
- package/dist/gateway-models.d.ts +62 -0
- package/dist/gateway-models.d.ts.map +1 -0
- package/dist/gateway-models.js +180 -0
- package/dist/native-subagents.d.ts +34 -9
- package/dist/native-subagents.d.ts.map +1 -1
- package/dist/native-subagents.js +55 -11
- package/dist/session-index/connection.d.ts +4 -3
- package/dist/session-index/connection.d.ts.map +1 -1
- package/dist/session-index/connection.js +8 -7
- package/dist/session-index/list-subscriptions.d.ts.map +1 -1
- package/dist/session-index/list-subscriptions.js +4 -1
- package/dist/session-index/service.d.ts +10 -0
- package/dist/session-index/service.d.ts.map +1 -1
- package/dist/session-index/service.js +21 -0
- package/dist/session-index/session-index.d.ts +10 -2
- package/dist/session-index/session-index.d.ts.map +1 -1
- package/dist/session-index/session-index.js +21 -5
- package/dist/session-index/session-info.d.ts.map +1 -1
- package/dist/session-index/session-info.js +1 -0
- package/dist/session-index/transcript-scan.d.ts +25 -1
- package/dist/session-index/transcript-scan.d.ts.map +1 -1
- package/dist/session-index/transcript-scan.js +57 -1
- package/dist/session-index/worktrees.d.ts +6 -0
- package/dist/session-index/worktrees.d.ts.map +1 -1
- package/dist/session-index/worktrees.js +12 -0
- package/dist/session-model.d.ts +21 -1
- package/dist/session-model.d.ts.map +1 -1
- package/dist/session-model.js +89 -11
- package/dist/turn-events.d.ts +5 -1
- package/dist/turn-events.d.ts.map +1 -1
- package/dist/v2/prompt.d.ts +2 -1
- package/dist/v2/prompt.d.ts.map +1 -1
- package/dist/v2/prompt.js +2 -1
- package/package.json +3 -3
package/dist/session-model.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AIR_RECOMMENDED_CONFIG_VALUE_CAPABILITY, withAirMeta } from "./air-extension.js";
|
|
2
|
+
import { bedrockRegionPrefix } from "./gateway-models.js";
|
|
2
3
|
export const MODEL_CONFIG_ID = "model";
|
|
3
4
|
const MODEL_CONTEXT_HINT_PATTERN = /\[(\d+m)\]$/i;
|
|
4
5
|
const CONTEXT_HINT_SUFFIX_PATTERN = /-(\d+m)$/i;
|
|
@@ -218,9 +219,10 @@ function resolveSettingsModel(models, settingsModel, logger) {
|
|
|
218
219
|
return resolveModelPreference(models, settingsModel);
|
|
219
220
|
}
|
|
220
221
|
const MODEL_FAMILY_ALIASES = new Set(["opus", "sonnet", "haiku", "fable"]);
|
|
221
|
-
/** A model id without the spellings
|
|
222
|
-
* prefixes, dates, version suffixes, `-fast` and context hints.
|
|
223
|
-
|
|
222
|
+
/** A model id without the spellings that name the same model: provider
|
|
223
|
+
* prefixes, dates, version suffixes, `-fast` and context hints. `deniedModels`
|
|
224
|
+
* and gateway listings both match on it. */
|
|
225
|
+
function normalizeModelId(value) {
|
|
224
226
|
let id = stripContextHints(value.trim().toLowerCase());
|
|
225
227
|
const providerPrefix = id.lastIndexOf("anthropic.");
|
|
226
228
|
if (providerPrefix !== -1)
|
|
@@ -239,11 +241,11 @@ function normalizeDeniedModelId(value) {
|
|
|
239
241
|
* the enforcer; this only keeps the picker from offering a refused row.
|
|
240
242
|
*/
|
|
241
243
|
export function isDeniedModel(modelId, deniedModels) {
|
|
242
|
-
const id =
|
|
244
|
+
const id = normalizeModelId(modelId);
|
|
243
245
|
if (!id)
|
|
244
246
|
return false;
|
|
245
247
|
return deniedModels.some((entry) => {
|
|
246
|
-
const denied =
|
|
248
|
+
const denied = normalizeModelId(entry);
|
|
247
249
|
if (!denied)
|
|
248
250
|
return false;
|
|
249
251
|
if (MODEL_FAMILY_ALIASES.has(denied))
|
|
@@ -324,6 +326,46 @@ export function applyAvailableModelsAllowlist(sdkModels, allowlist, settingsMode
|
|
|
324
326
|
}
|
|
325
327
|
return result;
|
|
326
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Keep the SDK models the `providers/set` gateway listed (`listGatewayModels`,
|
|
331
|
+
* `listBedrockModels`). A row matches when its `resolvedModel` (or
|
|
332
|
+
* its `value` when the SDK gives none) names a listed model in any spelling:
|
|
333
|
+
* `claude-sonnet-5[1m]` matches a listed `claude-sonnet-5-20260101`, and
|
|
334
|
+
* `eu.anthropic.claude-sonnet-5` matches a listed `eu.anthropic.claude-sonnet-5-v1:0`.
|
|
335
|
+
*
|
|
336
|
+
* With a Bedrock `regionPrefix`, a row resolved to another cross-region prefix
|
|
337
|
+
* (`us.anthropic.claude-sonnet-5` under `eu`) is dropped even when the same
|
|
338
|
+
* model is listed under `eu`: the CLI would call it in the other region.
|
|
339
|
+
*
|
|
340
|
+
* A row the SDK gives no `resolvedModel` names its model only by an alias, so
|
|
341
|
+
* it is checked as far as the alias allows: `default` is kept, and a family
|
|
342
|
+
* alias such as `opus` is kept when the gateway lists a model of that family.
|
|
343
|
+
*
|
|
344
|
+
* When no row matches by its model (a `default` row kept only for lacking a
|
|
345
|
+
* `resolvedModel` does not count), the gateway serves none of the SDK's
|
|
346
|
+
* models, and nothing is left: the session offers no model.
|
|
347
|
+
*/
|
|
348
|
+
export function narrowToGatewayModels(models, listedModelIds, regionPrefix) {
|
|
349
|
+
const listed = new Set(listedModelIds.map(normalizeModelId).filter(Boolean));
|
|
350
|
+
const narrowed = models.filter((model) => {
|
|
351
|
+
const modelId = model.resolvedModel ?? model.value;
|
|
352
|
+
const prefix = bedrockRegionPrefix(modelId);
|
|
353
|
+
if (regionPrefix !== undefined && prefix !== undefined && prefix !== regionPrefix) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
const id = normalizeModelId(modelId);
|
|
357
|
+
if (listed.has(id))
|
|
358
|
+
return true;
|
|
359
|
+
if (model.resolvedModel !== undefined)
|
|
360
|
+
return false;
|
|
361
|
+
if (model.value === "default")
|
|
362
|
+
return true;
|
|
363
|
+
return MODEL_FAMILY_ALIASES.has(id) && [...listed].some((entry) => entry.includes(`-${id}`));
|
|
364
|
+
});
|
|
365
|
+
return narrowed.some((model) => listed.has(normalizeModelId(model.resolvedModel ?? model.value)))
|
|
366
|
+
? narrowed
|
|
367
|
+
: [];
|
|
368
|
+
}
|
|
327
369
|
/** Whether a rejected `setModel` was vetoed by a user-configured
|
|
328
370
|
* PreModelSwitch hook. The CLI's rejection message is the stable,
|
|
329
371
|
* distinguishable marker ("Model switch blocked by a PreModelSwitch hook:
|
|
@@ -332,7 +374,16 @@ export function applyAvailableModelsAllowlist(sdkModels, allowlist, settingsMode
|
|
|
332
374
|
function isPreModelSwitchHookBlock(error) {
|
|
333
375
|
return error instanceof Error && error.message.includes("blocked by a PreModelSwitch hook");
|
|
334
376
|
}
|
|
335
|
-
export async function getAvailableModels(query, models, sdkModels, settingsManager, logger, isResumedSession, sessionId, resumedModelHint) {
|
|
377
|
+
export async function getAvailableModels(query, models, sdkModels, settingsManager, logger, isResumedSession, sessionId, resumedModelHint, narrowedByGateway = false) {
|
|
378
|
+
// A gateway that lists none of the SDK's models leaves none to offer
|
|
379
|
+
// (`narrowToGatewayModels`). The session stays on the model the SDK runs,
|
|
380
|
+
// and the gateway refuses its requests.
|
|
381
|
+
if (models.length === 0) {
|
|
382
|
+
return {
|
|
383
|
+
availableModels: [],
|
|
384
|
+
currentModelId: (isResumedSession && resumedModelHint) || sdkModels[0]?.value || "default",
|
|
385
|
+
};
|
|
386
|
+
}
|
|
336
387
|
const settings = settingsManager.getSettings();
|
|
337
388
|
let currentModel = models[0];
|
|
338
389
|
let resolvedFromInput;
|
|
@@ -377,8 +428,31 @@ export async function getAvailableModels(query, models, sdkModels, settingsManag
|
|
|
377
428
|
// be re-asserted to keep the reported model truthful.
|
|
378
429
|
// Anything else (fuzzy match, allowlist-synthesized value, alias) gets a
|
|
379
430
|
// setModel call so we don't drift from the user's intended pin.
|
|
431
|
+
// Case (a) does not hold when `narrowToGatewayModels` left the SDK on a
|
|
432
|
+
// model the gateway does not list: the dropped `default` row of a fresh or
|
|
433
|
+
// transcript-less session, or a resumed transcript model outside the list.
|
|
434
|
+
// Such a session switches to models[0].
|
|
380
435
|
const sdkSawSameValue = sdkModels.some((m) => m.value === currentModel.value);
|
|
381
|
-
const
|
|
436
|
+
const sdkDefault = sdkModels.find((m) => m.value === "default");
|
|
437
|
+
const sdkDefaultDropped = sdkDefault !== undefined && !models.some((m) => m.value === "default");
|
|
438
|
+
let switchToListed = false;
|
|
439
|
+
if (resolvedFromInput === undefined) {
|
|
440
|
+
if (!isResumedSession || !resumedModelHint) {
|
|
441
|
+
switchToListed = sdkDefaultDropped;
|
|
442
|
+
}
|
|
443
|
+
else if (narrowedByGateway &&
|
|
444
|
+
(!models.some((m) => m.value === currentModel.value) ||
|
|
445
|
+
// A loose match can map the transcript's model onto a listed row of
|
|
446
|
+
// another version, which the CLI does not resume on.
|
|
447
|
+
(currentModel.resolvedModel !== undefined &&
|
|
448
|
+
normalizeModelId(currentModel.resolvedModel) !== normalizeModelId(resumedModelHint)))) {
|
|
449
|
+
currentModel = models[0];
|
|
450
|
+
switchToListed = true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// When the switch fails, the SDK stays on the model it ran before it.
|
|
454
|
+
const modelBeforeSwitch = () => switchToListed && sdkDefault !== undefined ? sdkDefault : models[0];
|
|
455
|
+
const skipSetModel = (resolvedFromInput === undefined && !switchToListed) ||
|
|
382
456
|
(!isResumedSession && currentModel.value === resolvedFromInput && sdkSawSameValue);
|
|
383
457
|
if (!skipSetModel) {
|
|
384
458
|
const setModelStartedAt = performance.now();
|
|
@@ -407,14 +481,18 @@ export async function getAvailableModels(query, models, sdkModels, settingsManag
|
|
|
407
481
|
// live model back on this path: getContextUsage isn't serviced on a
|
|
408
482
|
// fresh session until the first prompt turn (issues #886/#880).
|
|
409
483
|
if (!isResumedSession) {
|
|
410
|
-
|
|
484
|
+
// A switch onto a listed model is advisory too: the session stays on
|
|
485
|
+
// the model the SDK runs and reports it.
|
|
486
|
+
if (!switchToListed && !isPreModelSwitchHookBlock(error))
|
|
411
487
|
throw error;
|
|
412
|
-
logger.error(`Model
|
|
413
|
-
currentModel =
|
|
488
|
+
logger.error(`Model switch to "${currentModel.value}" failed or was vetoed by a PreModelSwitch hook; staying on the default model:`, error);
|
|
489
|
+
currentModel = modelBeforeSwitch();
|
|
414
490
|
}
|
|
415
491
|
else {
|
|
416
492
|
logger.error(`Failed to re-assert model "${currentModel.value}" on resume:`, error);
|
|
417
|
-
currentModel = resumedModelHint
|
|
493
|
+
currentModel = resumedModelHint
|
|
494
|
+
? matchResumedModel(models, resumedModelHint)
|
|
495
|
+
: modelBeforeSwitch();
|
|
418
496
|
}
|
|
419
497
|
}
|
|
420
498
|
}
|
package/dist/turn-events.d.ts
CHANGED
|
@@ -53,7 +53,11 @@ export interface TurnEvents {
|
|
|
53
53
|
* the cycle reports nothing more, and the turn reports from there.
|
|
54
54
|
*/
|
|
55
55
|
export interface ForegroundEvents {
|
|
56
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* The work started, or works again after it waited for the user. Not after
|
|
58
|
+
* a wait that a cancel ended: Claude Code's interrupt withdrew the last
|
|
59
|
+
* request, so the work is being stopped, and {@link ended} follows at once.
|
|
60
|
+
*/
|
|
57
61
|
running(): void;
|
|
58
62
|
/**
|
|
59
63
|
* The work waits for the user: a permission request or a question is open in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-events.d.ts","sourceRoot":"","sources":["../src/turn-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAgB;IAC/B
|
|
1
|
+
{"version":3,"file":"turn-events.d.ts","sourceRoot":"","sources":["../src/turn-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,OAAO,IAAI,IAAI,CAAC;IAChB;;;;OAIG;IACH,YAAY,IAAI,IAAI,CAAC;IACrB,sBAAsB;IACtB,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnG,wBAAwB;AACxB,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC"}
|
package/dist/v2/prompt.d.ts
CHANGED
|
@@ -28,7 +28,8 @@ export declare function v2Prompt(agent: ClaudeAcpAgent, params: v2.PromptRequest
|
|
|
28
28
|
*
|
|
29
29
|
* - Started: `running`. For a prompt's turn, right after its `user_message`.
|
|
30
30
|
* - Waiting on a permission request or a question: `requires_action`, and
|
|
31
|
-
* `running` once none is open
|
|
31
|
+
* `running` once none is open, unless a cancel withdrew the last one: the
|
|
32
|
+
* work is being stopped then, and its `idle` follows.
|
|
32
33
|
* - Ended: `idle` with the stop reason, usage, and `_meta` of the work.
|
|
33
34
|
* - Failed: `idle` with the `error` stop reason and the JSON-RPC error that v1
|
|
34
35
|
* answers the prompt with, so a client can show its message and handle its
|
package/dist/v2/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/v2/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAuC,MAAM,mBAAmB,CAAC;AAE/F;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,EAAE,CAAC,aAAa,EACxB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GACvC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAiC5B;AAED
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/v2/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,0CAA0C,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAuC,MAAM,mBAAmB,CAAC;AAE/F;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,EAAE,CAAC,aAAa,EACxB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GACvC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAiC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GAAG,gBAAgB,CAoBvF;AAgCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,aAAa,GAAG,aAAa,CAEvF"}
|
package/dist/v2/prompt.js
CHANGED
|
@@ -57,7 +57,8 @@ export function v2Prompt(agent, params, send) {
|
|
|
57
57
|
*
|
|
58
58
|
* - Started: `running`. For a prompt's turn, right after its `user_message`.
|
|
59
59
|
* - Waiting on a permission request or a question: `requires_action`, and
|
|
60
|
-
* `running` once none is open
|
|
60
|
+
* `running` once none is open, unless a cancel withdrew the last one: the
|
|
61
|
+
* work is being stopped then, and its `idle` follows.
|
|
61
62
|
* - Ended: `idle` with the stop reason, usage, and `_meta` of the work.
|
|
62
63
|
* - Failed: `idle` with the `error` stop reason and the JSON-RPC error that v1
|
|
63
64
|
* answers the prompt with, so a client can show its message and handle its
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.91.1-preview.1",
|
|
7
7
|
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
|
|
8
8
|
"main": "dist/lib.js",
|
|
9
9
|
"types": "dist/lib.d.ts",
|
|
@@ -66,12 +66,12 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@agentclientprotocol/sdk": "1.8.0",
|
|
69
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
69
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.300",
|
|
70
70
|
"diff": "9.0.0",
|
|
71
71
|
"zod": "4.6.7"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@anthropic-ai/sdk": "0.
|
|
74
|
+
"@anthropic-ai/sdk": "0.134.0",
|
|
75
75
|
"@eslint/js": "10.0.1",
|
|
76
76
|
"@tsconfig/node22": "22.0.6",
|
|
77
77
|
"@types/node": "26.6.5",
|