@armadra/agent 0.6.6 → 0.6.7

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 CHANGED
@@ -5,6 +5,13 @@ 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.6.7 (2026-10-03)
9
+
10
+ - **A host runner with id `ama` is used**: when the host registers a runner for `ama` via `HostApi.runners.provide`
11
+ (for example another ama node on an Armadra canvas), `task(agent="ama")` now goes to it instead of being unknown; without
12
+ one nothing changes, and the built-in types (`general` / `explore` / `plan`) are always ama sub-sessions. Docs:
13
+ docs/agents.md.
14
+
8
15
  ## 0.6.6 (2026-10-03)
9
16
 
10
17
  - **Local search hints**: when both `grep` and `glob` are directly available, the system prompt's rules gain one line
@@ -4,6 +4,12 @@
4
4
 
5
5
  > 从 0.6.0 起 [CHANGELOG.md](CHANGELOG.md) 为英文,本文件保留中文记录(0.1–0.5.1 的完整历史在此)。新条目两份都要加。
6
6
 
7
+ ## 0.6.7(2026-10-03)
8
+
9
+ - **宿主注入的 `ama` runner 生效**:宿主经 `HostApi.runners.provide` 注入 id 为 `ama` 的 runner(如 Armadra 画布上另一个
10
+ ama 节点)时,`task(agent="ama")` 交给它;没注入时行为不变,内置类型(`general` / `explore` / `plan`)始终是 ama 子会话。
11
+ 文档:docs/agents.md。
12
+
7
13
  ## 0.6.6(2026-10-03)
8
14
 
9
15
  - **本地检索提示**:`grep` 与 `glob` 都直接可用时,系统提示的规则节多一句「先 grep / glob 定位再 read,不要猜路径」;`grep` /
@@ -2,7 +2,8 @@
2
2
  * 外部 Agent 接入 `task(agent=…)`(docs/wave5-plan.md §5.3–§5.5、§7.3、§7.6,D13、D15、D17)。[W5-EG]
3
3
  *
4
4
  * - 名字:`claude` / `codex` / `acp:<program>` / 驱动表里的其它 id(`gemini` …,`ama` 除外——那是子会话
5
- * 类型的 runner 名;ama 自己经 ACP 用 `acp:ama`)/ 宿主注入的 runner id。启动时 PATH 上找得到的
5
+ * 类型的 runner 名;ama 自己经 ACP 用 `acp:ama`)/ 宿主注入的 runner id(宿主注入的 `ama` 在类型里的 runner
6
+ * 名是 `host:ama`,交给宿主;没注入时 `ama` 照旧不是外部 Agent)。启动时 PATH 上找得到的
6
7
  * claude / codex 与已注入的宿主 runner 登记进类型目录(进 task 工具描述);其余按需解析(不进描述,
7
8
  * 描述在会话内字节不变)。
