@wrongstack/core 0.5.7 → 0.6.1
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-BKNiE1VH.d.ts → agent-bridge-DaCvA_uK.d.ts} +1 -1
- package/dist/coordination/index.d.ts +5 -5
- package/dist/coordination/index.js +218 -78
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +10 -9
- package/dist/defaults/index.js +1127 -180
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-DPQKFX7W.d.ts → events-CzkeaVVl.d.ts} +8 -2
- package/dist/execution/index.d.ts +281 -5
- package/dist/execution/index.js +785 -3
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +2 -2
- package/dist/extension/index.js +2 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/goal-store-DVCfj7Ff.d.ts +95 -0
- package/dist/{index-j2WyAyML.d.ts → index-BkKLQjea.d.ts} +34 -2
- package/dist/{index-Bf9Bpkdc.d.ts → index-i9rPR53g.d.ts} +11 -4
- package/dist/index.d.ts +51 -16
- package/dist/index.js +1506 -247
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +2 -2
- package/dist/kernel/index.d.ts +2 -2
- package/dist/kernel/index.js.map +1 -1
- package/dist/models/index.js +2 -3
- package/dist/models/index.js.map +1 -1
- package/dist/{multi-agent-Cpp7FXUl.d.ts → multi-agent-MfI6dmv-.d.ts} +30 -5
- package/dist/observability/index.d.ts +1 -1
- package/dist/{path-resolver--g_hKJ7V.d.ts → path-resolver-CWINz5XR.d.ts} +1 -1
- package/dist/{plan-templates-Bveo2W8n.d.ts → plan-templates-Bne1pB4d.d.ts} +6 -5
- package/dist/{provider-runner-hl4Il3xS.d.ts → provider-runner-CZYIzeBp.d.ts} +1 -1
- package/dist/sdd/index.d.ts +5 -3
- package/dist/sdd/index.js +102 -68
- package/dist/sdd/index.js.map +1 -1
- package/dist/security/index.js +82 -82
- package/dist/security/index.js.map +1 -1
- package/dist/skills/index.js +102 -38
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +3 -2
- package/dist/storage/index.js +134 -22
- package/dist/storage/index.js.map +1 -1
- package/dist/{tool-executor-DbAFkHdP.d.ts → tool-executor-40Q6shR-.d.ts} +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.js +116 -103
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -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-MfI6dmv-.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-memory pub/sub transport for agent-to-agent messaging.
|
|
@@ -1,11 +1,11 @@
|
|
|
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-
|
|
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-i9rPR53g.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-MfI6dmv-.js';
|
|
3
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-DaCvA_uK.js';
|
|
4
4
|
import '../director-state-BmYi3DGA.js';
|
|
5
5
|
import '../context-CDRyrkKQ.js';
|
|
6
|
-
import '../events-
|
|
6
|
+
import '../events-CzkeaVVl.js';
|
|
7
7
|
import 'node:events';
|
|
8
|
-
import '../index-
|
|
8
|
+
import '../index-BkKLQjea.js';
|
|
9
9
|
import '../logger-BMQgxvdy.js';
|
|
10
10
|
import '../system-prompt-Dl2QY1_B.js';
|
|
11
11
|
import '../observability-BhnVLBLS.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 {
|
|
@@ -794,7 +792,7 @@ var BudgetThresholdSignal = class extends Error {
|
|
|
794
792
|
this.decision = decision;
|
|
795
793
|
}
|
|
796
794
|
};
|
|
797
|
-
var SubagentBudget = class {
|
|
795
|
+
var SubagentBudget = class _SubagentBudget {
|
|
798
796
|
limits;
|
|
799
797
|
iterations = 0;
|
|
800
798
|
toolCalls = 0;
|
|
@@ -803,6 +801,26 @@ var SubagentBudget = class {
|
|
|
803
801
|
costUsd = 0;
|
|
804
802
|
startTime = null;
|
|
805
803
|
_onThreshold;
|
|
804
|
+
/**
|
|
805
|
+
* Tracks which budget kinds currently have an extension request
|
|
806
|
+
* in flight. While a kind is here, further `checkLimit` calls for the
|
|
807
|
+
* same kind are no-ops — without this dedup, every `recordIteration`
|
|
808
|
+
* after the limit is reached spawns a fresh decision Promise (until
|
|
809
|
+
* the first one lands and patches limits), flooding the FleetBus
|
|
810
|
+
* with redundant threshold events. Cleared in `checkLimitAsync`'s
|
|
811
|
+
* `finally`.
|
|
812
|
+
*/
|
|
813
|
+
pendingExtensions = /* @__PURE__ */ new Set();
|
|
814
|
+
/**
|
|
815
|
+
* Hard cap on how long `checkLimitAsync` waits for the coordinator to
|
|
816
|
+
* respond before defaulting to 'stop'. Without this fallback an absent
|
|
817
|
+
* or hung listener (Director not built / event filter detached mid-run)
|
|
818
|
+
* leaves the budget over-limit and never enforces anything, since
|
|
819
|
+
* `checkLimit` returns synchronously via `void this.checkLimitAsync`.
|
|
820
|
+
* Hardcoded for now — most fleets set their own per-task timeout that
|
|
821
|
+
* dwarfs this anyway. 30 s matches the existing event-emit timeoutMs.
|
|
822
|
+
*/
|
|
823
|
+
static DECISION_TIMEOUT_MS = 3e4;
|
|
806
824
|
/**
|
|
807
825
|
* Injected by the runner when wiring the budget to its EventBus.
|
|
808
826
|
* Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
|
|
@@ -845,56 +863,92 @@ var SubagentBudget = class {
|
|
|
845
863
|
if (kind === "timeout" || !this._onThreshold) {
|
|
846
864
|
throw new BudgetExceededError(kind, limit, used);
|
|
847
865
|
}
|
|
848
|
-
|
|
866
|
+
const bus = this._events;
|
|
867
|
+
if (!bus || bus.listenerCount("budget.threshold_reached") === 0) {
|
|
868
|
+
throw new BudgetExceededError(kind, limit, used);
|
|
869
|
+
}
|
|
870
|
+
if (this.pendingExtensions.has(kind)) return;
|
|
871
|
+
this.pendingExtensions.add(kind);
|
|
872
|
+
const decision = this.negotiateExtension(kind, used, limit);
|
|
873
|
+
throw new BudgetThresholdSignal(kind, limit, used, decision);
|
|
849
874
|
}
|
|
850
875
|
/**
|
|
851
|
-
*
|
|
852
|
-
*
|
|
853
|
-
*
|
|
876
|
+
* Drive the threshold handler to a decision. Resolves with `'stop'`
|
|
877
|
+
* (signal the runner to abort) or `{ extend: ... }` (limits already
|
|
878
|
+
* patched in-place; the runner should not abort). Always releases the
|
|
879
|
+
* `pendingExtensions` slot in `finally`.
|
|
880
|
+
*
|
|
881
|
+
* The 'continue' return from a sync handler is treated as
|
|
882
|
+
* `{ extend: {} }` — keep going without patching, next overrun will
|
|
883
|
+
* fire a fresh signal.
|
|
854
884
|
*/
|
|
855
|
-
async
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
885
|
+
async negotiateExtension(kind, used, limit) {
|
|
886
|
+
try {
|
|
887
|
+
const result = this._onThreshold({
|
|
888
|
+
kind,
|
|
889
|
+
used,
|
|
890
|
+
limit,
|
|
891
|
+
// Inject a requestDecision helper the handler can call to emit the
|
|
892
|
+
// budget.threshold_reached event and wait for the coordinator's verdict.
|
|
893
|
+
// A hard fallback timer guarantees the promise eventually resolves
|
|
894
|
+
// even if no listener responds — without it, an absent/detached
|
|
895
|
+
// Director would leave the budget permanently in "asking" state.
|
|
896
|
+
requestDecision: () => {
|
|
897
|
+
const bus = this._events;
|
|
898
|
+
if (!bus || bus.listenerCount("budget.threshold_reached") === 0) {
|
|
899
|
+
return Promise.resolve("stop");
|
|
900
|
+
}
|
|
901
|
+
return new Promise((resolve) => {
|
|
902
|
+
let resolved = false;
|
|
903
|
+
const respond = (d) => {
|
|
904
|
+
if (resolved) return;
|
|
905
|
+
resolved = true;
|
|
906
|
+
resolve(d);
|
|
907
|
+
};
|
|
908
|
+
const fallback = setTimeout(
|
|
909
|
+
() => respond("stop"),
|
|
910
|
+
_SubagentBudget.DECISION_TIMEOUT_MS
|
|
911
|
+
);
|
|
912
|
+
bus.emit("budget.threshold_reached", {
|
|
913
|
+
kind,
|
|
914
|
+
used,
|
|
915
|
+
limit,
|
|
916
|
+
timeoutMs: _SubagentBudget.DECISION_TIMEOUT_MS,
|
|
917
|
+
extend: (extra) => {
|
|
918
|
+
clearTimeout(fallback);
|
|
919
|
+
respond({ extend: extra });
|
|
920
|
+
},
|
|
921
|
+
deny: () => {
|
|
922
|
+
clearTimeout(fallback);
|
|
923
|
+
respond("stop");
|
|
924
|
+
}
|
|
925
|
+
});
|
|
872
926
|
});
|
|
873
|
-
}
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
if (result === "throw") return "stop";
|
|
930
|
+
if (result === "continue") return { extend: {} };
|
|
931
|
+
const decision = await result;
|
|
932
|
+
if (decision === "stop") return "stop";
|
|
933
|
+
const ext = decision.extend;
|
|
934
|
+
if (ext.maxIterations !== void 0) {
|
|
935
|
+
this.limits.maxIterations = ext.maxIterations;
|
|
874
936
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
if (ext.maxToolCalls !== void 0) {
|
|
891
|
-
this.limits.maxToolCalls = ext.maxToolCalls;
|
|
892
|
-
}
|
|
893
|
-
if (ext.maxTokens !== void 0) {
|
|
894
|
-
this.limits.maxTokens = ext.maxTokens;
|
|
895
|
-
}
|
|
896
|
-
if (ext.maxCostUsd !== void 0) {
|
|
897
|
-
this.limits.maxCostUsd = ext.maxCostUsd;
|
|
937
|
+
if (ext.maxToolCalls !== void 0) {
|
|
938
|
+
this.limits.maxToolCalls = ext.maxToolCalls;
|
|
939
|
+
}
|
|
940
|
+
if (ext.maxTokens !== void 0) {
|
|
941
|
+
this.limits.maxTokens = ext.maxTokens;
|
|
942
|
+
}
|
|
943
|
+
if (ext.maxCostUsd !== void 0) {
|
|
944
|
+
this.limits.maxCostUsd = ext.maxCostUsd;
|
|
945
|
+
}
|
|
946
|
+
if (ext.timeoutMs !== void 0) {
|
|
947
|
+
this.limits.timeoutMs = ext.timeoutMs;
|
|
948
|
+
}
|
|
949
|
+
return decision;
|
|
950
|
+
} finally {
|
|
951
|
+
this.pendingExtensions.delete(kind);
|
|
898
952
|
}
|
|
899
953
|
}
|
|
900
954
|
recordIteration() {
|
|
@@ -1177,6 +1231,19 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1177
1231
|
setRunner(runner) {
|
|
1178
1232
|
this.runner = runner;
|
|
1179
1233
|
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Change the in-flight dispatch ceiling at runtime. Lowering does NOT
|
|
1236
|
+
* preempt running tasks — already-dispatched subagents finish their
|
|
1237
|
+
* current task; only future dispatches respect the new cap. Raising
|
|
1238
|
+
* immediately tries to fill the freed slots from the pending queue.
|
|
1239
|
+
*/
|
|
1240
|
+
setMaxConcurrent(n) {
|
|
1241
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
1242
|
+
throw new Error(`maxConcurrent must be a finite integer >= 1, got ${n}`);
|
|
1243
|
+
}
|
|
1244
|
+
this.config.maxConcurrent = Math.floor(n);
|
|
1245
|
+
this.tryDispatchNext();
|
|
1246
|
+
}
|
|
1180
1247
|
async spawn(subagent) {
|
|
1181
1248
|
const id = subagent.id || randomUUID();
|
|
1182
1249
|
if (this.subagents.has(id)) {
|
|
@@ -1436,14 +1503,65 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1436
1503
|
this.recordCompletion(result);
|
|
1437
1504
|
}
|
|
1438
1505
|
async executeWithTimeout(runner, task, ctx, budget) {
|
|
1439
|
-
const
|
|
1440
|
-
if (
|
|
1506
|
+
const initialTimeoutMs = budget.limits.timeoutMs;
|
|
1507
|
+
if (initialTimeoutMs === void 0) return runner(task, ctx);
|
|
1508
|
+
const start = Date.now();
|
|
1441
1509
|
let timer = null;
|
|
1442
1510
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1511
|
+
const armFor = (ms) => {
|
|
1512
|
+
if (timer) clearTimeout(timer);
|
|
1513
|
+
timer = setTimeout(async () => {
|
|
1514
|
+
const elapsed = Date.now() - start;
|
|
1515
|
+
const limit = budget.limits.timeoutMs ?? initialTimeoutMs;
|
|
1516
|
+
if (!budget.onThreshold) {
|
|
1517
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1518
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
try {
|
|
1522
|
+
const result = budget.onThreshold({
|
|
1523
|
+
kind: "timeout",
|
|
1524
|
+
used: elapsed,
|
|
1525
|
+
limit,
|
|
1526
|
+
requestDecision: () => new Promise((resolveDecision) => {
|
|
1527
|
+
budget._events?.emit("budget.threshold_reached", {
|
|
1528
|
+
kind: "timeout",
|
|
1529
|
+
used: elapsed,
|
|
1530
|
+
limit,
|
|
1531
|
+
timeoutMs: 3e4,
|
|
1532
|
+
extend: (extra) => resolveDecision({ extend: extra }),
|
|
1533
|
+
deny: () => resolveDecision("stop")
|
|
1534
|
+
});
|
|
1535
|
+
})
|
|
1536
|
+
});
|
|
1537
|
+
const decision = typeof result === "string" ? result : await result;
|
|
1538
|
+
if (decision === "continue") {
|
|
1539
|
+
armFor(Math.max(1e3, limit));
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
if (decision === "throw" || decision === "stop") {
|
|
1543
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1544
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
if (decision.extend.timeoutMs !== void 0) {
|
|
1548
|
+
budget.limits.timeoutMs = decision.extend.timeoutMs;
|
|
1549
|
+
const newLimit = decision.extend.timeoutMs;
|
|
1550
|
+
const remaining = Math.max(1e3, newLimit - elapsed);
|
|
1551
|
+
armFor(remaining);
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1555
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1556
|
+
} catch (err) {
|
|
1557
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1558
|
+
reject(
|
|
1559
|
+
err instanceof BudgetExceededError ? err : new BudgetExceededError("timeout", limit, elapsed)
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
}, ms);
|
|
1563
|
+
};
|
|
1564
|
+
armFor(initialTimeoutMs);
|
|
1447
1565
|
});
|
|
1448
1566
|
try {
|
|
1449
1567
|
return await Promise.race([runner(task, ctx), timeoutPromise]);
|
|
@@ -1982,7 +2100,9 @@ var Director = class {
|
|
|
1982
2100
|
}, opts.checkpointDebounceMs ?? 250) : null;
|
|
1983
2101
|
this.fleetManager = opts.fleetManager;
|
|
1984
2102
|
if (this.sharedScratchpadPath) {
|
|
1985
|
-
void fsp4.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(
|
|
2103
|
+
void fsp4.mkdir(this.sharedScratchpadPath, { recursive: true }).catch(
|
|
2104
|
+
(err) => this.logShutdownError("shared_scratchpad_mkdir", err)
|
|
2105
|
+
);
|
|
1986
2106
|
}
|
|
1987
2107
|
this.transport = new InMemoryBridgeTransport();
|
|
1988
2108
|
this.bridge = new InMemoryAgentBridge(
|
|
@@ -2052,7 +2172,7 @@ var Director = class {
|
|
|
2052
2172
|
return;
|
|
2053
2173
|
}
|
|
2054
2174
|
extendCounts.set(guardKey, prior + 1);
|
|
2055
|
-
|
|
2175
|
+
setImmediate(() => {
|
|
2056
2176
|
const extra = {};
|
|
2057
2177
|
switch (payload.kind) {
|
|
2058
2178
|
case "iterations":
|
|
@@ -2067,9 +2187,12 @@ var Director = class {
|
|
|
2067
2187
|
case "cost":
|
|
2068
2188
|
extra.maxCostUsd = Math.min(payload.limit * 1.5, 10);
|
|
2069
2189
|
break;
|
|
2190
|
+
case "timeout":
|
|
2191
|
+
extra.timeoutMs = Math.min(Math.ceil(payload.limit * 1.5), 60 * 6e4);
|
|
2192
|
+
break;
|
|
2070
2193
|
}
|
|
2071
2194
|
payload.extend(extra);
|
|
2072
|
-
}
|
|
2195
|
+
});
|
|
2073
2196
|
});
|
|
2074
2197
|
}
|
|
2075
2198
|
/** Best-effort session-writer append. Swallows failures — the director
|
|
@@ -2088,7 +2211,9 @@ var Director = class {
|
|
|
2088
2211
|
if (this.manifestTimer) return;
|
|
2089
2212
|
this.manifestTimer = setTimeout(() => {
|
|
2090
2213
|
this.manifestTimer = null;
|
|
2091
|
-
void this.writeManifest().catch(
|
|
2214
|
+
void this.writeManifest().catch(
|
|
2215
|
+
(err) => this.logShutdownError("manifest_write_debounced", err)
|
|
2216
|
+
);
|
|
2092
2217
|
}, this.manifestDebounceMs);
|
|
2093
2218
|
}
|
|
2094
2219
|
/**
|
|
@@ -2279,7 +2404,7 @@ var Director = class {
|
|
|
2279
2404
|
usage: this.usage.snapshot()
|
|
2280
2405
|
};
|
|
2281
2406
|
await fsp4.mkdir(path4.dirname(this.manifestPath), { recursive: true });
|
|
2282
|
-
await
|
|
2407
|
+
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
2283
2408
|
return this.manifestPath;
|
|
2284
2409
|
}
|
|
2285
2410
|
/**
|
|
@@ -2808,9 +2933,11 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
2808
2933
|
candidates.push(path4.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
|
|
2809
2934
|
} else {
|
|
2810
2935
|
try {
|
|
2811
|
-
const
|
|
2812
|
-
for (const
|
|
2813
|
-
|
|
2936
|
+
const entries = await fsp4.readdir(opts.sessionsRoot, { withFileTypes: true });
|
|
2937
|
+
for (const entry of entries) {
|
|
2938
|
+
if (entry.isDirectory()) {
|
|
2939
|
+
candidates.push(path4.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
|
|
2940
|
+
}
|
|
2814
2941
|
}
|
|
2815
2942
|
} catch {
|
|
2816
2943
|
return void 0;
|
|
@@ -2860,6 +2987,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
2860
2987
|
const detachFleet = opts.fleetBus?.attach(ctx.subagentId, events, task.id);
|
|
2861
2988
|
const aborter = new AbortController();
|
|
2862
2989
|
ctx.budget._events = events;
|
|
2990
|
+
ctx.budget.onThreshold = ({ requestDecision }) => requestDecision();
|
|
2863
2991
|
let budgetError = null;
|
|
2864
2992
|
const onBudgetError = (err) => {
|
|
2865
2993
|
if (err instanceof BudgetThresholdSignal) {
|
|
@@ -3116,19 +3244,25 @@ var DefaultSessionStore = class {
|
|
|
3116
3244
|
{ cause: err }
|
|
3117
3245
|
);
|
|
3118
3246
|
}
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
handle,
|
|
3122
|
-
(/* @__PURE__ */ new Date()).toISOString(),
|
|
3123
|
-
{
|
|
3247
|
+
try {
|
|
3248
|
+
const writer = new FileSessionWriter(
|
|
3124
3249
|
id,
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3250
|
+
handle,
|
|
3251
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
3252
|
+
{
|
|
3253
|
+
id,
|
|
3254
|
+
model: data.metadata.model,
|
|
3255
|
+
provider: data.metadata.provider
|
|
3256
|
+
},
|
|
3257
|
+
this.events,
|
|
3258
|
+
{ resumed: true, dir: this.dir, filePath: file }
|
|
3259
|
+
);
|
|
3260
|
+
return { writer, data };
|
|
3261
|
+
} catch (err) {
|
|
3262
|
+
await handle.close().catch(() => {
|
|
3263
|
+
});
|
|
3264
|
+
throw err;
|
|
3265
|
+
}
|
|
3132
3266
|
}
|
|
3133
3267
|
async load(id) {
|
|
3134
3268
|
const file = path4.join(this.dir, `${id}.jsonl`);
|
|
@@ -3174,7 +3308,7 @@ var DefaultSessionStore = class {
|
|
|
3174
3308
|
const full = path4.join(this.dir, `${id}.jsonl`);
|
|
3175
3309
|
const stat3 = await fsp4.stat(full);
|
|
3176
3310
|
const summary = await this.summarize(id, stat3.mtime.toISOString());
|
|
3177
|
-
await
|
|
3311
|
+
await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
|
|
3178
3312
|
console.warn(
|
|
3179
3313
|
`[session-store] Failed to write manifest for "${id}":`,
|
|
3180
3314
|
err instanceof Error ? err.message : String(err)
|
|
@@ -3402,7 +3536,7 @@ var FileSessionWriter = class {
|
|
|
3402
3536
|
this.closed = true;
|
|
3403
3537
|
if (this.manifestFile) {
|
|
3404
3538
|
try {
|
|
3405
|
-
await
|
|
3539
|
+
await atomicWrite(this.manifestFile, JSON.stringify(this.summary), { mode: 384 });
|
|
3406
3540
|
} catch {
|
|
3407
3541
|
}
|
|
3408
3542
|
}
|
|
@@ -3676,7 +3810,7 @@ var FleetManager = class {
|
|
|
3676
3810
|
usage: this.usage.snapshot()
|
|
3677
3811
|
};
|
|
3678
3812
|
await fsp4.mkdir(path4.dirname(this.manifestPath), { recursive: true });
|
|
3679
|
-
await
|
|
3813
|
+
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
3680
3814
|
return this.manifestPath;
|
|
3681
3815
|
}
|
|
3682
3816
|
/**
|
|
@@ -3696,7 +3830,13 @@ var FleetManager = class {
|
|
|
3696
3830
|
if (this.manifestTimer) return;
|
|
3697
3831
|
this.manifestTimer = setTimeout(() => {
|
|
3698
3832
|
this.manifestTimer = null;
|
|
3699
|
-
void this.writeManifest().catch(() =>
|
|
3833
|
+
void this.writeManifest().catch((err) => {
|
|
3834
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3835
|
+
process.emitWarning(
|
|
3836
|
+
`FleetManager manifest write failed: ${detail}`,
|
|
3837
|
+
"FleetManagerWarning"
|
|
3838
|
+
);
|
|
3839
|
+
});
|
|
3700
3840
|
}, this.manifestDebounceMs);
|
|
3701
3841
|
}
|
|
3702
3842
|
/** Best-effort session event writer. Swallows failures. */
|