@armadra/agent 0.6.1 → 0.6.3
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 +80 -0
- package/CHANGELOG.zh-CN.md +56 -0
- package/README.md +168 -575
- package/README.zh-CN.md +165 -596
- package/dist/agent/session-settings.d.ts +4 -1
- package/dist/agent/session-settings.js +7 -2
- package/dist/agent/session.d.ts +6 -0
- package/dist/agent/session.js +8 -0
- package/dist/agent/subagent-background.d.ts +75 -0
- package/dist/agent/subagent-background.js +209 -0
- package/dist/agent/subagent-registry.d.ts +24 -5
- package/dist/agent/subagent-registry.js +64 -92
- package/dist/agent/types-w5.d.ts +11 -1
- package/dist/agent/types.d.ts +5 -0
- package/dist/agents/builtin.js +0 -1
- package/dist/agents/external.js +0 -1
- package/dist/agents/parse.js +4 -3
- package/dist/agents/result.d.ts +7 -1
- package/dist/agents/result.js +20 -1
- package/dist/agents/task-control.d.ts +13 -2
- package/dist/agents/task-record.d.ts +13 -1
- package/dist/agents/task-record.js +32 -0
- package/dist/agents/types.d.ts +5 -1
- package/dist/ai/apis/chatgpt-backend.d.ts +7 -2
- package/dist/ai/apis/chatgpt-backend.js +12 -4
- package/dist/ai/providers/discovered-cache.d.ts +29 -12
- package/dist/ai/providers/discovered-cache.js +72 -12
- package/dist/ai/providers/registry.js +7 -6
- package/dist/ai/types.d.ts +5 -0
- package/dist/auth/chatgpt/backend-client.d.ts +14 -4
- package/dist/auth/chatgpt/backend-client.js +41 -8
- package/dist/auth/chatgpt/cli.d.ts +2 -1
- package/dist/auth/chatgpt/cli.js +14 -7
- package/dist/auth/chatgpt/follow.d.ts +16 -0
- package/dist/auth/chatgpt/follow.js +51 -0
- package/dist/auth/chatgpt/presets.d.ts +8 -0
- package/dist/auth/chatgpt/presets.js +12 -0
- package/dist/auth/testing/fake-oauth.d.ts +4 -1
- package/dist/auth/testing/fake-oauth.js +24 -1
- package/dist/bundle/ama.cjs +2016 -664
- package/dist/cli/compose-agents.d.ts +2 -1
- package/dist/cli/compose-agents.js +11 -2
- package/dist/cli/compose-providers.d.ts +2 -1
- package/dist/cli/compose-providers.js +6 -3
- package/dist/cli/startup-steps.js +4 -1
- package/dist/cli/subcommands/models-discover.d.ts +5 -2
- package/dist/cli/subcommands/models-discover.js +52 -10
- package/dist/config/json-schema.js +10 -2
- package/dist/config/key-docs.js +9 -3
- package/dist/config/merge.d.ts +1 -1
- package/dist/config/merge.js +20 -3
- package/dist/config/schema-w5.js +4 -2
- package/dist/config/schema-w6.d.ts +1 -1
- package/dist/config/schema-w6.js +2 -1
- package/dist/config/schema.js +2 -0
- package/dist/config/settings-registry.js +4 -0
- package/dist/config/types-w5.d.ts +10 -0
- package/dist/config/types-w5.js +2 -0
- package/dist/config/types-w6.d.ts +5 -0
- package/dist/config/types.d.ts +3 -1
- package/dist/git/info.d.ts +19 -0
- package/dist/git/info.js +64 -8
- package/dist/i18n/catalog.d.ts +52 -8
- package/dist/i18n/messages/agents.d.ts +56 -0
- package/dist/i18n/messages/agents.js +58 -2
- package/dist/i18n/messages/auth.d.ts +12 -0
- package/dist/i18n/messages/auth.js +20 -0
- package/dist/i18n/messages/config-keys.d.ts +8 -0
- package/dist/i18n/messages/config-keys.js +18 -10
- package/dist/i18n/messages/config.d.ts +8 -0
- package/dist/i18n/messages/interactive-startup.d.ts +0 -16
- package/dist/i18n/messages/interactive-startup.js +0 -16
- package/dist/i18n/messages/interactive.d.ts +23 -16
- package/dist/i18n/messages/interactive.js +25 -0
- package/dist/i18n/messages/print.d.ts +4 -0
- package/dist/i18n/messages/print.js +4 -0
- package/dist/i18n/messages/report.js +4 -4
- package/dist/i18n/messages/settings.d.ts +6 -0
- package/dist/i18n/messages/settings.js +6 -0
- package/dist/i18n/messages/subcommands-config.d.ts +4 -0
- package/dist/i18n/messages/subcommands-config.js +4 -0
- package/dist/i18n/messages/subcommands.d.ts +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/modes/commands-core.js +8 -4
- package/dist/modes/interactive/agent-bar.d.ts +3 -1
- package/dist/modes/interactive/agent-bar.js +12 -5
- package/dist/modes/interactive/agent-ui.d.ts +21 -3
- package/dist/modes/interactive/agent-ui.js +81 -12
- package/dist/modes/interactive/agent-view.d.ts +4 -0
- package/dist/modes/interactive/agent-view.js +14 -1
- package/dist/modes/interactive/approval-dock.d.ts +51 -0
- package/dist/modes/interactive/approval-dock.js +112 -0
- package/dist/modes/interactive/approval-ui.d.ts +43 -0
- package/dist/modes/interactive/approval-ui.js +64 -0
- package/dist/modes/interactive/commands.js +4 -1
- package/dist/modes/interactive/event-notices.d.ts +6 -1
- package/dist/modes/interactive/event-notices.js +7 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -2
- package/dist/modes/interactive/interactive-mode.js +33 -38
- package/dist/modes/interactive/key-dispatch.d.ts +21 -4
- package/dist/modes/interactive/key-dispatch.js +60 -8
- package/dist/modes/interactive/line/line-mode.js +5 -0
- package/dist/modes/interactive/run-indicator.d.ts +15 -0
- package/dist/modes/interactive/run-indicator.js +37 -5
- package/dist/modes/interactive/session-events.js +5 -1
- package/dist/modes/interactive/startup-header.d.ts +29 -14
- package/dist/modes/interactive/startup-header.js +93 -59
- package/dist/modes/interactive/startup-logo.d.ts +83 -0
- package/dist/modes/interactive/startup-logo.js +183 -0
- package/dist/modes/interactive/status-area.d.ts +18 -0
- package/dist/modes/interactive/status-area.js +67 -1
- package/dist/modes/interactive/status-bar.d.ts +9 -1
- package/dist/modes/interactive/status-bar.js +43 -11
- package/dist/modes/interactive/status-line.d.ts +2 -0
- package/dist/modes/interactive/status-line.js +11 -6
- package/dist/modes/interactive/status-quota.d.ts +44 -0
- package/dist/modes/interactive/status-quota.js +135 -0
- package/dist/modes/interactive/subagent-view.d.ts +1 -0
- package/dist/modes/interactive/subagent-view.js +8 -0
- package/dist/modes/interactive/task-background.d.ts +31 -0
- package/dist/modes/interactive/task-background.js +68 -0
- package/dist/modes/interactive/tool-view.d.ts +7 -1
- package/dist/modes/interactive/tool-view.js +24 -1
- package/dist/modes/print/print-mode.d.ts +11 -0
- package/dist/modes/print/print-mode.js +36 -1
- package/dist/modes/rpc/commands.d.ts +2 -1
- package/dist/modes/rpc/commands.js +9 -1
- package/dist/rpc.d.ts +13 -0
- package/dist/rpc.js +3 -0
- package/dist/tools/task-ctl.d.ts +2 -0
- package/dist/tools/task-ctl.js +7 -2
- package/dist/tools/task.d.ts +11 -0
- package/dist/tools/task.js +20 -2
- package/dist/tui/components/editor.d.ts +2 -0
- package/dist/tui/components/editor.js +4 -0
- package/dist/tui/components/loader.d.ts +5 -1
- package/dist/tui/components/loader.js +18 -5
- package/dist/tui/keybindings.d.ts +8 -3
- package/dist/tui/keybindings.js +8 -3
- package/docs/agents.md +52 -28
- package/docs/en/host-api.md +5 -1
- package/docs/en/providers.md +8 -4
- package/docs/en/rpc.md +19 -7
- package/docs/en/sessions.md +3 -1
- package/docs/en/tui.md +84 -66
- package/docs/host-api.md +5 -1
- package/docs/providers.md +29 -12
- package/docs/rpc.md +19 -7
- package/docs/sessions.md +2 -1
- package/docs/tui-design.md +42 -29
- package/docs/tui.md +67 -49
- package/package.json +1 -1
package/docs/en/providers.md
CHANGED
|
@@ -170,9 +170,11 @@ ama auth logout chatgpt # siwc revokes the refresh token first, t
|
|
|
170
170
|
| Quota | only known when exceeded (429); set a weekly cap for ama under ChatGPT → Settings → Usage → App limits | response headers, `codex.rate_limits` events, `ama auth status` queries `wham/usage` |
|
|
171
171
|
| Logout | calls `revocation_endpoint`, then deletes locally | deletes locally only |
|
|
172
172
|
|
|
173
|
-
**Model list**: `chatgpt` has no built-in model table (`chatgpt/<slug>` accepts any slug). After a successful `ama auth login chatgpt`, ama calls the model list endpoint once (siwc `GET /v1/models`, codex `GET /models
|
|
173
|
+
**Model list**: `chatgpt` has no built-in model table (`chatgpt/<slug>` accepts any slug). After a successful `ama auth login chatgpt`, ama deletes the old cache and calls the model list endpoint once (siwc `GET /v1/models`, codex `GET /models?client_version=…`; read-only, no usage consumed; failures are silent and the output suggests `ama models discover chatgpt` instead) and caches the slugs and display names available to the account, with the flavor and a timestamp, in `<dataDir>/models/discovered/chatgpt.json` — an empty list is written as well when no model comes back, so no cache from the other sign-in method is left behind; `ama models discover chatgpt` rewrites the cache and `ama auth logout chatgpt` deletes it. When the registry is assembled the cache is merged into providers whose model table is empty, and the context window, input modalities and reasoning efforts reported by the backend (codex reports them; siwc entries are read the same way when present) are cached and take precedence over the models.dev snapshot — the subscription backend's effective window (such as 272k) can be far smaller than the API window models.dev lists, and the compaction threshold follows the backend window; fields the backend leaves out (such as the output limit) come from models.dev, and when neither has a context window a conservative 128k is used. A cache written by an older version without windows keeps using models.dev until `ama models discover chatgpt` refreshes it. This way the `/model` picker and `ama models list` show the models; a cache whose flavor differs from the current sign-in counts as stale and is not merged (the picker suggests discovering again). Slugs missing from the cache still work with `--model chatgpt/<slug>`.
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
**codex `client_version`**: the codex backend filters models by `client_version` (each model has a minimum client version; omitting the parameter is a 400), and ama sends a Codex CLI version (default `0.160.0`), not its own version. If codex returns no models at login or discover time, that version is most likely too old: set a newer Codex CLI version with `ama config set auth.chatgpt.codexClientVersion <version>` (user level) or the environment variable `AMA_CHATGPT_CODEX_CLIENT_VERSION` (takes precedence), then run `ama models discover chatgpt`. Inference requests carry no version.
|
|
176
|
+
|
|
177
|
+
**The channel follows the sign-in method**: the default channel of `chatgpt` is chosen at assembly time from the flavor of the auth.json entry; on top of that every request picks the channel from the flavor of the token it uses — a model reference without `@channel` automatically uses the current sign-in method's channel (endpoint, channel headers such as `originator`, and the request-body allowlist all switch), so after `ama auth logout` and signing in the other way, a running session's next request goes to the new channel without a restart; when a session is resumed, the channel recorded in it does not count as explicit either. Only an explicit `provider/model@siwc|codex` that differs from the sign-in method reports `chatgpt_flavor_mismatch` (suggesting to drop `@channel` or switch the sign-in method).
|
|
176
178
|
|
|
177
179
|
**Credentials**: a `{ "type": "oauth", … }` entry in auth.json (file mode 0600); `ama auth list` only shows `oauth · <flavor> · <plan>`. The access token is refreshed automatically when less than 5 minutes remain or a request returns 401; several ama processes (several nodes on the canvas) share one auth.json, and refreshes are serialized through `auth.json.lock` (re-read after taking the lock; if another process already refreshed, its token is used), so refresh-token rotation never knocks another process out. When refreshing fails permanently the entry is marked `needsLogin` (tokens are not deleted), requests report `auth_expired`, and you sign in again with `ama auth login chatgpt` as prompted. Raw tokens, codes and id_tokens never reach logs, sessions, events or errors. Logins of other applications (Codex CLI and others) are never read or imported.
|
|
178
180
|
|
|
@@ -184,12 +186,14 @@ The default channel of `chatgpt` is chosen at assembly time from the flavor of t
|
|
|
184
186
|
| ---------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
|
|
185
187
|
| `quota_exceeded` | siwc 429 `subscription_sharing_usage_limit_exceeded`; codex 429 `usage_limit_reached` / `usage_not_included` | no retry; carries the reset time and emits `quota_update` |
|
|
186
188
|
| `auth_expired` | a 401 still failing after one refresh, a permanently failed refresh, an entry marked `needsLogin` | no retry; run `ama auth login chatgpt` again |
|
|
187
|
-
| `not_eligible` | siwc 403 `subscription_sharing_user_not_eligible` | no retry, no re-login
|
|
189
|
+
| `not_eligible` | siwc 403 `subscription_sharing_user_not_eligible` | no retry, no re-login; see troubleshooting below |
|
|
188
190
|
| (as is) | 503 and similar | the session layer's existing backoff retries |
|
|
189
191
|
|
|
192
|
+
**Troubleshooting `not_eligible`**: the account cannot share its plan usage with ama. Possible causes: the plan (sharing is offered to Plus / Pro only); a workspace account (Team / Enterprise / Edu may not offer it); a region restriction or a preview that has not rolled out yet — **the most likely cause when a Pro account still gets this error**. You can sign in with `ama auth login chatgpt --flavor codex` instead. A successful siwc login only means authorization passed; whether plan usage can be shared is only confirmed on the first request.
|
|
193
|
+
|
|
190
194
|
**Usage**: subscription requests record `usage.cost = 0` with `billing: "subscription"`; `/session` lists "subscription usage" separately (requests, tokens, cache hit rate, no USD conversion) together with the latest quota; the `quota_update` event is forwarded as is over RPC and has the same name among host events.
|
|
191
195
|
|
|
192
|
-
**Overrides** (for tests or a future own client): `auth.chatgpt.clientId` / `issuer` / `originator` / `redirectPorts` (user level and profile only), environment variables `AMA_CHATGPT_CLIENT_ID`, `AMA_CHATGPT_ISSUER`, `AMA_CHATGPT_BASE_URL` (changes the address of the current flavor's channel)
|
|
196
|
+
**Overrides** (for tests or a future own client): `auth.chatgpt.clientId` / `issuer` / `originator` / `codexClientVersion` / `redirectPorts` (user level and profile only), environment variables `AMA_CHATGPT_CLIENT_ID`, `AMA_CHATGPT_ISSUER`, `AMA_CHATGPT_BASE_URL` (changes the address of the current flavor's channel), `AMA_CHATGPT_CODEX_CLIENT_VERSION`.
|
|
193
197
|
|
|
194
198
|
**Embedding hosts**: with a profile ama never starts an interactive login; when `chatgpt` is used and the login has expired the request reports `auth_expired`, and the host guides the user to run `ama auth login chatgpt --paste` in a terminal. Hosts never read, store or forward tokens; they only consume `quota_update` and `auth_expired` / `quota_exceeded`.
|
|
195
199
|
|
package/docs/en/rpc.md
CHANGED
|
@@ -171,7 +171,18 @@ After a session switch the server re-subscribes to events and sends `session_sta
|
|
|
171
171
|
- Errors: `invalid_arguments` (out-of-range parameters, `before` not a turn id on this branch, `before` together with
|
|
172
172
|
`since`) and `task_not_found`.
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
### Background sub-agents (wave 7)
|
|
175
|
+
|
|
176
|
+
| Command | Parameters | `data` |
|
|
177
|
+
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
178
|
+
| `background_task` | `taskId?` | `{ backgrounded: string[] }`: the task ids actually moved. Without `taskId`, every running foreground task; an empty list for finished, already-background or unknown tasks; a non-string `taskId` → `invalid_arguments` |
|
|
179
|
+
|
|
180
|
+
A moved foreground task is not interrupted: its `task` call returns at once with `tool_execution_end` (the result text starts with
|
|
181
|
+
`[task tN] Moved to the background`, `details.status: "running"`), followed by `subagent_background`; when the task ends you get
|
|
182
|
+
`subagent_end` as usual and, once the parent session is idle, the notification message with `origin: "task"`. Same semantics as
|
|
183
|
+
`Ctrl+B` in the interactive UI.
|
|
184
|
+
|
|
185
|
+
44 commands in total; their names are the keys of `RpcCommandMap`.
|
|
175
186
|
|
|
176
187
|
## Events
|
|
177
188
|
|
|
@@ -216,13 +227,14 @@ There is also the non-session event `{"type":"notification","level":"info"|"warn
|
|
|
216
227
|
|
|
217
228
|
Sub-agents started by `task` / `task_ctl` (ama sub-sessions and external agents share the same events, see [agents.md](../agents.md), Chinese):
|
|
218
229
|
|
|
219
|
-
| Event
|
|
220
|
-
|
|
|
221
|
-
| `subagent_start`
|
|
222
|
-
| `subagent_update`
|
|
223
|
-
| `
|
|
230
|
+
| Event | Fields |
|
|
231
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
232
|
+
| `subagent_start` | `taskId`, `parentToolCallId`, `agent`, `runner` (`ama` / `claude` / `codex` / `acp:<program>`), `description`, `background`, `model?`, `sessionFile?`, `cwd`; sent again when the same `taskId` is continued |
|
|
233
|
+
| `subagent_update` | `taskId`, `kind: tool \| text \| turn`, `toolName?`, `textDelta?` (merged over ≥ 250 ms), `turn`, `usage?` |
|
|
234
|
+
| `subagent_background` | `taskId`, `parentToolCallId`, `reason: user \| timeout \| host` (a foreground task moved to the background: by hand in the interactive UI, when `subagents.autoBackgroundAfterMs` elapses, or by an RPC / SDK call; wave 7) |
|
|
235
|
+
| `subagent_end` | `taskId`, `status: completed \| failed \| aborted \| max_turns \| interrupted`, `usage?`, `cache?`, `outputFile?`, `worktree?: { branch, changed }` |
|
|
224
236
|
|
|
225
|
-
Approvals of sub-sessions and external agents are sent to this connection as `permission_request` as usual, with an optional `context` marking the origin (since wave 6, approvals of this session's own tool calls also carry `context.toolCallId`, the id of the tool call that triggered the approval, which traces use to compute approval wait time; external agent requests do not carry it): `depth` (1 = from a task sub-agent), `taskId` (the originating task), `origin` (permission requests from external agents: `agent`, `sessionId` (the external CLI's own session id), `toolCall: { title, kind, locations?, inputSummary? }`, `options`). Dialogs use it to show `[task:<agent>]` or `[claude · session abc1]`. For external agent requests `toolName` is `agent:<id>` and the answer applies to this one request only ("allow for this session" is remembered by the external agent itself); the first run of an external agent in a session additionally gets one confirmation with `toolName: "task"`, `input: { agent, mode, note }` (`context.taskId`). `test/fixtures/rpc/external.out.jsonl` is the golden record of the three approvals of `task(agent="acp:ama")` (the task tool, the first run, the child ama's bash), updated by `src/agents/external-rpc.test.ts` with `UPDATE_GOLDEN=1`. After a background task completes, the parent session receives a user message with `origin: "task"` (`<task-notification …>…</task-notification>`) and starts a new turn as usual. Task and type lists are returned by `get_tasks` / `get_agents` (shapes `TaskInfo` / `AgentInfo`; empty without the task tool), with data from the current session's `taskRegistryView(sessionId)` / `sessionAgents(sessionId)` (`src/agent/subagent-registry.ts`). `get_agents` also includes external agents (`installed` / `version` come from PATH and a `--version` probe, cached asynchronously when the session is created and refreshed when external tasks end or host injections change; before the cache is ready there is only the type catalog, see `cachedAgentInfos` in `src/agents/external.ts`). `test/fixtures/rpc/subagent.out.jsonl` is the golden record of a foreground `task(agent="explore")` plus `get_tasks` / `get_agents` (keeping only responses, `tool_execution_*`, `subagent_*` and `agent_settled`), updated by `src/agent/subagent-rpc.test.ts` with `UPDATE_GOLDEN=1`.
|
|
237
|
+
Approvals of sub-sessions and external agents are sent to this connection as `permission_request` as usual, with an optional `context` marking the origin (since wave 6, approvals of this session's own tool calls also carry `context.toolCallId`, the id of the tool call that triggered the approval, which traces use to compute approval wait time; external agent requests do not carry it): `depth` (1 = from a task sub-agent), `taskId` (the originating task), `origin` (permission requests from external agents: `agent`, `sessionId` (the external CLI's own session id), `toolCall: { title, kind, locations?, inputSummary? }`, `options`). Dialogs use it to show `[task:<agent>]` or `[claude · session abc1]`. For external agent requests `toolName` is `agent:<id>` and the answer applies to this one request only ("allow for this session" is remembered by the external agent itself); the first run of an external agent in a session additionally gets one confirmation with `toolName: "task"`, `input: { agent, mode, note }` (`context.taskId`). `test/fixtures/rpc/external.out.jsonl` is the golden record of the three approvals of `task(agent="acp:ama")` (the task tool, the first run, the child ama's bash), updated by `src/agents/external-rpc.test.ts` with `UPDATE_GOLDEN=1`. After a background task completes, the parent session receives a user message with `origin: "task"` (`<task-notification …>…</task-notification>`) and starts a new turn as usual. Task and type lists are returned by `get_tasks` / `get_agents` (shapes `TaskInfo` / `AgentInfo`; empty without the task tool), with data from the current session's `taskRegistryView(sessionId)` / `sessionAgents(sessionId)` (`src/agent/subagent-registry.ts`). `get_agents` also includes external agents (`installed` / `version` come from PATH and a `--version` probe, cached asynchronously when the session is created and refreshed when external tasks end or host injections change; before the cache is ready there is only the type catalog, see `cachedAgentInfos` in `src/agents/external.ts`). `test/fixtures/rpc/subagent.out.jsonl` is the golden record of a foreground `task(agent="explore")` plus `get_tasks` / `get_agents` (keeping only responses, `tool_execution_*`, `subagent_*` and `agent_settled`), updated by `src/agent/subagent-rpc.test.ts` with `UPDATE_GOLDEN=1`. `test/fixtures/rpc/background.out.jsonl` is the golden record of `background_task` moving a running foreground `task` to the background, the task ending and its notification turn, updated by `src/modes/rpc/rpc-background.test.ts`.
|
|
226
238
|
|
|
227
239
|
### Throughput telemetry (wave 5)
|
|
228
240
|
|
package/docs/en/sessions.md
CHANGED
|
@@ -51,7 +51,9 @@ Top 5 tool calls
|
|
|
51
51
|
| Errors / retries | Assistant messages with `stopReason: "error"`; `context_edit{reason:"retry"}` (failed attempts removed by automatic retry) |
|
|
52
52
|
| Channel | The `channel` of the latest `model_change` with the same provider / model as the request |
|
|
53
53
|
|
|
54
|
-
`task` sub-sessions are separate files and count under their own cwd.
|
|
54
|
+
`task` sub-sessions are separate files and count under their own cwd. The notification message a parent session receives when a
|
|
55
|
+
background task finishes (`origin: "task"`) also starts a turn and counts under the parent; when `-p` waits for background tasks,
|
|
56
|
+
those notification turns are written to the same session file.
|
|
55
57
|
|
|
56
58
|
### Performance and index
|
|
57
59
|
|
package/docs/en/tui.md
CHANGED
|
@@ -15,16 +15,12 @@ Running `ama` directly in a terminal (stdin / stdout both TTYs, `TERM` not `dumb
|
|
|
15
15
|
The visual spec (colors, glyphs, screen-by-screen mockups) is in [tui-design.md](../tui-design.md) (Chinese). Hierarchy is expressed by indentation: column 0 holds the user `›`, the tool `⏺` and notice symbols, column 2 the result connector `⎿`, column 4 the tool output; the structure stays readable without colors (`NO_COLOR`, `capture-pane` without `-e`).
|
|
16
16
|
|
|
17
17
|
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
│ Loaded AGENTS.md · 2 Skills │
|
|
25
|
-
│ │
|
|
26
|
-
│ /help commands · Shift+Tab mode · Ctrl+O expand tool output │
|
|
27
|
-
╰──────────────────────────────────────────────────────────────╯
|
|
18
|
+
▄███▄ ██▄ ▄██ ▄███▄ ama 0.6.2 ← startup header (normal)
|
|
19
|
+
██▀ ▀██ ███▄ ▄███ ██▀ ▀██ anthropic/claude-sonnet-4-5@messages · thinking medium
|
|
20
|
+
███████ ██ ▀█▀ ██ ███████ ~/Projects/demo · trusted (trust.json)
|
|
21
|
+
██ ██ ██ ██ ██ ██ Accept edits · preset default
|
|
22
|
+
▀▀ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀ AGENTS.md · 2 Skill
|
|
23
|
+
/help commands · Shift+Tab mode · Ctrl+O expand tool output
|
|
28
24
|
|
|
29
25
|
› read the README ← user message (continuation lines indented 2)
|
|
30
26
|
|
|
@@ -44,23 +40,26 @@ The visual spec (colors, glyphs, screen-by-screen mockups) is in [tui-design.md]
|
|
|
44
40
|
› Type a message, / commands, @ files, Shift+Enter newline ← input box (placeholder)
|
|
45
41
|
────────────────────────────────────────────────
|
|
46
42
|
tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) ↑12k ↓1.2k · cache 80% ♨ · [-] ← rate line (full)
|
|
47
|
-
Accept edits claude-opus-5-5 medium | Ctx 3.0% | proj ⎇ main 5ae9e54 (+12,-3) | $0.26 | 2h24m
|
|
43
|
+
Accept edits claude-opus-5-5 medium | Ctx 3.0% | proj ⎇ main 5ae9e54 ↑2 (+12,-3) | $0.26 | 2h24m
|
|
44
|
+
Session: 10.0% | Reset: 2h 18m | Weekly: 31.0% | Weekly Reset: 6d 5h ← subscription quota line (full, ChatGPT subscription model)
|
|
48
45
|
```
|
|
49
46
|
|
|
50
47
|
- **User messages**: start with `›`, continuation lines indented 2 columns; steers while running are marked `↳ steer`, messages queued after this turn `↳ after`, and messages injected by the host (the Armadra canvas) `↳ host` (the `origin` in the session file stays steer / followUp / host).
|
|
51
48
|
- **Thinking blocks**: `ui.showThinking` = `collapsed` (default: "thinking…" → "thinking · 1.2k tokens", `Ctrl+O` expands it to an indented body of at most 60 lines) / `full` (always expanded) / `hidden`.
|
|
52
49
|
- **Tool calls**: titled `⏺ tool name summary`; `⏺` is the accent color while running, green on success, red on failure. The second line after `⎿` is the result summary: lines read, `N changes · +a −b`, `exit 0 · 2.1s · 48 lines`, matches and files, `N inner calls · M lines of script output`, `sub-agent · running 1m05s` / `done · 1m42s · ↑28k ↓4.1k`; while running the summary line carries a spinner in the same frame as the bottom and the seconds. Bodies show the first 3 lines folded; `edit` shows a diff (first 12 lines, with line numbers at ≥ 60 columns); running `bash` scrolls its last 8 lines. `Ctrl+O` expands / folds everything (thinking blocks included). Inner calls of a codemode script hang under the outer call (folded, only the titles and summaries of the latest 5 are listed).
|
|
53
50
|
- **Notices**: `✗` errors, `↻ retry n/m`, `!` warnings (cache misses, remaining context), `⛔` hook blocks, host notifications, explanations of denied or timed-out approvals; compaction / branch summaries are left-bar cards (`▎ context compacted 128k → 24k tokens`).
|
|
54
|
-
- **Running**: `⠋ verb · elapsed · …`, with the verb taken from the deepest current state: waiting for confirmation (approval open), `running bash` / `running 3 tools`, `retry 2/3 · in 2s`, compacting context, replying `· ↓≈1.2k` (estimated tokens of this output), thinking.
|
|
55
|
-
- **Status bar**: always the last line
|
|
51
|
+
- **Running**: `⠋ verb · elapsed · …`, with the verb taken from the deepest current state: waiting for confirmation (approval open), `running bash` / `running 3 tools`, `retry 2/3 · in 2s`, compacting context, replying `· ↓≈1.2k` (estimated tokens of this output), thinking. While a foreground sub-agent task blocks the turn, `Ctrl+B to background` is appended; while the agent bar has tasks, `↓ Agent bar` is appended (`↓ handle approval` instead when an approval is docked): `⠏ running task · 4s · Esc to interrupt · Ctrl+B to background · ↓ Agent bar`; items are dropped whole from the end when the line does not fit.
|
|
52
|
+
- **Status bar**: the mode is always on the far left; the status bar is the last line except for the subscription quota line in the `full` layout (`compact` always keeps it last). In `compact` the separator is always `·` (embedding hosts parse it), in `full` it is `|`. The layout follows `ui.statusLine`: `full` (two lines) by default in a standalone terminal, `compact` (one line, same layout as before) by default in an embedding host with a profile; `Ctrl+G` or `/statusline [full|compact]` switches at runtime for this session only. With `full` the input box is the 4th line from the bottom (`compact` keeps it 3rd from the bottom).
|
|
56
53
|
- **`full` top line (rate line)**: `tps: <rate> tok/s • <output tokens> tok / <elapsed> (avg <session average> · ttft <time to first token>)`. While streaming the rate is the instantaneous value over the last 2 s (`tps:` in the accent color); afterwards it is the request's average; whole replies generated in under 0.25 s get no rate and show `—`; elapsed time starts at the first token; in ASCII `•` becomes `*`. The right side holds usage items: `↑` input (including cache reads and writes) `↓` output · cache · re-billing · queue count · codemode · tool preset (when not default) · host status, with `[-]` at the end hinting that it folds. Only chat requests count (compaction summaries, warming and the classifier do not). When narrow, these drop in order: output / elapsed, codemode, queue count, tokens, cache, re-billing, preset, host status, avg, ttft; `tps` and `[-]` never drop.
|
|
57
|
-
- **`full` bottom line**: on the left `permission mode | shift+tab to switch`, on the right `model thinking-level | Ctx 3.0% | <dir name> ⎇ <branch> <short commit> (+a,-d) | $cost | session duration` (Ctx with one decimal, no meter even when wide); when narrow, these drop in order: the switch hint, thinking level, line changes, directory name, branch and commit, duration, cost, context, model.
|
|
58
|
-
-
|
|
59
|
-
- **
|
|
54
|
+
- **`full` bottom line**: on the left `permission mode | shift+tab to switch`, on the right `model thinking-level | Ctx 3.0% | <dir name> ⎇ <branch> <short commit> ↑N ↓N (+a,-d) | $cost | session duration` (Ctx with one decimal, no meter even when wide); when narrow, these drop in order: the switch hint, thinking level, line changes, directory name, branch and commit, duration, cost, context, model.
|
|
55
|
+
- **Subscription quota line** (third `full` line, below the status bar): when the current model uses a ChatGPT subscription (the `chatgpt` provider) it shows `Session: <used %> | Reset: <time to reset> | Weekly: <used %> | Weekly Reset: <time to reset>` (Chinese labels in the Chinese interface), from the latest `quota_update` (the codex flavor's `x-codex-primary/secondary-*` response headers and `codex.rate_limits` events; siwc only has it after a 429). Reset times are relative (`2h 18m`, `6d 5h`) and refresh once a minute. Before the first request the codex flavor shows "Quota: shown after the first request" (the first request brings the quota back, so holding the line avoids the row count jumping); siwc without data takes no line (it only gets a quota when over the limit, so a placeholder would stay forever); non-subscription models show nothing. Below 80 columns it compresses to `5h 10% ↻2h18m · wk 31% ↻6d5h`, dropping the reset times first when narrower. A window that is not 5 hours / 7 days is labelled with its actual length. `Ctrl+G` / `/statusline compact` folds the quota line together with the rate line (`compact` stays a single line; hosts anchor on "last line = status bar").
|
|
56
|
+
- **Colors** (`full`): labels, units, separators and parentheses dim gray; the rate number purple, output / elapsed / avg blue, ttft purple; model and thinking level blue; Ctx and quota percentages by threshold green / yellow / red (≥ 70% yellow, ≥ 90% red); directory and branch green, short commit dim, `↑N` ahead orange, `↓N` behind red, `(+a,-d)` green / red; cost yellow; duration and reset times purple. All come from theme semantic colors with dark / light and 16-color mappings; `NO_COLOR` and ASCII drop the colors and keep the structure. `compact` colors are unchanged.
|
|
57
|
+
- **`compact`**: one line; on the right model · thinking level · `↑ ↓` · cache · cost · re-billing · context usage · dir ⎇ branch commit +a −b · session duration · queue count · codemode · preset · host status · a short subscription quota item (`5h 10% wk 31%`, only with quota data; no `·` inside the item); when narrow, these drop in order: the quota item, the switch hint, host status, preset, re-billing, cost, cache, tokens, thinking level, queue count, codemode, line changes, directory name, branch and commit, duration, context, model.
|
|
58
|
+
- **git**: branch and short commit are read directly from `.git/HEAD` (worktrees understood; detached shows only the short commit; outside git the whole part is omitted, leaving only the directory name). `+a −b` is the working tree (staged included) line diff against HEAD, computed in the background with `git diff --numstat HEAD` after a turn ends, a writing tool finishes, a rewind or `/tree`, at most once every 10 seconds; if it takes longer than 2 seconds or fails, line changes are hidden for the rest of the session; `AMA_STATUS_GIT=0` turns it off. In `full`, `↑N` / `↓N` count the commits the current branch is ahead of / behind its upstream: when the branch has an upstream in the git config (`branch.<name>.merge`), the same throttled cycle then runs `git rev-list --left-right --count @{upstream}...HEAD` (same 2-second timeout; after a timeout it stops for the session); zero, no upstream or detached shows nothing; ASCII uses `^N` / `vN`.
|
|
60
59
|
- **Cost** includes sub-tasks, warming, the classifier and external agent usage priced in USD (other units only in `/session`); **duration** counts from when this process opened the current session (`Ns` / `Nm` / `NhMm`).
|
|
61
60
|
- When bash commands run in the OS sandbox (`sandbox.bash: "auto"` and available on this machine, see [sandbox.md](../sandbox.md), Chinese), the usage items gain a sandbox marker, dropped first together with codemode when space runs out.
|
|
62
61
|
- During a model fallback (`fallbackModel`: when the main model is overloaded or retries are exhausted, one retry with the fallback model) the model item shows `main model → fallback model` (the fallback in yellow); it disappears once the fallback model replies and the main model is restored, and the message area gets an explanatory line.
|
|
63
|
-
- Model names abbreviate with width (provider dropped below 100 columns, channel below 60, version suffix below 48); `compact` at ≥ 110 columns shows context as a meter `ctx ▮▮▮▯▯▯▯▯▯▯ 34%`; changing numbers reserve their widest shape, so items never flicker in and out as values change. In ASCII mode `⎇` → `git`, `−` → `-`, `♨` →
|
|
62
|
+
- Model names abbreviate with width (provider dropped below 100 columns, channel below 60, version suffix below 48); `compact` at ≥ 110 columns shows context as a meter `ctx ▮▮▮▯▯▯▯▯▯▯ 34%`; changing numbers reserve their widest shape, so items never flicker in and out as values change. In ASCII mode `⎇` → `git`, `−` → `-`, `♨` → `~`, `↻` → `@`.
|
|
64
63
|
- **Exit**: a session summary line and the resume command are appended at the end of the message area and stay in the terminal scrollback:
|
|
65
64
|
|
|
66
65
|
```
|
|
@@ -117,26 +116,27 @@ Trade-offs: the status bar shows the latest hit rate (the session total lives in
|
|
|
117
116
|
|
|
118
117
|
## Keys
|
|
119
118
|
|
|
120
|
-
| Key
|
|
121
|
-
|
|
|
122
|
-
| Enter
|
|
123
|
-
| Alt+Enter
|
|
124
|
-
| Shift+Enter / Ctrl+J
|
|
125
|
-
| Esc
|
|
126
|
-
| Esc Esc (idle)
|
|
127
|
-
| Alt+↑
|
|
128
|
-
| Shift+Tab / Tab
|
|
129
|
-
| Ctrl+O
|
|
130
|
-
| Ctrl+L / Ctrl+T
|
|
131
|
-
| Ctrl+G
|
|
132
|
-
| Ctrl+V
|
|
133
|
-
| Ctrl+C
|
|
134
|
-
| Ctrl+D
|
|
135
|
-
| Tab
|
|
136
|
-
| ↑ / ↓
|
|
137
|
-
|
|
|
138
|
-
|
|
139
|
-
|
|
119
|
+
| Key | Effect |
|
|
120
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
121
|
+
| Enter | Send; while running = steer (inserted into the current turn) |
|
|
122
|
+
| Alt+Enter | While running, queue after this turn (followUp); when idle, same as Enter |
|
|
123
|
+
| Shift+Enter / Ctrl+J | New line |
|
|
124
|
+
| Esc | Interrupt: queued messages go back into the input box, then the current run stops (with foreground sub-agent tasks; background tasks keep running, as the hint says); closes completion first when it is open |
|
|
125
|
+
| Esc Esc (idle) | Empty input: open the rewind list (same as `/rewind`); with text: clear it and save it into input history |
|
|
126
|
+
| Alt+↑ | Recall the last queued message |
|
|
127
|
+
| Shift+Tab / Tab | Cycle permission modes Manual → Accept edits → Plan → Auto → Bypass permissions (Tab only on an empty input with completion closed, otherwise still completion; entering Bypass asks to confirm, see "Entering Bypass" below) |
|
|
128
|
+
| Ctrl+O | Expand / fold tool output and thinking blocks |
|
|
129
|
+
| Ctrl+L / Ctrl+T | Pick model / thinking level |
|
|
130
|
+
| Ctrl+G | Bottom info line two lines (full) ↔ one line (compact), this session only |
|
|
131
|
+
| Ctrl+V | Paste an image from the clipboard: saved in the data directory, `@<path>` inserted at the cursor (same as `/paste`) |
|
|
132
|
+
| Ctrl+C | Clear the input; on an empty input, press again within 1.5 seconds to quit (exit code 130) |
|
|
133
|
+
| Ctrl+D | Quit on an empty input |
|
|
134
|
+
| Tab | Complete |
|
|
135
|
+
| ↑ / ↓ | Browse history on a single line (`<data dir>/history`, 500 entries) |
|
|
136
|
+
| ↓ (empty input) | Enter the agent bar (whenever there are sub-agent tasks); with text it still moves down / through history and hints once, see "Sub-agents" |
|
|
137
|
+
| Ctrl+B | When foreground sub-agent tasks (or a `task_ctl wait`) block the turn, move them all to the background, whatever is in the input box; otherwise cursor left. In tmux press `C-b C-b`, see "Sub-agents" |
|
|
138
|
+
|
|
139
|
+
Keys can be overridden in `~/.config/ama/keybindings.json`: keys are action ids (`app.interrupt`, `app.rewind`, `app.message.followUp`, `app.statusLine.toggle`, `app.paste.image`, `app.agents.focus`, `app.tasks.background`, `tui.editor.newLine` …), values are a key or an array of keys, and an empty array disables the action. `app.rewind` is the key double-pressed while idle (Esc by default, at most 800 ms apart).
|
|
140
140
|
|
|
141
141
|
## Rewind
|
|
142
142
|
|
|
@@ -315,12 +315,17 @@ Sub-agents started by the `task` tool ([agents.md](../agents.md), Chinese) fold
|
|
|
315
315
|
⏺ task check test coverage gaps in src/tui
|
|
316
316
|
⎿ ⠋ explore · running 1m05s · 3 turns · read grep bash · ↑12k ↓3.4k
|
|
317
317
|
⏺ task background review
|
|
318
|
-
⎿
|
|
318
|
+
⎿ started in the background
|
|
319
319
|
↳ t2 explore · running 40s · 1 turn · read
|
|
320
|
+
⏺ task scan
|
|
321
|
+
⎿ moved to the background · 12s
|
|
322
|
+
↳ t3 explore · running 30s · 2 turns · grep
|
|
320
323
|
```
|
|
321
324
|
|
|
322
|
-
- The status line shows the type (external agents show a runner such as `claude (claude)`), status and elapsed time, turns, the latest 3 tools and usage; after a foreground task ends it is replaced by the result summary. A background task's (
|
|
323
|
-
- `/tasks`: focus the agent bar (below); `/tasks <id>` opens that task's sub-agent view directly; `/tasks stop <id>` stops it. With `ui.agentBar: "off"`
|
|
325
|
+
- The status line shows the type (external agents show a runner such as `claude (claude)`), status and elapsed time, turns, the latest 3 tools and usage; after a foreground task ends it is replaced by the result summary. A background task's tool call (background is the default in the interactive UI, see [agents.md](../agents.md) "foreground and background", Chinese) returns immediately; the summary line says "started in the background", with an extra follow-up status line below (refreshed every second while running). A foreground task moved to the background shows "moved to the background · elapsed" with the same follow-up line (the explanation meant for the model is hidden; `Ctrl+O` shows it). A task moved by the auto timeout (`subagents.autoBackgroundAfterMs`) or by the host also gets a one-line notice; when it completes, the `<task-notification>` the model receives shows in the message area as a single line (e.g. "↳ sub-agent notification: t2 explore done · 7 turns · see /tasks for output"), plus a yellow notice on failure or stop.
|
|
326
|
+
- `/tasks`: focus the agent bar (below); `/tasks <id>` opens that task's sub-agent view directly; `/tasks stop <id>` stops it; `/tasks bg [id]` moves it to the background (without an id: every blocking foreground task, same as `Ctrl+B`). With `ui.agentBar: "off"` `/tasks` is still the task picker (newest on top, Enter shows the output, running tasks can be stopped). Line mode: `/tasks` lists, `/tasks <id>` shows output, `/tasks stop <id>` stops, `/tasks bg [id]` moves to the background (typed while running it is still a command, not a steer).
|
|
327
|
+
- Moving to the background (`Ctrl+B`, key action `app.tasks.background`): while the main turn waits for a foreground task (`task` with `background: false`, the `-p` default, or `task_ctl wait`), press it and the tool call returns at once, the task keeps running, the main turn carries on and you can keep sending messages; when the task ends the `<task-notification>` arrives and opens a turn as usual. The hint says "Moved to the background: t2; you'll be notified when it finishes". With nothing to move, `Ctrl+B` falls through to the editor (cursor left) and is not swallowed. tmux's default prefix is `C-b`: in tmux press `C-b C-b` (default `send-prefix`) to pass it to ama, or press `b` in the agent bar; you can also rebind it in `keybindings.json`.
|
|
328
|
+
- Esc interrupts only the foreground: Esc while running stops the main turn and the sub-tasks still in the foreground; tasks already in the background keep running, and the hint says "Interrupted (background task t2 keeps running; Esc doesn't affect it)".
|
|
324
329
|
- `/agents`: the available types: name, runner, source (built-in / user / project / profile / host), external agents marked installed with a version or not installed, plus a one-line description.
|
|
325
330
|
- Notices reported by external agents themselves (budget exhausted, timeout, mode downgrade …) show in the message area as a single line `[claude · t3] …`.
|
|
326
331
|
|
|
@@ -335,11 +340,13 @@ Above the status line (below the hint line) the bar lists sub-agent tasks, one l
|
|
|
335
340
|
1 more
|
|
336
341
|
```
|
|
337
342
|
|
|
338
|
-
- States: queued (the concurrency pool is full) / running (elapsed time, turns, latest tool) / awaiting approval (the approval dialog currently holds its request) / done / failed / stopped (plus out of turns and interrupted); `⏺` is the accent color while running, green when done, red on failure, yellow / dim otherwise; `*` in ASCII.
|
|
343
|
+
- States: queued (the concurrency pool is full) / running (elapsed time, turns, latest tool) / awaiting approval (the approval dialog currently holds its request, or it is docked in the bar; the row is yellow) / done / failed / stopped (plus out of turns and interrupted); `⏺` is the accent color while running, green when done, red on failure, yellow / dim otherwise; `*` in ASCII.
|
|
339
344
|
- When it shows: while any task is queued, running or awaiting approval; tasks that ended in this session and have not been looked at in the view stay until viewed, at most 10 minutes. Tasks already finished when a session is resumed are not shown (`/tasks` lists them).
|
|
340
|
-
- Entering:
|
|
341
|
-
-
|
|
342
|
-
-
|
|
345
|
+
- Entering: press `↓` with an empty input box and no completion open, whenever the session has tasks (even after the bar has collapsed, same as `/tasks`); the same inside and outside tmux. It works while a turn runs too; the `↓ Agent bar` at the end of the running line is the reminder. The key action is `app.agents.focus` (only `down` by default), configurable in `keybindings.json`.
|
|
346
|
+
- When the key does not get you in, a one-line hint shows for 3 seconds: text in the input box — "Input is not empty; clear it and press ↓ for the Agent bar" (once per draft, with the cursor on the last line; `↓` still moves down); the bar is off — "Agent bar is off (ui.agentBar); use /tasks"; no tasks — "No sub-agent tasks yet". While browsing input history with `↑` `↓`, `↓` only steps through history.
|
|
347
|
+
- `Ctrl+B` does not enter the bar; it moves foreground tasks to the background (above). For the old "`Ctrl+B` enters the bar", set `"app.agents.focus": ["down", "ctrl+b"]` in `keybindings.json` and rebind `app.tasks.background`.
|
|
348
|
+
- In the bar: `↑` `↓` select (lists every task of the session, the window scrolls along; `↑` on the first item returns to the input box), Enter opens the sub-agent view (a docked approval of the selected task pops up right away), `b` / `Ctrl+B` moves the selected foreground task to the background (a one-line hint when it is not running in the foreground), `x` stops the selected task (the first press hints "Press x again to stop t2"; it stops only on a second press within 1.5 seconds), Esc returns to the input box; other letters return to the input box with the text filled in. The last line is the key hint `↑↓ select · Enter open · b background · x stop · Esc back`; narrow screens drop the `b` / `x` items.
|
|
349
|
+
- Embedding hosts (with a profile) no longer turn the bar off by default; a host that shows sub-tasks itself and does not want the bar sets `ui.agentBar: "off"` in its profile (see [host-api.md](host-api.md) "Embedding in Armadra"). With the bar off it is not shown, and `↓` with tasks points to `/tasks`.
|
|
343
350
|
|
|
344
351
|
### Sub-agent view
|
|
345
352
|
|
|
@@ -360,8 +367,17 @@ t2 explore · running 1m05s · 3 turns · ↑12k ↓3.4k · Esc back · /tasks s
|
|
|
360
367
|
- The body follows live: for ama sub-agents it shows every message and tool call of the sub-session (rendered like the message area); when the sub-session handle has been released (at most 16 are kept) or the session was resumed, the sub-session file is loaded read-only and live events are attached when the task runs again. External agents (claude / codex / ACP) show the live output held in this process's memory (text, thinking, tool start / end, turns, notices; at most 2000 items / 1 MB, never written to disk); after ama restarts only one line remains, saying to use the original CLI's resume <session id> for the full text.
|
|
361
368
|
- With an empty input box: `↑` / PgUp scroll up (pausing follow, with "follow paused · End to resume" at the bottom), `↓` / PgDn scroll down, End (or `f` while paused) resumes following; `←` `→` switch to the previous / next task; Esc returns to the main screen. With text in the input box, Esc clears it first.
|
|
362
369
|
- Enter sends the input to this sub-agent (recorded in the sub-session as a user message with `origin: "direct"`, see [session-format.md](../session-format.md), Chinese): ama sub-agent running → delivered when its current turn ends; external agent running or task still queued → continued after this run ends; finished → continued in the background (like `task_ctl send`; the main session receives the `<task-notification>` as usual when it completes). A line at the bottom reports the result. The parent session's model does not know you talked to the sub-agent directly; the result comes back through the completion notification.
|
|
363
|
-
- Nothing is interrupted from the view: Esc only goes back. To stop the task use `/tasks stop <id
|
|
364
|
-
- When the viewed task waits for approval the title says "awaiting approval", and the approval dialog pops up over the view as usual (with the `[task:<type>]` origin).
|
|
370
|
+
- Nothing is interrupted from the view: Esc only goes back. To stop the task use `/tasks stop <id>`; to move it to the background use `Ctrl+B` or `/tasks bg [id]`. Both work in the view's input box (the only commands the view accepts).
|
|
371
|
+
- When the viewed task waits for approval the title says "awaiting approval", and the approval dialog pops up over the view as usual (with the `[task:<type>]` origin); if its approval is docked in the bar, opening the view pops it up.
|
|
372
|
+
|
|
373
|
+
### Docked approvals of background tasks
|
|
374
|
+
|
|
375
|
+
When a background task (including one moved to the background) needs approval, it does not interrupt what you are doing:
|
|
376
|
+
|
|
377
|
+
- While the main session is running, the input box has a draft, or another overlay is open, no dialog pops up; the request is **docked**: the task's row in the agent bar says "needs approval" (yellow) and the running line shows `↓ handle approval`; the sub-task waits meanwhile.
|
|
378
|
+
- It pops up on its own once the main session is idle, the input box is empty and no overlay is open; entering the bar, selecting it and pressing Enter (opening the view) pops it up immediately.
|
|
379
|
+
- If the main session or a foreground task asks for approval while one is docked: approvals are serialized, so the docked one pops up first and theirs follow; the main session's approvals are never held back.
|
|
380
|
+
- Approvals of foreground tasks and of the main session pop up immediately as before; timeouts (deny after 10 minutes by default), aborts and unattended rules are unchanged. RPC clients receive `permission_request` as usual and decide how to present it.
|
|
365
381
|
|
|
366
382
|
Origin labels on approval boxes:
|
|
367
383
|
|
|
@@ -413,12 +429,13 @@ Requires memory to be enabled (`ama memory enable` or `--memory`, see [memory.md
|
|
|
413
429
|
|
|
414
430
|
## Startup screen
|
|
415
431
|
|
|
416
|
-
`ui.quietStartup` / `--quiet-startup`: `normal` shows
|
|
432
|
+
`ui.quietStartup` / `--quiet-startup`: `normal` shows an "AMA" logo with an info column: version, model and thinking level, directory (`~` abbreviated) and trust state, permission mode / preset / codemode, loaded context files / Skills / prompt templates / hooks, warning count and common keys. At 72 columns or wider the logo sits on the left and the info on the right; at 48–71 columns the logo is on top; below 48 columns a two-line header is shown instead (version · model · thinking / mode · directory · trust). `ui.logo: "off"` or `ui.compact` shows only the info column. The logo takes the theme's accent → user → tool colors letter by letter; ASCII mode swaps in a glyph made of `_ / \ |`. On startup a one-off "light-up" sweep plays for about a second (the glyph starts dim, a highlight band sweeps left to right, then it settles); it redraws in place and leaves no frames in the scrollback, and any key settles it at once while the key still goes to the input box. The settled frame is shown directly with `ui.animation: false`, `NO_COLOR` / a colorless terminal, a non-TTY, an embedding host (profile.host), a `CI` environment, a prompt given on the command line (`ama "…"`), a terminal shorter than 16 rows or content taller than one screen; the line interface, `-p`, RPC and ACP draw no startup header. `header` is a single line `✻ ama version · model · mode · /help` (the profile default); `silent` shows nothing. When `--resume` has no id, the model has no key, the session directory does not exist or project resources need trust, a small selection / input prompt appears before the interface starts, collapsing into one line on screen once answered.
|
|
417
433
|
|
|
418
434
|
## In tmux / Armadra terminal nodes
|
|
419
435
|
|
|
420
436
|
- Bracketed paste: enabled at startup; pasted multi-line content enters the input box as a whole (folded into a paste placeholder with the line count beyond 10 lines or 1 000 characters), and an Enter right after a paste sends directly, which suits writes from external programs.
|
|
421
437
|
- Terminal capabilities are not queried, and mouse and the Kitty keyboard protocol are not enabled, so no replies get mixed into input; tmux ≥ 3.4 passes synchronized output through, and older versions display fine too.
|
|
438
|
+
- tmux's default prefix `C-b` is taken by the tmux client: to move tasks to the background press `C-b C-b` (`send-prefix` passes it through), or `↓` into the agent bar and press `b`; entering the bar uses `↓`, which the prefix does not affect.
|
|
422
439
|
- When the window size changes the last screen is redrawn in full; history in the scrollback is unaffected.
|
|
423
440
|
- Automatic fallback: non-TTY, `TERM=dumb`, `--no-tui` or a failed terminal initialization use line mode, with the same commands and approval prompts.
|
|
424
441
|
|
|
@@ -430,8 +447,9 @@ The `ui` section of `config.json` (settable at project level too):
|
|
|
430
447
|
| ----------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
431
448
|
| `ui.theme` | `dark` | `dark` / `light` / `auto`; auto only looks at `COLORFGBG` (no terminal query) and uses dark when unsure; configuring it explicitly is recommended |
|
|
432
449
|
| `ui.ascii` | auto-detected | ASCII glyphs (`›` → `>`, `⏺` → `*`, `⎿` → `L`, box lines → `+ - \|`, a 4-frame spinner) |
|
|
433
|
-
| `ui.compact` | `false` | No blank lines between message blocks, no
|
|
434
|
-
| `ui.
|
|
450
|
+
| `ui.compact` | `false` | No blank lines between message blocks, no logo in the startup header |
|
|
451
|
+
| `ui.logo` | `auto` | The "AMA" logo in the startup header; `off` shows only the info column |
|
|
452
|
+
| `ui.animation` | `true` | `false`: the spinner stays still as `·` while running and redraws only when seconds change; the startup logo does not animate |
|
|
435
453
|
| `ui.markdown` | `true` | `false`: assistant text is not rendered as Markdown |
|
|
436
454
|
| `ui.showThinking` | `collapsed` | See "Layout" |
|
|
437
455
|
| `ui.quietStartup` | `normal` | See "Startup screen" |
|
|
@@ -505,29 +523,29 @@ tui.setFocus(editor);
|
|
|
505
523
|
tui.start();
|
|
506
524
|
```
|
|
507
525
|
|
|
508
|
-
| Export | Purpose
|
|
509
|
-
| ------------------------------------------------------------------------- |
|
|
510
|
-
| `Component`, `Focusable`, `CURSOR_MARKER` | The component contract: `render(width)` returns lines (each with visible width ≤ width), `handleInput?(data)`, `invalidate()`; the focused component emits `CURSOR_MARKER` at the cursor
|
|
511
|
-
| `TUI` | Root container and differential rendering (main screen, synchronized output): `addChild`, `start` / `stop`, `requestRender`, `setFocus`, `addInputListener`, `showOverlay`
|
|
512
|
-
| `ProcessTerminal`, `MemoryTerminal`, `VirtualScreen` | A real terminal (raw mode, bracketed paste); an in-memory terminal and a VT screen (tests, frame goldens)
|
|
513
|
-
| `Container`, `Text`, `TruncatedText`, `Markdown`, `Box`, `Card`, `Spacer` | Basic components; `Card` is a left-bar card, `Box` accepts `borderColor`
|
|
514
|
-
| `Loader` | Running indicator: `setVerb(verb, extras, { elapsed })
|
|
515
|
-
| `Editor`, `EditorBuffer`, `PasteStore` | Multi-line editor (history, the `AutocompleteProvider` completion interface, paste folding)
|
|
516
|
-
| `SelectList` | Filterable selection list: groups, badges, number keys, `stacked`, `currentValue` (✓), `footer` key hints
|
|
517
|
-
| `KeyValue`, `Meter` | Two-column aligned key-value table (`wrap` wraps aligned to the value column); a meter (`levelColor` threshold coloring)
|
|
518
|
-
| `compositeOverlays`, `OverlayOptions` | Overlay compositing (centered / bottom-anchored)
|
|
519
|
-
| `createTheme`, `plainTheme`, `detectCapabilities`, `Theme` | Themes and color capability detection (`NO_COLOR`, 16 / 256 / truecolor); 14 semantic colors, `resolveThemeName("auto")`
|
|
520
|
-
| `Theme.glyphs`, `UNICODE_GLYPHS`, `ASCII_GLYPHS`, `detectAscii` | Glyph tables (`›` `⏺` `⎿` `✻` `▎`, box lines, spinner frames …) with ASCII fallback; `createTheme(name, { ascii })`
|
|
521
|
-
| `Keybindings`, `DEFAULT_KEYBINDINGS`, `loadKeybindingsFile` | Action id → keys, overridden by `keybindings.json`
|
|
522
|
-
| `parseKey`, `matchesKey`, `StdinBuffer` | Key sequence parsing and Esc timeout splitting (`AMA_TUI_ESC_TIMEOUT`)
|
|
523
|
-
| `visibleWidth`, `truncateToWidth`, `wrapTextWithAnsi`, `sliceByColumn` … | Width computation and truncation aware of ANSI and wide characters
|
|
526
|
+
| Export | Purpose |
|
|
527
|
+
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
528
|
+
| `Component`, `Focusable`, `CURSOR_MARKER` | The component contract: `render(width)` returns lines (each with visible width ≤ width), `handleInput?(data)`, `invalidate()`; the focused component emits `CURSOR_MARKER` at the cursor |
|
|
529
|
+
| `TUI` | Root container and differential rendering (main screen, synchronized output): `addChild`, `start` / `stop`, `requestRender`, `setFocus`, `addInputListener`, `showOverlay` |
|
|
530
|
+
| `ProcessTerminal`, `MemoryTerminal`, `VirtualScreen` | A real terminal (raw mode, bracketed paste); an in-memory terminal and a VT screen (tests, frame goldens) |
|
|
531
|
+
| `Container`, `Text`, `TruncatedText`, `Markdown`, `Box`, `Card`, `Spacer` | Basic components; `Card` is a left-bar card, `Box` accepts `borderColor` |
|
|
532
|
+
| `Loader` | Running indicator: `setVerb(verb, extras, { elapsed, optional })` (`optional` extras are dropped whole when the line does not fit), `frame` / `onFrame` (changes glyph in the same frame as other components), `animation: false` |
|
|
533
|
+
| `Editor`, `EditorBuffer`, `PasteStore` | Multi-line editor (history, the `AutocompleteProvider` completion interface, paste folding) |
|
|
534
|
+
| `SelectList` | Filterable selection list: groups, badges, number keys, `stacked`, `currentValue` (✓), `footer` key hints |
|
|
535
|
+
| `KeyValue`, `Meter` | Two-column aligned key-value table (`wrap` wraps aligned to the value column); a meter (`levelColor` threshold coloring) |
|
|
536
|
+
| `compositeOverlays`, `OverlayOptions` | Overlay compositing (centered / bottom-anchored) |
|
|
537
|
+
| `createTheme`, `plainTheme`, `detectCapabilities`, `Theme` | Themes and color capability detection (`NO_COLOR`, 16 / 256 / truecolor); 14 semantic colors, `resolveThemeName("auto")` |
|
|
538
|
+
| `Theme.glyphs`, `UNICODE_GLYPHS`, `ASCII_GLYPHS`, `detectAscii` | Glyph tables (`›` `⏺` `⎿` `✻` `▎`, box lines, spinner frames …) with ASCII fallback; `createTheme(name, { ascii })` |
|
|
539
|
+
| `Keybindings`, `DEFAULT_KEYBINDINGS`, `loadKeybindingsFile` | Action id → keys, overridden by `keybindings.json` |
|
|
540
|
+
| `parseKey`, `matchesKey`, `StdinBuffer` | Key sequence parsing and Esc timeout splitting (`AMA_TUI_ESC_TIMEOUT`) |
|
|
541
|
+
| `visibleWidth`, `truncateToWidth`, `wrapTextWithAnsi`, `sliceByColumn` … | Width computation and truncation aware of ANSI and wide characters |
|
|
524
542
|
|
|
525
543
|
## Testing
|
|
526
544
|
|
|
527
545
|
Frame goldens all live in `test/fixtures/tui/`; `MemoryTerminal` reconstructs the screen (without color, verifying only layout and glyphs):
|
|
528
546
|
|
|
529
547
|
- `src/modes/interactive/interactive-mode.test.ts`: a complete read-file run at 80x24 and 40x24 (startup, input, tool running, finish, `Ctrl+O` expand, exit summary) → `run-*.txt`; approvals, cache notices and more.
|
|
530
|
-
- `src/modes/interactive/interactive-frames.test.ts`: startup headers (`startup-normal-*`, `header-quiet-*`), tool hierarchy (`tools-*`), notices (`notices-*`), running verbs (`loader-verbs-*`), the `/session` panel (`panel-session-*`), a whole run in ASCII mode (`ascii-run-*`).
|
|
548
|
+
- `src/modes/interactive/interactive-frames.test.ts`: startup headers (`startup-normal-*`, `header-quiet-*`; logo variants and the animation in `startup-logo.test.ts` / `startup-logo-*`), tool hierarchy (`tools-*`), notices (`notices-*`), running verbs (`loader-verbs-*`), the `/session` panel (`panel-session-*`), a whole run in ASCII mode (`ascii-run-*`).
|
|
531
549
|
- Wave 5 (W5-U): `plan-dialog.test.ts` (`plan-dialog-*`: four options, execution mode, feedback, external editor, ASCII, 40 columns), `approval-origin.test.ts` (`approval-origin-*`, `approval-task-agent-*`, `approval-first-run-*`, `approval-task-external-*` and the first-run merge), `subagent-view.test.ts` (`subagent-view-*`), `tasks-panel.test.ts` (`tasks-picker-*`, `tasks-output-*`, `agents-panel-*`), `harness-notices.test.ts` (`harness-notices-*`), `interactive-w5.test.ts` (plan → approval → execution, `/plan`, background tasks into `/tasks`, Ctrl+V; `interactive-plan-*`, `interactive-tasks-*`).
|
|
532
550
|
- `src/tui/tui-frames.test.ts`: component level (conversation, Markdown, editor placeholder / multi-line / paste / completion); `status-widths.txt` of `status-bar.test.ts`; approvals and mode pickers in `approval-dialog.test.ts` and `pickers.test.ts`.
|
|
533
551
|
|
package/docs/host-api.md
CHANGED
|
@@ -159,4 +159,8 @@ interface WarmDecision {
|
|
|
159
159
|
|
|
160
160
|
## 嵌入 Armadra
|
|
161
161
|
|
|
162
|
-
Armadra 用 profile 启动 ama:`ama --profile <path>`,profile 的 `host` 指向它的适配器(`ama-armadra.cjs`),另带 instructions、skillDirs、hooksFile、authFile、sessionDir、`trustProject`。适配器在 `ARMADRA_NODE_ID` 缺失时返回 `undefined`,同一个 profile 在画布外退化为普通 ama
|
|
162
|
+
Armadra 用 profile 启动 ama:`ama --profile <path>`,profile 的 `host` 指向它的适配器(`ama-armadra.cjs`),另带 instructions、skillDirs、hooksFile、authFile、sessionDir、`trustProject`。适配器在 `ARMADRA_NODE_ID` 缺失时返回 `undefined`,同一个 profile 在画布外退化为普通 ama。
|
|
163
|
+
|
|
164
|
+
有 profile 时的界面缺省:`ui.quietStartup: "header"`、`ui.statusLine: "compact"`(最后一行是状态栏,宿主按 `·` 解析)。Agent 栏(`ui.agentBar`)不再缺省关闭,与独立终端一样是 `auto`;宿主自己展示子任务、不要栏时在 profile 的 `config` 指向的配置文件里写 `{ "ui": { "agentBar": "off" } }`。
|
|
165
|
+
|
|
166
|
+
契约细节见 Armadra 仓库 [docs/design/coordinator-agent.md](https://github.com/yovinchen/Armadra/blob/main/docs/design/coordinator-agent.md)。
|
package/docs/providers.md
CHANGED
|
@@ -185,14 +185,27 @@ ama auth logout chatgpt # siwc 先撤销 refresh token 再删本
|
|
|
185
185
|
| 配额 | 只在超限(429)时可知;在 ChatGPT → 设置 → Usage → App limits 给 ama 设周上限 | 响应头、`codex.rate_limits` 事件、`ama auth status` 查 `wham/usage` |
|
|
186
186
|
| 登出 | 调 `revocation_endpoint` 撤销,再删本地 | 只删本地 |
|
|
187
187
|
|
|
188
|
-
**模型列表**:`chatgpt` 没有内置模型表(`chatgpt/<slug>` 任意接受)。`ama auth login chatgpt`
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
chatgpt
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
188
|
+
**模型列表**:`chatgpt` 没有内置模型表(`chatgpt/<slug>` 任意接受)。`ama auth login chatgpt` 成功后先删旧缓存,再调一次
|
|
189
|
+
模型列表接口(siwc `GET /v1/models`、codex `GET /models?client_version=…`,只读、不消耗额度;失败静默,改提示
|
|
190
|
+
`ama models discover chatgpt`),把账户可用的 slug 与显示名连同 flavor、时间戳缓存到
|
|
191
|
+
`<dataDir>/models/discovered/chatgpt.json`——返回 0 个也写空表,免得残留另一种登录方式的缓存;`ama models discover
|
|
192
|
+
chatgpt` 也重写这份缓存,`ama auth logout chatgpt` 删掉它。组装注册表时缓存并入模型表为空的供应商,后端给的上下文窗口、
|
|
193
|
+
输入模态、推理强度(codex 后端给;siwc 条目带了也取)存进缓存并优先于 models.dev 快照——订阅后端的生效窗口(如 272k)
|
|
194
|
+
可能远小于 models.dev 记的 API 版窗口,压缩阈值按后端窗口算;后端没给的字段(输出上限等)用 models.dev 补,两边都没有
|
|
195
|
+
上下文窗口时按保守缺省 128k。旧版本写的缓存不含窗口就照旧用 models.dev,重新 `ama models discover chatgpt` 即刷新。`/model` 选择器、
|
|
196
|
+
`ama models list` 照常列出;缓存的 flavor 与当前登录不符时视为过期、不并入(选择器提示重新发现)。缓存里没有的 slug
|
|
197
|
+
仍可 `--model chatgpt/<slug>` 使用。
|
|
198
|
+
|
|
199
|
+
**codex 的 `client_version`**:codex 后端按 `client_version` 过滤模型(每个模型有最低客户端版本,不带参数报 400),
|
|
200
|
+
ama 发的是 Codex CLI 的版本号(缺省 `0.160.0`),而不是 ama 自己的版本。登录或 discover 时 codex 返回 0 个模型,多半是
|
|
201
|
+
这个版本过旧:用 `ama config set auth.chatgpt.codexClientVersion <版本>`(用户级)或环境变量
|
|
202
|
+
`AMA_CHATGPT_CODEX_CLIENT_VERSION`(优先)设成较新的 Codex CLI 版本,再 `ama models discover chatgpt`。推理请求不带版本号。
|
|
203
|
+
|
|
204
|
+
**渠道跟随登录方式**:`chatgpt` 的缺省渠道在组装时按 auth.json 条目的 flavor 决定;此外每次请求按当次 token 所属的
|
|
205
|
+
flavor 选渠道——模型引用没写 `@渠道` 时自动用当前登录方式的渠道(端点、`originator` 等渠道头、请求体白名单一起换),
|
|
206
|
+
所以运行中的会话在 `ama auth logout` 后换另一种方式登录,下一次请求就走新渠道,不用重启;恢复会话时,会话里记录的渠道
|
|
207
|
+
也不算显式。只有显式写了 `provider/model@siwc|codex` 且与登录方式不符时才报 `chatgpt_flavor_mismatch`(提示去掉
|
|
208
|
+
`@渠道` 或换登录方式)。
|
|
196
209
|
|
|
197
210
|
**凭据**:auth.json 的 `{ "type": "oauth", … }` 条目(文件 0600),`ama auth list` 只显示 `oauth · <flavor> · <计划>`。
|
|
198
211
|
access token 剩余不到 5 分钟或请求返回 401 时自动刷新;多个 ama 进程(画布上的多个节点)共享一个 auth.json,刷新经
|
|
@@ -214,15 +227,19 @@ developer 消息(前缀依然稳定)。compat `toolsInNamespace: true` 时
|
|
|
214
227
|
| ---------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
215
228
|
| `quota_exceeded` | siwc 429 `subscription_sharing_usage_limit_exceeded`;codex 429 `usage_limit_reached` / `usage_not_included` | 不重试;附重置时间并发 `quota_update` |
|
|
216
229
|
| `auth_expired` | 401 刷新一次仍失败、刷新永久失败、条目 `needsLogin` | 不重试;重新 `ama auth login chatgpt` |
|
|
217
|
-
| `not_eligible` | siwc 403 `subscription_sharing_user_not_eligible` |
|
|
230
|
+
| `not_eligible` | siwc 403 `subscription_sharing_user_not_eligible` | 不重试、不重登;排查见下 |
|
|
218
231
|
| (原样) | 503 等 | 走会话层现有的退避重试 |
|
|
219
232
|
|
|
233
|
+
**`not_eligible` 排查**:账户不能把套餐额度共享给 ama。可能的原因:账户套餐(额度共享只对 Plus / Pro 开放);工作空间
|
|
234
|
+
账户(Team / Enterprise / Edu 可能未开放);地区受限或预览期尚未开放——**Pro 账户仍报此错时最可能是这一条**。可以改用
|
|
235
|
+
`ama auth login chatgpt --flavor codex`。siwc 登录成功只说明授权通过,能否共享额度要到首次请求才能确认。
|
|
236
|
+
|
|
220
237
|
**用量**:订阅请求 `usage.cost = 0` 并标 `billing: "subscription"`;`/session` 单列「订阅用量」(请求数、token、
|
|
221
238
|
缓存命中率,不折算美元)与最近一次配额;事件 `quota_update`(RPC 原样转发,宿主事件同名)。
|
|
222
239
|
|
|
223
|
-
**覆盖**(测试或将来换自有客户端用):`auth.chatgpt.clientId` / `issuer` / `originator` / `
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
**覆盖**(测试或将来换自有客户端用):`auth.chatgpt.clientId` / `issuer` / `originator` / `codexClientVersion` /
|
|
241
|
+
`redirectPorts`(只认用户级与 profile),环境变量 `AMA_CHATGPT_CLIENT_ID`、`AMA_CHATGPT_ISSUER`、`AMA_CHATGPT_BASE_URL`
|
|
242
|
+
(改当前 flavor 渠道的地址)、`AMA_CHATGPT_CODEX_CLIENT_VERSION`。
|
|
226
243
|
|
|
227
244
|
**嵌入宿主**:有 profile 时 ama 不发起交互式登录;用到 `chatgpt` 而登录失效时请求报 `auth_expired`,由宿主引导用户
|
|
228
245
|
在终端执行 `ama auth login chatgpt --paste`。宿主不读、不存、不转发 token,只消费 `quota_update` 与
|
package/docs/rpc.md
CHANGED
|
@@ -159,7 +159,17 @@
|
|
|
159
159
|
- 整个 `data` 都经过脱敏;节点里只有 id、时间、计数与用量,正文只在 `previews` 里。运行中没有结果的工具标 `running`。
|
|
160
160
|
- 错误:`invalid_arguments`(参数越界、`before` 不是本分支的回合 id、`before` 与 `since` 同用)、`task_not_found`。
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
### 后台子 Agent(第七波)
|
|
163
|
+
|
|
164
|
+
| 命令 | 参数 | `data` |
|
|
165
|
+
| ----------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
166
|
+
| `background_task` | `taskId?` | `{ backgrounded: string[] }`:实际转了后台的 `taskId`。不给 `taskId` = 全部前台运行中任务;已结束、已在后台或不存在的任务回空表;`taskId` 不是字符串 → `invalid_arguments` |
|
|
167
|
+
|
|
168
|
+
被转的前台任务不中断,其 `task` 调用立即以 `tool_execution_end` 返回(结果文本以 `[task tN] Moved to the background` 开头,
|
|
169
|
+
`details.status: "running"`),随后发 `subagent_background`;任务结束时照常 `subagent_end`,父会话空闲后收到 `origin: "task"`
|
|
170
|
+
的通知消息。语义与交互界面的 `Ctrl+B` 相同,见 [agents.md](agents.md)「前台与后台」。
|
|
171
|
+
|
|
172
|
+
合计 44 条命令,名字即 `RpcCommandMap` 的键。
|
|
163
173
|
|
|
164
174
|
## 事件
|
|
165
175
|
|
|
@@ -204,11 +214,12 @@
|
|
|
204
214
|
|
|
205
215
|
`task` / `task_ctl` 起的子 Agent(ama 子会话与外部 Agent 同一组事件,见 [agents.md](agents.md)「子 Agent」):
|
|
206
216
|
|
|
207
|
-
| 事件
|
|
208
|
-
|
|
|
209
|
-
| `subagent_start`
|
|
210
|
-
| `subagent_update`
|
|
211
|
-
| `
|
|
217
|
+
| 事件 | 字段 |
|
|
218
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
219
|
+
| `subagent_start` | `taskId`、`parentToolCallId`、`agent`、`runner`(`ama` / `claude` / `codex` / `acp:<程序>`)、`description`、`background`、`model?`、`sessionFile?`、`cwd`;同一 `taskId` 续聊时再发一次 |
|
|
220
|
+
| `subagent_update` | `taskId`、`kind: tool \| text \| turn`、`toolName?`、`textDelta?`(≥ 250 ms 合并)、`turn`、`usage?` |
|
|
221
|
+
| `subagent_background` | `taskId`、`parentToolCallId`、`reason: user \| timeout \| host`(前台任务转后台:交互界面手动、`subagents.autoBackgroundAfterMs` 到时、RPC / SDK 调用;第七波) |
|
|
222
|
+
| `subagent_end` | `taskId`、`status: completed \| failed \| aborted \| max_turns \| interrupted`、`usage?`、`cache?`、`outputFile?`、`worktree?: { branch, changed }` |
|
|
212
223
|
|
|
213
224
|
子会话与外部 Agent 的审批照常以 `permission_request` 发给本连接,`context`(可选)标出来源(第六波起本会话工具调用的审批也带
|
|
214
225
|
`context.toolCallId`——触发审批的工具调用 id,轨迹据此算审批等待;外部 Agent 的请求不带):
|
|
@@ -225,7 +236,8 @@
|
|
|
225
236
|
只有类型目录,见 `cachedAgentInfos`,`src/agents/external.ts`)。
|
|
226
237
|
`test/fixtures/rpc/subagent.out.jsonl` 是一次前台 `task(agent="explore")` 加 `get_tasks` / `get_agents` 的黄金记录(只保留
|
|
227
238
|
响应、`tool_execution_*`、`subagent_*` 与 `agent_settled`),由
|
|
228
|
-
`src/agent/subagent-rpc.test.ts` 用 `UPDATE_GOLDEN=1`
|
|
239
|
+
`src/agent/subagent-rpc.test.ts` 用 `UPDATE_GOLDEN=1` 更新。`test/fixtures/rpc/background.out.jsonl` 是前台 `task` 运行中
|
|
240
|
+
`background_task` 转后台、随后任务结束并投递通知回合的黄金记录,由 `src/modes/rpc/rpc-background.test.ts` 更新。
|
|
229
241
|
|
|
230
242
|
### 速率遥测(第五波)
|
|
231
243
|
|
package/docs/sessions.md
CHANGED
|
@@ -46,7 +46,8 @@ packy/deepseek-v4-flash 1 3 1 4.6k 980 2k 0 30.8
|
|
|
46
46
|
| 错误 / 重试 | `stopReason: "error"` 的 assistant;`context_edit{reason:"retry"}`(自动重试剔除的失败尝试) |
|
|
47
47
|
| 渠道 | 最近一条 `model_change` 与请求同 provider / model 时取它的 `channel` |
|
|
48
48
|
|
|
49
|
-
`task` 子会话是独立文件,按它自己的 cwd
|
|
49
|
+
`task` 子会话是独立文件,按它自己的 cwd 计入。后台任务完成后父会话里的通知消息(`origin: "task"`)同样开启一个回合,
|
|
50
|
+
按父会话计入;`-p` 等后台任务时(见 [agents.md](agents.md)「前台与后台」)这些通知回合也写进同一个会话文件。
|
|
50
51
|
|
|
51
52
|
### 性能与索引
|
|
52
53
|
|