@armadra/agent 0.11.0 → 0.12.0
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/CHANGELOG.md +13 -0
- package/CHANGELOG.zh-CN.md +13 -0
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +2 -2
- package/dist/bundle/ama.cjs +125 -24
- package/dist/cli/compose-agents.js +8 -0
- package/dist/drivers/acp/client.d.ts +54 -5
- package/dist/drivers/acp/client.js +96 -9
- package/dist/drivers/acp/types.d.ts +69 -3
- package/dist/drivers/acp/types.js +30 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.js +12 -4
- package/dist/permissions/auto-safe.d.ts +3 -0
- package/dist/permissions/auto-safe.js +10 -3
- package/dist/permissions/readonly-bash.d.ts +2 -2
- package/dist/permissions/readonly-bash.js +2 -2
- package/dist/tools/presets.d.ts +7 -0
- package/dist/tools/presets.js +10 -1
- package/dist/tools/task-ctl.d.ts +9 -0
- package/dist/tools/task-ctl.js +22 -3
- package/docs/en/guides/permissions.md +10 -10
- package/docs/en/reference/acp.md +7 -3
- package/docs/guides/agents.md +4 -1
- package/docs/guides/permissions.md +10 -10
- package/docs/reference/acp.md +7 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ English · [简体中文](CHANGELOG.zh-CN.md)
|
|
|
5
5
|
> This file is in English starting with 0.6.0. Release notes for 0.1 through 0.5.1 are in Chinese in
|
|
6
6
|
> [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md). New entries go into both files.
|
|
7
7
|
|
|
8
|
+
## 0.12.0 (2026-11-02)
|
|
9
|
+
|
|
10
|
+
### Tools and permissions
|
|
11
|
+
|
|
12
|
+
- **The `coordinator` preset never blocks**: when `task` / `task_ctl` are exposed, `task` defaults to background (regardless of `-p` and `subagents.background`; an explicit `background` argument and an agent definition's `background:` still win) and `task_ctl wait` is capped at 5 s (the default and larger `timeoutMs` included); the timed-out reply says the wait was capped and that a `<task-notification>` follows. Other presets, tool descriptions and schemas are byte-identical (#242).
|
|
13
|
+
- **`env` / `printenv` are no longer auto-safe**: the bash subprocess inherits the whole process environment (provider API keys included), so in Auto mode a bare `env`, `printenv`, `env FOO=1` or `env | grep …` now goes to the classifier / approval instead of being allowed statically; `env FOO=1 cmd` is still judged as `cmd`. The read-only list for Plan already excluded them, so both lists now agree (#240).
|
|
14
|
+
|
|
15
|
+
### ACP client
|
|
16
|
+
|
|
17
|
+
- **Authentication**: `AcpClient.authenticate(methodId)` and `logout()` (`supportsLogout()`), `isAuthRequiredError` for -32000, and the `authTerminal` option that declares `clientCapabilities.auth.terminal`. `authMethods` keeps id, name, description, type and, for terminal methods, `args` / `env`; a known terminal method is refused locally by `authenticate` (-32602) as the spec requires. `isTerminalAuthMethod` and the types `AcpAuthenticateResult`, `AcpLogoutResult`, `AcpTerminalAuthMethod` are exported (#245).
|
|
18
|
+
- **`elicitation/complete` and richer forms**: `onElicitationComplete` handles the notification (declaring `elicitation: { form: {}, url: {} }`) and dismisses a still-pending request with the same `elicitationId`; form fields gain `array` multi-select and titled `oneOf` / `anyOf`, `content` values may be string arrays, and `multiSelectOptions` / `singleSelectOptions` normalize the option lists (#245).
|
|
19
|
+
- **Sessions**: `listSessions` takes a `signal`, `listAllSessions` follows `nextCursor`, `closeSession` takes a `signal` and first answers the session's pending permission and elicitation requests with cancel; `AcpSessionInfo` gains `additionalDirectories` and `_meta`. `AcpClient.features` gains `auth` and `elicitationComplete`. Default wire output is unchanged unless the new options are used (#245).
|
|
20
|
+
|
|
8
21
|
## 0.11.0 (2026-10-30)
|
|
9
22
|
|
|
10
23
|
### Tools and permissions
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
> 从 0.6.0 起 [CHANGELOG.md](CHANGELOG.md) 为英文,本文件保留中文记录(0.1–0.5.1 的完整历史在此)。新条目两份都要加。
|
|
6
6
|
|
|
7
|
+
## 0.12.0(2026-11-02)
|
|
8
|
+
|
|
9
|
+
### 工具与权限
|
|
10
|
+
|
|
11
|
+
- **`coordinator` 预设不阻塞**:暴露 `task` / `task_ctl` 时,`task` 缺省后台(不受 `-p` 与 `subagents.background` 影响,调用参数 `background` 与类型定义的 `background:` 仍优先),`task_ctl wait` 的超时封顶 5 秒(含缺省与更大的 `timeoutMs`),超时回复说明被封顶、完成后会有 `<task-notification>`。其它预设、工具描述与 schema 逐字节不变(#242)。
|
|
12
|
+
- **`env` / `printenv` 不再免审批**:bash 子进程继承整个进程环境(含供应商 API key),Auto 模式下裸 `env`、`printenv`、`env FOO=1`、`env | grep …` 现在交给分类器 / 审批,不再静态放行;`env FOO=1 cmd` 仍按 `cmd` 判断。Plan 的只读名单本来就没有它们,两份名单现在一致(#240)。
|
|
13
|
+
|
|
14
|
+
### ACP 客户端
|
|
15
|
+
|
|
16
|
+
- **认证**:`AcpClient.authenticate(methodId)` 与 `logout()`(`supportsLogout()`)、判断 -32000 的 `isAuthRequiredError`,以及声明 `clientCapabilities.auth.terminal` 的构造参数 `authTerminal`。`authMethods` 保留 id、name、description、type,terminal 型还有 `args` / `env`;已知是 terminal 型的方法按规范由 `authenticate` 本地拒绝(-32602)。新增导出 `isTerminalAuthMethod` 与类型 `AcpAuthenticateResult`、`AcpLogoutResult`、`AcpTerminalAuthMethod`(#245)。
|
|
17
|
+
- **`elicitation/complete` 与更丰富的表单**:`onElicitationComplete` 接这条通知(声明 `elicitation: { form: {}, url: {} }`),并收掉同 `elicitationId` 还挂着的请求;表单字段新增 `array` 多选与带标题的 `oneOf` / `anyOf`,`content` 的值可以是字符串数组,`multiSelectOptions` / `singleSelectOptions` 把几种写法收成统一的选项列表(#245)。
|
|
18
|
+
- **会话**:`listSessions` 可传 `signal`,新增跟 `nextCursor` 翻页的 `listAllSessions`;`closeSession` 可传 `signal`,并先把该会话挂起的权限与 elicitation 请求答成取消;`AcpSessionInfo` 补 `additionalDirectories`、`_meta`。`AcpClient.features` 增加 `auth` 与 `elicitationComplete`。不用新选项时默认线路输出不变(#245)。
|
|
19
|
+
|
|
7
20
|
## 0.11.0(2026-10-30)
|
|
8
21
|
|
|
9
22
|
### 工具与权限
|
package/dist/acp.d.ts
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export type * from "./drivers/types.js";
|
|
10
10
|
export type * from "./drivers/acp/types.js";
|
|
11
|
-
export { ACP_META_KEY, ACP_METHODS, ACP_PROTOCOL_VERSION, RPC_ERRORS, } from "./drivers/acp/types.js";
|
|
11
|
+
export { ACP_META_KEY, isTerminalAuthMethod, multiSelectOptions, singleSelectOptions, ACP_METHODS, ACP_PROTOCOL_VERSION, RPC_ERRORS, } from "./drivers/acp/types.js";
|
|
12
12
|
export { WRITE_CHUNK_BYTES, createLineReader, writeChunked, type LineReader, } from "./modes/rpc/jsonl.js";
|
|
13
13
|
export { JsonRpcPeer, RpcError, type IncomingRequestContext, type JsonRpcPeerOptions, type RpcId, } from "./drivers/jsonrpc.js";
|
|
14
|
-
export { AcpClient, unattendedOutcome, type AcpClientHandlers, type AcpClientOptions, } from "./drivers/acp/client.js";
|
|
14
|
+
export { AcpClient, isAuthRequiredError, unattendedOutcome, type AcpClientHandlers, type AcpClientOptions, } from "./drivers/acp/client.js";
|
|
15
15
|
export { AcpDriver } from "./drivers/acp/driver.js";
|
|
16
16
|
export { runFakeAcpAgent, type FakeAcpAgentOptions } from "./drivers/acp/testing/fake-agent.js";
|
|
17
17
|
/** 假 ACP Agent 的可执行入口(`node <path> [--minimal] [--config-options] [--config-only] [--auth-required]`);只在已编译的包里存在。 */
|
package/dist/acp.js
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* - 假 ACP Agent(进程内 `runFakeAcpAgent`,或 `fakeAcpAgentPath()` 起子进程),用于黄金记录。
|
|
8
8
|
*/
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
-
export { ACP_META_KEY, ACP_METHODS, ACP_PROTOCOL_VERSION, RPC_ERRORS, } from "./drivers/acp/types.js";
|
|
10
|
+
export { ACP_META_KEY, isTerminalAuthMethod, multiSelectOptions, singleSelectOptions, ACP_METHODS, ACP_PROTOCOL_VERSION, RPC_ERRORS, } from "./drivers/acp/types.js";
|
|
11
11
|
export { WRITE_CHUNK_BYTES, createLineReader, writeChunked, } from "./modes/rpc/jsonl.js";
|
|
12
12
|
export { JsonRpcPeer, RpcError, } from "./drivers/jsonrpc.js";
|
|
13
|
-
export { AcpClient, unattendedOutcome, } from "./drivers/acp/client.js";
|
|
13
|
+
export { AcpClient, isAuthRequiredError, unattendedOutcome, } from "./drivers/acp/client.js";
|
|
14
14
|
export { AcpDriver } from "./drivers/acp/driver.js";
|
|
15
15
|
export { runFakeAcpAgent } from "./drivers/acp/testing/fake-agent.js";
|
|
16
16
|
/** 假 ACP Agent 的可执行入口(`node <path> [--minimal] [--config-options] [--config-only] [--auth-required]`);只在已编译的包里存在。 */
|
package/dist/bundle/ama.cjs
CHANGED
|
@@ -41,7 +41,7 @@ var AMA_VERSION;
|
|
|
41
41
|
var init_version = __esm({
|
|
42
42
|
"src/version.ts"() {
|
|
43
43
|
"use strict";
|
|
44
|
-
AMA_VERSION = true ? "0.
|
|
44
|
+
AMA_VERSION = true ? "0.12.0" : readPackageVersion();
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -15493,6 +15493,9 @@ var init_jsonl = __esm({
|
|
|
15493
15493
|
});
|
|
15494
15494
|
|
|
15495
15495
|
// src/drivers/acp/types.ts
|
|
15496
|
+
function isTerminalAuthMethod(method) {
|
|
15497
|
+
return method.type === "terminal";
|
|
15498
|
+
}
|
|
15496
15499
|
var ACP_PROTOCOL_VERSION, ACP_METHODS, RPC_ERRORS, ACP_META_KEY;
|
|
15497
15500
|
var init_types7 = __esm({
|
|
15498
15501
|
"src/drivers/acp/types.ts"() {
|
|
@@ -15500,8 +15503,10 @@ var init_types7 = __esm({
|
|
|
15500
15503
|
ACP_PROTOCOL_VERSION = 1;
|
|
15501
15504
|
ACP_METHODS = {
|
|
15502
15505
|
initialize: "initialize",
|
|
15503
|
-
/**
|
|
15506
|
+
/** 客户端 → Agent:agent 型认证方法经它完成;terminal 型不经它(规范)。 */
|
|
15504
15507
|
authenticate: "authenticate",
|
|
15508
|
+
/** 客户端 → Agent:登出当前账号(Agent 声明 `agentCapabilities.auth.logout` 才可用)。 */
|
|
15509
|
+
logout: "logout",
|
|
15505
15510
|
sessionNew: "session/new",
|
|
15506
15511
|
sessionLoad: "session/load",
|
|
15507
15512
|
sessionResume: "session/resume",
|
|
@@ -15514,6 +15519,8 @@ var init_types7 = __esm({
|
|
|
15514
15519
|
sessionUpdate: "session/update",
|
|
15515
15520
|
requestPermission: "session/request_permission",
|
|
15516
15521
|
elicitationCreate: "elicitation/create",
|
|
15522
|
+
/** Agent → 客户端通知:URL 型 elicitation 已在带外完成。 */
|
|
15523
|
+
elicitationComplete: "elicitation/complete",
|
|
15517
15524
|
/** 协议级取消(双向通知,`requestId` 指对端发来的、尚未答复的请求)。 */
|
|
15518
15525
|
cancelRequest: "$/cancel_request"
|
|
15519
15526
|
};
|
|
@@ -19372,6 +19379,9 @@ var init_task_control = __esm({
|
|
|
19372
19379
|
});
|
|
19373
19380
|
|
|
19374
19381
|
// src/tools/task-ctl.ts
|
|
19382
|
+
function bindTaskCtlWaitCap(tool, capMs) {
|
|
19383
|
+
if (tool !== void 0) waitCaps.set(tool, capMs);
|
|
19384
|
+
}
|
|
19375
19385
|
function fail4(message) {
|
|
19376
19386
|
return { content: message, isError: true };
|
|
19377
19387
|
}
|
|
@@ -19398,7 +19408,7 @@ async function send(input2, ctx) {
|
|
|
19398
19408
|
return { content: result.text, isError: result.isError };
|
|
19399
19409
|
}
|
|
19400
19410
|
function createTaskCtlTool() {
|
|
19401
|
-
|
|
19411
|
+
const tool = {
|
|
19402
19412
|
name: TASK_CTL_TOOL,
|
|
19403
19413
|
label: "TaskCtl",
|
|
19404
19414
|
description: "Manage sub-agent tasks started by task: list them, wait for one, stop it, read its output, or send it a follow-up message (runs in background).",
|
|
@@ -19449,14 +19459,17 @@ ${body}` };
|
|
|
19449
19459
|
};
|
|
19450
19460
|
}
|
|
19451
19461
|
case "wait": {
|
|
19452
|
-
const
|
|
19462
|
+
const cap = Math.min(waitCaps.get(tool) ?? MAX_WAIT_MS, MAX_WAIT_MS);
|
|
19463
|
+
const wanted = Math.min(Math.max(input2.timeoutMs ?? DEFAULT_WAIT_MS, 0), MAX_WAIT_MS);
|
|
19464
|
+
const timeout = Math.min(wanted, cap);
|
|
19453
19465
|
const signal = control.detachSignal(taskId);
|
|
19454
19466
|
const result = await control.wait(taskId, timeout, { signal });
|
|
19455
19467
|
if (result === void 0 && signal.aborted) return { content: waitDetachedText(taskId) };
|
|
19456
19468
|
if (result === void 0) {
|
|
19457
19469
|
const turns = control.get(taskId)?.turns ?? 0;
|
|
19470
|
+
const capped2 = wanted > timeout ? ` Waits are capped at ${Math.round(timeout / 1e3)}s here; do not block on it: keep working, a <task-notification> follows when it finishes.` : "";
|
|
19458
19471
|
return {
|
|
19459
|
-
content: `Task ${taskId} is still running (${turns} turns so far). Wait again or stop it
|
|
19472
|
+
content: `Task ${taskId} is still running (${turns} turns so far). Wait again or stop it.${capped2}`
|
|
19460
19473
|
};
|
|
19461
19474
|
}
|
|
19462
19475
|
return {
|
|
@@ -19470,8 +19483,9 @@ ${result.text}`,
|
|
|
19470
19483
|
}
|
|
19471
19484
|
}
|
|
19472
19485
|
};
|
|
19486
|
+
return tool;
|
|
19473
19487
|
}
|
|
19474
|
-
var TASK_CTL_TOOL, DEFAULT_WAIT_MS, MAX_WAIT_MS;
|
|
19488
|
+
var TASK_CTL_TOOL, DEFAULT_WAIT_MS, MAX_WAIT_MS, COORDINATOR_WAIT_MAX_MS, waitCaps;
|
|
19475
19489
|
var init_task_ctl = __esm({
|
|
19476
19490
|
"src/tools/task-ctl.ts"() {
|
|
19477
19491
|
"use strict";
|
|
@@ -19481,6 +19495,8 @@ var init_task_ctl = __esm({
|
|
|
19481
19495
|
TASK_CTL_TOOL = "task_ctl";
|
|
19482
19496
|
DEFAULT_WAIT_MS = 3e4;
|
|
19483
19497
|
MAX_WAIT_MS = 6e5;
|
|
19498
|
+
COORDINATOR_WAIT_MAX_MS = 5e3;
|
|
19499
|
+
waitCaps = /* @__PURE__ */ new WeakMap();
|
|
19484
19500
|
}
|
|
19485
19501
|
});
|
|
19486
19502
|
|
|
@@ -20364,7 +20380,10 @@ function effectiveCodemodeMode(config, strict) {
|
|
|
20364
20380
|
return resolveCodemodeMode(config, strict).mode;
|
|
20365
20381
|
}
|
|
20366
20382
|
function codemodeCallableFilter(config) {
|
|
20367
|
-
return
|
|
20383
|
+
return isCoordinatorPreset(config) ? "active" : void 0;
|
|
20384
|
+
}
|
|
20385
|
+
function isCoordinatorPreset(config) {
|
|
20386
|
+
return canonicalPreset(config.tools?.preset) === "coordinator";
|
|
20368
20387
|
}
|
|
20369
20388
|
function applyToolAdjustments(base4, adjustments) {
|
|
20370
20389
|
if (adjustments === void 0 || adjustments.length === 0) return [...base4];
|
|
@@ -25563,6 +25582,7 @@ function cdTarget(argv, cwd) {
|
|
|
25563
25582
|
function parseSegment(segment) {
|
|
25564
25583
|
const redirects = extractRedirects(segment);
|
|
25565
25584
|
return {
|
|
25585
|
+
first: shellWords(redirects.rest.replace(/^[({\s]+/, ""))[0],
|
|
25566
25586
|
argv: commandWords(redirects.rest),
|
|
25567
25587
|
withSudo: commandWords(redirects.rest, true),
|
|
25568
25588
|
redirects
|
|
@@ -25586,7 +25606,9 @@ function ruleAsk(info2, options) {
|
|
|
25586
25606
|
}
|
|
25587
25607
|
function safeSegment(info2, extra) {
|
|
25588
25608
|
const argv = info2.withSudo;
|
|
25589
|
-
if (argv.length === 0)
|
|
25609
|
+
if (argv.length === 0) {
|
|
25610
|
+
return info2.first === void 0 ? "empty command" : `${base2(info2.first)} is not in the auto safe list`;
|
|
25611
|
+
}
|
|
25590
25612
|
for (const word of argv) {
|
|
25591
25613
|
if (word.includes("$")) return `variable expansion in ${word}`;
|
|
25592
25614
|
if (GLOB.test(word) && /(^|\/)\.[^./]/.test(word)) return `glob over dotfiles (${word})`;
|
|
@@ -25663,7 +25685,6 @@ var init_auto_safe = __esm({
|
|
|
25663
25685
|
"echo",
|
|
25664
25686
|
"printf",
|
|
25665
25687
|
"which",
|
|
25666
|
-
"printenv",
|
|
25667
25688
|
"true",
|
|
25668
25689
|
"false",
|
|
25669
25690
|
"cut",
|
|
@@ -35016,6 +35037,7 @@ var init_client = __esm({
|
|
|
35016
35037
|
onNotification: (method, params) => {
|
|
35017
35038
|
if (method === ACP_METHODS.sessionUpdate)
|
|
35018
35039
|
options.onUpdate?.(params);
|
|
35040
|
+
else if (method === ACP_METHODS.elicitationComplete) this.onElicitationComplete(params);
|
|
35019
35041
|
},
|
|
35020
35042
|
onClose: () => {
|
|
35021
35043
|
for (const set of this.pendingPermissions.values()) for (const c of set) c.abort();
|
|
@@ -35031,14 +35053,25 @@ var init_client = __esm({
|
|
|
35031
35053
|
* - `mcpServers`:开会话时可经 {@link AcpSessionOptions} 传 MCP 服务器;
|
|
35032
35054
|
* - `elicitation`:构造参数 `onElicitation` 接 `elicitation/create`;
|
|
35033
35055
|
* - `configOptions`:`setConfigOption` 与开会话答的 `configOptions`;
|
|
35034
|
-
* - `terminal`:构造参数 `onTerminal` 接 `terminal
|
|
35056
|
+
* - `terminal`:构造参数 `onTerminal` 接 `terminal/*`;
|
|
35057
|
+
* - `auth`:`authenticate` / `logout`、构造参数 `authTerminal`、`isAuthRequiredError`;
|
|
35058
|
+
* - `elicitationComplete`:构造参数 `onElicitationComplete` 接 `elicitation/complete`,表单字段含多选与 `oneOf`。
|
|
35035
35059
|
*/
|
|
35036
|
-
static features = {
|
|
35060
|
+
static features = {
|
|
35061
|
+
mcpServers: true,
|
|
35062
|
+
elicitation: true,
|
|
35063
|
+
configOptions: true,
|
|
35064
|
+
terminal: true,
|
|
35065
|
+
auth: true,
|
|
35066
|
+
elicitationComplete: true
|
|
35067
|
+
};
|
|
35037
35068
|
peer;
|
|
35038
35069
|
/** sessionId → 挂起权限请求的取消器。 */
|
|
35039
35070
|
pendingPermissions = /* @__PURE__ */ new Map();
|
|
35040
35071
|
/** sessionId(没给就是空串)→ 挂起 elicitation 的取消器。 */
|
|
35041
35072
|
pendingElicitations = /* @__PURE__ */ new Map();
|
|
35073
|
+
/** elicitationId → 挂起 elicitation 的取消器(`elicitation/complete` 用)。 */
|
|
35074
|
+
elicitationsById = /* @__PURE__ */ new Map();
|
|
35042
35075
|
initResult;
|
|
35043
35076
|
get closed() {
|
|
35044
35077
|
return this.peer.closed;
|
|
@@ -35065,7 +35098,10 @@ var init_client = __esm({
|
|
|
35065
35098
|
fs: { readTextFile: false, writeTextFile: false },
|
|
35066
35099
|
terminal: this.options.onTerminal !== void 0,
|
|
35067
35100
|
session: { configOptions: {} },
|
|
35068
|
-
...this.options.
|
|
35101
|
+
...this.options.authTerminal === true ? { auth: { terminal: true } } : {},
|
|
35102
|
+
...this.options.onElicitation !== void 0 || this.options.onElicitationComplete ? {
|
|
35103
|
+
elicitation: this.options.onElicitationComplete !== void 0 ? { form: {}, url: {} } : {}
|
|
35104
|
+
} : {}
|
|
35069
35105
|
},
|
|
35070
35106
|
...this.options.clientInfo !== void 0 ? { clientInfo: this.options.clientInfo } : {}
|
|
35071
35107
|
},
|
|
@@ -35091,9 +35127,30 @@ var init_client = __esm({
|
|
|
35091
35127
|
supportsClose() {
|
|
35092
35128
|
return this.agentCapabilities.sessionCapabilities?.close != null;
|
|
35093
35129
|
}
|
|
35130
|
+
/** Agent 声明了 `auth.logout`(存在即支持)。 */
|
|
35131
|
+
supportsLogout() {
|
|
35132
|
+
return this.agentCapabilities.auth?.logout != null;
|
|
35133
|
+
}
|
|
35094
35134
|
supportsImages() {
|
|
35095
35135
|
return this.agentCapabilities.promptCapabilities?.image === true;
|
|
35096
35136
|
}
|
|
35137
|
+
/**
|
|
35138
|
+
* 用 agent 型认证方法登录(`methodId` 取自 `authMethods`)。terminal 型方法不经 `authenticate`:已知是
|
|
35139
|
+
* terminal 型时抛 -32602,由宿主在终端里跑该方法的 `args` / `env`。失败的错误码原样抛出。
|
|
35140
|
+
*/
|
|
35141
|
+
async authenticate(methodId, signal) {
|
|
35142
|
+
const known = this.authMethods.find((method) => method.id === methodId);
|
|
35143
|
+
if (known !== void 0 && isTerminalAuthMethod(known))
|
|
35144
|
+
throw new RpcError(
|
|
35145
|
+
RPC_ERRORS.invalidParams,
|
|
35146
|
+
`auth method ${methodId} is a terminal method: run it in a terminal, not through authenticate`
|
|
35147
|
+
);
|
|
35148
|
+
return this.peer.request(ACP_METHODS.authenticate, { methodId }, signal);
|
|
35149
|
+
}
|
|
35150
|
+
/** 登出当前账号;Agent 没声明 `auth.logout`(见 `supportsLogout`)时会答 method not found。 */
|
|
35151
|
+
logout(signal) {
|
|
35152
|
+
return this.peer.request(ACP_METHODS.logout, {}, signal);
|
|
35153
|
+
}
|
|
35097
35154
|
newSession(cwd, signal, options) {
|
|
35098
35155
|
return this.peer.request(
|
|
35099
35156
|
ACP_METHODS.sessionNew,
|
|
@@ -35117,14 +35174,34 @@ var init_client = __esm({
|
|
|
35117
35174
|
signal
|
|
35118
35175
|
);
|
|
35119
35176
|
}
|
|
35120
|
-
|
|
35121
|
-
|
|
35122
|
-
|
|
35123
|
-
|
|
35124
|
-
|
|
35177
|
+
/** 一页会话;`cwd` 过滤(绝对路径),`cursor` 取自上一页的 `nextCursor`。 */
|
|
35178
|
+
listSessions(cwd, cursor, signal) {
|
|
35179
|
+
return this.peer.request(
|
|
35180
|
+
ACP_METHODS.sessionList,
|
|
35181
|
+
{
|
|
35182
|
+
...cwd !== void 0 ? { cwd } : {},
|
|
35183
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
35184
|
+
},
|
|
35185
|
+
signal
|
|
35186
|
+
);
|
|
35125
35187
|
}
|
|
35126
|
-
|
|
35127
|
-
|
|
35188
|
+
/** 跟 `nextCursor` 翻页取全(`maxPages` 防对端游标不终止,缺省 100 页)。 */
|
|
35189
|
+
async listAllSessions(cwd, signal, maxPages = 100) {
|
|
35190
|
+
const sessions = [];
|
|
35191
|
+
let cursor;
|
|
35192
|
+
for (let page2 = 0; page2 < maxPages; page2++) {
|
|
35193
|
+
const result = await this.listSessions(cwd, cursor, signal);
|
|
35194
|
+
sessions.push(...result.sessions ?? []);
|
|
35195
|
+
if (typeof result.nextCursor !== "string" || result.nextCursor === "") break;
|
|
35196
|
+
cursor = result.nextCursor;
|
|
35197
|
+
}
|
|
35198
|
+
return sessions;
|
|
35199
|
+
}
|
|
35200
|
+
/** 关闭会话:规范要求 Agent 先取消进行中的工作,所以本端先把该会话挂起的请求收掉。 */
|
|
35201
|
+
closeSession(sessionId, signal) {
|
|
35202
|
+
for (const controller of this.pendingPermissions.get(sessionId) ?? []) controller.abort();
|
|
35203
|
+
for (const controller of this.pendingElicitations.get(sessionId) ?? []) controller.abort();
|
|
35204
|
+
return this.peer.request(ACP_METHODS.sessionClose, { sessionId }, signal);
|
|
35128
35205
|
}
|
|
35129
35206
|
prompt(sessionId, prompt, signal) {
|
|
35130
35207
|
return this.peer.request(ACP_METHODS.sessionPrompt, { sessionId, prompt }, signal);
|
|
@@ -35191,6 +35268,8 @@ var init_client = __esm({
|
|
|
35191
35268
|
const set = this.pendingElicitations.get(key) ?? /* @__PURE__ */ new Set();
|
|
35192
35269
|
set.add(controller);
|
|
35193
35270
|
this.pendingElicitations.set(key, set);
|
|
35271
|
+
const id = typeof request.elicitationId === "string" ? request.elicitationId : void 0;
|
|
35272
|
+
if (id !== void 0) this.elicitationsById.set(id, controller);
|
|
35194
35273
|
const signal = AbortSignal.any([controller.signal, connection]);
|
|
35195
35274
|
try {
|
|
35196
35275
|
const answer = await Promise.race([
|
|
@@ -35205,8 +35284,17 @@ var init_client = __esm({
|
|
|
35205
35284
|
return elicitationAnswer(answer);
|
|
35206
35285
|
} finally {
|
|
35207
35286
|
set.delete(controller);
|
|
35287
|
+
if (id !== void 0 && this.elicitationsById.get(id) === controller)
|
|
35288
|
+
this.elicitationsById.delete(id);
|
|
35208
35289
|
}
|
|
35209
35290
|
}
|
|
35291
|
+
/** 通知没有答复:参数不对就忽略;还挂着的同 id elicitation 先收掉,再交给宿主。 */
|
|
35292
|
+
onElicitationComplete(params) {
|
|
35293
|
+
const id = params?.elicitationId;
|
|
35294
|
+
if (typeof id !== "string") return;
|
|
35295
|
+
this.elicitationsById.get(id)?.abort();
|
|
35296
|
+
this.options.onElicitationComplete?.(params);
|
|
35297
|
+
}
|
|
35210
35298
|
};
|
|
35211
35299
|
}
|
|
35212
35300
|
});
|
|
@@ -38784,6 +38872,7 @@ function subagentEnvironment(deps, catalog) {
|
|
|
38784
38872
|
if (retain !== void 0) env.retain = retain;
|
|
38785
38873
|
const sub = config.subagents;
|
|
38786
38874
|
env.background = resolveTaskBackground(sub?.background, deps.assembly.unattended === true);
|
|
38875
|
+
if (isCoordinatorPreset(config)) env.background = true;
|
|
38787
38876
|
const after = sub?.autoBackgroundAfterMs;
|
|
38788
38877
|
if (typeof after === "number" && after > 0) env.autoBackgroundAfterMs = after;
|
|
38789
38878
|
return env;
|
|
@@ -38836,6 +38925,8 @@ function createSubagentsFactory(deps) {
|
|
|
38836
38925
|
bindTaskAgents(task, catalog);
|
|
38837
38926
|
const env = subagentEnvironment(deps, catalog);
|
|
38838
38927
|
bindTaskBackground(task, env.background === true);
|
|
38928
|
+
if (isCoordinatorPreset(deps.assembly.config))
|
|
38929
|
+
bindTaskCtlWaitCap(deps.assembly.tools.get("task_ctl"), COORDINATOR_WAIT_MAX_MS);
|
|
38839
38930
|
return ({ core }) => core.depth > 0 ? void 0 : createSubagentExtension(core, env, wiring);
|
|
38840
38931
|
}
|
|
38841
38932
|
var warned;
|
|
@@ -38847,6 +38938,8 @@ var init_compose_agents = __esm({
|
|
|
38847
38938
|
init_discover();
|
|
38848
38939
|
init_external();
|
|
38849
38940
|
init_api_impl();
|
|
38941
|
+
init_presets2();
|
|
38942
|
+
init_task_ctl();
|
|
38850
38943
|
init_task();
|
|
38851
38944
|
init_subagent_background();
|
|
38852
38945
|
init_i18n();
|
|
@@ -65827,6 +65920,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
65827
65920
|
tui.addChild(status);
|
|
65828
65921
|
tui.addChild(area.quota);
|
|
65829
65922
|
let finished = false;
|
|
65923
|
+
const hintTimers = options.hintTimers ?? realHintTimers;
|
|
65830
65924
|
let hintTimer;
|
|
65831
65925
|
let resolveExit = () => void 0;
|
|
65832
65926
|
const render = () => tui.requestRender();
|
|
@@ -65836,14 +65930,13 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
65836
65930
|
};
|
|
65837
65931
|
const showHint = (text, ms = HINT_MS) => {
|
|
65838
65932
|
hint.setText(text === "" ? "" : theme.fg("dim", text));
|
|
65839
|
-
if (hintTimer !== void 0)
|
|
65933
|
+
if (hintTimer !== void 0) hintTimers.clear(hintTimer);
|
|
65840
65934
|
hintTimer = void 0;
|
|
65841
65935
|
if (text !== "") {
|
|
65842
|
-
hintTimer =
|
|
65936
|
+
hintTimer = hintTimers.set(() => {
|
|
65843
65937
|
hint.setText("");
|
|
65844
65938
|
render();
|
|
65845
65939
|
}, ms);
|
|
65846
|
-
hintTimer.unref?.();
|
|
65847
65940
|
}
|
|
65848
65941
|
render();
|
|
65849
65942
|
};
|
|
@@ -66096,7 +66189,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
66096
66189
|
if (finished) return;
|
|
66097
66190
|
finished = true;
|
|
66098
66191
|
logoAnimation?.finish();
|
|
66099
|
-
if (hintTimer !== void 0)
|
|
66192
|
+
if (hintTimer !== void 0) hintTimers.clear(hintTimer);
|
|
66100
66193
|
loader.stop();
|
|
66101
66194
|
area.dispose();
|
|
66102
66195
|
osc7501.exit();
|
|
@@ -66162,7 +66255,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
66162
66255
|
}
|
|
66163
66256
|
});
|
|
66164
66257
|
}
|
|
66165
|
-
var import_node_path101, HINT_MS;
|
|
66258
|
+
var import_node_path101, HINT_MS, realHintTimers;
|
|
66166
66259
|
var init_interactive_mode = __esm({
|
|
66167
66260
|
"src/modes/interactive/interactive-mode.ts"() {
|
|
66168
66261
|
"use strict";
|
|
@@ -66201,6 +66294,14 @@ var init_interactive_mode = __esm({
|
|
|
66201
66294
|
init_tool_view();
|
|
66202
66295
|
init_task_background();
|
|
66203
66296
|
HINT_MS = 2500;
|
|
66297
|
+
realHintTimers = {
|
|
66298
|
+
set: (fn, ms) => {
|
|
66299
|
+
const handle = setTimeout(fn, ms);
|
|
66300
|
+
handle.unref?.();
|
|
66301
|
+
return handle;
|
|
66302
|
+
},
|
|
66303
|
+
clear: (handle) => clearTimeout(handle)
|
|
66304
|
+
};
|
|
66204
66305
|
}
|
|
66205
66306
|
});
|
|
66206
66307
|
|
|
@@ -18,6 +18,8 @@ import { AgentCatalog } from "../agents/catalog.js";
|
|
|
18
18
|
import { agentSources, discoverAgents } from "../agents/discover.js";
|
|
19
19
|
import { NO_AGENT_PROBE_ENV, SessionExternalAgents, registerExternalAgents, } from "../agents/external.js";
|
|
20
20
|
import { hostRunnersOf } from "../host/api-impl.js";
|
|
21
|
+
import { isCoordinatorPreset } from "../tools/presets.js";
|
|
22
|
+
import { COORDINATOR_WAIT_MAX_MS, bindTaskCtlWaitCap } from "../tools/task-ctl.js";
|
|
21
23
|
import { bindTaskAgents, bindTaskBackground } from "../tools/task.js";
|
|
22
24
|
import { resolveTaskBackground } from "../agent/subagent-background.js";
|
|
23
25
|
import { msg } from "../i18n/index.js";
|
|
@@ -62,6 +64,9 @@ export function subagentEnvironment(deps, catalog) {
|
|
|
62
64
|
// [W7-B1] 缺省后台与自动转后台(配置键 W7-B2 登记于 config/types-w5.ts)
|
|
63
65
|
const sub = config.subagents;
|
|
64
66
|
env.background = resolveTaskBackground(sub?.background, deps.assembly.unattended === true);
|
|
67
|
+
// [#242] 协调者不阻塞:缺省后台,不受 subagents.background / -p 影响(调用参数与类型定义仍优先)
|
|
68
|
+
if (isCoordinatorPreset(config))
|
|
69
|
+
env.background = true;
|
|
65
70
|
const after = sub?.autoBackgroundAfterMs;
|
|
66
71
|
if (typeof after === "number" && after > 0)
|
|
67
72
|
env.autoBackgroundAfterMs = after;
|
|
@@ -120,5 +125,8 @@ export function createSubagentsFactory(deps) {
|
|
|
120
125
|
bindTaskAgents(task, catalog);
|
|
121
126
|
const env = subagentEnvironment(deps, catalog);
|
|
122
127
|
bindTaskBackground(task, env.background === true);
|
|
128
|
+
// [#242] 协调者预设:task_ctl wait 超时封顶(task 与 task_ctl 同进退)
|
|
129
|
+
if (isCoordinatorPreset(deps.assembly.config))
|
|
130
|
+
bindTaskCtlWaitCap(deps.assembly.tools.get("task_ctl"), COORDINATOR_WAIT_MAX_MS);
|
|
123
131
|
return ({ core }) => (core.depth > 0 ? undefined : createSubagentExtension(core, env, wiring));
|
|
124
132
|
}
|
|
@@ -14,13 +14,29 @@
|
|
|
14
14
|
* - `elicitation/create` 交给 `onElicitation`;给了它 `initialize` 才声明 `clientCapabilities.elicitation`,
|
|
15
15
|
* 没给时线路与旧版相同(不声明,Agent 发来的请求回 method not found)。`cancel(sessionId)`、连接关闭时
|
|
16
16
|
* 挂起的 elicitation 一律回 `{ action: "cancel" }`;ama 从不替人填表。
|
|
17
|
+
* - `elicitation/complete`(Agent → 客户端通知,URL 型 elicitation 在带外完成)交给 `onElicitationComplete`;给了它
|
|
18
|
+
* `initialize` 声明 `elicitation: { form: {}, url: {} }`(只给 `onElicitation` 时仍是 `{}`,与旧版相同)。同一
|
|
19
|
+
* `elicitationId` 若还挂着(处理器没答),它的 `signal` 随之 abort、答 `{ action: "cancel" }`,宿主据此收掉卡片。
|
|
20
|
+
* 表单字段含字符串多选(`type: "array"`)与带标题的 `oneOf` / `anyOf`,答复 `content` 里多选是字符串数组;
|
|
21
|
+
* {@link multiSelectOptions} / {@link singleSelectOptions} 把两种写法收成统一的 `{ const, title }` 列表。
|
|
22
|
+
* - 会话管理:`listSessions(cwd?, cursor?, signal?)` 发 `session/list`(要 Agent 声明 `sessionCapabilities.list`,见
|
|
23
|
+
* `supportsList`),`listAllSessions` 跟 `nextCursor` 翻页取全;`closeSession(sessionId, signal?)` 发 `session/close`
|
|
24
|
+
* (`supportsClose`),按规范等同先取消:该会话挂起的权限请求答 `cancelled`、elicitation 答 `cancel`,再发请求。
|
|
25
|
+
* 没声明能力的 Agent 会答 -32601,开会话遇 -32000 同样原样抛出({@link isAuthRequiredError})。
|
|
17
26
|
* - `setConfigOption(sessionId, configId, value)` 发 `session/set_config_option`;开会话答的 `configOptions`
|
|
18
27
|
* 原样交回。`initialize` 声明 `clientCapabilities.session.configOptions: {}`(只认 select,不声明 boolean);
|
|
19
|
-
*
|
|
28
|
+
* `auth.terminal` 缺省不声明(ama 作客户端没有可借给 Agent 的交互终端),见下 `authTerminal`。[ACP-D]
|
|
29
|
+
* - 认证:`authenticate(methodId)` 发 `authenticate`(agent 型方法)、`logout()` 发 `logout`(Agent 声明
|
|
30
|
+
* `auth.logout` 才可用,见 `supportsLogout`);terminal 型方法规范禁止经 `authenticate`,已知是 terminal 型时本地
|
|
31
|
+
* 拒绝(-32602),宿主自己在终端里跑 `args` / `env`。构造参数 `authTerminal: true` 才在 `initialize` 声明
|
|
32
|
+
* `clientCapabilities.auth.terminal`(宿主有交互终端可借;Agent 据此才给 terminal 型方法),缺省线路与旧版相同。
|
|
33
|
+
* 开会话遇 -32000(auth_required)用 {@link isAuthRequiredError} 判断,`authMethods` 保留 id / name / description / type
|
|
34
|
+
* / args / env 原样。
|
|
20
35
|
* - 线路两侧开 `$/cancel_request`:本端请求的 `signal` abort 时通知 Agent;Agent 撤回挂起的
|
|
21
36
|
* `session/request_permission` / `elicitation/create` 时处理器的 `signal` abort,回 cancelled / cancel。[ACP-D]
|
|
22
37
|
*/
|
|
23
|
-
import {
|
|
38
|
+
import { RpcError } from "../jsonrpc.js";
|
|
39
|
+
import { type AcpAgentCapabilities, type AcpAuthMethod, type AcpAuthenticateResult, type AcpLogoutResult, type AcpCompleteElicitationParams, type AcpContentBlock, type AcpElicitationParams, type AcpElicitationResult, type AcpImplementationInfo, type AcpInitializeResult, type AcpListSessionsResult, type AcpCloseSessionResult, type AcpSessionInfo, type AcpLoadSessionResult, type AcpNewSessionResult, type AcpPromptResult, type AcpRequestPermissionParams, type AcpRequestPermissionResult, type AcpSessionNotification, type AcpSessionOptions, type AcpSetConfigOptionResult } from "./types.js";
|
|
24
40
|
export interface AcpClientHandlers {
|
|
25
41
|
onUpdate?(notification: AcpSessionNotification): void;
|
|
26
42
|
/** `signal`:该会话被 cancel、连接关闭时 abort(此时应尽快回 cancelled)。 */
|
|
@@ -30,6 +46,11 @@ export interface AcpClientHandlers {
|
|
|
30
46
|
* `signal`:该会话被 cancel、连接关闭时 abort(此时回 `{ action: "cancel" }`,不必再答)。
|
|
31
47
|
*/
|
|
32
48
|
onElicitation?(params: AcpElicitationParams, signal: AbortSignal): Promise<AcpElicitationResult>;
|
|
49
|
+
/**
|
|
50
|
+
* `elicitation/complete`:URL 型 elicitation 已在带外完成(`params.elicitationId` 对应此前
|
|
51
|
+
* `elicitation/create` 的同名字段),宿主据此收掉对应卡片。给了它,`initialize` 才声明 `elicitation.url`。
|
|
52
|
+
*/
|
|
53
|
+
onElicitationComplete?(params: AcpCompleteElicitationParams): void;
|
|
33
54
|
/**
|
|
34
55
|
* `terminal/*`(create / output / wait_for_exit / kill / release):宿主替 Agent 起终端。给了它才声明
|
|
35
56
|
* `clientCapabilities.terminal: true` 并把这些请求交给它;`method` 是完整方法名,`params` 原样交回,返回值即
|
|
@@ -43,7 +64,14 @@ export interface AcpClientOptions extends AcpClientHandlers {
|
|
|
43
64
|
input: NodeJS.ReadableStream;
|
|
44
65
|
output: NodeJS.WritableStream;
|
|
45
66
|
clientInfo?: AcpImplementationInfo;
|
|
67
|
+
/**
|
|
68
|
+
* 宿主能在交互终端里复现 Agent 的启动命令:声明 `clientCapabilities.auth.terminal`,Agent 才会在
|
|
69
|
+
* `authMethods` 里给 terminal 型方法。缺省不声明。
|
|
70
|
+
*/
|
|
71
|
+
authTerminal?: boolean;
|
|
46
72
|
}
|
|
73
|
+
/** 错误是 ACP 的 auth_required(-32000):开会话或发提示前需要先认证 / 登录。 */
|
|
74
|
+
export declare function isAuthRequiredError(error: unknown): error is RpcError;
|
|
47
75
|
/** 无人值守的回答:首个 reject_once,没有就 cancelled。 */
|
|
48
76
|
export declare function unattendedOutcome(params: AcpRequestPermissionParams): AcpRequestPermissionResult;
|
|
49
77
|
export declare class AcpClient {
|
|
@@ -53,19 +81,25 @@ export declare class AcpClient {
|
|
|
53
81
|
* - `mcpServers`:开会话时可经 {@link AcpSessionOptions} 传 MCP 服务器;
|
|
54
82
|
* - `elicitation`:构造参数 `onElicitation` 接 `elicitation/create`;
|
|
55
83
|
* - `configOptions`:`setConfigOption` 与开会话答的 `configOptions`;
|
|
56
|
-
* - `terminal`:构造参数 `onTerminal` 接 `terminal
|
|
84
|
+
* - `terminal`:构造参数 `onTerminal` 接 `terminal/*`;
|
|
85
|
+
* - `auth`:`authenticate` / `logout`、构造参数 `authTerminal`、`isAuthRequiredError`;
|
|
86
|
+
* - `elicitationComplete`:构造参数 `onElicitationComplete` 接 `elicitation/complete`,表单字段含多选与 `oneOf`。
|
|
57
87
|
*/
|
|
58
88
|
static readonly features: {
|
|
59
89
|
readonly mcpServers: true;
|
|
60
90
|
readonly elicitation: true;
|
|
61
91
|
readonly configOptions: true;
|
|
62
92
|
readonly terminal: true;
|
|
93
|
+
readonly auth: true;
|
|
94
|
+
readonly elicitationComplete: true;
|
|
63
95
|
};
|
|
64
96
|
private readonly peer;
|
|
65
97
|
/** sessionId → 挂起权限请求的取消器。 */
|
|
66
98
|
private readonly pendingPermissions;
|
|
67
99
|
/** sessionId(没给就是空串)→ 挂起 elicitation 的取消器。 */
|
|
68
100
|
private readonly pendingElicitations;
|
|
101
|
+
/** elicitationId → 挂起 elicitation 的取消器(`elicitation/complete` 用)。 */
|
|
102
|
+
private readonly elicitationsById;
|
|
69
103
|
private initResult;
|
|
70
104
|
constructor(options: AcpClientOptions);
|
|
71
105
|
get closed(): Promise<void>;
|
|
@@ -79,14 +113,27 @@ export declare class AcpClient {
|
|
|
79
113
|
supportsLoad(): boolean;
|
|
80
114
|
supportsList(): boolean;
|
|
81
115
|
supportsClose(): boolean;
|
|
116
|
+
/** Agent 声明了 `auth.logout`(存在即支持)。 */
|
|
117
|
+
supportsLogout(): boolean;
|
|
82
118
|
supportsImages(): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* 用 agent 型认证方法登录(`methodId` 取自 `authMethods`)。terminal 型方法不经 `authenticate`:已知是
|
|
121
|
+
* terminal 型时抛 -32602,由宿主在终端里跑该方法的 `args` / `env`。失败的错误码原样抛出。
|
|
122
|
+
*/
|
|
123
|
+
authenticate(methodId: string, signal?: AbortSignal): Promise<AcpAuthenticateResult>;
|
|
124
|
+
/** 登出当前账号;Agent 没声明 `auth.logout`(见 `supportsLogout`)时会答 method not found。 */
|
|
125
|
+
logout(signal?: AbortSignal): Promise<AcpLogoutResult>;
|
|
83
126
|
newSession(cwd: string, signal?: AbortSignal, options?: AcpSessionOptions): Promise<AcpNewSessionResult>;
|
|
84
127
|
/** 不回放历史(优先,R13:v2 计划取消 load)。 */
|
|
85
128
|
resumeSession(sessionId: string, cwd: string, signal?: AbortSignal, options?: AcpSessionOptions): Promise<AcpLoadSessionResult>;
|
|
86
129
|
/** 回放历史(以 session/update 通知)。 */
|
|
87
130
|
loadSession(sessionId: string, cwd: string, signal?: AbortSignal, options?: AcpSessionOptions): Promise<AcpLoadSessionResult>;
|
|
88
|
-
|
|
89
|
-
|
|
131
|
+
/** 一页会话;`cwd` 过滤(绝对路径),`cursor` 取自上一页的 `nextCursor`。 */
|
|
132
|
+
listSessions(cwd?: string, cursor?: string, signal?: AbortSignal): Promise<AcpListSessionsResult>;
|
|
133
|
+
/** 跟 `nextCursor` 翻页取全(`maxPages` 防对端游标不终止,缺省 100 页)。 */
|
|
134
|
+
listAllSessions(cwd?: string, signal?: AbortSignal, maxPages?: number): Promise<AcpSessionInfo[]>;
|
|
135
|
+
/** 关闭会话:规范要求 Agent 先取消进行中的工作,所以本端先把该会话挂起的请求收掉。 */
|
|
136
|
+
closeSession(sessionId: string, signal?: AbortSignal): Promise<AcpCloseSessionResult>;
|
|
90
137
|
prompt(sessionId: string, prompt: AcpContentBlock[], signal?: AbortSignal): Promise<AcpPromptResult>;
|
|
91
138
|
setMode(sessionId: string, modeId: string): Promise<unknown>;
|
|
92
139
|
/** 改一个会话配置项(如模型);答复是全部配置项的新状态。 */
|
|
@@ -96,4 +143,6 @@ export declare class AcpClient {
|
|
|
96
143
|
close(): void;
|
|
97
144
|
private onRequest;
|
|
98
145
|
private onElicitation;
|
|
146
|
+
/** 通知没有答复:参数不对就忽略;还挂着的同 id elicitation 先收掉,再交给宿主。 */
|
|
147
|
+
private onElicitationComplete;
|
|
99
148
|
}
|