@wrongstack/core 0.5.5 → 0.5.7
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/{agent-bridge-B07AYFBk.d.ts → agent-bridge-BKNiE1VH.d.ts} +1 -1
- package/dist/{compactor-BWhJXxsW.d.ts → compactor-RIPuTtWK.d.ts} +1 -1
- package/dist/{config-BgM0BIpz.d.ts → config-BGGuP_Ar.d.ts} +1 -1
- package/dist/{context-CLZXPPYk.d.ts → context-CDRyrkKQ.d.ts} +7 -0
- package/dist/coordination/index.d.ts +10 -9
- package/dist/coordination/index.js +558 -61
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +19 -18
- package/dist/defaults/index.js +521 -64
- package/dist/defaults/index.js.map +1 -1
- package/dist/director-state-BmYi3DGA.d.ts +108 -0
- package/dist/{events-qnDZbrtb.d.ts → events-DPQKFX7W.d.ts} +1 -1
- package/dist/execution/index.d.ts +18 -11
- package/dist/execution/index.js +19 -3
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{index-De4R4rQ7.d.ts → index-Bf9Bpkdc.d.ts} +452 -9
- package/dist/{index-DPLJw_ZI.d.ts → index-j2WyAyML.d.ts} +20 -5
- package/dist/index.d.ts +108 -27
- package/dist/index.js +819 -90
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +9 -9
- package/dist/{mcp-servers-CSMfaBuL.d.ts → mcp-servers-DBdh3cee.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/{multi-agent-Cv8wk47i.d.ts → multi-agent-Cpp7FXUl.d.ts} +11 -3
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-DiCUvEg6.d.ts → path-resolver--g_hKJ7V.d.ts} +2 -2
- package/dist/{director-state-BUxlqkOa.d.ts → plan-templates-Bveo2W8n.d.ts} +37 -76
- package/dist/{provider-runner-3SHqk9zB.d.ts → provider-runner-hl4Il3xS.d.ts} +3 -3
- package/dist/{retry-policy-LLUxJmYY.d.ts → retry-policy-LKS8MHsB.d.ts} +1 -1
- package/dist/sdd/index.d.ts +3 -3
- package/dist/{secret-scrubber-Z_VXuXQT.d.ts → secret-scrubber-BzQR5BiL.d.ts} +1 -1
- package/dist/{secret-scrubber-BhJTNr9v.d.ts → secret-scrubber-CfMdAJ_l.d.ts} +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/{selector-DB2-byKH.d.ts → selector-C7HqnZJU.d.ts} +1 -1
- package/dist/{session-reader-4jxsYLZ8.d.ts → session-reader-CzfRA6Vk.d.ts} +1 -1
- package/dist/storage/index.d.ts +6 -5
- package/dist/storage/index.js +206 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-DI4Dtc1I.d.ts → system-prompt-Dl2QY1_B.d.ts} +1 -1
- package/dist/{tool-executor-DSvmOBe6.d.ts → tool-executor-DbAFkHdP.d.ts} +4 -4
- package/dist/types/index.d.ts +15 -15
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/defaults/index.js
CHANGED
|
@@ -6,7 +6,12 @@ import * as fsp from 'fs/promises';
|
|
|
6
6
|
import * as os from 'os';
|
|
7
7
|
import { EventEmitter } from 'events';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
10
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
11
|
+
}) : x)(function(x) {
|
|
12
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
13
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
|
+
});
|
|
10
15
|
|
|
11
16
|
// src/utils/color.ts
|
|
12
17
|
var isColorTty = () => {
|
|
@@ -2153,9 +2158,149 @@ function matchIndex(plan, idOrIndex) {
|
|
|
2153
2158
|
const lower = idOrIndex.toLowerCase();
|
|
2154
2159
|
return plan.items.findIndex((it) => it.title.toLowerCase().includes(lower));
|
|
2155
2160
|
}
|
|
2161
|
+
function deriveTodosFromPlanItem(plan, idOrIndex, subtasks) {
|
|
2162
|
+
const idx = matchIndex(plan, idOrIndex);
|
|
2163
|
+
if (idx === -1) return null;
|
|
2164
|
+
const item = plan.items[idx];
|
|
2165
|
+
if (!item) return null;
|
|
2166
|
+
let updatedPlan = plan;
|
|
2167
|
+
if (item.status !== "done") {
|
|
2168
|
+
updatedPlan = setPlanItemStatus(plan, idOrIndex, "in_progress");
|
|
2169
|
+
}
|
|
2170
|
+
const todos = [];
|
|
2171
|
+
todos.push({
|
|
2172
|
+
id: `todo_${Date.now()}_plan`,
|
|
2173
|
+
content: item.title,
|
|
2174
|
+
status: "in_progress",
|
|
2175
|
+
activeForm: item.title
|
|
2176
|
+
});
|
|
2177
|
+
if (subtasks && subtasks.length > 0) {
|
|
2178
|
+
for (const st of subtasks) {
|
|
2179
|
+
todos.push({
|
|
2180
|
+
id: `todo_${Date.now()}_${randomUUID().slice(0, 6)}`,
|
|
2181
|
+
content: st,
|
|
2182
|
+
status: "pending"
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
return { plan: updatedPlan, todos };
|
|
2187
|
+
}
|
|
2156
2188
|
function attachPlanCheckpoint(_state, _filePath, _sessionId) {
|
|
2157
2189
|
return () => void 0;
|
|
2158
2190
|
}
|
|
2191
|
+
|
|
2192
|
+
// src/storage/plan-templates.ts
|
|
2193
|
+
var templates = {
|
|
2194
|
+
"new-feature": {
|
|
2195
|
+
name: "new-feature",
|
|
2196
|
+
description: "Standard workflow for adding a new feature",
|
|
2197
|
+
category: "development",
|
|
2198
|
+
items: [
|
|
2199
|
+
{ title: "Write specification / design doc", details: "Define scope, acceptance criteria, edge cases" },
|
|
2200
|
+
{ title: "Set up feature branch", details: "git checkout -b feature/..." },
|
|
2201
|
+
{ title: "Implement core logic", details: "TDD preferred \u2014 write tests first" },
|
|
2202
|
+
{ title: "Add unit tests", details: ">= 80% coverage for new code" },
|
|
2203
|
+
{ title: "Add integration tests", details: "End-to-end happy path + error paths" },
|
|
2204
|
+
{ title: "Update documentation", details: "README, API docs, changelog" },
|
|
2205
|
+
{ title: "Code review", details: "Self-review before requesting review" },
|
|
2206
|
+
{ title: "Merge and deploy", details: "CI green, tag release" }
|
|
2207
|
+
]
|
|
2208
|
+
},
|
|
2209
|
+
"bug-fix": {
|
|
2210
|
+
name: "bug-fix",
|
|
2211
|
+
description: "Systematic approach to fixing bugs",
|
|
2212
|
+
category: "maintenance",
|
|
2213
|
+
items: [
|
|
2214
|
+
{ title: "Reproduce the bug", details: "Minimal reproduction case" },
|
|
2215
|
+
{ title: "Root cause analysis", details: "Trace through logs, debugger" },
|
|
2216
|
+
{ title: "Write failing test", details: "Test must fail before fix" },
|
|
2217
|
+
{ title: "Implement fix", details: "Smallest possible change" },
|
|
2218
|
+
{ title: "Verify fix", details: "Test passes, reproduction no longer fails" },
|
|
2219
|
+
{ title: "Regression test", details: "Ensure no related tests broken" },
|
|
2220
|
+
{ title: "Document in changelog", details: "Brief description + issue link" }
|
|
2221
|
+
]
|
|
2222
|
+
},
|
|
2223
|
+
"refactor": {
|
|
2224
|
+
name: "refactor",
|
|
2225
|
+
description: "Safe refactoring workflow",
|
|
2226
|
+
category: "maintenance",
|
|
2227
|
+
items: [
|
|
2228
|
+
{ title: "Identify refactoring target", details: "Code smell, performance bottleneck, or tech debt" },
|
|
2229
|
+
{ title: "Ensure test coverage", details: "Existing tests must pass before and after" },
|
|
2230
|
+
{ title: "Write characterization tests", details: "Capture current behavior if tests weak" },
|
|
2231
|
+
{ title: "Apply refactoring", details: "Small steps, frequent commits" },
|
|
2232
|
+
{ title: "Run full test suite", details: "All tests must pass" },
|
|
2233
|
+
{ title: "Performance check", details: "Ensure no regression" },
|
|
2234
|
+
{ title: "Code review", details: "Explain the why, not just the what" }
|
|
2235
|
+
]
|
|
2236
|
+
},
|
|
2237
|
+
"release": {
|
|
2238
|
+
name: "release",
|
|
2239
|
+
description: "Preparing a new release",
|
|
2240
|
+
category: "release",
|
|
2241
|
+
items: [
|
|
2242
|
+
{ title: "Version bump", details: "package.json, lockfiles, tags" },
|
|
2243
|
+
{ title: "Update changelog", details: "All changes since last release" },
|
|
2244
|
+
{ title: "Run full test suite", details: "Unit + integration + e2e" },
|
|
2245
|
+
{ title: "Build artifacts", details: "Docker images, bundles, binaries" },
|
|
2246
|
+
{ title: "Staging smoke tests", details: "Deploy to staging, verify" },
|
|
2247
|
+
{ title: "Production deploy", details: "Blue-green or canary" },
|
|
2248
|
+
{ title: "Post-deploy verification", details: "Health checks, error rates" },
|
|
2249
|
+
{ title: "Announce release", details: "Slack, email, GitHub release notes" }
|
|
2250
|
+
]
|
|
2251
|
+
},
|
|
2252
|
+
"security-audit": {
|
|
2253
|
+
name: "security-audit",
|
|
2254
|
+
description: "Security review and hardening",
|
|
2255
|
+
category: "infrastructure",
|
|
2256
|
+
items: [
|
|
2257
|
+
{ title: "Dependency audit", details: "npm audit, Snyk, Dependabot alerts" },
|
|
2258
|
+
{ title: "Secret scan", details: "git-secrets, truffleHog, manual review" },
|
|
2259
|
+
{ title: "Access control review", details: "IAM, roles, least privilege" },
|
|
2260
|
+
{ title: "Input validation audit", details: "SQL injection, XSS, path traversal" },
|
|
2261
|
+
{ title: "Authentication review", details: "Session management, MFA, password policy" },
|
|
2262
|
+
{ title: "Logging and monitoring", details: "PII in logs, audit trails" },
|
|
2263
|
+
{ title: "Incident response plan", details: "Runbooks, contacts, escalation" }
|
|
2264
|
+
]
|
|
2265
|
+
},
|
|
2266
|
+
"onboarding": {
|
|
2267
|
+
name: "onboarding",
|
|
2268
|
+
description: "New developer onboarding checklist",
|
|
2269
|
+
category: "infrastructure",
|
|
2270
|
+
items: [
|
|
2271
|
+
{ title: "Repository access", details: "GitHub/GitLab permissions" },
|
|
2272
|
+
{ title: "Local environment setup", details: "Docker, dependencies, env files" },
|
|
2273
|
+
{ title: "Run tests locally", details: "Verify green suite" },
|
|
2274
|
+
{ title: "Read architecture docs", details: "ADR, README, onboarding guide" },
|
|
2275
|
+
{ title: "First commit", details: "Docs fix or small improvement" },
|
|
2276
|
+
{ title: "Pair programming session", details: "Walk through codebase with buddy" },
|
|
2277
|
+
{ title: "Deploy to staging", details: "Verify CI/CD access" }
|
|
2278
|
+
]
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
function listPlanTemplates() {
|
|
2282
|
+
return Object.values(templates);
|
|
2283
|
+
}
|
|
2284
|
+
function getPlanTemplate(name) {
|
|
2285
|
+
return templates[name];
|
|
2286
|
+
}
|
|
2287
|
+
function formatPlanTemplates() {
|
|
2288
|
+
const cats = /* @__PURE__ */ new Map();
|
|
2289
|
+
for (const t of Object.values(templates)) {
|
|
2290
|
+
const arr = cats.get(t.category) ?? [];
|
|
2291
|
+
arr.push(t);
|
|
2292
|
+
cats.set(t.category, arr);
|
|
2293
|
+
}
|
|
2294
|
+
const lines = ["Available plan templates:"];
|
|
2295
|
+
for (const [cat, items] of cats) {
|
|
2296
|
+
lines.push(`
|
|
2297
|
+
${cat}:`);
|
|
2298
|
+
for (const t of items) {
|
|
2299
|
+
lines.push(` ${t.name.padEnd(18)} \u2014 ${t.description}`);
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
return lines.join("\n");
|
|
2303
|
+
}
|
|
2159
2304
|
async function loadDirectorState(filePath) {
|
|
2160
2305
|
let raw;
|
|
2161
2306
|
try {
|
|
@@ -2171,15 +2316,48 @@ async function loadDirectorState(filePath) {
|
|
|
2171
2316
|
return null;
|
|
2172
2317
|
}
|
|
2173
2318
|
}
|
|
2319
|
+
async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
2320
|
+
let existing;
|
|
2321
|
+
try {
|
|
2322
|
+
existing = await fsp.readFile(lockPath, "utf8");
|
|
2323
|
+
} catch {
|
|
2324
|
+
}
|
|
2325
|
+
if (existing) {
|
|
2326
|
+
try {
|
|
2327
|
+
const lock2 = JSON.parse(existing);
|
|
2328
|
+
try {
|
|
2329
|
+
process.kill(lock2.pid, 0);
|
|
2330
|
+
return false;
|
|
2331
|
+
} catch {
|
|
2332
|
+
}
|
|
2333
|
+
} catch {
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
const lock = {
|
|
2337
|
+
pid: processId,
|
|
2338
|
+
hostname: __require("os").hostname(),
|
|
2339
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2340
|
+
};
|
|
2341
|
+
await atomicWrite(lockPath, JSON.stringify(lock), { mode: 384 });
|
|
2342
|
+
return true;
|
|
2343
|
+
}
|
|
2344
|
+
async function releaseDirectorStateLock(lockPath) {
|
|
2345
|
+
try {
|
|
2346
|
+
await fsp.unlink(lockPath);
|
|
2347
|
+
} catch {
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2174
2350
|
var DirectorStateCheckpoint = class {
|
|
2175
2351
|
snapshot;
|
|
2176
2352
|
filePath;
|
|
2353
|
+
lockPath;
|
|
2177
2354
|
timer = null;
|
|
2178
2355
|
debounceMs;
|
|
2179
2356
|
writing = false;
|
|
2180
2357
|
rewriteRequested = false;
|
|
2181
2358
|
constructor(filePath, init, debounceMs = 250) {
|
|
2182
2359
|
this.filePath = filePath;
|
|
2360
|
+
this.lockPath = `${filePath}.lock`;
|
|
2183
2361
|
this.debounceMs = debounceMs;
|
|
2184
2362
|
this.snapshot = {
|
|
2185
2363
|
version: 1,
|
|
@@ -2189,10 +2367,36 @@ var DirectorStateCheckpoint = class {
|
|
|
2189
2367
|
maxSpawns: init.maxSpawns,
|
|
2190
2368
|
spawnDepth: init.spawnDepth,
|
|
2191
2369
|
maxSpawnDepth: init.maxSpawnDepth,
|
|
2370
|
+
directorBudget: init.directorBudget,
|
|
2192
2371
|
subagents: [],
|
|
2193
2372
|
tasks: []
|
|
2194
2373
|
};
|
|
2195
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Attempt to acquire the lock for this checkpoint. Call this before
|
|
2377
|
+
* resuming a crashed director run. If it returns false, another
|
|
2378
|
+
* director process is still running this fleet — do not resume.
|
|
2379
|
+
*/
|
|
2380
|
+
async acquireLock() {
|
|
2381
|
+
return acquireDirectorStateLock(this.lockPath);
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Release the lock on graceful shutdown. Call `flush()` first to ensure
|
|
2385
|
+
* the final checkpoint state is on disk before removing the lock.
|
|
2386
|
+
* Without this, the next resume will see a stale-lock and refuse.
|
|
2387
|
+
*/
|
|
2388
|
+
async releaseLock() {
|
|
2389
|
+
return releaseDirectorStateLock(this.lockPath);
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
* Resume from a snapshot previously loaded via `loadDirectorState()`.
|
|
2393
|
+
* Use this when `--resume <runId>` is triggered — the snapshot has
|
|
2394
|
+
* the full fleet state (subagents, tasks) from before the crash; the
|
|
2395
|
+
* checkpoint continues from there.
|
|
2396
|
+
*/
|
|
2397
|
+
resume(snapshot) {
|
|
2398
|
+
this.snapshot = snapshot;
|
|
2399
|
+
}
|
|
2196
2400
|
current() {
|
|
2197
2401
|
return this.snapshot;
|
|
2198
2402
|
}
|
|
@@ -4833,6 +5037,14 @@ var DoneConditionChecker = class {
|
|
|
4833
5037
|
};
|
|
4834
5038
|
}
|
|
4835
5039
|
break;
|
|
5040
|
+
case "directive":
|
|
5041
|
+
if (this.condition.maxIterations && state.iterations >= this.condition.maxIterations) {
|
|
5042
|
+
return { done: true, reason: `max iterations (${this.condition.maxIterations}) reached`, ...state };
|
|
5043
|
+
}
|
|
5044
|
+
if (this.condition.maxToolCalls && state.toolCalls >= this.condition.maxToolCalls) {
|
|
5045
|
+
return { done: true, reason: `max tool calls (${this.condition.maxToolCalls}) reached`, ...state };
|
|
5046
|
+
}
|
|
5047
|
+
break;
|
|
4836
5048
|
}
|
|
4837
5049
|
return { done: false, iterations: state.iterations, toolCalls: state.toolCalls };
|
|
4838
5050
|
}
|
|
@@ -4852,10 +5064,16 @@ var AutonomousRunner = class {
|
|
|
4852
5064
|
const offToolExecuted = this.opts.agent.events?.on?.("tool.executed", () => {
|
|
4853
5065
|
this.toolCalls++;
|
|
4854
5066
|
});
|
|
5067
|
+
const offIterationCompleted = this.opts.agent.events?.on?.("iteration.completed", () => {
|
|
5068
|
+
if (this.opts.enableAutonomousContinue && this.opts.doneCondition.type === "directive") {
|
|
5069
|
+
this.iterations++;
|
|
5070
|
+
}
|
|
5071
|
+
});
|
|
4855
5072
|
try {
|
|
4856
5073
|
return await this.runLoop();
|
|
4857
5074
|
} finally {
|
|
4858
5075
|
offToolExecuted?.();
|
|
5076
|
+
offIterationCompleted?.();
|
|
4859
5077
|
}
|
|
4860
5078
|
}
|
|
4861
5079
|
async runLoop() {
|
|
@@ -4879,12 +5097,14 @@ var AutonomousRunner = class {
|
|
|
4879
5097
|
const ctrl = new AbortController();
|
|
4880
5098
|
const timeout = setTimeout(() => ctrl.abort(), this.opts.iterationTimeoutMs ?? 3e4);
|
|
4881
5099
|
try {
|
|
5100
|
+
const isDirectiveMode = this.opts.doneCondition.type === "directive" && this.opts.enableAutonomousContinue;
|
|
4882
5101
|
const result = await this.opts.agent.run("", {
|
|
4883
5102
|
signal: ctrl.signal,
|
|
4884
|
-
maxIterations: 1,
|
|
4885
|
-
executionStrategy: "sequential"
|
|
5103
|
+
maxIterations: isDirectiveMode ? this.opts.doneCondition.maxIterations ?? 100 : 1,
|
|
5104
|
+
executionStrategy: "sequential",
|
|
5105
|
+
autonomousContinue: isDirectiveMode ? true : void 0
|
|
4886
5106
|
});
|
|
4887
|
-
this.iterations++;
|
|
5107
|
+
if (!isDirectiveMode) this.iterations++;
|
|
4888
5108
|
if (result.status === "done") {
|
|
4889
5109
|
this.lastOutput = result.finalText;
|
|
4890
5110
|
}
|
|
@@ -6227,7 +6447,10 @@ function makeSpawnTool(director, roster) {
|
|
|
6227
6447
|
const subagentId = await director.spawn(cfg);
|
|
6228
6448
|
return { subagentId, provider: cfg.provider, model: cfg.model, name: cfg.name };
|
|
6229
6449
|
} catch (err) {
|
|
6230
|
-
if (err instanceof
|
|
6450
|
+
if (err instanceof FleetSpawnBudgetError) {
|
|
6451
|
+
return { error: err.message, kind: err.kind, limit: err.limit, observed: err.observed };
|
|
6452
|
+
}
|
|
6453
|
+
if (err instanceof FleetCostCapError) {
|
|
6231
6454
|
return { error: err.message, kind: err.kind, limit: err.limit, observed: err.observed };
|
|
6232
6455
|
}
|
|
6233
6456
|
return { error: err instanceof Error ? err.message : String(err) };
|
|
@@ -6367,9 +6590,68 @@ function makeFleetUsageTool(director) {
|
|
|
6367
6590
|
}
|
|
6368
6591
|
};
|
|
6369
6592
|
}
|
|
6593
|
+
function makeFleetSessionTool(director) {
|
|
6594
|
+
return {
|
|
6595
|
+
name: "fleet_session",
|
|
6596
|
+
description: "Read a subagent's JSONL transcript and extract its last assistant text, stop reason, and tool-use count. Use this to see what a running or timed-out subagent actually produced.",
|
|
6597
|
+
permission: "auto",
|
|
6598
|
+
mutating: false,
|
|
6599
|
+
inputSchema: {
|
|
6600
|
+
type: "object",
|
|
6601
|
+
properties: {
|
|
6602
|
+
subagentId: { type: "string", description: "Subagent id to read the transcript of." },
|
|
6603
|
+
/** Number of trailing lines to return (last N JSONL lines). Default: all. */
|
|
6604
|
+
tail: { type: "number", description: "Number of trailing JSONL lines to return. Omit for the full transcript." }
|
|
6605
|
+
},
|
|
6606
|
+
required: ["subagentId"]
|
|
6607
|
+
},
|
|
6608
|
+
async execute(input) {
|
|
6609
|
+
const i = input;
|
|
6610
|
+
const result = await director.readSession(i.subagentId, i.tail);
|
|
6611
|
+
if (!result) {
|
|
6612
|
+
return {
|
|
6613
|
+
error: `fleet_session: transcript unavailable for "${i.subagentId}". Is sessionsRoot configured?`
|
|
6614
|
+
};
|
|
6615
|
+
}
|
|
6616
|
+
return result;
|
|
6617
|
+
}
|
|
6618
|
+
};
|
|
6619
|
+
}
|
|
6620
|
+
function makeFleetHealthTool(director) {
|
|
6621
|
+
return {
|
|
6622
|
+
name: "fleet_health",
|
|
6623
|
+
description: "Per-subagent health report: budget pressure (pct of limits consumed), last activity timestamp, and current status. Use to decide whether to assign more work to a subagent or spawn a fresh one.",
|
|
6624
|
+
permission: "auto",
|
|
6625
|
+
mutating: false,
|
|
6626
|
+
inputSchema: { type: "object", properties: {}, required: [] },
|
|
6627
|
+
async execute() {
|
|
6628
|
+
const status = director.status();
|
|
6629
|
+
const snapshot = director.snapshot();
|
|
6630
|
+
const subagents = status.subagents ?? [];
|
|
6631
|
+
const perSubagent = snapshot.perSubagent ?? {};
|
|
6632
|
+
return {
|
|
6633
|
+
subagents: subagents.map((s) => {
|
|
6634
|
+
const usage = perSubagent[s.id];
|
|
6635
|
+
return {
|
|
6636
|
+
id: s.id,
|
|
6637
|
+
status: s.status,
|
|
6638
|
+
lastEventAt: usage?.lastEventAt,
|
|
6639
|
+
// Budget pressure: fraction of each limit consumed if we have it.
|
|
6640
|
+
// BudgetWarning events carry used/limit ratios; surface them here.
|
|
6641
|
+
budgetPressure: {
|
|
6642
|
+
iterations: usage?.iterations,
|
|
6643
|
+
toolCalls: usage?.toolCalls,
|
|
6644
|
+
costUsd: usage?.cost
|
|
6645
|
+
}
|
|
6646
|
+
};
|
|
6647
|
+
})
|
|
6648
|
+
};
|
|
6649
|
+
}
|
|
6650
|
+
};
|
|
6651
|
+
}
|
|
6370
6652
|
|
|
6371
6653
|
// src/coordination/director.ts
|
|
6372
|
-
var
|
|
6654
|
+
var FleetSpawnBudgetError = class extends Error {
|
|
6373
6655
|
kind;
|
|
6374
6656
|
limit;
|
|
6375
6657
|
observed;
|
|
@@ -6377,16 +6659,48 @@ var DirectorBudgetError = class extends Error {
|
|
|
6377
6659
|
super(
|
|
6378
6660
|
kind === "max_spawns" ? `Director spawn budget exceeded: tried to spawn #${observed} but maxSpawns is ${limit}` : `Director spawn depth budget exceeded: this director is at depth ${observed} and maxSpawnDepth is ${limit}`
|
|
6379
6661
|
);
|
|
6380
|
-
this.name = "
|
|
6662
|
+
this.name = "FleetSpawnBudgetError";
|
|
6381
6663
|
this.kind = kind;
|
|
6382
6664
|
this.limit = limit;
|
|
6383
6665
|
this.observed = observed;
|
|
6384
6666
|
}
|
|
6385
6667
|
};
|
|
6668
|
+
var FleetCostCapError = class extends Error {
|
|
6669
|
+
kind;
|
|
6670
|
+
limit;
|
|
6671
|
+
observed;
|
|
6672
|
+
constructor(limit, observed) {
|
|
6673
|
+
super(
|
|
6674
|
+
`Director cost cap exceeded: total fleet spend ${observed.toFixed(4)} exceeds maxCostUsd ${limit.toFixed(4)}`
|
|
6675
|
+
);
|
|
6676
|
+
this.name = "FleetCostCapError";
|
|
6677
|
+
this.kind = "max_cost_usd";
|
|
6678
|
+
this.limit = limit;
|
|
6679
|
+
this.observed = observed;
|
|
6680
|
+
}
|
|
6681
|
+
};
|
|
6386
6682
|
var Director = class {
|
|
6683
|
+
/** Alias for the ICoordinator contract. `id` is retained for backward compatibility. */
|
|
6684
|
+
get coordinatorId() {
|
|
6685
|
+
return this.id;
|
|
6686
|
+
}
|
|
6387
6687
|
id;
|
|
6688
|
+
/**
|
|
6689
|
+
* The fleet event bus. Backed by `fleetManager?.fleet` when a FleetManager
|
|
6690
|
+
* is injected; otherwise own FleetBus instance (preserves existing behavior).
|
|
6691
|
+
*/
|
|
6388
6692
|
fleet;
|
|
6693
|
+
/**
|
|
6694
|
+
* Usage rollup. Backed by `fleetManager?.usage` when a FleetManager is
|
|
6695
|
+
* injected; otherwise own FleetUsageAggregator.
|
|
6696
|
+
*/
|
|
6389
6697
|
usage;
|
|
6698
|
+
/**
|
|
6699
|
+
* Optional fleet-level policy container. When provided the Director
|
|
6700
|
+
* delegates spawn budgeting, manifest entries, and checkpointing to it
|
|
6701
|
+
* instead of managing those internally. All other behavior is unchanged.
|
|
6702
|
+
*/
|
|
6703
|
+
fleetManager;
|
|
6390
6704
|
/**
|
|
6391
6705
|
* Director-side bridge endpoint. Subagents are wired to the same
|
|
6392
6706
|
* in-memory transport so the director can `ask()` them synchronously
|
|
@@ -6437,6 +6751,14 @@ var Director = class {
|
|
|
6437
6751
|
/** Debounce timer for periodic manifest writes. */
|
|
6438
6752
|
manifestTimer = null;
|
|
6439
6753
|
manifestDebounceMs;
|
|
6754
|
+
/** Fleet-wide cost cap (entire fleet total, distinct from SubagentBudget limits). Infinity means no cap. */
|
|
6755
|
+
maxFleetCostUsd;
|
|
6756
|
+
/** Max auto-extensions per subagent per budget kind before denying. */
|
|
6757
|
+
maxBudgetExtensions;
|
|
6758
|
+
/** Sessions root for direct subagent JSONL reads (fleet_session tool). */
|
|
6759
|
+
sessionsRoot;
|
|
6760
|
+
/** Director run id for JSONL path resolution. */
|
|
6761
|
+
directorRunId;
|
|
6440
6762
|
/** Resolves task descriptions back from `assign()` so completion events
|
|
6441
6763
|
* can also carry a human-readable title. */
|
|
6442
6764
|
taskDescriptions = /* @__PURE__ */ new Map();
|
|
@@ -6463,12 +6785,18 @@ var Director = class {
|
|
|
6463
6785
|
this.spawnDepth = opts.spawnDepth ?? 0;
|
|
6464
6786
|
this.sessionWriter = opts.sessionWriter ?? null;
|
|
6465
6787
|
this.manifestDebounceMs = opts.manifestDebounceMs ?? 2e3;
|
|
6788
|
+
this.maxFleetCostUsd = opts.directorBudget?.maxCostUsd ?? Number.POSITIVE_INFINITY;
|
|
6789
|
+
this.maxBudgetExtensions = opts.maxBudgetExtensions ?? 2;
|
|
6790
|
+
this.sessionsRoot = opts.sessionsRoot;
|
|
6791
|
+
this.directorRunId = opts.directorRunId ?? this.id;
|
|
6466
6792
|
this.stateCheckpoint = opts.stateCheckpointPath ? new DirectorStateCheckpoint(opts.stateCheckpointPath, {
|
|
6467
6793
|
directorRunId: this.id,
|
|
6468
6794
|
maxSpawns: opts.maxSpawns,
|
|
6469
6795
|
spawnDepth: this.spawnDepth,
|
|
6470
|
-
maxSpawnDepth: this.maxSpawnDepth
|
|
6471
|
-
|
|
6796
|
+
maxSpawnDepth: this.maxSpawnDepth,
|
|
6797
|
+
directorBudget: opts.directorBudget
|
|
6798
|
+
}, opts.checkpointDebounceMs ?? 250) : null;
|
|
6799
|
+
this.fleetManager = opts.fleetManager;
|
|
6472
6800
|
if (this.sharedScratchpadPath) {
|
|
6473
6801
|
void fsp.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(() => void 0);
|
|
6474
6802
|
}
|
|
@@ -6477,12 +6805,17 @@ var Director = class {
|
|
|
6477
6805
|
{ agentId: this.id, coordinatorId: this.id },
|
|
6478
6806
|
this.transport
|
|
6479
6807
|
);
|
|
6480
|
-
this.
|
|
6481
|
-
|
|
6482
|
-
this.
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6808
|
+
if (this.fleetManager) {
|
|
6809
|
+
this.fleet = this.fleetManager.fleet;
|
|
6810
|
+
this.usage = this.fleetManager.usage;
|
|
6811
|
+
} else {
|
|
6812
|
+
this.fleet = new FleetBus();
|
|
6813
|
+
this.usage = new FleetUsageAggregator(
|
|
6814
|
+
this.fleet,
|
|
6815
|
+
(id) => this.priceLookups.get(id),
|
|
6816
|
+
(id) => this.subagentMeta.get(id)
|
|
6817
|
+
);
|
|
6818
|
+
}
|
|
6486
6819
|
this.coordinator = new DefaultMultiAgentCoordinator(
|
|
6487
6820
|
{ ...opts.config, coordinatorId: this.id },
|
|
6488
6821
|
{ runner: opts.runner }
|
|
@@ -6529,7 +6862,7 @@ var Director = class {
|
|
|
6529
6862
|
const payload = e.payload;
|
|
6530
6863
|
const guardKey = `${e.subagentId}:${payload.kind}`;
|
|
6531
6864
|
const prior = extendCounts.get(guardKey) ?? 0;
|
|
6532
|
-
if (prior >=
|
|
6865
|
+
if (prior >= this.maxBudgetExtensions) {
|
|
6533
6866
|
payload.deny();
|
|
6534
6867
|
extendCounts.delete(guardKey);
|
|
6535
6868
|
return;
|
|
@@ -6584,52 +6917,73 @@ var Director = class {
|
|
|
6584
6917
|
* it the `cost` column in `usage.snapshot()` stays at 0.
|
|
6585
6918
|
*/
|
|
6586
6919
|
async spawn(config, priceLookup) {
|
|
6587
|
-
if (this.
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6920
|
+
if (this.fleetManager) {
|
|
6921
|
+
const rejection = this.fleetManager.canSpawn(config);
|
|
6922
|
+
if (rejection) {
|
|
6923
|
+
if (rejection.kind === "max_spawn_depth") throw new FleetSpawnBudgetError("max_spawn_depth", rejection.limit, rejection.observed);
|
|
6924
|
+
if (rejection.kind === "max_spawns") throw new FleetSpawnBudgetError("max_spawns", rejection.limit, rejection.observed);
|
|
6925
|
+
if (rejection.kind === "max_cost_usd") throw new FleetCostCapError(rejection.limit, rejection.observed);
|
|
6926
|
+
}
|
|
6927
|
+
} else {
|
|
6928
|
+
if (this.spawnDepth >= this.maxSpawnDepth) {
|
|
6929
|
+
throw new FleetSpawnBudgetError("max_spawn_depth", this.maxSpawnDepth, this.spawnDepth);
|
|
6930
|
+
}
|
|
6931
|
+
if (this.spawnCount >= this.maxSpawns) {
|
|
6932
|
+
throw new FleetSpawnBudgetError("max_spawns", this.maxSpawns, this.spawnCount + 1);
|
|
6933
|
+
}
|
|
6934
|
+
if (this.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
|
|
6935
|
+
const totalCost = this.usage.snapshot().total?.cost ?? 0;
|
|
6936
|
+
if (totalCost >= this.maxFleetCostUsd) {
|
|
6937
|
+
throw new FleetCostCapError(this.maxFleetCostUsd, totalCost);
|
|
6938
|
+
}
|
|
6939
|
+
}
|
|
6592
6940
|
}
|
|
6593
6941
|
const result = await this.coordinator.spawn(config);
|
|
6594
|
-
this.
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6942
|
+
if (this.fleetManager) {
|
|
6943
|
+
this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
|
|
6944
|
+
} else {
|
|
6945
|
+
this.spawnCount += 1;
|
|
6946
|
+
this.subagentMeta.set(result.subagentId, {
|
|
6947
|
+
provider: config.provider,
|
|
6948
|
+
model: config.model
|
|
6949
|
+
});
|
|
6950
|
+
if (priceLookup) this.priceLookups.set(result.subagentId, priceLookup);
|
|
6951
|
+
}
|
|
6600
6952
|
const subagentBridge = new InMemoryAgentBridge(
|
|
6601
6953
|
{ agentId: result.subagentId, coordinatorId: this.id },
|
|
6602
6954
|
this.transport
|
|
6603
6955
|
);
|
|
6604
6956
|
this.coordinator.setSubagentBridge(result.subagentId, subagentBridge);
|
|
6605
6957
|
this.subagentBridges.set(result.subagentId, subagentBridge);
|
|
6606
|
-
this.
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
role: config.role,
|
|
6610
|
-
provider: config.provider,
|
|
6611
|
-
model: config.model,
|
|
6612
|
-
taskIds: []
|
|
6613
|
-
});
|
|
6614
|
-
const spawnedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6615
|
-
this.stateCheckpoint?.recordSpawn(
|
|
6616
|
-
{
|
|
6617
|
-
id: result.subagentId,
|
|
6958
|
+
if (!this.fleetManager) {
|
|
6959
|
+
this.manifestEntries.set(result.subagentId, {
|
|
6960
|
+
subagentId: result.subagentId,
|
|
6618
6961
|
name: config.name,
|
|
6619
6962
|
role: config.role,
|
|
6620
6963
|
provider: config.provider,
|
|
6621
6964
|
model: config.model,
|
|
6622
|
-
|
|
6623
|
-
}
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6965
|
+
taskIds: []
|
|
6966
|
+
});
|
|
6967
|
+
const spawnedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6968
|
+
this.stateCheckpoint?.recordSpawn(
|
|
6969
|
+
{
|
|
6970
|
+
id: result.subagentId,
|
|
6971
|
+
name: config.name,
|
|
6972
|
+
role: config.role,
|
|
6973
|
+
provider: config.provider,
|
|
6974
|
+
model: config.model,
|
|
6975
|
+
spawnedAt
|
|
6976
|
+
},
|
|
6977
|
+
this.spawnCount
|
|
6978
|
+
);
|
|
6979
|
+
void this.appendSessionEvent({
|
|
6980
|
+
type: "agent_spawned",
|
|
6981
|
+
ts: spawnedAt,
|
|
6982
|
+
agentId: result.subagentId,
|
|
6983
|
+
role: config.role ?? config.name
|
|
6984
|
+
});
|
|
6985
|
+
this.scheduleManifest();
|
|
6986
|
+
}
|
|
6633
6987
|
return result.subagentId;
|
|
6634
6988
|
}
|
|
6635
6989
|
/**
|
|
@@ -6769,6 +7123,7 @@ var Director = class {
|
|
|
6769
7123
|
if (this.stateCheckpoint) {
|
|
6770
7124
|
this.stateCheckpoint.setUsage(this.usage.snapshot());
|
|
6771
7125
|
await this.stateCheckpoint.flush().catch((err) => this.logShutdownError("state_checkpoint_flush", err));
|
|
7126
|
+
await this.stateCheckpoint.releaseLock().catch((err) => this.logShutdownError("state_checkpoint_lock_release", err));
|
|
6772
7127
|
}
|
|
6773
7128
|
}
|
|
6774
7129
|
/**
|
|
@@ -6795,8 +7150,12 @@ var Director = class {
|
|
|
6795
7150
|
async assign(task) {
|
|
6796
7151
|
const taskWithId = task.id ? task : { ...task, id: randomUUID() };
|
|
6797
7152
|
if (task.subagentId) {
|
|
6798
|
-
|
|
6799
|
-
|
|
7153
|
+
if (this.fleetManager) {
|
|
7154
|
+
this.fleetManager.addTaskToSubagent(task.subagentId, taskWithId.id);
|
|
7155
|
+
} else {
|
|
7156
|
+
const entry = this.manifestEntries.get(task.subagentId);
|
|
7157
|
+
if (entry) entry.taskIds.push(taskWithId.id);
|
|
7158
|
+
}
|
|
6800
7159
|
}
|
|
6801
7160
|
await this.coordinator.assign(taskWithId);
|
|
6802
7161
|
this.taskDescriptions.set(taskWithId.id, taskWithId.description);
|
|
@@ -6872,6 +7231,58 @@ var Director = class {
|
|
|
6872
7231
|
completedResults() {
|
|
6873
7232
|
return Array.from(this.completed.values());
|
|
6874
7233
|
}
|
|
7234
|
+
/**
|
|
7235
|
+
* Inject a previously-saved checkpoint snapshot. Call this right after
|
|
7236
|
+
* constructing a Director during a `--resume` run so the in-memory state
|
|
7237
|
+
* (subagents, tasks, waiters) reflects the pre-crash reality instead of
|
|
7238
|
+
* starting from a blank slate. The director then resumes from there —
|
|
7239
|
+
* completing any in-flight tasks and ignoring tasks that already reached
|
|
7240
|
+
* a terminal state in the prior run.
|
|
7241
|
+
*/
|
|
7242
|
+
setCheckpointState(snapshot) {
|
|
7243
|
+
this.stateCheckpoint?.resume(snapshot);
|
|
7244
|
+
}
|
|
7245
|
+
/**
|
|
7246
|
+
* Read a subagent's JSONL transcript directly from disk (no bridge
|
|
7247
|
+
* round-trip needed). Returns the last assistant text, stop reason,
|
|
7248
|
+
* tool-use count, and line count — or null if the file is unavailable.
|
|
7249
|
+
* Requires `sessionsRoot` to be set on construction.
|
|
7250
|
+
*/
|
|
7251
|
+
async readSession(subagentId, tail) {
|
|
7252
|
+
if (!this.sessionsRoot) return null;
|
|
7253
|
+
const filePath = path3.join(this.sessionsRoot, this.directorRunId, `${subagentId}.jsonl`);
|
|
7254
|
+
let raw;
|
|
7255
|
+
try {
|
|
7256
|
+
raw = await fsp.readFile(filePath, "utf8");
|
|
7257
|
+
} catch {
|
|
7258
|
+
return null;
|
|
7259
|
+
}
|
|
7260
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
7261
|
+
const targetLines = tail ? lines.slice(-tail) : lines;
|
|
7262
|
+
let lastAssistantText;
|
|
7263
|
+
let lastStopReason;
|
|
7264
|
+
let toolUses = 0;
|
|
7265
|
+
for (const line of targetLines) {
|
|
7266
|
+
try {
|
|
7267
|
+
const ev = JSON.parse(line);
|
|
7268
|
+
if (ev.type === "assistant" && typeof ev.text === "string") {
|
|
7269
|
+
lastAssistantText = ev.text;
|
|
7270
|
+
} else if (ev.type === "stop" && ev.stopReason) {
|
|
7271
|
+
lastStopReason = ev.stopReason;
|
|
7272
|
+
} else if (ev.type === "tool_use") {
|
|
7273
|
+
toolUses++;
|
|
7274
|
+
}
|
|
7275
|
+
} catch {
|
|
7276
|
+
}
|
|
7277
|
+
}
|
|
7278
|
+
return {
|
|
7279
|
+
lastAssistantText,
|
|
7280
|
+
lastStopReason,
|
|
7281
|
+
toolUsesObserved: toolUses,
|
|
7282
|
+
events: targetLines.length,
|
|
7283
|
+
path: filePath
|
|
7284
|
+
};
|
|
7285
|
+
}
|
|
6875
7286
|
snapshot() {
|
|
6876
7287
|
return this.usage.snapshot();
|
|
6877
7288
|
}
|
|
@@ -6942,18 +7353,37 @@ var Director = class {
|
|
|
6942
7353
|
* still permission-checked normally.
|
|
6943
7354
|
*/
|
|
6944
7355
|
tools(roster) {
|
|
7356
|
+
const effectiveRoster = roster ?? this.roster;
|
|
6945
7357
|
const t = [
|
|
6946
|
-
makeSpawnTool(this,
|
|
7358
|
+
makeSpawnTool(this, effectiveRoster),
|
|
6947
7359
|
makeAssignTool(this),
|
|
6948
7360
|
makeAwaitTasksTool(this),
|
|
6949
7361
|
makeAskTool(this),
|
|
6950
7362
|
makeRollUpTool(this),
|
|
6951
7363
|
makeTerminateTool(this),
|
|
6952
7364
|
makeFleetStatusTool(this),
|
|
6953
|
-
makeFleetUsageTool(this)
|
|
7365
|
+
makeFleetUsageTool(this),
|
|
7366
|
+
makeFleetSessionTool(this),
|
|
7367
|
+
makeFleetHealthTool(this)
|
|
6954
7368
|
];
|
|
6955
7369
|
return t;
|
|
6956
7370
|
}
|
|
7371
|
+
/**
|
|
7372
|
+
* Attempt to acquire the checkpoint lock. Must be called before
|
|
7373
|
+
* resuming — if another director process is alive, this returns
|
|
7374
|
+
* false and the caller should not proceed with the resume.
|
|
7375
|
+
*/
|
|
7376
|
+
async acquireCheckpointLock() {
|
|
7377
|
+
return this.stateCheckpoint ? this.stateCheckpoint.acquireLock() : true;
|
|
7378
|
+
}
|
|
7379
|
+
/**
|
|
7380
|
+
* Resume from a prior checkpoint snapshot (loaded via
|
|
7381
|
+
* `loadDirectorState()`). Re-attach to the fleet mid-flight so
|
|
7382
|
+
* subsequent spawn/assign calls update the checkpoint normally.
|
|
7383
|
+
*/
|
|
7384
|
+
resumeFromCheckpoint(snapshot) {
|
|
7385
|
+
this.stateCheckpoint?.resume(snapshot);
|
|
7386
|
+
}
|
|
6957
7387
|
};
|
|
6958
7388
|
function createDelegateTool(opts) {
|
|
6959
7389
|
const defaultTimeoutMs = opts.defaultTimeoutMs ?? 4 * 60 * 60 * 1e3;
|
|
@@ -7059,7 +7489,7 @@ function createDelegateTool(opts) {
|
|
|
7059
7489
|
if (typeof i.maxToolCalls === "number" && i.maxToolCalls > 0) {
|
|
7060
7490
|
cfg.maxToolCalls = i.maxToolCalls;
|
|
7061
7491
|
}
|
|
7062
|
-
const SUBAGENT_TIMEOUT_BUFFER_MS = 3e4;
|
|
7492
|
+
const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 3e4;
|
|
7063
7493
|
const desiredSubTimeout = Math.max(3e4, timeoutMs - SUBAGENT_TIMEOUT_BUFFER_MS);
|
|
7064
7494
|
if (!cfg.timeoutMs || cfg.timeoutMs > desiredSubTimeout) {
|
|
7065
7495
|
cfg.timeoutMs = desiredSubTimeout;
|
|
@@ -7111,7 +7541,7 @@ function createDelegateTool(opts) {
|
|
|
7111
7541
|
toolCalls: result.toolCalls,
|
|
7112
7542
|
durationMs: result.durationMs,
|
|
7113
7543
|
...partial ? { partial } : {},
|
|
7114
|
-
...hintForKind(errorKind, retryable, backoffMs) ? { hint: hintForKind(errorKind, retryable, backoffMs) } : {}
|
|
7544
|
+
...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {}
|
|
7115
7545
|
};
|
|
7116
7546
|
} catch (err) {
|
|
7117
7547
|
return {
|
|
@@ -7131,7 +7561,7 @@ function instantiateRosterConfig2(role, base) {
|
|
|
7131
7561
|
id: `${role}-${randomUUID().slice(0, 8)}`
|
|
7132
7562
|
};
|
|
7133
7563
|
}
|
|
7134
|
-
function hintForKind(kind, retryable, backoffMs) {
|
|
7564
|
+
function hintForKind(kind, retryable, backoffMs, partial) {
|
|
7135
7565
|
if (!kind) return void 0;
|
|
7136
7566
|
switch (kind) {
|
|
7137
7567
|
case "provider_rate_limit":
|
|
@@ -7147,16 +7577,40 @@ function hintForKind(kind, retryable, backoffMs) {
|
|
|
7147
7577
|
case "budget_iterations":
|
|
7148
7578
|
case "budget_tool_calls":
|
|
7149
7579
|
case "budget_tokens":
|
|
7150
|
-
case "budget_cost":
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7580
|
+
case "budget_cost": {
|
|
7581
|
+
const base = "Subagent exhausted its budget. The coordinator may auto-extend; otherwise raise the matching `max*` field (e.g. maxToolCalls: 600) on the next delegate, or split the task.";
|
|
7582
|
+
if (partial?.lastAssistantText) {
|
|
7583
|
+
return `${base}
|
|
7584
|
+
|
|
7585
|
+
Partial output produced before budget hit:
|
|
7586
|
+
${partial.lastAssistantText}`;
|
|
7587
|
+
}
|
|
7588
|
+
return base;
|
|
7589
|
+
}
|
|
7590
|
+
case "budget_timeout": {
|
|
7591
|
+
const base = "Subagent hit its wall-clock budget. Raise `timeoutMs` on the next delegate or split the task.";
|
|
7592
|
+
if (partial?.lastAssistantText) {
|
|
7593
|
+
return `${base}
|
|
7594
|
+
|
|
7595
|
+
Partial output produced before timeout:
|
|
7596
|
+
${partial.lastAssistantText}`;
|
|
7597
|
+
}
|
|
7598
|
+
return base;
|
|
7599
|
+
}
|
|
7154
7600
|
case "aborted_by_parent":
|
|
7155
7601
|
return "Subagent was aborted (user Ctrl+C, parent unwound, or sibling failure cascade). Not retryable until the abort condition is resolved.";
|
|
7156
7602
|
case "empty_response":
|
|
7157
7603
|
return "Subagent ended its turn with no text and no tool calls. Almost always a prompt / config issue \u2014 clarify the task or check the model.";
|
|
7158
|
-
case "tool_failed":
|
|
7159
|
-
|
|
7604
|
+
case "tool_failed": {
|
|
7605
|
+
const base = "A tool inside the subagent returned ok:false. Retry with corrected inputs.";
|
|
7606
|
+
if (partial?.lastAssistantText) {
|
|
7607
|
+
return `${base}
|
|
7608
|
+
|
|
7609
|
+
Agent reasoning before failure:
|
|
7610
|
+
${partial.lastAssistantText}`;
|
|
7611
|
+
}
|
|
7612
|
+
return base;
|
|
7613
|
+
}
|
|
7160
7614
|
case "bridge_failed":
|
|
7161
7615
|
return "Parent-child bridge transport failed. This is rare \u2014 restart the session and retry.";
|
|
7162
7616
|
default:
|
|
@@ -7367,6 +7821,9 @@ function makeDirectorSessionFactory(opts) {
|
|
|
7367
7821
|
}
|
|
7368
7822
|
};
|
|
7369
7823
|
}
|
|
7824
|
+
|
|
7825
|
+
// src/coordination/null-fleet-bus.ts
|
|
7826
|
+
var NULL_FLEET_BUS = new FleetBus();
|
|
7370
7827
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
7371
7828
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
7372
7829
|
var FAMILY_BY_NPM = {
|
|
@@ -11286,6 +11743,6 @@ var allServers = () => ({
|
|
|
11286
11743
|
"minimax-vision": { ...miniMaxVisionServer(), enabled: false }
|
|
11287
11744
|
});
|
|
11288
11745
|
|
|
11289
|
-
export { AISpecBuilder, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, ConfigMigrationError, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_SUBAGENT_BASELINE, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionStore, DefaultSkillLoader, DefaultTaskStore, Director,
|
|
11746
|
+
export { AISpecBuilder, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, ConfigMigrationError, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_SUBAGENT_BASELINE, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPermissionPolicy, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionStore, DefaultSkillLoader, DefaultTaskStore, Director, DirectorStateCheckpoint, DoneConditionChecker, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetSpawnBudgetError, FleetUsageAggregator, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, IntelligentCompactor, LLMSelector, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, SelectiveCompactor, SessionAnalyzer, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, ToolExecutor, addPlanItem, allServers, analyzeCriticalPath, applyRosterBudget, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildOtlpMetricsRequest, buildOtlpTracesRequest, classifyFamily, clearPlan, composeDirectorPrompt, composeSubagentPrompt, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDelegateTool, createMessage, decryptConfigSecrets2 as decryptConfigSecrets, deriveTodosFromPlanItem, emptyPlan, encryptConfigSecrets, everArtServer, filesystemServer, formatPlan, formatPlanTemplates, getPlanTemplate, getTemplate, githubServer, googleMapsServer, listPlanTemplates, listTemplates, loadDirectorState, loadPlan, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeDirectorSessionFactory, migratePlaintextSecrets, miniMaxVisionServer, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, savePlan, saveTodosCheckpoint, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, templateToMarkdown, wireMetricsToEvents, zaiVisionServer };
|
|
11290
11747
|
//# sourceMappingURL=index.js.map
|
|
11291
11748
|
//# sourceMappingURL=index.js.map
|