@wrongstack/core 0.6.6 → 0.6.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-BBXK_ppx.d.ts → agent-bridge-BCVxmrOn.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DsSm9lKN.d.ts → agent-subagent-runner-BTloSwjE.d.ts} +3 -3
- package/dist/{compactor-C8NhpSt5.d.ts → compactor-BUJ8550X.d.ts} +1 -1
- package/dist/{config-DfC6g6KV.d.ts → config-BHkYGzUT.d.ts} +1 -1
- package/dist/{context-DN5v-uQX.d.ts → context-C8mBUzBv.d.ts} +3 -5
- package/dist/coordination/index.d.ts +10 -10
- package/dist/coordination/index.js +62 -30
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +19 -19
- package/dist/defaults/index.js +94 -32
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-CJqwQl8G.d.ts → events-DounT6pP.d.ts} +10 -1
- package/dist/execution/index.d.ts +20 -12
- package/dist/execution/index.js +59 -18
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{index-CXnWsGBp.d.ts → index-BlVITqm-.d.ts} +6 -9
- package/dist/{index-DcnXDPdY.d.ts → index-DiIGZh5I.d.ts} +20 -5
- package/dist/index.d.ts +26 -26
- package/dist/index.js +212 -127
- 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/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-CevFHHM1.d.ts → mcp-servers-CXFfDN_d.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/{multi-agent-D5IbASk_.d.ts → multi-agent-Iy8YUe3v.d.ts} +4 -4
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-CBx_q1HA.d.ts → path-resolver-DwJO5XBn.d.ts} +2 -2
- package/dist/{plan-templates-BEOllUJV.d.ts → plan-templates-CG_pInJV.d.ts} +4 -4
- package/dist/{provider-runner-Byh5TcJs.d.ts → provider-runner-DoohzfyD.d.ts} +3 -3
- package/dist/{retry-policy-BZSIMxrJ.d.ts → retry-policy-DOnwHAyz.d.ts} +1 -1
- package/dist/sdd/index.d.ts +3 -3
- package/dist/{secret-scrubber-CT7wefiO.d.ts → secret-scrubber-C9UJxFCJ.d.ts} +1 -1
- package/dist/{secret-scrubber-I0QHY_ob.d.ts → secret-scrubber-DcTK9JHC.d.ts} +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/{selector-DDb_mq9X.d.ts → selector-DVo3eT-P.d.ts} +1 -1
- package/dist/{session-reader-B9nVkziM.d.ts → session-reader-BXWxFAhS.d.ts} +1 -1
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-gL06H9P4.d.ts → system-prompt-BBGles-N.d.ts} +1 -1
- package/dist/{tool-executor-BF7QfYVE.d.ts → tool-executor-CwpjhwHC.d.ts} +4 -4
- package/dist/types/index.d.ts +15 -15
- package/dist/types/index.js +1 -3
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2558,10 +2558,8 @@ var InMemoryAgentBridge = class {
|
|
|
2558
2558
|
this.pendingRequests.delete(correlationId);
|
|
2559
2559
|
reject(new Error(`Request ${correlationId} timed out after ${timeout}ms`));
|
|
2560
2560
|
}, timeout);
|
|
2561
|
-
if (this.
|
|
2561
|
+
if (!this.inflightGuards.has(correlationId)) {
|
|
2562
2562
|
clearTimeout(timer);
|
|
2563
|
-
this.inflightGuards.delete(correlationId);
|
|
2564
|
-
this.pendingRequests.delete(correlationId);
|
|
2565
2563
|
reject(new Error("Bridge stopped"));
|
|
2566
2564
|
return;
|
|
2567
2565
|
}
|
|
@@ -5745,7 +5743,7 @@ var DirectorStateCheckpoint = class {
|
|
|
5745
5743
|
this.timer = null;
|
|
5746
5744
|
}
|
|
5747
5745
|
await this.persist();
|
|
5748
|
-
|
|
5746
|
+
while (this.rewriteRequested) {
|
|
5749
5747
|
this.rewriteRequested = false;
|
|
5750
5748
|
await this.persist();
|
|
5751
5749
|
}
|
|
@@ -7454,7 +7452,8 @@ function formatGoal(goal, journalLimit = 10) {
|
|
|
7454
7452
|
// src/execution/eternal-autonomy.ts
|
|
7455
7453
|
var execFileP = promisify(execFile);
|
|
7456
7454
|
var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
|
|
7457
|
-
var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]
|
|
7455
|
+
var GOAL_COMPLETE_MARKER = /^\s*\[goal[_\s-]*complete\]\s*$/im;
|
|
7456
|
+
var GOAL_CLEAR_MARKER = /^\s*\[\/?goal\s*clear\]\s*$/im;
|
|
7458
7457
|
var EternalAutonomyEngine = class {
|
|
7459
7458
|
constructor(opts) {
|
|
7460
7459
|
this.opts = opts;
|
|
@@ -7680,7 +7679,12 @@ var EternalAutonomyEngine = class {
|
|
|
7680
7679
|
emit({ phase: "sleep", ms: cycleGapMs });
|
|
7681
7680
|
await sleep(cycleGapMs);
|
|
7682
7681
|
if (GOAL_COMPLETE_MARKER.test(finalText)) {
|
|
7683
|
-
await this.
|
|
7682
|
+
await this.clearGoalManually(finalText);
|
|
7683
|
+
this.stopRequested = true;
|
|
7684
|
+
return true;
|
|
7685
|
+
}
|
|
7686
|
+
if (GOAL_CLEAR_MARKER.test(finalText)) {
|
|
7687
|
+
await this.clearGoalManually(finalText);
|
|
7684
7688
|
this.stopRequested = true;
|
|
7685
7689
|
return true;
|
|
7686
7690
|
}
|
|
@@ -7980,6 +7984,30 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
7980
7984
|
});
|
|
7981
7985
|
await saveGoal(this.goalPath, withEntry);
|
|
7982
7986
|
}
|
|
7987
|
+
/**
|
|
7988
|
+
* Manually clear the goal — equivalent to `/goal clear` typed by the user.
|
|
7989
|
+
* Sets goalState to `abandoned`, removes the goal file, and fires
|
|
7990
|
+
* `onEternalStop` so the REPL returns to normal mode.
|
|
7991
|
+
*/
|
|
7992
|
+
async clearGoalManually(note) {
|
|
7993
|
+
const current = await loadGoal(this.goalPath);
|
|
7994
|
+
if (current) {
|
|
7995
|
+
const abandoned = { ...current, goalState: "abandoned" };
|
|
7996
|
+
await saveGoal(this.goalPath, abandoned);
|
|
7997
|
+
}
|
|
7998
|
+
try {
|
|
7999
|
+
const { unlink: unlink10 } = await import('fs/promises');
|
|
8000
|
+
await unlink10(this.goalPath);
|
|
8001
|
+
} catch {
|
|
8002
|
+
}
|
|
8003
|
+
this.opts.onEternalStop?.();
|
|
8004
|
+
void this.appendIterationEntry({
|
|
8005
|
+
source: "manual",
|
|
8006
|
+
task: "goal cleared",
|
|
8007
|
+
status: "success",
|
|
8008
|
+
note: note.slice(0, 240)
|
|
8009
|
+
});
|
|
8010
|
+
}
|
|
7983
8011
|
async appendFailure(task, note) {
|
|
7984
8012
|
await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
|
|
7985
8013
|
}
|
|
@@ -8047,10 +8075,10 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8047
8075
|
* or hung listener (Director not built / event filter detached mid-run)
|
|
8048
8076
|
* leaves the budget over-limit and never enforces anything, since
|
|
8049
8077
|
* `checkLimit` returns synchronously via `void this.checkLimitAsync`.
|
|
8050
|
-
*
|
|
8051
|
-
*
|
|
8078
|
+
* Raised from 30s to 60s to give subagents more headroom before
|
|
8079
|
+
* the threshold negotiation times out and triggers a hard stop.
|
|
8052
8080
|
*/
|
|
8053
|
-
static DECISION_TIMEOUT_MS =
|
|
8081
|
+
static DECISION_TIMEOUT_MS = 6e4;
|
|
8054
8082
|
/**
|
|
8055
8083
|
* Injected by the runner when wiring the budget to its EventBus.
|
|
8056
8084
|
* Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
|
|
@@ -8581,13 +8609,19 @@ var FLEET_ROSTER = {
|
|
|
8581
8609
|
"security-scanner": SECURITY_SCANNER_AGENT
|
|
8582
8610
|
};
|
|
8583
8611
|
var FLEET_ROSTER_BUDGETS = {
|
|
8584
|
-
"audit-log": { timeoutMs:
|
|
8585
|
-
"bug-hunter": { timeoutMs:
|
|
8586
|
-
"refactor-planner": { timeoutMs:
|
|
8587
|
-
"security-scanner": { timeoutMs:
|
|
8612
|
+
"audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
|
|
8613
|
+
"bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
|
|
8614
|
+
"refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
|
|
8615
|
+
"security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 }
|
|
8616
|
+
};
|
|
8617
|
+
var GENERIC_SUBAGENT_BUDGET = {
|
|
8618
|
+
timeoutMs: 3 * 60 * 60 * 1e3,
|
|
8619
|
+
maxIterations: 5e3,
|
|
8620
|
+
maxToolCalls: 15e3
|
|
8588
8621
|
};
|
|
8589
8622
|
function applyRosterBudget(cfg) {
|
|
8590
|
-
const
|
|
8623
|
+
const roleBudget = cfg.role ? FLEET_ROSTER_BUDGETS[cfg.role] : void 0;
|
|
8624
|
+
const defaultBudget = roleBudget ?? (cfg.name ? GENERIC_SUBAGENT_BUDGET : void 0);
|
|
8591
8625
|
if (!defaultBudget) return cfg;
|
|
8592
8626
|
return {
|
|
8593
8627
|
...cfg,
|
|
@@ -8659,7 +8693,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
8659
8693
|
// hasParentBridge() — the type now reflects this.
|
|
8660
8694
|
parentBridge: null,
|
|
8661
8695
|
doneCondition: this.config.doneCondition,
|
|
8662
|
-
maxConcurrent: this.config.maxConcurrent ??
|
|
8696
|
+
maxConcurrent: this.config.maxConcurrent ?? 16
|
|
8663
8697
|
};
|
|
8664
8698
|
this.subagents.set(id, {
|
|
8665
8699
|
config: { ...subagent, id },
|
|
@@ -8786,7 +8820,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
8786
8820
|
}
|
|
8787
8821
|
}
|
|
8788
8822
|
canDispatch() {
|
|
8789
|
-
const max = this.config.maxConcurrent ??
|
|
8823
|
+
const max = this.config.maxConcurrent ?? 16;
|
|
8790
8824
|
return this.inFlight < max && this.pendingTasks.length > 0;
|
|
8791
8825
|
}
|
|
8792
8826
|
takeNextDispatchableTask() {
|
|
@@ -8880,13 +8914,18 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
8880
8914
|
task.subagentId = subagentId;
|
|
8881
8915
|
subagent.context.tasks.push(task);
|
|
8882
8916
|
this.emit("task.assigned", { task, subagentId });
|
|
8917
|
+
const rawMaxIterations = subagent.config.maxIterations;
|
|
8918
|
+
const rawMaxToolCalls = subagent.config.maxToolCalls;
|
|
8919
|
+
const rawMaxTokens = subagent.config.maxTokens;
|
|
8920
|
+
const rawMaxCostUsd = subagent.config.maxCostUsd;
|
|
8921
|
+
const rawTimeoutMs = subagent.config.timeoutMs;
|
|
8883
8922
|
const configWithRosterDefaults = applyRosterBudget(subagent.config);
|
|
8884
8923
|
const budget = new SubagentBudget({
|
|
8885
|
-
maxIterations:
|
|
8886
|
-
maxToolCalls:
|
|
8887
|
-
maxTokens:
|
|
8888
|
-
maxCostUsd:
|
|
8889
|
-
timeoutMs:
|
|
8924
|
+
maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
|
|
8925
|
+
maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
|
|
8926
|
+
maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
|
|
8927
|
+
maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
|
|
8928
|
+
timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs
|
|
8890
8929
|
});
|
|
8891
8930
|
subagent.activeBudget = budget;
|
|
8892
8931
|
if (!this.runner) {
|
|
@@ -8957,7 +8996,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
8957
8996
|
kind: "timeout",
|
|
8958
8997
|
used: elapsed,
|
|
8959
8998
|
limit,
|
|
8960
|
-
timeoutMs:
|
|
8999
|
+
timeoutMs: 6e4,
|
|
8961
9000
|
extend: (extra) => resolveDecision({ extend: extra }),
|
|
8962
9001
|
deny: () => resolveDecision("stop")
|
|
8963
9002
|
});
|
|
@@ -10387,7 +10426,12 @@ var Director = class {
|
|
|
10387
10426
|
}
|
|
10388
10427
|
}
|
|
10389
10428
|
}
|
|
10390
|
-
|
|
10429
|
+
let result;
|
|
10430
|
+
try {
|
|
10431
|
+
result = await this.coordinator.spawn(config);
|
|
10432
|
+
} catch (err) {
|
|
10433
|
+
throw err;
|
|
10434
|
+
}
|
|
10391
10435
|
if (this.fleetManager) {
|
|
10392
10436
|
this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
|
|
10393
10437
|
} else {
|
|
@@ -10835,7 +10879,7 @@ var Director = class {
|
|
|
10835
10879
|
}
|
|
10836
10880
|
};
|
|
10837
10881
|
function createDelegateTool(opts) {
|
|
10838
|
-
const defaultTimeoutMs = opts.defaultTimeoutMs ??
|
|
10882
|
+
const defaultTimeoutMs = opts.defaultTimeoutMs ?? 30 * 60 * 1e3;
|
|
10839
10883
|
const rosterIds = opts.roster ? Object.keys(opts.roster) : [];
|
|
10840
10884
|
const inputSchema = {
|
|
10841
10885
|
type: "object",
|
|
@@ -10851,7 +10895,7 @@ function createDelegateTool(opts) {
|
|
|
10851
10895
|
},
|
|
10852
10896
|
name: {
|
|
10853
10897
|
type: "string",
|
|
10854
|
-
description: "Display name for
|
|
10898
|
+
description: "Display name for free-form subagents (not using a roster role). The subagent gets a large default budget (3h, 5000 iter, 15000 tool calls). Required when `role` is omitted."
|
|
10855
10899
|
},
|
|
10856
10900
|
provider: {
|
|
10857
10901
|
type: "string",
|
|
@@ -10882,8 +10926,8 @@ function createDelegateTool(opts) {
|
|
|
10882
10926
|
};
|
|
10883
10927
|
return {
|
|
10884
10928
|
name: "delegate",
|
|
10885
|
-
description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
|
|
10886
|
-
usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster or pass `name`
|
|
10929
|
+
description: "Hand a discrete piece of work to a dedicated subagent and wait for its result. The subagent has its own context, its own LLM call, and its own budget \u2014 use this when a task is self-contained, would otherwise blow up your context, or benefits from a specialized role (bug-hunter, security-scanner, refactor-planner, audit-log). For free-form coding tasks (not tied to a pre-defined role), pass `name` + `task` \u2014 the subagent runs as a general-purpose coding agent with a large default budget. YOU decide how big the budget is: pass `timeoutMs`, `maxIterations`, and `maxToolCalls` sized to the actual work. There is no hidden cap forcing a 3-minute / 80-iteration limit \u2014 if a monorepo audit needs 2 hours and 500 tool calls, ask for that. Call multiple delegates in parallel through the provider's parallel-tool-call surface to fan work out across roles.",
|
|
10930
|
+
usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster (audit-log, bug-hunter, refactor-planner, security-scanner) or pass `name` to run a free-form coding agent. For non-trivial work, also pass `timeoutMs`, `maxIterations`, and `maxToolCalls`. Returns the subagent's `TaskResult` \u2014 including the textual `result`, iteration count, tool count, and duration. Auto-promotes the host into director mode on first call.",
|
|
10887
10931
|
permission: "auto",
|
|
10888
10932
|
mutating: false,
|
|
10889
10933
|
inputSchema,
|
|
@@ -10931,6 +10975,7 @@ function createDelegateTool(opts) {
|
|
|
10931
10975
|
model: i.model,
|
|
10932
10976
|
systemPromptOverride: i.systemPromptOverride
|
|
10933
10977
|
};
|
|
10978
|
+
cfg = applyRosterBudget({ ...cfg, name: i.name });
|
|
10934
10979
|
}
|
|
10935
10980
|
if (typeof i.maxIterations === "number" && i.maxIterations > 0) {
|
|
10936
10981
|
cfg.maxIterations = i.maxIterations;
|
|
@@ -10938,7 +10983,7 @@ function createDelegateTool(opts) {
|
|
|
10938
10983
|
if (typeof i.maxToolCalls === "number" && i.maxToolCalls > 0) {
|
|
10939
10984
|
cfg.maxToolCalls = i.maxToolCalls;
|
|
10940
10985
|
}
|
|
10941
|
-
const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ??
|
|
10986
|
+
const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 6e4;
|
|
10942
10987
|
const desiredSubTimeout = Math.max(3e4, timeoutMs - SUBAGENT_TIMEOUT_BUFFER_MS);
|
|
10943
10988
|
if (!cfg.timeoutMs || cfg.timeoutMs > desiredSubTimeout) {
|
|
10944
10989
|
cfg.timeoutMs = desiredSubTimeout;
|
|
@@ -10975,6 +11020,7 @@ function createDelegateTool(opts) {
|
|
|
10975
11020
|
const errorKind = result.error?.kind;
|
|
10976
11021
|
const retryable = result.error?.retryable;
|
|
10977
11022
|
const backoffMs = result.error?.backoffMs;
|
|
11023
|
+
const summary = buildDelegateSummary(i.role, result);
|
|
10978
11024
|
return {
|
|
10979
11025
|
ok: result.status === "success",
|
|
10980
11026
|
status: result.status,
|
|
@@ -10990,7 +11036,10 @@ function createDelegateTool(opts) {
|
|
|
10990
11036
|
toolCalls: result.toolCalls,
|
|
10991
11037
|
durationMs: result.durationMs,
|
|
10992
11038
|
...partial ? { partial } : {},
|
|
10993
|
-
...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {}
|
|
11039
|
+
...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {},
|
|
11040
|
+
// Summary is included so callers (TUI, CLI renderer) can surface
|
|
11041
|
+
// it as a chat history line — the LLM also sees it for continuity.
|
|
11042
|
+
summary
|
|
10994
11043
|
};
|
|
10995
11044
|
} catch (err) {
|
|
10996
11045
|
return {
|
|
@@ -11003,10 +11052,11 @@ function createDelegateTool(opts) {
|
|
|
11003
11052
|
};
|
|
11004
11053
|
}
|
|
11005
11054
|
function instantiateRosterConfig2(role, base) {
|
|
11055
|
+
const withBudget = applyRosterBudget({ ...base, role });
|
|
11006
11056
|
return {
|
|
11007
|
-
...
|
|
11008
|
-
//
|
|
11009
|
-
//
|
|
11057
|
+
...withBudget,
|
|
11058
|
+
// Give each spawn a fresh id so parallel or repeated delegates
|
|
11059
|
+
// can use the same role safely.
|
|
11010
11060
|
id: `${role}-${randomUUID().slice(0, 8)}`
|
|
11011
11061
|
};
|
|
11012
11062
|
}
|
|
@@ -11066,6 +11116,18 @@ ${partial.lastAssistantText}`;
|
|
|
11066
11116
|
return retryable ? "Failure classified as retryable. Try again with the same input." : void 0;
|
|
11067
11117
|
}
|
|
11068
11118
|
}
|
|
11119
|
+
function buildDelegateSummary(role, result) {
|
|
11120
|
+
const roleLabel = role ?? "subagent";
|
|
11121
|
+
const ms = result.durationMs;
|
|
11122
|
+
const duration = ms < 6e4 ? `${Math.round(ms / 1e3)}s` : ms < 36e5 ? `${Math.round(ms / 6e4)}m` : `${(ms / 36e5).toFixed(1)}h`;
|
|
11123
|
+
if (result.status === "success") {
|
|
11124
|
+
const preview = typeof result.result === "string" ? result.result.trim().slice(0, 120).replace(/\n+/g, " ") : null;
|
|
11125
|
+
const tail = preview ? ` \u2014 ${preview}` : "";
|
|
11126
|
+
return `[${roleLabel}] done in ${duration} (${result.iterations} iter, ${result.toolCalls} tools)${tail}`;
|
|
11127
|
+
}
|
|
11128
|
+
const errLabel = result.error?.kind ?? result.status;
|
|
11129
|
+
return `[${roleLabel}] ${result.status} after ${duration} (${result.iterations} iter, ${result.toolCalls} tools) \u2014 ${errLabel}`;
|
|
11130
|
+
}
|
|
11069
11131
|
async function readSubagentPartial(opts, subagentId) {
|
|
11070
11132
|
if (!opts.sessionsRoot) return void 0;
|
|
11071
11133
|
const candidates = [];
|
|
@@ -17987,10 +18049,15 @@ var Agent = class {
|
|
|
17987
18049
|
});
|
|
17988
18050
|
let finalText = "";
|
|
17989
18051
|
let iterations = 0;
|
|
18052
|
+
const delegateSummaries = [];
|
|
17990
18053
|
let effectiveLimit = opts.maxIterations ?? this.maxIterations;
|
|
17991
18054
|
const hasHardLimit = effectiveLimit > 0 && Number.isFinite(effectiveLimit);
|
|
17992
18055
|
let recoveryRetries = 0;
|
|
17993
18056
|
const autonomousContinue = opts.autonomousContinue ?? this.autonomousContinue;
|
|
18057
|
+
const onSubagentDone = ({ summary, ok }) => {
|
|
18058
|
+
delegateSummaries.push({ summary, ok });
|
|
18059
|
+
};
|
|
18060
|
+
const offSubagentDone = this.events.on("subagent.done", onSubagentDone);
|
|
17994
18061
|
const diRunner = this.container.has(TOKENS.ProviderRunner) ? this.container.resolve(TOKENS.ProviderRunner) : null;
|
|
17995
18062
|
const baseRunner = diRunner ? (ctx, req) => diRunner.run({
|
|
17996
18063
|
provider: ctx.provider,
|
|
@@ -18012,116 +18079,122 @@ var Agent = class {
|
|
|
18012
18079
|
tracer: this.tracer
|
|
18013
18080
|
});
|
|
18014
18081
|
const customRunner = this.extensions.wrapProviderRunner(baseRunner);
|
|
18015
|
-
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
return { status: "aborted", iterations };
|
|
18019
|
-
}
|
|
18020
|
-
if (autonomousContinue) {
|
|
18021
|
-
consumeAutonomousContinue(this.ctx);
|
|
18022
|
-
}
|
|
18023
|
-
const limitCheck = await this.checkIterationLimit(
|
|
18024
|
-
i,
|
|
18025
|
-
effectiveLimit,
|
|
18026
|
-
hasHardLimit,
|
|
18027
|
-
iterations
|
|
18028
|
-
);
|
|
18029
|
-
effectiveLimit = limitCheck.limit;
|
|
18030
|
-
if (limitCheck.exit) {
|
|
18031
|
-
return { ...limitCheck.exit, finalText };
|
|
18032
|
-
}
|
|
18033
|
-
await this.extensions.runBeforeIteration(this.ctx, i);
|
|
18034
|
-
this.events.emit("iteration.started", { ctx: this.ctx, index: i });
|
|
18035
|
-
const req = await this.buildAndRunRequestPipeline(opts);
|
|
18036
|
-
let res;
|
|
18037
|
-
try {
|
|
18038
|
-
res = await customRunner(this.ctx, req);
|
|
18039
|
-
recoveryRetries = 0;
|
|
18040
|
-
} catch (err) {
|
|
18082
|
+
try {
|
|
18083
|
+
for (let i = 0; ; i++) {
|
|
18084
|
+
iterations = i + 1;
|
|
18041
18085
|
if (controller.signal.aborted) {
|
|
18042
|
-
|
|
18043
|
-
return { status: "aborted", iterations, error: toWrongStackError(err, "AGENT_ABORTED") };
|
|
18086
|
+
return { status: "aborted", iterations };
|
|
18044
18087
|
}
|
|
18045
|
-
|
|
18046
|
-
|
|
18047
|
-
|
|
18088
|
+
if (autonomousContinue) {
|
|
18089
|
+
consumeAutonomousContinue(this.ctx);
|
|
18090
|
+
}
|
|
18091
|
+
const limitCheck = await this.checkIterationLimit(
|
|
18092
|
+
i,
|
|
18093
|
+
effectiveLimit,
|
|
18094
|
+
hasHardLimit,
|
|
18095
|
+
iterations,
|
|
18096
|
+
delegateSummaries
|
|
18097
|
+
);
|
|
18098
|
+
effectiveLimit = limitCheck.limit;
|
|
18099
|
+
if (limitCheck.exit) {
|
|
18100
|
+
return { ...limitCheck.exit, finalText };
|
|
18101
|
+
}
|
|
18102
|
+
await this.extensions.runBeforeIteration(this.ctx, i);
|
|
18103
|
+
this.events.emit("iteration.started", { ctx: this.ctx, index: i });
|
|
18104
|
+
const req = await this.buildAndRunRequestPipeline(opts);
|
|
18105
|
+
let res;
|
|
18106
|
+
try {
|
|
18107
|
+
res = await customRunner(this.ctx, req);
|
|
18108
|
+
recoveryRetries = 0;
|
|
18109
|
+
} catch (err) {
|
|
18110
|
+
if (controller.signal.aborted) {
|
|
18048
18111
|
this.events.emit("error", { err: toError(err), phase: "provider" });
|
|
18049
|
-
return { status: "
|
|
18112
|
+
return { status: "aborted", iterations, error: toWrongStackError(err, "AGENT_ABORTED") };
|
|
18050
18113
|
}
|
|
18051
|
-
|
|
18052
|
-
|
|
18053
|
-
|
|
18114
|
+
const extDecision = await this.extensions.runOnError(this.ctx, err, "provider", i);
|
|
18115
|
+
if (extDecision) {
|
|
18116
|
+
if (extDecision.action === "fail") {
|
|
18117
|
+
this.events.emit("error", { err: toError(err), phase: "provider" });
|
|
18118
|
+
return { status: "failed", iterations, error: toWrongStackError(err), delegateSummaries };
|
|
18119
|
+
}
|
|
18120
|
+
if (extDecision.action === "continue") {
|
|
18121
|
+
await this.extensions.runAfterIteration(this.ctx, i);
|
|
18122
|
+
continue;
|
|
18123
|
+
}
|
|
18124
|
+
if (extDecision.action === "retry") {
|
|
18125
|
+
recoveryRetries++;
|
|
18126
|
+
if (recoveryRetries > 2) {
|
|
18127
|
+
this.events.emit("error", { err: toError(err), phase: "provider" });
|
|
18128
|
+
return { status: "failed", iterations, error: toWrongStackError(err), delegateSummaries };
|
|
18129
|
+
}
|
|
18130
|
+
if (extDecision.model) this.ctx.model = extDecision.model;
|
|
18131
|
+
this.logger.info("Extension requested retry; retrying turn");
|
|
18132
|
+
continue;
|
|
18133
|
+
}
|
|
18054
18134
|
}
|
|
18055
|
-
|
|
18135
|
+
const recovered = await this.errorHandler.recover(err, this.ctx);
|
|
18136
|
+
if (!recovered || recovered.action === "fail") {
|
|
18137
|
+
this.events.emit("error", { err: toError(err), phase: "provider" });
|
|
18138
|
+
return {
|
|
18139
|
+
status: "failed",
|
|
18140
|
+
iterations,
|
|
18141
|
+
error: toWrongStackError(recovered?.error ?? err),
|
|
18142
|
+
delegateSummaries
|
|
18143
|
+
};
|
|
18144
|
+
}
|
|
18145
|
+
if (recovered.action === "retry") {
|
|
18056
18146
|
recoveryRetries++;
|
|
18057
18147
|
if (recoveryRetries > 2) {
|
|
18058
18148
|
this.events.emit("error", { err: toError(err), phase: "provider" });
|
|
18059
18149
|
return { status: "failed", iterations, error: toWrongStackError(err) };
|
|
18060
18150
|
}
|
|
18061
|
-
if (
|
|
18062
|
-
this.logger.info(
|
|
18151
|
+
if (recovered.model) this.ctx.model = recovered.model;
|
|
18152
|
+
this.logger.info(`Recovered provider error via ${recovered.reason}; retrying turn`);
|
|
18063
18153
|
continue;
|
|
18064
18154
|
}
|
|
18155
|
+
recoveryRetries = 0;
|
|
18156
|
+
res = recovered.response;
|
|
18065
18157
|
}
|
|
18066
|
-
const
|
|
18067
|
-
if (
|
|
18068
|
-
|
|
18069
|
-
return {
|
|
18070
|
-
status: "failed",
|
|
18071
|
-
iterations,
|
|
18072
|
-
error: toWrongStackError(recovered?.error ?? err)
|
|
18073
|
-
};
|
|
18158
|
+
const responseResult = await this.processResponse(res, req);
|
|
18159
|
+
if (responseResult.aborted) {
|
|
18160
|
+
return { status: "aborted", iterations, finalText: responseResult.finalText, delegateSummaries };
|
|
18074
18161
|
}
|
|
18075
|
-
if (
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18162
|
+
if (responseResult.done) {
|
|
18163
|
+
return { status: "done", iterations, finalText: responseResult.finalText, delegateSummaries };
|
|
18164
|
+
}
|
|
18165
|
+
finalText = responseResult.finalText;
|
|
18166
|
+
const toolUses = res.content.filter(isToolUseBlock);
|
|
18167
|
+
if (toolUses.length === 0) {
|
|
18168
|
+
this.events.emit("iteration.completed", { ctx: this.ctx, index: i });
|
|
18169
|
+
if (autonomousContinue && responseResult.directive === "continue") {
|
|
18170
|
+
await this.compactContextIfNeeded();
|
|
18171
|
+
await this.extensions.runAfterIteration(this.ctx, i);
|
|
18172
|
+
continue;
|
|
18080
18173
|
}
|
|
18081
|
-
if (
|
|
18082
|
-
|
|
18083
|
-
|
|
18174
|
+
if (autonomousContinue && responseResult.directive === "stop") {
|
|
18175
|
+
return { status: "done", iterations, finalText, delegateSummaries };
|
|
18176
|
+
}
|
|
18177
|
+
return { status: "done", iterations, finalText, delegateSummaries };
|
|
18084
18178
|
}
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
const responseResult = await this.processResponse(res, req);
|
|
18089
|
-
if (responseResult.aborted) {
|
|
18090
|
-
return { status: "aborted", iterations, finalText: responseResult.finalText };
|
|
18091
|
-
}
|
|
18092
|
-
if (responseResult.done) {
|
|
18093
|
-
return { status: "done", iterations, finalText: responseResult.finalText };
|
|
18094
|
-
}
|
|
18095
|
-
finalText = responseResult.finalText;
|
|
18096
|
-
const toolUses = res.content.filter(isToolUseBlock);
|
|
18097
|
-
if (toolUses.length === 0) {
|
|
18098
|
-
this.events.emit("iteration.completed", { ctx: this.ctx, index: i });
|
|
18099
|
-
if (autonomousContinue && responseResult.directive === "continue") {
|
|
18179
|
+
await this.executeTools(toolUses);
|
|
18180
|
+
if (autonomousContinue && consumeAutonomousContinue(this.ctx)) {
|
|
18181
|
+
this.events.emit("iteration.completed", { ctx: this.ctx, index: i });
|
|
18100
18182
|
await this.compactContextIfNeeded();
|
|
18101
18183
|
await this.extensions.runAfterIteration(this.ctx, i);
|
|
18102
18184
|
continue;
|
|
18103
18185
|
}
|
|
18104
|
-
if (autonomousContinue && responseResult.directive === "stop") {
|
|
18105
|
-
return { status: "done", iterations, finalText };
|
|
18106
|
-
}
|
|
18107
|
-
return { status: "done", iterations, finalText };
|
|
18108
|
-
}
|
|
18109
|
-
await this.executeTools(toolUses);
|
|
18110
|
-
if (autonomousContinue && consumeAutonomousContinue(this.ctx)) {
|
|
18111
18186
|
this.events.emit("iteration.completed", { ctx: this.ctx, index: i });
|
|
18112
18187
|
await this.compactContextIfNeeded();
|
|
18113
18188
|
await this.extensions.runAfterIteration(this.ctx, i);
|
|
18114
|
-
continue
|
|
18115
|
-
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
continue;
|
|
18121
|
-
}
|
|
18122
|
-
if (autonomousContinue && responseResult.directive === "stop") {
|
|
18123
|
-
return { status: "done", iterations, finalText };
|
|
18189
|
+
if (autonomousContinue && responseResult.directive === "continue") {
|
|
18190
|
+
continue;
|
|
18191
|
+
}
|
|
18192
|
+
if (autonomousContinue && responseResult.directive === "stop") {
|
|
18193
|
+
return { status: "done", iterations, finalText, delegateSummaries };
|
|
18194
|
+
}
|
|
18124
18195
|
}
|
|
18196
|
+
} finally {
|
|
18197
|
+
offSubagentDone();
|
|
18125
18198
|
}
|
|
18126
18199
|
}
|
|
18127
18200
|
/**
|
|
@@ -18130,7 +18203,7 @@ var Agent = class {
|
|
|
18130
18203
|
* the loop should exit. Returns `{ limit }` with no result when the
|
|
18131
18204
|
* iteration may proceed.
|
|
18132
18205
|
*/
|
|
18133
|
-
async checkIterationLimit(iterationIndex, limit, hasHardLimit, currentIterations) {
|
|
18206
|
+
async checkIterationLimit(iterationIndex, limit, hasHardLimit, currentIterations, delegateSummaries) {
|
|
18134
18207
|
if (hasHardLimit && iterationIndex >= limit) {
|
|
18135
18208
|
const extendBy = await requestLimitExtension({
|
|
18136
18209
|
events: this.events,
|
|
@@ -18143,7 +18216,7 @@ var Agent = class {
|
|
|
18143
18216
|
this.logger.info(`Iteration limit extended by ${extendBy} (new limit: ${newLimit})`);
|
|
18144
18217
|
return { limit: newLimit };
|
|
18145
18218
|
}
|
|
18146
|
-
return { limit, exit: { status: "max_iterations", iterations: currentIterations } };
|
|
18219
|
+
return { limit, exit: { status: "max_iterations", iterations: currentIterations, delegateSummaries } };
|
|
18147
18220
|
}
|
|
18148
18221
|
return { limit };
|
|
18149
18222
|
}
|
|
@@ -18550,11 +18623,9 @@ var Context = class {
|
|
|
18550
18623
|
return this._state;
|
|
18551
18624
|
}
|
|
18552
18625
|
/**
|
|
18553
|
-
* Register a teardown hook tied to the current run's abort signal.
|
|
18554
|
-
*
|
|
18555
|
-
*
|
|
18556
|
-
* and fired when the next run ends; there is no "immediate fire" when no
|
|
18557
|
-
* run is active.
|
|
18626
|
+
* Register a teardown hook tied to the current run's abort signal.
|
|
18627
|
+
* Hooks registered before a run starts are stored and fired when the
|
|
18628
|
+
* next run ends; there is no immediate fire when no run is active.
|
|
18558
18629
|
*
|
|
18559
18630
|
* **Scope:** these hooks fire on the **whole agent run's** abort, not on
|
|
18560
18631
|
* an individual tool call. For per-tool teardown of resources owned by
|
|
@@ -19133,7 +19204,7 @@ ${mem}`);
|
|
|
19133
19204
|
};
|
|
19134
19205
|
|
|
19135
19206
|
// src/registry/tool-registry.ts
|
|
19136
|
-
var ToolRegistry = class {
|
|
19207
|
+
var ToolRegistry = class _ToolRegistry {
|
|
19137
19208
|
tools = /* @__PURE__ */ new Map();
|
|
19138
19209
|
register(tool, owner = "core") {
|
|
19139
19210
|
if (this.tools.has(tool.name)) {
|
|
@@ -19255,6 +19326,15 @@ var ToolRegistry = class {
|
|
|
19255
19326
|
clear() {
|
|
19256
19327
|
this.tools.clear();
|
|
19257
19328
|
}
|
|
19329
|
+
/**
|
|
19330
|
+
* Return a new ToolRegistry with the same registered tools and owners.
|
|
19331
|
+
* Useful for creating filtered copies in multi-agent scenarios.
|
|
19332
|
+
*/
|
|
19333
|
+
clone() {
|
|
19334
|
+
const copy = new _ToolRegistry();
|
|
19335
|
+
for (const { tool, owner } of this.listWithOwner()) copy.register(tool, owner);
|
|
19336
|
+
return copy;
|
|
19337
|
+
}
|
|
19258
19338
|
};
|
|
19259
19339
|
|
|
19260
19340
|
// src/registry/provider-registry.ts
|
|
@@ -19714,7 +19794,12 @@ async function unloadPlugins(loadedPlugins, opts) {
|
|
|
19714
19794
|
for (const plugin of ordered) {
|
|
19715
19795
|
if (typeof plugin.teardown !== "function") continue;
|
|
19716
19796
|
try {
|
|
19717
|
-
const api = pluginApiMap.get(plugin)
|
|
19797
|
+
const api = pluginApiMap.get(plugin);
|
|
19798
|
+
if (!api) {
|
|
19799
|
+
throw new Error(
|
|
19800
|
+
`Plugin "${plugin.name}" API not found in pluginApiMap \u2014 was setup() called?`
|
|
19801
|
+
);
|
|
19802
|
+
}
|
|
19718
19803
|
await plugin.teardown(api);
|
|
19719
19804
|
pluginApiMap.delete(plugin);
|
|
19720
19805
|
opts.log.info(`Plugin "${plugin.name}" torn down`);
|