8
9
  * - 每个主会话一个 {@link ExternalAgents}:审批接 `requestApproval`(只走 broker 链,不经 gateToolCall
@@ -34,6 +35,11 @@ export declare const externalTesting: {
34
35
  export declare function isExternalSpec(name: string): boolean;
35
36
  /** 外部 CLI 的类型(`task(agent="claude")`)。 */
36
37
  export declare function externalDefinition(spec: string): AgentDefinition;
38
+ /**
39
+ * 宿主注入的 id 恰为 `ama` 的 runner(画布上另一个 ama 节点)在类型里的 runner 名。裸 `ama` 是子会话
40
+ * 类型的 runner 名(注册表按它起子会话),不能共用;名字仍是 `ama`,`task(agent="ama")` 照常解析。
41
+ */
42
+ export declare const HOST_AMA_RUNNER = "host:ama";
37
43
  export declare function hostDefinition(runner: HostRunner): AgentDefinition;
38
44
  /** 只查 PATH(不起进程):候选链里任一程序在 PATH 上。 */
39
45
  export declare function externalOnPath(spec: string, env: NodeJS.ProcessEnv): boolean;
@@ -2,7 +2,8 @@
2
2
  * 外部 Agent 接入 `task(agent=…)`(docs/wave5-plan.md §5.3–§5.5、§7.3、§7.6,D13、D15、D17)。[W5-EG]
3
3
  *
4
4
  * - 名字:`claude` / `codex` / `acp:<program>` / 驱动表里的其它 id(`gemini` …,`ama` 除外——那是子会话
5
- * 类型的 runner 名;ama 自己经 ACP 用 `acp:ama`)/ 宿主注入的 runner id。启动时 PATH 上找得到的
5
+ * 类型的 runner 名;ama 自己经 ACP 用 `acp:ama`)/ 宿主注入的 runner id(宿主注入的 `ama` 在类型里的 runner
6
+ * 名是 `host:ama`,交给宿主;没注入时 `ama` 照旧不是外部 Agent)。启动时 PATH 上找得到的
6
7
  * claude / codex 与已注入的宿主 runner 登记进类型目录(进 task 工具描述);其余按需解析(不进描述,
7
8
  * 描述在会话内字节不变)。
8
9
  * - 每个主会话一个 {@link ExternalAgents}:审批接 `requestApproval`(只走 broker 链,不经 gateToolCall
@@ -58,8 +59,17 @@ function definition(name, runner, description, source) {
58
59
  export function externalDefinition(spec) {
59
60
  return definition(spec, spec, `External ${labelOf(spec)} CLI (its own login, model and permission policy; full instructions in prompt).`, "builtin");
60
61
  }
62
+ /**
63
+ * 宿主注入的 id 恰为 `ama` 的 runner(画布上另一个 ama 节点)在类型里的 runner 名。裸 `ama` 是子会话
64
+ * 类型的 runner 名(注册表按它起子会话),不能共用;名字仍是 `ama`,`task(agent="ama")` 照常解析。
65
+ */
66
+ export const HOST_AMA_RUNNER = "host:ama";
67
+ /** 宿主 runner id → 类型里的 runner 名。 */
68
+ function hostRunnerName(id) {
69
+ return id === "ama" ? HOST_AMA_RUNNER : id;
70
+ }
61
71
  export function hostDefinition(runner) {
62
- return definition(runner.id, runner.id, runner.description, "host");
72
+ return definition(runner.id, hostRunnerName(runner.id), runner.description, "host");
63
73
  }
64
74
  /** 只查 PATH(不起进程):候选链里任一程序在 PATH 上。 */
65
75
  export function externalOnPath(spec, env) {
@@ -207,8 +217,16 @@ export class SessionExternalAgents {
207
217
  runner(agent) {
208
218
  if (agent.runner === "ama")
209
219
  return undefined;
210
- const spec = agent.runner;
220
+ // 宿主注入的 `ama` 走宿主;宿主已注销时报不可用,不退回自起(驱动表里也有一个 ama)。
221
+ // 宿主 id 不在 AgentRunnerSpec 的字面量里(见 definition),按字符串比
222
+ const runnerName = agent.runner;
223
+ const hostAma = runnerName === HOST_AMA_RUNNER;
224
+ const spec = hostAma ? "ama" : agent.runner;
211
225
  const host = this.wiring.hostRunners?.get(spec);
226
+ if (hostAma && host === undefined) {
227
+ const error = new AmaError("agent_host_only", `"ama" was provided by the host and is no longer available`);
228
+ return { id: spec, start: () => Promise.reject(error) };
229
+ }
212
230
  let inner;
213
231
  try {
214
232
  inner = this.agents.resolve(spec);
@@ -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.6.6" : readPackageVersion();
44
+ AMA_VERSION = true ? "0.6.7" : readPackageVersion();
45
45
  }
46
46
  });
47
47
 
@@ -33541,8 +33541,11 @@ function externalDefinition(spec2) {
33541
33541
  "builtin"
33542
33542
  );
33543
33543
  }
33544
+ function hostRunnerName(id) {
33545
+ return id === "ama" ? HOST_AMA_RUNNER : id;
33546
+ }
33544
33547
  function hostDefinition(runner) {
33545
- return definition(runner.id, runner.id, runner.description, "host");
33548
+ return definition(runner.id, hostRunnerName(runner.id), runner.description, "host");
33546
33549
  }
33547
33550
  function externalOnPath(spec2, env) {
33548
33551
  const found = candidatesFor(spec2);
@@ -33594,7 +33597,7 @@ function mergeAgentInfos(base4, external) {
33594
33597
  }
33595
33598
  return out;
33596
33599
  }
33597
- var import_node_crypto14, LISTED_EXTERNAL_AGENTS, NO_AGENT_PROBE_ENV, externalTesting, ExternalTaskHandle, infoCache, SessionExternalAgents;
33600
+ var import_node_crypto14, LISTED_EXTERNAL_AGENTS, NO_AGENT_PROBE_ENV, externalTesting, HOST_AMA_RUNNER, ExternalTaskHandle, infoCache, SessionExternalAgents;
33598
33601
  var init_external = __esm({
33599
33602
  "src/agents/external.ts"() {
33600
33603
  "use strict";
@@ -33611,6 +33614,7 @@ var init_external = __esm({
33611
33614
  LISTED_EXTERNAL_AGENTS = ["claude", "codex"];
33612
33615
  NO_AGENT_PROBE_ENV = "AMA_NO_AGENT_PROBE";
33613
33616
  externalTesting = {};
33617
+ HOST_AMA_RUNNER = "host:ama";
33614
33618
  ExternalTaskHandle = class {
33615
33619
  constructor(inner, reopen) {
33616
33620
  this.inner = inner;
@@ -33689,8 +33693,17 @@ var init_external = __esm({
33689
33693
  /** 注册表的 `runners(agent)`:ama 子会话类型返回 undefined。 */
33690
33694
  runner(agent) {
33691
33695
  if (agent.runner === "ama") return void 0;
33692
- const spec2 = agent.runner;
33696
+ const runnerName = agent.runner;
33697
+ const hostAma = runnerName === HOST_AMA_RUNNER;
33698
+ const spec2 = hostAma ? "ama" : agent.runner;
33693
33699
  const host = this.wiring.hostRunners?.get(spec2);
33700
+ if (hostAma && host === void 0) {
33701
+ const error2 = new AmaError(
33702
+ "agent_host_only",
33703
+ `"ama" was provided by the host and is no longer available`
33704
+ );
33705
+ return { id: spec2, start: () => Promise.reject(error2) };
33706
+ }
33694
33707
  let inner;
33695
33708
  try {
33696
33709
  inner = this.agents.resolve(spec2);
package/docs/agents.md CHANGED
@@ -259,7 +259,7 @@ ama 能以各 CLI 自己的账户、模型与权限策略驱动外部编码 Agen
259
259
 
260
260
  ### 嵌入宿主
261
261
 
262
- 有宿主(`--host` 或 profile 的 `host`,如嵌入 Armadra)时 ama **不自己启动外部 CLI**:内置外部 Agent 一律不可用,不写进 task 描述,`task(agent="claude")` 以「由宿主提供」失败;只有宿主经 `HostApi.runners.provide(runner)` 注入的 runner 可用,它以同一个 `task(agent=<id>)` 入口出现,同名时替换内置的。`create()` 时已注入的 runner 写进 task 描述(`- <id>: <description>`),之后注入的也能用但不进描述。runner 的 `start` 收到 `prompt`、`cwd`、`mode`(父会话当前模式)、`taskId`、`signal`、`onEvent`;不经首次确认。
262
+ 有宿主(`--host` 或 profile 的 `host`,如嵌入 Armadra)时 ama **不自己启动外部 CLI**:内置外部 Agent 一律不可用,不写进 task 描述,`task(agent="claude")` 以「由宿主提供」失败;只有宿主经 `HostApi.runners.provide(runner)` 注入的 runner 可用,它以同一个 `task(agent=<id>)` 入口出现,同名时替换内置的。`create()` 时已注入的 runner 写进 task 描述(`- <id>: <description>`),之后注入的也能用但不进描述。runner 的 `start` 收到 `prompt`、`cwd`、`mode`(父会话当前模式)、`taskId`、`signal`、`onEvent`;不经首次确认。宿主注入的 runner id 也可以是 `ama`(例如画布上另一个 ama 节点):`task(agent="ama")` 交给宿主,不起子会话;没注入时 `ama` 照旧不是可用类型,内置类型(`general` / `explore` / `plan`)始终是 ama 子会话。
263
263
 
264
264
  **在 Armadra 画布终端里直接运行 ama(没有 `--host`)**:此时 ama 按独立模式工作,自己启动的外部 Agent 是这个终端节点里的子进程,不会出现在画布上,也不经连线授权;需要让多个 Agent 在画布上协同,就在画布上连线 Agent 节点,或以宿主模式嵌入 ama。终端带着该节点的身份变量(`ARMADRA_NODE_ID`、`ARMADRA_SESSION_ID`、Hook 端点、`ARMADRA_CANVAS_CONTROL` 等),ama 起子进程时一律剥离(askpass 除外),否则 Armadra 装在 Claude / Codex 上的 Hook 会把子 Agent 的事件记到这个节点名下。
265
265
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@armadra/agent",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "A coding and coordination agent that runs standalone or embedded in Armadra",
5
5
  "type": "module",
6
6
  "keywords": [