@aragon-agent/cli 0.6.15 → 0.6.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -71
- package/dist/agent/controller.d.ts +10 -0
- package/dist/agent/controller.js +52 -47
- package/dist/agent/reducer.js +0 -4
- package/dist/cli.js +49 -15
- package/dist/commands/builtins.js +27 -43
- package/dist/compaction/child.d.ts +10 -8
- package/dist/compaction/child.js +23 -25
- package/dist/compaction/context-command.js +14 -3
- package/dist/compaction/limits.d.ts +0 -2
- package/dist/compaction/limits.js +0 -2
- package/dist/compaction/types.d.ts +6 -1
- package/dist/config/app-paths.d.ts +10 -0
- package/dist/config/app-paths.js +12 -0
- package/dist/config/cli-commands.d.ts +1 -1
- package/dist/config/cli-commands.js +16 -15
- package/dist/config/env.d.ts +2 -1
- package/dist/config/env.js +13 -1
- package/dist/config/load.d.ts +9 -17
- package/dist/config/load.js +14 -6
- package/dist/config/model-windows.d.ts +91 -0
- package/dist/config/model-windows.js +181 -0
- package/dist/config/schema.d.ts +34 -5
- package/dist/config/schema.js +15 -11
- package/dist/exec/events.d.ts +12 -8
- package/dist/exec/events.js +2 -2
- package/dist/exec/runner.js +4 -1
- package/dist/fast/limits.d.ts +2 -2
- package/dist/fast/limits.js +2 -2
- package/dist/fast/prompt.d.ts +10 -11
- package/dist/fast/prompt.js +19 -20
- package/dist/fast/reviewer.d.ts +1 -1
- package/dist/fast/reviewer.js +1 -1
- package/dist/fast/types.d.ts +0 -2
- package/dist/fast/wiring.d.ts +18 -34
- package/dist/fast/wiring.js +20 -51
- package/dist/input/csiu-keys.d.ts +66 -0
- package/dist/input/csiu-keys.js +170 -0
- package/dist/input/keyboard-enhancement.d.ts +42 -0
- package/dist/input/keyboard-enhancement.js +65 -0
- package/dist/input/stdin-filter.d.ts +9 -0
- package/dist/input/stdin-filter.js +45 -9
- package/dist/input/win32-input-mode.d.ts +61 -0
- package/dist/input/win32-input-mode.js +251 -0
- package/dist/session/validate-session.js +3 -1
- package/dist/team/child-reviewer.d.ts +105 -0
- package/dist/team/child-reviewer.js +117 -0
- package/dist/team/normalize.d.ts +7 -26
- package/dist/team/normalize.js +9 -22
- package/dist/team/prompt.d.ts +0 -11
- package/dist/team/prompt.js +3 -12
- package/dist/team/report.d.ts +4 -19
- package/dist/team/report.js +1 -27
- package/dist/team/runtime.d.ts +5 -10
- package/dist/team/runtime.js +35 -39
- package/dist/team/subagent.d.ts +18 -18
- package/dist/team/subagent.js +80 -30
- package/dist/team/task-tool.d.ts +6 -26
- package/dist/team/task-tool.js +13 -47
- package/dist/team/types.d.ts +3 -42
- package/dist/ui/App.js +3 -4
- package/dist/ui/BottomStatusRow.js +2 -1
- package/dist/ui/StatusBar.js +2 -1
- package/dist/ui/TeamPanel.js +1 -1
- package/dist/ui/entries/TeamCard.js +1 -6
- package/dist/ui/layout/status-detail-layout.js +12 -2
- package/dist/ui/layout/status-layout.d.ts +4 -2
- package/dist/ui/layout/status-layout.js +24 -1
- package/dist/ui/overlays/HelpOverlay.js +1 -2
- package/package.json +2 -2
- package/dist/ui/ModeChip.d.ts +0 -18
- package/dist/ui/ModeChip.js +0 -24
package/README.md
CHANGED
|
@@ -409,7 +409,7 @@ signal ends the run (`130` SIGINT, `143` SIGTERM, `129` SIGHUP).
|
|
|
409
409
|
| `/team [on\|off\|max <n>]` | Team subagents: status and the live roster, the on/off switch, the fan-out width |
|
|
410
410
|
| `/todo [on\|off\|panel on\|off\|follow <mode>\|clear\|continue]` | Todo planning: status, the on/off switch, the rail, follow-through, and picking an unfinished plan back up |
|
|
411
411
|
| `/retry [show\|on\|off\|max <n>]` | API retry: the effective ladder, the on/off switch, the retry count. Takes effect **in the running session**, children included |
|
|
412
|
-
| `/fast [on\|off\|model <id>\|provider <id>\|same\|review <n\|off
|
|
412
|
+
| `/fast [on\|off\|model <id>\|provider <id>\|same\|review <n\|off>]` | Fast model tier: status and this session's totals, the on/off switch, which model, the review cadence |
|
|
413
413
|
| `/compact [status\|on\|off\|threshold <n>\|keep <n>\|history\|show <n>\|<instructions>]` | Context compaction: occupancy and this session's totals, the on/off switch, when it fires, how much it keeps. With free text, compacts now and tells the summarizer what to pay attention to |
|
|
414
414
|
| `/context` | What the context gauge is showing: occupancy split into measured and estimated, the window and **where it came from**, how stale the measurement is, compaction's actual state, and what the session-spend readout includes |
|
|
415
415
|
| `/bg [list\|logs <id> [n]\|stop <id\|all>\|status]` | Background services: what is running, its log tail, and how to stop it. `list` is the default |
|
|
@@ -433,7 +433,7 @@ completes, `Up` / `Down` moves the selection, `Esc` closes it.
|
|
|
433
433
|
| Key | Action |
|
|
434
434
|
| --- | --- |
|
|
435
435
|
| `Enter` | 空闲时发送,运行时加入队列;收到 Core 已纳入会话的接收凭据后才移除 Queue 提示 |
|
|
436
|
-
| `Ctrl+J` / `Alt+Enter` / `Shift+Enter` |
|
|
436
|
+
| `Ctrl+J` / `Alt+Enter` / `Shift+Enter` | 插入换行。应用默认请求终端区分修饰键(Windows 用 win32-input-mode,macOS/Linux 用 kitty/modifyOtherKeys),Shift+Enter 在支持的终端开箱即用;不支持的终端用 Ctrl+J。参见 [终端设置](#terminal-setup-for-shiftenter) |
|
|
437
437
|
| `Shift+Tab` | Toggle **plan mode** (`BUILD` <-> `PLAN`). Equivalent: `/plan`. On Windows this needs a console flag Node < 22.17 does not set; aragon sets it at startup — see [Requirements](#requirements) |
|
|
438
438
|
| `Ctrl+P` | The same toggle, over a channel no Windows console can swallow. Use it if `Shift+Tab` does nothing |
|
|
439
439
|
| `Esc` | Close an overlay or popup; otherwise ask for interruption confirmation. While idle, cancel pending auto-continuation |
|
|
@@ -490,10 +490,13 @@ is what it used to do. Inline mode is unaffected either way.
|
|
|
490
490
|
|
|
491
491
|
## Terminal setup for Shift+Enter
|
|
492
492
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
493
|
+
应用现在会主动请求终端区分修饰键:Windows 上推送 win32-input-mode(conhost 与
|
|
494
|
+
Windows Terminal 均支持),macOS/Linux 上推送 kitty disambiguate 与
|
|
495
|
+
`modifyOtherKeys=2`(iTerm2、kitty、ghostty、WezTerm、foot、Alacritty 实现其一),
|
|
496
|
+
并在 stdin 过滤器里把新编码翻译回传统字节,Ink 的按键解析不受影响。上述推送不满足时
|
|
497
|
+
(macOS Terminal.app、旧 Node 下的 conhost、或不支持任何协议的终端)Shift+Enter 仍与
|
|
498
|
+
Enter 同为 CR,此时用 `Ctrl+J` 换行,或按 `/terminal-setup` 给终端加一条让
|
|
499
|
+
Shift+Enter 发送 `\u001b[13;2u` 的绑定(合并进已有配置,不要覆盖其他快捷键)。参考绑定如下:
|
|
497
500
|
|
|
498
501
|
- **Windows Terminal** — `settings.json` 的 `actions` 与 `keybindings` 分别定义动作和按键;完整示例见下文“输入、待处理队列与底部状态区”。
|
|
499
502
|
- **VS Code integrated terminal** — `keybindings.json`:
|
|
@@ -507,10 +510,14 @@ Shift+Enter 与 Enter 都发送为 CR,应用无法区分;请用 `/terminal-s
|
|
|
507
510
|
- **macOS Terminal.app / legacy conhost** — cannot rebind `Enter`; use
|
|
508
511
|
`Ctrl+J` or `Alt+Enter`
|
|
509
512
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
513
|
+
The push and its translation ship as one unit: `input/win32-input-mode.ts` and
|
|
514
|
+
`input/csiu-keys.ts` translate every enhanced encoding back to the legacy
|
|
515
|
+
bytes before Ink parses them, so a translated stream is byte-identical to a
|
|
516
|
+
pre-enhancement one (Enter family excepted: a modified Enter becomes the
|
|
517
|
+
newline frame). Windows additionally requires Node >= 22.17 / >= 24.2 --
|
|
518
|
+
older versions never turn on virtual-terminal input. Opt out with
|
|
519
|
+
`aragon config set keyboardEnhancement false`, `--no-keyboard-enhancement`,
|
|
520
|
+
or `ARAGON_KEYBOARD_ENHANCEMENT=0`.
|
|
514
521
|
|
|
515
522
|
## Queued messages while the agent runs
|
|
516
523
|
|
|
@@ -803,9 +810,11 @@ still exits the session outright.
|
|
|
803
810
|
|
|
804
811
|
### Where the mode is shown
|
|
805
812
|
|
|
806
|
-
The status bar always names
|
|
807
|
-
|
|
808
|
-
|
|
813
|
+
The status bar's first row always names the current mode (`BUILD` or `PLAN`,
|
|
814
|
+
an accent word right after the run state; `PLAN>BUILD` while a switch is
|
|
815
|
+
pending; `B` / `P` / `P>B` when the terminal is narrow), including on short
|
|
816
|
+
terminals and with `--no-hints`. The Ctrl+G details row repeats it, and the
|
|
817
|
+
composer tints its border in plan mode.
|
|
809
818
|
|
|
810
819
|
### Switching mid-run
|
|
811
820
|
|
|
@@ -814,7 +823,7 @@ during a run takes effect immediately — you pressed it *because* the agent is
|
|
|
814
823
|
about to do something. Pressing it toward `BUILD` during a run is **deferred to
|
|
815
824
|
the end of the run**, so a session you launched under a read-only guarantee
|
|
816
825
|
cannot start writing files because of one stray keypress. The status bar shows
|
|
817
|
-
`PLAN
|
|
826
|
+
`PLAN>BUILD` while that is pending. Approving a plan is the one exception, and
|
|
818
827
|
it is an informed act rather than a stray keypress.
|
|
819
828
|
|
|
820
829
|
### If `Shift+Tab` does nothing
|
|
@@ -832,7 +841,7 @@ node -e "process.stdin.setRawMode(true);process.stdin.resume();process.stdin.on(
|
|
|
832
841
|
| It prints | What it means |
|
|
833
842
|
| --- | --- |
|
|
834
843
|
| `09` | The console is swallowing the modifier — the key is arriving as an ordinary `Tab`. Check `node -v`: below 22.17.0 (or on 24.0/24.1) this is expected, and aragon's own attempt to fix it was blocked. See [Requirements](#requirements) |
|
|
835
|
-
| `1b5b5a` | The key reaches the process fine, so something inside aragon is eating it — most often an overlay is open, or the run is still going and the switch is pending (the status bar shows `BUILD
|
|
844
|
+
| `1b5b5a` | The key reaches the process fine, so something inside aragon is eating it — most often an overlay is open, or the run is still going and the switch is pending (the status bar shows `PLAN>BUILD`) |
|
|
836
845
|
| nothing | Your terminal, multiplexer or remote-desktop stack never sent it; some never send `CSI Z` at all |
|
|
837
846
|
|
|
838
847
|
On the first row the wheel is dead for the same reason, and with the `/` palette
|
|
@@ -1177,25 +1186,24 @@ children's tokens are folded into the `[usage]` footer.
|
|
|
1177
1186
|
## Fast model tier
|
|
1178
1187
|
|
|
1179
1188
|
A second, cheaper model can be made a first-class citizen of a session. It is
|
|
1180
|
-
**off by default** — with `fast.enabled: false` the system prompt, the
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
**
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
*model* choice, never a permission boundary. This is where "not complicated, but
|
|
1189
|
-
very expensive in context" is actually paid for: a child that reads nine files
|
|
1190
|
-
and reports four sentences moves ~200 KB of file bodies out of the lead's window
|
|
1191
|
-
and onto a model that costs a fraction as much per token.
|
|
1189
|
+
**off by default** — with `fast.enabled: false` the system prompt, the
|
|
1190
|
+
transcript and the request payloads are exactly what they were before this
|
|
1191
|
+
feature existed — and it buys you two things once you turn it on.
|
|
1192
|
+
|
|
1193
|
+
**Every `task` child runs the lead's own model.** Per-child fast dispatch
|
|
1194
|
+
(`model: "fast"`) was removed for main-agent parity: a delegation is never a
|
|
1195
|
+
downgrade, and all the gates (tools, working directory, `--confirm`, plan mode,
|
|
1196
|
+
skills ceiling, compaction policy) are the lead's own.
|
|
1192
1197
|
|
|
1193
1198
|
**Periodic review (the harness decides).** Every *N* completed turns, a small
|
|
1194
1199
|
digest of what the lead has been doing goes to the fast model with one question
|
|
1195
1200
|
— is this still on track? — and if the answer is not "on track" it is injected
|
|
1196
1201
|
back into the running loop as a `<fast_review>` block. The lead sees a short
|
|
1197
1202
|
second opinion mid-run, when it can still act on it, for a few hundred tokens
|
|
1198
|
-
instead of a second full-size turn.
|
|
1203
|
+
instead of a second full-size turn. **Subagents get the same review**: when the
|
|
1204
|
+
tier is live and `fast.review` is on, each dispatched child runs with its own
|
|
1205
|
+
reviewer — same cadence, same budget per child, same fail-fast transport — so a
|
|
1206
|
+
team is as capable as the agent that dispatched it.
|
|
1199
1207
|
|
|
1200
1208
|
```
|
|
1201
1209
|
> refactor the config loader and keep the tests green
|
|
@@ -1217,7 +1225,7 @@ separately. If the fast model is not in the built-in price table the number is
|
|
|
1217
1225
|
shown as `unknown` rather than as `$0.00` — a feature that looks free while it
|
|
1218
1226
|
is spending money is worse than one that admits it does not know.
|
|
1219
1227
|
|
|
1220
|
-
**The review has a session budget
|
|
1228
|
+
**The review has a session budget.** A
|
|
1221
1229
|
session is not one run — it is one run per message you send — so a cadence alone
|
|
1222
1230
|
bounds nothing over a working afternoon. `fast.reviewMaxPerSession` (default
|
|
1223
1231
|
**40**) is the total number of reviews a session may *start*; reaching it prints
|
|
@@ -1226,9 +1234,7 @@ first review rather than a bare count you can only size afterwards. Raise it liv
|
|
|
1226
1234
|
with `/fast budget 80`. The budget is denominated in **reviews, not currency**,
|
|
1227
1235
|
because the fast tier is precisely where a model the price table has never seen
|
|
1228
1236
|
lives — a dollar ceiling would silently never fire for the configuration that
|
|
1229
|
-
most needs one.
|
|
1230
|
-
service of a message you sent, it is already bounded by `team.*`, and it exists
|
|
1231
|
-
to *reduce* total cost.
|
|
1237
|
+
most needs one.
|
|
1232
1238
|
|
|
1233
1239
|
### Turning it on
|
|
1234
1240
|
|
|
@@ -1248,9 +1254,8 @@ cannot grow a field mid-session.
|
|
|
1248
1254
|
| `fast.provider` | `''` | Empty inherits the main provider. |
|
|
1249
1255
|
| `fast.model` | `''` | The fast model id. Empty means *not configured* — it never falls back to the main model, so "same as main" stays distinguishable from a typo. |
|
|
1250
1256
|
| `fast.baseUrl` | `''` | Empty inherits the session's base URL **only** when the provider matches. |
|
|
1251
|
-
| `fast.thinkingLevel` | `'off'` | Applied to
|
|
1252
|
-
| `fast.
|
|
1253
|
-
| `fast.review` | `true` | Run the periodic review. |
|
|
1257
|
+
| `fast.thinkingLevel` | `'off'` | Applied to reviews (lead and subagents) and to fast-tier compaction summaries. |
|
|
1258
|
+
| `fast.review` | `true` | Run the periodic review — for the lead and for every `task` child. |
|
|
1254
1259
|
| `fast.reviewEveryTurns` | `5` | Turns between reviews (1–50). |
|
|
1255
1260
|
| `fast.reviewContextTurns` | `3` | Turns included in one digest (1–10). |
|
|
1256
1261
|
| `fast.reviewMaxChars` | `280` | Ceiling on an injected critique (80–600). |
|
|
@@ -1274,7 +1279,6 @@ reporting one:
|
|
|
1274
1279
|
/fast same run the fast tier on the main model
|
|
1275
1280
|
/fast review <n> | off
|
|
1276
1281
|
/fast budget [n] the session review budget; bare form reads it
|
|
1277
|
-
/fast delegate on | off
|
|
1278
1282
|
```
|
|
1279
1283
|
|
|
1280
1284
|
`/fast budget` with no argument is a **read**, so it is answerable while a `task`
|
|
@@ -1283,9 +1287,8 @@ like every other `/fast` setting.
|
|
|
1283
1287
|
|
|
1284
1288
|
**What you see.** A `fast` chip in the status bar's right cluster while the tier
|
|
1285
1289
|
is live (`fast*` while a review is in flight, dropped below 100 columns), a
|
|
1286
|
-
one-line card per review in the transcript
|
|
1287
|
-
|
|
1288
|
-
status bar cannot: reviews run, children delegated, tokens and cost. Under `-p`
|
|
1290
|
+
one-line card per review in the transcript. `/fast status` reports the session totals the
|
|
1291
|
+
status bar cannot: reviews run, tokens and cost. Under `-p`
|
|
1289
1292
|
nothing extra is written to stdout or stderr — the review spend is folded into
|
|
1290
1293
|
the `[usage]` footer and the reviews are in the log.
|
|
1291
1294
|
|
|
@@ -1353,7 +1356,8 @@ Context
|
|
|
1353
1356
|
```
|
|
1354
1357
|
|
|
1355
1358
|
Two lines are worth reading closely. **`Window`** always names where the number
|
|
1356
|
-
came from — the model API, the model table, your own `contextWindow`,
|
|
1359
|
+
came from — the model API, the model table, your own `contextWindow`, a
|
|
1360
|
+
`model-windows.json` entry, or the invented
|
|
1357
1361
|
placeholder — because those are indistinguishable everywhere else. And
|
|
1358
1362
|
**`Compaction`** reports what is actually true of this session, including
|
|
1359
1363
|
`off - not registered for this session (started with --no-compaction)`; it never
|
|
@@ -1361,8 +1365,9 @@ promises a threshold that nothing will act on.
|
|
|
1361
1365
|
|
|
1362
1366
|
### `contextWindow`
|
|
1363
1367
|
|
|
1364
|
-
Window resolution uses your explicit override first, then
|
|
1365
|
-
|
|
1368
|
+
Window resolution uses your explicit override first, then per-model declarations
|
|
1369
|
+
in `model-windows.json`, then API metadata from the configured endpoint, then the
|
|
1370
|
+
built-in catalog (including known aliases and dated
|
|
1366
1371
|
snapshots). Startup, connection changes, and subsequent prompts refresh discovery
|
|
1367
1372
|
in the background, with a five-minute cache. OpenAI-compatible endpoints may expose
|
|
1368
1373
|
`context_length` or `context_window`; Anthropic uses `max_input_tokens`; Google uses
|
|
@@ -1384,6 +1389,33 @@ Values are clamped to `[8000, 5000000]`; `auto` (the default) is stored as
|
|
|
1384
1389
|
and `/context` still shows that it came from you, which is what makes a wrong
|
|
1385
1390
|
value findable.
|
|
1386
1391
|
|
|
1392
|
+
#### `model-windows.json` — one window per model
|
|
1393
|
+
|
|
1394
|
+
`contextWindow` describes ONE model: the active one. To pin several at once — a
|
|
1395
|
+
main model plus a fast tier plus a gateway alias — declare them by id in
|
|
1396
|
+
`~/.aragon-agent/model-windows.json`:
|
|
1397
|
+
|
|
1398
|
+
```json
|
|
1399
|
+
{
|
|
1400
|
+
"version": 1,
|
|
1401
|
+
"windows": {
|
|
1402
|
+
"kimi-k3": 1048576,
|
|
1403
|
+
"glm-5.3": 1048576,
|
|
1404
|
+
"glm-5.3-flash": 1048576
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
```
|
|
1408
|
+
|
|
1409
|
+
A bare map without the wrapper works too. Keys are matched case-insensitively
|
|
1410
|
+
after stripping a `models/`-style prefix and a dated snapshot suffix, so
|
|
1411
|
+
`Kimi-K3-20260716` still resolves. Entries must be whole tokens between 1024 and
|
|
1412
|
+
1e9; at most 512 are kept. The file is read live (mtime-cached), never written
|
|
1413
|
+
by the CLI, and outranks API discovery and the catalog while still losing to the
|
|
1414
|
+
active model's `contextWindow` override. `/context` reports these windows as
|
|
1415
|
+
`from model-windows.json`, and a file that cannot be parsed is ignored with one
|
|
1416
|
+
log line rather than trusted. UTF-8 (with or without BOM) and UTF-16 saves are
|
|
1417
|
+
both accepted.
|
|
1418
|
+
|
|
1387
1419
|
## Context compaction
|
|
1388
1420
|
|
|
1389
1421
|
A long agentic run fills the model's context window. Before this existed, the
|
|
@@ -1522,19 +1554,20 @@ refusal is explained. Automatic tail clipping and failure truncation are disable
|
|
|
1522
1554
|
|
|
1523
1555
|
### Sub-agents get the same protection
|
|
1524
1556
|
|
|
1525
|
-
|
|
1526
|
-
`
|
|
1527
|
-
|
|
1528
|
-
dispatch reached you as one partial sentence.
|
|
1529
|
-
|
|
1530
|
-
Children now compact their own history, under tighter bounds: **two** retained
|
|
1531
|
-
turns instead of four, at most **two** compactions per child instead of five, the
|
|
1532
|
-
fast tier preferred whenever it resolves, and failures preserve history. Each
|
|
1557
|
+
Children compact their own history **under the lead's own policy**: the same
|
|
1558
|
+
`keepRecentTurns`, the same `onFailure`, the same archive setting, the same
|
|
1559
|
+
per-run compaction bound, the fast tier preferred whenever it resolves. Each
|
|
1533
1560
|
child owns its own context meter and counts compaction only after Core accepts
|
|
1534
1561
|
the candidate. There is no transcript card for a
|
|
1535
1562
|
child — the lead's transcript describes the lead's context. Turn it off with
|
|
1536
1563
|
`compaction.subagents: false`.
|
|
1537
1564
|
|
|
1565
|
+
Since main-agent parity, the turn cap, the per-child wall clock and the dispatch
|
|
1566
|
+
wall clock all default to **0 = no limit**: a child runs until it finishes, like
|
|
1567
|
+
the lead, with only its own idle watchdog and your Esc as ceilings. Set any of
|
|
1568
|
+
`team.subagentTimeoutMs` / `team.dispatchTimeoutMs` / `team.maxTurnsPerSubagent`
|
|
1569
|
+
to a positive value to bring a ceiling back.
|
|
1570
|
+
|
|
1538
1571
|
### A compaction is no longer irreversible
|
|
1539
1572
|
|
|
1540
1573
|
After a splice is adopted, the dropped messages are written verbatim to
|
|
@@ -1923,9 +1956,9 @@ env / `.env` → CLI flags**.
|
|
|
1923
1956
|
| `team.enabled` | `true` | Master switch for team subagents. `false` means the `task` tool is never registered — `/team on` in such a session saves the setting for next launch and says so, rather than advertising a tool that is not there. |
|
|
1924
1957
|
| `team.maxSubagents` | `5` | Subagents per dispatch, clamped to `[1, 10]`. The 10 is the hard ceiling and is enforced twice — on the config value and again on what the model asks for — so hand-editing this file cannot raise it. |
|
|
1925
1958
|
| `team.maxConcurrent` | `3` | Subagents in flight at once, clamped to `[1, 10]` and capped at `maxSubagents`. A separate knob because provider rate limits are a different constraint from context economics. |
|
|
1926
|
-
| `team.subagentTimeoutMs` | `
|
|
1927
|
-
| `team.dispatchTimeoutMs` | `
|
|
1928
|
-
| `team.maxTurnsPerSubagent` | `
|
|
1959
|
+
| `team.subagentTimeoutMs` | `0` | One subagent's wall clock before it is aborted, clamped to `[0, 1800000]`. `0` (the default) = no ceiling — a wedged subagent still dies on its own idle watchdog, exactly like the lead. |
|
|
1960
|
+
| `team.dispatchTimeoutMs` | `0` | The whole dispatch's wall clock (and the `task` tool timeout), clamped to `[0, 3600000]`. `0` (the default) = no ceiling; only Esc ends a dispatch early. |
|
|
1961
|
+
| `team.maxTurnsPerSubagent` | `0` | Runaway-loop cap, clamped to `[0, 100]`. `0` (the default) = no cap, matching the lead. A subagent stopped at a positive cap is reported as `stopped: turn cap reached`, with whatever it had produced. |
|
|
1929
1962
|
| `todo.enabled` | `true` | Master switch for todo planning. `false` means the `todo_write` tool is never registered — `/todo on` in such a session saves the setting for next launch and says so, rather than advertising a tool that is not there. |
|
|
1930
1963
|
| `todo.panel` | `true` | Render the right-hand rail. Independent of `todo.enabled` on purpose: a screen-reader user wants the planning discipline without the column, and the system prompt varies one sentence accordingly. |
|
|
1931
1964
|
| `todo.followThrough` | `"notify"` | What happens when a run ends with steps left. `notify` says so and stops; `auto` continues the plan after a 3-second grace window, bounded by two structural limits (one fruitless attempt, 25 continuations per plan) that are deliberately **not** settings; `off` is silent. An unrecognized value falls back to `notify`. |
|
|
@@ -1936,7 +1969,7 @@ env / `.env` → CLI flags**.
|
|
|
1936
1969
|
| `retry.multiplier` | `2` | Growth factor, clamped to `[1, 5]`. The one **float** key in this section: `2.5` is a legitimate factor and is stored as typed. |
|
|
1937
1970
|
| `retry.jitter` | `true` | Equal jitter (`d/2 + rand·d/2`), which de-correlates concurrent subagents hitting the same 429 while keeping the announced countdown within a factor of two of the truth. Full jitter can fire 40 ms after announcing 30 s, which reads as a bug. |
|
|
1938
1971
|
| `retry.respectRetryAfter` | `true` | Honour `Retry-After` (and the provider rate-limit reset headers) as a **floor**, never a replacement — a `Retry-After: 1` on the ninth retry does not undo eight retries of backoff. A stated wait above 60 s is surfaced immediately instead of waited out. |
|
|
1939
|
-
| `retry.maxElapsedMs` | `240000` | Wall-clock budget from the first failure, clamped to `[10000, 1800000]`.
|
|
1972
|
+
| `retry.maxElapsedMs` | `240000` | Wall-clock budget from the first failure, clamped to `[10000, 1800000]`. When `team.subagentTimeoutMs` is positive, keep this below it: an equal budget means a subagent is killed at the same instant its ladder ends, and the user is then told "subagent timed out" for what was a provider outage. |
|
|
1940
1973
|
| `retry.onPartialStream` | `true` | Allow a restart after content has already streamed to the transcript. The view is rewound and the discarded tool cards removed; engine history is provably clean at that point, because it is only written on a completed turn. `false` refuses the whole path. |
|
|
1941
1974
|
| `skills.enabled` | `true` | Master switch for the skill system. |
|
|
1942
1975
|
| `skills.requireApproval` | `true` | Require a human to approve `skill_install` / `skill_create`. |
|
|
@@ -2150,6 +2183,8 @@ Everything AragonAgent keeps for you lives under one directory in your home:
|
|
|
2150
2183
|
~/.aragon-agent/ (Windows: C:\Users\<you>\.aragon-agent\)
|
|
2151
2184
|
├── config.json settings + API keys (0600 on POSIX)
|
|
2152
2185
|
├── config.json.bak written by `aragon config edit` before it opens
|
|
2186
|
+
├── model-windows.json per-model context windows you declare by hand;
|
|
2187
|
+
│ read live, never written by the CLI
|
|
2153
2188
|
├── prompt-history.jsonl prompts you submitted, for ↑ recall (0600 on POSIX)
|
|
2154
2189
|
├── state.json UI bookkeeping: submit count, one-shot notices
|
|
2155
2190
|
├── update-state.json auto-update: last check, pending restart, skipped version,
|
|
@@ -2326,19 +2361,19 @@ node packages/cli/dist/cli.js --version
|
|
|
2326
2361
|
- `echo "list files" | node dist/cli.js -p` prints an answer and exits `0`.
|
|
2327
2362
|
- A missing/invalid key produces a visible, actionable message (never a blank
|
|
2328
2363
|
screen), both in the TUI and headless.
|
|
2329
|
-
- `Shift+Tab` at 40, 80 and 120 columns - the
|
|
2330
|
-
|
|
2364
|
+
- `Shift+Tab` at 40, 80 and 120 columns - the status-bar mode word (`PLAN` / `P`)
|
|
2365
|
+
stays legible and nothing wraps onto a second row.
|
|
2331
2366
|
- The question wizard at 24 rows with 5 questions x 4 options - no clipping, and
|
|
2332
2367
|
the `n/N` counter matches what is on screen.
|
|
2333
2368
|
- Approve a plan and watch the SAME run start writing files, with no second
|
|
2334
2369
|
prompt.
|
|
2335
|
-
- `--no-color` on a legacy `cmd.exe` - the
|
|
2336
|
-
`*`/`o`, checkboxes render `[x]`/`[ ]`, no mojibake anywhere.
|
|
2370
|
+
- `--no-color` on a legacy `cmd.exe` - the mode word renders as plain `PLAN` text,
|
|
2371
|
+
radios render `*`/`o`, checkboxes render `[x]`/`[ ]`, no mojibake anywhere.
|
|
2337
2372
|
- A plan with a 600-character summary and a 400-character step detail - the text
|
|
2338
2373
|
wraps and scrolls, the footer count matches the real number of rows, and
|
|
2339
2374
|
nothing is truncated to a single line.
|
|
2340
2375
|
- `--no-hints` on a 20-row terminal in plan mode - the status bar still says
|
|
2341
|
-
`PLAN
|
|
2376
|
+
`PLAN`.
|
|
2342
2377
|
- Dismiss a plan card with `Esc`, let the agent resubmit, then close the card and press `Esc` twice within 1.5 seconds:
|
|
2343
2378
|
the run aborts and the session returns to an idle prompt. Do this one BY HAND
|
|
2344
2379
|
as well as in a test - the point of the check is whether the exit is findable,
|
|
@@ -2366,7 +2401,9 @@ UTF-16 编辑和 ZWJ/组合字形仍有既有限制,本次修复保证视觉
|
|
|
2366
2401
|
## 输入、待处理队列与底部状态区
|
|
2367
2402
|
|
|
2368
2403
|
Enter 在空闲时发送,运行时加入队列;启动阶段拒绝重复提交并保留草稿。
|
|
2369
|
-
Ctrl+J
|
|
2404
|
+
Ctrl+J 换行;应用默认推送键盘增强模式(Windows 用 win32-input-mode,其余平台用
|
|
2405
|
+
kitty disambiguate + modifyOtherKeys=2)并将新编码翻译回传统字节,因此 Shift+Enter
|
|
2406
|
+
与 Alt+Enter 在支持的终端开箱即用,Ctrl+J 始终可用。
|
|
2370
2407
|
光标按完整字素移动,支持中文、组合字符和 emoji;输入最多占终端高度四分之一且不超过六行。
|
|
2371
2408
|
括号粘贴保留换行,不触发发送。过滤器或粘贴支持关闭时,不保证未标记多行粘贴安全。
|
|
2372
2409
|
过滤器不可用时 Delete 保守按 Backspace 处理,避免退格误删后文。
|
|
@@ -2375,14 +2412,14 @@ Ctrl+J 换行;终端能发送独立序列时,Shift+Enter 与 Alt+Enter 也
|
|
|
2375
2412
|
原生剪贴板工具完成后显示确认,OSC 52 只表示请求已发送,终端可能拒绝。
|
|
2376
2413
|
Shift+拖动或 `/mouse off` 后的选区由宿主管理,应用无法关闭宿主的自动复制。
|
|
2377
2414
|
|
|
2378
|
-
Queue 面板逐条显示待处理消息,数量在展开状态详情中按空间显示。只有 Core 已把消息纳入会话并发回接收凭据,
|
|
2415
|
+
Queue 面板逐条显示待处理消息,数量在展开状态详情中按空间显示。只有 Core 已把消息纳入会话并发回接收凭据,
|
|
2379
2416
|
该条提示才会消失。中断时未接收消息显示暂停;`/queue` 可分页查看全部原文,Esc 关闭。
|
|
2380
2417
|
`/clear` 不丢待处理消息;`/reset`、切换会话会明确报告取消数量;恢复保存的未发送历史不会自动重发。
|
|
2381
2418
|
|
|
2382
|
-
底部依次为固定输入框和一行核心状态;Ctrl+G 展开或收起第二行详情。五个核心字段按显示宽度缩写,始终保留。
|
|
2383
|
-
核心上下文显示当前主 Agent 的百分比;展开详情或 /context 可查看已用/上限 tokens;`~` 表示含估算,`?` 表示上限未知。
|
|
2419
|
+
底部依次为固定输入框和一行核心状态;Ctrl+G 展开或收起第二行详情。五个核心字段按显示宽度缩写,始终保留。
|
|
2420
|
+
核心上下文显示当前主 Agent 的百分比;展开详情或 /context 可查看已用/上限 tokens;`~` 表示含估算,`?` 表示上限未知。
|
|
2384
2421
|
费用是含子代理、快速模型及压缩的会话估算 USD,恢复会话沿用累计,缺价格按零计,零值不保证免费。
|
|
2385
|
-
本轮均速只累计主 Agent 已报告的 output tokens,再除以本轮总耗时(含工具与等待);排除辅助调用,并非瞬时生成速度。结束后保留耗时,速度显示 --。
|
|
2422
|
+
本轮均速只累计主 Agent 已报告的 output tokens,再除以本轮总耗时(含工具与等待);排除辅助调用,并非瞬时生成速度。结束后保留耗时,速度显示 --。
|
|
2386
2423
|
`/context` 提供统计范围和完整值。
|
|
2387
2424
|
|
|
2388
2425
|
Windows Terminal:在设置 JSON **根级**添加 `"copyOnSelect": false`,把以下条目合并到已有数组:
|
|
@@ -2432,10 +2469,10 @@ VS Code 用户设置添加 `"terminal.integrated.copyOnSelection": false`,快
|
|
|
2432
2469
|
|
|
2433
2470
|
配置库仍位于 `ARAGON_HOME` 指向目录中的 `config.json`,不写入会话文件。密钥按现有机制明文保存:POSIX 创建权限为 0600,Windows 依赖用户目录 ACL,不提供加密。`config get/list` 对方案密钥使用固定掩码;损坏或未来版本的配置段整体隐藏。既有 `config edit` 备份也包含凭据。关闭通用日志脱敏、使用短密钥或分享第三方 SDK 错误日志时,仍需自行检查日志内容。
|
|
2434
2471
|
|
|
2435
|
-
### 固定输入与状态详情人工验收
|
|
2436
|
-
|
|
2437
|
-
在 Windows Terminal/PowerShell、VS Code 集成终端以及 macOS/Linux 终端分别检查
|
|
2438
|
-
40x12、80x24、120x40。保留草稿,连续输出思考、正文与工具日志至少 30 秒:
|
|
2439
|
-
输入上下边框不得移动;拖动消息滚动条不会隐藏输入。切换 Ctrl+G 仅改变一行,
|
|
2440
|
-
复制、队列、通知和更新不自动展开。验证补全、Unicode 草稿和光标在切换后保留,
|
|
2441
|
-
弹层期间 Ctrl+G 无效,小屏恢复后草稿与状态模式保留。自动化测试不能替代这些宿主观察。
|
|
2472
|
+
### 固定输入与状态详情人工验收
|
|
2473
|
+
|
|
2474
|
+
在 Windows Terminal/PowerShell、VS Code 集成终端以及 macOS/Linux 终端分别检查
|
|
2475
|
+
40x12、80x24、120x40。保留草稿,连续输出思考、正文与工具日志至少 30 秒:
|
|
2476
|
+
输入上下边框不得移动;拖动消息滚动条不会隐藏输入。切换 Ctrl+G 仅改变一行,
|
|
2477
|
+
复制、队列、通知和更新不自动展开。验证补全、Unicode 草稿和光标在切换后保留,
|
|
2478
|
+
弹层期间 Ctrl+G 无效,小屏恢复后草稿与状态模式保留。自动化测试不能替代这些宿主观察。
|
|
@@ -15,6 +15,7 @@ import type { PromptOptions, PromptOutcome } from './prompt-options.js';
|
|
|
15
15
|
import { ModelRegistry, type AgentEvent, type AgentTool, type Message, type ModelInfo, type ModelRef, type ProviderRegistry, type ThinkingLevel } from '@aragon-agent/core';
|
|
16
16
|
import type { CliConfig, CompactionConfig, FastConfig, RetryConfig, TeamConfig, ThemeName, TodoConfig } from '../config/schema.js';
|
|
17
17
|
import type { ModelRole } from '../config/model-profiles.js';
|
|
18
|
+
import { ModelWindows } from '../config/model-windows.js';
|
|
18
19
|
import { type ConfirmRequest } from '../tools/index.js';
|
|
19
20
|
import type { ToolPermission } from '../exec/permission.js';
|
|
20
21
|
import { type ToolOutputListener } from '../tools/tool-output-store.js';
|
|
@@ -102,6 +103,13 @@ export interface ControllerDeps {
|
|
|
102
103
|
* once at construction and lost at the first `rebuildSystemPrompt()`.
|
|
103
104
|
*/
|
|
104
105
|
appendSystemPrompt?: string;
|
|
106
|
+
/**
|
|
107
|
+
* The per-model window table from ~/.aragon-agent/model-windows.json.
|
|
108
|
+
* Injectable so tests can hand the controller a table without writing into
|
|
109
|
+
* the shared vitest home root (app-paths.ts TEST-ISOLATION CONTRACT);
|
|
110
|
+
* production leaves it absent and the constructor builds the real one.
|
|
111
|
+
*/
|
|
112
|
+
modelWindows?: ModelWindows;
|
|
105
113
|
}
|
|
106
114
|
/** What `setAgentMode` actually adopted — see `AgentController.setAgentMode`. */
|
|
107
115
|
export interface AgentModeState {
|
|
@@ -124,6 +132,8 @@ export declare class AgentController {
|
|
|
124
132
|
private readonly agent;
|
|
125
133
|
private readonly providerRegistry;
|
|
126
134
|
private readonly modelRegistry;
|
|
135
|
+
/** Per-model user-declared context windows; see `config/model-windows.ts`. */
|
|
136
|
+
private readonly modelWindows;
|
|
127
137
|
private modelMetadataEnabled;
|
|
128
138
|
private modelMetadataGeneration;
|
|
129
139
|
private modelMetadataAbort;
|
package/dist/agent/controller.js
CHANGED
|
@@ -7,10 +7,12 @@ import { clampCompactionConfig, clampFastConfig, clampRetryConfig, clampTeamConf
|
|
|
7
7
|
import { resolveModelProfileState } from '../config/model-profile-resolution.js';
|
|
8
8
|
import { makeGetApiKey } from '../config/load.js';
|
|
9
9
|
import { updatePersistedConfig } from '../config/store.js';
|
|
10
|
+
import { ModelWindows } from '../config/model-windows.js';
|
|
10
11
|
import { createBuiltinTools } from '../tools/index.js';
|
|
11
12
|
import { createFileChangeStore } from '../tools/file-change-store.js';
|
|
12
13
|
import { createToolOutputStore, } from '../tools/tool-output-store.js';
|
|
13
14
|
import { TeamRuntime } from '../team/runtime.js';
|
|
15
|
+
import { createChildReviewer } from '../team/child-reviewer.js';
|
|
14
16
|
import { TeamHumanQueue } from '../team/human-queue.js';
|
|
15
17
|
import { createTaskTool } from '../team/task-tool.js';
|
|
16
18
|
import { buildTeamBlock } from '../team/prompt.js';
|
|
@@ -53,6 +55,8 @@ export class AgentController {
|
|
|
53
55
|
agent;
|
|
54
56
|
providerRegistry;
|
|
55
57
|
modelRegistry;
|
|
58
|
+
/** Per-model user-declared context windows; see `config/model-windows.ts`. */
|
|
59
|
+
modelWindows;
|
|
56
60
|
modelMetadataEnabled = false;
|
|
57
61
|
modelMetadataGeneration = 0;
|
|
58
62
|
modelMetadataAbort = new AbortController();
|
|
@@ -158,14 +162,14 @@ export class AgentController {
|
|
|
158
162
|
// Fast model tier (fast-model-tier §3.1 / §3.3)
|
|
159
163
|
//
|
|
160
164
|
// ONE FIELD AND FOUR THIN FORWARDERS. The flag pair, the tier cache, the
|
|
161
|
-
// reviewer's lifetime and the
|
|
165
|
+
// reviewer's lifetime and the shared fail-fast review transport all live in
|
|
162
166
|
// `fast/wiring.ts`, which is a BUDGET decision rather than an aesthetic one
|
|
163
167
|
// (C-12 / RV-5): `CLAUDE.md` caps a source file at 1000 lines and this one had
|
|
164
168
|
// 40 to spare when the design was written.
|
|
165
169
|
//
|
|
166
170
|
// `null` when the tier could not be resolved at construction, which is the
|
|
167
|
-
// byte-identity branch: no reviewer is subscribed
|
|
168
|
-
//
|
|
171
|
+
// byte-identity branch: no reviewer is subscribed and `<fast_tier>` is
|
|
172
|
+
// never spliced (I-2).
|
|
169
173
|
// -----------------------------------------------------------------------
|
|
170
174
|
fast;
|
|
171
175
|
// -----------------------------------------------------------------------
|
|
@@ -275,6 +279,7 @@ export class AgentController {
|
|
|
275
279
|
// reuses this very registry instance.
|
|
276
280
|
this.providerRegistry = initProviders({ retryPolicy: toRetryPolicy(config.retry) });
|
|
277
281
|
this.modelRegistry = new ModelRegistry(this.providerRegistry);
|
|
282
|
+
this.modelWindows = deps.modelWindows ?? new ModelWindows();
|
|
278
283
|
this.skillsEnabled = config.skills.enabled;
|
|
279
284
|
this.onSkillsChanged = deps.onSkillsChanged;
|
|
280
285
|
this.skills = new SkillService({
|
|
@@ -307,8 +312,8 @@ export class AgentController {
|
|
|
307
312
|
this.todos = this.todoRegistered ? new TodoStore() : null;
|
|
308
313
|
// --- Fast model tier ---------------------------------------------------
|
|
309
314
|
//
|
|
310
|
-
// RESOLVED BEFORE THE
|
|
311
|
-
// `
|
|
315
|
+
// RESOLVED BEFORE THE AGENT, because `fastRegistered` decides whether the
|
|
316
|
+
// `FastWiring` (reviewer, tier cache) exists at all and the wiring is built
|
|
312
317
|
// ONCE (C-2). `FastWiring` re-runs the same pure function in its own
|
|
313
318
|
// constructor; the two agree by construction because they read the same
|
|
314
319
|
// config through the same resolver.
|
|
@@ -320,24 +325,35 @@ export class AgentController {
|
|
|
320
325
|
this.teamRuntime = this.teamRegistered
|
|
321
326
|
? new TeamRuntime({
|
|
322
327
|
getConfig: () => this.config,
|
|
323
|
-
// Read LIVE
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
// settings-screen edit reaches the next dispatch.
|
|
328
|
+
// Read LIVE: the closure is only ever called from inside a dispatch,
|
|
329
|
+
// and `childFactory()` re-reads `compaction.subagents` on every call
|
|
330
|
+
// so a settings-screen edit reaches the next dispatch.
|
|
327
331
|
contextManagerFor: (req) => this.compaction?.childFactory()?.(req),
|
|
328
|
-
//
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
332
|
+
// PER-CHILD FAST REVIEW (main-agent parity): one reviewer per
|
|
333
|
+
// child, sharing the lead wiring's tier, policy and fail-fast
|
|
334
|
+
// transport. `this.fast` is null until after the Agent exists; these
|
|
335
|
+
// closures run only from inside a dispatch, long after construction.
|
|
336
|
+
review: {
|
|
337
|
+
// EVERY `this.fast` READ LIVES INSIDE A CLOSURE: the wiring is
|
|
338
|
+
// assigned AFTER this constructor block (it needs the Agent), and
|
|
339
|
+
// a read in the constructor's own flow would be a use-before-assign.
|
|
340
|
+
// The closures run only from inside a dispatch, long after
|
|
341
|
+
// construction, when the field has its final value.
|
|
342
|
+
active: () => this.fast !== null && this.fast.available() && this.config.fast.review,
|
|
343
|
+
modelId: () => {
|
|
344
|
+
const tier = this.fast?.getTier();
|
|
345
|
+
return tier && tier.ok ? tier.ref.modelId : '';
|
|
340
346
|
},
|
|
347
|
+
create: (request) => this.fast
|
|
348
|
+
? createChildReviewer(request, {
|
|
349
|
+
getConfig: () => this.config,
|
|
350
|
+
hasKey: (id, role) => this.hasApiKey(id, role),
|
|
351
|
+
getApiKey: (id, role) => this.resolveKey(id, role),
|
|
352
|
+
complete: (providerId, llmRequest) => this.fast.completeViaFastRegistry(providerId, llmRequest),
|
|
353
|
+
available: () => this.fast?.available() === true,
|
|
354
|
+
})
|
|
355
|
+
: undefined,
|
|
356
|
+
},
|
|
341
357
|
providerRegistry: this.providerRegistry,
|
|
342
358
|
getCwd: () => this.cwd,
|
|
343
359
|
getMode: () => this.effectiveMode,
|
|
@@ -484,23 +500,12 @@ export class AgentController {
|
|
|
484
500
|
runtime: this.teamRuntime,
|
|
485
501
|
// Read LIVE: `/team off` flips the flag, it cannot unregister.
|
|
486
502
|
isTeamEnabled: () => this.teamEnabled,
|
|
487
|
-
// FROZEN AT CONSTRUCTION (C-2). `/fast on` in a session launched
|
|
488
|
-
// without the tier cannot add a schema property, and it says so
|
|
489
|
-
// rather than advertising one that is not there.
|
|
490
|
-
fastRegistered,
|
|
491
|
-
// Read LIVE at dispatch time (RV-3): the tier can stop resolving
|
|
492
|
-
// mid-session, and the normalizer and the subagent factory must
|
|
493
|
-
// agree about that at the same instant.
|
|
494
|
-
fastAvailable: () => this.fast?.delegationAvailable() === true,
|
|
495
503
|
maxSubagents: () => this.config.team.maxSubagents,
|
|
496
504
|
hasApiKey: () => this.hasApiKey(),
|
|
497
505
|
activeProvider: () => this.config.provider,
|
|
506
|
+
// Every child runs the lead's own model, so the lead's cost table
|
|
507
|
+
// is the one honest price for the dispatch total.
|
|
498
508
|
modelCost: () => this.getModelInfo().cost,
|
|
499
|
-
fastModelCost: () => {
|
|
500
|
-
const ref = this.fast?.fastRef();
|
|
501
|
-
return ref ? this.getModelInfoFor(ref).cost : undefined;
|
|
502
|
-
},
|
|
503
|
-
fastPricingUnknown: () => this.fast?.snapshot().pricingUnknown === true,
|
|
504
509
|
withPausedWatchdog: (fn) => this.withPausedWatchdog(fn),
|
|
505
510
|
}),
|
|
506
511
|
]
|
|
@@ -599,6 +604,10 @@ export class AgentController {
|
|
|
599
604
|
// number only bites BECAUSE `task` races `ctx.signal` — the
|
|
600
605
|
// executor's timeout is cooperative, so an override is inert for any
|
|
601
606
|
// tool that does not listen (I-2).
|
|
607
|
+
//
|
|
608
|
+
// `dispatchTimeoutMs: 0` (the default) reaches the executor as an
|
|
609
|
+
// override of `0` = NO TIMER AT ALL: the dispatch lasts as long as its
|
|
610
|
+
// slowest child, and only an Esc ends it early (main-agent parity).
|
|
602
611
|
...(this.teamRegistered ? { task: config.team.dispatchTimeoutMs } : {}),
|
|
603
612
|
},
|
|
604
613
|
},
|
|
@@ -668,13 +677,6 @@ export class AgentController {
|
|
|
668
677
|
});
|
|
669
678
|
if (this.fast) {
|
|
670
679
|
this.rebuildSystemPrompt();
|
|
671
|
-
// Fast-tier children are counted from the outcome rather than from the
|
|
672
|
-
// specs, so a downgraded child is not miscounted as a saving (§3.6).
|
|
673
|
-
this.teamRuntime?.subscribe((event) => {
|
|
674
|
-
if (event.type !== 'dispatch_end')
|
|
675
|
-
return;
|
|
676
|
-
this.fast?.noteDelegated(event.outcome.runs.filter((r) => r.tier === 'fast').length);
|
|
677
|
-
});
|
|
678
680
|
}
|
|
679
681
|
// ONE LINE FOR THE TWO CONFIGURATION MISTAKES THAT ARE OTHERWISE INVISIBLE
|
|
680
682
|
// (§3.3): the tier is on but unnamed, or named against a provider with no
|
|
@@ -734,11 +736,6 @@ export class AgentController {
|
|
|
734
736
|
? buildTeamBlock({
|
|
735
737
|
maxSubagents: config.team.maxSubagents,
|
|
736
738
|
maxConcurrent: config.team.maxConcurrent,
|
|
737
|
-
// One cross-reference sentence, present only when the capability
|
|
738
|
-
// is (§3.8). `this.fast` is null during the FIRST compose (the
|
|
739
|
-
// wiring needs the Agent), which is why the constructor composes
|
|
740
|
-
// again once it exists.
|
|
741
|
-
fastDelegation: !!fastAvailable && config.fast.delegate,
|
|
742
739
|
})
|
|
743
740
|
: '',
|
|
744
741
|
// BOTH FLAGS, exactly as team mode uses both, and for the identical
|
|
@@ -758,7 +755,6 @@ export class AgentController {
|
|
|
758
755
|
fastBlock: fastAvailable
|
|
759
756
|
? buildFastBlock({
|
|
760
757
|
model: tier.ok ? tier.ref.modelId : '',
|
|
761
|
-
delegate: config.fast.delegate,
|
|
762
758
|
review: config.fast.review,
|
|
763
759
|
})
|
|
764
760
|
: '',
|
|
@@ -1737,9 +1733,18 @@ export class AgentController {
|
|
|
1737
1733
|
const found = this.modelRegistry.getModel(ref.providerId, ref.modelId);
|
|
1738
1734
|
const baseUrl = ref.baseUrl ?? (ref.providerId === this.config.provider && ref.modelId === this.config.model
|
|
1739
1735
|
? this.config.baseUrl : undefined);
|
|
1736
|
+
const userWindow = this.modelWindows.lookup(ref.modelId);
|
|
1740
1737
|
return {
|
|
1741
1738
|
...(found ?? this.modelRegistry.buildRuntimeModel(ref.providerId, ref.modelId)),
|
|
1742
1739
|
...this.modelRegistry.getContextWindow(ref.providerId, ref.modelId, baseUrl),
|
|
1740
|
+
// A USER-DECLARED WINDOW OUTRANKS EVERY TABLE (model-windows.json): the
|
|
1741
|
+
// user asserted the number for exactly this id, while api/catalog are
|
|
1742
|
+
// what this process managed to look up about it. It still LOSES to
|
|
1743
|
+
// config.json's `contextWindow`, which `ContextMeter.resolveWindow`
|
|
1744
|
+
// consults before it ever reaches here.
|
|
1745
|
+
...(userWindow !== undefined
|
|
1746
|
+
? { contextWindow: userWindow, contextWindowSource: 'user' }
|
|
1747
|
+
: {}),
|
|
1743
1748
|
};
|
|
1744
1749
|
}
|
|
1745
1750
|
/** Best-effort metadata lookup; never block typing or a model request. */
|
package/dist/agent/reducer.js
CHANGED
|
@@ -860,10 +860,6 @@ export function viewReducer(state, action) {
|
|
|
860
860
|
const runs = action.specs.map((spec) => ({
|
|
861
861
|
label: spec.label,
|
|
862
862
|
description: spec.description,
|
|
863
|
-
// Already downgraded by the normalizer when the tier was unavailable, so
|
|
864
|
-
// the card and the report agree from the first frame (fast-model-tier
|
|
865
|
-
// §3.4).
|
|
866
|
-
tier: spec.tier,
|
|
867
863
|
phase: 'queued',
|
|
868
864
|
turns: 0,
|
|
869
865
|
toolCalls: 0,
|