@wrongstack/core 0.6.6 → 0.7.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/{agent-bridge-BBXK_ppx.d.ts → agent-bridge-CrQpYjM7.d.ts} +1 -1
- package/dist/{compactor-C8NhpSt5.d.ts → compactor-CWV1u-IU.d.ts} +1 -1
- package/dist/{config-DfC6g6KV.d.ts → config-C34JRwl4.d.ts} +1 -1
- package/dist/{context-DN5v-uQX.d.ts → context-bmR0YgBm.d.ts} +74 -8
- package/dist/coordination/index.d.ts +11 -11
- package/dist/coordination/index.js +115 -39
- package/dist/coordination/index.js.map +1 -1
- package/dist/default-config-DvRSTELf.d.ts +20 -0
- package/dist/defaults/index.d.ts +20 -19
- package/dist/defaults/index.js +224 -64
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-CJqwQl8G.d.ts → events-CEKFTmIY.d.ts} +10 -1
- package/dist/execution/index.d.ts +27 -13
- package/dist/execution/index.js +153 -40
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/extension/index.js +3 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-DcnXDPdY.d.ts → index-BJIFLGII.d.ts} +20 -5
- package/dist/{index-CXnWsGBp.d.ts → index-CZR0HjxM.d.ts} +14 -110
- package/dist/index.d.ts +27 -26
- package/dist/index.js +396 -180
- 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 +8 -4
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-CevFHHM1.d.ts → mcp-servers-BRJicm5o.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/{multi-agent-D5IbASk_.d.ts → multi-agent-Cm1wYSrw.d.ts} +9 -4
- package/dist/{agent-subagent-runner-DsSm9lKN.d.ts → multi-agent-coordinator-CCupVFqv.d.ts} +117 -4
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-CBx_q1HA.d.ts → path-resolver-CfT7e_HT.d.ts} +2 -2
- package/dist/{plan-templates-BEOllUJV.d.ts → plan-templates-Q78an-GJ.d.ts} +4 -4
- package/dist/{provider-runner-Byh5TcJs.d.ts → provider-runner-WDj28o7J.d.ts} +3 -3
- package/dist/{retry-policy-BZSIMxrJ.d.ts → retry-policy-Dpxp4SET.d.ts} +1 -1
- package/dist/sdd/index.d.ts +3 -3
- package/dist/{secret-scrubber-CT7wefiO.d.ts → secret-scrubber-C2YCYtkn.d.ts} +1 -1
- package/dist/{secret-scrubber-I0QHY_ob.d.ts → secret-scrubber-CowtdEF8.d.ts} +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/{selector-DDb_mq9X.d.ts → selector-CP39HhCe.d.ts} +1 -1
- package/dist/{session-reader-B9nVkziM.d.ts → session-reader-Dwjn4WZR.d.ts} +1 -1
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +94 -11
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-gL06H9P4.d.ts → system-prompt-CfgXqyv2.d.ts} +1 -1
- package/dist/{tool-executor-BF7QfYVE.d.ts → tool-executor-D5NFi_LV.d.ts} +5 -5
- package/dist/types/index.d.ts +16 -15
- package/dist/types/index.js +102 -23
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-
|
|
1
|
+
import { B as BridgeTransport, l as BridgeMessage, A as AgentBridge, m as AgentBridgeConfig } from './multi-agent-Cm1wYSrw.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-memory pub/sub transport for agent-to-agent messaging.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { W as WireFamily } from './models-registry-Y2xbog0E.js';
|
|
2
|
-
import { P as Permission } from './context-
|
|
2
|
+
import { P as Permission } from './context-bmR0YgBm.js';
|
|
3
3
|
|
|
4
4
|
type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
|
|
5
5
|
type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
|
|
@@ -91,8 +91,62 @@ declare function asText(content: string | ContentBlock[]): string;
|
|
|
91
91
|
* This lets consumers (CLI, TUI, plugins, tests) branch on structured
|
|
92
92
|
* data instead of parsing error messages.
|
|
93
93
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Machine-readable error codes as frozen constants.
|
|
96
|
+
*
|
|
97
|
+
* Use `ERROR_CODES.X` instead of raw string literals for:
|
|
98
|
+
* - IDE autocomplete and compile-time validation
|
|
99
|
+
* - Safe refactoring (rename updates all usages)
|
|
100
|
+
* - Plugin extensibility (extend the object to add custom codes)
|
|
101
|
+
*
|
|
102
|
+
* The `ErrorCode` type is derived from this object, so adding a new
|
|
103
|
+
* code here automatically updates the type without extra changes.
|
|
104
|
+
*/
|
|
105
|
+
declare const ERROR_CODES: {
|
|
106
|
+
readonly PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED";
|
|
107
|
+
readonly PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED";
|
|
108
|
+
readonly PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED";
|
|
109
|
+
readonly PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST";
|
|
110
|
+
readonly PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR";
|
|
111
|
+
readonly PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR";
|
|
112
|
+
readonly PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW";
|
|
113
|
+
readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND";
|
|
114
|
+
readonly TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED";
|
|
115
|
+
readonly TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED";
|
|
116
|
+
readonly TOOL_TIMEOUT: "TOOL_TIMEOUT";
|
|
117
|
+
readonly TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID";
|
|
118
|
+
readonly CONFIG_INVALID: "CONFIG_INVALID";
|
|
119
|
+
readonly CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND";
|
|
120
|
+
readonly CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED";
|
|
121
|
+
readonly CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED";
|
|
122
|
+
readonly PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED";
|
|
123
|
+
readonly PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH";
|
|
124
|
+
readonly PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY";
|
|
125
|
+
readonly AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT";
|
|
126
|
+
readonly AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW";
|
|
127
|
+
readonly AGENT_ABORTED: "AGENT_ABORTED";
|
|
128
|
+
readonly AGENT_RUN_FAILED: "AGENT_RUN_FAILED";
|
|
129
|
+
readonly SESSION_NOT_FOUND: "SESSION_NOT_FOUND";
|
|
130
|
+
readonly SESSION_CORRUPTED: "SESSION_CORRUPTED";
|
|
131
|
+
readonly SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED";
|
|
132
|
+
readonly CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND";
|
|
133
|
+
readonly CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND";
|
|
134
|
+
readonly REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE";
|
|
135
|
+
readonly REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND";
|
|
136
|
+
readonly FS_READ_FAILED: "FS_READ_FAILED";
|
|
137
|
+
readonly FS_WRITE_FAILED: "FS_WRITE_FAILED";
|
|
138
|
+
readonly FS_MKDIR_FAILED: "FS_MKDIR_FAILED";
|
|
139
|
+
readonly FS_DELETE_FAILED: "FS_DELETE_FAILED";
|
|
140
|
+
readonly FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED";
|
|
141
|
+
readonly UNKNOWN: "UNKNOWN";
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`
|
|
145
|
+
* instead of a string literal union means TypeScript auto-updates the type whenever
|
|
146
|
+
* a new code is added to `ERROR_CODES` — no need to keep two lists in sync.
|
|
147
|
+
*/
|
|
148
|
+
type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
149
|
+
type ErrorSubsystem = 'provider' | 'tool' | 'config' | 'plugin' | 'agent' | 'session' | 'container' | 'fs' | 'general';
|
|
96
150
|
type ErrorSeverity = 'fatal' | 'error' | 'warning';
|
|
97
151
|
declare class WrongStackError extends Error {
|
|
98
152
|
readonly code: ErrorCode;
|
|
@@ -186,12 +240,26 @@ declare class SessionError extends WrongStackError {
|
|
|
186
240
|
cause?: unknown;
|
|
187
241
|
});
|
|
188
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* File system operation errors.
|
|
245
|
+
*/
|
|
246
|
+
declare class FsError extends WrongStackError {
|
|
247
|
+
readonly path?: string;
|
|
248
|
+
constructor(opts: {
|
|
249
|
+
message: string;
|
|
250
|
+
code: Extract<ErrorCode, 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'>;
|
|
251
|
+
path?: string;
|
|
252
|
+
context?: Record<string, unknown>;
|
|
253
|
+
cause?: unknown;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
189
256
|
declare function isWrongStackError(err: unknown): err is WrongStackError;
|
|
190
257
|
declare function isToolError(err: unknown): err is ToolError;
|
|
191
258
|
declare function isConfigError(err: unknown): err is ConfigError;
|
|
192
259
|
declare function isPluginError(err: unknown): err is PluginError;
|
|
193
260
|
declare function isSessionError(err: unknown): err is SessionError;
|
|
194
261
|
declare function isAgentError(err: unknown): err is AgentError;
|
|
262
|
+
declare function isFsError(err: unknown): err is FsError;
|
|
195
263
|
|
|
196
264
|
type Permission = 'auto' | 'confirm' | 'deny';
|
|
197
265
|
/**
|
|
@@ -952,11 +1020,9 @@ declare class Context implements RunEnv {
|
|
|
952
1020
|
private _state;
|
|
953
1021
|
get state(): ConversationState;
|
|
954
1022
|
/**
|
|
955
|
-
* Register a teardown hook tied to the current run's abort signal.
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
* and fired when the next run ends; there is no "immediate fire" when no
|
|
959
|
-
* run is active.
|
|
1023
|
+
* Register a teardown hook tied to the current run's abort signal.
|
|
1024
|
+
* Hooks registered before a run starts are stored and fired when the
|
|
1025
|
+
* next run ends; there is no immediate fire when no run is active.
|
|
960
1026
|
*
|
|
961
1027
|
* **Scope:** these hooks fire on the **whole agent run's** abort, not on
|
|
962
1028
|
* an individual tool call. For per-tool teardown of resources owned by
|
|
@@ -972,4 +1038,4 @@ declare class Context implements RunEnv {
|
|
|
972
1038
|
usage(): Usage;
|
|
973
1039
|
}
|
|
974
1040
|
|
|
975
|
-
export {
|
|
1041
|
+
export { isThinkingBlock as $, AgentError as A, type ToolFinalEvent as B, type Capabilities as C, type ToolProgressEvent as D, ERROR_CODES as E, type FileSnapshot as F, type ToolResultBlock as G, type ToolStreamEvent as H, type ImageBlock as I, type JSONSchema as J, type ToolUseBlock as K, asBlocks as L, type Message as M, asText as N, isAgentError as O, type Permission as P, isConfigError as Q, type Request as R, type SessionData as S, type TextBlock as T, type Usage as U, isFsError as V, WrongStackError as W, isImageBlock as X, isPluginError as Y, isSessionError as Z, isTextBlock as _, ConfigError as a, isToolError as a0, isToolResultBlock as a1, isToolUseBlock as a2, isWrongStackError as a3, toWrongStackError as a4, Context as a5, type TokenCounter as a6, type CacheStats as a7, type TodoItem as a8, ConversationState as a9, type ContextInit as aa, type ReadonlyConversationState as ab, type RunEnv as ac, type RunOptions as ad, type StateChange as ae, type StateChangeHandler as af, extractRunEnv as ag, wrapAsState as ah, type ContentBlock as b, type ErrorCode as c, type ErrorSeverity as d, type ErrorSubsystem as e, FsError as f, type MessageRole as g, PluginError as h, type Provider as i, ProviderError as j, type ProviderErrorBody as k, type Response as l, type ResumedSession as m, type RiskTier as n, SessionError as o, type SessionEvent as p, type SessionMetadata as q, type SessionStore as r, type SessionSummary as s, type SessionWriter as t, type StopReason as u, type StreamEvent as v, type ThinkingBlock as w, type Tool as x, type ToolCallContext as y, ToolError as z };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-
|
|
1
|
+
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, b as DEFAULT_SUBAGENT_BASELINE, c as DelegateHost, d as Director, e as DirectorPromptParts, f as DirectorSessionFactory, g as DirectorSessionFactoryOptions, F as FLEET_ROSTER, t as FleetCostCapError, i as FleetManager, j as FleetManagerOptions, k as FleetSpawnBudgetError, I as ICoordinator, l as IFleetManager, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, m as SubagentPromptParts, o as composeDirectorPrompt, p as composeSubagentPrompt, q as createDelegateTool, r as makeDirectorSessionFactory, s as rosterSummaryFromConfigs } from '../index-CZR0HjxM.js';
|
|
2
|
+
export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, D as DefaultMultiAgentCoordinator, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, M as MultiAgentCoordinatorOptions, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../multi-agent-coordinator-CCupVFqv.js';
|
|
3
|
+
export { n as BudgetExceededError, o as BudgetKind, p as BudgetLimits, s as BudgetThresholdDecision, t as BudgetThresholdHandler, u as BudgetThresholdSignal, q as BudgetUsage, r as SubagentBudget } from '../multi-agent-Cm1wYSrw.js';
|
|
4
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-CrQpYjM7.js';
|
|
5
5
|
import '../director-state-BmYi3DGA.js';
|
|
6
|
-
import '../context-
|
|
7
|
-
import '
|
|
8
|
-
import '../events-CJqwQl8G.js';
|
|
9
|
-
import '../index-DcnXDPdY.js';
|
|
6
|
+
import '../context-bmR0YgBm.js';
|
|
7
|
+
import '../index-BJIFLGII.js';
|
|
10
8
|
import '../logger-BMQgxvdy.js';
|
|
11
|
-
import '../system-prompt-
|
|
9
|
+
import '../system-prompt-CfgXqyv2.js';
|
|
12
10
|
import '../observability-BhnVLBLS.js';
|
|
13
|
-
import '../
|
|
14
|
-
import '../
|
|
11
|
+
import '../events-CEKFTmIY.js';
|
|
12
|
+
import '../secret-scrubber-C2YCYtkn.js';
|
|
13
|
+
import '../config-C34JRwl4.js';
|
|
15
14
|
import '../models-registry-Y2xbog0E.js';
|
|
15
|
+
import 'node:events';
|
|
@@ -197,7 +197,7 @@ var DirectorStateCheckpoint = class {
|
|
|
197
197
|
this.timer = null;
|
|
198
198
|
}
|
|
199
199
|
await this.persist();
|
|
200
|
-
|
|
200
|
+
while (this.rewriteRequested) {
|
|
201
201
|
this.rewriteRequested = false;
|
|
202
202
|
await this.persist();
|
|
203
203
|
}
|
|
@@ -338,10 +338,8 @@ var InMemoryAgentBridge = class {
|
|
|
338
338
|
this.pendingRequests.delete(correlationId);
|
|
339
339
|
reject(new Error(`Request ${correlationId} timed out after ${timeout}ms`));
|
|
340
340
|
}, timeout);
|
|
341
|
-
if (this.
|
|
341
|
+
if (!this.inflightGuards.has(correlationId)) {
|
|
342
342
|
clearTimeout(timer);
|
|
343
|
-
this.inflightGuards.delete(correlationId);
|
|
344
|
-
this.pendingRequests.delete(correlationId);
|
|
345
343
|
reject(new Error("Bridge stopped"));
|
|
346
344
|
return;
|
|
347
345
|
}
|
|
@@ -635,6 +633,14 @@ var FleetUsageAggregator = class {
|
|
|
635
633
|
};
|
|
636
634
|
|
|
637
635
|
// src/types/errors.ts
|
|
636
|
+
var ERROR_CODES = {
|
|
637
|
+
// Provider
|
|
638
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
639
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
640
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
641
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
642
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
643
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR"};
|
|
638
644
|
var WrongStackError = class extends Error {
|
|
639
645
|
code;
|
|
640
646
|
subsystem;
|
|
@@ -726,14 +732,14 @@ function truncate(s, n) {
|
|
|
726
732
|
return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
|
|
727
733
|
}
|
|
728
734
|
function providerStatusToCode(status, type) {
|
|
729
|
-
if (status === 0) return
|
|
730
|
-
if (type === "rate_limit_error" || status === 429) return
|
|
731
|
-
if (type === "authentication_error" || status === 401) return
|
|
732
|
-
if (type === "overloaded_error" || status === 529) return
|
|
733
|
-
if (type === "invalid_request_error" || status === 400) return
|
|
734
|
-
if (status === 408) return
|
|
735
|
-
if (status >= 500) return
|
|
736
|
-
return
|
|
735
|
+
if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
|
|
736
|
+
if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
|
|
737
|
+
if (type === "authentication_error" || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;
|
|
738
|
+
if (type === "overloaded_error" || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;
|
|
739
|
+
if (type === "invalid_request_error" || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;
|
|
740
|
+
if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
|
|
741
|
+
if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;
|
|
742
|
+
return ERROR_CODES.PROVIDER_INVALID_REQUEST;
|
|
737
743
|
}
|
|
738
744
|
|
|
739
745
|
// src/coordination/subagent-budget.ts
|
|
@@ -789,10 +795,10 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
789
795
|
* or hung listener (Director not built / event filter detached mid-run)
|
|
790
796
|
* leaves the budget over-limit and never enforces anything, since
|
|
791
797
|
* `checkLimit` returns synchronously via `void this.checkLimitAsync`.
|
|
792
|
-
*
|
|
793
|
-
*
|
|
798
|
+
* Raised from 30s to 60s to give subagents more headroom before
|
|
799
|
+
* the threshold negotiation times out and triggers a hard stop.
|
|
794
800
|
*/
|
|
795
|
-
static DECISION_TIMEOUT_MS =
|
|
801
|
+
static DECISION_TIMEOUT_MS = 6e4;
|
|
796
802
|
/**
|
|
797
803
|
* Injected by the runner when wiring the budget to its EventBus.
|
|
798
804
|
* Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
|
|
@@ -1155,13 +1161,19 @@ var FLEET_ROSTER = {
|
|
|
1155
1161
|
"security-scanner": SECURITY_SCANNER_AGENT
|
|
1156
1162
|
};
|
|
1157
1163
|
var FLEET_ROSTER_BUDGETS = {
|
|
1158
|
-
"audit-log": { timeoutMs:
|
|
1159
|
-
"bug-hunter": { timeoutMs:
|
|
1160
|
-
"refactor-planner": { timeoutMs:
|
|
1161
|
-
"security-scanner": { timeoutMs:
|
|
1164
|
+
"audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
|
|
1165
|
+
"bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
|
|
1166
|
+
"refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
|
|
1167
|
+
"security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 }
|
|
1168
|
+
};
|
|
1169
|
+
var GENERIC_SUBAGENT_BUDGET = {
|
|
1170
|
+
timeoutMs: 3 * 60 * 60 * 1e3,
|
|
1171
|
+
maxIterations: 5e3,
|
|
1172
|
+
maxToolCalls: 15e3
|
|
1162
1173
|
};
|
|
1163
1174
|
function applyRosterBudget(cfg) {
|
|
1164
|
-
const
|
|
1175
|
+
const roleBudget = cfg.role ? FLEET_ROSTER_BUDGETS[cfg.role] : void 0;
|
|
1176
|
+
const defaultBudget = roleBudget ?? (cfg.name ? GENERIC_SUBAGENT_BUDGET : void 0);
|
|
1165
1177
|
if (!defaultBudget) return cfg;
|
|
1166
1178
|
return {
|
|
1167
1179
|
...cfg,
|
|
@@ -1233,7 +1245,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1233
1245
|
// hasParentBridge() — the type now reflects this.
|
|
1234
1246
|
parentBridge: null,
|
|
1235
1247
|
doneCondition: this.config.doneCondition,
|
|
1236
|
-
maxConcurrent: this.config.maxConcurrent ??
|
|
1248
|
+
maxConcurrent: this.config.maxConcurrent ?? 16
|
|
1237
1249
|
};
|
|
1238
1250
|
this.subagents.set(id, {
|
|
1239
1251
|
config: { ...subagent, id },
|
|
@@ -1279,6 +1291,30 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1279
1291
|
this.drainPendingAsAborted("Coordinator stopAll() drained the pending queue");
|
|
1280
1292
|
await Promise.allSettled([...this.subagents.keys()].map((id) => this.stop(id)));
|
|
1281
1293
|
}
|
|
1294
|
+
async remove(subagentId) {
|
|
1295
|
+
await this.stop(subagentId);
|
|
1296
|
+
this.subagents.delete(subagentId);
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Get current coordinator stats for monitoring/debugging.
|
|
1300
|
+
*/
|
|
1301
|
+
getStats() {
|
|
1302
|
+
let running = 0, idle = 0, stopped = 0;
|
|
1303
|
+
for (const [, entry] of this.subagents) {
|
|
1304
|
+
if (entry.status === "running") running++;
|
|
1305
|
+
else if (entry.status === "idle") idle++;
|
|
1306
|
+
else stopped++;
|
|
1307
|
+
}
|
|
1308
|
+
return {
|
|
1309
|
+
total: this.subagents.size,
|
|
1310
|
+
running,
|
|
1311
|
+
idle,
|
|
1312
|
+
stopped,
|
|
1313
|
+
inFlight: this.inFlight,
|
|
1314
|
+
pending: this.pendingTasks.length,
|
|
1315
|
+
completed: this.completedResults.length
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1282
1318
|
getStatus() {
|
|
1283
1319
|
return {
|
|
1284
1320
|
coordinatorId: this.coordinatorId,
|
|
@@ -1360,7 +1396,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1360
1396
|
}
|
|
1361
1397
|
}
|
|
1362
1398
|
canDispatch() {
|
|
1363
|
-
const max = this.config.maxConcurrent ??
|
|
1399
|
+
const max = this.config.maxConcurrent ?? 16;
|
|
1364
1400
|
return this.inFlight < max && this.pendingTasks.length > 0;
|
|
1365
1401
|
}
|
|
1366
1402
|
takeNextDispatchableTask() {
|
|
@@ -1454,13 +1490,18 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1454
1490
|
task.subagentId = subagentId;
|
|
1455
1491
|
subagent.context.tasks.push(task);
|
|
1456
1492
|
this.emit("task.assigned", { task, subagentId });
|
|
1493
|
+
const rawMaxIterations = subagent.config.maxIterations;
|
|
1494
|
+
const rawMaxToolCalls = subagent.config.maxToolCalls;
|
|
1495
|
+
const rawMaxTokens = subagent.config.maxTokens;
|
|
1496
|
+
const rawMaxCostUsd = subagent.config.maxCostUsd;
|
|
1497
|
+
const rawTimeoutMs = subagent.config.timeoutMs;
|
|
1457
1498
|
const configWithRosterDefaults = applyRosterBudget(subagent.config);
|
|
1458
1499
|
const budget = new SubagentBudget({
|
|
1459
|
-
maxIterations:
|
|
1460
|
-
maxToolCalls:
|
|
1461
|
-
maxTokens:
|
|
1462
|
-
maxCostUsd:
|
|
1463
|
-
timeoutMs:
|
|
1500
|
+
maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
|
|
1501
|
+
maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
|
|
1502
|
+
maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
|
|
1503
|
+
maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
|
|
1504
|
+
timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs
|
|
1464
1505
|
});
|
|
1465
1506
|
subagent.activeBudget = budget;
|
|
1466
1507
|
if (!this.runner) {
|
|
@@ -1531,7 +1572,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1531
1572
|
kind: "timeout",
|
|
1532
1573
|
used: elapsed,
|
|
1533
1574
|
limit,
|
|
1534
|
-
timeoutMs:
|
|
1575
|
+
timeoutMs: 6e4,
|
|
1535
1576
|
extend: (extra) => resolveDecision({ extend: extra }),
|
|
1536
1577
|
deny: () => resolveDecision("stop")
|
|
1537
1578
|
});
|
|
@@ -2249,7 +2290,12 @@ var Director = class {
|
|
|
2249
2290
|
}
|
|
2250
2291
|
}
|
|
2251
2292
|
}
|
|
2252
|
-
|
|
2293
|
+
let result;
|
|
2294
|
+
try {
|
|
2295
|
+
result = await this.coordinator.spawn(config);
|
|
2296
|
+
} catch (err) {
|
|
2297
|
+
throw err;
|
|
2298
|
+
}
|
|
2253
2299
|
if (this.fleetManager) {
|
|
2254
2300
|
this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
|
|
2255
2301
|
} else {
|
|
@@ -2517,6 +2563,9 @@ var Director = class {
|
|
|
2517
2563
|
async terminateAll() {
|
|
2518
2564
|
await this.coordinator.stopAll();
|
|
2519
2565
|
}
|
|
2566
|
+
async remove(subagentId) {
|
|
2567
|
+
await this.coordinator.remove(subagentId);
|
|
2568
|
+
}
|
|
2520
2569
|
status() {
|
|
2521
2570
|
return this.coordinator.getStatus();
|
|
2522
2571
|
}
|
|
@@ -2697,7 +2746,7 @@ var Director = class {
|
|
|
2697
2746
|
}
|
|
2698
2747
|
};
|
|
2699
2748
|
function createDelegateTool(opts) {
|
|
2700
|
-
const defaultTimeoutMs = opts.defaultTimeoutMs ??
|
|
2749
|
+
const defaultTimeoutMs = opts.defaultTimeoutMs ?? 30 * 60 * 1e3;
|
|
2701
2750
|
const rosterIds = opts.roster ? Object.keys(opts.roster) : [];
|
|
2702
2751
|
const inputSchema = {
|
|
2703
2752
|
type: "object",
|
|
@@ -2713,7 +2762,7 @@ function createDelegateTool(opts) {
|
|
|
2713
2762
|
},
|
|
2714
2763
|
name: {
|
|
2715
2764
|
type: "string",
|
|
2716
|
-
description: "Display name for
|
|
2765
|
+
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."
|
|
2717
2766
|
},
|
|
2718
2767
|
provider: {
|
|
2719
2768
|
type: "string",
|
|
@@ -2744,8 +2793,8 @@ function createDelegateTool(opts) {
|
|
|
2744
2793
|
};
|
|
2745
2794
|
return {
|
|
2746
2795
|
name: "delegate",
|
|
2747
|
-
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.",
|
|
2748
|
-
usageHint: "Set `task` to a complete instruction. Either pick `role` from the roster or pass `name`
|
|
2796
|
+
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.",
|
|
2797
|
+
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.",
|
|
2749
2798
|
permission: "auto",
|
|
2750
2799
|
mutating: false,
|
|
2751
2800
|
inputSchema,
|
|
@@ -2793,6 +2842,7 @@ function createDelegateTool(opts) {
|
|
|
2793
2842
|
model: i.model,
|
|
2794
2843
|
systemPromptOverride: i.systemPromptOverride
|
|
2795
2844
|
};
|
|
2845
|
+
cfg = applyRosterBudget({ ...cfg, name: i.name });
|
|
2796
2846
|
}
|
|
2797
2847
|
if (typeof i.maxIterations === "number" && i.maxIterations > 0) {
|
|
2798
2848
|
cfg.maxIterations = i.maxIterations;
|
|
@@ -2800,7 +2850,7 @@ function createDelegateTool(opts) {
|
|
|
2800
2850
|
if (typeof i.maxToolCalls === "number" && i.maxToolCalls > 0) {
|
|
2801
2851
|
cfg.maxToolCalls = i.maxToolCalls;
|
|
2802
2852
|
}
|
|
2803
|
-
const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ??
|
|
2853
|
+
const SUBAGENT_TIMEOUT_BUFFER_MS = opts.subagentTimeoutBufferMs ?? 6e4;
|
|
2804
2854
|
const desiredSubTimeout = Math.max(3e4, timeoutMs - SUBAGENT_TIMEOUT_BUFFER_MS);
|
|
2805
2855
|
if (!cfg.timeoutMs || cfg.timeoutMs > desiredSubTimeout) {
|
|
2806
2856
|
cfg.timeoutMs = desiredSubTimeout;
|
|
@@ -2837,6 +2887,7 @@ function createDelegateTool(opts) {
|
|
|
2837
2887
|
const errorKind = result.error?.kind;
|
|
2838
2888
|
const retryable = result.error?.retryable;
|
|
2839
2889
|
const backoffMs = result.error?.backoffMs;
|
|
2890
|
+
const summary = buildDelegateSummary(i.role, result);
|
|
2840
2891
|
return {
|
|
2841
2892
|
ok: result.status === "success",
|
|
2842
2893
|
status: result.status,
|
|
@@ -2852,7 +2903,10 @@ function createDelegateTool(opts) {
|
|
|
2852
2903
|
toolCalls: result.toolCalls,
|
|
2853
2904
|
durationMs: result.durationMs,
|
|
2854
2905
|
...partial ? { partial } : {},
|
|
2855
|
-
...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {}
|
|
2906
|
+
...hintForKind(errorKind, retryable, backoffMs, partial) ? { hint: hintForKind(errorKind, retryable, backoffMs, partial) } : {},
|
|
2907
|
+
// Summary is included so callers (TUI, CLI renderer) can surface
|
|
2908
|
+
// it as a chat history line — the LLM also sees it for continuity.
|
|
2909
|
+
summary
|
|
2856
2910
|
};
|
|
2857
2911
|
} catch (err) {
|
|
2858
2912
|
return {
|
|
@@ -2865,10 +2919,11 @@ function createDelegateTool(opts) {
|
|
|
2865
2919
|
};
|
|
2866
2920
|
}
|
|
2867
2921
|
function instantiateRosterConfig2(role, base) {
|
|
2922
|
+
const withBudget = applyRosterBudget({ ...base, role });
|
|
2868
2923
|
return {
|
|
2869
|
-
...
|
|
2870
|
-
//
|
|
2871
|
-
//
|
|
2924
|
+
...withBudget,
|
|
2925
|
+
// Give each spawn a fresh id so parallel or repeated delegates
|
|
2926
|
+
// can use the same role safely.
|
|
2872
2927
|
id: `${role}-${randomUUID().slice(0, 8)}`
|
|
2873
2928
|
};
|
|
2874
2929
|
}
|
|
@@ -2928,6 +2983,18 @@ ${partial.lastAssistantText}`;
|
|
|
2928
2983
|
return retryable ? "Failure classified as retryable. Try again with the same input." : void 0;
|
|
2929
2984
|
}
|
|
2930
2985
|
}
|
|
2986
|
+
function buildDelegateSummary(role, result) {
|
|
2987
|
+
const roleLabel = role ?? "subagent";
|
|
2988
|
+
const ms = result.durationMs;
|
|
2989
|
+
const duration = ms < 6e4 ? `${Math.round(ms / 1e3)}s` : ms < 36e5 ? `${Math.round(ms / 6e4)}m` : `${(ms / 36e5).toFixed(1)}h`;
|
|
2990
|
+
if (result.status === "success") {
|
|
2991
|
+
const preview = typeof result.result === "string" ? result.result.trim().slice(0, 120).replace(/\n+/g, " ") : null;
|
|
2992
|
+
const tail = preview ? ` \u2014 ${preview}` : "";
|
|
2993
|
+
return `[${roleLabel}] done in ${duration} (${result.iterations} iter, ${result.toolCalls} tools)${tail}`;
|
|
2994
|
+
}
|
|
2995
|
+
const errLabel = result.error?.kind ?? result.status;
|
|
2996
|
+
return `[${roleLabel}] ${result.status} after ${duration} (${result.iterations} iter, ${result.toolCalls} tools) \u2014 ${errLabel}`;
|
|
2997
|
+
}
|
|
2931
2998
|
async function readSubagentPartial(opts, subagentId) {
|
|
2932
2999
|
if (!opts.sessionsRoot) return void 0;
|
|
2933
3000
|
const candidates = [];
|
|
@@ -2968,6 +3035,7 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
2968
3035
|
}
|
|
2969
3036
|
}
|
|
2970
3037
|
} catch {
|
|
3038
|
+
continue;
|
|
2971
3039
|
}
|
|
2972
3040
|
}
|
|
2973
3041
|
return {
|
|
@@ -3273,8 +3341,16 @@ var DefaultSessionStore = class {
|
|
|
3273
3341
|
}
|
|
3274
3342
|
}
|
|
3275
3343
|
async resume(id) {
|
|
3276
|
-
const data = await this.load(id);
|
|
3277
3344
|
const file = path4.join(this.dir, `${id}.jsonl`);
|
|
3345
|
+
try {
|
|
3346
|
+
await fsp4.access(file, fsp4.constants.R_OK);
|
|
3347
|
+
} catch {
|
|
3348
|
+
throw new Error(
|
|
3349
|
+
`Session "${id}" not found \u2014 the session file does not exist or was deleted.`,
|
|
3350
|
+
{ cause: new Error("ENOENT") }
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3353
|
+
const data = await this.load(id);
|
|
3278
3354
|
let handle;
|
|
3279
3355
|
try {
|
|
3280
3356
|
handle = await fsp4.open(file, "a", 384);
|