@wrongstack/core 0.5.6 → 0.6.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-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 +9 -9
- package/dist/coordination/index.js +339 -80
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +20 -19
- package/dist/defaults/index.js +731 -180
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-qnDZbrtb.d.ts → events-DPQKFX7W.d.ts} +1 -1
- package/dist/execution/index.d.ts +152 -12
- package/dist/execution/index.js +474 -5
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/extension/index.js +2 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/goal-store-BQ3YX1h1.d.ts +75 -0
- package/dist/{index-DPLJw_ZI.d.ts → index-B0qTujQW.d.ts} +52 -5
- package/dist/{index-BDnUCRvL.d.ts → index-DkdRz6yK.d.ts} +351 -15
- package/dist/index.d.ts +109 -28
- package/dist/index.js +1143 -234
- 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/models/index.js +2 -3
- package/dist/models/index.js.map +1 -1
- 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/{plan-templates-DaxTCPfk.d.ts → plan-templates-CKJs_sYh.d.ts} +9 -8
- 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 +6 -4
- package/dist/sdd/index.js +102 -68
- package/dist/sdd/index.js.map +1 -1
- 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/security/index.js +82 -82
- package/dist/security/index.js.map +1 -1
- 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/skills/index.js +102 -38
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +6 -5
- package/dist/storage/index.js +131 -22
- 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-B03CRwu-.d.ts} +4 -4
- package/dist/types/index.d.ts +15 -15
- package/dist/types/index.js +100 -102
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +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-Cpp7FXUl.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-CDRyrkKQ.js';
|
|
3
3
|
|
|
4
4
|
type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
|
|
5
5
|
type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
|
|
@@ -887,6 +887,13 @@ interface RunOptions {
|
|
|
887
887
|
model?: string;
|
|
888
888
|
executionStrategy?: 'parallel' | 'sequential' | 'smart';
|
|
889
889
|
maxIterations?: number;
|
|
890
|
+
/**
|
|
891
|
+
* Enable autonomous continue for this specific run. When true, the agent
|
|
892
|
+
* loop re-runs on `[continue]`/`[next step]`/`[proceed]` markers or
|
|
893
|
+
* `continue_to_next_iteration()` tool calls instead of returning.
|
|
894
|
+
* Overrides `AgentInit.autonomousContinue` for this call only.
|
|
895
|
+
*/
|
|
896
|
+
autonomousContinue?: boolean;
|
|
890
897
|
}
|
|
891
898
|
interface ContextInit {
|
|
892
899
|
systemPrompt: TextBlock[];
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT, b as AgentFactory, c as AgentFactoryResult, d as AgentRunnerOptions, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, e as DEFAULT_SUBAGENT_BASELINE, f as DefaultMultiAgentCoordinator, g as DelegateHost, h as Director, i as
|
|
2
|
-
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-
|
|
3
|
-
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 AgentFactory, c as AgentFactoryResult, d as AgentRunnerOptions, B as BUG_HUNTER_AGENT, C as CreateDelegateToolOptions, D as DEFAULT_DIRECTOR_PREAMBLE, e as DEFAULT_SUBAGENT_BASELINE, f as DefaultMultiAgentCoordinator, g as DelegateHost, h as Director, i as DirectorPromptParts, j as DirectorSessionFactory, k as DirectorSessionFactoryOptions, F as FLEET_ROSTER, m as FleetBus, K as FleetCostCapError, n as FleetEvent, o as FleetHandler, p as FleetManager, q as FleetManagerOptions, r as FleetSpawnBudgetError, s as FleetUsage, t as FleetUsageAggregator, I as ICoordinator, u as IFleetManager, M as MultiAgentCoordinatorOptions, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, v as SubagentPromptParts, w as SubagentUsageSnapshot, y as composeDirectorPrompt, z as composeSubagentPrompt, E as createDelegateTool, G as makeAgentSubagentRunner, H as makeDirectorSessionFactory, J as rosterSummaryFromConfigs } from '../index-DkdRz6yK.js';
|
|
2
|
+
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-Cpp7FXUl.js';
|
|
3
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BKNiE1VH.js';
|
|
4
4
|
import '../director-state-BmYi3DGA.js';
|
|
5
|
-
import '../context-
|
|
6
|
-
import '../events-
|
|
5
|
+
import '../context-CDRyrkKQ.js';
|
|
6
|
+
import '../events-DPQKFX7W.js';
|
|
7
7
|
import 'node:events';
|
|
8
|
-
import '../index-
|
|
8
|
+
import '../index-B0qTujQW.js';
|
|
9
9
|
import '../logger-BMQgxvdy.js';
|
|
10
|
-
import '../system-prompt-
|
|
10
|
+
import '../system-prompt-Dl2QY1_B.js';
|
|
11
11
|
import '../observability-BhnVLBLS.js';
|
|
12
|
-
import '../secret-scrubber-
|
|
13
|
-
import '../config-
|
|
12
|
+
import '../secret-scrubber-CfMdAJ_l.js';
|
|
13
|
+
import '../config-BGGuP_Ar.js';
|
|
14
14
|
import '../models-registry-Y2xbog0E.js';
|
|
@@ -73,8 +73,6 @@ async function renameWithRetry(from, to) {
|
|
|
73
73
|
}
|
|
74
74
|
throw lastErr;
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
// src/storage/director-state.ts
|
|
78
76
|
async function acquireDirectorStateLock(lockPath, processId = process.pid) {
|
|
79
77
|
let existing;
|
|
80
78
|
try {
|
|
@@ -1631,10 +1629,10 @@ function makeSpawnTool(director, roster) {
|
|
|
1631
1629
|
const subagentId = await director.spawn(cfg);
|
|
1632
1630
|
return { subagentId, provider: cfg.provider, model: cfg.model, name: cfg.name };
|
|
1633
1631
|
} catch (err) {
|
|
1634
|
-
if (err instanceof
|
|
1632
|
+
if (err instanceof FleetSpawnBudgetError) {
|
|
1635
1633
|
return { error: err.message, kind: err.kind, limit: err.limit, observed: err.observed };
|
|
1636
1634
|
}
|
|
1637
|
-
if (err instanceof
|
|
1635
|
+
if (err instanceof FleetCostCapError) {
|
|
1638
1636
|
return { error: err.message, kind: err.kind, limit: err.limit, observed: err.observed };
|
|
1639
1637
|
}
|
|
1640
1638
|
return { error: err instanceof Error ? err.message : String(err) };
|
|
@@ -1835,7 +1833,7 @@ function makeFleetHealthTool(director) {
|
|
|
1835
1833
|
}
|
|
1836
1834
|
|
|
1837
1835
|
// src/coordination/director.ts
|
|
1838
|
-
var
|
|
1836
|
+
var FleetSpawnBudgetError = class extends Error {
|
|
1839
1837
|
kind;
|
|
1840
1838
|
limit;
|
|
1841
1839
|
observed;
|
|
@@ -1843,13 +1841,13 @@ var DirectorBudgetError = class extends Error {
|
|
|
1843
1841
|
super(
|
|
1844
1842
|
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}`
|
|
1845
1843
|
);
|
|
1846
|
-
this.name = "
|
|
1844
|
+
this.name = "FleetSpawnBudgetError";
|
|
1847
1845
|
this.kind = kind;
|
|
1848
1846
|
this.limit = limit;
|
|
1849
1847
|
this.observed = observed;
|
|
1850
1848
|
}
|
|
1851
1849
|
};
|
|
1852
|
-
var
|
|
1850
|
+
var FleetCostCapError = class extends Error {
|
|
1853
1851
|
kind;
|
|
1854
1852
|
limit;
|
|
1855
1853
|
observed;
|
|
@@ -1857,16 +1855,34 @@ var DirectorCostCapError = class extends Error {
|
|
|
1857
1855
|
super(
|
|
1858
1856
|
`Director cost cap exceeded: total fleet spend ${observed.toFixed(4)} exceeds maxCostUsd ${limit.toFixed(4)}`
|
|
1859
1857
|
);
|
|
1860
|
-
this.name = "
|
|
1858
|
+
this.name = "FleetCostCapError";
|
|
1861
1859
|
this.kind = "max_cost_usd";
|
|
1862
1860
|
this.limit = limit;
|
|
1863
1861
|
this.observed = observed;
|
|
1864
1862
|
}
|
|
1865
1863
|
};
|
|
1866
1864
|
var Director = class {
|
|
1865
|
+
/** Alias for the ICoordinator contract. `id` is retained for backward compatibility. */
|
|
1866
|
+
get coordinatorId() {
|
|
1867
|
+
return this.id;
|
|
1868
|
+
}
|
|
1867
1869
|
id;
|
|
1870
|
+
/**
|
|
1871
|
+
* The fleet event bus. Backed by `fleetManager?.fleet` when a FleetManager
|
|
1872
|
+
* is injected; otherwise own FleetBus instance (preserves existing behavior).
|
|
1873
|
+
*/
|
|
1868
1874
|
fleet;
|
|
1875
|
+
/**
|
|
1876
|
+
* Usage rollup. Backed by `fleetManager?.usage` when a FleetManager is
|
|
1877
|
+
* injected; otherwise own FleetUsageAggregator.
|
|
1878
|
+
*/
|
|
1869
1879
|
usage;
|
|
1880
|
+
/**
|
|
1881
|
+
* Optional fleet-level policy container. When provided the Director
|
|
1882
|
+
* delegates spawn budgeting, manifest entries, and checkpointing to it
|
|
1883
|
+
* instead of managing those internally. All other behavior is unchanged.
|
|
1884
|
+
*/
|
|
1885
|
+
fleetManager;
|
|
1870
1886
|
/**
|
|
1871
1887
|
* Director-side bridge endpoint. Subagents are wired to the same
|
|
1872
1888
|
* in-memory transport so the director can `ask()` them synchronously
|
|
@@ -1917,8 +1933,8 @@ var Director = class {
|
|
|
1917
1933
|
/** Debounce timer for periodic manifest writes. */
|
|
1918
1934
|
manifestTimer = null;
|
|
1919
1935
|
manifestDebounceMs;
|
|
1920
|
-
/** Fleet-wide cost cap. Infinity means no cap. */
|
|
1921
|
-
|
|
1936
|
+
/** Fleet-wide cost cap (entire fleet total, distinct from SubagentBudget limits). Infinity means no cap. */
|
|
1937
|
+
maxFleetCostUsd;
|
|
1922
1938
|
/** Max auto-extensions per subagent per budget kind before denying. */
|
|
1923
1939
|
maxBudgetExtensions;
|
|
1924
1940
|
/** Sessions root for direct subagent JSONL reads (fleet_session tool). */
|
|
@@ -1951,7 +1967,7 @@ var Director = class {
|
|
|
1951
1967
|
this.spawnDepth = opts.spawnDepth ?? 0;
|
|
1952
1968
|
this.sessionWriter = opts.sessionWriter ?? null;
|
|
1953
1969
|
this.manifestDebounceMs = opts.manifestDebounceMs ?? 2e3;
|
|
1954
|
-
this.
|
|
1970
|
+
this.maxFleetCostUsd = opts.directorBudget?.maxCostUsd ?? Number.POSITIVE_INFINITY;
|
|
1955
1971
|
this.maxBudgetExtensions = opts.maxBudgetExtensions ?? 2;
|
|
1956
1972
|
this.sessionsRoot = opts.sessionsRoot;
|
|
1957
1973
|
this.directorRunId = opts.directorRunId ?? this.id;
|
|
@@ -1962,20 +1978,28 @@ var Director = class {
|
|
|
1962
1978
|
maxSpawnDepth: this.maxSpawnDepth,
|
|
1963
1979
|
directorBudget: opts.directorBudget
|
|
1964
1980
|
}, opts.checkpointDebounceMs ?? 250) : null;
|
|
1981
|
+
this.fleetManager = opts.fleetManager;
|
|
1965
1982
|
if (this.sharedScratchpadPath) {
|
|
1966
|
-
void fsp4.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(
|
|
1983
|
+
void fsp4.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(
|
|
1984
|
+
(err) => this.logShutdownError("shared_scratchpad_mkdir", err)
|
|
1985
|
+
);
|
|
1967
1986
|
}
|
|
1968
1987
|
this.transport = new InMemoryBridgeTransport();
|
|
1969
1988
|
this.bridge = new InMemoryAgentBridge(
|
|
1970
1989
|
{ agentId: this.id, coordinatorId: this.id },
|
|
1971
1990
|
this.transport
|
|
1972
1991
|
);
|
|
1973
|
-
this.
|
|
1974
|
-
|
|
1975
|
-
this.
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1992
|
+
if (this.fleetManager) {
|
|
1993
|
+
this.fleet = this.fleetManager.fleet;
|
|
1994
|
+
this.usage = this.fleetManager.usage;
|
|
1995
|
+
} else {
|
|
1996
|
+
this.fleet = new FleetBus();
|
|
1997
|
+
this.usage = new FleetUsageAggregator(
|
|
1998
|
+
this.fleet,
|
|
1999
|
+
(id) => this.priceLookups.get(id),
|
|
2000
|
+
(id) => this.subagentMeta.get(id)
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
1979
2003
|
this.coordinator = new DefaultMultiAgentCoordinator(
|
|
1980
2004
|
{ ...opts.config, coordinatorId: this.id },
|
|
1981
2005
|
{ runner: opts.runner }
|
|
@@ -2064,7 +2088,9 @@ var Director = class {
|
|
|
2064
2088
|
if (this.manifestTimer) return;
|
|
2065
2089
|
this.manifestTimer = setTimeout(() => {
|
|
2066
2090
|
this.manifestTimer = null;
|
|
2067
|
-
void this.writeManifest().catch(
|
|
2091
|
+
void this.writeManifest().catch(
|
|
2092
|
+
(err) => this.logShutdownError("manifest_write_debounced", err)
|
|
2093
|
+
);
|
|
2068
2094
|
}, this.manifestDebounceMs);
|
|
2069
2095
|
}
|
|
2070
2096
|
/**
|
|
@@ -2077,58 +2103,73 @@ var Director = class {
|
|
|
2077
2103
|
* it the `cost` column in `usage.snapshot()` stays at 0.
|
|
2078
2104
|
*/
|
|
2079
2105
|
async spawn(config, priceLookup) {
|
|
2080
|
-
if (this.
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
if (
|
|
2089
|
-
throw new
|
|
2106
|
+
if (this.fleetManager) {
|
|
2107
|
+
const rejection = this.fleetManager.canSpawn(config);
|
|
2108
|
+
if (rejection) {
|
|
2109
|
+
if (rejection.kind === "max_spawn_depth") throw new FleetSpawnBudgetError("max_spawn_depth", rejection.limit, rejection.observed);
|
|
2110
|
+
if (rejection.kind === "max_spawns") throw new FleetSpawnBudgetError("max_spawns", rejection.limit, rejection.observed);
|
|
2111
|
+
if (rejection.kind === "max_cost_usd") throw new FleetCostCapError(rejection.limit, rejection.observed);
|
|
2112
|
+
}
|
|
2113
|
+
} else {
|
|
2114
|
+
if (this.spawnDepth >= this.maxSpawnDepth) {
|
|
2115
|
+
throw new FleetSpawnBudgetError("max_spawn_depth", this.maxSpawnDepth, this.spawnDepth);
|
|
2116
|
+
}
|
|
2117
|
+
if (this.spawnCount >= this.maxSpawns) {
|
|
2118
|
+
throw new FleetSpawnBudgetError("max_spawns", this.maxSpawns, this.spawnCount + 1);
|
|
2119
|
+
}
|
|
2120
|
+
if (this.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
|
|
2121
|
+
const totalCost = this.usage.snapshot().total?.cost ?? 0;
|
|
2122
|
+
if (totalCost >= this.maxFleetCostUsd) {
|
|
2123
|
+
throw new FleetCostCapError(this.maxFleetCostUsd, totalCost);
|
|
2124
|
+
}
|
|
2090
2125
|
}
|
|
2091
2126
|
}
|
|
2092
2127
|
const result = await this.coordinator.spawn(config);
|
|
2093
|
-
this.
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2128
|
+
if (this.fleetManager) {
|
|
2129
|
+
this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
|
|
2130
|
+
} else {
|
|
2131
|
+
this.spawnCount += 1;
|
|
2132
|
+
this.subagentMeta.set(result.subagentId, {
|
|
2133
|
+
provider: config.provider,
|
|
2134
|
+
model: config.model
|
|
2135
|
+
});
|
|
2136
|
+
if (priceLookup) this.priceLookups.set(result.subagentId, priceLookup);
|
|
2137
|
+
}
|
|
2099
2138
|
const subagentBridge = new InMemoryAgentBridge(
|
|
2100
2139
|
{ agentId: result.subagentId, coordinatorId: this.id },
|
|
2101
2140
|
this.transport
|
|
2102
2141
|
);
|
|
2103
2142
|
this.coordinator.setSubagentBridge(result.subagentId, subagentBridge);
|
|
2104
2143
|
this.subagentBridges.set(result.subagentId, subagentBridge);
|
|
2105
|
-
this.
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
role: config.role,
|
|
2109
|
-
provider: config.provider,
|
|
2110
|
-
model: config.model,
|
|
2111
|
-
taskIds: []
|
|
2112
|
-
});
|
|
2113
|
-
const spawnedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2114
|
-
this.stateCheckpoint?.recordSpawn(
|
|
2115
|
-
{
|
|
2116
|
-
id: result.subagentId,
|
|
2144
|
+
if (!this.fleetManager) {
|
|
2145
|
+
this.manifestEntries.set(result.subagentId, {
|
|
2146
|
+
subagentId: result.subagentId,
|
|
2117
2147
|
name: config.name,
|
|
2118
2148
|
role: config.role,
|
|
2119
2149
|
provider: config.provider,
|
|
2120
2150
|
model: config.model,
|
|
2121
|
-
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2151
|
+
taskIds: []
|
|
2152
|
+
});
|
|
2153
|
+
const spawnedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2154
|
+
this.stateCheckpoint?.recordSpawn(
|
|
2155
|
+
{
|
|
2156
|
+
id: result.subagentId,
|
|
2157
|
+
name: config.name,
|
|
2158
|
+
role: config.role,
|
|
2159
|
+
provider: config.provider,
|
|
2160
|
+
model: config.model,
|
|
2161
|
+
spawnedAt
|
|
2162
|
+
},
|
|
2163
|
+
this.spawnCount
|
|
2164
|
+
);
|
|
2165
|
+
void this.appendSessionEvent({
|
|
2166
|
+
type: "agent_spawned",
|
|
2167
|
+
ts: spawnedAt,
|
|
2168
|
+
agentId: result.subagentId,
|
|
2169
|
+
role: config.role ?? config.name
|
|
2170
|
+
});
|
|
2171
|
+
this.scheduleManifest();
|
|
2172
|
+
}
|
|
2132
2173
|
return result.subagentId;
|
|
2133
2174
|
}
|
|
2134
2175
|
/**
|
|
@@ -2240,7 +2281,7 @@ var Director = class {
|
|
|
2240
2281
|
usage: this.usage.snapshot()
|
|
2241
2282
|
};
|
|
2242
2283
|
await fsp4.mkdir(path4.dirname(this.manifestPath), { recursive: true });
|
|
2243
|
-
await
|
|
2284
|
+
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
2244
2285
|
return this.manifestPath;
|
|
2245
2286
|
}
|
|
2246
2287
|
/**
|
|
@@ -2295,8 +2336,12 @@ var Director = class {
|
|
|
2295
2336
|
async assign(task) {
|
|
2296
2337
|
const taskWithId = task.id ? task : { ...task, id: randomUUID() };
|
|
2297
2338
|
if (task.subagentId) {
|
|
2298
|
-
|
|
2299
|
-
|
|
2339
|
+
if (this.fleetManager) {
|
|
2340
|
+
this.fleetManager.addTaskToSubagent(task.subagentId, taskWithId.id);
|
|
2341
|
+
} else {
|
|
2342
|
+
const entry = this.manifestEntries.get(task.subagentId);
|
|
2343
|
+
if (entry) entry.taskIds.push(taskWithId.id);
|
|
2344
|
+
}
|
|
2300
2345
|
}
|
|
2301
2346
|
await this.coordinator.assign(taskWithId);
|
|
2302
2347
|
this.taskDescriptions.set(taskWithId.id, taskWithId.description);
|
|
@@ -2494,8 +2539,9 @@ var Director = class {
|
|
|
2494
2539
|
* still permission-checked normally.
|
|
2495
2540
|
*/
|
|
2496
2541
|
tools(roster) {
|
|
2542
|
+
const effectiveRoster = roster ?? this.roster;
|
|
2497
2543
|
const t = [
|
|
2498
|
-
makeSpawnTool(this,
|
|
2544
|
+
makeSpawnTool(this, effectiveRoster),
|
|
2499
2545
|
makeAssignTool(this),
|
|
2500
2546
|
makeAwaitTasksTool(this),
|
|
2501
2547
|
makeAskTool(this),
|
|
@@ -2764,9 +2810,11 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
2764
2810
|
candidates.push(path4.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
|
|
2765
2811
|
} else {
|
|
2766
2812
|
try {
|
|
2767
|
-
const
|
|
2768
|
-
for (const
|
|
2769
|
-
|
|
2813
|
+
const entries = await fsp4.readdir(opts.sessionsRoot, { withFileTypes: true });
|
|
2814
|
+
for (const entry of entries) {
|
|
2815
|
+
if (entry.isDirectory()) {
|
|
2816
|
+
candidates.push(path4.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
|
|
2817
|
+
}
|
|
2770
2818
|
}
|
|
2771
2819
|
} catch {
|
|
2772
2820
|
return void 0;
|
|
@@ -3072,19 +3120,25 @@ var DefaultSessionStore = class {
|
|
|
3072
3120
|
{ cause: err }
|
|
3073
3121
|
);
|
|
3074
3122
|
}
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
handle,
|
|
3078
|
-
(/* @__PURE__ */ new Date()).toISOString(),
|
|
3079
|
-
{
|
|
3123
|
+
try {
|
|
3124
|
+
const writer = new FileSessionWriter(
|
|
3080
3125
|
id,
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3126
|
+
handle,
|
|
3127
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
3128
|
+
{
|
|
3129
|
+
id,
|
|
3130
|
+
model: data.metadata.model,
|
|
3131
|
+
provider: data.metadata.provider
|
|
3132
|
+
},
|
|
3133
|
+
this.events,
|
|
3134
|
+
{ resumed: true, dir: this.dir, filePath: file }
|
|
3135
|
+
);
|
|
3136
|
+
return { writer, data };
|
|
3137
|
+
} catch (err) {
|
|
3138
|
+
await handle.close().catch(() => {
|
|
3139
|
+
});
|
|
3140
|
+
throw err;
|
|
3141
|
+
}
|
|
3088
3142
|
}
|
|
3089
3143
|
async load(id) {
|
|
3090
3144
|
const file = path4.join(this.dir, `${id}.jsonl`);
|
|
@@ -3130,7 +3184,7 @@ var DefaultSessionStore = class {
|
|
|
3130
3184
|
const full = path4.join(this.dir, `${id}.jsonl`);
|
|
3131
3185
|
const stat3 = await fsp4.stat(full);
|
|
3132
3186
|
const summary = await this.summarize(id, stat3.mtime.toISOString());
|
|
3133
|
-
await
|
|
3187
|
+
await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
|
|
3134
3188
|
console.warn(
|
|
3135
3189
|
`[session-store] Failed to write manifest for "${id}":`,
|
|
3136
3190
|
err instanceof Error ? err.message : String(err)
|
|
@@ -3358,7 +3412,7 @@ var FileSessionWriter = class {
|
|
|
3358
3412
|
this.closed = true;
|
|
3359
3413
|
if (this.manifestFile) {
|
|
3360
3414
|
try {
|
|
3361
|
-
await
|
|
3415
|
+
await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 384 });
|
|
3362
3416
|
} catch {
|
|
3363
3417
|
}
|
|
3364
3418
|
}
|
|
@@ -3483,6 +3537,211 @@ function makeDirectorSessionFactory(opts) {
|
|
|
3483
3537
|
};
|
|
3484
3538
|
}
|
|
3485
3539
|
|
|
3486
|
-
|
|
3540
|
+
// src/coordination/null-fleet-bus.ts
|
|
3541
|
+
var NULL_FLEET_BUS = new FleetBus();
|
|
3542
|
+
var FleetManager = class {
|
|
3543
|
+
/** The fleet-wide event bus. */
|
|
3544
|
+
fleet;
|
|
3545
|
+
/** Usage rollup across all subagents. */
|
|
3546
|
+
usage;
|
|
3547
|
+
manifestPath;
|
|
3548
|
+
sessionsRoot;
|
|
3549
|
+
directorRunId;
|
|
3550
|
+
/** Spawn cap (lifetime total). Infinity means unlimited. */
|
|
3551
|
+
maxSpawns;
|
|
3552
|
+
/** Nesting cap. */
|
|
3553
|
+
maxSpawnDepth;
|
|
3554
|
+
/** This director's depth in a director chain. Root = 0. */
|
|
3555
|
+
spawnDepth;
|
|
3556
|
+
/** Live spawn counter. */
|
|
3557
|
+
spawnCount = 0;
|
|
3558
|
+
stateCheckpoint;
|
|
3559
|
+
sessionWriter;
|
|
3560
|
+
manifestTimer = null;
|
|
3561
|
+
manifestDebounceMs;
|
|
3562
|
+
/** Fleet-wide cost cap. Infinity = no cap. Distinct from SubagentBudget limits,
|
|
3563
|
+
* which track per-subagent spend — this field caps the entire fleet total. */
|
|
3564
|
+
maxFleetCostUsd;
|
|
3565
|
+
manifestEntries = /* @__PURE__ */ new Map();
|
|
3566
|
+
/** Pending tasks with their descriptions — populated by `addPendingTask`
|
|
3567
|
+
* and cleared by `removePendingTask`. Replaces the host-side `pending`
|
|
3568
|
+
* Map so task descriptions live in one place (FleetManager). */
|
|
3569
|
+
pendingTasks = /* @__PURE__ */ new Map();
|
|
3570
|
+
subagentMeta = /* @__PURE__ */ new Map();
|
|
3571
|
+
priceLookups = /* @__PURE__ */ new Map();
|
|
3572
|
+
constructor(opts = {}) {
|
|
3573
|
+
this.manifestPath = opts.manifestPath;
|
|
3574
|
+
this.sessionsRoot = opts.sessionsRoot;
|
|
3575
|
+
this.directorRunId = opts.directorRunId ?? randomUUID();
|
|
3576
|
+
this.maxSpawns = opts.maxSpawns ?? Number.POSITIVE_INFINITY;
|
|
3577
|
+
this.maxSpawnDepth = opts.maxSpawnDepth ?? 2;
|
|
3578
|
+
this.spawnDepth = opts.spawnDepth ?? 0;
|
|
3579
|
+
this.sessionWriter = opts.sessionWriter ?? null;
|
|
3580
|
+
this.manifestDebounceMs = opts.manifestDebounceMs ?? 2e3;
|
|
3581
|
+
this.maxFleetCostUsd = opts.directorBudget?.maxCostUsd ?? Number.POSITIVE_INFINITY;
|
|
3582
|
+
this.stateCheckpoint = opts.stateCheckpointPath ? new DirectorStateCheckpoint(
|
|
3583
|
+
opts.stateCheckpointPath,
|
|
3584
|
+
{
|
|
3585
|
+
directorRunId: this.directorRunId,
|
|
3586
|
+
maxSpawns: opts.maxSpawns,
|
|
3587
|
+
spawnDepth: this.spawnDepth,
|
|
3588
|
+
maxSpawnDepth: this.maxSpawnDepth,
|
|
3589
|
+
directorBudget: opts.directorBudget
|
|
3590
|
+
},
|
|
3591
|
+
opts.checkpointDebounceMs ?? 250
|
|
3592
|
+
) : null;
|
|
3593
|
+
this.fleet = new FleetBus();
|
|
3594
|
+
this.usage = new FleetUsageAggregator(
|
|
3595
|
+
this.fleet,
|
|
3596
|
+
(id) => this.priceLookups.get(id),
|
|
3597
|
+
(id) => this.subagentMeta.get(id)
|
|
3598
|
+
);
|
|
3599
|
+
}
|
|
3600
|
+
// -----------------------------------------------------------------------
|
|
3601
|
+
// IFleetManager surface
|
|
3602
|
+
// -----------------------------------------------------------------------
|
|
3603
|
+
get fleetBus() {
|
|
3604
|
+
return this.fleet;
|
|
3605
|
+
}
|
|
3606
|
+
snapshot() {
|
|
3607
|
+
return this.usage.snapshot();
|
|
3608
|
+
}
|
|
3609
|
+
getSubagentMeta(id) {
|
|
3610
|
+
return this.subagentMeta.get(id);
|
|
3611
|
+
}
|
|
3612
|
+
/**
|
|
3613
|
+
* Returns null if the spawn is allowed, or an object describing
|
|
3614
|
+
* which cap was exceeded. Does NOT throw — the caller decides
|
|
3615
|
+
* how to surface the rejection.
|
|
3616
|
+
*/
|
|
3617
|
+
canSpawn(config) {
|
|
3618
|
+
if (this.spawnDepth >= this.maxSpawnDepth) {
|
|
3619
|
+
return { kind: "max_spawn_depth", limit: this.maxSpawnDepth, observed: this.spawnDepth };
|
|
3620
|
+
}
|
|
3621
|
+
if (this.spawnCount >= this.maxSpawns) {
|
|
3622
|
+
return { kind: "max_spawns", limit: this.maxSpawns, observed: this.spawnCount + 1 };
|
|
3623
|
+
}
|
|
3624
|
+
if (this.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
|
|
3625
|
+
const totalCost = this.usage.snapshot().total?.cost ?? 0;
|
|
3626
|
+
if (totalCost >= this.maxFleetCostUsd) {
|
|
3627
|
+
return { kind: "max_cost_usd", limit: this.maxFleetCostUsd, observed: totalCost };
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
return null;
|
|
3631
|
+
}
|
|
3632
|
+
/**
|
|
3633
|
+
* Records a spawn: increments counter, stores metadata, updates state checkpoint,
|
|
3634
|
+
* and schedules a debounced manifest write. Call AFTER the coordinator
|
|
3635
|
+
* has successfully spawned the subagent.
|
|
3636
|
+
*
|
|
3637
|
+
* @param subagentId The subagent's id (from coordinator.spawn result)
|
|
3638
|
+
* @param config The SubagentConfig that was used
|
|
3639
|
+
* @param priceLookup Optional per-subagent pricing data
|
|
3640
|
+
*/
|
|
3641
|
+
recordSpawn(subagentId, config, priceLookup) {
|
|
3642
|
+
this.spawnCount += 1;
|
|
3643
|
+
this.subagentMeta.set(subagentId, {
|
|
3644
|
+
provider: config.provider,
|
|
3645
|
+
model: config.model
|
|
3646
|
+
});
|
|
3647
|
+
if (priceLookup) this.priceLookups.set(subagentId, priceLookup);
|
|
3648
|
+
this.manifestEntries.set(subagentId, {
|
|
3649
|
+
subagentId,
|
|
3650
|
+
name: config.name,
|
|
3651
|
+
role: config.role,
|
|
3652
|
+
provider: config.provider,
|
|
3653
|
+
model: config.model,
|
|
3654
|
+
taskIds: []
|
|
3655
|
+
});
|
|
3656
|
+
this.stateCheckpoint?.recordSpawn({
|
|
3657
|
+
id: subagentId,
|
|
3658
|
+
name: config.name,
|
|
3659
|
+
role: config.role,
|
|
3660
|
+
provider: config.provider,
|
|
3661
|
+
model: config.model,
|
|
3662
|
+
spawnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3663
|
+
}, this.spawnCount);
|
|
3664
|
+
void this.appendSessionEvent({
|
|
3665
|
+
type: "agent_spawned",
|
|
3666
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3667
|
+
agentId: subagentId,
|
|
3668
|
+
role: config.role ?? config.name
|
|
3669
|
+
});
|
|
3670
|
+
this.scheduleManifest();
|
|
3671
|
+
}
|
|
3672
|
+
async writeManifest() {
|
|
3673
|
+
if (!this.manifestPath) return null;
|
|
3674
|
+
const manifest = {
|
|
3675
|
+
version: 1,
|
|
3676
|
+
directorRunId: this.directorRunId,
|
|
3677
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3678
|
+
children: Array.from(this.manifestEntries.values()).map((entry) => ({
|
|
3679
|
+
id: entry.subagentId,
|
|
3680
|
+
name: entry.name,
|
|
3681
|
+
role: entry.role,
|
|
3682
|
+
provider: entry.provider,
|
|
3683
|
+
model: entry.model,
|
|
3684
|
+
taskIds: entry.taskIds
|
|
3685
|
+
})),
|
|
3686
|
+
usage: this.usage.snapshot()
|
|
3687
|
+
};
|
|
3688
|
+
await fsp4.mkdir(path4.dirname(this.manifestPath), { recursive: true });
|
|
3689
|
+
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
3690
|
+
return this.manifestPath;
|
|
3691
|
+
}
|
|
3692
|
+
/**
|
|
3693
|
+
* Attach task ids to an already-spawned subagent. Called by
|
|
3694
|
+
* `Director.assign()` after the coordinator assigns a task.
|
|
3695
|
+
*/
|
|
3696
|
+
addTaskToSubagent(subagentId, taskId) {
|
|
3697
|
+
const entry = this.manifestEntries.get(subagentId);
|
|
3698
|
+
if (entry) entry.taskIds.push(taskId);
|
|
3699
|
+
}
|
|
3700
|
+
/**
|
|
3701
|
+
* Debounced manifest write. Call after any state mutation
|
|
3702
|
+
* (spawn, assign, complete) so a burst collapses into one write.
|
|
3703
|
+
*/
|
|
3704
|
+
scheduleManifest() {
|
|
3705
|
+
if (!this.manifestPath || this.manifestDebounceMs <= 0) return;
|
|
3706
|
+
if (this.manifestTimer) return;
|
|
3707
|
+
this.manifestTimer = setTimeout(() => {
|
|
3708
|
+
this.manifestTimer = null;
|
|
3709
|
+
void this.writeManifest().catch((err) => {
|
|
3710
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3711
|
+
process.emitWarning(
|
|
3712
|
+
`FleetManager manifest write failed: ${detail}`,
|
|
3713
|
+
"FleetManagerWarning"
|
|
3714
|
+
);
|
|
3715
|
+
});
|
|
3716
|
+
}, this.manifestDebounceMs);
|
|
3717
|
+
}
|
|
3718
|
+
/** Best-effort session event writer. Swallows failures. */
|
|
3719
|
+
async appendSessionEvent(event) {
|
|
3720
|
+
if (!this.sessionWriter) return;
|
|
3721
|
+
try {
|
|
3722
|
+
await this.sessionWriter.append(event);
|
|
3723
|
+
} catch {
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
// -----------------------------------------------------------------------
|
|
3727
|
+
// Pending task management — eliminates host-side state duplication
|
|
3728
|
+
// -----------------------------------------------------------------------
|
|
3729
|
+
addPendingTask(taskId, subagentId, description) {
|
|
3730
|
+
this.pendingTasks.set(taskId, { subagentId, description });
|
|
3731
|
+
}
|
|
3732
|
+
removePendingTask(taskId) {
|
|
3733
|
+
this.pendingTasks.delete(taskId);
|
|
3734
|
+
}
|
|
3735
|
+
getFleetStatus() {
|
|
3736
|
+
const pending = Array.from(this.pendingTasks.entries()).map(([taskId, v]) => ({
|
|
3737
|
+
taskId,
|
|
3738
|
+
description: v.description,
|
|
3739
|
+
subagentId: v.subagentId
|
|
3740
|
+
}));
|
|
3741
|
+
return { pending, live: [] };
|
|
3742
|
+
}
|
|
3743
|
+
};
|
|
3744
|
+
|
|
3745
|
+
export { ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, BUG_HUNTER_AGENT, BudgetExceededError, BudgetThresholdSignal, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_SUBAGENT_BASELINE, DefaultMultiAgentCoordinator, Director, FLEET_ROSTER, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, InMemoryAgentBridge, InMemoryBridgeTransport, NULL_FLEET_BUS, REFACTOR_PLANNER_AGENT, SECURITY_SCANNER_AGENT, SubagentBudget, composeDirectorPrompt, composeSubagentPrompt, createDelegateTool, createMessage, makeAgentSubagentRunner, makeDirectorSessionFactory, rosterSummaryFromConfigs };
|
|
3487
3746
|
//# sourceMappingURL=index.js.map
|
|
3488
3747
|
//# sourceMappingURL=index.js.map
|