@aragon-agent/cli 0.6.21 → 0.6.23
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 +22 -1
- package/dist/agent/reducer.js +8 -6
- 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/load.js +42 -3
- package/dist/config/schema.d.ts +53 -12
- package/dist/config/schema.js +42 -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 +158 -18
- package/dist/team/overseer.js +356 -49
- 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 +498 -74
- package/dist/team/subagent.d.ts +10 -0
- package/dist/team/subagent.js +20 -6
- package/dist/team/task-tool.d.ts +7 -0
- package/dist/team/task-tool.js +2 -0
- package/dist/team/types.d.ts +44 -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/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')
|
package/dist/team/overseer.d.ts
CHANGED
|
@@ -1,33 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The dispatch supervisor (team-overseer).
|
|
2
|
+
* The dispatch supervisor (team-overseer, upgraded by subagent-overseer-v2).
|
|
3
3
|
*
|
|
4
4
|
* ASCII ONLY: `src/team/**` is inside the glyph scanner's scope
|
|
5
5
|
* (`glyphs.test.ts`), so no literal in this tree may hold a non-ASCII byte.
|
|
6
6
|
*
|
|
7
7
|
* A TIME CEILING ON A CHILD IS AN INSPECTION TRIGGER, NOT A DEATH SENTENCE.
|
|
8
|
-
* When a child stalls (event silence) or
|
|
9
|
-
*
|
|
8
|
+
* When a child stalls (event silence) or a cadence tick comes due, the
|
|
9
|
+
* supervisor looks at it through ONE bounded fast-tier call and decides:
|
|
10
10
|
* keep waiting, steer a nudge in to help it recover, rebuild it with an
|
|
11
11
|
* amended brief, or abandon it with a recorded reason. Only the supervisor
|
|
12
12
|
* "decides"; the RUNTIME applies (see `runtime.ts`), because every child
|
|
13
13
|
* lifecycle change must funnel through the worker loop that awaits it
|
|
14
14
|
* (I-OV1).
|
|
15
15
|
*
|
|
16
|
+
* THE SUPERVISOR IS A NO-LOOP, BOUNDED, REMEMBERED CALLEE - NOT AN AGENT
|
|
17
|
+
* (subagent-overseer-v2 D-1). The requirement says "a dedicated supervising
|
|
18
|
+
* subagent on the fast model"; it is satisfied by a per-dispatch, remembered,
|
|
19
|
+
* cadence-woken caller on the fast tier rather than a real `Agent.prompt()`
|
|
20
|
+
* loop, because a supervisor that can itself wedge needs a second supervisor.
|
|
21
|
+
*
|
|
22
|
+
* TWO INSPECTION SHAPES (D-3). Event silence triggers a SINGLE-child look
|
|
23
|
+
* (fast reaction to a suspected stall, unchanged from round 1); the cadence
|
|
24
|
+
* ladder triggers a BATCH look that carries every live child in one digest
|
|
25
|
+
* and returns one JSON array of per-child decisions. The batch call carries
|
|
26
|
+
* its own output budget (`overseerBatchOutputTokens`, R-P0-1): a full
|
|
27
|
+
* ten-child reply does not physically fit in the single-inspection 512
|
|
28
|
+
* tokens, and a truncated reply would parse to nothing - all wait, exactly
|
|
29
|
+
* when help is most needed.
|
|
30
|
+
*
|
|
16
31
|
* THE TRANSPORT IS THE REVIEWER'S, DELIBERATELY. One `complete` call, no
|
|
17
|
-
* tools, thinking off, temperature 0, output capped
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
32
|
+
* tools, thinking off, temperature 0, output capped (512 single /
|
|
33
|
+
* 2048 batch) and wall clock at `FAST_LIMITS.reviewTimeoutMs` — a
|
|
34
|
+
* supervision call that could itself hang would need a second supervisor,
|
|
35
|
+
* which is the regress this design refuses.
|
|
21
36
|
*
|
|
22
37
|
* REPAIR, NEVER REJECT (the `normalizeSubagentSpecs` rule). An unparseable
|
|
23
38
|
* or out-of-budget decision becomes `wait` with the default interval: the
|
|
24
39
|
* failure mode of a supervisor must be "looked and let it run", never
|
|
25
|
-
* "looked and killed it" (I-OV2).
|
|
40
|
+
* "looked and killed it" (I-OV2). In a batch, one bad ENTRY degrades only
|
|
41
|
+
* that entry; a wholly unparseable reply degrades the whole batch to wait
|
|
42
|
+
* with zero action side effects (R-P0-1 / AC-13).
|
|
26
43
|
*/
|
|
27
|
-
import type { AssistantMessage, LLMRequest, Message } from '@aragon-agent/core';
|
|
44
|
+
import type { AssistantMessage, LLMRequest, Message, TokenUsage } from '@aragon-agent/core';
|
|
28
45
|
import type { ModelRole } from '../config/model-profiles.js';
|
|
29
46
|
import type { CliConfig } from '../config/schema.js';
|
|
30
47
|
import type { OverseerAction, OverseerDecision, SubagentRun, SubagentSpec } from './types.js';
|
|
48
|
+
/**
|
|
49
|
+
* Bumped whenever either supervisor protocol prompt changes (D-9), so a
|
|
50
|
+
* behaviour report can be tied to a prompt revision with one grep.
|
|
51
|
+
* `TEAM_BLOCK_VERSION` covers only the LEAD's `<team>` block, not these.
|
|
52
|
+
*
|
|
53
|
+
* v3 adds the turn-cap trigger to the single-inspection prompt (F-8 A'2).
|
|
54
|
+
*/
|
|
55
|
+
export declare const OVERSEER_PROMPT_VERSION = "v3-2026-10";
|
|
31
56
|
/** One remembered decision, so the second look knows the first happened. */
|
|
32
57
|
export interface OverseerMemoryEntry {
|
|
33
58
|
/** Seconds into the dispatch. */
|
|
@@ -40,7 +65,7 @@ export interface ChildDigestInput {
|
|
|
40
65
|
run: SubagentRun;
|
|
41
66
|
/** False only in the post-mortem inspection, after the child settled. */
|
|
42
67
|
childAlive: boolean;
|
|
43
|
-
trigger: 'silence' | 'clock' | 'postmortem';
|
|
68
|
+
trigger: 'silence' | 'clock' | 'turncap' | 'postmortem';
|
|
44
69
|
/** The child's LIVE history (`SubagentAgentLike.state.messages`). */
|
|
45
70
|
messages: readonly Message[];
|
|
46
71
|
memory: readonly OverseerMemoryEntry[];
|
|
@@ -57,6 +82,38 @@ export interface ChildDigestInput {
|
|
|
57
82
|
* is worse than one missing the fifth message back.
|
|
58
83
|
*/
|
|
59
84
|
export declare function buildChildDigest(input: ChildDigestInput): string;
|
|
85
|
+
/**
|
|
86
|
+
* The per-child sections of one batch payload (D-3).
|
|
87
|
+
*
|
|
88
|
+
* SORTED BY LABEL so the same roster produces the byte-identical payload -
|
|
89
|
+
* the batch is the one place where ordering is observable to the model and
|
|
90
|
+
* to every test that asserts on it. Each child's digest is clamped to
|
|
91
|
+
* `overseerPerChildDigestBytes` (facts first, history tail last - R-P2-5).
|
|
92
|
+
* The whole-batch ceiling is applied by the joiner in the provider request.
|
|
93
|
+
*/
|
|
94
|
+
export declare function buildBatchSections(children: readonly ChildDigestInput[]): Array<{
|
|
95
|
+
label: string;
|
|
96
|
+
goal: string;
|
|
97
|
+
digest: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* The FIRST cadence check, from the D-8 priority: `overseerIntervalMs` when
|
|
101
|
+
* the user named one; otherwise a positive `subagentTimeoutMs` (compat with
|
|
102
|
+
* users who already treated it as a trigger); otherwise the structural
|
|
103
|
+
* default. Read-only derivation - the user's stored config is never
|
|
104
|
+
* rewritten to "resolve" this.
|
|
105
|
+
*/
|
|
106
|
+
export declare function resolveOverseerFirstCheckMs(team: {
|
|
107
|
+
overseerIntervalMs: number;
|
|
108
|
+
subagentTimeoutMs: number;
|
|
109
|
+
}): number;
|
|
110
|
+
/**
|
|
111
|
+
* The next ladder step after one that produced no action: grow by
|
|
112
|
+
* `overseerCadenceRatio`, clamped to the structural range. With the shipped
|
|
113
|
+
* 300 s base the checks land at 300 / 780 / 1548 / 2448 / ... seconds - a
|
|
114
|
+
* healthy slow child is looked at logarithmically in its run time (AC-11).
|
|
115
|
+
*/
|
|
116
|
+
export declare function nextOverseerLadderStepMs(previousMs: number): number;
|
|
60
117
|
/** Clamp a model-chosen next check into the structural range. */
|
|
61
118
|
export declare function clampNextCheckMs(ms: unknown): number | undefined;
|
|
62
119
|
/**
|
|
@@ -66,6 +123,10 @@ export declare function clampNextCheckMs(ms: unknown): number | undefined;
|
|
|
66
123
|
* replaced or abandoned, never waited on or nudged, so those normalize to
|
|
67
124
|
* `abandon` rather than being rejected — a post-mortem answer the protocol
|
|
68
125
|
* cannot honour must still produce a decision the runtime can apply.
|
|
126
|
+
*
|
|
127
|
+
* The single-inspection char limits (200/1200) are the defaults here; the
|
|
128
|
+
* batch path calls `normalizeWithLimits` directly with the tighter protocol
|
|
129
|
+
* limits (R-P0-1).
|
|
69
130
|
*/
|
|
70
131
|
export declare function normalizeOverseerDecision(raw: unknown, childAlive: boolean): OverseerDecision;
|
|
71
132
|
/**
|
|
@@ -76,16 +137,47 @@ export declare function normalizeOverseerDecision(raw: unknown, childAlive: bool
|
|
|
76
137
|
* `wait` — the caller never sees a throw from parsing.
|
|
77
138
|
*/
|
|
78
139
|
export declare function parseOverseerDecisionText(text: string, childAlive: boolean): OverseerDecision;
|
|
79
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Parse the model's answer text as a JSON ARRAY of per-child decisions (D-3).
|
|
142
|
+
*
|
|
143
|
+
* Same forgiving span rule as the single path - first `[` to last `]` - and
|
|
144
|
+
* the same failure semantics: a reply that is not an array (prose, a single
|
|
145
|
+
* object, or TRUNCATED output with no closing `]`) is `[]`, which the caller
|
|
146
|
+
* turns into all-wait with zero action side effects (R-P0-1 / AC-13). Never
|
|
147
|
+
* throws.
|
|
148
|
+
*/
|
|
149
|
+
export declare function parseOverseerBatchText(text: string): unknown[];
|
|
150
|
+
/**
|
|
151
|
+
* The slice the runtime needs: "can you look?", "decide", "what did looking
|
|
152
|
+
* cost?". The provider is the CALL boundary; `TeamOverseer` owns budgets,
|
|
153
|
+
* memory and normalization, so a stub in a test scripts decisions by
|
|
154
|
+
* returning objects or arrays and nothing else.
|
|
155
|
+
*/
|
|
80
156
|
export interface OverseerProvider {
|
|
81
|
-
/** Live predicate, re-read per dispatch
|
|
157
|
+
/** Live predicate, re-read per tick: this, not the dispatch-time value, decides assisted vs unassisted (R-P0-2). */
|
|
82
158
|
active(): boolean;
|
|
83
|
-
/** One bounded decision call.
|
|
159
|
+
/** One bounded SINGLE-child decision call (silence path). Must not throw. */
|
|
84
160
|
inspect(req: {
|
|
85
161
|
label: string;
|
|
86
162
|
goal: string;
|
|
87
163
|
digest: string;
|
|
88
164
|
}): Promise<OverseerDecision>;
|
|
165
|
+
/**
|
|
166
|
+
* One bounded BATCH call (cadence path, D-3). Returns the RAW reply - the
|
|
167
|
+
* fast provider answers the assistant TEXT - for `TeamOverseer` to parse
|
|
168
|
+
* and normalize. Must not throw.
|
|
169
|
+
*/
|
|
170
|
+
inspectBatch(req: ReadonlyArray<{
|
|
171
|
+
label: string;
|
|
172
|
+
goal: string;
|
|
173
|
+
digest: string;
|
|
174
|
+
}>): Promise<unknown>;
|
|
175
|
+
/**
|
|
176
|
+
* Everything this provider has spent on inspection calls (D-7, honest
|
|
177
|
+
* accounting). Read once by the runtime at dispatch end; there is exactly
|
|
178
|
+
* one accounting of it and no second aggregation path.
|
|
179
|
+
*/
|
|
180
|
+
usage(): TokenUsage;
|
|
89
181
|
}
|
|
90
182
|
/** Everything the fast-tier-backed provider needs from the session. */
|
|
91
183
|
export interface FastOverseerDeps {
|
|
@@ -102,13 +194,18 @@ export interface FastOverseerDeps {
|
|
|
102
194
|
* The fast-tier-backed provider, mirroring `createChildReviewer`'s shape so
|
|
103
195
|
* the controller wires it the same way: shared transport, live predicates,
|
|
104
196
|
* fail-soft (any failure resolves to `wait` — I-OV2).
|
|
197
|
+
*
|
|
198
|
+
* USAGE IS ACCUMULATED HERE (D-7), off every `AssistantMessage` the shared
|
|
199
|
+
* transport returns, along the same `usageOf` / `accumulateUsage` path the
|
|
200
|
+
* fast reviewer already proved. A reply without a usage block contributes
|
|
201
|
+
* nothing rather than a fabricated zero-cost total.
|
|
105
202
|
*/
|
|
106
203
|
export declare function createFastOverseerProvider(deps: FastOverseerDeps): OverseerProvider;
|
|
107
204
|
/** One inspection request, as the runtime builds it. */
|
|
108
205
|
export interface OverseerInspectRequest {
|
|
109
206
|
run: SubagentRun;
|
|
110
207
|
messages: readonly Message[];
|
|
111
|
-
trigger: 'silence' | 'clock' | 'postmortem';
|
|
208
|
+
trigger: 'silence' | 'clock' | 'turncap' | 'postmortem';
|
|
112
209
|
childAlive: boolean;
|
|
113
210
|
}
|
|
114
211
|
export interface TeamOverseerOptions {
|
|
@@ -123,27 +220,70 @@ export declare const OVERSEER_DEFAULT_NEXT_CHECK_MS: 300000;
|
|
|
123
220
|
* THE CLASS NEVER TOUCHES A CHILD (I-OV1). It looks and decides; `runtime.ts`
|
|
124
221
|
* steers, flags, aborts and rebuilds, because only the worker loop can apply
|
|
125
222
|
* a lifecycle change without orphaning the replacement.
|
|
223
|
+
*
|
|
224
|
+
* LOOKS AND ACTIONS ARE SEPARATE LEDGERS (D-5). A LOOK is cost: every
|
|
225
|
+
* inspection of a child spends one, including a call that failed softly -
|
|
226
|
+
* which is what closes G-6 (a flaky transport used to burn the budget the
|
|
227
|
+
* same as a decision, and the supervisor went quiet exactly when the team
|
|
228
|
+
* was hardest to see). An ACTION is a mutation (nudge / replace / abandon)
|
|
229
|
+
* and is counted only when the runtime APPLIES it, through the `note*`
|
|
230
|
+
* methods below. A label skipped because an inspection is already in flight
|
|
231
|
+
* spends NOTHING (R-P1-4).
|
|
126
232
|
*/
|
|
127
233
|
export declare class TeamOverseer {
|
|
128
234
|
private readonly provider;
|
|
129
235
|
private readonly options;
|
|
130
236
|
private readonly memory;
|
|
131
|
-
private readonly
|
|
237
|
+
private readonly looks;
|
|
238
|
+
private readonly nudges;
|
|
132
239
|
private readonly replacements;
|
|
240
|
+
private readonly abandons;
|
|
133
241
|
private readonly inFlight;
|
|
242
|
+
private looksTotal;
|
|
243
|
+
private callCount;
|
|
134
244
|
constructor(provider: OverseerProvider, options: TeamOverseerOptions);
|
|
135
245
|
/** Never throws: a provider bug must not take the dispatch down. */
|
|
136
246
|
isActive(): boolean;
|
|
137
|
-
|
|
247
|
+
/** Whether ANY inspection of `label` is in flight (single or batch). */
|
|
248
|
+
isInFlight(label: string): boolean;
|
|
249
|
+
/** Per-child look budget spent (D-5). */
|
|
250
|
+
looksExhausted(label: string): boolean;
|
|
251
|
+
/** The fool-proof dispatch-wide total (R-P1-6). */
|
|
252
|
+
dispatchLooksExhausted(): boolean;
|
|
253
|
+
nudgesLeft(label: string): boolean;
|
|
138
254
|
replacementsLeft(label: string): boolean;
|
|
255
|
+
abandonsLeft(label: string): boolean;
|
|
256
|
+
/** Called by the runtime when it APPLIES a nudge, not when it merely reads one. */
|
|
257
|
+
noteNudge(label: string): void;
|
|
139
258
|
/** Called by the runtime when it APPLIES a replace, not when it merely reads one. */
|
|
140
259
|
noteReplacement(label: string): void;
|
|
260
|
+
/** Called by the runtime when it APPLIES an abandon, not when it merely reads one. */
|
|
261
|
+
noteAbandon(label: string): void;
|
|
262
|
+
/** The provider's own accumulated inspection spend (D-7), zero when unreadable. */
|
|
263
|
+
usage(): TokenUsage;
|
|
264
|
+
/** Provider invocations, including ones that failed softly (D-7). */
|
|
265
|
+
calls(): number;
|
|
141
266
|
/**
|
|
142
|
-
* ONE inspection
|
|
143
|
-
*
|
|
267
|
+
* ONE single-child inspection (the silence-triggered path, round-1
|
|
268
|
+
* behaviour preserved). `null` means QUIET — not active, no budget left, or
|
|
269
|
+
* one already in flight for this child — and the caller then does nothing,
|
|
144
270
|
* which is exactly what quiet should do.
|
|
145
271
|
*/
|
|
146
272
|
inspect(req: OverseerInspectRequest): Promise<OverseerDecision | null>;
|
|
273
|
+
/**
|
|
274
|
+
* ONE batch inspection over every requested child (the cadence path, D-3):
|
|
275
|
+
* a single fast-tier call, a JSON array back, one decision per child.
|
|
276
|
+
*
|
|
277
|
+
* SKIPS FIRST, CALLS SECOND (R-P1-4): a label whose single inspection is
|
|
278
|
+
* still in flight, or whose look budget is spent, simply gets NO entry -
|
|
279
|
+
* no decision, no look charged, ladder untouched by the caller. A label
|
|
280
|
+
* that IS carried but whose reply entry is missing or garbage gets `wait`
|
|
281
|
+
* (repair, never reject). A wholly unparseable or truncated reply is ALL
|
|
282
|
+
* wait with zero action side effects (R-P0-1 / AC-13).
|
|
283
|
+
*/
|
|
284
|
+
inspectBatch(reqs: readonly OverseerInspectRequest[]): Promise<Map<string, OverseerDecision>>;
|
|
285
|
+
private spendLook;
|
|
286
|
+
private remember;
|
|
147
287
|
}
|
|
148
288
|
/**
|
|
149
289
|
* Prepend the supervisor's note to a spec's prompt, bounding the TOTAL to
|