@wrongstack/core 0.6.0 → 0.6.3
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-eb7qnNrd.d.ts} +1 -1
- package/dist/coordination/index.d.ts +5 -5
- package/dist/coordination/index.js +183 -87
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +10 -10
- package/dist/defaults/index.js +596 -114
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-DPQKFX7W.d.ts → events-BHuIHekD.d.ts} +27 -4
- package/dist/execution/index.d.ts +149 -6
- package/dist/execution/index.js +401 -21
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +2 -2
- package/dist/{goal-store-BQ3YX1h1.d.ts → goal-store-DVCfj7Ff.d.ts} +20 -0
- package/dist/{index-B0qTujQW.d.ts → index-BOn9NK7D.d.ts} +1 -1
- package/dist/{index-DkdRz6yK.d.ts → index-CPcDqvZh.d.ts} +11 -4
- package/dist/index.d.ts +50 -16
- package/dist/index.js +831 -125
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +2 -2
- package/dist/infrastructure/index.js +1 -1
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +2 -2
- package/dist/kernel/index.js.map +1 -1
- package/dist/{multi-agent-Cpp7FXUl.d.ts → multi-agent-CxSb-9dQ.d.ts} +30 -5
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +1 -1
- package/dist/observability/index.js.map +1 -1
- package/dist/{path-resolver--g_hKJ7V.d.ts → path-resolver-CMGNadvq.d.ts} +1 -1
- package/dist/{plan-templates-CKJs_sYh.d.ts → plan-templates-BJflQY2i.d.ts} +1 -1
- package/dist/{provider-runner-hl4Il3xS.d.ts → provider-runner-BFgNXpaP.d.ts} +1 -1
- package/dist/sdd/index.d.ts +2 -2
- package/dist/storage/index.d.ts +3 -3
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/{tool-executor-B03CRwu-.d.ts → tool-executor-FoxBjULX.d.ts} +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.js +30 -4
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.js +1 -1
- 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-CxSb-9dQ.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-CPcDqvZh.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-CxSb-9dQ.js';
|
|
3
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-eb7qnNrd.js';
|
|
4
4
|
import '../director-state-BmYi3DGA.js';
|
|
5
5
|
import '../context-CDRyrkKQ.js';
|
|
6
|
-
import '../events-
|
|
6
|
+
import '../events-BHuIHekD.js';
|
|
7
7
|
import 'node:events';
|
|
8
|
-
import '../index-
|
|
8
|
+
import '../index-BOn9NK7D.js';
|
|
9
9
|
import '../logger-BMQgxvdy.js';
|
|
10
10
|
import '../system-prompt-Dl2QY1_B.js';
|
|
11
11
|
import '../observability-BhnVLBLS.js';
|
|
@@ -492,40 +492,12 @@ var FleetBus = class {
|
|
|
492
492
|
* subagent teardown so the listeners don't outlive the run.
|
|
493
493
|
*/
|
|
494
494
|
attach(subagentId, bus, taskId) {
|
|
495
|
-
const
|
|
496
|
-
"
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
"tool.confirm_needed",
|
|
500
|
-
"iteration.started",
|
|
501
|
-
"iteration.completed",
|
|
502
|
-
"provider.text_delta",
|
|
503
|
-
// Subagent extended-thinking output. Forwarded so the FleetPanel /
|
|
504
|
-
// /fleet log can surface "the planner is thinking…" instead of a
|
|
505
|
-
// silent gap between iteration.started and the first text_delta.
|
|
506
|
-
"provider.thinking_delta",
|
|
507
|
-
"provider.response",
|
|
508
|
-
"provider.retry",
|
|
509
|
-
"provider.error",
|
|
510
|
-
"session.started",
|
|
511
|
-
"session.ended",
|
|
512
|
-
"session.damaged",
|
|
513
|
-
"compaction.fired",
|
|
514
|
-
"compaction.failed",
|
|
515
|
-
"token.threshold",
|
|
516
|
-
// Subagent hit a soft budget limit — coordinator can extend or stop.
|
|
517
|
-
"budget.threshold_reached"
|
|
518
|
-
];
|
|
519
|
-
const offs = [];
|
|
520
|
-
for (const t of FORWARDED_TYPES) {
|
|
521
|
-
offs.push(
|
|
522
|
-
bus.on(t, (payload) => {
|
|
523
|
-
this.emit({ subagentId, taskId, ts: Date.now(), type: t, payload });
|
|
524
|
-
})
|
|
525
|
-
);
|
|
526
|
-
}
|
|
495
|
+
const off = bus.onPattern("*", (type, payload) => {
|
|
496
|
+
if (type.startsWith("subagent.")) return;
|
|
497
|
+
this.emit({ subagentId, taskId, ts: Date.now(), type, payload });
|
|
498
|
+
});
|
|
527
499
|
return () => {
|
|
528
|
-
|
|
500
|
+
off();
|
|
529
501
|
};
|
|
530
502
|
}
|
|
531
503
|
/** Subscribe to every event from one subagent. */
|
|
@@ -792,7 +764,7 @@ var BudgetThresholdSignal = class extends Error {
|
|
|
792
764
|
this.decision = decision;
|
|
793
765
|
}
|
|
794
766
|
};
|
|
795
|
-
var SubagentBudget = class {
|
|
767
|
+
var SubagentBudget = class _SubagentBudget {
|
|
796
768
|
limits;
|
|
797
769
|
iterations = 0;
|
|
798
770
|
toolCalls = 0;
|
|
@@ -801,6 +773,26 @@ var SubagentBudget = class {
|
|
|
801
773
|
costUsd = 0;
|
|
802
774
|
startTime = null;
|
|
803
775
|
_onThreshold;
|
|
776
|
+
/**
|
|
777
|
+
* Tracks which budget kinds currently have an extension request
|
|
778
|
+
* in flight. While a kind is here, further `checkLimit` calls for the
|
|
779
|
+
* same kind are no-ops — without this dedup, every `recordIteration`
|
|
780
|
+
* after the limit is reached spawns a fresh decision Promise (until
|
|
781
|
+
* the first one lands and patches limits), flooding the FleetBus
|
|
782
|
+
* with redundant threshold events. Cleared in `checkLimitAsync`'s
|
|
783
|
+
* `finally`.
|
|
784
|
+
*/
|
|
785
|
+
pendingExtensions = /* @__PURE__ */ new Set();
|
|
786
|
+
/**
|
|
787
|
+
* Hard cap on how long `checkLimitAsync` waits for the coordinator to
|
|
788
|
+
* respond before defaulting to 'stop'. Without this fallback an absent
|
|
789
|
+
* or hung listener (Director not built / event filter detached mid-run)
|
|
790
|
+
* leaves the budget over-limit and never enforces anything, since
|
|
791
|
+
* `checkLimit` returns synchronously via `void this.checkLimitAsync`.
|
|
792
|
+
* Hardcoded for now — most fleets set their own per-task timeout that
|
|
793
|
+
* dwarfs this anyway. 30 s matches the existing event-emit timeoutMs.
|
|
794
|
+
*/
|
|
795
|
+
static DECISION_TIMEOUT_MS = 3e4;
|
|
804
796
|
/**
|
|
805
797
|
* Injected by the runner when wiring the budget to its EventBus.
|
|
806
798
|
* Used by `checkLimitAsync` to emit `budget.threshold_reached` events.
|
|
@@ -843,56 +835,92 @@ var SubagentBudget = class {
|
|
|
843
835
|
if (kind === "timeout" || !this._onThreshold) {
|
|
844
836
|
throw new BudgetExceededError(kind, limit, used);
|
|
845
837
|
}
|
|
846
|
-
|
|
838
|
+
const bus = this._events;
|
|
839
|
+
if (!bus || bus.listenerCount("budget.threshold_reached") === 0) {
|
|
840
|
+
throw new BudgetExceededError(kind, limit, used);
|
|
841
|
+
}
|
|
842
|
+
if (this.pendingExtensions.has(kind)) return;
|
|
843
|
+
this.pendingExtensions.add(kind);
|
|
844
|
+
const decision = this.negotiateExtension(kind, used, limit);
|
|
845
|
+
throw new BudgetThresholdSignal(kind, limit, used, decision);
|
|
847
846
|
}
|
|
848
847
|
/**
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
848
|
+
* Drive the threshold handler to a decision. Resolves with `'stop'`
|
|
849
|
+
* (signal the runner to abort) or `{ extend: ... }` (limits already
|
|
850
|
+
* patched in-place; the runner should not abort). Always releases the
|
|
851
|
+
* `pendingExtensions` slot in `finally`.
|
|
852
|
+
*
|
|
853
|
+
* The 'continue' return from a sync handler is treated as
|
|
854
|
+
* `{ extend: {} }` — keep going without patching, next overrun will
|
|
855
|
+
* fire a fresh signal.
|
|
852
856
|
*/
|
|
853
|
-
async
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
857
|
+
async negotiateExtension(kind, used, limit) {
|
|
858
|
+
try {
|
|
859
|
+
const result = this._onThreshold({
|
|
860
|
+
kind,
|
|
861
|
+
used,
|
|
862
|
+
limit,
|
|
863
|
+
// Inject a requestDecision helper the handler can call to emit the
|
|
864
|
+
// budget.threshold_reached event and wait for the coordinator's verdict.
|
|
865
|
+
// A hard fallback timer guarantees the promise eventually resolves
|
|
866
|
+
// even if no listener responds — without it, an absent/detached
|
|
867
|
+
// Director would leave the budget permanently in "asking" state.
|
|
868
|
+
requestDecision: () => {
|
|
869
|
+
const bus = this._events;
|
|
870
|
+
if (!bus || bus.listenerCount("budget.threshold_reached") === 0) {
|
|
871
|
+
return Promise.resolve("stop");
|
|
872
|
+
}
|
|
873
|
+
return new Promise((resolve) => {
|
|
874
|
+
let resolved = false;
|
|
875
|
+
const respond = (d) => {
|
|
876
|
+
if (resolved) return;
|
|
877
|
+
resolved = true;
|
|
878
|
+
resolve(d);
|
|
879
|
+
};
|
|
880
|
+
const fallback = setTimeout(
|
|
881
|
+
() => respond("stop"),
|
|
882
|
+
_SubagentBudget.DECISION_TIMEOUT_MS
|
|
883
|
+
);
|
|
884
|
+
bus.emit("budget.threshold_reached", {
|
|
885
|
+
kind,
|
|
886
|
+
used,
|
|
887
|
+
limit,
|
|
888
|
+
timeoutMs: _SubagentBudget.DECISION_TIMEOUT_MS,
|
|
889
|
+
extend: (extra) => {
|
|
890
|
+
clearTimeout(fallback);
|
|
891
|
+
respond({ extend: extra });
|
|
892
|
+
},
|
|
893
|
+
deny: () => {
|
|
894
|
+
clearTimeout(fallback);
|
|
895
|
+
respond("stop");
|
|
896
|
+
}
|
|
897
|
+
});
|
|
870
898
|
});
|
|
871
|
-
}
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
if (result === "throw") return "stop";
|
|
902
|
+
if (result === "continue") return { extend: {} };
|
|
903
|
+
const decision = await result;
|
|
904
|
+
if (decision === "stop") return "stop";
|
|
905
|
+
const ext = decision.extend;
|
|
906
|
+
if (ext.maxIterations !== void 0) {
|
|
907
|
+
this.limits.maxIterations = ext.maxIterations;
|
|
872
908
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
if (ext.maxToolCalls !== void 0) {
|
|
889
|
-
this.limits.maxToolCalls = ext.maxToolCalls;
|
|
890
|
-
}
|
|
891
|
-
if (ext.maxTokens !== void 0) {
|
|
892
|
-
this.limits.maxTokens = ext.maxTokens;
|
|
893
|
-
}
|
|
894
|
-
if (ext.maxCostUsd !== void 0) {
|
|
895
|
-
this.limits.maxCostUsd = ext.maxCostUsd;
|
|
909
|
+
if (ext.maxToolCalls !== void 0) {
|
|
910
|
+
this.limits.maxToolCalls = ext.maxToolCalls;
|
|
911
|
+
}
|
|
912
|
+
if (ext.maxTokens !== void 0) {
|
|
913
|
+
this.limits.maxTokens = ext.maxTokens;
|
|
914
|
+
}
|
|
915
|
+
if (ext.maxCostUsd !== void 0) {
|
|
916
|
+
this.limits.maxCostUsd = ext.maxCostUsd;
|
|
917
|
+
}
|
|
918
|
+
if (ext.timeoutMs !== void 0) {
|
|
919
|
+
this.limits.timeoutMs = ext.timeoutMs;
|
|
920
|
+
}
|
|
921
|
+
return decision;
|
|
922
|
+
} finally {
|
|
923
|
+
this.pendingExtensions.delete(kind);
|
|
896
924
|
}
|
|
897
925
|
}
|
|
898
926
|
recordIteration() {
|
|
@@ -1175,6 +1203,19 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1175
1203
|
setRunner(runner) {
|
|
1176
1204
|
this.runner = runner;
|
|
1177
1205
|
}
|
|
1206
|
+
/**
|
|
1207
|
+
* Change the in-flight dispatch ceiling at runtime. Lowering does NOT
|
|
1208
|
+
* preempt running tasks — already-dispatched subagents finish their
|
|
1209
|
+
* current task; only future dispatches respect the new cap. Raising
|
|
1210
|
+
* immediately tries to fill the freed slots from the pending queue.
|
|
1211
|
+
*/
|
|
1212
|
+
setMaxConcurrent(n) {
|
|
1213
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
1214
|
+
throw new Error(`maxConcurrent must be a finite integer >= 1, got ${n}`);
|
|
1215
|
+
}
|
|
1216
|
+
this.config.maxConcurrent = Math.floor(n);
|
|
1217
|
+
this.tryDispatchNext();
|
|
1218
|
+
}
|
|
1178
1219
|
async spawn(subagent) {
|
|
1179
1220
|
const id = subagent.id || randomUUID();
|
|
1180
1221
|
if (this.subagents.has(id)) {
|
|
@@ -1434,14 +1475,65 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1434
1475
|
this.recordCompletion(result);
|
|
1435
1476
|
}
|
|
1436
1477
|
async executeWithTimeout(runner, task, ctx, budget) {
|
|
1437
|
-
const
|
|
1438
|
-
if (
|
|
1478
|
+
const initialTimeoutMs = budget.limits.timeoutMs;
|
|
1479
|
+
if (initialTimeoutMs === void 0) return runner(task, ctx);
|
|
1480
|
+
const start = Date.now();
|
|
1439
1481
|
let timer = null;
|
|
1440
1482
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1483
|
+
const armFor = (ms) => {
|
|
1484
|
+
if (timer) clearTimeout(timer);
|
|
1485
|
+
timer = setTimeout(async () => {
|
|
1486
|
+
const elapsed = Date.now() - start;
|
|
1487
|
+
const limit = budget.limits.timeoutMs ?? initialTimeoutMs;
|
|
1488
|
+
if (!budget.onThreshold) {
|
|
1489
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1490
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
try {
|
|
1494
|
+
const result = budget.onThreshold({
|
|
1495
|
+
kind: "timeout",
|
|
1496
|
+
used: elapsed,
|
|
1497
|
+
limit,
|
|
1498
|
+
requestDecision: () => new Promise((resolveDecision) => {
|
|
1499
|
+
budget._events?.emit("budget.threshold_reached", {
|
|
1500
|
+
kind: "timeout",
|
|
1501
|
+
used: elapsed,
|
|
1502
|
+
limit,
|
|
1503
|
+
timeoutMs: 3e4,
|
|
1504
|
+
extend: (extra) => resolveDecision({ extend: extra }),
|
|
1505
|
+
deny: () => resolveDecision("stop")
|
|
1506
|
+
});
|
|
1507
|
+
})
|
|
1508
|
+
});
|
|
1509
|
+
const decision = typeof result === "string" ? result : await result;
|
|
1510
|
+
if (decision === "continue") {
|
|
1511
|
+
armFor(Math.max(1e3, limit));
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
if (decision === "throw" || decision === "stop") {
|
|
1515
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1516
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
if (decision.extend.timeoutMs !== void 0) {
|
|
1520
|
+
budget.limits.timeoutMs = decision.extend.timeoutMs;
|
|
1521
|
+
const newLimit = decision.extend.timeoutMs;
|
|
1522
|
+
const remaining = Math.max(1e3, newLimit - elapsed);
|
|
1523
|
+
armFor(remaining);
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1527
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
1530
|
+
reject(
|
|
1531
|
+
err instanceof BudgetExceededError ? err : new BudgetExceededError("timeout", limit, elapsed)
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1534
|
+
}, ms);
|
|
1535
|
+
};
|
|
1536
|
+
armFor(initialTimeoutMs);
|
|
1445
1537
|
});
|
|
1446
1538
|
try {
|
|
1447
1539
|
return await Promise.race([runner(task, ctx), timeoutPromise]);
|
|
@@ -2052,7 +2144,7 @@ var Director = class {
|
|
|
2052
2144
|
return;
|
|
2053
2145
|
}
|
|
2054
2146
|
extendCounts.set(guardKey, prior + 1);
|
|
2055
|
-
|
|
2147
|
+
setImmediate(() => {
|
|
2056
2148
|
const extra = {};
|
|
2057
2149
|
switch (payload.kind) {
|
|
2058
2150
|
case "iterations":
|
|
@@ -2067,9 +2159,12 @@ var Director = class {
|
|
|
2067
2159
|
case "cost":
|
|
2068
2160
|
extra.maxCostUsd = Math.min(payload.limit * 1.5, 10);
|
|
2069
2161
|
break;
|
|
2162
|
+
case "timeout":
|
|
2163
|
+
extra.timeoutMs = Math.min(Math.ceil(payload.limit * 1.5), 60 * 6e4);
|
|
2164
|
+
break;
|
|
2070
2165
|
}
|
|
2071
2166
|
payload.extend(extra);
|
|
2072
|
-
}
|
|
2167
|
+
});
|
|
2073
2168
|
});
|
|
2074
2169
|
}
|
|
2075
2170
|
/** Best-effort session-writer append. Swallows failures — the director
|
|
@@ -2864,6 +2959,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
2864
2959
|
const detachFleet = opts.fleetBus?.attach(ctx.subagentId, events, task.id);
|
|
2865
2960
|
const aborter = new AbortController();
|
|
2866
2961
|
ctx.budget._events = events;
|
|
2962
|
+
ctx.budget.onThreshold = ({ requestDecision }) => requestDecision();
|
|
2867
2963
|
let budgetError = null;
|
|
2868
2964
|
const onBudgetError = (err) => {
|
|
2869
2965
|
if (err instanceof BudgetThresholdSignal) {
|