@aragon-agent/cli 0.6.21 → 0.6.22
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 +32 -12
- package/dist/agent/controller.js +13 -0
- package/dist/commands/builtins.js +2 -1
- package/dist/config/cli-commands.d.ts +1 -1
- package/dist/config/cli-commands.js +3 -0
- package/dist/config/schema.d.ts +28 -12
- package/dist/config/schema.js +4 -0
- package/dist/team/limits.d.ts +73 -13
- package/dist/team/limits.js +82 -15
- package/dist/team/normalize.js +7 -2
- package/dist/team/overseer.d.ts +154 -16
- package/dist/team/overseer.js +342 -46
- package/dist/team/report.d.ts +9 -0
- package/dist/team/report.js +32 -4
- package/dist/team/runtime.d.ts +51 -9
- package/dist/team/runtime.js +478 -71
- package/dist/team/task-tool.d.ts +7 -0
- package/dist/team/task-tool.js +2 -0
- package/dist/team/types.d.ts +43 -2
- package/dist/ui/App.js +14 -0
- package/dist/ui/TeamPanel.d.ts +22 -0
- package/dist/ui/TeamPanel.js +71 -2
- package/dist/ui/layout/team-panel.js +4 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1148,15 +1148,34 @@ than a fact: the file list is derived from `write_file` / `edit_file`, so a
|
|
|
1148
1148
|
write made through `bash` is invisible to it.
|
|
1149
1149
|
|
|
1150
1150
|
**The dispatch supervisor.** A time ceiling on a subagent is an inspection
|
|
1151
|
-
trigger, not a death sentence
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1151
|
+
trigger, not a death sentence. Every dispatch gets its own supervisor on the
|
|
1152
|
+
fast model: a per-child silence window for suspected stalls, plus a periodic
|
|
1153
|
+
cadence check over the WHOLE roster — one bounded call that carries every live
|
|
1154
|
+
subagent and returns one decision per child: keep waiting, steer a nudge in,
|
|
1155
|
+
rebuild the child with an amended brief, or abandon it with a recorded reason.
|
|
1156
|
+
The cadence grows geometrically (5 min base, ×1.6, capped at 15 min), so a
|
|
1157
|
+
healthy slow subagent is checked logarithmically in its run time rather than
|
|
1158
|
+
every five minutes forever. The budgets are structural, not settings — 12
|
|
1159
|
+
looks, 3 nudges, 1 replacement and 1 abandon per child per dispatch. When the
|
|
1160
|
+
look budget is spent the supervisor says so once (`quiet` in the report) and
|
|
1161
|
+
stops waking that child; failed inspection calls cost a look but never an
|
|
1162
|
+
action. Every applied decision is recorded in the report's Supervisor section
|
|
1163
|
+
with the supervisor's own fast-tier spend, and replace/abandon also surface as
|
|
1164
|
+
a transcript notice while the dispatch runs.
|
|
1165
|
+
|
|
1166
|
+
**No kill by default.** While `team.overseer` is on (the default),
|
|
1167
|
+
`team.subagentTimeoutMs` never aborts anything — a positive value is only the
|
|
1168
|
+
supervisor's first cadence check. If the fast tier is missing (no key,
|
|
1169
|
+
`/fast off`), a due check degrades to an announced *unassisted wait*: the
|
|
1170
|
+
children keep running, the report notes how many checks ran degraded, and
|
|
1171
|
+
nothing is killed. A subagent still ends on the user's Esc, the explicit
|
|
1172
|
+
`team.dispatchTimeoutMs` / `team.maxTurnsPerSubagent` ceilings, its own idle
|
|
1173
|
+
watchdog (lengthened 4× while supervised), or the supervisor's own
|
|
1174
|
+
replace/abandon verdict. One boundary to know: a session with NO fast wiring
|
|
1175
|
+
at all and `team.overseer: true` runs children with no wall clock whatsoever
|
|
1176
|
+
— they finish, or die on their own un-lengthened watchdog. `/team overseer
|
|
1177
|
+
off` is the escape hatch back to the legacy regime where
|
|
1178
|
+
`team.subagentTimeoutMs` is a hard abort again.
|
|
1160
1179
|
|
|
1161
1180
|
**Talking to each other.** Subagents get two extra tools, `team_send` and
|
|
1162
1181
|
`team_wait`. Messages are delivered by attaching them to the recipient's next
|
|
@@ -2001,10 +2020,11 @@ env / `.env` → CLI flags**.
|
|
|
2001
2020
|
| `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. |
|
|
2002
2021
|
| `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. |
|
|
2003
2022
|
| `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. |
|
|
2004
|
-
| `team.subagentTimeoutMs` | `0` | One subagent's wall clock, clamped to `[0, 1800000]`. With
|
|
2023
|
+
| `team.subagentTimeoutMs` | `0` | One subagent's wall clock, clamped to `[0, 1800000]`. With `team.overseer: false` it is a hard abort (the legacy regime). With the supervisor on (the default) it **never aborts anything** — a positive value is only a compatibility source for the supervisor's first cadence check. `0` (the default) = use `team.overseerIntervalMs` / the structural 5 min instead. |
|
|
2005
2024
|
| `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. |
|
|
2006
2025
|
| `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. |
|
|
2007
|
-
| `team.overseer` | `true` | The dispatch supervisor:
|
|
2026
|
+
| `team.overseer` | `true` | The dispatch supervisor: one per dispatch on the fast model, ticking on a geometric cadence over every live subagent and deciding wait / nudge / replace / abandon. With the fast tier missing a tick degrades to an announced unassisted wait — never a kill; with this `false`, children run under the legacy hard ceilings exactly. `/team overseer on\|off` flips it live, and it is read per dispatch. |
|
|
2027
|
+
| `team.overseerIntervalMs` | `0` | Supervisor cadence base, clamped to `[0, 3600000]`. `0` (the default) = the structural 300 s; a positive `team.subagentTimeoutMs` is honoured first when this is `0` (compat). Later checks grow ×1.6, clamped to `[60 s, 900 s]`; any nudge/replace/abandon resets that child's cadence to the base. Only meaningful while `team.overseer` is true. |
|
|
2008
2028
|
| `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. |
|
|
2009
2029
|
| `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. |
|
|
2010
2030
|
| `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`. |
|
|
@@ -2015,7 +2035,7 @@ env / `.env` → CLI flags**.
|
|
|
2015
2035
|
| `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. |
|
|
2016
2036
|
| `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. |
|
|
2017
2037
|
| `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. |
|
|
2018
|
-
| `retry.maxElapsedMs` | `240000` | Wall-clock budget from the first failure, clamped to `[10000, 1800000]`.
|
|
2038
|
+
| `retry.maxElapsedMs` | `240000` | Wall-clock budget from the first failure, clamped to `[10000, 1800000]`. Under the legacy regime (`team.overseer: false`) with `team.subagentTimeoutMs` 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. |
|
|
2019
2039
|
| `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. |
|
|
2020
2040
|
| `skills.enabled` | `true` | Master switch for the skill system. |
|
|
2021
2041
|
| `skills.requireApproval` | `true` | Require a human to approve `skill_install` / `skill_create`. |
|
package/dist/agent/controller.js
CHANGED
|
@@ -519,6 +519,19 @@ export class AgentController {
|
|
|
519
519
|
// Every child runs the lead's own model, so the lead's cost table
|
|
520
520
|
// is the one honest price for the dispatch total.
|
|
521
521
|
modelCost: () => this.getModelInfo().cost,
|
|
522
|
+
// The FAST table for the supervisor's own spend line
|
|
523
|
+
// (subagent-overseer-v2 D-7 / R-P1-2). Reuses the tier
|
|
524
|
+
// resolution and the unknown-pricing predicate the fast
|
|
525
|
+
// reviewer already uses: undefined prices as `pricing
|
|
526
|
+
// unknown`, never as $0.00 (C-11 / RV-4).
|
|
527
|
+
fastModelCost: () => {
|
|
528
|
+
const tier = this.fast?.getTier();
|
|
529
|
+
if (!tier || !tier.ok)
|
|
530
|
+
return undefined;
|
|
531
|
+
return this.isPricedModel(tier.ref)
|
|
532
|
+
? this.getModelInfoFor(tier.ref).cost
|
|
533
|
+
: undefined;
|
|
534
|
+
},
|
|
522
535
|
withPausedWatchdog: (fn) => this.withPausedWatchdog(fn),
|
|
523
536
|
}),
|
|
524
537
|
]
|
|
@@ -294,7 +294,8 @@ const COMMANDS = [
|
|
|
294
294
|
? `\nRunning: ${snapshot.runs.map((r) => `${r.label} (${r.phase})`).join(', ')}`
|
|
295
295
|
: '';
|
|
296
296
|
ctx.notify('info', `Team mode: ${state}. Max subagents: ${cfg.maxSubagents}, ` +
|
|
297
|
-
`concurrent: ${cfg.maxConcurrent}, supervisor: ${cfg.overseer ? 'on' : 'off'}
|
|
297
|
+
`concurrent: ${cfg.maxConcurrent}, supervisor: ${cfg.overseer ? 'on' : 'off'}` +
|
|
298
|
+
`${cfg.overseer ? ' (never kills; checks the fast tier each tick)' : ' (legacy hard timeouts)'}.${roster}`);
|
|
298
299
|
return;
|
|
299
300
|
}
|
|
300
301
|
if (verb === 'on' || verb === 'off') {
|
|
@@ -20,7 +20,7 @@ export declare const LOG_CONFIG_SET_KEYS: readonly ["log.level", "log.toFile", "
|
|
|
20
20
|
* switch falls through every case, writes nothing, and still prints
|
|
21
21
|
* `Set team.enabled = false`.
|
|
22
22
|
*/
|
|
23
|
-
export declare const TEAM_CONFIG_SET_KEYS: readonly ["team.enabled", "team.maxSubagents", "team.maxConcurrent", "team.subagentTimeoutMs", "team.dispatchTimeoutMs", "team.maxTurnsPerSubagent", "team.overseer"];
|
|
23
|
+
export declare const TEAM_CONFIG_SET_KEYS: readonly ["team.enabled", "team.maxSubagents", "team.maxConcurrent", "team.subagentTimeoutMs", "team.dispatchTimeoutMs", "team.maxTurnsPerSubagent", "team.overseer", "team.overseerIntervalMs"];
|
|
24
24
|
/**
|
|
25
25
|
* Config keys under `retry.` that `aragon config set` accepts
|
|
26
26
|
* (llm-api-retry-backoff §8.2).
|
|
@@ -44,6 +44,7 @@ export const TEAM_CONFIG_SET_KEYS = [
|
|
|
44
44
|
'team.dispatchTimeoutMs',
|
|
45
45
|
'team.maxTurnsPerSubagent',
|
|
46
46
|
'team.overseer',
|
|
47
|
+
'team.overseerIntervalMs',
|
|
47
48
|
];
|
|
48
49
|
/**
|
|
49
50
|
* Config keys under `retry.` that `aragon config set` accepts
|
|
@@ -202,6 +203,8 @@ export function applyTeamConfigSet(key, value) {
|
|
|
202
203
|
return patch(clampOne('maxTurnsPerSubagent'));
|
|
203
204
|
case 'team.overseer':
|
|
204
205
|
return patch({ overseer: isTrue(value) });
|
|
206
|
+
case 'team.overseerIntervalMs':
|
|
207
|
+
return patch(clampOne('overseerIntervalMs'));
|
|
205
208
|
default:
|
|
206
209
|
return null;
|
|
207
210
|
}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -309,10 +309,11 @@ export interface TeamConfig {
|
|
|
309
309
|
* the lead, whose only in-run ceiling is the event-silence idle watchdog
|
|
310
310
|
* a child already keeps. A wedged child still dies on its OWN watchdog.
|
|
311
311
|
*
|
|
312
|
-
* WITH `team.overseer` ON (the default) this
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
312
|
+
* WITH `team.overseer` ON (the default) this NEVER aborts anything
|
|
313
|
+
* (subagent-overseer-v2 D-4): a positive value is only a COMPATIBILITY
|
|
314
|
+
* SOURCE for the supervisor's first cadence check, honouring users who
|
|
315
|
+
* already treated it as a trigger point. The only hard abort left is
|
|
316
|
+
* the legacy regime (`team.overseer: false`).
|
|
316
317
|
*/
|
|
317
318
|
subagentTimeoutMs: number;
|
|
318
319
|
/**
|
|
@@ -329,17 +330,32 @@ export interface TeamConfig {
|
|
|
329
330
|
*/
|
|
330
331
|
maxTurnsPerSubagent: number;
|
|
331
332
|
/**
|
|
332
|
-
* The dispatch supervisor (team-overseer): time
|
|
333
|
-
* become inspection triggers for a fast-tier
|
|
334
|
-
* wait / nudge / replace / abandon, instead of
|
|
333
|
+
* The dispatch supervisor (team-overseer / subagent-overseer-v2): time
|
|
334
|
+
* ceilings on children become inspection triggers for a fast-tier
|
|
335
|
+
* supervisor that decides wait / nudge / replace / abandon, instead of
|
|
336
|
+
* aborts. Default TRUE.
|
|
335
337
|
*
|
|
336
|
-
* READ PER DISPATCH.
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
* a
|
|
338
|
+
* READ PER DISPATCH. The supervisor ticks on a cadence ladder over every
|
|
339
|
+
* live child, and NO timeout is a death sentence while this is on: with
|
|
340
|
+
* the fast tier missing a tick degrades to an announced unassisted wait,
|
|
341
|
+
* never a kill. With this FALSE, children run exactly the pre-feature
|
|
342
|
+
* legacy regime: `subagentTimeoutMs` is a hard abort and silence is the
|
|
343
|
+
* child's own watchdog.
|
|
341
344
|
*/
|
|
342
345
|
overseer: boolean;
|
|
346
|
+
/**
|
|
347
|
+
* Supervisor cadence BASE, in milliseconds (subagent-overseer-v2 D-8).
|
|
348
|
+
* `0` (the default) = the structural default
|
|
349
|
+
* (`TEAM_LIMITS.overseerDefaultCheckMs`, 300 s).
|
|
350
|
+
*
|
|
351
|
+
* EFFECTIVE FIRST CHECK, derived read-only and never written back:
|
|
352
|
+
* `overseerIntervalMs > 0` wins; otherwise a positive
|
|
353
|
+
* `subagentTimeoutMs` is honoured (users who already treated it as a
|
|
354
|
+
* trigger point); otherwise the structural default. Later checks grow
|
|
355
|
+
* by `overseerCadenceRatio` (1.6), clamped to [60 s, 900 s]. Only
|
|
356
|
+
* meaningful while `team.overseer` is true.
|
|
357
|
+
*/
|
|
358
|
+
overseerIntervalMs: number;
|
|
343
359
|
}
|
|
344
360
|
/**
|
|
345
361
|
* The requirement's ceiling on the fan-out (R-g).
|
package/dist/config/schema.js
CHANGED
|
@@ -455,6 +455,8 @@ export const DEFAULT_TEAM_CONFIG = {
|
|
|
455
455
|
// The dispatch supervisor, default ON (team-overseer): ceilings become
|
|
456
456
|
// inspections; the fast-tier supervisor decides what to do.
|
|
457
457
|
overseer: true,
|
|
458
|
+
// 0 = the structural cadence default (300 s). See the field docstring.
|
|
459
|
+
overseerIntervalMs: 0,
|
|
458
460
|
};
|
|
459
461
|
const SUBAGENTS_RANGE = { min: 1, max: HARD_MAX_SUBAGENTS };
|
|
460
462
|
const CONCURRENT_RANGE = { min: 1, max: HARD_MAX_SUBAGENTS };
|
|
@@ -463,6 +465,7 @@ const CONCURRENT_RANGE = { min: 1, max: HARD_MAX_SUBAGENTS };
|
|
|
463
465
|
// ("my setting won't stick"), the exact trap `scrollResumeMs` records above.
|
|
464
466
|
const SUBAGENT_TIMEOUT_RANGE = { min: 0, max: 1_800_000 };
|
|
465
467
|
const DISPATCH_TIMEOUT_RANGE = { min: 0, max: 3_600_000 };
|
|
468
|
+
const OVERSEER_INTERVAL_RANGE = { min: 0, max: 3_600_000 };
|
|
466
469
|
const TURNS_RANGE = { min: 0, max: 100 };
|
|
467
470
|
/**
|
|
468
471
|
* THE single gate for every team-config read AND write, mirroring
|
|
@@ -486,6 +489,7 @@ export function clampTeamConfig(raw) {
|
|
|
486
489
|
dispatchTimeoutMs: clampIntAllowingZero(src.dispatchTimeoutMs, DEFAULT_TEAM_CONFIG.dispatchTimeoutMs, DISPATCH_TIMEOUT_RANGE),
|
|
487
490
|
maxTurnsPerSubagent: clampIntAllowingZero(src.maxTurnsPerSubagent, DEFAULT_TEAM_CONFIG.maxTurnsPerSubagent, TURNS_RANGE),
|
|
488
491
|
overseer: bool(src.overseer, DEFAULT_TEAM_CONFIG.overseer),
|
|
492
|
+
overseerIntervalMs: clampIntAllowingZero(src.overseerIntervalMs, DEFAULT_TEAM_CONFIG.overseerIntervalMs, OVERSEER_INTERVAL_RANGE),
|
|
489
493
|
};
|
|
490
494
|
}
|
|
491
495
|
export const DEFAULT_TODO_CONFIG = {
|
package/dist/team/limits.d.ts
CHANGED
|
@@ -102,11 +102,12 @@ export declare const TEAM_LIMITS: {
|
|
|
102
102
|
readonly maxColdStartRetries: 1;
|
|
103
103
|
readonly retryBackoffMs: 2000;
|
|
104
104
|
/**
|
|
105
|
-
* Wall-clock budget of everything one inspection may carry
|
|
106
|
-
* run facts, the supervisor's own
|
|
107
|
-
* history; unbounded, one look at a
|
|
108
|
-
*
|
|
109
|
-
* FAST_LIMITS.digestMaxChars makes,
|
|
105
|
+
* Wall-clock budget of everything one SINGLE inspection may carry (the
|
|
106
|
+
* silence-triggered path). The digest holds run facts, the supervisor's own
|
|
107
|
+
* memory and the tail of the child's live history; unbounded, one look at a
|
|
108
|
+
* child that read five big files would make the "cheap" supervision call
|
|
109
|
+
* cost more than the child (the argument FAST_LIMITS.digestMaxChars makes,
|
|
110
|
+
* one level up).
|
|
110
111
|
*/
|
|
111
112
|
readonly overseerDigestBytes: 8000;
|
|
112
113
|
/** Clamp on a `nudge` guidance text. Advice, not a second brief. */
|
|
@@ -114,11 +115,48 @@ export declare const TEAM_LIMITS: {
|
|
|
114
115
|
/** Clamp on the decision `reason` recorded in the report. */
|
|
115
116
|
readonly overseerReasonChars: 200;
|
|
116
117
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
118
|
+
* Per-child slice of a BATCH digest (D-3 / R-P2-5). 6.7x tighter than the
|
|
119
|
+
* single-inspection budget above: a batch carries up to ten children in one
|
|
120
|
+
* call, and memory plus the history tail are the first to give way (the
|
|
121
|
+
* facts-first assembly order already puts them last).
|
|
120
122
|
*/
|
|
121
|
-
readonly
|
|
123
|
+
readonly overseerPerChildDigestBytes: 1200;
|
|
124
|
+
/** Whole-batch digest ceiling (D-3): 10 children x 1 200 B fits exactly. */
|
|
125
|
+
readonly overseerBatchDigestBytes: 12000;
|
|
126
|
+
/**
|
|
127
|
+
* Output budget of ONE batch inspection (R-P0-1). The single-inspection path
|
|
128
|
+
* keeps `FAST_LIMITS.reviewOutputTokens` (512); a batch must return up to
|
|
129
|
+
* ten decision objects, and 512 tokens cannot physically hold ten x
|
|
130
|
+
* (reason <= 200 + guidance <= 1200). A truncated batch reply fails
|
|
131
|
+
* "first `[` to last `]`" parsing and degrades to all-wait - exactly the
|
|
132
|
+
* failure this separate, larger budget exists to prevent.
|
|
133
|
+
*/
|
|
134
|
+
readonly overseerBatchOutputTokens: 2048;
|
|
135
|
+
/** Tighter `reason` clamp inside the batch protocol (R-P0-1). */
|
|
136
|
+
readonly overseerBatchReasonChars: 80;
|
|
137
|
+
/** Tighter `guidance` clamp inside the batch protocol (R-P0-1). */
|
|
138
|
+
readonly overseerBatchGuidanceChars: 400;
|
|
139
|
+
/**
|
|
140
|
+
* LOOKS per child per dispatch (D-5). A look is cost, not mutation: every
|
|
141
|
+
* inspection of a child - silence-triggered, cadence tick or post-mortem -
|
|
142
|
+
* spends one, including a call that failed softly. Twelve with the cadence
|
|
143
|
+
* ladder covers hours of healthy slow work; past the budget the supervisor
|
|
144
|
+
* says so once (`trigger: 'quiet'`) and stops waking that child up.
|
|
145
|
+
*/
|
|
146
|
+
readonly overseerMaxLooksPerChild: 12;
|
|
147
|
+
/**
|
|
148
|
+
* LOOKS per dispatch, the fool-proof total (R-P1-6):
|
|
149
|
+
* hardMaxSubagents x overseerMaxLooksPerChild = 120. A mathematical upper
|
|
150
|
+
* bound, not a tuning knob - the per-child budget always binds first; this
|
|
151
|
+
* one exists so a bug cannot loop calls forever. When it trips, the whole
|
|
152
|
+
* MonitorLoop stops with one aggregate notice.
|
|
153
|
+
*/
|
|
154
|
+
readonly overseerMaxLooksPerDispatch: number;
|
|
155
|
+
/**
|
|
156
|
+
* NUDGES per child per dispatch (D-5). Advice is cheap but not free: a
|
|
157
|
+
* supervisor that steers the same child forever is one that never decided.
|
|
158
|
+
*/
|
|
159
|
+
readonly overseerMaxNudgesPerChild: 3;
|
|
122
160
|
/**
|
|
123
161
|
* Rebuilds PER CHILD per dispatch. One: a replacement that also stalls dies
|
|
124
162
|
* on its own watchdog rather than ping-ponging fresh children at a task the
|
|
@@ -126,13 +164,25 @@ export declare const TEAM_LIMITS: {
|
|
|
126
164
|
*/
|
|
127
165
|
readonly overseerMaxReplacementsPerChild: 1;
|
|
128
166
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
167
|
+
* Abandons PER CHILD per dispatch (D-5). One, so a supervisor that has
|
|
168
|
+
* already given up on a brief cannot keep re-killing bodies of it.
|
|
169
|
+
*/
|
|
170
|
+
readonly overseerMaxAbandonsPerChild: 1;
|
|
171
|
+
/**
|
|
172
|
+
* Cadence ladder growth factor (D-2). Each no-action inspection schedules
|
|
173
|
+
* the next `previous * ratio` out, so a healthy slow child is looked at
|
|
174
|
+
* logarithmically in its run time rather than every five minutes.
|
|
175
|
+
*/
|
|
176
|
+
readonly overseerCadenceRatio: 1.6;
|
|
177
|
+
/**
|
|
178
|
+
* First cadence check when neither `team.overseerIntervalMs` nor
|
|
179
|
+
* `team.subagentTimeoutMs` names one (the shipped defaults): the supervisor
|
|
180
|
+
* still looks even when no ceiling was configured.
|
|
131
181
|
*/
|
|
132
182
|
readonly overseerDefaultCheckMs: 300000;
|
|
133
|
-
/** Clamp on
|
|
183
|
+
/** Clamp on a ladder step / model-chosen `nextCheckMs`, lower bound. */
|
|
134
184
|
readonly overseerNextCheckMinMs: 60000;
|
|
135
|
-
/** Clamp on
|
|
185
|
+
/** Clamp on a ladder step / model-chosen `nextCheckMs`, upper bound. */
|
|
136
186
|
readonly overseerNextCheckMaxMs: 900000;
|
|
137
187
|
/**
|
|
138
188
|
* A child's OWN idle watchdog, multiplied by this while the supervisor is
|
|
@@ -142,6 +192,16 @@ export declare const TEAM_LIMITS: {
|
|
|
142
192
|
*/
|
|
143
193
|
readonly overseerWatchdogFactor: 4;
|
|
144
194
|
};
|
|
195
|
+
/**
|
|
196
|
+
* The pseudo-label the runtime's AGGREGATE supervisor notices travel under
|
|
197
|
+
* (subagent-overseer-v2 D-5 / R-P1-6): the dispatch-total look-budget notice
|
|
198
|
+
* is one fact about the whole roster, not a row any child owns. RESERVED at
|
|
199
|
+
* normalization (`normalizeSubagentSpecs` seeds `dedupeLabel` with it), so a
|
|
200
|
+
* spec asking for the bare label `team` is handed `team-2` instead - the
|
|
201
|
+
* report ledger and the exec stream can then never attribute an aggregate
|
|
202
|
+
* notice to a real child, or swallow that child's own quiet note.
|
|
203
|
+
*/
|
|
204
|
+
export declare const TEAM_AGGREGATE_LABEL = "team";
|
|
145
205
|
/**
|
|
146
206
|
* The two comm tools, which are POLICY-EXEMPT inside a child (§3.11).
|
|
147
207
|
*
|
package/dist/team/limits.js
CHANGED
|
@@ -24,13 +24,20 @@
|
|
|
24
24
|
* is 72 000 bytes, so a character-denominated cap would let the executor chop
|
|
25
25
|
* the report mid-section and take the failure count with it.
|
|
26
26
|
*/
|
|
27
|
+
/**
|
|
28
|
+
* The two factors of the dispatch-total look budget (R-P1-6), hoisted only so
|
|
29
|
+
* `TEAM_LIMITS.overseerMaxLooksPerDispatch` can state their product without a
|
|
30
|
+
* second copy of either number. Not for export: the authority is TEAM_LIMITS.
|
|
31
|
+
*/
|
|
32
|
+
const HARD_MAX_SUBAGENTS = 10;
|
|
33
|
+
const OVERSEER_MAX_LOOKS_PER_CHILD = 12;
|
|
27
34
|
export const TEAM_LIMITS = {
|
|
28
35
|
/**
|
|
29
36
|
* The requirement's ceiling (R-g). Enforced in `clampTeamConfig` AND in
|
|
30
37
|
* `normalizeSubagentSpecs`, so neither a hand-edited file nor a model asking
|
|
31
38
|
* for thirty can exceed it.
|
|
32
39
|
*/
|
|
33
|
-
hardMaxSubagents:
|
|
40
|
+
hardMaxSubagents: HARD_MAX_SUBAGENTS,
|
|
34
41
|
// --- Spec normalization (§3.3.1) ---
|
|
35
42
|
/** `SubagentSpec.description`, clamped (never rejected). */
|
|
36
43
|
descriptionChars: 60,
|
|
@@ -106,13 +113,14 @@ export const TEAM_LIMITS = {
|
|
|
106
113
|
* nothing a re-dispatch by the lead would not buy better. */
|
|
107
114
|
maxColdStartRetries: 1,
|
|
108
115
|
retryBackoffMs: 2_000,
|
|
109
|
-
// --- The dispatch supervisor (team-overseer) ---
|
|
116
|
+
// --- The dispatch supervisor (team-overseer / subagent-overseer-v2) ---
|
|
110
117
|
/**
|
|
111
|
-
* Wall-clock budget of everything one inspection may carry
|
|
112
|
-
* run facts, the supervisor's own
|
|
113
|
-
* history; unbounded, one look at a
|
|
114
|
-
*
|
|
115
|
-
* FAST_LIMITS.digestMaxChars makes,
|
|
118
|
+
* Wall-clock budget of everything one SINGLE inspection may carry (the
|
|
119
|
+
* silence-triggered path). The digest holds run facts, the supervisor's own
|
|
120
|
+
* memory and the tail of the child's live history; unbounded, one look at a
|
|
121
|
+
* child that read five big files would make the "cheap" supervision call
|
|
122
|
+
* cost more than the child (the argument FAST_LIMITS.digestMaxChars makes,
|
|
123
|
+
* one level up).
|
|
116
124
|
*/
|
|
117
125
|
overseerDigestBytes: 8_000,
|
|
118
126
|
/** Clamp on a `nudge` guidance text. Advice, not a second brief. */
|
|
@@ -120,11 +128,48 @@ export const TEAM_LIMITS = {
|
|
|
120
128
|
/** Clamp on the decision `reason` recorded in the report. */
|
|
121
129
|
overseerReasonChars: 200,
|
|
122
130
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
131
|
+
* Per-child slice of a BATCH digest (D-3 / R-P2-5). 6.7x tighter than the
|
|
132
|
+
* single-inspection budget above: a batch carries up to ten children in one
|
|
133
|
+
* call, and memory plus the history tail are the first to give way (the
|
|
134
|
+
* facts-first assembly order already puts them last).
|
|
135
|
+
*/
|
|
136
|
+
overseerPerChildDigestBytes: 1_200,
|
|
137
|
+
/** Whole-batch digest ceiling (D-3): 10 children x 1 200 B fits exactly. */
|
|
138
|
+
overseerBatchDigestBytes: 12_000,
|
|
139
|
+
/**
|
|
140
|
+
* Output budget of ONE batch inspection (R-P0-1). The single-inspection path
|
|
141
|
+
* keeps `FAST_LIMITS.reviewOutputTokens` (512); a batch must return up to
|
|
142
|
+
* ten decision objects, and 512 tokens cannot physically hold ten x
|
|
143
|
+
* (reason <= 200 + guidance <= 1200). A truncated batch reply fails
|
|
144
|
+
* "first `[` to last `]`" parsing and degrades to all-wait - exactly the
|
|
145
|
+
* failure this separate, larger budget exists to prevent.
|
|
146
|
+
*/
|
|
147
|
+
overseerBatchOutputTokens: 2_048,
|
|
148
|
+
/** Tighter `reason` clamp inside the batch protocol (R-P0-1). */
|
|
149
|
+
overseerBatchReasonChars: 80,
|
|
150
|
+
/** Tighter `guidance` clamp inside the batch protocol (R-P0-1). */
|
|
151
|
+
overseerBatchGuidanceChars: 400,
|
|
152
|
+
/**
|
|
153
|
+
* LOOKS per child per dispatch (D-5). A look is cost, not mutation: every
|
|
154
|
+
* inspection of a child - silence-triggered, cadence tick or post-mortem -
|
|
155
|
+
* spends one, including a call that failed softly. Twelve with the cadence
|
|
156
|
+
* ladder covers hours of healthy slow work; past the budget the supervisor
|
|
157
|
+
* says so once (`trigger: 'quiet'`) and stops waking that child up.
|
|
158
|
+
*/
|
|
159
|
+
overseerMaxLooksPerChild: 12,
|
|
160
|
+
/**
|
|
161
|
+
* LOOKS per dispatch, the fool-proof total (R-P1-6):
|
|
162
|
+
* hardMaxSubagents x overseerMaxLooksPerChild = 120. A mathematical upper
|
|
163
|
+
* bound, not a tuning knob - the per-child budget always binds first; this
|
|
164
|
+
* one exists so a bug cannot loop calls forever. When it trips, the whole
|
|
165
|
+
* MonitorLoop stops with one aggregate notice.
|
|
126
166
|
*/
|
|
127
|
-
|
|
167
|
+
overseerMaxLooksPerDispatch: HARD_MAX_SUBAGENTS * OVERSEER_MAX_LOOKS_PER_CHILD,
|
|
168
|
+
/**
|
|
169
|
+
* NUDGES per child per dispatch (D-5). Advice is cheap but not free: a
|
|
170
|
+
* supervisor that steers the same child forever is one that never decided.
|
|
171
|
+
*/
|
|
172
|
+
overseerMaxNudgesPerChild: 3,
|
|
128
173
|
/**
|
|
129
174
|
* Rebuilds PER CHILD per dispatch. One: a replacement that also stalls dies
|
|
130
175
|
* on its own watchdog rather than ping-ponging fresh children at a task the
|
|
@@ -132,13 +177,25 @@ export const TEAM_LIMITS = {
|
|
|
132
177
|
*/
|
|
133
178
|
overseerMaxReplacementsPerChild: 1,
|
|
134
179
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
180
|
+
* Abandons PER CHILD per dispatch (D-5). One, so a supervisor that has
|
|
181
|
+
* already given up on a brief cannot keep re-killing bodies of it.
|
|
182
|
+
*/
|
|
183
|
+
overseerMaxAbandonsPerChild: 1,
|
|
184
|
+
/**
|
|
185
|
+
* Cadence ladder growth factor (D-2). Each no-action inspection schedules
|
|
186
|
+
* the next `previous * ratio` out, so a healthy slow child is looked at
|
|
187
|
+
* logarithmically in its run time rather than every five minutes.
|
|
188
|
+
*/
|
|
189
|
+
overseerCadenceRatio: 1.6,
|
|
190
|
+
/**
|
|
191
|
+
* First cadence check when neither `team.overseerIntervalMs` nor
|
|
192
|
+
* `team.subagentTimeoutMs` names one (the shipped defaults): the supervisor
|
|
193
|
+
* still looks even when no ceiling was configured.
|
|
137
194
|
*/
|
|
138
195
|
overseerDefaultCheckMs: 300_000,
|
|
139
|
-
/** Clamp on
|
|
196
|
+
/** Clamp on a ladder step / model-chosen `nextCheckMs`, lower bound. */
|
|
140
197
|
overseerNextCheckMinMs: 60_000,
|
|
141
|
-
/** Clamp on
|
|
198
|
+
/** Clamp on a ladder step / model-chosen `nextCheckMs`, upper bound. */
|
|
142
199
|
overseerNextCheckMaxMs: 900_000,
|
|
143
200
|
/**
|
|
144
201
|
* A child's OWN idle watchdog, multiplied by this while the supervisor is
|
|
@@ -148,6 +205,16 @@ export const TEAM_LIMITS = {
|
|
|
148
205
|
*/
|
|
149
206
|
overseerWatchdogFactor: 4,
|
|
150
207
|
};
|
|
208
|
+
/**
|
|
209
|
+
* The pseudo-label the runtime's AGGREGATE supervisor notices travel under
|
|
210
|
+
* (subagent-overseer-v2 D-5 / R-P1-6): the dispatch-total look-budget notice
|
|
211
|
+
* is one fact about the whole roster, not a row any child owns. RESERVED at
|
|
212
|
+
* normalization (`normalizeSubagentSpecs` seeds `dedupeLabel` with it), so a
|
|
213
|
+
* spec asking for the bare label `team` is handed `team-2` instead - the
|
|
214
|
+
* report ledger and the exec stream can then never attribute an aggregate
|
|
215
|
+
* notice to a real child, or swallow that child's own quiet note.
|
|
216
|
+
*/
|
|
217
|
+
export const TEAM_AGGREGATE_LABEL = 'team';
|
|
151
218
|
/**
|
|
152
219
|
* The two comm tools, which are POLICY-EXEMPT inside a child (§3.11).
|
|
153
220
|
*
|
package/dist/team/normalize.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* honest reading of a stale key is silence, not a report line about a
|
|
25
25
|
* capability that no longer exists.
|
|
26
26
|
*/
|
|
27
|
-
import { TEAM_LIMITS } from './limits.js';
|
|
27
|
+
import { TEAM_AGGREGATE_LABEL, TEAM_LIMITS } from './limits.js';
|
|
28
28
|
function asString(value) {
|
|
29
29
|
return typeof value === 'string' ? value : '';
|
|
30
30
|
}
|
|
@@ -88,7 +88,12 @@ export function normalizeSubagentSpecs(raw, max) {
|
|
|
88
88
|
return { specs: [], requested: 0 };
|
|
89
89
|
const requested = raw.length;
|
|
90
90
|
const kept = [];
|
|
91
|
-
|
|
91
|
+
// SEEDED WITH THE RESERVED AGGREGATE LABEL (subagent-overseer-v2 D-5 /
|
|
92
|
+
// R-P1-6): the runtime's dispatch-total supervisor notices travel under
|
|
93
|
+
// `TEAM_AGGREGATE_LABEL`, so no child may wear that slug - `dedupeLabel`
|
|
94
|
+
// hands a spec asking for it the suffixed form instead, the same namespace
|
|
95
|
+
// fix it already applies to any other collision.
|
|
96
|
+
const taken = new Set([TEAM_AGGREGATE_LABEL]);
|
|
92
97
|
for (let i = 0; i < raw.length; i += 1) {
|
|
93
98
|
const item = raw[i];
|
|
94
99
|
if (!item || typeof item !== 'object')
|