@wrongstack/core 0.6.3 → 0.6.5
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-eb7qnNrd.d.ts → agent-bridge-BBXK_ppx.d.ts} +1 -1
- package/dist/agent-subagent-runner-DsSm9lKN.d.ts +174 -0
- package/dist/{compactor-RIPuTtWK.d.ts → compactor-C8NhpSt5.d.ts} +1 -1
- package/dist/{config-BGGuP_Ar.d.ts → config-DfC6g6KV.d.ts} +1 -1
- package/dist/{context-CDRyrkKQ.d.ts → context-DN5v-uQX.d.ts} +11 -0
- package/dist/coordination/index.d.ts +10 -9
- package/dist/coordination/index.js +113 -20
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +21 -20
- package/dist/defaults/index.js +1329 -925
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-BHuIHekD.d.ts → events-CJqwQl8G.d.ts} +17 -1
- package/dist/execution/index.d.ts +82 -13
- package/dist/execution/index.js +1366 -74
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{goal-store-DVCfj7Ff.d.ts → goal-store-_Er467ya.d.ts} +2 -2
- package/dist/{index-CPcDqvZh.d.ts → index-CXnWsGBp.d.ts} +11 -175
- package/dist/{index-BOn9NK7D.d.ts → index-DcnXDPdY.d.ts} +6 -6
- package/dist/index.d.ts +28 -27
- package/dist/index.js +1068 -664
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DBdh3cee.d.ts → mcp-servers-CevFHHM1.d.ts} +3 -3
- package/dist/models/index.d.ts +2 -2
- package/dist/models/index.js +5 -16
- package/dist/models/index.js.map +1 -1
- package/dist/{multi-agent-CxSb-9dQ.d.ts → multi-agent-D5IbASk_.d.ts} +16 -4
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-CMGNadvq.d.ts → path-resolver-CBx_q1HA.d.ts} +2 -2
- package/dist/{plan-templates-BJflQY2i.d.ts → plan-templates-BEOllUJV.d.ts} +5 -4
- package/dist/{provider-runner-BFgNXpaP.d.ts → provider-runner-Byh5TcJs.d.ts} +3 -3
- package/dist/{retry-policy-LKS8MHsB.d.ts → retry-policy-BZSIMxrJ.d.ts} +1 -1
- package/dist/sdd/index.d.ts +3 -3
- package/dist/{secret-scrubber-CfMdAJ_l.d.ts → secret-scrubber-CT7wefiO.d.ts} +1 -1
- package/dist/{secret-scrubber-BzQR5BiL.d.ts → secret-scrubber-I0QHY_ob.d.ts} +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/{selector-C7HqnZJU.d.ts → selector-DDb_mq9X.d.ts} +1 -1
- package/dist/{session-reader-CzfRA6Vk.d.ts → session-reader-B9nVkziM.d.ts} +1 -1
- package/dist/storage/index.d.ts +6 -6
- package/dist/storage/index.js +27 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-Dl2QY1_B.d.ts → system-prompt-gL06H9P4.d.ts} +1 -1
- package/dist/{tool-executor-FoxBjULX.d.ts → tool-executor-BF7QfYVE.d.ts} +4 -4
- package/dist/types/index.d.ts +15 -15
- package/dist/types/index.js +5 -16
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
- package/skills/audit-log/SKILL.md +57 -28
- package/skills/bug-hunter/SKILL.md +85 -61
- package/skills/git-flow/SKILL.md +73 -18
- package/skills/multi-agent/SKILL.md +69 -40
- package/skills/node-modern/SKILL.md +111 -19
- package/skills/prompt-engineering/SKILL.md +97 -16
- package/skills/react-modern/SKILL.md +104 -18
- package/skills/refactor-planner/SKILL.md +73 -43
- package/skills/sdd/SKILL.md +54 -112
- package/skills/security-scanner/SKILL.md +95 -93
- package/skills/skill-creator/SKILL.md +58 -25
- package/skills/typescript-strict/SKILL.md +107 -15
|
@@ -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-D5IbASk_.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* In-memory pub/sub transport for agent-to-agent messaging.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { A as Agent, k as AgentInput } from './index-DcnXDPdY.js';
|
|
2
|
+
import { E as EventBus } from './events-CJqwQl8G.js';
|
|
3
|
+
import { c as SubagentConfig, k as TaskSpec, i as SubagentRunner } from './multi-agent-D5IbASk_.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Single fleet-wide event with subagent attribution. Whatever a child
|
|
7
|
+
* agent emits on its own EventBus gets re-published here, prefixed with
|
|
8
|
+
* `subagentId` so a single subscriber can multiplex across the fleet.
|
|
9
|
+
*
|
|
10
|
+
* The director uses `FleetBus.filter('tool.executed', …)` to see every
|
|
11
|
+
* tool call across the fleet; the TUI uses
|
|
12
|
+
* `FleetBus.subscribe(id, handler)` to render a per-subagent panel.
|
|
13
|
+
*/
|
|
14
|
+
interface FleetEvent {
|
|
15
|
+
subagentId: string;
|
|
16
|
+
taskId?: string;
|
|
17
|
+
ts: number;
|
|
18
|
+
type: string;
|
|
19
|
+
payload: unknown;
|
|
20
|
+
}
|
|
21
|
+
type FleetHandler = (event: FleetEvent) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Fan-in for per-subagent EventBuses. Each subagent's bus is plugged in
|
|
24
|
+
* via `attach()`; the FleetBus re-emits every event with subagent
|
|
25
|
+
* attribution. Detachment is automatic via the returned disposer — call
|
|
26
|
+
* it when a subagent terminates so we don't leak listeners.
|
|
27
|
+
*
|
|
28
|
+
* The bus exposes two subscription modes: by `subagentId` (everything
|
|
29
|
+
* from one child) and by `type` (one event-type across the fleet). They
|
|
30
|
+
* compose — if you need a per-subagent + per-type slice, subscribe by
|
|
31
|
+
* type and filter on `event.subagentId` in your handler.
|
|
32
|
+
*/
|
|
33
|
+
declare class FleetBus {
|
|
34
|
+
private readonly byId;
|
|
35
|
+
private readonly byType;
|
|
36
|
+
private readonly any;
|
|
37
|
+
/**
|
|
38
|
+
* Hook a subagent's EventBus into the fleet. EventBus is strongly
|
|
39
|
+
* typed and doesn't expose an `onAny` hook, so we subscribe to the
|
|
40
|
+
* canonical set of event types a subagent emits during a run. New
|
|
41
|
+
* event types added to the kernel must be added here too — but the
|
|
42
|
+
* cost is a tiny single line per type, and the explicit list keeps
|
|
43
|
+
* the wire format clear.
|
|
44
|
+
*
|
|
45
|
+
* Returns a disposer that detaches every subscription; call on
|
|
46
|
+
* subagent teardown so the listeners don't outlive the run.
|
|
47
|
+
*/
|
|
48
|
+
attach(subagentId: string, bus: EventBus, taskId?: string): () => void;
|
|
49
|
+
/** Subscribe to every event from one subagent. */
|
|
50
|
+
subscribe(subagentId: string, handler: FleetHandler): () => void;
|
|
51
|
+
/** Subscribe to one event type across all subagents. */
|
|
52
|
+
filter(type: string, handler: FleetHandler): () => void;
|
|
53
|
+
/** Subscribe to literally everything. The fleet roll-up uses this. */
|
|
54
|
+
onAny(handler: FleetHandler): () => void;
|
|
55
|
+
emit(event: FleetEvent): void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Roll-up of token usage + cost across an entire director run. The
|
|
59
|
+
* director's `fleet_status` tool returns this so the model can reason
|
|
60
|
+
* about budget in its next turn ("the researcher already burned $0.40,
|
|
61
|
+
* lean on summaries for the next task").
|
|
62
|
+
*/
|
|
63
|
+
interface FleetUsage {
|
|
64
|
+
total: {
|
|
65
|
+
input: number;
|
|
66
|
+
output: number;
|
|
67
|
+
cacheRead: number;
|
|
68
|
+
cacheWrite: number;
|
|
69
|
+
cost: number;
|
|
70
|
+
};
|
|
71
|
+
perSubagent: Record<string, SubagentUsageSnapshot>;
|
|
72
|
+
}
|
|
73
|
+
interface SubagentUsageSnapshot {
|
|
74
|
+
subagentId: string;
|
|
75
|
+
provider?: string;
|
|
76
|
+
model?: string;
|
|
77
|
+
input: number;
|
|
78
|
+
output: number;
|
|
79
|
+
cacheRead: number;
|
|
80
|
+
cacheWrite: number;
|
|
81
|
+
cost: number;
|
|
82
|
+
toolCalls: number;
|
|
83
|
+
iterations: number;
|
|
84
|
+
startedAt: number;
|
|
85
|
+
lastEventAt: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Aggregates provider.response + tool.executed events from the FleetBus
|
|
89
|
+
* into a live `FleetUsage` snapshot. Costs are computed by the caller
|
|
90
|
+
* via a `priceLookup(subagentId)` so we don't bake provider-pricing
|
|
91
|
+
* coupling into core; the CLI/tests supply a function that resolves
|
|
92
|
+
* each subagent's per-token rates from the models registry.
|
|
93
|
+
*/
|
|
94
|
+
declare class FleetUsageAggregator {
|
|
95
|
+
private readonly bus;
|
|
96
|
+
private readonly priceLookup?;
|
|
97
|
+
private readonly metaLookup?;
|
|
98
|
+
private readonly perSubagent;
|
|
99
|
+
private readonly total;
|
|
100
|
+
constructor(bus: FleetBus, priceLookup?: ((subagentId: string) => {
|
|
101
|
+
input?: number;
|
|
102
|
+
output?: number;
|
|
103
|
+
cacheRead?: number;
|
|
104
|
+
cacheWrite?: number;
|
|
105
|
+
} | undefined) | undefined, metaLookup?: ((subagentId: string) => {
|
|
106
|
+
provider?: string;
|
|
107
|
+
model?: string;
|
|
108
|
+
} | undefined) | undefined);
|
|
109
|
+
/** Live snapshot — safe to call from a tool's execute() body. */
|
|
110
|
+
snapshot(): FleetUsage;
|
|
111
|
+
private ensure;
|
|
112
|
+
private onProviderResponse;
|
|
113
|
+
private onToolExecuted;
|
|
114
|
+
private onIterationStarted;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Caller-supplied factory that builds an isolated `Agent` for a subagent.
|
|
119
|
+
* The factory MUST construct a fresh `Context` per call — sharing context
|
|
120
|
+
* between subagents defeats isolation. Each Agent should also use either
|
|
121
|
+
* its own `EventBus` or a forwarded view, so per-subagent metrics can be
|
|
122
|
+
* attributed correctly.
|
|
123
|
+
*/
|
|
124
|
+
type AgentFactory = (config: SubagentConfig) => Promise<AgentFactoryResult>;
|
|
125
|
+
interface AgentFactoryResult {
|
|
126
|
+
agent: Agent;
|
|
127
|
+
/** Event bus the factory wired to this agent — required for budget hookup. */
|
|
128
|
+
events: EventBus;
|
|
129
|
+
/**
|
|
130
|
+
* Optional cleanup hook invoked in the runner's `finally` block once
|
|
131
|
+
* the task ends (success, failure, abort — same exit path). Factories
|
|
132
|
+
* that own resources scoped to a single task (per-subagent JSONL
|
|
133
|
+
* writers, transient providers, throwaway containers) implement this
|
|
134
|
+
* to close them deterministically instead of relying on GC. Errors
|
|
135
|
+
* thrown here are swallowed so a flaky cleanup can't mask the task's
|
|
136
|
+
* real result.
|
|
137
|
+
*/
|
|
138
|
+
dispose?: () => Promise<void> | void;
|
|
139
|
+
}
|
|
140
|
+
interface AgentRunnerOptions {
|
|
141
|
+
factory: AgentFactory;
|
|
142
|
+
/**
|
|
143
|
+
* Format a TaskSpec into the user input the agent will receive. Defaults
|
|
144
|
+
* to `task.description ?? ''`. Override when subagents expect structured
|
|
145
|
+
* input (e.g. JSON contracts, role-prefixed prompts).
|
|
146
|
+
*/
|
|
147
|
+
formatTaskInput?: (task: TaskSpec, config: SubagentConfig) => AgentInput;
|
|
148
|
+
/**
|
|
149
|
+
* When set, the runner attaches the subagent's EventBus to this FleetBus
|
|
150
|
+
* on task start and detaches it when the task finishes. This is the
|
|
151
|
+
* injection seam that lets the TUI fleet panel observe subagent activity
|
|
152
|
+
* live — without it, FleetBus stays empty.
|
|
153
|
+
*/
|
|
154
|
+
fleetBus?: FleetBus;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Builds a `SubagentRunner` that drives a real `Agent` per task while honoring
|
|
158
|
+
* the coordinator's budget and abort signal. This is the production adapter —
|
|
159
|
+
* the coordinator's `runner` option in CLI/TUI assemblies points here.
|
|
160
|
+
*
|
|
161
|
+
* Lifecycle per task:
|
|
162
|
+
* 1. factory(config) → fresh Agent + EventBus.
|
|
163
|
+
* 2. Subscribe to events to feed the budget (tool calls, token usage).
|
|
164
|
+
* 3. Call agent.run(input, { signal }) — the coordinator's signal cancels.
|
|
165
|
+
* 4. Map RunResult.status onto a `SubagentRunOutcome` or throw on failure.
|
|
166
|
+
* 5. Unsubscribe and let the factory's resources be GC'd.
|
|
167
|
+
*
|
|
168
|
+
* The budget is checked synchronously from event handlers — a runaway agent
|
|
169
|
+
* that crosses its tool-call limit triggers `BudgetExceededError`, which the
|
|
170
|
+
* coordinator surfaces as `status: 'failed'` on the task result.
|
|
171
|
+
*/
|
|
172
|
+
declare function makeAgentSubagentRunner(opts: AgentRunnerOptions): SubagentRunner;
|
|
173
|
+
|
|
174
|
+
export { type AgentFactory as A, FleetBus as F, type SubagentUsageSnapshot as S, type AgentFactoryResult as a, type AgentRunnerOptions as b, type FleetEvent as c, type FleetHandler as d, type FleetUsage as e, FleetUsageAggregator as f, makeAgentSubagentRunner as m };
|
|
@@ -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-DN5v-uQX.js';
|
|
3
3
|
|
|
4
4
|
type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';
|
|
5
5
|
type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';
|
|
@@ -696,6 +696,12 @@ interface SessionStore {
|
|
|
696
696
|
resume(id: string): Promise<ResumedSession>;
|
|
697
697
|
list(limit?: number): Promise<SessionSummary[]>;
|
|
698
698
|
delete(id: string): Promise<void>;
|
|
699
|
+
/**
|
|
700
|
+
* Rewrite the session JSONL file to contain only a fresh session_start
|
|
701
|
+
* event, effectively clearing all conversation history for that session.
|
|
702
|
+
* Called by /clear to wipe persistent chat history.
|
|
703
|
+
*/
|
|
704
|
+
clearHistory(id: string): Promise<void>;
|
|
699
705
|
}
|
|
700
706
|
interface SessionWriter {
|
|
701
707
|
readonly id: string;
|
|
@@ -736,6 +742,11 @@ interface SessionWriter {
|
|
|
736
742
|
* Returns the number of events removed.
|
|
737
743
|
*/
|
|
738
744
|
truncateToCheckpoint(promptIndex: number): Promise<number>;
|
|
745
|
+
/**
|
|
746
|
+
* Clear the session transcript file, resetting the on-disk history.
|
|
747
|
+
* Called by /clear to wipe chat history from persistent storage.
|
|
748
|
+
*/
|
|
749
|
+
clearSession(): Promise<void>;
|
|
739
750
|
}
|
|
740
751
|
|
|
741
752
|
interface CacheStats {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
export { A as ALL_FLEET_AGENTS, a as AUDIT_LOG_AGENT,
|
|
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 {
|
|
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 DefaultMultiAgentCoordinator, d as DelegateHost, e as Director, f as DirectorPromptParts, g as DirectorSessionFactory, h as DirectorSessionFactoryOptions, F as FLEET_ROSTER, u as FleetCostCapError, j as FleetManager, k as FleetManagerOptions, l as FleetSpawnBudgetError, I as ICoordinator, m as IFleetManager, M as MultiAgentCoordinatorOptions, N as NULL_FLEET_BUS, R as REFACTOR_PLANNER_AGENT, S as SECURITY_SCANNER_AGENT, n as SubagentPromptParts, p as composeDirectorPrompt, q as composeSubagentPrompt, r as createDelegateTool, s as makeDirectorSessionFactory, t as rosterSummaryFromConfigs } from '../index-CXnWsGBp.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-D5IbASk_.js';
|
|
3
|
+
export { A as AgentFactory, a as AgentFactoryResult, b as AgentRunnerOptions, F as FleetBus, c as FleetEvent, d as FleetHandler, e as FleetUsage, f as FleetUsageAggregator, S as SubagentUsageSnapshot, m as makeAgentSubagentRunner } from '../agent-subagent-runner-DsSm9lKN.js';
|
|
4
|
+
export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-BBXK_ppx.js';
|
|
4
5
|
import '../director-state-BmYi3DGA.js';
|
|
5
|
-
import '../context-
|
|
6
|
-
import '../events-BHuIHekD.js';
|
|
6
|
+
import '../context-DN5v-uQX.js';
|
|
7
7
|
import 'node:events';
|
|
8
|
-
import '../
|
|
8
|
+
import '../events-CJqwQl8G.js';
|
|
9
|
+
import '../index-DcnXDPdY.js';
|
|
9
10
|
import '../logger-BMQgxvdy.js';
|
|
10
|
-
import '../system-prompt-
|
|
11
|
+
import '../system-prompt-gL06H9P4.js';
|
|
11
12
|
import '../observability-BhnVLBLS.js';
|
|
12
|
-
import '../secret-scrubber-
|
|
13
|
-
import '../config-
|
|
13
|
+
import '../secret-scrubber-CT7wefiO.js';
|
|
14
|
+
import '../config-DfC6g6KV.js';
|
|
14
15
|
import '../models-registry-Y2xbog0E.js';
|
|
@@ -832,7 +832,7 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
832
832
|
* is dispatched as a fire-and-forget promise.
|
|
833
833
|
*/
|
|
834
834
|
checkLimit(kind, used, limit) {
|
|
835
|
-
if (
|
|
835
|
+
if (!this._onThreshold) {
|
|
836
836
|
throw new BudgetExceededError(kind, limit, used);
|
|
837
837
|
}
|
|
838
838
|
const bus = this._events;
|
|
@@ -948,14 +948,18 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
948
948
|
}
|
|
949
949
|
}
|
|
950
950
|
/**
|
|
951
|
-
*
|
|
952
|
-
*
|
|
951
|
+
* Wall-clock budget check. Unlike other limits, timeout is treated as a
|
|
952
|
+
* warning-only event — it NEVER hard-stops the subagent. When the
|
|
953
|
+
* elapsed time exceeds timeoutMs, emits `budget.threshold_reached` with
|
|
954
|
+
* kind='timeout' so the Director can decide whether to extend or warn.
|
|
955
|
+
* Call this from the iteration loop so a hung tool gets a chance to
|
|
956
|
+
* negotiate more time before the coordinator's Promise.race kills it.
|
|
953
957
|
*/
|
|
954
958
|
checkTimeout() {
|
|
955
959
|
if (this.startTime === null || this.limits.timeoutMs === void 0) return;
|
|
956
960
|
const elapsed = Date.now() - this.startTime;
|
|
957
961
|
if (elapsed > this.limits.timeoutMs) {
|
|
958
|
-
|
|
962
|
+
void this.checkLimit("timeout", elapsed, this.limits.timeoutMs);
|
|
959
963
|
}
|
|
960
964
|
}
|
|
961
965
|
/** Returns true if a timeout has occurred without throwing. Useful for races. */
|
|
@@ -1151,10 +1155,10 @@ var FLEET_ROSTER = {
|
|
|
1151
1155
|
"security-scanner": SECURITY_SCANNER_AGENT
|
|
1152
1156
|
};
|
|
1153
1157
|
var FLEET_ROSTER_BUDGETS = {
|
|
1154
|
-
"audit-log": { timeoutMs:
|
|
1155
|
-
"bug-hunter": { timeoutMs:
|
|
1156
|
-
"refactor-planner": { timeoutMs:
|
|
1157
|
-
"security-scanner": { timeoutMs:
|
|
1158
|
+
"audit-log": { timeoutMs: 8 * 60 * 1e3, maxIterations: 150, maxToolCalls: 500 },
|
|
1159
|
+
"bug-hunter": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 },
|
|
1160
|
+
"refactor-planner": { timeoutMs: 12 * 60 * 1e3, maxIterations: 180, maxToolCalls: 550 },
|
|
1161
|
+
"security-scanner": { timeoutMs: 15 * 60 * 1e3, maxIterations: 200, maxToolCalls: 600 }
|
|
1158
1162
|
};
|
|
1159
1163
|
function applyRosterBudget(cfg) {
|
|
1160
1164
|
const defaultBudget = FLEET_ROSTER_BUDGETS[cfg.role ?? ""];
|
|
@@ -1294,6 +1298,33 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1294
1298
|
results() {
|
|
1295
1299
|
return this.completedResults;
|
|
1296
1300
|
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Wait for one or more tasks to complete and return their results.
|
|
1303
|
+
* If a task is already done when called, returns immediately.
|
|
1304
|
+
* Resolves to an array in the same order as `taskIds`.
|
|
1305
|
+
*/
|
|
1306
|
+
async awaitTasks(taskIds) {
|
|
1307
|
+
return Promise.all(
|
|
1308
|
+
taskIds.map((id) => {
|
|
1309
|
+
const cached = this.completedResults.find((r) => r.taskId === id);
|
|
1310
|
+
if (cached) return cached;
|
|
1311
|
+
return new Promise((resolve, reject) => {
|
|
1312
|
+
const timeout = setTimeout(() => {
|
|
1313
|
+
this.off("task.completed", handler);
|
|
1314
|
+
reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
|
|
1315
|
+
}, this.config.timeoutMs ?? 3e5);
|
|
1316
|
+
const handler = ({ result }) => {
|
|
1317
|
+
if (result.taskId === id) {
|
|
1318
|
+
clearTimeout(timeout);
|
|
1319
|
+
this.off("task.completed", handler);
|
|
1320
|
+
resolve(result);
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
this.on("task.completed", handler);
|
|
1324
|
+
});
|
|
1325
|
+
})
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1297
1328
|
/**
|
|
1298
1329
|
* Manual completion — for callers that drive subagents without a runner
|
|
1299
1330
|
* (e.g. external orchestrators). When a runner is configured the coordinator
|
|
@@ -1512,8 +1543,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
1512
1543
|
return;
|
|
1513
1544
|
}
|
|
1514
1545
|
if (decision === "throw" || decision === "stop") {
|
|
1515
|
-
|
|
1516
|
-
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
1546
|
+
armFor(Math.max(1e3, limit));
|
|
1517
1547
|
return;
|
|
1518
1548
|
}
|
|
1519
1549
|
if (decision.extend.timeoutMs !== void 0) {
|
|
@@ -2060,7 +2090,7 @@ var Director = class {
|
|
|
2060
2090
|
this.sessionWriter = opts.sessionWriter ?? null;
|
|
2061
2091
|
this.manifestDebounceMs = opts.manifestDebounceMs ?? 2e3;
|
|
2062
2092
|
this.maxFleetCostUsd = opts.directorBudget?.maxCostUsd ?? Number.POSITIVE_INFINITY;
|
|
2063
|
-
this.maxBudgetExtensions = opts.maxBudgetExtensions ??
|
|
2093
|
+
this.maxBudgetExtensions = opts.maxBudgetExtensions ?? 5;
|
|
2064
2094
|
this.sessionsRoot = opts.sessionsRoot;
|
|
2065
2095
|
this.directorRunId = opts.directorRunId ?? this.id;
|
|
2066
2096
|
this.stateCheckpoint = opts.stateCheckpointPath ? new DirectorStateCheckpoint(opts.stateCheckpointPath, {
|
|
@@ -2148,19 +2178,19 @@ var Director = class {
|
|
|
2148
2178
|
const extra = {};
|
|
2149
2179
|
switch (payload.kind) {
|
|
2150
2180
|
case "iterations":
|
|
2151
|
-
extra.maxIterations = Math.min(payload.used +
|
|
2181
|
+
extra.maxIterations = Math.min(payload.used + 100, 800);
|
|
2152
2182
|
break;
|
|
2153
2183
|
case "tool_calls":
|
|
2154
|
-
extra.maxToolCalls = Math.min(Math.ceil(payload.limit *
|
|
2184
|
+
extra.maxToolCalls = Math.min(Math.ceil(payload.limit * 2), 1500);
|
|
2155
2185
|
break;
|
|
2156
2186
|
case "tokens":
|
|
2157
|
-
extra.maxTokens = Math.min(Math.ceil(payload.limit *
|
|
2187
|
+
extra.maxTokens = Math.min(Math.ceil(payload.limit * 2), 8e5);
|
|
2158
2188
|
break;
|
|
2159
2189
|
case "cost":
|
|
2160
|
-
extra.maxCostUsd = Math.min(payload.limit *
|
|
2190
|
+
extra.maxCostUsd = Math.min(payload.limit * 2, 25);
|
|
2161
2191
|
break;
|
|
2162
2192
|
case "timeout":
|
|
2163
|
-
extra.timeoutMs = Math.min(Math.ceil(payload.limit *
|
|
2193
|
+
extra.timeoutMs = Math.min(Math.ceil(payload.limit * 2), 2 * 60 * 6e4);
|
|
2164
2194
|
break;
|
|
2165
2195
|
}
|
|
2166
2196
|
payload.extend(extra);
|
|
@@ -3009,10 +3039,22 @@ function makeAgentSubagentRunner(opts) {
|
|
|
3009
3039
|
events.on("iteration.started", () => {
|
|
3010
3040
|
try {
|
|
3011
3041
|
ctx.budget.recordIteration();
|
|
3012
|
-
ctx.budget.checkTimeout();
|
|
3013
3042
|
} catch (e) {
|
|
3014
3043
|
void onBudgetError(e);
|
|
3015
3044
|
}
|
|
3045
|
+
const u = ctx.budget.usage();
|
|
3046
|
+
const since = u.iterations - lastSummaryAtIteration;
|
|
3047
|
+
if (since >= SUMMARY_INTERVAL) {
|
|
3048
|
+
lastSummaryAtIteration = u.iterations;
|
|
3049
|
+
events.emit("subagent.iteration_summary", {
|
|
3050
|
+
subagentId: ctx.subagentId,
|
|
3051
|
+
iteration: u.iterations,
|
|
3052
|
+
toolCalls: u.toolCalls,
|
|
3053
|
+
costUsd: u.costUsd,
|
|
3054
|
+
currentTool: currentToolName,
|
|
3055
|
+
partialText: streamingTextAcc.trim() || void 0
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3016
3058
|
}),
|
|
3017
3059
|
// D3: cooperative timeout enforcement DURING a long tool call.
|
|
3018
3060
|
// The iteration-loop checkTimeout() only fires between agent
|
|
@@ -3035,6 +3077,18 @@ function makeAgentSubagentRunner(opts) {
|
|
|
3035
3077
|
}
|
|
3036
3078
|
})
|
|
3037
3079
|
);
|
|
3080
|
+
let currentToolName;
|
|
3081
|
+
let streamingTextAcc = "";
|
|
3082
|
+
let lastSummaryAtIteration = 0;
|
|
3083
|
+
const SUMMARY_INTERVAL = 25;
|
|
3084
|
+
unsub.push(
|
|
3085
|
+
events.on("tool.started", (e) => {
|
|
3086
|
+
currentToolName = e.name;
|
|
3087
|
+
}),
|
|
3088
|
+
events.on("provider.text_delta", (e) => {
|
|
3089
|
+
streamingTextAcc = (streamingTextAcc + e.text).slice(-200);
|
|
3090
|
+
})
|
|
3091
|
+
);
|
|
3038
3092
|
const onParentAbort = () => aborter.abort();
|
|
3039
3093
|
ctx.signal.addEventListener("abort", onParentAbort);
|
|
3040
3094
|
let result;
|
|
@@ -3051,7 +3105,21 @@ function makeAgentSubagentRunner(opts) {
|
|
|
3051
3105
|
}
|
|
3052
3106
|
}
|
|
3053
3107
|
}
|
|
3054
|
-
if (budgetError)
|
|
3108
|
+
if (budgetError) {
|
|
3109
|
+
if ("decision" in budgetError) {
|
|
3110
|
+
const decision = await budgetError.decision;
|
|
3111
|
+
if (decision === "stop") {
|
|
3112
|
+
budgetError = new BudgetExceededError(
|
|
3113
|
+
budgetError.kind,
|
|
3114
|
+
budgetError.limit,
|
|
3115
|
+
budgetError.used
|
|
3116
|
+
);
|
|
3117
|
+
} else {
|
|
3118
|
+
budgetError = null;
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
if (budgetError) throw budgetError;
|
|
3122
|
+
}
|
|
3055
3123
|
if (result.status === "failed") {
|
|
3056
3124
|
throw result.error instanceof Error ? result.error : new Error(String(result.error ?? "agent failed"));
|
|
3057
3125
|
}
|
|
@@ -3293,6 +3361,20 @@ var DefaultSessionStore = class {
|
|
|
3293
3361
|
await fsp4.unlink(path4.join(this.dir, `${id}.jsonl`));
|
|
3294
3362
|
await fsp4.unlink(path4.join(this.dir, `${id}.summary.json`)).catch(() => void 0);
|
|
3295
3363
|
}
|
|
3364
|
+
async clearHistory(id) {
|
|
3365
|
+
const file = path4.join(this.dir, `${id}.jsonl`);
|
|
3366
|
+
const meta = path4.join(this.dir, `${id}.summary.json`);
|
|
3367
|
+
const record = `${JSON.stringify({
|
|
3368
|
+
type: "session_start",
|
|
3369
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3370
|
+
id,
|
|
3371
|
+
model: "unknown",
|
|
3372
|
+
provider: "unknown"
|
|
3373
|
+
})}
|
|
3374
|
+
`;
|
|
3375
|
+
await fsp4.writeFile(file, record, "utf8");
|
|
3376
|
+
await fsp4.unlink(meta).catch(() => void 0);
|
|
3377
|
+
}
|
|
3296
3378
|
async summarize(id, mtime) {
|
|
3297
3379
|
try {
|
|
3298
3380
|
const data = await this.load(id);
|
|
@@ -3598,10 +3680,21 @@ var FileSessionWriter = class {
|
|
|
3598
3680
|
});
|
|
3599
3681
|
return removedCount;
|
|
3600
3682
|
}
|
|
3683
|
+
async clearSession() {
|
|
3684
|
+
if (!this.filePath) return;
|
|
3685
|
+
const record = `${JSON.stringify({
|
|
3686
|
+
type: "session_start",
|
|
3687
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3688
|
+
id: this.id,
|
|
3689
|
+
model: this.meta.model ?? "unknown",
|
|
3690
|
+
provider: this.meta.provider ?? "unknown"
|
|
3691
|
+
})}
|
|
3692
|
+
`;
|
|
3693
|
+
await fsp4.writeFile(this.filePath, record, "utf8");
|
|
3694
|
+
}
|
|
3601
3695
|
};
|
|
3602
3696
|
function userInputTitle(content) {
|
|
3603
|
-
|
|
3604
|
-
const text = content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
3697
|
+
const text = typeof content === "string" ? content : content.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
3605
3698
|
return (text || "(non-text input)").slice(0, 60);
|
|
3606
3699
|
}
|
|
3607
3700
|
|