@wrongstack/core 0.299.0 → 0.300.0
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/dist/coordination/director.d.ts +8 -0
- package/dist/coordination/fleet-manager.d.ts +48 -3
- package/dist/coordination/ifleet-manager.d.ts +2 -0
- package/dist/coordination/index.js +120 -20
- package/dist/coordination/multi-agent-coordinator.d.ts +1 -0
- package/dist/core/fallback-model.d.ts +48 -0
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.js +226 -26
- package/dist/core/instruction-template.d.ts +80 -0
- package/dist/core/system-prompt-blocks.d.ts +10 -1
- package/dist/core/system-prompt-builder.d.ts +35 -1
- package/dist/defaults/index.js +238 -99
- package/dist/execution/autonomy-brain.d.ts +7 -0
- package/dist/execution/council-brain.d.ts +11 -0
- package/dist/execution/council-orchestrator.d.ts +23 -4
- package/dist/execution/council-prompts.d.ts +12 -1
- package/dist/execution/index.js +355 -138
- package/dist/fleet-notifier.d.ts +9 -2
- package/dist/hooks/index.js +8 -4
- package/dist/hq/index.js +18 -4
- package/dist/hq/protocol/fleet.d.ts +20 -0
- package/dist/hq/protocol.js +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1512 -707
- package/dist/kernel/events/brain-events.d.ts +9 -0
- package/dist/kernel/events/provider-events.d.ts +42 -1
- package/dist/models/index.js +1 -1
- package/dist/plugin/api.d.ts +6 -0
- package/dist/plugin/config.d.ts +55 -0
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.js +134 -21
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +157 -42
- package/dist/security/permission-helpers.d.ts +23 -6
- package/dist/security/permission-policy.d.ts +16 -0
- package/dist/security/totp.d.ts +14 -0
- package/dist/storage/director-state.d.ts +7 -0
- package/dist/storage/index.js +33 -8
- package/dist/tools/fallback-system-config-view-tool.d.ts +1 -1
- package/dist/tools/index.js +388 -102
- package/dist/types/council.d.ts +11 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/multi-agent.d.ts +10 -0
- package/dist/types/one-shot-llm.d.ts +9 -0
- package/dist/types/plugin.d.ts +28 -0
- package/dist/worktree/index.js +4 -4
- package/instructions/system-lite.md +81 -3
- package/instructions/system-pro.md +275 -90
- package/instructions/system.md +228 -81
- package/package.json +3 -3
|
@@ -149,5 +149,13 @@ export declare class Director implements DirectorFleetHost, ICoordinator {
|
|
|
149
149
|
acquireCheckpointLock(): Promise<boolean>;
|
|
150
150
|
spawnCollab(options: CollabSessionOptions): Promise<CollabDebugReport>;
|
|
151
151
|
resumeFromCheckpoint(snapshot: DirectorStateSnapshot): void;
|
|
152
|
+
/**
|
|
153
|
+
* After re-attaching checkpoint metadata, pin the live maxSpawns ceiling
|
|
154
|
+
* (profile/flag/env wins over historical checkpoint metadata). The
|
|
155
|
+
* historical cumulative spawn counter is deliberately NOT restored — the
|
|
156
|
+
* lifetime budget is scoped to this director run, so a restarted session
|
|
157
|
+
* resumes with a fresh budget rather than a possibly-exhausted counter.
|
|
158
|
+
*/
|
|
159
|
+
private applyResumeBudget;
|
|
152
160
|
}
|
|
153
161
|
//# sourceMappingURL=director.d.ts.map
|
|
@@ -72,6 +72,14 @@ export declare class FleetManager implements IFleetManager {
|
|
|
72
72
|
readonly spawnDepth: number;
|
|
73
73
|
/** Live spawn counter. */
|
|
74
74
|
private spawnCount;
|
|
75
|
+
/**
|
|
76
|
+
* Historical `maxSpawns` from the last restored checkpoint (set for any
|
|
77
|
+
* finite checkpoint ceiling, matching or not). Surfaced in
|
|
78
|
+
* `budgetSnapshot()` so operators can see resume reconciliation without
|
|
79
|
+
* reading the JSON file; `ceilingMismatch` carries the actual mismatch signal.
|
|
80
|
+
*/
|
|
81
|
+
private checkpointMaxSpawnsAtResume;
|
|
82
|
+
private ceilingMismatchAtResume;
|
|
75
83
|
private readonly stateCheckpoint;
|
|
76
84
|
private readonly sessionWriter;
|
|
77
85
|
private manifestTimer;
|
|
@@ -129,7 +137,7 @@ export declare class FleetManager implements IFleetManager {
|
|
|
129
137
|
* which cap was exceeded. Does NOT throw — the caller decides
|
|
130
138
|
* how to surface the rejection.
|
|
131
139
|
*/
|
|
132
|
-
canSpawn(
|
|
140
|
+
canSpawn(config: SubagentConfig): {
|
|
133
141
|
kind: 'max_spawns' | 'max_spawn_depth' | 'max_cost_usd' | 'max_tokens' | 'max_context_load';
|
|
134
142
|
limit: number;
|
|
135
143
|
observed: number;
|
|
@@ -144,6 +152,41 @@ export declare class FleetManager implements IFleetManager {
|
|
|
144
152
|
maxCostUsd: number;
|
|
145
153
|
usedCostUsd: number;
|
|
146
154
|
remainingCostUsd: number;
|
|
155
|
+
/** Historical ceiling from the last restored checkpoint, when it differs. */
|
|
156
|
+
checkpointMaxSpawns?: number | undefined;
|
|
157
|
+
/** True when checkpoint metadata and the live ceiling disagree. */
|
|
158
|
+
ceilingMismatch?: boolean | undefined;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Re-attach the on-disk checkpoint after a resume while keeping the live
|
|
162
|
+
* `maxSpawns` ceiling from construction (profile / flag / env). The
|
|
163
|
+
* historical `spawnCount` is deliberately NOT restored: the lifetime
|
|
164
|
+
* budget is scoped to this director run, so a restarted session gets a
|
|
165
|
+
* fresh budget instead of inheriting a (possibly exhausted) counter from
|
|
166
|
+
* before the restart. The checkpoint ceiling is rewritten to the live
|
|
167
|
+
* value so subsequent writes do not reintroduce a stale limit.
|
|
168
|
+
*/
|
|
169
|
+
restoreFromCheckpoint(snapshot: {
|
|
170
|
+
spawnCount: number;
|
|
171
|
+
maxSpawns?: number | undefined;
|
|
172
|
+
version?: 1 | undefined;
|
|
173
|
+
directorRunId?: string | undefined;
|
|
174
|
+
updatedAt?: string | undefined;
|
|
175
|
+
spawnDepth?: number | undefined;
|
|
176
|
+
maxSpawnDepth?: number | undefined;
|
|
177
|
+
directorBudget?: {
|
|
178
|
+
maxCostUsd?: number | undefined;
|
|
179
|
+
maxTokens?: number | undefined;
|
|
180
|
+
} | undefined;
|
|
181
|
+
subagents?: unknown[] | undefined;
|
|
182
|
+
tasks?: unknown[] | undefined;
|
|
183
|
+
usage?: unknown | undefined;
|
|
184
|
+
}): {
|
|
185
|
+
usedSpawns: number;
|
|
186
|
+
maxSpawns: number;
|
|
187
|
+
remainingSpawns: number;
|
|
188
|
+
checkpointMaxSpawns?: number | undefined;
|
|
189
|
+
ceilingMismatch: boolean;
|
|
147
190
|
};
|
|
148
191
|
setLeaderContextPressure(tokens: number): void;
|
|
149
192
|
/** Test-only accessor: number of entries in the private subagent-meta map. */
|
|
@@ -175,8 +218,10 @@ export declare class FleetManager implements IFleetManager {
|
|
|
175
218
|
*/
|
|
176
219
|
get usedNicknames(): ReadonlySet<string>;
|
|
177
220
|
/**
|
|
178
|
-
* Records a spawn:
|
|
179
|
-
*
|
|
221
|
+
* Records a spawn: stores metadata, updates state checkpoint, and schedules
|
|
222
|
+
* a debounced manifest write. Increments the lifetime spawn counter UNLESS
|
|
223
|
+
* the config is `spawnBudgetExempt` (ephemeral Chimera reviewer/cascade
|
|
224
|
+
* spawns do not consume the leader's budget). Call AFTER the coordinator
|
|
180
225
|
* has successfully spawned the subagent.
|
|
181
226
|
*
|
|
182
227
|
* @param subagentId The subagent's id (from coordinator.spawn result)
|
|
@@ -52,6 +52,8 @@ export interface IFleetManager {
|
|
|
52
52
|
maxCostUsd: number;
|
|
53
53
|
usedCostUsd: number;
|
|
54
54
|
remainingCostUsd: number;
|
|
55
|
+
checkpointMaxSpawns?: number | undefined;
|
|
56
|
+
ceilingMismatch?: boolean | undefined;
|
|
55
57
|
}) | undefined;
|
|
56
58
|
/**
|
|
57
59
|
* Update the leader agent's current context pressure (tokens used in the
|
|
@@ -6758,16 +6758,21 @@ var BrainMonitor = class {
|
|
|
6758
6758
|
this.activeRuns += 1;
|
|
6759
6759
|
this.lastProgressAt = Date.now();
|
|
6760
6760
|
}),
|
|
6761
|
+
// `agent.run.completed` is the only terminator. `Agent.run` emits it on
|
|
6762
|
+
// every exit path — the success path and, unconditionally, the catch
|
|
6763
|
+
// path — and emits `agent.run.error` *in addition* when a run fails
|
|
6764
|
+
// (`core/agent.ts:302` then `:310`). Decrementing on both meant one
|
|
6765
|
+
// failed run subtracted two, and the `Math.max(0, …)` clamp hid it
|
|
6766
|
+
// instead of letting the counter go visibly negative.
|
|
6767
|
+
//
|
|
6768
|
+
// The effect was that the watchdog below stopped watching: with two
|
|
6769
|
+
// concurrent runs where one fails, `activeRuns` reaches 0 while a run
|
|
6770
|
+
// is still live, and the stall check returns early on every tick.
|
|
6761
6771
|
this.opts.events.on("agent.run.completed", (e) => {
|
|
6762
6772
|
const lsid = this.resolveLeaderSessionId();
|
|
6763
6773
|
if (lsid && e.sessionId && e.sessionId !== lsid) return;
|
|
6764
6774
|
this.activeRuns = Math.max(0, this.activeRuns - 1);
|
|
6765
6775
|
}),
|
|
6766
|
-
this.opts.events.on("agent.run.error", (e) => {
|
|
6767
|
-
const lsid = this.resolveLeaderSessionId();
|
|
6768
|
-
if (lsid && e.sessionId && e.sessionId !== lsid) return;
|
|
6769
|
-
this.activeRuns = Math.max(0, this.activeRuns - 1);
|
|
6770
|
-
}),
|
|
6771
6776
|
this.opts.events.on("iteration.started", (e) => {
|
|
6772
6777
|
const lsid = this.resolveLeaderSessionId();
|
|
6773
6778
|
if (lsid && e.sessionId && e.sessionId !== lsid) return;
|
|
@@ -9783,6 +9788,21 @@ var DirectorStateCheckpoint = class {
|
|
|
9783
9788
|
resume(snapshot) {
|
|
9784
9789
|
this.snapshot = snapshot;
|
|
9785
9790
|
}
|
|
9791
|
+
/**
|
|
9792
|
+
* After resume, pin the live spawn ceiling from the current profile/flag
|
|
9793
|
+
* while preserving `spawnCount` (cumulative used budget). Checkpoint
|
|
9794
|
+
* metadata previously stored a historical `maxSpawns` that can diverge
|
|
9795
|
+
* from the live runtime ceiling — operators need the live value to win.
|
|
9796
|
+
*/
|
|
9797
|
+
applyLiveMaxSpawns(maxSpawns) {
|
|
9798
|
+
if (this.snapshot.maxSpawns === maxSpawns) return;
|
|
9799
|
+
this.snapshot = {
|
|
9800
|
+
...this.snapshot,
|
|
9801
|
+
maxSpawns
|
|
9802
|
+
};
|
|
9803
|
+
this.bumpUpdatedAt();
|
|
9804
|
+
this.schedule();
|
|
9805
|
+
}
|
|
9786
9806
|
current() {
|
|
9787
9807
|
return this.snapshot;
|
|
9788
9808
|
}
|
|
@@ -13526,7 +13546,7 @@ async function spawn2(host, config, priceLookup) {
|
|
|
13526
13546
|
if (host.spawnDepth >= maxSpawnDepth) {
|
|
13527
13547
|
throw new FleetSpawnBudgetError("max_spawn_depth", maxSpawnDepth, host.spawnDepth);
|
|
13528
13548
|
}
|
|
13529
|
-
if (host.spawnCount >= host.maxSpawns) {
|
|
13549
|
+
if (host.spawnCount >= host.maxSpawns && !config.spawnBudgetExempt) {
|
|
13530
13550
|
throw new FleetSpawnBudgetError("max_spawns", host.maxSpawns, host.spawnCount + 1);
|
|
13531
13551
|
}
|
|
13532
13552
|
if (host.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
|
|
@@ -13577,7 +13597,9 @@ async function spawn2(host, config, priceLookup) {
|
|
|
13577
13597
|
...Number.isFinite(budget?.remainingSpawns ?? host.maxSpawns - host.spawnCount) ? {
|
|
13578
13598
|
remainingSpawns: Math.max(
|
|
13579
13599
|
0,
|
|
13580
|
-
|
|
13600
|
+
// Exempt spawns don't consume leader budget, so the reported
|
|
13601
|
+
// headroom is not decremented for them.
|
|
13602
|
+
(budget?.remainingSpawns ?? host.maxSpawns - host.spawnCount) - (config.spawnBudgetExempt ? 0 : 1)
|
|
13581
13603
|
)
|
|
13582
13604
|
} : {},
|
|
13583
13605
|
...Number.isFinite(maxFleetTokens) ? { maxTokens: maxFleetTokens } : {},
|
|
@@ -13590,7 +13612,9 @@ async function spawn2(host, config, priceLookup) {
|
|
|
13590
13612
|
if (host.fleetManager) {
|
|
13591
13613
|
host.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
|
|
13592
13614
|
} else {
|
|
13593
|
-
|
|
13615
|
+
if (!config.spawnBudgetExempt) {
|
|
13616
|
+
host.spawnCount += 1;
|
|
13617
|
+
}
|
|
13594
13618
|
host.subagentMeta.set(result.subagentId, {
|
|
13595
13619
|
provider: config.provider,
|
|
13596
13620
|
model: config.model
|
|
@@ -14515,8 +14539,17 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
14515
14539
|
durationMs: 0
|
|
14516
14540
|
};
|
|
14517
14541
|
this.completedResults.push(synthetic);
|
|
14542
|
+
this.trimCompletedResults();
|
|
14518
14543
|
this.emit("task.completed", { task, result: synthetic });
|
|
14519
14544
|
}
|
|
14545
|
+
trimCompletedResults() {
|
|
14546
|
+
if (this.completedResults.length > _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS) {
|
|
14547
|
+
this.completedResults.splice(
|
|
14548
|
+
0,
|
|
14549
|
+
this.completedResults.length - _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS
|
|
14550
|
+
);
|
|
14551
|
+
}
|
|
14552
|
+
}
|
|
14520
14553
|
async runDispatched(subagentId, task) {
|
|
14521
14554
|
const subagent = this.subagents.get(subagentId);
|
|
14522
14555
|
if (!subagent) return;
|
|
@@ -14650,12 +14683,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
|
|
|
14650
14683
|
}
|
|
14651
14684
|
recordCompletion(result) {
|
|
14652
14685
|
this.completedResults.push(result);
|
|
14653
|
-
|
|
14654
|
-
this.completedResults.splice(
|
|
14655
|
-
0,
|
|
14656
|
-
this.completedResults.length - _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS
|
|
14657
|
-
);
|
|
14658
|
-
}
|
|
14686
|
+
this.trimCompletedResults();
|
|
14659
14687
|
this.totalIterations += result.iterations;
|
|
14660
14688
|
if (this.inFlight > 0) {
|
|
14661
14689
|
this.inFlight--;
|
|
@@ -19297,6 +19325,7 @@ var Director = class _Director {
|
|
|
19297
19325
|
}
|
|
19298
19326
|
setCheckpointState(snapshot) {
|
|
19299
19327
|
setCheckpointState(this.checkpointHost(), snapshot);
|
|
19328
|
+
this.applyResumeBudget(snapshot);
|
|
19300
19329
|
}
|
|
19301
19330
|
async readSession(subagentId, tail) {
|
|
19302
19331
|
return readDirectorSubagentSession({
|
|
@@ -19348,6 +19377,22 @@ var Director = class _Director {
|
|
|
19348
19377
|
}
|
|
19349
19378
|
resumeFromCheckpoint(snapshot) {
|
|
19350
19379
|
resumeFromCheckpoint(this.checkpointHost(), snapshot);
|
|
19380
|
+
this.applyResumeBudget(snapshot);
|
|
19381
|
+
}
|
|
19382
|
+
/**
|
|
19383
|
+
* After re-attaching checkpoint metadata, pin the live maxSpawns ceiling
|
|
19384
|
+
* (profile/flag/env wins over historical checkpoint metadata). The
|
|
19385
|
+
* historical cumulative spawn counter is deliberately NOT restored — the
|
|
19386
|
+
* lifetime budget is scoped to this director run, so a restarted session
|
|
19387
|
+
* resumes with a fresh budget rather than a possibly-exhausted counter.
|
|
19388
|
+
*/
|
|
19389
|
+
applyResumeBudget(snapshot) {
|
|
19390
|
+
if (this.fleetManager) {
|
|
19391
|
+
this.fleetManager.restoreFromCheckpoint(snapshot);
|
|
19392
|
+
}
|
|
19393
|
+
this.stateCheckpoint?.applyLiveMaxSpawns(
|
|
19394
|
+
Number.isFinite(this.maxSpawns) ? this.maxSpawns : void 0
|
|
19395
|
+
);
|
|
19351
19396
|
}
|
|
19352
19397
|
};
|
|
19353
19398
|
|
|
@@ -19370,6 +19415,14 @@ var FleetManager = class {
|
|
|
19370
19415
|
spawnDepth;
|
|
19371
19416
|
/** Live spawn counter. */
|
|
19372
19417
|
spawnCount = 0;
|
|
19418
|
+
/**
|
|
19419
|
+
* Historical `maxSpawns` from the last restored checkpoint (set for any
|
|
19420
|
+
* finite checkpoint ceiling, matching or not). Surfaced in
|
|
19421
|
+
* `budgetSnapshot()` so operators can see resume reconciliation without
|
|
19422
|
+
* reading the JSON file; `ceilingMismatch` carries the actual mismatch signal.
|
|
19423
|
+
*/
|
|
19424
|
+
checkpointMaxSpawnsAtResume;
|
|
19425
|
+
ceilingMismatchAtResume = false;
|
|
19373
19426
|
stateCheckpoint;
|
|
19374
19427
|
sessionWriter;
|
|
19375
19428
|
manifestTimer = null;
|
|
@@ -19473,11 +19526,11 @@ var FleetManager = class {
|
|
|
19473
19526
|
* which cap was exceeded. Does NOT throw — the caller decides
|
|
19474
19527
|
* how to surface the rejection.
|
|
19475
19528
|
*/
|
|
19476
|
-
canSpawn(
|
|
19529
|
+
canSpawn(config) {
|
|
19477
19530
|
if (this.spawnDepth >= this.maxSpawnDepth) {
|
|
19478
19531
|
return { kind: "max_spawn_depth", limit: this.maxSpawnDepth, observed: this.spawnDepth };
|
|
19479
19532
|
}
|
|
19480
|
-
if (this.spawnCount >= this.maxSpawns) {
|
|
19533
|
+
if (!config.spawnBudgetExempt && this.spawnCount >= this.maxSpawns) {
|
|
19481
19534
|
return { kind: "max_spawns", limit: this.maxSpawns, observed: this.spawnCount + 1 };
|
|
19482
19535
|
}
|
|
19483
19536
|
if (this.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
|
|
@@ -19519,7 +19572,39 @@ var FleetManager = class {
|
|
|
19519
19572
|
remainingTokens: Math.max(0, this.maxFleetTokens - usedTokens),
|
|
19520
19573
|
maxCostUsd: this.maxFleetCostUsd,
|
|
19521
19574
|
usedCostUsd,
|
|
19522
|
-
remainingCostUsd: Math.max(0, this.maxFleetCostUsd - usedCostUsd)
|
|
19575
|
+
remainingCostUsd: Math.max(0, this.maxFleetCostUsd - usedCostUsd),
|
|
19576
|
+
...this.checkpointMaxSpawnsAtResume !== void 0 ? { checkpointMaxSpawns: this.checkpointMaxSpawnsAtResume } : {},
|
|
19577
|
+
...this.ceilingMismatchAtResume ? { ceilingMismatch: true } : {}
|
|
19578
|
+
};
|
|
19579
|
+
}
|
|
19580
|
+
/**
|
|
19581
|
+
* Re-attach the on-disk checkpoint after a resume while keeping the live
|
|
19582
|
+
* `maxSpawns` ceiling from construction (profile / flag / env). The
|
|
19583
|
+
* historical `spawnCount` is deliberately NOT restored: the lifetime
|
|
19584
|
+
* budget is scoped to this director run, so a restarted session gets a
|
|
19585
|
+
* fresh budget instead of inheriting a (possibly exhausted) counter from
|
|
19586
|
+
* before the restart. The checkpoint ceiling is rewritten to the live
|
|
19587
|
+
* value so subsequent writes do not reintroduce a stale limit.
|
|
19588
|
+
*/
|
|
19589
|
+
restoreFromCheckpoint(snapshot) {
|
|
19590
|
+
const checkpointMax = typeof snapshot.maxSpawns === "number" && Number.isFinite(snapshot.maxSpawns) ? snapshot.maxSpawns : void 0;
|
|
19591
|
+
const ceilingMismatch = checkpointMax !== void 0 && checkpointMax !== this.maxSpawns;
|
|
19592
|
+
this.checkpointMaxSpawnsAtResume = checkpointMax;
|
|
19593
|
+
this.ceilingMismatchAtResume = ceilingMismatch;
|
|
19594
|
+
if (this.stateCheckpoint) {
|
|
19595
|
+
if (snapshot.version === 1 && snapshot.directorRunId && snapshot.updatedAt) {
|
|
19596
|
+
this.stateCheckpoint.resume(snapshot);
|
|
19597
|
+
}
|
|
19598
|
+
this.stateCheckpoint.applyLiveMaxSpawns(
|
|
19599
|
+
Number.isFinite(this.maxSpawns) ? this.maxSpawns : void 0
|
|
19600
|
+
);
|
|
19601
|
+
}
|
|
19602
|
+
return {
|
|
19603
|
+
usedSpawns: this.spawnCount,
|
|
19604
|
+
maxSpawns: this.maxSpawns,
|
|
19605
|
+
remainingSpawns: Math.max(0, this.maxSpawns - this.spawnCount),
|
|
19606
|
+
...checkpointMax !== void 0 ? { checkpointMaxSpawns: checkpointMax } : {},
|
|
19607
|
+
ceilingMismatch
|
|
19523
19608
|
};
|
|
19524
19609
|
}
|
|
19525
19610
|
setLeaderContextPressure(tokens) {
|
|
@@ -19573,8 +19658,10 @@ var FleetManager = class {
|
|
|
19573
19658
|
return this._usedNicknames;
|
|
19574
19659
|
}
|
|
19575
19660
|
/**
|
|
19576
|
-
* Records a spawn:
|
|
19577
|
-
*
|
|
19661
|
+
* Records a spawn: stores metadata, updates state checkpoint, and schedules
|
|
19662
|
+
* a debounced manifest write. Increments the lifetime spawn counter UNLESS
|
|
19663
|
+
* the config is `spawnBudgetExempt` (ephemeral Chimera reviewer/cascade
|
|
19664
|
+
* spawns do not consume the leader's budget). Call AFTER the coordinator
|
|
19578
19665
|
* has successfully spawned the subagent.
|
|
19579
19666
|
*
|
|
19580
19667
|
* @param subagentId The subagent's id (from coordinator.spawn result)
|
|
@@ -19583,7 +19670,9 @@ var FleetManager = class {
|
|
|
19583
19670
|
*/
|
|
19584
19671
|
recordSpawn(subagentId, config, priceLookup) {
|
|
19585
19672
|
this.closing = false;
|
|
19586
|
-
|
|
19673
|
+
if (!config.spawnBudgetExempt) {
|
|
19674
|
+
this.spawnCount += 1;
|
|
19675
|
+
}
|
|
19587
19676
|
this.subagentMeta.set(subagentId, {
|
|
19588
19677
|
provider: config.provider,
|
|
19589
19678
|
model: config.model
|
|
@@ -26467,6 +26556,9 @@ var KnowledgeGraph = class _KnowledgeGraph {
|
|
|
26467
26556
|
};
|
|
26468
26557
|
|
|
26469
26558
|
// src/coordination/task-dag.ts
|
|
26559
|
+
function isTerminalDagStatus(status) {
|
|
26560
|
+
return status === "done" || status === "failed" || status === "skipped";
|
|
26561
|
+
}
|
|
26470
26562
|
var TaskDAG = class {
|
|
26471
26563
|
nodes = /* @__PURE__ */ new Map();
|
|
26472
26564
|
handlers = /* @__PURE__ */ new Set();
|
|
@@ -26549,6 +26641,7 @@ var TaskDAG = class {
|
|
|
26549
26641
|
complete(id, result) {
|
|
26550
26642
|
const node = this.nodes.get(id);
|
|
26551
26643
|
if (!node) return;
|
|
26644
|
+
if (isTerminalDagStatus(node.status)) return;
|
|
26552
26645
|
node.status = "done";
|
|
26553
26646
|
node.result = result;
|
|
26554
26647
|
node.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -26574,6 +26667,7 @@ var TaskDAG = class {
|
|
|
26574
26667
|
fail(id, error) {
|
|
26575
26668
|
const node = this.nodes.get(id);
|
|
26576
26669
|
if (!node) return;
|
|
26670
|
+
if (isTerminalDagStatus(node.status)) return;
|
|
26577
26671
|
node.status = "failed";
|
|
26578
26672
|
node.error = error;
|
|
26579
26673
|
node.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -26602,6 +26696,7 @@ var TaskDAG = class {
|
|
|
26602
26696
|
skip(id, reason) {
|
|
26603
26697
|
const node = this.nodes.get(id);
|
|
26604
26698
|
if (!node) return;
|
|
26699
|
+
if (isTerminalDagStatus(node.status)) return;
|
|
26605
26700
|
node.status = "skipped";
|
|
26606
26701
|
node.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
26607
26702
|
this.invalidateCache();
|
|
@@ -26758,6 +26853,9 @@ var TaskDAG = class {
|
|
|
26758
26853
|
|
|
26759
26854
|
// src/coordination/task-auctioneer.ts
|
|
26760
26855
|
import { randomUUID as randomUUID18 } from "node:crypto";
|
|
26856
|
+
function isTerminalGoalStatus(status) {
|
|
26857
|
+
return status === "done" || status === "failed";
|
|
26858
|
+
}
|
|
26761
26859
|
var TaskAuctioneer = class {
|
|
26762
26860
|
graph;
|
|
26763
26861
|
fleet;
|
|
@@ -26953,6 +27051,7 @@ Priority: ${goal.priority}`,
|
|
|
26953
27051
|
async complete(taskId, _result) {
|
|
26954
27052
|
const goal = this.graph.get(taskId);
|
|
26955
27053
|
if (!goal) return;
|
|
27054
|
+
if (isTerminalGoalStatus(goal.status)) return;
|
|
26956
27055
|
const agentId = goal.assignee ?? "unknown";
|
|
26957
27056
|
this.agentTaskCount(agentId, -1);
|
|
26958
27057
|
await this.graph.update(taskId, {
|
|
@@ -26993,6 +27092,7 @@ ${_result ?? "No result provided."}`
|
|
|
26993
27092
|
async fail(taskId, error) {
|
|
26994
27093
|
const goal = this.graph.get(taskId);
|
|
26995
27094
|
if (!goal) return;
|
|
27095
|
+
if (isTerminalGoalStatus(goal.status)) return;
|
|
26996
27096
|
const agentId = goal.assignee ?? "unknown";
|
|
26997
27097
|
this.agentTaskCount(agentId, -1);
|
|
26998
27098
|
await this.graph.update(taskId, {
|
|
@@ -186,6 +186,7 @@ export declare class DefaultMultiAgentCoordinator extends EventEmitter implement
|
|
|
186
186
|
* `awaitTasks()` caller. Pushes the result and fires the event directly.
|
|
187
187
|
*/
|
|
188
188
|
private emitPendingAborted;
|
|
189
|
+
private trimCompletedResults;
|
|
189
190
|
private runDispatched;
|
|
190
191
|
private executeWithTimeout;
|
|
191
192
|
private recordCompletion;
|
|
@@ -90,7 +90,55 @@ export interface FallbackModelDeps {
|
|
|
90
90
|
* the fallback chain.
|
|
91
91
|
*/
|
|
92
92
|
statusTracker?: ProviderModelStatusTracker | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* When set, the fallback chain pauses BEFORE attempting any fallback entry
|
|
95
|
+
* and emits `provider.fallback_pending`. The gate waits for a choice
|
|
96
|
+
* (manual pick or auto-countdown) before proceeding. This lets the UI show
|
|
97
|
+
* a modal with a countdown and manual model selection on every fallback hop.
|
|
98
|
+
*
|
|
99
|
+
* Returns the chosen model reference, or `null` to auto-switch to the next
|
|
100
|
+
* candidate (countdown expired or user accepted the default).
|
|
101
|
+
*/
|
|
102
|
+
fallbackGate?: FallbackGateFn | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Seconds the UI counts down before auto-switching. Default: 7.
|
|
105
|
+
*/
|
|
106
|
+
fallbackGateSeconds?: number | undefined;
|
|
93
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Gate function invoked when the fallback chain is about to engage. It should
|
|
110
|
+
* emit `provider.fallback_pending` on the supplied `events` bus — carrying a
|
|
111
|
+
* unique `requestId` and a `timestamp` in the payload — wait for the UI's
|
|
112
|
+
* `provider.fallback_choice` emission echoing that `requestId` (or the
|
|
113
|
+
* countdown), and resolve with the selected model or `null` to accept the
|
|
114
|
+
* default next. See `createFallbackGate` in the CLI wiring for a reference
|
|
115
|
+
* implementation.
|
|
116
|
+
*/
|
|
117
|
+
export type FallbackGateFn = (params: {
|
|
118
|
+
events: EventBus;
|
|
119
|
+
sessionId: string | undefined;
|
|
120
|
+
from: {
|
|
121
|
+
providerId: string;
|
|
122
|
+
model: string;
|
|
123
|
+
};
|
|
124
|
+
status: number;
|
|
125
|
+
candidates: Array<{
|
|
126
|
+
providerId: string;
|
|
127
|
+
model: string;
|
|
128
|
+
}>;
|
|
129
|
+
autoSwitchSeconds: number;
|
|
130
|
+
/**
|
|
131
|
+
* Correlation id owned by the caller (the fallback-model extension). The
|
|
132
|
+
* gate MUST echo it in `provider.fallback_pending` so the UI's choice
|
|
133
|
+
* reply and the eventual `provider.fallback` completion event share the
|
|
134
|
+
* same id — clients use it to match the modal to the right gate when
|
|
135
|
+
* parallel requests fail on the same primary.
|
|
136
|
+
*/
|
|
137
|
+
requestId: string;
|
|
138
|
+
}) => Promise<{
|
|
139
|
+
providerId: string;
|
|
140
|
+
model: string;
|
|
141
|
+
} | null>;
|
|
94
142
|
export declare function fallbackProfileChain(config: Config, profileName: string | undefined): string[];
|
|
95
143
|
export declare function smartDefaultFallbackChain(config: Config): string[];
|
|
96
144
|
/**
|
package/dist/core/index.d.ts
CHANGED
|
@@ -5,11 +5,12 @@ export { ConversationState, type ReadonlyConversationState, type StateChange, ty
|
|
|
5
5
|
export { InputBuilder, type InputBuilderEvent, type InputBuilderOptions, } from './input-builder.js';
|
|
6
6
|
export { buildBtwBlock, consumeBtwNotes, pendingBtwCount, setBtwNote, } from './btw.js';
|
|
7
7
|
export { type ContinuationInput, type ContinuationSource, detectContinueIntent, type ResolvedContinuation, resolveContinuation, } from './continue-intent.js';
|
|
8
|
-
export { createFallbackModelExtension, effectiveFallbackChain, fallbackProfileChain, smartDefaultFallbackChain, } from './fallback-model.js';
|
|
8
|
+
export { createFallbackModelExtension, effectiveFallbackChain, type FallbackGateFn, type FallbackModelDeps, fallbackProfileChain, smartDefaultFallbackChain, } from './fallback-model.js';
|
|
9
9
|
export { FallbackProfileManager } from './fallback-profile-manager.js';
|
|
10
10
|
export { formatModelRef, normalizeModelRef, parseModelRef, type ModelRef, } from './model-ref.js';
|
|
11
11
|
export { DefaultSystemPromptBuilder, type DefaultSystemPromptBuilderOptions, type SystemBlockSource, } from './system-prompt-builder.js';
|
|
12
|
-
export type
|
|
12
|
+
export { type InstructionBundle, type InstructionBundlePaths, loadInstructionBundle, type SystemInstructionVariant, } from './instruction-bundle.js';
|
|
13
|
+
export { type InstructionTemplateContext, renderInstructionLayer, } from './instruction-template.js';
|
|
13
14
|
export { setQueuedMessagesSnapshot } from './queued-messages.js';
|
|
14
15
|
export { runProviderWithRetry } from './provider-runner.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|