@directive-run/ai 1.12.0 → 1.14.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/anthropic.cjs +1 -1
- package/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.js.map +1 -1
- package/dist/{chunk-XV2QSBBE.cjs → chunk-2TD4ZSGZ.cjs} +7 -7
- package/dist/{chunk-XV2QSBBE.cjs.map → chunk-2TD4ZSGZ.cjs.map} +1 -1
- package/dist/chunk-3WO4MWJM.cjs +3 -0
- package/dist/chunk-3WO4MWJM.cjs.map +1 -0
- package/dist/chunk-5JQ2A3JK.js +2 -0
- package/dist/chunk-5JQ2A3JK.js.map +1 -0
- package/dist/chunk-A22KLB23.cjs +67 -0
- package/dist/chunk-A22KLB23.cjs.map +1 -0
- package/dist/chunk-A5K77UDX.cjs +4 -0
- package/dist/chunk-A5K77UDX.cjs.map +1 -0
- package/dist/chunk-DN5NAJM6.js +6 -0
- package/dist/chunk-DN5NAJM6.js.map +1 -0
- package/dist/chunk-FABDFT74.cjs +6 -0
- package/dist/chunk-FABDFT74.cjs.map +1 -0
- package/dist/chunk-FBT73WFY.js +2 -0
- package/dist/chunk-FBT73WFY.js.map +1 -0
- package/dist/chunk-FFRWQNK7.cjs +7 -0
- package/dist/chunk-FFRWQNK7.cjs.map +1 -0
- package/dist/chunk-IR3IHBVQ.cjs +2 -0
- package/dist/chunk-IR3IHBVQ.cjs.map +1 -0
- package/dist/chunk-IUGSMTBE.js +16 -0
- package/dist/{chunk-Q3PQLWBR.js.map → chunk-IUGSMTBE.js.map} +1 -1
- package/dist/chunk-J2Q5KKPN.js +37 -0
- package/dist/chunk-J2Q5KKPN.js.map +1 -0
- package/dist/chunk-K64WKZ22.cjs +2 -0
- package/dist/chunk-K64WKZ22.cjs.map +1 -0
- package/dist/chunk-LKY4K5TV.cjs +11 -0
- package/dist/chunk-LKY4K5TV.cjs.map +1 -0
- package/dist/chunk-LXUMJKGJ.js +67 -0
- package/dist/chunk-LXUMJKGJ.js.map +1 -0
- package/dist/chunk-NNAQ4ZH2.js +11 -0
- package/dist/chunk-NNAQ4ZH2.js.map +1 -0
- package/dist/chunk-PD772MSE.cjs +30 -0
- package/dist/chunk-PD772MSE.cjs.map +1 -0
- package/dist/chunk-POBEEJR6.js +30 -0
- package/dist/chunk-POBEEJR6.js.map +1 -0
- package/dist/chunk-QRXWLD6H.js +4 -0
- package/dist/chunk-QRXWLD6H.js.map +1 -0
- package/dist/chunk-UR4ZGO7V.js +7 -0
- package/dist/chunk-UR4ZGO7V.js.map +1 -0
- package/dist/chunk-UR5BMWEN.js +2 -0
- package/dist/chunk-UR5BMWEN.js.map +1 -0
- package/dist/chunk-WOFIBIPW.cjs +2 -0
- package/dist/chunk-WOFIBIPW.cjs.map +1 -0
- package/dist/chunk-XN5LUOVS.cjs +37 -0
- package/dist/chunk-XN5LUOVS.cjs.map +1 -0
- package/dist/chunk-ZFLHWJ56.js +3 -0
- package/dist/chunk-ZFLHWJ56.js.map +1 -0
- package/dist/debug-timeline-DpnRMnLU.d.cts +87 -0
- package/dist/debug-timeline-L13P-U2I.d.ts +87 -0
- package/dist/devtools.cjs +2 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +354 -0
- package/dist/devtools.d.ts +354 -0
- package/dist/devtools.js +2 -0
- package/dist/devtools.js.map +1 -0
- package/dist/evals.cjs +2 -0
- package/dist/evals.cjs.map +1 -0
- package/dist/evals.d.cts +361 -0
- package/dist/evals.d.ts +361 -0
- package/dist/evals.js +2 -0
- package/dist/evals.js.map +1 -0
- package/dist/gemini.cjs +1 -1
- package/dist/gemini.d.cts +1 -1
- package/dist/gemini.d.ts +1 -1
- package/dist/gemini.js +1 -1
- package/dist/gemini.js.map +1 -1
- package/dist/guardrails.cjs +2 -0
- package/dist/guardrails.cjs.map +1 -0
- package/dist/guardrails.d.cts +618 -0
- package/dist/guardrails.d.ts +618 -0
- package/dist/guardrails.js +2 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/health-monitor-C6xoXrQz.d.cts +55 -0
- package/dist/health-monitor-qL9RNMH3.d.ts +55 -0
- package/dist/index.cjs +21 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1202 -4542
- package/dist/index.d.ts +1202 -4542
- package/dist/index.js +21 -99
- package/dist/index.js.map +1 -1
- package/dist/mcp.cjs +2 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.cts +450 -0
- package/dist/mcp.d.ts +450 -0
- package/dist/mcp.js +2 -0
- package/dist/mcp.js.map +1 -0
- package/dist/multi-agent-orchestrator-QWWQKKGX.js +2 -0
- package/dist/{multi-agent-orchestrator-4PXNYRHB.js.map → multi-agent-orchestrator-QWWQKKGX.js.map} +1 -1
- package/dist/multi-agent-orchestrator-Y5U4JCFO.cjs +2 -0
- package/dist/{multi-agent-orchestrator-KFGTEGE5.cjs.map → multi-agent-orchestrator-Y5U4JCFO.cjs.map} +1 -1
- package/dist/multi-agent.cjs +2 -0
- package/dist/multi-agent.cjs.map +1 -0
- package/dist/multi-agent.d.cts +1429 -0
- package/dist/multi-agent.d.ts +1429 -0
- package/dist/multi-agent.js +2 -0
- package/dist/multi-agent.js.map +1 -0
- package/dist/ollama.cjs +1 -1
- package/dist/ollama.d.cts +1 -1
- package/dist/ollama.d.ts +1 -1
- package/dist/ollama.js +2 -2
- package/dist/ollama.js.map +1 -1
- package/dist/openai.cjs +1 -1
- package/dist/openai.d.cts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +1 -1
- package/dist/openai.js.map +1 -1
- package/dist/{orchestrator-types-CTfIKk0W.d.ts → orchestrator-types-DGBhL6mc.d.ts} +5 -138
- package/dist/{orchestrator-types-Bh8r3_Sq.d.cts → orchestrator-types-DeIMRLR7.d.cts} +5 -138
- package/dist/predicate.cjs +2 -0
- package/dist/predicate.cjs.map +1 -0
- package/dist/predicate.d.cts +371 -0
- package/dist/predicate.d.ts +371 -0
- package/dist/predicate.js +2 -0
- package/dist/predicate.js.map +1 -0
- package/dist/{semantic-cache-nBpQqILc.d.cts → semantic-cache-DM7ev7NQ.d.cts} +1 -1
- package/dist/{semantic-cache-nBpQqILc.d.ts → semantic-cache-DM7ev7NQ.d.ts} +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +4 -2
- package/dist/testing.d.ts +4 -2
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/{types-CRmwFnVk.d.cts → types-DJ09LjZX.d.cts} +1 -1
- package/dist/{types-CRmwFnVk.d.ts → types-DJ09LjZX.d.ts} +1 -1
- package/package.json +32 -2
- package/dist/chunk-Q3PQLWBR.js +0 -16
- package/dist/chunk-RW4R3O5P.js +0 -72
- package/dist/chunk-RW4R3O5P.js.map +0 -1
- package/dist/chunk-W6MVJKWN.cjs +0 -3
- package/dist/chunk-W6MVJKWN.cjs.map +0 -1
- package/dist/chunk-W6WZBQER.js +0 -3
- package/dist/chunk-W6WZBQER.js.map +0 -1
- package/dist/chunk-X3VQ5F7D.cjs +0 -72
- package/dist/chunk-X3VQ5F7D.cjs.map +0 -1
- package/dist/multi-agent-orchestrator-4PXNYRHB.js +0 -2
- package/dist/multi-agent-orchestrator-KFGTEGE5.cjs +0 -2
|
@@ -0,0 +1,1429 @@
|
|
|
1
|
+
import { a as MultiAgentOrchestratorOptions, M as MultiAgentOrchestrator, P as ParallelPattern, y as RacePattern, L as ReflectionEvaluation, F as ReflectIterationRecord, I as ReflectPattern, W as SequentialPattern, a3 as SupervisorPattern, i as ExecutionPattern, D as DebatePattern, f as AgentRegistry, Q as RunAgentRequirement, g as DebateResult } from './orchestrator-types-DeIMRLR7.cjs';
|
|
2
|
+
export { e as AgentRegistration, H as HandoffRequest, j as HandoffResult, s as MultiAgentRunCallOptions, t as MultiAgentState, z as RaceResult, C as RaceSuccessEntry, J as ReflectionConfig, K as ReflectionContext, R as ReflectionEvaluator, N as ReflectionExhaustedError, a4 as TaskContext, T as TaskRegistration, as as withReflection } from './orchestrator-types-DeIMRLR7.cjs';
|
|
3
|
+
import { aG as PatternCheckpointState, ah as CheckpointDiff, h as CheckpointStore, aj as CheckpointProgress, J as AgentSelectionStrategy, j as DagNode, D as DagExecutionContext, k as DagPattern, F as GoalNode, K as RelaxationTier, at as GoalMetrics, P as PatternCheckpointConfig, E as GoalPattern, q as RunResult, s as OrchestratorConstraint, L as GoalResult } from './types-DJ09LjZX.cjs';
|
|
4
|
+
export { z as BreakpointConfig, ab as BreakpointContext, B as BreakpointModifications, d as BreakpointRequest, ae as BreakpointState, af as BreakpointType, C as Checkpoint, ai as CheckpointLocalState, au as GoalStepMetrics, i as InMemoryCheckpointStore, aB as InMemoryCheckpointStoreOptions, aC as MAX_BREAKPOINT_HISTORY, $ as MultiAgentBreakpointType, aD as MultiAgentCheckpointLocalState, aO as RelaxationContext, aP as RelaxationRecord, aQ as RelaxationStrategy, aY as SingleAgentCheckpointLocalState, b2 as createBreakpointId, b3 as createCheckpointId, b4 as createInitialBreakpointState, b6 as matchBreakpoint, b7 as validateCheckpoint } from './types-DJ09LjZX.cjs';
|
|
5
|
+
import '@directive-run/core';
|
|
6
|
+
import '@directive-run/core/plugins';
|
|
7
|
+
import './debug-timeline-DpnRMnLU.cjs';
|
|
8
|
+
import './health-monitor-C6xoXrQz.cjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Async semaphore for controlling concurrent access.
|
|
12
|
+
* Uses a queue-based approach instead of polling for efficiency.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { Semaphore } from '@directive-run/ai';
|
|
17
|
+
*
|
|
18
|
+
* const sem = new Semaphore(3); // Allow 3 concurrent operations
|
|
19
|
+
*
|
|
20
|
+
* async function doWork() {
|
|
21
|
+
* const release = await sem.acquire();
|
|
22
|
+
* try {
|
|
23
|
+
* await performWork();
|
|
24
|
+
* } finally {
|
|
25
|
+
* release();
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare class Semaphore {
|
|
31
|
+
private count;
|
|
32
|
+
private readonly maxPermits;
|
|
33
|
+
private readonly queue;
|
|
34
|
+
constructor(max: number);
|
|
35
|
+
/** Create a one-shot release function that guards against double-release */
|
|
36
|
+
private createReleaseFn;
|
|
37
|
+
/** Acquire a permit, optionally with abort signal support */
|
|
38
|
+
acquire(signal?: AbortSignal): Promise<() => void>;
|
|
39
|
+
/** Non-blocking acquire — returns null if no permits available */
|
|
40
|
+
tryAcquire(): (() => void) | null;
|
|
41
|
+
private release;
|
|
42
|
+
/** Get current available permits */
|
|
43
|
+
get available(): number;
|
|
44
|
+
/** Get number of waiters in queue */
|
|
45
|
+
get waiting(): number;
|
|
46
|
+
/** Get maximum permits */
|
|
47
|
+
get max(): number;
|
|
48
|
+
/** Reject all pending waiters with an error and reset permits */
|
|
49
|
+
drain(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the current step/round/iteration count from a pattern checkpoint state.
|
|
53
|
+
*
|
|
54
|
+
* Maps each pattern type to its natural progress counter: `step` for sequential
|
|
55
|
+
* and goal, `round` for supervisor and debate, `iteration` for reflect, and
|
|
56
|
+
* `completedCount` for DAG.
|
|
57
|
+
*
|
|
58
|
+
* @param state - The pattern checkpoint state to inspect.
|
|
59
|
+
* @returns The current progress count for the pattern.
|
|
60
|
+
*/
|
|
61
|
+
declare function getPatternStep(state: PatternCheckpointState): number;
|
|
62
|
+
/**
|
|
63
|
+
* Compute progress metrics from a pattern checkpoint state.
|
|
64
|
+
*
|
|
65
|
+
* Returns percentage complete, steps completed/remaining, tokens consumed,
|
|
66
|
+
* and estimated tokens remaining (when computable). Each pattern type
|
|
67
|
+
* calculates these metrics from its own state structure.
|
|
68
|
+
*
|
|
69
|
+
* @param state - The pattern checkpoint state to analyze.
|
|
70
|
+
* @returns A {@link CheckpointProgress} object with completion metrics.
|
|
71
|
+
*/
|
|
72
|
+
declare function getCheckpointProgress(state: PatternCheckpointState): CheckpointProgress;
|
|
73
|
+
/**
|
|
74
|
+
* Compute the diff between two checkpoint states of the same pattern type.
|
|
75
|
+
*
|
|
76
|
+
* Returns the delta in steps, tokens, and time between checkpoints.
|
|
77
|
+
* Useful for understanding how much progress occurred between saves.
|
|
78
|
+
*
|
|
79
|
+
* @param a - The earlier checkpoint state.
|
|
80
|
+
* @param b - The later checkpoint state.
|
|
81
|
+
* @returns A {@link CheckpointDiff} with step, token, and time deltas.
|
|
82
|
+
* @throws If the two checkpoints have different pattern types.
|
|
83
|
+
*/
|
|
84
|
+
declare function diffCheckpoints(a: PatternCheckpointState, b: PatternCheckpointState): CheckpointDiff;
|
|
85
|
+
/**
|
|
86
|
+
* Fork an orchestrator from a checkpoint — creates a new independent orchestrator
|
|
87
|
+
* restored to the checkpoint's state, ready to diverge from that point.
|
|
88
|
+
*
|
|
89
|
+
* @param options - The original orchestrator options used to create the orchestrator
|
|
90
|
+
* @param checkpointStore - The checkpoint store containing the checkpoint
|
|
91
|
+
* @param checkpointId - The ID of the checkpoint to fork from
|
|
92
|
+
* @returns A new independent MultiAgentOrchestrator restored to checkpoint state
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const forked = await forkFromCheckpoint(orchestratorOptions, store, "ckpt_abc123");
|
|
97
|
+
* const result = await forked.replay("ckpt_abc123", pattern, { input: "new input" });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function forkFromCheckpoint(options: MultiAgentOrchestratorOptions, checkpointStore: CheckpointStore, checkpointId: string): Promise<MultiAgentOrchestrator>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create a parallel execution pattern that runs handlers concurrently and merges results.
|
|
104
|
+
*
|
|
105
|
+
* @param handlers - Handler IDs (agents or tasks) to run concurrently.
|
|
106
|
+
* @param merge - Combine all handler results into a single output (array may be shorter than handlers when `minSuccess` is set).
|
|
107
|
+
* @param options - Optional `minSuccess` and `timeout` overrides.
|
|
108
|
+
* @returns A {@link ParallelPattern} configuration object.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const researchPattern = parallel(
|
|
113
|
+
* ['researcher', 'researcher', 'researcher'],
|
|
114
|
+
* (results) => results.map(r => r.output).join('\n'),
|
|
115
|
+
* );
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare function parallel<T>(handlers: string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
|
|
119
|
+
minSuccess?: number;
|
|
120
|
+
timeout?: number;
|
|
121
|
+
}): ParallelPattern<T>;
|
|
122
|
+
/**
|
|
123
|
+
* Create a sequential execution pattern that pipes output from one handler to the next.
|
|
124
|
+
*
|
|
125
|
+
* @param handlers - Handler IDs (agents or tasks) to run in order, where each handler's output feeds as input to the next.
|
|
126
|
+
* @param options - Optional `transform`, `extract`, and `continueOnError` overrides.
|
|
127
|
+
* @returns A {@link SequentialPattern} configuration object.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const writeReviewPattern = sequential(
|
|
132
|
+
* ['writer', 'reviewer'],
|
|
133
|
+
* { transform: (output) => `Review this: ${output}` },
|
|
134
|
+
* );
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
declare function sequential<T>(handlers: string[], options?: {
|
|
138
|
+
transform?: (output: unknown, handlerId: string, index: number) => string;
|
|
139
|
+
extract?: (output: unknown) => T;
|
|
140
|
+
continueOnError?: boolean;
|
|
141
|
+
}): SequentialPattern<T>;
|
|
142
|
+
/**
|
|
143
|
+
* Create a supervisor pattern where a coordinating agent delegates work to a pool of workers.
|
|
144
|
+
*
|
|
145
|
+
* The supervisor runs first, then dispatches tasks to workers based on its output.
|
|
146
|
+
* This repeats for up to `maxRounds` until the supervisor signals completion.
|
|
147
|
+
*
|
|
148
|
+
* @param supervisorAgent - Agent ID that coordinates the workers.
|
|
149
|
+
* @param workers - Agent IDs for the worker pool.
|
|
150
|
+
* @param options - Optional `maxRounds` and `extract` overrides.
|
|
151
|
+
* @returns A {@link SupervisorPattern} configuration object.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const managedPattern = supervisor(
|
|
156
|
+
* 'manager',
|
|
157
|
+
* ['worker1', 'worker2'],
|
|
158
|
+
* { maxRounds: 3 },
|
|
159
|
+
* );
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
declare function supervisor<T>(supervisorAgent: string, workers: string[], options?: {
|
|
163
|
+
maxRounds?: number;
|
|
164
|
+
extract?: (supervisorOutput: unknown, workerResults: RunResult<unknown>[]) => T;
|
|
165
|
+
}): SupervisorPattern<T>;
|
|
166
|
+
/**
|
|
167
|
+
* Create a directed acyclic graph (DAG) execution pattern.
|
|
168
|
+
*
|
|
169
|
+
* Nodes run concurrently when their dependencies are satisfied. The runtime
|
|
170
|
+
* validates the graph is acyclic and that all dependency references are valid.
|
|
171
|
+
*
|
|
172
|
+
* @param nodes - Node definitions keyed by ID, each with a `handler` and optional `deps` array.
|
|
173
|
+
* @param merge - Combine DAG outputs into a single result (defaults to `context.outputs`).
|
|
174
|
+
* @param options - Optional `timeout`, `maxConcurrent`, and `onNodeError` strategy.
|
|
175
|
+
* @returns A {@link DagPattern} configuration object.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const researchPipeline = dag(
|
|
180
|
+
* {
|
|
181
|
+
* fetch: { handler: 'fetcher' },
|
|
182
|
+
* analyze: { handler: 'analyzer', deps: ['fetch'] },
|
|
183
|
+
* summarize: { handler: 'summarizer', deps: ['analyze'] },
|
|
184
|
+
* },
|
|
185
|
+
* (context) => context.outputs.summarize,
|
|
186
|
+
* );
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
declare function dag<T = Record<string, unknown>>(nodes: Record<string, DagNode>, merge?: (context: DagExecutionContext) => T | Promise<T>, options?: {
|
|
190
|
+
/** Overall timeout in ms for the entire DAG. */
|
|
191
|
+
timeout?: number;
|
|
192
|
+
/** Max nodes running concurrently. Default: Infinity */
|
|
193
|
+
maxConcurrent?: number;
|
|
194
|
+
/**
|
|
195
|
+
* Error handling strategy.
|
|
196
|
+
* - `"fail"` — abort entire DAG on first node error (default)
|
|
197
|
+
* - `"skip-downstream"` — mark downstream nodes as skipped, other branches continue
|
|
198
|
+
* - `"continue"` — ignore errors, other branches continue
|
|
199
|
+
*/
|
|
200
|
+
onNodeError?: "fail" | "skip-downstream" | "continue";
|
|
201
|
+
}): DagPattern<T>;
|
|
202
|
+
/**
|
|
203
|
+
* Create a reflect pattern that iterates between a producer and evaluator until quality is met.
|
|
204
|
+
*
|
|
205
|
+
* The producer generates output, then the evaluator scores it. If the score
|
|
206
|
+
* is below the threshold, the producer retries with evaluator feedback,
|
|
207
|
+
* up to `maxIterations` times.
|
|
208
|
+
*
|
|
209
|
+
* @param handler - Producer handler ID (agent or task) that generates output.
|
|
210
|
+
* @param evaluator - Evaluator handler ID that judges quality and provides feedback.
|
|
211
|
+
* @param options - Optional iteration, parsing, signal, and threshold configuration.
|
|
212
|
+
* @returns A {@link ReflectPattern} configuration object.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const reviewPattern = reflect('writer', 'reviewer', { maxIterations: 2 });
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
declare function reflect<T>(handler: string, evaluator: string, options?: {
|
|
220
|
+
maxIterations?: number;
|
|
221
|
+
parseEvaluation?: (output: unknown) => ReflectionEvaluation;
|
|
222
|
+
buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
|
|
223
|
+
extract?: (output: unknown) => T;
|
|
224
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
225
|
+
onIteration?: (record: ReflectIterationRecord) => void;
|
|
226
|
+
signal?: AbortSignal;
|
|
227
|
+
timeout?: number;
|
|
228
|
+
threshold?: number | ((iteration: number) => number);
|
|
229
|
+
}): ReflectPattern<T>;
|
|
230
|
+
/**
|
|
231
|
+
* Create a race pattern that runs handlers concurrently and returns the first successful result.
|
|
232
|
+
*
|
|
233
|
+
* All handlers start simultaneously. The first to complete successfully wins;
|
|
234
|
+
* remaining handlers are aborted. Use `minSuccess` to wait for N results before picking.
|
|
235
|
+
*
|
|
236
|
+
* @param handlers - Handler IDs (agents or tasks) to race concurrently.
|
|
237
|
+
* @param options - Optional `extract`, `timeout`, `minSuccess`, and `signal` overrides.
|
|
238
|
+
* @returns A {@link RacePattern} configuration object.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const fastest = race(['fast-model', 'smart-model'], { timeout: 5000 });
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
declare function race<T>(handlers: string[], options?: {
|
|
246
|
+
extract?: (result: RunResult<unknown>) => T;
|
|
247
|
+
timeout?: number;
|
|
248
|
+
minSuccess?: number;
|
|
249
|
+
signal?: AbortSignal;
|
|
250
|
+
}): RacePattern<T>;
|
|
251
|
+
/**
|
|
252
|
+
* Create a goal-driven execution pattern where agents are selected and run
|
|
253
|
+
* until a goal condition is satisfied.
|
|
254
|
+
*
|
|
255
|
+
* Declare what each agent produces and requires. The runtime automatically
|
|
256
|
+
* infers the execution graph from dependency analysis and drives agents
|
|
257
|
+
* toward goal achievement, with optional satisfaction scoring and relaxation tiers.
|
|
258
|
+
*
|
|
259
|
+
* @param nodes - Goal node definitions keyed by ID, each declaring `produces`, `requires`, and a `handler`.
|
|
260
|
+
* @param when - Predicate that returns `true` when the goal is achieved.
|
|
261
|
+
* @param options - Optional `satisfaction`, `maxSteps`, `extract`, `timeout`, `selectionStrategy`, and `relaxation` config.
|
|
262
|
+
* @returns A {@link GoalPattern} configuration object.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```typescript
|
|
266
|
+
* const pipeline = goal(
|
|
267
|
+
* {
|
|
268
|
+
* researcher: {
|
|
269
|
+
* handler: "researcher",
|
|
270
|
+
* produces: ["research.findings"],
|
|
271
|
+
* requires: ["research.topic"],
|
|
272
|
+
* extractOutput: (r) => ({ "research.findings": r.output }),
|
|
273
|
+
* },
|
|
274
|
+
* writer: {
|
|
275
|
+
* handler: "writer",
|
|
276
|
+
* produces: ["article.draft"],
|
|
277
|
+
* requires: ["research.findings"],
|
|
278
|
+
* extractOutput: (r) => ({ "article.draft": r.output }),
|
|
279
|
+
* },
|
|
280
|
+
* },
|
|
281
|
+
* (facts) => facts["article.draft"] != null,
|
|
282
|
+
* { maxSteps: 10, extract: (facts) => facts["article.draft"] },
|
|
283
|
+
* );
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
declare function goal<T = Record<string, unknown>>(nodes: Record<string, GoalNode>, when: (facts: Record<string, unknown>) => boolean, options?: {
|
|
287
|
+
satisfaction?: (facts: Record<string, unknown>) => number;
|
|
288
|
+
maxSteps?: number;
|
|
289
|
+
extract?: (facts: Record<string, unknown>) => T;
|
|
290
|
+
timeout?: number;
|
|
291
|
+
signal?: AbortSignal;
|
|
292
|
+
selectionStrategy?: AgentSelectionStrategy;
|
|
293
|
+
relaxation?: RelaxationTier[];
|
|
294
|
+
onStep?: (step: number, facts: Record<string, unknown>, readyNodes: string[]) => void;
|
|
295
|
+
onStall?: (step: number, metrics: GoalMetrics) => void;
|
|
296
|
+
checkpoint?: PatternCheckpointConfig;
|
|
297
|
+
}): GoalPattern<T>;
|
|
298
|
+
/**
|
|
299
|
+
* Create a selection strategy that runs all ready agents concurrently.
|
|
300
|
+
*
|
|
301
|
+
* This is the default strategy for {@link goal} patterns.
|
|
302
|
+
*
|
|
303
|
+
* @returns An {@link AgentSelectionStrategy} that selects every ready agent.
|
|
304
|
+
*/
|
|
305
|
+
declare function allReadyStrategy(): AgentSelectionStrategy;
|
|
306
|
+
/**
|
|
307
|
+
* Create a selection strategy that picks agents with the highest historical impact.
|
|
308
|
+
*
|
|
309
|
+
* Sorts ready agents by average satisfaction delta (descending) and selects the top N.
|
|
310
|
+
*
|
|
311
|
+
* @param opts - Optional `topN` to limit how many agents are selected (default: 3).
|
|
312
|
+
* @returns An {@link AgentSelectionStrategy} that prioritizes high-impact agents.
|
|
313
|
+
*/
|
|
314
|
+
declare function highestImpactStrategy(opts?: {
|
|
315
|
+
topN?: number;
|
|
316
|
+
}): AgentSelectionStrategy;
|
|
317
|
+
/**
|
|
318
|
+
* Create a selection strategy that prefers agents with lower token cost per satisfaction delta.
|
|
319
|
+
*
|
|
320
|
+
* Agents without historical metrics are prioritized first (to gather data).
|
|
321
|
+
*
|
|
322
|
+
* @returns An {@link AgentSelectionStrategy} that optimizes for cost efficiency.
|
|
323
|
+
*/
|
|
324
|
+
declare function costEfficientStrategy(): AgentSelectionStrategy;
|
|
325
|
+
|
|
326
|
+
/** Serialized DAG node (functions stripped) */
|
|
327
|
+
interface SerializedDagNode {
|
|
328
|
+
handler: string;
|
|
329
|
+
agent?: string;
|
|
330
|
+
deps?: string[];
|
|
331
|
+
timeout?: number;
|
|
332
|
+
priority?: number;
|
|
333
|
+
}
|
|
334
|
+
/** JSON-safe representation of any execution pattern (all functions stripped) */
|
|
335
|
+
type SerializedPattern = {
|
|
336
|
+
type: "parallel";
|
|
337
|
+
handlers: string[];
|
|
338
|
+
minSuccess?: number;
|
|
339
|
+
timeout?: number;
|
|
340
|
+
} | {
|
|
341
|
+
type: "sequential";
|
|
342
|
+
handlers: string[];
|
|
343
|
+
continueOnError?: boolean;
|
|
344
|
+
} | {
|
|
345
|
+
type: "supervisor";
|
|
346
|
+
supervisor: string;
|
|
347
|
+
workers: string[];
|
|
348
|
+
maxRounds?: number;
|
|
349
|
+
} | {
|
|
350
|
+
type: "dag";
|
|
351
|
+
nodes: Record<string, SerializedDagNode>;
|
|
352
|
+
timeout?: number;
|
|
353
|
+
maxConcurrent?: number;
|
|
354
|
+
onNodeError?: "fail" | "skip-downstream" | "continue";
|
|
355
|
+
} | {
|
|
356
|
+
type: "reflect";
|
|
357
|
+
handler: string;
|
|
358
|
+
evaluator: string;
|
|
359
|
+
maxIterations?: number;
|
|
360
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
361
|
+
timeout?: number;
|
|
362
|
+
threshold?: number;
|
|
363
|
+
} | {
|
|
364
|
+
type: "race";
|
|
365
|
+
handlers: string[];
|
|
366
|
+
timeout?: number;
|
|
367
|
+
minSuccess?: number;
|
|
368
|
+
} | {
|
|
369
|
+
type: "debate";
|
|
370
|
+
handlers: string[];
|
|
371
|
+
evaluator: string;
|
|
372
|
+
maxRounds?: number;
|
|
373
|
+
timeout?: number;
|
|
374
|
+
} | {
|
|
375
|
+
type: "goal";
|
|
376
|
+
nodes: Record<string, SerializedGoalNode>;
|
|
377
|
+
maxSteps?: number;
|
|
378
|
+
timeout?: number;
|
|
379
|
+
};
|
|
380
|
+
/** Serialized goal node (functions stripped) */
|
|
381
|
+
interface SerializedGoalNode {
|
|
382
|
+
handler: string;
|
|
383
|
+
agent?: string;
|
|
384
|
+
produces: string[];
|
|
385
|
+
requires?: string[];
|
|
386
|
+
allowRerun?: boolean;
|
|
387
|
+
priority?: number;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Serialize an execution pattern to a JSON-safe object.
|
|
391
|
+
*
|
|
392
|
+
* @remarks
|
|
393
|
+
* Strips all function callbacks and runtime objects (AbortSignal) while
|
|
394
|
+
* preserving the topology -- which agents, in what structure, with what
|
|
395
|
+
* numeric/string/boolean options.
|
|
396
|
+
*
|
|
397
|
+
* Use this for visual editors, LLM-generated plans, persistence, or
|
|
398
|
+
* debugging. Restore with {@link patternFromJSON}.
|
|
399
|
+
*
|
|
400
|
+
* Function-form `threshold` on reflect patterns is not serializable and will be dropped.
|
|
401
|
+
* Re-supply it via `overrides` when calling {@link patternFromJSON}.
|
|
402
|
+
*
|
|
403
|
+
* @param pattern - The execution pattern to serialize.
|
|
404
|
+
* @returns A {@link SerializedPattern} safe for `JSON.stringify`.
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```typescript
|
|
408
|
+
* const p = parallel(['a', 'b'], (r) => r);
|
|
409
|
+
* const json = patternToJSON(p);
|
|
410
|
+
* // { type: "parallel", handlers: ["a", "b"] }
|
|
411
|
+
* localStorage.setItem("plan", JSON.stringify(json));
|
|
412
|
+
* ```
|
|
413
|
+
*/
|
|
414
|
+
declare function patternToJSON(pattern: ExecutionPattern<unknown>): SerializedPattern;
|
|
415
|
+
/**
|
|
416
|
+
* Restore an execution pattern from its serialized JSON form.
|
|
417
|
+
*
|
|
418
|
+
* @remarks
|
|
419
|
+
* Returns the data structure with all function fields set to `undefined`.
|
|
420
|
+
* Supply callbacks via the optional `overrides` parameter to re-attach
|
|
421
|
+
* runtime behavior.
|
|
422
|
+
*
|
|
423
|
+
* @param json - The serialized pattern from {@link patternToJSON} or persisted storage.
|
|
424
|
+
* @param overrides - Optional partial pattern to re-attach function callbacks (e.g. `merge`, `extract`).
|
|
425
|
+
* @returns A fully typed {@link ExecutionPattern} ready for use with the imperative API.
|
|
426
|
+
* @throws If the pattern type is invalid or unknown.
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* ```typescript
|
|
430
|
+
* const json = JSON.parse(localStorage.getItem("plan")!);
|
|
431
|
+
* const pattern = patternFromJSON<string[]>(json, {
|
|
432
|
+
* merge: (results) => results.map(r => r.output as string),
|
|
433
|
+
* });
|
|
434
|
+
* if (pattern.type === "parallel") {
|
|
435
|
+
* const result = await orchestrator.runParallel(pattern.handlers, input, pattern.merge);
|
|
436
|
+
* }
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
declare function patternFromJSON<T = unknown>(json: SerializedPattern, overrides?: Partial<ExecutionPattern<T>>): ExecutionPattern<T>;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Create a constraint that routes to a specific agent when a condition is met.
|
|
443
|
+
*
|
|
444
|
+
* @param when - Predicate that triggers the constraint (may be async).
|
|
445
|
+
* @param agent - Agent ID or function returning an agent ID to route to.
|
|
446
|
+
* @param input - Input string or function returning the input for the selected agent.
|
|
447
|
+
* @param priority - Optional constraint priority (higher = evaluated first).
|
|
448
|
+
* @returns An {@link OrchestratorConstraint} that emits a `RUN_AGENT` requirement.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```typescript
|
|
452
|
+
* const constraints = {
|
|
453
|
+
* routeToExpert: selectAgent(
|
|
454
|
+
* (facts) => facts.complexity > 0.8,
|
|
455
|
+
* 'expert',
|
|
456
|
+
* (facts) => facts.query,
|
|
457
|
+
* ),
|
|
458
|
+
* };
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
declare function selectAgent(when: (facts: Record<string, unknown>) => boolean | Promise<boolean>, agent: string | ((facts: Record<string, unknown>) => string), input: string | ((facts: Record<string, unknown>) => string), priority?: number): OrchestratorConstraint<Record<string, unknown>>;
|
|
462
|
+
/**
|
|
463
|
+
* Create a `RUN_AGENT` requirement object for use in constraint `require()` functions.
|
|
464
|
+
*
|
|
465
|
+
* @param agent - The agent ID to run.
|
|
466
|
+
* @param input - The input string for the agent.
|
|
467
|
+
* @param context - Optional additional context passed to the agent runner.
|
|
468
|
+
* @returns A `RUN_AGENT` {@link RunAgentRequirement} object.
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```typescript
|
|
472
|
+
* constraints: {
|
|
473
|
+
* needsResearch: {
|
|
474
|
+
* when: (facts) => facts.hasUnknowns,
|
|
475
|
+
* require: (facts) => runAgentRequirement('researcher', facts.query as string),
|
|
476
|
+
* },
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
declare function runAgentRequirement(agent: string, input: string, context?: Record<string, unknown>): RunAgentRequirement;
|
|
481
|
+
/**
|
|
482
|
+
* Merge run results by concatenating their outputs into a single string.
|
|
483
|
+
*
|
|
484
|
+
* @param results - Array of run results to concatenate.
|
|
485
|
+
* @param separator - String inserted between outputs (default: `"\n\n"`).
|
|
486
|
+
* @returns The concatenated output string.
|
|
487
|
+
*/
|
|
488
|
+
declare function concatResults(results: RunResult<unknown>[], separator?: string): string;
|
|
489
|
+
/**
|
|
490
|
+
* Pick the highest-scoring result from an array using a scoring function.
|
|
491
|
+
*
|
|
492
|
+
* @param results - Array of run results to compare.
|
|
493
|
+
* @param score - Function that assigns a numeric score to each result (higher wins).
|
|
494
|
+
* @returns The {@link RunResult} with the highest score.
|
|
495
|
+
* @throws If the results array is empty.
|
|
496
|
+
*/
|
|
497
|
+
declare function pickBestResult<T>(results: RunResult<T>[], score: (result: RunResult<T>) => number): RunResult<T>;
|
|
498
|
+
/**
|
|
499
|
+
* Extract the `output` value from each run result into an array.
|
|
500
|
+
*
|
|
501
|
+
* @param results - Array of run results to collect from.
|
|
502
|
+
* @returns An array of output values in the same order as the input results.
|
|
503
|
+
*/
|
|
504
|
+
declare function collectOutputs<T>(results: RunResult<T>[]): T[];
|
|
505
|
+
/**
|
|
506
|
+
* Sum the total token counts from an array of run results.
|
|
507
|
+
*
|
|
508
|
+
* @param results - Array of run results to aggregate.
|
|
509
|
+
* @returns The total number of tokens consumed across all results.
|
|
510
|
+
*/
|
|
511
|
+
declare function aggregateTokens(results: RunResult<unknown>[]): number;
|
|
512
|
+
/**
|
|
513
|
+
* Compose multiple execution patterns into a pipeline where each pattern's
|
|
514
|
+
* output feeds as input to the next.
|
|
515
|
+
*
|
|
516
|
+
* @remarks
|
|
517
|
+
* Between patterns, output is converted to a string input:
|
|
518
|
+
* - `string` output passes through directly
|
|
519
|
+
* - Objects are JSON-stringified
|
|
520
|
+
* - Optionally provide a `transform` to customize between steps
|
|
521
|
+
*
|
|
522
|
+
* @param patterns - One or more execution patterns to chain together.
|
|
523
|
+
* @returns An async function that runs the pipeline on a given orchestrator.
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* const workflow = composePatterns(
|
|
528
|
+
* parallel(['researcher', 'researcher'], concatResults),
|
|
529
|
+
* sequential(['writer', 'reviewer']),
|
|
530
|
+
* );
|
|
531
|
+
*
|
|
532
|
+
* const result = await workflow(orchestrator, 'Research topic X');
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
declare function composePatterns(...patterns: ExecutionPattern[]): (orchestrator: MultiAgentOrchestrator, input: string) => Promise<unknown>;
|
|
536
|
+
/**
|
|
537
|
+
* Find agents in a registry that match all required capabilities.
|
|
538
|
+
*
|
|
539
|
+
* @param registry - The agent registry to search.
|
|
540
|
+
* @param requiredCapabilities - Capabilities that each matching agent must have.
|
|
541
|
+
* @returns An array of agent IDs whose `capabilities` include every required capability.
|
|
542
|
+
*
|
|
543
|
+
* @example
|
|
544
|
+
* ```typescript
|
|
545
|
+
* const agents = {
|
|
546
|
+
* researcher: { agent: researchAgent, capabilities: ['search', 'summarize'] },
|
|
547
|
+
* coder: { agent: coderAgent, capabilities: ['code', 'debug'] },
|
|
548
|
+
* writer: { agent: writerAgent, capabilities: ['write', 'edit'] },
|
|
549
|
+
* };
|
|
550
|
+
*
|
|
551
|
+
* const matches = findAgentsByCapability(agents, ['search']);
|
|
552
|
+
* // Returns ['researcher']
|
|
553
|
+
* ```
|
|
554
|
+
*/
|
|
555
|
+
declare function findAgentsByCapability(registry: AgentRegistry, requiredCapabilities: string[]): string[];
|
|
556
|
+
/**
|
|
557
|
+
* Create a constraint that auto-routes to an agent based on required capabilities.
|
|
558
|
+
*
|
|
559
|
+
* When the condition fires, it finds agents matching the capabilities returned by
|
|
560
|
+
* `getCapabilities`, then emits a `RUN_AGENT` requirement for the best match.
|
|
561
|
+
*
|
|
562
|
+
* @param registry - The agent registry to search for matching capabilities.
|
|
563
|
+
* @param getCapabilities - Function that extracts required capabilities from facts.
|
|
564
|
+
* @param getInput - Function that extracts the input string from facts.
|
|
565
|
+
* @param options - Optional `priority` and custom `select` function.
|
|
566
|
+
* @returns An {@link OrchestratorConstraint} that routes to a capability-matched agent.
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* const routeByCapability = capabilityRoute(
|
|
571
|
+
* agents,
|
|
572
|
+
* (facts) => facts.requiredCapabilities as string[],
|
|
573
|
+
* (facts) => facts.query as string,
|
|
574
|
+
* );
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
577
|
+
declare function capabilityRoute(registry: AgentRegistry, getCapabilities: (facts: Record<string, unknown>) => string[], getInput: (facts: Record<string, unknown>) => string, options?: {
|
|
578
|
+
priority?: number;
|
|
579
|
+
select?: (matches: string[], registry: AgentRegistry) => string;
|
|
580
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
581
|
+
/**
|
|
582
|
+
* Options for spawnOnCondition.
|
|
583
|
+
*/
|
|
584
|
+
interface SpawnOnConditionOptions {
|
|
585
|
+
/** Priority for the constraint (higher = evaluated first) */
|
|
586
|
+
priority?: number;
|
|
587
|
+
/** Additional context passed to the agent */
|
|
588
|
+
context?: Record<string, unknown>;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Create a constraint that auto-runs a single agent when a condition is met.
|
|
592
|
+
*
|
|
593
|
+
* The orchestrator's built-in `RUN_AGENT` resolver handles execution --
|
|
594
|
+
* you only need to add this to your `constraints` config.
|
|
595
|
+
*
|
|
596
|
+
* @param config - Condition, agent ID, input builder, and optional priority/context.
|
|
597
|
+
* @returns An {@link OrchestratorConstraint} that emits a `RUN_AGENT` requirement.
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* ```typescript
|
|
601
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
602
|
+
* agents: { reviewer: { agent: reviewerAgent } },
|
|
603
|
+
* constraints: {
|
|
604
|
+
* autoReview: spawnOnCondition({
|
|
605
|
+
* when: (facts) => (facts.confidence as number) < 0.7,
|
|
606
|
+
* agent: 'reviewer',
|
|
607
|
+
* input: (facts) => `Review this: ${facts.lastOutput}`,
|
|
608
|
+
* }),
|
|
609
|
+
* },
|
|
610
|
+
* });
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
613
|
+
declare function spawnOnCondition(config: {
|
|
614
|
+
when: (facts: Record<string, unknown>) => boolean;
|
|
615
|
+
agent: string;
|
|
616
|
+
input: (facts: Record<string, unknown>) => string;
|
|
617
|
+
/** Priority for the constraint (higher = evaluated first) */
|
|
618
|
+
priority?: number;
|
|
619
|
+
/** Additional context passed to the agent */
|
|
620
|
+
context?: Record<string, unknown>;
|
|
621
|
+
options?: SpawnOnConditionOptions;
|
|
622
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
623
|
+
/** Configuration for the debate() factory and runDebate() imperative API. @see DebatePattern */
|
|
624
|
+
type DebateConfig<T = unknown> = Omit<DebatePattern<T>, "type">;
|
|
625
|
+
/**
|
|
626
|
+
* Create a debate pattern where agents compete and an evaluator picks the best.
|
|
627
|
+
*
|
|
628
|
+
* @remarks
|
|
629
|
+
* Flow:
|
|
630
|
+
* 1. All agents produce proposals in parallel
|
|
631
|
+
* 2. Evaluator receives all proposals and picks a winner
|
|
632
|
+
* 3. Optionally repeat with evaluator feedback for refinement
|
|
633
|
+
*
|
|
634
|
+
* @param config - Debate configuration with `handlers`, `evaluator`, and optional settings.
|
|
635
|
+
* @returns A {@link DebatePattern} configuration object.
|
|
636
|
+
* @see {@link runDebate} for the imperative API
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* ```typescript
|
|
640
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
641
|
+
* agents: {
|
|
642
|
+
* optimist: { agent: optimistAgent },
|
|
643
|
+
* pessimist: { agent: pessimistAgent },
|
|
644
|
+
* judge: { agent: judgeAgent },
|
|
645
|
+
* },
|
|
646
|
+
* patterns: {
|
|
647
|
+
* debate: debate({
|
|
648
|
+
* handlers: ['optimist', 'pessimist'],
|
|
649
|
+
* evaluator: 'judge',
|
|
650
|
+
* maxRounds: 2,
|
|
651
|
+
* }),
|
|
652
|
+
* },
|
|
653
|
+
* });
|
|
654
|
+
*
|
|
655
|
+
* const result = await orchestrator.runPattern('debate', 'Should we invest in X?');
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
declare function debate<T = unknown>(config: DebateConfig<T>): DebatePattern<T>;
|
|
659
|
+
/**
|
|
660
|
+
* Run a debate imperatively on an orchestrator without pattern registration.
|
|
661
|
+
*
|
|
662
|
+
* Delegates to `orchestrator.runDebate()` so that lifecycle hooks, debug timeline,
|
|
663
|
+
* and signal propagation all work correctly.
|
|
664
|
+
*
|
|
665
|
+
* @param orchestrator - The multi-agent orchestrator instance to run the debate on.
|
|
666
|
+
* @param config - Debate configuration with agents, evaluator, and optional settings.
|
|
667
|
+
* @param input - The initial input/prompt for the debate.
|
|
668
|
+
* @returns The winning agent's output, the winner ID, and all proposals from each round.
|
|
669
|
+
* @see {@link debate} for the declarative pattern API
|
|
670
|
+
*/
|
|
671
|
+
declare function runDebate<T>(orchestrator: MultiAgentOrchestrator, config: DebateConfig<T>, input: string): Promise<DebateResult<T>>;
|
|
672
|
+
/**
|
|
673
|
+
* Create a constraint that fires when a cross-agent derivation meets a condition.
|
|
674
|
+
*
|
|
675
|
+
* @remarks
|
|
676
|
+
* Wire this into the orchestrator's `derive` config and `constraints` config together.
|
|
677
|
+
* The constraint's `when()` reads the derivation value from the orchestrator's derived snapshot.
|
|
678
|
+
*
|
|
679
|
+
* @param derivationId - The ID of the cross-agent derivation to watch.
|
|
680
|
+
* @param condition - Predicate that receives the derivation value and returns `true` when the constraint should fire.
|
|
681
|
+
* @param action - Agent ID, input builder, and optional priority/context for the emitted requirement.
|
|
682
|
+
* @returns An {@link OrchestratorConstraint} that emits a `RUN_AGENT` requirement when the derivation condition is met.
|
|
683
|
+
*
|
|
684
|
+
* @example
|
|
685
|
+
* ```typescript
|
|
686
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
687
|
+
* agents: { ... },
|
|
688
|
+
* derive: {
|
|
689
|
+
* totalCost: (snap) => snap.coordinator.globalTokens * 0.001,
|
|
690
|
+
* },
|
|
691
|
+
* constraints: {
|
|
692
|
+
* budgetAlert: derivedConstraint('totalCost', (cost) => cost > 5.0, {
|
|
693
|
+
* agent: 'budget-manager',
|
|
694
|
+
* input: (value) => `Budget exceeded: $${value}`,
|
|
695
|
+
* }),
|
|
696
|
+
* },
|
|
697
|
+
* });
|
|
698
|
+
* ```
|
|
699
|
+
*/
|
|
700
|
+
declare function derivedConstraint(derivationId: string, condition: (value: unknown) => boolean, action: {
|
|
701
|
+
agent: string;
|
|
702
|
+
input: (value: unknown) => string;
|
|
703
|
+
priority?: number;
|
|
704
|
+
context?: Record<string, unknown>;
|
|
705
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
706
|
+
/** Configuration for spawnPool constraint-driven auto-scaling */
|
|
707
|
+
interface SpawnPoolConfig {
|
|
708
|
+
/** Agent ID to spawn (must be registered in the orchestrator) */
|
|
709
|
+
agent: string;
|
|
710
|
+
/** Build the input for each spawned agent. Receives current facts and spawn index (0-based). */
|
|
711
|
+
input: (facts: Record<string, unknown>, index: number) => string;
|
|
712
|
+
/** How many agents to spawn. Number or function of facts for dynamic scaling. */
|
|
713
|
+
count: number | ((facts: Record<string, unknown>) => number);
|
|
714
|
+
/** Priority for the constraint. @default undefined */
|
|
715
|
+
priority?: number;
|
|
716
|
+
/** Additional context passed to each spawned agent */
|
|
717
|
+
context?: Record<string, unknown>;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Create a constraint that spawns a pool of agent instances when a condition is met.
|
|
721
|
+
*
|
|
722
|
+
* @remarks
|
|
723
|
+
* Unlike {@link spawnOnCondition} (which spawns one agent), `spawnPool` can target N agents.
|
|
724
|
+
* However, only one requirement is emitted per constraint evaluation cycle -- the constraint
|
|
725
|
+
* re-fires on subsequent cycles as long as `when()` returns true, spawning one agent per cycle.
|
|
726
|
+
*
|
|
727
|
+
* @param when - Predicate that triggers the pool spawn.
|
|
728
|
+
* @param config - Pool configuration with agent ID, input builder, count, and optional priority/context.
|
|
729
|
+
* @returns An {@link OrchestratorConstraint} that emits `RUN_AGENT` requirements.
|
|
730
|
+
* @see {@link spawnOnCondition} for spawning a single agent
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* ```typescript
|
|
734
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
735
|
+
* agents: { worker: { agent: workerAgent } },
|
|
736
|
+
* constraints: {
|
|
737
|
+
* scaleWorkers: spawnPool(
|
|
738
|
+
* (facts) => (facts.pendingTasks as number) > 0,
|
|
739
|
+
* {
|
|
740
|
+
* agent: 'worker',
|
|
741
|
+
* count: (facts) => Math.min(facts.pendingTasks as number, 5),
|
|
742
|
+
* input: (facts, i) => `Process task ${i + 1}`,
|
|
743
|
+
* },
|
|
744
|
+
* ),
|
|
745
|
+
* },
|
|
746
|
+
* });
|
|
747
|
+
* ```
|
|
748
|
+
*/
|
|
749
|
+
declare function spawnPool(when: (facts: Record<string, unknown>) => boolean, config: SpawnPoolConfig): OrchestratorConstraint<Record<string, unknown>>;
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Multi-Agent Orchestration Patterns
|
|
753
|
+
*
|
|
754
|
+
* Provides patterns for coordinating multiple AI agents:
|
|
755
|
+
* - Parallel execution with result merging
|
|
756
|
+
* - Sequential pipelines
|
|
757
|
+
* - Supervisor patterns with worker delegation
|
|
758
|
+
* - Constraint-driven agent selection
|
|
759
|
+
*
|
|
760
|
+
* @example
|
|
761
|
+
* ```typescript
|
|
762
|
+
* import { createMultiAgentOrchestrator } from '@directive-run/ai';
|
|
763
|
+
*
|
|
764
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
765
|
+
* agents: {
|
|
766
|
+
* researcher: { agent: researchAgent, maxConcurrent: 3 },
|
|
767
|
+
* writer: { agent: writerAgent, maxConcurrent: 1 },
|
|
768
|
+
* reviewer: { agent: reviewerAgent, maxConcurrent: 1 },
|
|
769
|
+
* },
|
|
770
|
+
* patterns: {
|
|
771
|
+
* parallelResearch: {
|
|
772
|
+
* type: 'parallel',
|
|
773
|
+
* handlers: ['researcher', 'researcher', 'researcher'],
|
|
774
|
+
* merge: (results) => combineResearch(results),
|
|
775
|
+
* },
|
|
776
|
+
* },
|
|
777
|
+
* });
|
|
778
|
+
* ```
|
|
779
|
+
*/
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* Create a multi-agent orchestrator backed by a Directive System.
|
|
783
|
+
*
|
|
784
|
+
* Each registered agent becomes a namespaced Directive module with reactive state,
|
|
785
|
+
* constraint evaluation, guardrails, streaming, approval, memory, retry, budget,
|
|
786
|
+
* hooks, and time-travel debugging -- all features at parity with {@link createAgentOrchestrator}.
|
|
787
|
+
*
|
|
788
|
+
* @param options - Orchestrator configuration including runner, agent registry, patterns, guardrails, and plugins.
|
|
789
|
+
* @returns A {@link MultiAgentOrchestrator} instance with `runAgent`, `runPattern`, `handoff`, and checkpoint APIs.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```typescript
|
|
793
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
794
|
+
* runner,
|
|
795
|
+
* agents: {
|
|
796
|
+
* researcher: { agent: researchAgent, maxConcurrent: 3 },
|
|
797
|
+
* writer: { agent: writerAgent },
|
|
798
|
+
* reviewer: { agent: reviewerAgent },
|
|
799
|
+
* },
|
|
800
|
+
* guardrails: {
|
|
801
|
+
* input: [createEnhancedPIIGuardrail()],
|
|
802
|
+
* output: [checkToxicity],
|
|
803
|
+
* },
|
|
804
|
+
* hooks: {
|
|
805
|
+
* onAgentStart: ({ agentId, input }) => console.log(`${agentId}: ${input}`),
|
|
806
|
+
* },
|
|
807
|
+
* maxTokenBudget: 50000,
|
|
808
|
+
* debug: true,
|
|
809
|
+
* });
|
|
810
|
+
*
|
|
811
|
+
* // Run with full guardrails + approval + streaming
|
|
812
|
+
* const result = await orchestrator.runAgent('researcher', 'What is AI?');
|
|
813
|
+
*
|
|
814
|
+
* // Stream agent output
|
|
815
|
+
* const { stream } = orchestrator.runAgentStream('writer', 'Write about AI');
|
|
816
|
+
* for await (const chunk of stream) {
|
|
817
|
+
* if (chunk.type === 'token') process.stdout.write(chunk.data);
|
|
818
|
+
* }
|
|
819
|
+
* ```
|
|
820
|
+
*
|
|
821
|
+
* @throws If a pattern references an agent that is not in the registry
|
|
822
|
+
* @throws If autoApproveToolCalls is false but no onApprovalRequest callback is provided
|
|
823
|
+
* @public
|
|
824
|
+
*/
|
|
825
|
+
declare function createMultiAgentOrchestrator(options: MultiAgentOrchestratorOptions): MultiAgentOrchestrator;
|
|
826
|
+
|
|
827
|
+
type MermaidDirection = "LR" | "TD" | "TB" | "RL" | "BT";
|
|
828
|
+
interface MermaidNodeShapes {
|
|
829
|
+
/** Shape for agent nodes. @default "square" */
|
|
830
|
+
agent?: "square" | "round" | "stadium" | "hexagon";
|
|
831
|
+
/** Shape for task nodes. @default "hexagon" */
|
|
832
|
+
task?: "square" | "round" | "stadium" | "hexagon";
|
|
833
|
+
/** Shape for virtual nodes (Input, Output, Merge). @default "circle" */
|
|
834
|
+
virtual?: "circle" | "square" | "round" | "stadium";
|
|
835
|
+
}
|
|
836
|
+
interface MermaidOptions {
|
|
837
|
+
/** Graph flow direction. @default "LR" */
|
|
838
|
+
direction?: MermaidDirection;
|
|
839
|
+
/** Emits %%{init}%% preamble when set. */
|
|
840
|
+
theme?: "default" | "dark" | "forest" | "neutral";
|
|
841
|
+
/** Node shape overrides. */
|
|
842
|
+
shapes?: MermaidNodeShapes;
|
|
843
|
+
/** Set of task IDs — used to render task nodes with distinct shapes. */
|
|
844
|
+
taskIds?: ReadonlySet<string>;
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Convert an execution pattern to a Mermaid diagram string.
|
|
848
|
+
*
|
|
849
|
+
* Accepts both runtime `ExecutionPattern` (with function callbacks) and
|
|
850
|
+
* pre-serialized `SerializedPattern`. Normalizes internally via `patternToJSON()`
|
|
851
|
+
* when it detects function-valued fields.
|
|
852
|
+
*
|
|
853
|
+
* @example
|
|
854
|
+
* ```typescript
|
|
855
|
+
* const p = dag({ fetch: { handler: "fetcher" }, report: { handler: "reporter", deps: ["fetch"] } });
|
|
856
|
+
* console.log(patternToMermaid(p, { direction: "TD" }));
|
|
857
|
+
* // graph TD
|
|
858
|
+
* // fetch[fetcher]
|
|
859
|
+
* // fetch[fetcher] --> report[reporter]
|
|
860
|
+
* ```
|
|
861
|
+
*
|
|
862
|
+
* @throws If pattern type is not one of the 8 known types.
|
|
863
|
+
*/
|
|
864
|
+
declare function patternToMermaid(pattern: ExecutionPattern<unknown> | SerializedPattern, options?: MermaidOptions): string;
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Agent-to-Agent Communication Protocol
|
|
868
|
+
*
|
|
869
|
+
* Provides structured communication channels between agents for coordination,
|
|
870
|
+
* delegation, and knowledge sharing without central orchestration.
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* ```typescript
|
|
874
|
+
* import { createAgentNetwork, createMessageBus } from '@directive-run/ai';
|
|
875
|
+
*
|
|
876
|
+
* const messageBus = createMessageBus();
|
|
877
|
+
*
|
|
878
|
+
* const network = createAgentNetwork({
|
|
879
|
+
* bus: messageBus,
|
|
880
|
+
* agents: {
|
|
881
|
+
* researcher: { capabilities: ['search', 'analyze'] },
|
|
882
|
+
* writer: { capabilities: ['draft', 'edit'] },
|
|
883
|
+
* reviewer: { capabilities: ['review', 'approve'] },
|
|
884
|
+
* },
|
|
885
|
+
* });
|
|
886
|
+
*
|
|
887
|
+
* // Agents can send messages to each other
|
|
888
|
+
* await network.send('researcher', 'writer', {
|
|
889
|
+
* type: 'DELEGATION',
|
|
890
|
+
* task: 'Draft an article based on this research',
|
|
891
|
+
* context: { findings: [...] },
|
|
892
|
+
* });
|
|
893
|
+
* ```
|
|
894
|
+
*/
|
|
895
|
+
/** Base message structure */
|
|
896
|
+
interface AgentMessage {
|
|
897
|
+
id: string;
|
|
898
|
+
type: AgentMessageType;
|
|
899
|
+
from: string;
|
|
900
|
+
to: string | string[] | "*";
|
|
901
|
+
timestamp: number;
|
|
902
|
+
correlationId?: string;
|
|
903
|
+
replyTo?: string;
|
|
904
|
+
priority?: "low" | "normal" | "high" | "urgent";
|
|
905
|
+
ttlMs?: number;
|
|
906
|
+
metadata?: Record<string, unknown>;
|
|
907
|
+
}
|
|
908
|
+
/** Message types for agent communication */
|
|
909
|
+
type AgentMessageType = "REQUEST" | "RESPONSE" | "DELEGATION" | "DELEGATION_RESULT" | "QUERY" | "INFORM" | "SUBSCRIBE" | "UNSUBSCRIBE" | "UPDATE" | "ACK" | "NACK" | "PING" | "PONG" | "CUSTOM";
|
|
910
|
+
/** Request message */
|
|
911
|
+
interface RequestMessage extends AgentMessage {
|
|
912
|
+
type: "REQUEST";
|
|
913
|
+
action: string;
|
|
914
|
+
payload: Record<string, unknown>;
|
|
915
|
+
timeout?: number;
|
|
916
|
+
}
|
|
917
|
+
/** Response message */
|
|
918
|
+
interface ResponseMessage extends AgentMessage {
|
|
919
|
+
type: "RESPONSE";
|
|
920
|
+
success: boolean;
|
|
921
|
+
result?: unknown;
|
|
922
|
+
error?: string;
|
|
923
|
+
}
|
|
924
|
+
/** Delegation message */
|
|
925
|
+
interface DelegationMessage extends AgentMessage {
|
|
926
|
+
type: "DELEGATION";
|
|
927
|
+
task: string;
|
|
928
|
+
context: Record<string, unknown>;
|
|
929
|
+
constraints?: {
|
|
930
|
+
deadline?: number;
|
|
931
|
+
maxCost?: number;
|
|
932
|
+
requiredCapabilities?: string[];
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
/** Delegation result message */
|
|
936
|
+
interface DelegationResultMessage extends AgentMessage {
|
|
937
|
+
type: "DELEGATION_RESULT";
|
|
938
|
+
success: boolean;
|
|
939
|
+
result?: unknown;
|
|
940
|
+
error?: string;
|
|
941
|
+
metrics?: {
|
|
942
|
+
durationMs: number;
|
|
943
|
+
tokensUsed?: number;
|
|
944
|
+
cost?: number;
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
/** Query message */
|
|
948
|
+
interface QueryMessage extends AgentMessage {
|
|
949
|
+
type: "QUERY";
|
|
950
|
+
question: string;
|
|
951
|
+
context?: Record<string, unknown>;
|
|
952
|
+
}
|
|
953
|
+
/** Inform message */
|
|
954
|
+
interface InformMessage extends AgentMessage {
|
|
955
|
+
type: "INFORM";
|
|
956
|
+
topic: string;
|
|
957
|
+
content: unknown;
|
|
958
|
+
}
|
|
959
|
+
/** Subscribe message */
|
|
960
|
+
interface SubscribeMessage extends AgentMessage {
|
|
961
|
+
type: "SUBSCRIBE";
|
|
962
|
+
topics: string[];
|
|
963
|
+
}
|
|
964
|
+
/** Update message */
|
|
965
|
+
interface UpdateMessage extends AgentMessage {
|
|
966
|
+
type: "UPDATE";
|
|
967
|
+
topic: string;
|
|
968
|
+
content: unknown;
|
|
969
|
+
}
|
|
970
|
+
/** Union of all message types */
|
|
971
|
+
type TypedAgentMessage = RequestMessage | ResponseMessage | DelegationMessage | DelegationResultMessage | QueryMessage | InformMessage | SubscribeMessage | UpdateMessage | (AgentMessage & {
|
|
972
|
+
type: "UNSUBSCRIBE" | "ACK" | "NACK" | "PING" | "PONG" | "CUSTOM";
|
|
973
|
+
});
|
|
974
|
+
/** Message handler function */
|
|
975
|
+
type MessageHandler = (message: TypedAgentMessage) => void | Promise<void>;
|
|
976
|
+
/** Subscription to messages */
|
|
977
|
+
interface Subscription {
|
|
978
|
+
id: string;
|
|
979
|
+
agentId: string;
|
|
980
|
+
handler: MessageHandler;
|
|
981
|
+
filter?: MessageFilter;
|
|
982
|
+
unsubscribe: () => void;
|
|
983
|
+
}
|
|
984
|
+
/** Message filter criteria */
|
|
985
|
+
interface MessageFilter {
|
|
986
|
+
types?: AgentMessageType[];
|
|
987
|
+
from?: string | string[];
|
|
988
|
+
topics?: string[];
|
|
989
|
+
priority?: ("low" | "normal" | "high" | "urgent")[];
|
|
990
|
+
custom?: (message: TypedAgentMessage) => boolean;
|
|
991
|
+
}
|
|
992
|
+
/** Message bus configuration */
|
|
993
|
+
interface MessageBusConfig {
|
|
994
|
+
/** Maximum messages to retain in history */
|
|
995
|
+
maxHistory?: number;
|
|
996
|
+
/** Default TTL for messages */
|
|
997
|
+
defaultTtlMs?: number;
|
|
998
|
+
/** Maximum pending messages per offline agent (prevents unbounded queue growth) */
|
|
999
|
+
maxPendingPerAgent?: number;
|
|
1000
|
+
/** Enable message persistence */
|
|
1001
|
+
persistence?: MessagePersistence;
|
|
1002
|
+
/** Callback when message is delivered */
|
|
1003
|
+
onDelivery?: (message: TypedAgentMessage, recipients: string[]) => void;
|
|
1004
|
+
/** Callback when message delivery fails */
|
|
1005
|
+
onDeliveryError?: (message: TypedAgentMessage, error: Error) => void;
|
|
1006
|
+
}
|
|
1007
|
+
/** Message persistence interface */
|
|
1008
|
+
interface MessagePersistence {
|
|
1009
|
+
save(message: TypedAgentMessage): Promise<void>;
|
|
1010
|
+
load(agentId: string, since?: number): Promise<TypedAgentMessage[]>;
|
|
1011
|
+
delete(messageId: string): Promise<void>;
|
|
1012
|
+
clear(agentId?: string): Promise<void>;
|
|
1013
|
+
}
|
|
1014
|
+
/** Message bus instance */
|
|
1015
|
+
interface MessageBus {
|
|
1016
|
+
/** Publish a message */
|
|
1017
|
+
publish(message: Omit<TypedAgentMessage, "id" | "timestamp">): string;
|
|
1018
|
+
/** Subscribe to messages */
|
|
1019
|
+
subscribe(agentId: string, handler: MessageHandler, filter?: MessageFilter): Subscription;
|
|
1020
|
+
/** Get message history */
|
|
1021
|
+
getHistory(filter?: MessageFilter, limit?: number): TypedAgentMessage[];
|
|
1022
|
+
/** Get a specific message by ID */
|
|
1023
|
+
getMessage(id: string): TypedAgentMessage | undefined;
|
|
1024
|
+
/** Get pending messages for an agent */
|
|
1025
|
+
getPending(agentId: string): TypedAgentMessage[];
|
|
1026
|
+
/** Clear all messages and data */
|
|
1027
|
+
clear(): void;
|
|
1028
|
+
/** Destroy the message bus, clearing all data and subscriptions */
|
|
1029
|
+
destroy(): void;
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Create a message bus for agent communication.
|
|
1033
|
+
*
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```typescript
|
|
1036
|
+
* const bus = createMessageBus({ maxHistory: 1000 });
|
|
1037
|
+
*
|
|
1038
|
+
* // Subscribe to messages
|
|
1039
|
+
* bus.subscribe('writer', (msg) => {
|
|
1040
|
+
* console.log(`Writer received: ${msg.type}`);
|
|
1041
|
+
* });
|
|
1042
|
+
*
|
|
1043
|
+
* // Publish a message
|
|
1044
|
+
* bus.publish({
|
|
1045
|
+
* type: 'DELEGATION',
|
|
1046
|
+
* from: 'researcher',
|
|
1047
|
+
* to: 'writer',
|
|
1048
|
+
* task: 'Write summary',
|
|
1049
|
+
* context: { data: '...' },
|
|
1050
|
+
* });
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
1053
|
+
/**
|
|
1054
|
+
* Note: `publish()` is fire-and-forget -- it returns the message ID synchronously
|
|
1055
|
+
* before delivery completes. Use `onDelivery` / `onDeliveryError` callbacks in
|
|
1056
|
+
* config to track delivery status if needed.
|
|
1057
|
+
*/
|
|
1058
|
+
declare function createMessageBus(config?: MessageBusConfig): MessageBus;
|
|
1059
|
+
/** Agent registration info */
|
|
1060
|
+
interface AgentInfo {
|
|
1061
|
+
id: string;
|
|
1062
|
+
capabilities: string[];
|
|
1063
|
+
status: "online" | "offline" | "busy";
|
|
1064
|
+
lastSeen: number;
|
|
1065
|
+
metadata?: Record<string, unknown>;
|
|
1066
|
+
}
|
|
1067
|
+
/** Agent network configuration */
|
|
1068
|
+
interface AgentNetworkConfig {
|
|
1069
|
+
/** Message bus to use */
|
|
1070
|
+
bus: MessageBus;
|
|
1071
|
+
/** Registered agents */
|
|
1072
|
+
agents?: Record<string, Omit<AgentInfo, "id" | "lastSeen" | "status">>;
|
|
1073
|
+
/** Timeout for request-response patterns */
|
|
1074
|
+
defaultTimeout?: number;
|
|
1075
|
+
/** Callback when agent comes online */
|
|
1076
|
+
onAgentOnline?: (agentId: string) => void;
|
|
1077
|
+
/** Callback when agent goes offline */
|
|
1078
|
+
onAgentOffline?: (agentId: string) => void;
|
|
1079
|
+
}
|
|
1080
|
+
/** Agent network instance */
|
|
1081
|
+
interface AgentNetwork {
|
|
1082
|
+
/** Register an agent */
|
|
1083
|
+
register(id: string, info: Omit<AgentInfo, "id" | "lastSeen" | "status">): void;
|
|
1084
|
+
/** Unregister an agent */
|
|
1085
|
+
unregister(id: string): void;
|
|
1086
|
+
/** Get agent info */
|
|
1087
|
+
getAgent(id: string): AgentInfo | undefined;
|
|
1088
|
+
/** Get all agents */
|
|
1089
|
+
getAgents(): AgentInfo[];
|
|
1090
|
+
/** Find agents by capability */
|
|
1091
|
+
findByCapability(capability: string): AgentInfo[];
|
|
1092
|
+
/** Send a message */
|
|
1093
|
+
send(from: string, to: string | string[], message: Partial<TypedAgentMessage>): string;
|
|
1094
|
+
/** Send a request and wait for response */
|
|
1095
|
+
request(from: string, to: string, action: string, payload: Record<string, unknown>, timeout?: number): Promise<ResponseMessage>;
|
|
1096
|
+
/** Delegate a task */
|
|
1097
|
+
delegate(from: string, to: string, task: string, context: Record<string, unknown>): Promise<DelegationResultMessage>;
|
|
1098
|
+
/** Query an agent */
|
|
1099
|
+
query(from: string, to: string, question: string, context?: Record<string, unknown>): Promise<ResponseMessage>;
|
|
1100
|
+
/** Broadcast to all agents */
|
|
1101
|
+
broadcast(from: string, message: Partial<TypedAgentMessage>): string;
|
|
1102
|
+
/** Subscribe an agent to messages */
|
|
1103
|
+
listen(agentId: string, handler: MessageHandler, filter?: MessageFilter): Subscription;
|
|
1104
|
+
/** Get the message bus */
|
|
1105
|
+
getBus(): MessageBus;
|
|
1106
|
+
/** Destroy the network, clearing pending waiters and timers */
|
|
1107
|
+
destroy(): void;
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Create an agent network for coordinated communication.
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* ```typescript
|
|
1114
|
+
* const network = createAgentNetwork({
|
|
1115
|
+
* bus: createMessageBus(),
|
|
1116
|
+
* agents: {
|
|
1117
|
+
* researcher: { capabilities: ['search', 'summarize'] },
|
|
1118
|
+
* writer: { capabilities: ['draft', 'edit'] },
|
|
1119
|
+
* reviewer: { capabilities: ['review', 'approve'] },
|
|
1120
|
+
* },
|
|
1121
|
+
* });
|
|
1122
|
+
*
|
|
1123
|
+
* // Delegate a task
|
|
1124
|
+
* const result = await network.delegate(
|
|
1125
|
+
* 'researcher',
|
|
1126
|
+
* 'writer',
|
|
1127
|
+
* 'Write an article about AI safety',
|
|
1128
|
+
* { research: findingsData }
|
|
1129
|
+
* );
|
|
1130
|
+
*
|
|
1131
|
+
* // Query for information
|
|
1132
|
+
* const answer = await network.query(
|
|
1133
|
+
* 'writer',
|
|
1134
|
+
* 'reviewer',
|
|
1135
|
+
* 'Is this paragraph technically accurate?',
|
|
1136
|
+
* { text: '...' }
|
|
1137
|
+
* );
|
|
1138
|
+
* ```
|
|
1139
|
+
*/
|
|
1140
|
+
declare function createAgentNetwork(config: AgentNetworkConfig): AgentNetwork;
|
|
1141
|
+
/**
|
|
1142
|
+
* Create a request-response helper for handling incoming requests.
|
|
1143
|
+
*
|
|
1144
|
+
* @example
|
|
1145
|
+
* ```typescript
|
|
1146
|
+
* const responder = createResponder(network, 'writer');
|
|
1147
|
+
*
|
|
1148
|
+
* responder.onRequest('draft', async (payload) => {
|
|
1149
|
+
* const draft = await generateDraft(payload.topic);
|
|
1150
|
+
* return { success: true, result: draft };
|
|
1151
|
+
* });
|
|
1152
|
+
* ```
|
|
1153
|
+
*/
|
|
1154
|
+
declare function createResponder(network: AgentNetwork, agentId: string): {
|
|
1155
|
+
onRequest(action: string, handler: (payload: Record<string, unknown>) => Promise<{
|
|
1156
|
+
success: boolean;
|
|
1157
|
+
result?: unknown;
|
|
1158
|
+
error?: string;
|
|
1159
|
+
}>): void;
|
|
1160
|
+
/** Remove a request handler */
|
|
1161
|
+
offRequest(action: string): void;
|
|
1162
|
+
/** Destroy this responder, unsubscribing from network */
|
|
1163
|
+
destroy(): void;
|
|
1164
|
+
};
|
|
1165
|
+
/**
|
|
1166
|
+
* Create a task delegator for handling incoming delegations.
|
|
1167
|
+
*
|
|
1168
|
+
* @example
|
|
1169
|
+
* ```typescript
|
|
1170
|
+
* const delegator = createDelegator(network, 'writer');
|
|
1171
|
+
*
|
|
1172
|
+
* delegator.onDelegation(async (task, context) => {
|
|
1173
|
+
* const result = await executeTask(task, context);
|
|
1174
|
+
* return {
|
|
1175
|
+
* success: true,
|
|
1176
|
+
* result,
|
|
1177
|
+
* metrics: { durationMs: 1500, tokensUsed: 500 },
|
|
1178
|
+
* };
|
|
1179
|
+
* });
|
|
1180
|
+
* ```
|
|
1181
|
+
*/
|
|
1182
|
+
declare function createDelegator(network: AgentNetwork, agentId: string): {
|
|
1183
|
+
onDelegation(handler: (task: string, context: Record<string, unknown>) => Promise<{
|
|
1184
|
+
success: boolean;
|
|
1185
|
+
result?: unknown;
|
|
1186
|
+
error?: string;
|
|
1187
|
+
metrics?: {
|
|
1188
|
+
durationMs: number;
|
|
1189
|
+
tokensUsed?: number;
|
|
1190
|
+
cost?: number;
|
|
1191
|
+
};
|
|
1192
|
+
}>): void;
|
|
1193
|
+
/** Remove the delegation handler */
|
|
1194
|
+
offDelegation(): void;
|
|
1195
|
+
/** Destroy this delegator, unsubscribing from network */
|
|
1196
|
+
destroy(): void;
|
|
1197
|
+
};
|
|
1198
|
+
/**
|
|
1199
|
+
* Create a pub/sub helper for topic-based communication.
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* ```typescript
|
|
1203
|
+
* const pubsub = createPubSub(network, 'analyst');
|
|
1204
|
+
*
|
|
1205
|
+
* // Subscribe to topics
|
|
1206
|
+
* pubsub.subscribe(['market-updates', 'alerts'], (topic, content) => {
|
|
1207
|
+
* console.log(`Received ${topic}:`, content);
|
|
1208
|
+
* });
|
|
1209
|
+
*
|
|
1210
|
+
* // Publish to topics
|
|
1211
|
+
* pubsub.publish('market-updates', { price: 100, change: 5 });
|
|
1212
|
+
* ```
|
|
1213
|
+
*/
|
|
1214
|
+
declare function createPubSub(network: AgentNetwork, agentId: string): {
|
|
1215
|
+
subscribe(topics: string[], handler: (topic: string, content: unknown) => void): () => void;
|
|
1216
|
+
publish(topic: string, content: unknown): void;
|
|
1217
|
+
/** Destroy this pub/sub, unsubscribing from network and clearing handlers */
|
|
1218
|
+
destroy(): void;
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Standalone utilities for goal planning and validation.
|
|
1223
|
+
*
|
|
1224
|
+
* These functions work with the same `produces` / `requires` agent
|
|
1225
|
+
* declarations used by the goal pattern, without requiring an
|
|
1226
|
+
* orchestrator instance.
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```typescript
|
|
1230
|
+
* import { validateGoal, planGoal, getDependencyGraph } from '@directive-run/ai';
|
|
1231
|
+
*
|
|
1232
|
+
* const agents = {
|
|
1233
|
+
* fetcher: { produces: ['data'], requires: [] },
|
|
1234
|
+
* analyzer: { produces: ['analysis'], requires: ['data'] },
|
|
1235
|
+
* reporter: { produces: ['report'], requires: ['analysis'] },
|
|
1236
|
+
* };
|
|
1237
|
+
*
|
|
1238
|
+
* // Validate — cycle detection, missing deps, warnings
|
|
1239
|
+
* const validation = validateGoal(agents);
|
|
1240
|
+
*
|
|
1241
|
+
* // Plan — dry-run without executing agents
|
|
1242
|
+
* const plan = planGoal(agents, ['query']);
|
|
1243
|
+
*
|
|
1244
|
+
* // Graph — topological order, roots, leaves, edges
|
|
1245
|
+
* const graph = getDependencyGraph(agents);
|
|
1246
|
+
* ```
|
|
1247
|
+
*
|
|
1248
|
+
* @module
|
|
1249
|
+
*/
|
|
1250
|
+
|
|
1251
|
+
/** Minimal agent declaration for goal utilities (subset of GoalNode) */
|
|
1252
|
+
interface GoalAgentDeclaration {
|
|
1253
|
+
/** Fact keys this agent writes as output */
|
|
1254
|
+
produces: string[];
|
|
1255
|
+
/** Fact keys this agent reads as input */
|
|
1256
|
+
requires?: string[];
|
|
1257
|
+
}
|
|
1258
|
+
/** Edge in the inferred dependency graph */
|
|
1259
|
+
interface GoalDependencyEdge {
|
|
1260
|
+
from: string;
|
|
1261
|
+
to: string;
|
|
1262
|
+
/** Fact key that creates this dependency */
|
|
1263
|
+
factKey: string;
|
|
1264
|
+
}
|
|
1265
|
+
/** Inferred dependency graph from produces/requires analysis */
|
|
1266
|
+
interface GoalDependencyGraph {
|
|
1267
|
+
/** Agent IDs in topological order (roots first) */
|
|
1268
|
+
order: string[];
|
|
1269
|
+
/** Edges between agents */
|
|
1270
|
+
edges: GoalDependencyEdge[];
|
|
1271
|
+
/** Root agents (no unfulfilled requires from other agents) */
|
|
1272
|
+
roots: string[];
|
|
1273
|
+
/** Leaf agents (nothing depends on their produces) */
|
|
1274
|
+
leaves: string[];
|
|
1275
|
+
/** Map of fact key to agent ID that produces it */
|
|
1276
|
+
producers: Map<string, string>;
|
|
1277
|
+
}
|
|
1278
|
+
/** Validation result */
|
|
1279
|
+
interface GoalValidationResult {
|
|
1280
|
+
valid: boolean;
|
|
1281
|
+
errors: string[];
|
|
1282
|
+
warnings: string[];
|
|
1283
|
+
}
|
|
1284
|
+
/** A single step in an execution plan */
|
|
1285
|
+
interface GoalPlanStep {
|
|
1286
|
+
/** Step number (1-based) */
|
|
1287
|
+
step: number;
|
|
1288
|
+
/** Agent IDs that would run in this step (parallel) */
|
|
1289
|
+
agents: string[];
|
|
1290
|
+
/** Fact keys available at the start of this step */
|
|
1291
|
+
availableFacts: string[];
|
|
1292
|
+
/** Fact keys produced after this step completes */
|
|
1293
|
+
producedFacts: string[];
|
|
1294
|
+
}
|
|
1295
|
+
/** Result of a planGoal() dry-run */
|
|
1296
|
+
interface GoalExecutionPlan {
|
|
1297
|
+
/** Ordered steps showing which agents run when */
|
|
1298
|
+
steps: GoalPlanStep[];
|
|
1299
|
+
/** Agents that can never run (requires never satisfiable) */
|
|
1300
|
+
unreachableAgents: string[];
|
|
1301
|
+
/** Required fact keys that no agent produces (must be in initial facts) */
|
|
1302
|
+
externalDeps: string[];
|
|
1303
|
+
/** Whether the plan can potentially reach all agents */
|
|
1304
|
+
feasible: boolean;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Get the dependency graph for a set of agent declarations.
|
|
1308
|
+
*
|
|
1309
|
+
* Uses Kahn's algorithm (topological sort) to compute execution order
|
|
1310
|
+
* and detect circular dependencies.
|
|
1311
|
+
*
|
|
1312
|
+
* @throws If agents form a circular dependency or a fact key has multiple producers.
|
|
1313
|
+
*
|
|
1314
|
+
* @example
|
|
1315
|
+
* ```typescript
|
|
1316
|
+
* const graph = getDependencyGraph({
|
|
1317
|
+
* fetcher: { produces: ['data'], requires: [] },
|
|
1318
|
+
* analyzer: { produces: ['analysis'], requires: ['data'] },
|
|
1319
|
+
* });
|
|
1320
|
+
*
|
|
1321
|
+
* console.log(graph.order); // ['fetcher', 'analyzer']
|
|
1322
|
+
* console.log(graph.roots); // ['fetcher']
|
|
1323
|
+
* console.log(graph.leaves); // ['analyzer']
|
|
1324
|
+
* ```
|
|
1325
|
+
*/
|
|
1326
|
+
declare function getDependencyGraph(agents: Record<string, GoalAgentDeclaration>): GoalDependencyGraph;
|
|
1327
|
+
/**
|
|
1328
|
+
* Validate a set of agent declarations for goal execution.
|
|
1329
|
+
*
|
|
1330
|
+
* Checks for:
|
|
1331
|
+
* - Circular dependencies
|
|
1332
|
+
* - Duplicate producers (same fact key produced by multiple agents)
|
|
1333
|
+
* - Agents with no `produces` (will never contribute)
|
|
1334
|
+
* - Required fact keys that no agent produces (must be in initial facts)
|
|
1335
|
+
*
|
|
1336
|
+
* @example
|
|
1337
|
+
* ```typescript
|
|
1338
|
+
* const result = validateGoal({
|
|
1339
|
+
* fetcher: { produces: ['data'] },
|
|
1340
|
+
* analyzer: { produces: ['analysis'], requires: ['data'] },
|
|
1341
|
+
* });
|
|
1342
|
+
*
|
|
1343
|
+
* if (!result.valid) {
|
|
1344
|
+
* console.error(result.errors);
|
|
1345
|
+
* }
|
|
1346
|
+
* ```
|
|
1347
|
+
*/
|
|
1348
|
+
declare function validateGoal(agents: Record<string, GoalAgentDeclaration>): GoalValidationResult;
|
|
1349
|
+
/**
|
|
1350
|
+
* Dry-run goal execution to preview the plan without running agents.
|
|
1351
|
+
*
|
|
1352
|
+
* Shows which agents would run in each step, which facts would be produced,
|
|
1353
|
+
* and whether any agents are unreachable.
|
|
1354
|
+
*
|
|
1355
|
+
* @param agents - Agent declarations with produces/requires
|
|
1356
|
+
* @param initialFactKeys - Fact keys available at the start (not values, just keys)
|
|
1357
|
+
* @param maxSteps - Maximum steps to simulate (default: 50)
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
* ```typescript
|
|
1361
|
+
* const plan = planGoal(
|
|
1362
|
+
* {
|
|
1363
|
+
* fetcher: { produces: ['data'] },
|
|
1364
|
+
* analyzer: { produces: ['analysis'], requires: ['data'] },
|
|
1365
|
+
* reporter: { produces: ['report'], requires: ['analysis'] },
|
|
1366
|
+
* },
|
|
1367
|
+
* ['query'],
|
|
1368
|
+
* );
|
|
1369
|
+
*
|
|
1370
|
+
* console.log(plan.feasible); // true
|
|
1371
|
+
* console.log(plan.steps); // 3 steps: fetcher → analyzer → reporter
|
|
1372
|
+
* ```
|
|
1373
|
+
*/
|
|
1374
|
+
declare function planGoal(agents: Record<string, GoalAgentDeclaration>, initialFactKeys?: string[], maxSteps?: number): GoalExecutionPlan;
|
|
1375
|
+
/** A single line in a goal execution explanation */
|
|
1376
|
+
interface GoalExplanationStep {
|
|
1377
|
+
step: number;
|
|
1378
|
+
agents: string[];
|
|
1379
|
+
factsProduced: string[];
|
|
1380
|
+
satisfaction: number;
|
|
1381
|
+
satisfactionDelta: number;
|
|
1382
|
+
durationMs: number;
|
|
1383
|
+
tokensConsumed: number;
|
|
1384
|
+
/** Human-readable description of what happened */
|
|
1385
|
+
description: string;
|
|
1386
|
+
}
|
|
1387
|
+
/** Structured explanation of a goal execution */
|
|
1388
|
+
interface GoalExplanation {
|
|
1389
|
+
/** Whether the goal was achieved */
|
|
1390
|
+
achieved: boolean;
|
|
1391
|
+
/** Human-readable summary */
|
|
1392
|
+
summary: string;
|
|
1393
|
+
/** Per-step explanations */
|
|
1394
|
+
steps: GoalExplanationStep[];
|
|
1395
|
+
/** Relaxation events with descriptions */
|
|
1396
|
+
relaxations: Array<{
|
|
1397
|
+
step: number;
|
|
1398
|
+
label: string;
|
|
1399
|
+
strategy: string;
|
|
1400
|
+
description: string;
|
|
1401
|
+
}>;
|
|
1402
|
+
/** Total tokens consumed */
|
|
1403
|
+
totalTokens: number;
|
|
1404
|
+
/** Total duration (ms) */
|
|
1405
|
+
durationMs: number;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Generate a human-readable explanation of a goal execution result.
|
|
1409
|
+
*
|
|
1410
|
+
* Takes a `GoalResult` and returns a structured explanation of why each
|
|
1411
|
+
* agent ran, how satisfaction progressed, and what relaxations were applied.
|
|
1412
|
+
*
|
|
1413
|
+
* @example
|
|
1414
|
+
* ```typescript
|
|
1415
|
+
* const result = await orchestrator.runGoal(nodes, input, when, options);
|
|
1416
|
+
* const explanation = explainGoal(result);
|
|
1417
|
+
*
|
|
1418
|
+
* console.log(explanation.summary);
|
|
1419
|
+
* // "Goal achieved in 3 steps (1,247 tokens, 892ms). Satisfaction: 0 → 1."
|
|
1420
|
+
*
|
|
1421
|
+
* for (const step of explanation.steps) {
|
|
1422
|
+
* console.log(step.description);
|
|
1423
|
+
* // "Step 1: Ran fetcher. Produced: data. Satisfaction: 0 → 0.3 (+0.3)."
|
|
1424
|
+
* }
|
|
1425
|
+
* ```
|
|
1426
|
+
*/
|
|
1427
|
+
declare function explainGoal<T = unknown>(result: GoalResult<T>): GoalExplanation;
|
|
1428
|
+
|
|
1429
|
+
export { type AgentInfo, type AgentMessage, type AgentMessageType, type AgentNetwork, type AgentNetworkConfig, AgentRegistry, AgentSelectionStrategy, CheckpointStore, type DebateConfig, DebatePattern, DebateResult, type DelegationMessage, type DelegationResultMessage, ExecutionPattern, type GoalAgentDeclaration, type GoalDependencyEdge, type GoalDependencyGraph, type GoalExecutionPlan, type GoalExplanation, type GoalExplanationStep, GoalMetrics, GoalNode, GoalPattern, type GoalPlanStep, GoalResult, type GoalValidationResult, type InformMessage, type MermaidDirection, type MermaidNodeShapes, type MermaidOptions, type MessageBus, type MessageBusConfig, type MessageFilter, type MessageHandler, MultiAgentOrchestrator, MultiAgentOrchestratorOptions, ParallelPattern, type QueryMessage, RacePattern, ReflectIterationRecord, ReflectPattern, ReflectionEvaluation, RelaxationTier, type RequestMessage, type ResponseMessage, RunAgentRequirement, Semaphore, SequentialPattern, type SerializedDagNode, type SerializedGoalNode, type SerializedPattern, type SpawnOnConditionOptions, type SpawnPoolConfig, type Subscription, SupervisorPattern, type TypedAgentMessage, type UpdateMessage, aggregateTokens, allReadyStrategy, capabilityRoute, collectOutputs, composePatterns, concatResults, costEfficientStrategy, createAgentNetwork, createDelegator, createMessageBus, createMultiAgentOrchestrator, createPubSub, createResponder, dag, debate, derivedConstraint, diffCheckpoints, explainGoal, findAgentsByCapability, forkFromCheckpoint, getCheckpointProgress, getDependencyGraph, getPatternStep, goal, highestImpactStrategy, parallel, patternFromJSON, patternToJSON, patternToMermaid, pickBestResult, planGoal, race, reflect, runAgentRequirement, runDebate, selectAgent, sequential, spawnOnCondition, spawnPool, supervisor, validateGoal };
|