@directive-run/ai 0.2.0 → 0.3.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/README.md +26 -31
- package/dist/anthropic.cjs +1 -1
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.d.cts +5 -9
- package/dist/anthropic.d.ts +5 -9
- package/dist/anthropic.js +1 -1
- package/dist/anthropic.js.map +1 -1
- package/dist/gemini.cjs +3 -0
- package/dist/gemini.cjs.map +1 -0
- package/dist/gemini.d.cts +93 -0
- package/dist/gemini.d.ts +93 -0
- package/dist/gemini.js +3 -0
- package/dist/gemini.js.map +1 -0
- package/dist/index.cjs +117 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1376 -2106
- package/dist/index.d.ts +1376 -2106
- package/dist/index.js +117 -45
- package/dist/index.js.map +1 -1
- package/dist/multi-agent-orchestrator-CxL8ycw_.d.cts +2290 -0
- package/dist/multi-agent-orchestrator-uMp8bLfV.d.ts +2290 -0
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts +3 -2
- package/dist/ollama.d.ts +3 -2
- package/dist/ollama.js.map +1 -1
- package/dist/openai.cjs +2 -2
- package/dist/openai.cjs.map +1 -1
- package/dist/openai.d.cts +4 -8
- package/dist/openai.d.ts +4 -8
- package/dist/openai.js +2 -2
- package/dist/openai.js.map +1 -1
- package/dist/semantic-cache-F0psCRuz.d.cts +271 -0
- package/dist/semantic-cache-F0psCRuz.d.ts +271 -0
- package/dist/testing.cjs +42 -7
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +365 -5
- package/dist/testing.d.ts +365 -5
- package/dist/testing.js +42 -7
- package/dist/testing.js.map +1 -1
- package/dist/types-Co4BzMiH.d.cts +1373 -0
- package/dist/types-Co4BzMiH.d.ts +1373 -0
- package/package.json +7 -2
- package/dist/types-Bbar7yKz.d.cts +0 -304
- package/dist/types-Bbar7yKz.d.ts +0 -304
|
@@ -0,0 +1,2290 @@
|
|
|
1
|
+
import { M as Message$1, e as RunResult, A as AgentLike, G as GuardrailFn, O as OutputGuardrailData, aX as StreamingCallbackRunner, D as DebugEvent, a1 as DebugEventType, b as AgentRunner, aw as OrchestratorState, aq as NamedGuardrail, I as InputGuardrailData, C as Checkpoint, u as BreakpointModifications, v as BreakpointRequest, ar as OrchestratorConstraint, au as OrchestratorResolver, af as GuardrailsConfig, o as ApprovalRequest, as as OrchestratorDebugConfig, k as AgentRetryConfig, at as OrchestratorLifecycleHooks, aU as SelfHealingConfig, L as CheckpointStore, r as BreakpointConfig, ai as HealthMonitorConfig, R as RunOptions, T as ToolCallGuardrailData, ay as PatternCheckpointConfig, Z as DagPattern, a7 as GoalPattern, a6 as GoalNode, m as AgentSelectionStrategy, aL as RelaxationTier, f as GoalResult, a4 as GoalCheckpointState, aV as SequentialCheckpointState, aY as SupervisorCheckpointState, aF as ReflectCheckpointState, _ as DebateCheckpointState, U as DagCheckpointState, aS as Scratchpad, ao as MultiAgentLifecycleHooks, ap as MultiAgentSelfHealingConfig, am as MultiAgentBreakpointType, P as CrossAgentDerivationFn, W as DagNode, V as DagExecutionContext, az as PatternCheckpointState, E as CheckpointDiff, H as CheckpointProgress, a5 as GoalMetrics } from './types-Co4BzMiH.cjs';
|
|
2
|
+
import { Plugin, System, Requirement } from '@directive-run/core';
|
|
3
|
+
import { CircuitBreaker } from '@directive-run/core/plugins';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Agent Memory System
|
|
7
|
+
*
|
|
8
|
+
* Provides sliding window message management and automatic summarization
|
|
9
|
+
* for long-running agent conversations.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createAgentMemory, createSlidingWindowStrategy } from '@directive-run/ai';
|
|
14
|
+
*
|
|
15
|
+
* const memory = createAgentMemory({
|
|
16
|
+
* strategy: createSlidingWindowStrategy({ maxMessages: 50 }),
|
|
17
|
+
* summarizer: async (messages) => {
|
|
18
|
+
* // Call LLM to summarize older messages
|
|
19
|
+
* return await summarizeWithLLM(messages);
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Use with orchestrator
|
|
24
|
+
* const orchestrator = createAgentOrchestrator({
|
|
25
|
+
* memory,
|
|
26
|
+
* runner: run,
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Memory-compatible message type.
|
|
32
|
+
* Extends the standard Message type to include system messages for summaries.
|
|
33
|
+
*/
|
|
34
|
+
interface MemoryMessage {
|
|
35
|
+
role: "user" | "assistant" | "tool" | "system";
|
|
36
|
+
content: string;
|
|
37
|
+
toolCallId?: string;
|
|
38
|
+
}
|
|
39
|
+
type Message = MemoryMessage;
|
|
40
|
+
/** Configuration for memory management strategies */
|
|
41
|
+
interface MemoryStrategyConfig {
|
|
42
|
+
/** Maximum number of messages to keep in active memory */
|
|
43
|
+
maxMessages?: number;
|
|
44
|
+
/** Maximum total tokens to keep in active memory */
|
|
45
|
+
maxTokens?: number;
|
|
46
|
+
/** Number of recent messages to always keep (protected from summarization) */
|
|
47
|
+
preserveRecentCount?: number;
|
|
48
|
+
/** Whether to include system messages in token count */
|
|
49
|
+
countSystemMessages?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Result of a memory strategy evaluation */
|
|
52
|
+
interface MemoryStrategyResult {
|
|
53
|
+
/** Messages to keep in active memory */
|
|
54
|
+
keep: Message[];
|
|
55
|
+
/** Messages to summarize or discard */
|
|
56
|
+
toSummarize: Message[];
|
|
57
|
+
/** Estimated token count of kept messages */
|
|
58
|
+
estimatedTokens: number;
|
|
59
|
+
}
|
|
60
|
+
/** Memory management strategy function */
|
|
61
|
+
type MemoryStrategy = (messages: Message[], config: MemoryStrategyConfig) => MemoryStrategyResult;
|
|
62
|
+
/** Summarizer function to compress older messages */
|
|
63
|
+
type MessageSummarizer = (messages: Message[]) => Promise<string>;
|
|
64
|
+
/** Agent memory configuration */
|
|
65
|
+
interface AgentMemoryConfig {
|
|
66
|
+
/** Memory management strategy */
|
|
67
|
+
strategy: MemoryStrategy;
|
|
68
|
+
/** Optional summarizer for compressing old messages */
|
|
69
|
+
summarizer?: MessageSummarizer;
|
|
70
|
+
/** Strategy configuration */
|
|
71
|
+
strategyConfig?: MemoryStrategyConfig;
|
|
72
|
+
/** Whether to auto-manage memory after each interaction */
|
|
73
|
+
autoManage?: boolean;
|
|
74
|
+
/** Callback when memory is managed */
|
|
75
|
+
onMemoryManaged?: (result: MemoryManageResult) => void;
|
|
76
|
+
/** Callback when auto-manage encounters an error */
|
|
77
|
+
onManageError?: (error: Error) => void;
|
|
78
|
+
/** Maximum context window tokens (triggers additional summarization if exceeded) */
|
|
79
|
+
maxContextTokens?: number;
|
|
80
|
+
}
|
|
81
|
+
/** Result of memory management */
|
|
82
|
+
interface MemoryManageResult {
|
|
83
|
+
/** Number of messages before management */
|
|
84
|
+
messagesBefore: number;
|
|
85
|
+
/** Number of messages after management */
|
|
86
|
+
messagesAfter: number;
|
|
87
|
+
/** Number of messages summarized */
|
|
88
|
+
messagesSummarized: number;
|
|
89
|
+
/** The summary that was generated (if any) */
|
|
90
|
+
summary?: string;
|
|
91
|
+
/** Estimated tokens before */
|
|
92
|
+
estimatedTokensBefore: number;
|
|
93
|
+
/** Estimated tokens after */
|
|
94
|
+
estimatedTokensAfter: number;
|
|
95
|
+
}
|
|
96
|
+
/** Memory state for a conversation */
|
|
97
|
+
interface MemoryState {
|
|
98
|
+
/** Active messages in memory */
|
|
99
|
+
messages: Message[];
|
|
100
|
+
/** Summaries of older messages */
|
|
101
|
+
summaries: Array<{
|
|
102
|
+
content: string;
|
|
103
|
+
messagesCount: number;
|
|
104
|
+
createdAt: number;
|
|
105
|
+
}>;
|
|
106
|
+
/** Total messages ever processed */
|
|
107
|
+
totalMessagesProcessed: number;
|
|
108
|
+
/** Estimated current token count */
|
|
109
|
+
estimatedTokens: number;
|
|
110
|
+
}
|
|
111
|
+
/** Agent memory instance */
|
|
112
|
+
interface AgentMemory {
|
|
113
|
+
/** Get current memory state */
|
|
114
|
+
getState(): MemoryState;
|
|
115
|
+
/** Add a message to memory */
|
|
116
|
+
addMessage(message: Message): void;
|
|
117
|
+
/** Check if memory management is currently in progress */
|
|
118
|
+
isManaging(): boolean;
|
|
119
|
+
/** Add multiple messages to memory */
|
|
120
|
+
addMessages(messages: Message[]): void;
|
|
121
|
+
/** Get messages for context (includes summaries as system messages) */
|
|
122
|
+
getContextMessages(): Message[];
|
|
123
|
+
/** Manually trigger memory management */
|
|
124
|
+
manage(): Promise<MemoryManageResult>;
|
|
125
|
+
/** Clear all memory */
|
|
126
|
+
clear(): void;
|
|
127
|
+
/** Export memory state for persistence */
|
|
128
|
+
export(): MemoryState;
|
|
129
|
+
/** Import memory state from persistence */
|
|
130
|
+
import(state: MemoryState): void;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a sliding window memory strategy.
|
|
134
|
+
*
|
|
135
|
+
* Keeps the most recent N messages, moving older ones to summarization.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const strategy = createSlidingWindowStrategy({
|
|
140
|
+
* maxMessages: 50,
|
|
141
|
+
* preserveRecentCount: 10,
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
declare function createSlidingWindowStrategy(defaultConfig?: MemoryStrategyConfig): MemoryStrategy;
|
|
146
|
+
/**
|
|
147
|
+
* Create a token-based memory strategy.
|
|
148
|
+
*
|
|
149
|
+
* Keeps messages until a token limit is reached, then moves older ones to summarization.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const strategy = createTokenBasedStrategy({
|
|
154
|
+
* maxTokens: 4000,
|
|
155
|
+
* preserveRecentCount: 5,
|
|
156
|
+
* });
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
declare function createTokenBasedStrategy(defaultConfig?: MemoryStrategyConfig): MemoryStrategy;
|
|
160
|
+
/**
|
|
161
|
+
* Create a hybrid strategy that combines message count and token limits.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const strategy = createHybridStrategy({
|
|
166
|
+
* maxMessages: 50,
|
|
167
|
+
* maxTokens: 4000,
|
|
168
|
+
* preserveRecentCount: 5,
|
|
169
|
+
* });
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
declare function createHybridStrategy(defaultConfig?: MemoryStrategyConfig): MemoryStrategy;
|
|
173
|
+
/**
|
|
174
|
+
* Create an agent memory instance.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const memory = createAgentMemory({
|
|
179
|
+
* strategy: createSlidingWindowStrategy({ maxMessages: 50 }),
|
|
180
|
+
* summarizer: async (messages) => {
|
|
181
|
+
* const response = await openai.chat.completions.create({
|
|
182
|
+
* model: 'gpt-4o-mini',
|
|
183
|
+
* messages: [
|
|
184
|
+
* { role: 'system', content: 'Summarize the following conversation concisely.' },
|
|
185
|
+
* ...messages.map(m => ({ role: m.role, content: m.content })),
|
|
186
|
+
* ],
|
|
187
|
+
* });
|
|
188
|
+
* return response.choices[0].message.content;
|
|
189
|
+
* },
|
|
190
|
+
* autoManage: true,
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
declare function createAgentMemory(config: AgentMemoryConfig): AgentMemory;
|
|
195
|
+
/**
|
|
196
|
+
* Create a simple truncation "summarizer" that just returns key points.
|
|
197
|
+
* Useful for testing or when LLM summarization isn't needed.
|
|
198
|
+
*/
|
|
199
|
+
declare function createTruncationSummarizer(maxLength?: number): MessageSummarizer;
|
|
200
|
+
/**
|
|
201
|
+
* Create a summarizer that extracts only user questions and key assistant answers.
|
|
202
|
+
*/
|
|
203
|
+
declare function createKeyPointsSummarizer(): MessageSummarizer;
|
|
204
|
+
/**
|
|
205
|
+
* Create a summarizer factory for LLM-based summarization.
|
|
206
|
+
* You provide the LLM call function, this handles the prompt.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const summarizer = createLLMSummarizer(async (prompt) => {
|
|
211
|
+
* const response = await openai.chat.completions.create({
|
|
212
|
+
* model: 'gpt-4o-mini',
|
|
213
|
+
* messages: [{ role: 'user', content: prompt }],
|
|
214
|
+
* });
|
|
215
|
+
* return response.choices[0].message.content ?? '';
|
|
216
|
+
* });
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
declare function createLLMSummarizer(llmCall: (prompt: string) => Promise<string>, options?: {
|
|
220
|
+
maxSummaryLength?: number;
|
|
221
|
+
preserveKeyFacts?: boolean;
|
|
222
|
+
}): MessageSummarizer;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Agent Streaming - Token-by-token streaming with backpressure support
|
|
226
|
+
*
|
|
227
|
+
* Provides async iterators for streaming agent responses with guardrail evaluation
|
|
228
|
+
* on partial output and configurable backpressure handling.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* import { createAgentOrchestrator } from '@directive-run/ai';
|
|
233
|
+
* import { createStreamingRunner } from '@directive-run/ai';
|
|
234
|
+
*
|
|
235
|
+
* const { stream, result } = orchestrator.runStream(agent, input);
|
|
236
|
+
*
|
|
237
|
+
* for await (const chunk of stream) {
|
|
238
|
+
* if (chunk.type === 'token') process.stdout.write(chunk.data);
|
|
239
|
+
* if (chunk.type === 'guardrail_triggered') handleGuardrail(chunk);
|
|
240
|
+
* }
|
|
241
|
+
*
|
|
242
|
+
* const finalResult = await result;
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
|
|
246
|
+
/** Token chunk from streaming response */
|
|
247
|
+
interface TokenChunk {
|
|
248
|
+
type: "token";
|
|
249
|
+
data: string;
|
|
250
|
+
/** Running total of tokens received */
|
|
251
|
+
tokenCount: number;
|
|
252
|
+
}
|
|
253
|
+
/** Tool execution started */
|
|
254
|
+
interface ToolStartChunk {
|
|
255
|
+
type: "tool_start";
|
|
256
|
+
tool: string;
|
|
257
|
+
toolCallId: string;
|
|
258
|
+
arguments: string;
|
|
259
|
+
}
|
|
260
|
+
/** Tool execution completed */
|
|
261
|
+
interface ToolEndChunk {
|
|
262
|
+
type: "tool_end";
|
|
263
|
+
tool: string;
|
|
264
|
+
toolCallId: string;
|
|
265
|
+
result: string;
|
|
266
|
+
}
|
|
267
|
+
/** Message added to conversation */
|
|
268
|
+
interface MessageChunk {
|
|
269
|
+
type: "message";
|
|
270
|
+
message: Message$1;
|
|
271
|
+
}
|
|
272
|
+
/** Guardrail was triggered during streaming */
|
|
273
|
+
interface GuardrailTriggeredChunk {
|
|
274
|
+
type: "guardrail_triggered";
|
|
275
|
+
guardrailName: string;
|
|
276
|
+
reason: string;
|
|
277
|
+
/** Partial output at the time of trigger */
|
|
278
|
+
partialOutput: string;
|
|
279
|
+
/** Whether the stream was stopped */
|
|
280
|
+
stopped: boolean;
|
|
281
|
+
}
|
|
282
|
+
/** Progress update for UI feedback */
|
|
283
|
+
interface ProgressChunk {
|
|
284
|
+
type: "progress";
|
|
285
|
+
phase: "starting" | "generating" | "tool_calling" | "finishing";
|
|
286
|
+
/** Percentage complete (0-100), if known */
|
|
287
|
+
percent?: number;
|
|
288
|
+
/** Human-readable status message */
|
|
289
|
+
message?: string;
|
|
290
|
+
}
|
|
291
|
+
/** Stream completed */
|
|
292
|
+
interface DoneChunk {
|
|
293
|
+
type: "done";
|
|
294
|
+
totalTokens: number;
|
|
295
|
+
duration: number;
|
|
296
|
+
/** Number of tokens dropped due to backpressure (only with 'drop' strategy) */
|
|
297
|
+
droppedTokens: number;
|
|
298
|
+
}
|
|
299
|
+
/** Error during streaming */
|
|
300
|
+
interface ErrorChunk {
|
|
301
|
+
type: "error";
|
|
302
|
+
error: Error;
|
|
303
|
+
/** Partial output before error */
|
|
304
|
+
partialOutput?: string;
|
|
305
|
+
}
|
|
306
|
+
/** Union of all stream chunk types */
|
|
307
|
+
type StreamChunk = TokenChunk | ToolStartChunk | ToolEndChunk | MessageChunk | GuardrailTriggeredChunk | ProgressChunk | DoneChunk | ErrorChunk;
|
|
308
|
+
/** Backpressure strategy when consumer is slow */
|
|
309
|
+
type BackpressureStrategy =
|
|
310
|
+
/** Drop tokens when buffer is full (lossy, fast) */
|
|
311
|
+
"drop"
|
|
312
|
+
/** Block producer when buffer is full (lossless, may slow response) */
|
|
313
|
+
| "block"
|
|
314
|
+
/** Buffer all tokens (lossless, uses memory) */
|
|
315
|
+
| "buffer";
|
|
316
|
+
/** Streaming run options */
|
|
317
|
+
interface StreamRunOptions {
|
|
318
|
+
/** Maximum turns before stopping */
|
|
319
|
+
maxTurns?: number;
|
|
320
|
+
/** Abort signal for cancellation */
|
|
321
|
+
signal?: AbortSignal;
|
|
322
|
+
/** Backpressure strategy. @default "buffer" */
|
|
323
|
+
backpressure?: BackpressureStrategy;
|
|
324
|
+
/** Buffer size for 'drop' and 'block' strategies. @default 1000 */
|
|
325
|
+
bufferSize?: number;
|
|
326
|
+
/** Evaluate guardrails every N tokens. @default 50 */
|
|
327
|
+
guardrailCheckInterval?: number;
|
|
328
|
+
/** Stop stream on guardrail trigger. @default true */
|
|
329
|
+
stopOnGuardrail?: boolean | ((chunk: GuardrailTriggeredChunk) => boolean);
|
|
330
|
+
}
|
|
331
|
+
/** Stream run function type (mirrors OpenAI Agents streaming API) */
|
|
332
|
+
type StreamRunner = <T = unknown>(agent: AgentLike, input: string, options?: StreamRunOptions) => StreamingRunResult<T>;
|
|
333
|
+
/** Result from a streaming run */
|
|
334
|
+
interface StreamingRunResult<T = unknown> {
|
|
335
|
+
/** Async iterator for streaming chunks */
|
|
336
|
+
stream: AsyncIterable<StreamChunk>;
|
|
337
|
+
/** Promise that resolves to the final result */
|
|
338
|
+
result: Promise<RunResult<T>>;
|
|
339
|
+
/** Abort the stream */
|
|
340
|
+
abort: () => void;
|
|
341
|
+
}
|
|
342
|
+
/** Streaming guardrail that evaluates partial output */
|
|
343
|
+
interface StreamingGuardrail {
|
|
344
|
+
/** Unique name for this guardrail */
|
|
345
|
+
name: string;
|
|
346
|
+
/** Check partial output (called every guardrailCheckInterval tokens) */
|
|
347
|
+
check: (partialOutput: string, tokenCount: number) => StreamingGuardrailResult | Promise<StreamingGuardrailResult>;
|
|
348
|
+
/** Whether to stop the stream on failure. @default true */
|
|
349
|
+
stopOnFail?: boolean;
|
|
350
|
+
}
|
|
351
|
+
/** Result from a streaming guardrail check */
|
|
352
|
+
interface StreamingGuardrailResult {
|
|
353
|
+
passed: boolean;
|
|
354
|
+
reason?: string;
|
|
355
|
+
/** Severity level for UI display */
|
|
356
|
+
severity?: "warning" | "error" | "critical";
|
|
357
|
+
/** Warning message (guardrail passed but wants to emit a warning) */
|
|
358
|
+
warning?: string;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Create a streaming runner that wraps a base run function.
|
|
362
|
+
* This is used internally by the orchestrator but can be used standalone.
|
|
363
|
+
*
|
|
364
|
+
* @param baseRunner - The underlying non-streaming runner
|
|
365
|
+
* @param options - Configuration options
|
|
366
|
+
*/
|
|
367
|
+
declare function createStreamingRunner(baseRunner: StreamingCallbackRunner, options?: {
|
|
368
|
+
streamingGuardrails?: StreamingGuardrail[];
|
|
369
|
+
}): StreamRunner;
|
|
370
|
+
/**
|
|
371
|
+
* Create a streaming guardrail that detects toxic content.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* const toxicityGuardrail = createToxicityStreamingGuardrail({
|
|
376
|
+
* threshold: 0.9,
|
|
377
|
+
* checkFn: async (text) => myToxicityModel.score(text),
|
|
378
|
+
* });
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
declare function createToxicityStreamingGuardrail(options: {
|
|
382
|
+
/** Toxicity scoring function (returns 0-1) */
|
|
383
|
+
checkFn: (text: string) => number | Promise<number>;
|
|
384
|
+
/** Threshold above which content is flagged. @default 0.8 */
|
|
385
|
+
threshold?: number;
|
|
386
|
+
/** Stop the stream on detection. @default true */
|
|
387
|
+
stopOnFail?: boolean;
|
|
388
|
+
}): StreamingGuardrail;
|
|
389
|
+
/**
|
|
390
|
+
* Create a streaming guardrail that limits output length.
|
|
391
|
+
*
|
|
392
|
+
* @example
|
|
393
|
+
* ```typescript
|
|
394
|
+
* const lengthGuardrail = createLengthStreamingGuardrail({
|
|
395
|
+
* maxTokens: 4000,
|
|
396
|
+
* warnAt: 3500,
|
|
397
|
+
* });
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
declare function createLengthStreamingGuardrail(options: {
|
|
401
|
+
/** Maximum tokens before stopping */
|
|
402
|
+
maxTokens: number;
|
|
403
|
+
/** Warn at this token count (optional) */
|
|
404
|
+
warnAt?: number;
|
|
405
|
+
/** Stop the stream on max. @default true */
|
|
406
|
+
stopOnFail?: boolean;
|
|
407
|
+
}): StreamingGuardrail;
|
|
408
|
+
/**
|
|
409
|
+
* Create a streaming guardrail that detects patterns (regex-based).
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* ```typescript
|
|
413
|
+
* const piiGuardrail = createPatternStreamingGuardrail({
|
|
414
|
+
* patterns: [
|
|
415
|
+
* { regex: /\b\d{3}-\d{2}-\d{4}\b/, name: 'SSN' },
|
|
416
|
+
* { regex: /\b\d{16}\b/, name: 'Credit Card' },
|
|
417
|
+
* ],
|
|
418
|
+
* stopOnFail: true,
|
|
419
|
+
* });
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
declare function createPatternStreamingGuardrail(options: {
|
|
423
|
+
patterns: Array<{
|
|
424
|
+
regex: RegExp;
|
|
425
|
+
name: string;
|
|
426
|
+
}>;
|
|
427
|
+
stopOnFail?: boolean;
|
|
428
|
+
}): StreamingGuardrail;
|
|
429
|
+
/**
|
|
430
|
+
* Combine multiple streaming guardrails into one.
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```typescript
|
|
434
|
+
* const combined = combineStreamingGuardrails([
|
|
435
|
+
* createToxicityStreamingGuardrail({ ... }),
|
|
436
|
+
* createLengthStreamingGuardrail({ ... }),
|
|
437
|
+
* ]);
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
declare function combineStreamingGuardrails(guardrails: StreamingGuardrail[], options?: {
|
|
441
|
+
name?: string;
|
|
442
|
+
stopOnFirstFail?: boolean;
|
|
443
|
+
}): StreamingGuardrail;
|
|
444
|
+
/**
|
|
445
|
+
* Convert a regular output guardrail to a streaming guardrail.
|
|
446
|
+
* Useful for reusing existing guardrails in streaming context.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* const streamingPII = adaptOutputGuardrail(
|
|
451
|
+
* "pii-streaming",
|
|
452
|
+
* createPIIGuardrail({ redact: false }),
|
|
453
|
+
* { checkInterval: 100 }
|
|
454
|
+
* );
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
457
|
+
declare function adaptOutputGuardrail(name: string, guardrail: GuardrailFn<OutputGuardrailData>, options?: {
|
|
458
|
+
/** Only run after this many tokens (optimization) */
|
|
459
|
+
minTokens?: number;
|
|
460
|
+
stopOnFail?: boolean;
|
|
461
|
+
}): StreamingGuardrail;
|
|
462
|
+
/**
|
|
463
|
+
* Collect all tokens from a stream into a string.
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```typescript
|
|
467
|
+
* const { stream, result } = orchestrator.runStream(agent, input);
|
|
468
|
+
* const fullOutput = await collectTokens(stream);
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
declare function collectTokens(stream: AsyncIterable<StreamChunk>): Promise<string>;
|
|
472
|
+
/**
|
|
473
|
+
* Tap into a stream without consuming it.
|
|
474
|
+
* Useful for logging or side effects.
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const { stream } = orchestrator.runStream(agent, input);
|
|
479
|
+
* const tapped = tapStream(stream, (chunk) => console.log(chunk));
|
|
480
|
+
* for await (const chunk of tapped) { ... }
|
|
481
|
+
* ```
|
|
482
|
+
*/
|
|
483
|
+
declare function tapStream(stream: AsyncIterable<StreamChunk>, fn: (chunk: StreamChunk) => void | Promise<void>): AsyncIterable<StreamChunk>;
|
|
484
|
+
/**
|
|
485
|
+
* Filter stream chunks by type.
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* ```typescript
|
|
489
|
+
* const tokensOnly = filterStream(stream, ['token']);
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
declare function filterStream<T extends StreamChunk["type"]>(stream: AsyncIterable<StreamChunk>, types: T[]): AsyncIterable<Extract<StreamChunk, {
|
|
493
|
+
type: T;
|
|
494
|
+
}>>;
|
|
495
|
+
/**
|
|
496
|
+
* Transform stream chunks.
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```typescript
|
|
500
|
+
* const upperTokens = mapStream(stream, (chunk) => {
|
|
501
|
+
* if (chunk.type === 'token') return { ...chunk, data: chunk.data.toUpperCase() };
|
|
502
|
+
* return chunk;
|
|
503
|
+
* });
|
|
504
|
+
* ```
|
|
505
|
+
*/
|
|
506
|
+
declare function mapStream<R>(stream: AsyncIterable<StreamChunk>, fn: (chunk: StreamChunk) => R | Promise<R>): AsyncIterable<R>;
|
|
507
|
+
/** A multiplexed stream chunk tagged with the agent that produced it */
|
|
508
|
+
interface MultiplexedStreamChunk {
|
|
509
|
+
chunk: OrchestratorStreamChunk;
|
|
510
|
+
agentId: string;
|
|
511
|
+
}
|
|
512
|
+
/** Result from a parallel streaming operation */
|
|
513
|
+
interface MultiplexedStreamResult<T = unknown> {
|
|
514
|
+
stream: AsyncIterable<MultiplexedStreamChunk>;
|
|
515
|
+
results: Promise<RunResult<unknown>[]>;
|
|
516
|
+
merge: Promise<T>;
|
|
517
|
+
abort: () => void;
|
|
518
|
+
/** Number of chunks dropped due to buffer overflow */
|
|
519
|
+
getDroppedCount: () => number;
|
|
520
|
+
}
|
|
521
|
+
/** A source stream with its agent ID */
|
|
522
|
+
interface TaggedSource {
|
|
523
|
+
agentId: string;
|
|
524
|
+
stream: AsyncIterable<OrchestratorStreamChunk>;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Merge multiple async iterables into a single multiplexed stream,
|
|
528
|
+
* tagging each chunk with its source agent ID.
|
|
529
|
+
*
|
|
530
|
+
* Race-based merge: pulls from all sources concurrently, emitting
|
|
531
|
+
* chunks in arrival order. Error chunks from individual agents are
|
|
532
|
+
* tagged and emitted (other agents continue).
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```typescript
|
|
536
|
+
* const merged = mergeTaggedStreams([
|
|
537
|
+
* { agentId: "researcher", stream: researchStream },
|
|
538
|
+
* { agentId: "writer", stream: writerStream },
|
|
539
|
+
* ]);
|
|
540
|
+
*
|
|
541
|
+
* for await (const { chunk, agentId } of merged) {
|
|
542
|
+
* console.log(`[${agentId}]`, chunk);
|
|
543
|
+
* }
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
/** Result from mergeTaggedStreams */
|
|
547
|
+
interface MergedTaggedStreamResult {
|
|
548
|
+
stream: AsyncIterable<MultiplexedStreamChunk>;
|
|
549
|
+
/** Number of chunks dropped due to buffer overflow */
|
|
550
|
+
getDroppedCount: () => number;
|
|
551
|
+
}
|
|
552
|
+
declare function mergeTaggedStreams(sources: TaggedSource[]): MergedTaggedStreamResult;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Debug Timeline — AI-specific event log with snapshot correlation.
|
|
556
|
+
*
|
|
557
|
+
* Records agent lifecycle events (start, complete, error, guardrail checks,
|
|
558
|
+
* approvals, handoffs, patterns) and correlates them with core time-travel
|
|
559
|
+
* snapshots for visual timeline UIs and fork-and-replay debugging.
|
|
560
|
+
*
|
|
561
|
+
* Zero-cost when debug=false — the timeline is simply `null`.
|
|
562
|
+
*
|
|
563
|
+
* @module
|
|
564
|
+
*/
|
|
565
|
+
|
|
566
|
+
/** Callback fired when a new event is recorded */
|
|
567
|
+
type DebugTimelineListener = (event: DebugEvent) => void;
|
|
568
|
+
/** Debug timeline instance */
|
|
569
|
+
interface DebugTimeline {
|
|
570
|
+
/** Record a new event (id is auto-assigned) */
|
|
571
|
+
record(event: Omit<DebugEvent, "id"> & Record<string, unknown>): DebugEvent;
|
|
572
|
+
/** Get all events in order */
|
|
573
|
+
getEvents(): DebugEvent[];
|
|
574
|
+
/** Get events for a specific agent */
|
|
575
|
+
getEventsForAgent(agentId: string): DebugEvent[];
|
|
576
|
+
/** Get events by type with type narrowing */
|
|
577
|
+
getEventsByType<T extends DebugEventType>(type: T): Extract<DebugEvent, {
|
|
578
|
+
type: T;
|
|
579
|
+
}>[];
|
|
580
|
+
/** Get events at a specific snapshot */
|
|
581
|
+
getEventsAtSnapshot(snapshotId: number): DebugEvent[];
|
|
582
|
+
/** Get events in a time range */
|
|
583
|
+
getEventsInRange(startMs: number, endMs: number): DebugEvent[];
|
|
584
|
+
/** Fork from a snapshot — truncates events after it and calls goTo */
|
|
585
|
+
forkFrom(snapshotId: number): void;
|
|
586
|
+
/** Export timeline as JSON */
|
|
587
|
+
export(): string;
|
|
588
|
+
/** Import timeline from JSON */
|
|
589
|
+
import(json: string): void;
|
|
590
|
+
/** Clear all events */
|
|
591
|
+
clear(): void;
|
|
592
|
+
/** Subscribe to new events. Returns unsubscribe function. */
|
|
593
|
+
subscribe(listener: DebugTimelineListener): () => void;
|
|
594
|
+
/** Current number of events */
|
|
595
|
+
readonly length: number;
|
|
596
|
+
}
|
|
597
|
+
/** Options for creating a debug timeline */
|
|
598
|
+
interface DebugTimelineOptions {
|
|
599
|
+
/** Maximum events before eviction. @default 2000 */
|
|
600
|
+
maxEvents?: number;
|
|
601
|
+
/** Callback to get current snapshot ID from the system */
|
|
602
|
+
getSnapshotId?: () => number | null;
|
|
603
|
+
/** Callback to navigate to a snapshot (for forkFrom) */
|
|
604
|
+
goToSnapshot?: (snapshotId: number) => void;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Create a debug timeline for recording and correlating AI events.
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```typescript
|
|
611
|
+
* const timeline = createDebugTimeline({ maxEvents: 1000 });
|
|
612
|
+
*
|
|
613
|
+
* timeline.record({
|
|
614
|
+
* type: "agent_start",
|
|
615
|
+
* timestamp: Date.now(),
|
|
616
|
+
* agentId: "researcher",
|
|
617
|
+
* snapshotId: null,
|
|
618
|
+
* inputLength: 42,
|
|
619
|
+
* });
|
|
620
|
+
*
|
|
621
|
+
* const agentEvents = timeline.getEventsForAgent("researcher");
|
|
622
|
+
* ```
|
|
623
|
+
*/
|
|
624
|
+
declare function createDebugTimeline(options?: DebugTimelineOptions): DebugTimeline;
|
|
625
|
+
/**
|
|
626
|
+
* Create a Directive plugin that bridges core constraint/resolver events
|
|
627
|
+
* to the debug timeline.
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```typescript
|
|
631
|
+
* const timeline = createDebugTimeline();
|
|
632
|
+
* const plugin = createDebugTimelinePlugin(timeline, () => system.debug?.currentIndex ?? null);
|
|
633
|
+
* ```
|
|
634
|
+
*/
|
|
635
|
+
declare function createDebugTimelinePlugin(timeline: DebugTimeline, getSnapshotId: () => number | null): Plugin;
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* P6: Structured Outputs — Schema validation with auto-retry for LLM responses.
|
|
639
|
+
*
|
|
640
|
+
* Turns unreliable text output into typed, validated data. Appends JSON schema
|
|
641
|
+
* instructions to the system prompt and retries with error feedback on parse failure.
|
|
642
|
+
*
|
|
643
|
+
* Works with any Zod-compatible schema (any object with a `safeParse` method).
|
|
644
|
+
*
|
|
645
|
+
* @module
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```typescript
|
|
649
|
+
* import { z } from "zod";
|
|
650
|
+
* import { withStructuredOutput, StructuredOutputError } from '@directive-run/ai';
|
|
651
|
+
*
|
|
652
|
+
* const SentimentSchema = z.object({
|
|
653
|
+
* sentiment: z.enum(["positive", "negative", "neutral"]),
|
|
654
|
+
* confidence: z.number().min(0).max(1),
|
|
655
|
+
* });
|
|
656
|
+
*
|
|
657
|
+
* const runner = withStructuredOutput(baseRunner, {
|
|
658
|
+
* schema: SentimentSchema,
|
|
659
|
+
* maxRetries: 2,
|
|
660
|
+
* });
|
|
661
|
+
*
|
|
662
|
+
* const result = await runner(agent, "Analyze: I love this product!");
|
|
663
|
+
* // result.output is typed as { sentiment: string; confidence: number }
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Zod-compatible schema duck type — any object with a `safeParse` method.
|
|
669
|
+
*
|
|
670
|
+
* This interface allows structured outputs to work with Zod, Valibot,
|
|
671
|
+
* or any validation library that implements this pattern.
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* ```typescript
|
|
675
|
+
* import { z } from "zod";
|
|
676
|
+
*
|
|
677
|
+
* // Zod schemas implement SafeParseable automatically
|
|
678
|
+
* const schema = z.object({ name: z.string() });
|
|
679
|
+
*
|
|
680
|
+
* // Custom schema
|
|
681
|
+
* const custom: SafeParseable<{ name: string }> = {
|
|
682
|
+
* safeParse(value) {
|
|
683
|
+
* if (typeof value === "object" && value && "name" in value) {
|
|
684
|
+
* return { success: true, data: value as { name: string } };
|
|
685
|
+
* }
|
|
686
|
+
* return { success: false, error: { message: "Missing name field" } };
|
|
687
|
+
* },
|
|
688
|
+
* };
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
interface SafeParseable<T = unknown> {
|
|
692
|
+
safeParse(value: unknown): SafeParseResult<T>;
|
|
693
|
+
/** Optional: schema description injected into the system prompt. */
|
|
694
|
+
description?: string;
|
|
695
|
+
}
|
|
696
|
+
interface SafeParseResult<T> {
|
|
697
|
+
success: boolean;
|
|
698
|
+
data?: T;
|
|
699
|
+
error?: {
|
|
700
|
+
message?: string;
|
|
701
|
+
issues?: Array<{
|
|
702
|
+
message: string;
|
|
703
|
+
}>;
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
interface StructuredOutputConfig<T = unknown> {
|
|
707
|
+
/** Zod-compatible schema with safeParse. */
|
|
708
|
+
schema: SafeParseable<T>;
|
|
709
|
+
/** Max retries on parse/validation failure. @default 2 */
|
|
710
|
+
maxRetries?: number;
|
|
711
|
+
/** Custom JSON extractor. Default: finds first `{...}` or `[...]` in output. */
|
|
712
|
+
extractJson?: (output: string) => unknown;
|
|
713
|
+
/** Schema description to inject into system prompt. Auto-derived from schema.description if available. */
|
|
714
|
+
schemaDescription?: string;
|
|
715
|
+
}
|
|
716
|
+
/** Default JSON extractor — finds the first `{...}` or `[...]` in output. */
|
|
717
|
+
declare function extractJsonFromOutput(output: string): unknown;
|
|
718
|
+
/**
|
|
719
|
+
* Wrap an AgentRunner with structured output parsing and validation.
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```typescript
|
|
723
|
+
* import { z } from "zod";
|
|
724
|
+
*
|
|
725
|
+
* const SentimentSchema = z.object({
|
|
726
|
+
* sentiment: z.enum(["positive", "negative", "neutral"]),
|
|
727
|
+
* confidence: z.number().min(0).max(1),
|
|
728
|
+
* });
|
|
729
|
+
*
|
|
730
|
+
* const runner = withStructuredOutput(baseRunner, {
|
|
731
|
+
* schema: SentimentSchema,
|
|
732
|
+
* maxRetries: 2,
|
|
733
|
+
* });
|
|
734
|
+
*
|
|
735
|
+
* const result = await runner(agent, "Analyze: I love this product!");
|
|
736
|
+
* // result.output is typed as { sentiment: string; confidence: number }
|
|
737
|
+
* ```
|
|
738
|
+
*/
|
|
739
|
+
declare function withStructuredOutput<T = unknown>(runner: AgentRunner, config: StructuredOutputConfig<T>): AgentRunner;
|
|
740
|
+
/** Error thrown when structured output parsing fails after all retries. */
|
|
741
|
+
declare class StructuredOutputError extends Error {
|
|
742
|
+
readonly lastResult: RunResult<unknown> | undefined;
|
|
743
|
+
constructor(message: string, lastResult?: RunResult<unknown>);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/** Orchestrator options */
|
|
747
|
+
interface OrchestratorOptions<F extends Record<string, unknown>> {
|
|
748
|
+
/** Function to run an agent */
|
|
749
|
+
runner: AgentRunner;
|
|
750
|
+
/**
|
|
751
|
+
* Schema for custom facts tracked in the orchestrator's Directive System.
|
|
752
|
+
* @example
|
|
753
|
+
* ```typescript
|
|
754
|
+
* import { t } from '@directive-run/core';
|
|
755
|
+
* const orchestrator = createOrchestrator({
|
|
756
|
+
* factsSchema: { confidence: t.number(), category: t.string() },
|
|
757
|
+
* // ...
|
|
758
|
+
* });
|
|
759
|
+
* ```
|
|
760
|
+
*/
|
|
761
|
+
factsSchema?: Record<string, {
|
|
762
|
+
_type: unknown;
|
|
763
|
+
_validators: [];
|
|
764
|
+
}>;
|
|
765
|
+
/** Initialize additional facts */
|
|
766
|
+
init?: (facts: F & OrchestratorState) => void;
|
|
767
|
+
/** Constraints for orchestration */
|
|
768
|
+
constraints?: Record<string, OrchestratorConstraint<F>>;
|
|
769
|
+
/** Resolvers for orchestration */
|
|
770
|
+
resolvers?: Record<string, OrchestratorResolver<F, Requirement>>;
|
|
771
|
+
/** Guardrails */
|
|
772
|
+
guardrails?: GuardrailsConfig;
|
|
773
|
+
/** Callback for approval requests */
|
|
774
|
+
onApprovalRequest?: (request: ApprovalRequest) => void;
|
|
775
|
+
/**
|
|
776
|
+
* Auto-approve tool calls
|
|
777
|
+
* @default true
|
|
778
|
+
*/
|
|
779
|
+
autoApproveToolCalls?: boolean;
|
|
780
|
+
/**
|
|
781
|
+
* Maximum token budget across all agent runs.
|
|
782
|
+
*
|
|
783
|
+
* When exceeded, agents are automatically paused with status "paused".
|
|
784
|
+
* Check `facts.agent.tokenUsage` to see current usage.
|
|
785
|
+
*
|
|
786
|
+
* For more sophisticated cost management (per-user budgets, tiered pricing,
|
|
787
|
+
* cost alerts), see the Cost Management section in the documentation.
|
|
788
|
+
*
|
|
789
|
+
* @example
|
|
790
|
+
* ```typescript
|
|
791
|
+
* const orchestrator = createAgentOrchestrator({
|
|
792
|
+
* maxTokenBudget: 10000, // Pause after 10K tokens
|
|
793
|
+
* });
|
|
794
|
+
*
|
|
795
|
+
* // Check if paused due to budget
|
|
796
|
+
* if (orchestrator.facts.agent.status === 'paused') {
|
|
797
|
+
* console.log('Budget exceeded:', orchestrator.facts.agent.tokenUsage);
|
|
798
|
+
* }
|
|
799
|
+
* ```
|
|
800
|
+
*/
|
|
801
|
+
maxTokenBudget?: number;
|
|
802
|
+
/** Fires when token usage reaches this percentage of maxTokenBudget (0-1). @default 0.8 */
|
|
803
|
+
budgetWarningThreshold?: number;
|
|
804
|
+
/** Callback when budget warning threshold is reached */
|
|
805
|
+
onBudgetWarning?: (event: {
|
|
806
|
+
currentTokens: number;
|
|
807
|
+
maxBudget: number;
|
|
808
|
+
percentage: number;
|
|
809
|
+
}) => void;
|
|
810
|
+
/** Plugins */
|
|
811
|
+
plugins?: Plugin[];
|
|
812
|
+
/**
|
|
813
|
+
* Enable debugging — `true` for default debug, or config object for advanced options
|
|
814
|
+
* @default false
|
|
815
|
+
*/
|
|
816
|
+
debug?: boolean | OrchestratorDebugConfig;
|
|
817
|
+
/**
|
|
818
|
+
* Approval timeout in milliseconds
|
|
819
|
+
* @default 300000 (5 minutes)
|
|
820
|
+
*/
|
|
821
|
+
approvalTimeoutMs?: number;
|
|
822
|
+
/** Retry configuration for agent runs (no retries if not specified) */
|
|
823
|
+
agentRetry?: AgentRetryConfig;
|
|
824
|
+
/** Lifecycle hooks for observability */
|
|
825
|
+
hooks?: OrchestratorLifecycleHooks;
|
|
826
|
+
/**
|
|
827
|
+
* Optional memory instance. When provided, context messages are auto-injected
|
|
828
|
+
* into agent instructions before each run, and result messages are auto-stored.
|
|
829
|
+
*/
|
|
830
|
+
memory?: AgentMemory;
|
|
831
|
+
/**
|
|
832
|
+
* Optional circuit breaker. Wraps every run() call.
|
|
833
|
+
* When OPEN, throws CircuitBreakerOpenError instead of calling the agent.
|
|
834
|
+
*/
|
|
835
|
+
circuitBreaker?: CircuitBreaker;
|
|
836
|
+
/** Self-healing configuration for automatic fallback */
|
|
837
|
+
selfHealing?: SelfHealingConfig;
|
|
838
|
+
/**
|
|
839
|
+
* Default schema for structured output. When set, agent output is parsed and
|
|
840
|
+
* validated against this schema with automatic retry on failure.
|
|
841
|
+
* Any Zod-compatible schema (anything with `safeParse`) works.
|
|
842
|
+
*/
|
|
843
|
+
outputSchema?: SafeParseable<unknown>;
|
|
844
|
+
/**
|
|
845
|
+
* Max retries for structured output parsing.
|
|
846
|
+
* @default 2
|
|
847
|
+
*/
|
|
848
|
+
maxSchemaRetries?: number;
|
|
849
|
+
/** Optional checkpoint store for save/restore workflow state. */
|
|
850
|
+
checkpointStore?: CheckpointStore;
|
|
851
|
+
/**
|
|
852
|
+
* Breakpoint configurations for human-in-the-loop pause points.
|
|
853
|
+
* Zero overhead when empty — guard checks at each insertion point.
|
|
854
|
+
*/
|
|
855
|
+
breakpoints?: BreakpointConfig[];
|
|
856
|
+
/** Callback fired when a breakpoint is hit and waiting for resolution. */
|
|
857
|
+
onBreakpoint?: (request: BreakpointRequest) => void;
|
|
858
|
+
/**
|
|
859
|
+
* Timeout for breakpoint resolution in milliseconds.
|
|
860
|
+
* @default 300000 (5 minutes)
|
|
861
|
+
*/
|
|
862
|
+
breakpointTimeoutMs?: number;
|
|
863
|
+
}
|
|
864
|
+
/** Streaming run result from orchestrator */
|
|
865
|
+
interface OrchestratorStreamResult<T = unknown> {
|
|
866
|
+
/** Async iterator for streaming chunks */
|
|
867
|
+
stream: AsyncIterable<OrchestratorStreamChunk>;
|
|
868
|
+
/** Promise that resolves to the final result */
|
|
869
|
+
result: Promise<RunResult<T>>;
|
|
870
|
+
/** Abort the stream */
|
|
871
|
+
abort: () => void;
|
|
872
|
+
}
|
|
873
|
+
/** Stream chunk types for orchestrator — extends StreamChunk with approval events */
|
|
874
|
+
type OrchestratorStreamChunk = StreamChunk | {
|
|
875
|
+
type: "approval_required";
|
|
876
|
+
requestId: string;
|
|
877
|
+
toolName: string;
|
|
878
|
+
} | {
|
|
879
|
+
type: "approval_resolved";
|
|
880
|
+
requestId: string;
|
|
881
|
+
approved: boolean;
|
|
882
|
+
};
|
|
883
|
+
/** Per-call options for run() */
|
|
884
|
+
interface RunCallOptions {
|
|
885
|
+
/** Override output guardrails for this call only. Set to [] to skip. */
|
|
886
|
+
outputGuardrails?: Array<GuardrailFn<OutputGuardrailData> | NamedGuardrail<OutputGuardrailData>>;
|
|
887
|
+
/** Override input guardrails for this call only. Set to [] to skip. */
|
|
888
|
+
inputGuardrails?: Array<GuardrailFn<InputGuardrailData> | NamedGuardrail<InputGuardrailData>>;
|
|
889
|
+
/** Signal for abort */
|
|
890
|
+
signal?: AbortSignal;
|
|
891
|
+
/** Override structured output schema for this call. Set to `null` to opt out. */
|
|
892
|
+
outputSchema?: SafeParseable<unknown> | null;
|
|
893
|
+
/** Override max schema retries for this call. */
|
|
894
|
+
maxSchemaRetries?: number;
|
|
895
|
+
}
|
|
896
|
+
/** Orchestrator instance */
|
|
897
|
+
interface AgentOrchestrator<F extends Record<string, unknown>> {
|
|
898
|
+
system: System<any>;
|
|
899
|
+
facts: F & OrchestratorState;
|
|
900
|
+
/** Run an agent with guardrails. Pass options to override guardrails per-call. */
|
|
901
|
+
run<T>(agent: AgentLike, input: string, options?: RunCallOptions): Promise<RunResult<T>>;
|
|
902
|
+
/**
|
|
903
|
+
* Run an agent with streaming support.
|
|
904
|
+
* Returns an async iterator for chunks and a promise for the final result.
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* ```typescript
|
|
908
|
+
* const { stream, result, abort } = orchestrator.runStream(agent, input);
|
|
909
|
+
*
|
|
910
|
+
* for await (const chunk of stream) {
|
|
911
|
+
* if (chunk.type === 'token') process.stdout.write(chunk.data);
|
|
912
|
+
* if (chunk.type === 'approval_required') showApprovalDialog(chunk);
|
|
913
|
+
* if (chunk.type === 'guardrail_triggered') handleGuardrail(chunk);
|
|
914
|
+
* }
|
|
915
|
+
*
|
|
916
|
+
* const finalResult = await result;
|
|
917
|
+
* ```
|
|
918
|
+
*/
|
|
919
|
+
runStream<T>(agent: AgentLike, input: string, options?: {
|
|
920
|
+
signal?: AbortSignal;
|
|
921
|
+
}): OrchestratorStreamResult<T>;
|
|
922
|
+
/** Approve a pending request */
|
|
923
|
+
approve(requestId: string): void;
|
|
924
|
+
/** Reject a pending request */
|
|
925
|
+
reject(requestId: string, reason?: string): void;
|
|
926
|
+
/** Pause all agents */
|
|
927
|
+
pause(): void;
|
|
928
|
+
/** Resume agents */
|
|
929
|
+
resume(): void;
|
|
930
|
+
/** Reset conversation state */
|
|
931
|
+
reset(): void;
|
|
932
|
+
/** Total tokens consumed across all agent runs */
|
|
933
|
+
readonly totalTokens: number;
|
|
934
|
+
/** Debug timeline (null when debug is false) */
|
|
935
|
+
readonly timeline: DebugTimeline | null;
|
|
936
|
+
/** Wait until agent is idle. Resolves immediately if already idle. */
|
|
937
|
+
waitForIdle(timeoutMs?: number): Promise<void>;
|
|
938
|
+
/** Create a checkpoint of the current orchestrator state. Only valid when agent is not running. */
|
|
939
|
+
checkpoint(options?: {
|
|
940
|
+
label?: string;
|
|
941
|
+
}): Promise<Checkpoint>;
|
|
942
|
+
/** Restore orchestrator state from a checkpoint. */
|
|
943
|
+
restore(checkpoint: Checkpoint, options?: {
|
|
944
|
+
restoreTimeline?: boolean;
|
|
945
|
+
}): void;
|
|
946
|
+
/** Resume a pending breakpoint, optionally with input modifications. */
|
|
947
|
+
resumeBreakpoint(id: string, modifications?: BreakpointModifications): void;
|
|
948
|
+
/** Cancel a pending breakpoint with optional reason. */
|
|
949
|
+
cancelBreakpoint(id: string, reason?: string): void;
|
|
950
|
+
/** Get all currently pending breakpoint requests. */
|
|
951
|
+
getPendingBreakpoints(): BreakpointRequest[];
|
|
952
|
+
/** Dispose of the orchestrator */
|
|
953
|
+
dispose(): void;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Create a constraint-driven agent orchestrator.
|
|
957
|
+
*
|
|
958
|
+
* @example
|
|
959
|
+
* ```typescript
|
|
960
|
+
* import { run as runner } from '@openai/agents'
|
|
961
|
+
*
|
|
962
|
+
* const orchestrator = createAgentOrchestrator({
|
|
963
|
+
* runner,
|
|
964
|
+
* constraints: {
|
|
965
|
+
* escalateToExpert: {
|
|
966
|
+
* when: (facts) => facts.agent.output?.confidence < 0.7,
|
|
967
|
+
* require: (facts) => ({
|
|
968
|
+
* type: 'RUN_EXPERT_AGENT',
|
|
969
|
+
* query: facts.agent.input,
|
|
970
|
+
* }),
|
|
971
|
+
* },
|
|
972
|
+
* budgetExceeded: {
|
|
973
|
+
* when: (facts) => facts.agent.tokenUsage > 10000,
|
|
974
|
+
* require: { type: 'PAUSE_AGENTS' },
|
|
975
|
+
* },
|
|
976
|
+
* },
|
|
977
|
+
* guardrails: {
|
|
978
|
+
* input: [
|
|
979
|
+
* async (data) => {
|
|
980
|
+
* const hasPII = await detectPII(data.input);
|
|
981
|
+
* return { passed: !hasPII, reason: hasPII ? 'Contains PII' : undefined };
|
|
982
|
+
* },
|
|
983
|
+
* ],
|
|
984
|
+
* output: [
|
|
985
|
+
* async (data) => {
|
|
986
|
+
* const isToxic = await checkToxicity(data.output);
|
|
987
|
+
* return { passed: !isToxic, reason: isToxic ? 'Toxic content' : undefined };
|
|
988
|
+
* },
|
|
989
|
+
* ],
|
|
990
|
+
* },
|
|
991
|
+
* });
|
|
992
|
+
*
|
|
993
|
+
* // Run with guardrails and constraint-driven orchestration
|
|
994
|
+
* const result = await orchestrator.run(myAgent, 'Hello, can you help me?');
|
|
995
|
+
* ```
|
|
996
|
+
*
|
|
997
|
+
* @throws {Error} If autoApproveToolCalls is false but no onApprovalRequest callback is provided
|
|
998
|
+
*/
|
|
999
|
+
declare function createAgentOrchestrator<F extends Record<string, unknown> = Record<string, never>>(options: OrchestratorOptions<F>): AgentOrchestrator<F>;
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Agent Reflection / Self-Improvement
|
|
1003
|
+
*
|
|
1004
|
+
* Quality-based iteration: agent produces output → evaluator checks it → retry
|
|
1005
|
+
* with feedback until pass. Works with any AgentRunner.
|
|
1006
|
+
*
|
|
1007
|
+
* Shipped with aggressive safeguards to prevent silent budget burn:
|
|
1008
|
+
* - maxIterations default: 2 (conservative)
|
|
1009
|
+
* - Dev-mode warning for maxIterations > 3
|
|
1010
|
+
* - onIteration fires on every iteration (observable by default)
|
|
1011
|
+
* - Token usage accumulated across iterations
|
|
1012
|
+
*
|
|
1013
|
+
* @example
|
|
1014
|
+
* ```typescript
|
|
1015
|
+
* import { withReflection } from '@directive-run/ai';
|
|
1016
|
+
*
|
|
1017
|
+
* const reflective = withReflection(runner, {
|
|
1018
|
+
* evaluate: (output) => ({
|
|
1019
|
+
* passed: output.includes('conclusion'),
|
|
1020
|
+
* feedback: 'Missing conclusion section',
|
|
1021
|
+
* }),
|
|
1022
|
+
* maxIterations: 2,
|
|
1023
|
+
* });
|
|
1024
|
+
*
|
|
1025
|
+
* const result = await reflective(agent, 'Write a report');
|
|
1026
|
+
* ```
|
|
1027
|
+
*/
|
|
1028
|
+
|
|
1029
|
+
/** Context passed to the reflection evaluator */
|
|
1030
|
+
interface ReflectionContext {
|
|
1031
|
+
input: string;
|
|
1032
|
+
/** 0-based iteration number */
|
|
1033
|
+
iteration: number;
|
|
1034
|
+
result: RunResult<unknown>;
|
|
1035
|
+
history: ReflectionEvaluation[];
|
|
1036
|
+
}
|
|
1037
|
+
/** Result of a reflection evaluation */
|
|
1038
|
+
interface ReflectionEvaluation {
|
|
1039
|
+
passed: boolean;
|
|
1040
|
+
feedback?: string;
|
|
1041
|
+
/** Quality score from 0 to 1, optional */
|
|
1042
|
+
score?: number;
|
|
1043
|
+
}
|
|
1044
|
+
/** Evaluator function for reflection */
|
|
1045
|
+
type ReflectionEvaluator<T = unknown> = (output: T, context: ReflectionContext) => ReflectionEvaluation | Promise<ReflectionEvaluation>;
|
|
1046
|
+
/** Configuration for the reflection wrapper */
|
|
1047
|
+
interface ReflectionConfig<T = unknown> {
|
|
1048
|
+
/** Evaluator function — decides if the output is acceptable */
|
|
1049
|
+
evaluate: ReflectionEvaluator<T>;
|
|
1050
|
+
/** Maximum iterations (including the first). Default: 2 (conservative) */
|
|
1051
|
+
maxIterations?: number;
|
|
1052
|
+
/** Build the retry input from original input + feedback */
|
|
1053
|
+
buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
|
|
1054
|
+
/** Callback on each iteration */
|
|
1055
|
+
onIteration?: (event: {
|
|
1056
|
+
iteration: number;
|
|
1057
|
+
passed: boolean;
|
|
1058
|
+
feedback?: string;
|
|
1059
|
+
score?: number;
|
|
1060
|
+
durationMs: number;
|
|
1061
|
+
}) => void;
|
|
1062
|
+
/** Behavior when maxIterations exhausted. Default: "accept-last" */
|
|
1063
|
+
onExhausted?: "accept-last" | "throw";
|
|
1064
|
+
/** Stop early if budget remaining < threshold (tokens). Works with withBudget. */
|
|
1065
|
+
budgetThreshold?: number;
|
|
1066
|
+
}
|
|
1067
|
+
/** Error thrown when reflection iterations are exhausted and onExhausted is "throw" */
|
|
1068
|
+
declare class ReflectionExhaustedError extends Error {
|
|
1069
|
+
readonly iterations: number;
|
|
1070
|
+
readonly history: ReflectionEvaluation[];
|
|
1071
|
+
readonly lastResult: RunResult<unknown>;
|
|
1072
|
+
readonly totalTokens: number;
|
|
1073
|
+
constructor(options: {
|
|
1074
|
+
iterations: number;
|
|
1075
|
+
history: ReflectionEvaluation[];
|
|
1076
|
+
lastResult: RunResult<unknown>;
|
|
1077
|
+
totalTokens: number;
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Wrap an AgentRunner with reflection (self-improvement) logic.
|
|
1082
|
+
*
|
|
1083
|
+
* The returned runner runs the agent, evaluates the output, and retries with
|
|
1084
|
+
* feedback if the evaluation fails — up to `maxIterations` times.
|
|
1085
|
+
*
|
|
1086
|
+
* @example
|
|
1087
|
+
* ```typescript
|
|
1088
|
+
* const reflective = withReflection(runner, {
|
|
1089
|
+
* evaluate: (output) => ({
|
|
1090
|
+
* passed: typeof output === 'string' && output.length > 100,
|
|
1091
|
+
* feedback: 'Response too short, please elaborate',
|
|
1092
|
+
* score: Math.min(1, (output as string).length / 200),
|
|
1093
|
+
* }),
|
|
1094
|
+
* maxIterations: 3,
|
|
1095
|
+
* onExhausted: 'accept-last',
|
|
1096
|
+
* });
|
|
1097
|
+
* ```
|
|
1098
|
+
*/
|
|
1099
|
+
declare function withReflection<T = unknown>(runner: AgentRunner, config: ReflectionConfig<T>): AgentRunner;
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Health Monitor — tracks per-agent health metrics for self-healing networks.
|
|
1103
|
+
*
|
|
1104
|
+
* Pure computation module with zero Directive dependency.
|
|
1105
|
+
* Maintains a rolling window of success/failure events and computes a health
|
|
1106
|
+
* score from 0-100 based on configurable weights.
|
|
1107
|
+
*
|
|
1108
|
+
* @module
|
|
1109
|
+
*/
|
|
1110
|
+
|
|
1111
|
+
/** Circuit state values */
|
|
1112
|
+
type HealthCircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
|
|
1113
|
+
/** Per-agent health metrics */
|
|
1114
|
+
interface AgentHealthMetrics {
|
|
1115
|
+
agentId: string;
|
|
1116
|
+
circuitState: HealthCircuitState;
|
|
1117
|
+
successRate: number;
|
|
1118
|
+
avgLatencyMs: number;
|
|
1119
|
+
recentFailures: number;
|
|
1120
|
+
recentSuccesses: number;
|
|
1121
|
+
healthScore: number;
|
|
1122
|
+
/** Last N error messages (most recent last) */
|
|
1123
|
+
lastErrors: string[];
|
|
1124
|
+
}
|
|
1125
|
+
/** Health monitor instance */
|
|
1126
|
+
interface HealthMonitor {
|
|
1127
|
+
recordSuccess(agentId: string, latencyMs: number): void;
|
|
1128
|
+
recordFailure(agentId: string, latencyMs: number, error?: Error): void;
|
|
1129
|
+
getMetrics(agentId: string): AgentHealthMetrics;
|
|
1130
|
+
getAllMetrics(): Record<string, AgentHealthMetrics>;
|
|
1131
|
+
/** Returns a 0-100 health score. Returns 50 (neutral) when no data is available for the agent. */
|
|
1132
|
+
getHealthScore(agentId: string): number;
|
|
1133
|
+
updateCircuitState(agentId: string, state: HealthCircuitState): void;
|
|
1134
|
+
/** Reset all metrics. Useful for testing. */
|
|
1135
|
+
reset(): void;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Create a health monitor that tracks per-agent metrics.
|
|
1139
|
+
*
|
|
1140
|
+
* @example
|
|
1141
|
+
* ```typescript
|
|
1142
|
+
* const monitor = createHealthMonitor({ windowMs: 30000 });
|
|
1143
|
+
*
|
|
1144
|
+
* monitor.recordSuccess("agent-a", 120);
|
|
1145
|
+
* monitor.recordFailure("agent-a", 5000, new Error("timeout"));
|
|
1146
|
+
*
|
|
1147
|
+
* const score = monitor.getHealthScore("agent-a");
|
|
1148
|
+
* console.log(score); // 0-100
|
|
1149
|
+
* ```
|
|
1150
|
+
*/
|
|
1151
|
+
declare function createHealthMonitor(config?: HealthMonitorConfig): HealthMonitor;
|
|
1152
|
+
|
|
1153
|
+
/** Get the current step/round/iteration count from a pattern checkpoint state */
|
|
1154
|
+
declare function getPatternStep(state: PatternCheckpointState): number;
|
|
1155
|
+
/** Compute progress from a pattern checkpoint state */
|
|
1156
|
+
declare function getCheckpointProgress(state: PatternCheckpointState): CheckpointProgress;
|
|
1157
|
+
/** Compute the diff between two checkpoint states */
|
|
1158
|
+
declare function diffCheckpoints(a: PatternCheckpointState, b: PatternCheckpointState): CheckpointDiff;
|
|
1159
|
+
/**
|
|
1160
|
+
* Fork an orchestrator from a checkpoint — creates a new independent orchestrator
|
|
1161
|
+
* restored to the checkpoint's state, ready to diverge from that point.
|
|
1162
|
+
*
|
|
1163
|
+
* @param options - The original orchestrator options used to create the orchestrator
|
|
1164
|
+
* @param checkpointStore - The checkpoint store containing the checkpoint
|
|
1165
|
+
* @param checkpointId - The ID of the checkpoint to fork from
|
|
1166
|
+
* @returns A new independent MultiAgentOrchestrator restored to checkpoint state
|
|
1167
|
+
*
|
|
1168
|
+
* @example
|
|
1169
|
+
* ```typescript
|
|
1170
|
+
* const forked = await forkFromCheckpoint(orchestratorOptions, store, "ckpt_abc123");
|
|
1171
|
+
* const result = await forked.replay("ckpt_abc123", pattern, { input: "new input" });
|
|
1172
|
+
* ```
|
|
1173
|
+
*/
|
|
1174
|
+
declare function forkFromCheckpoint(options: MultiAgentOrchestratorOptions, checkpointStore: CheckpointStore, checkpointId: string): Promise<MultiAgentOrchestrator>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Async semaphore for controlling concurrent access.
|
|
1177
|
+
* Uses a queue-based approach instead of polling for efficiency.
|
|
1178
|
+
*
|
|
1179
|
+
* @example
|
|
1180
|
+
* ```typescript
|
|
1181
|
+
* import { Semaphore } from '@directive-run/ai';
|
|
1182
|
+
*
|
|
1183
|
+
* const sem = new Semaphore(3); // Allow 3 concurrent operations
|
|
1184
|
+
*
|
|
1185
|
+
* async function doWork() {
|
|
1186
|
+
* const release = await sem.acquire();
|
|
1187
|
+
* try {
|
|
1188
|
+
* await performWork();
|
|
1189
|
+
* } finally {
|
|
1190
|
+
* release();
|
|
1191
|
+
* }
|
|
1192
|
+
* }
|
|
1193
|
+
* ```
|
|
1194
|
+
*/
|
|
1195
|
+
declare class Semaphore {
|
|
1196
|
+
private count;
|
|
1197
|
+
private readonly maxPermits;
|
|
1198
|
+
private readonly queue;
|
|
1199
|
+
constructor(max: number);
|
|
1200
|
+
/** Create a one-shot release function that guards against double-release */
|
|
1201
|
+
private createReleaseFn;
|
|
1202
|
+
/** Acquire a permit, optionally with abort signal support */
|
|
1203
|
+
acquire(signal?: AbortSignal): Promise<() => void>;
|
|
1204
|
+
/** Non-blocking acquire — returns null if no permits available */
|
|
1205
|
+
tryAcquire(): (() => void) | null;
|
|
1206
|
+
private release;
|
|
1207
|
+
/** Get current available permits */
|
|
1208
|
+
get available(): number;
|
|
1209
|
+
/** Get number of waiters in queue */
|
|
1210
|
+
get waiting(): number;
|
|
1211
|
+
/** Get maximum permits */
|
|
1212
|
+
get max(): number;
|
|
1213
|
+
/** Reject all pending waiters with an error and reset permits */
|
|
1214
|
+
drain(): void;
|
|
1215
|
+
}
|
|
1216
|
+
/** Configuration for a registered agent */
|
|
1217
|
+
interface AgentRegistration {
|
|
1218
|
+
/** The agent instance */
|
|
1219
|
+
agent: AgentLike;
|
|
1220
|
+
/** Maximum concurrent runs for this agent. @default 1 */
|
|
1221
|
+
maxConcurrent?: number;
|
|
1222
|
+
/** Timeout for agent runs (ms) */
|
|
1223
|
+
timeout?: number;
|
|
1224
|
+
/** Custom run options */
|
|
1225
|
+
runOptions?: Omit<RunOptions, "signal">;
|
|
1226
|
+
/** Description for constraint-based selection */
|
|
1227
|
+
description?: string;
|
|
1228
|
+
/** Capabilities this agent has */
|
|
1229
|
+
capabilities?: string[];
|
|
1230
|
+
/** Per-agent guardrails (applied in addition to orchestrator-level guardrails) */
|
|
1231
|
+
guardrails?: {
|
|
1232
|
+
input?: Array<GuardrailFn<InputGuardrailData> | NamedGuardrail<InputGuardrailData>>;
|
|
1233
|
+
output?: Array<GuardrailFn<OutputGuardrailData> | NamedGuardrail<OutputGuardrailData>>;
|
|
1234
|
+
toolCall?: Array<GuardrailFn<ToolCallGuardrailData> | NamedGuardrail<ToolCallGuardrailData>>;
|
|
1235
|
+
};
|
|
1236
|
+
/** Per-agent retry config (overrides orchestrator-level agentRetry) */
|
|
1237
|
+
retry?: AgentRetryConfig;
|
|
1238
|
+
/** Per-agent constraints */
|
|
1239
|
+
constraints?: Record<string, OrchestratorConstraint<Record<string, unknown>>>;
|
|
1240
|
+
/** Per-agent resolvers */
|
|
1241
|
+
resolvers?: Record<string, OrchestratorResolver<Record<string, unknown>, Requirement>>;
|
|
1242
|
+
/** Per-agent memory (overrides orchestrator-level memory) */
|
|
1243
|
+
memory?: AgentMemory;
|
|
1244
|
+
/** Per-agent circuit breaker (overrides orchestrator-level circuitBreaker) */
|
|
1245
|
+
circuitBreaker?: CircuitBreaker;
|
|
1246
|
+
/** Per-agent output schema for structured output */
|
|
1247
|
+
outputSchema?: SafeParseable<unknown>;
|
|
1248
|
+
/** Max retries for structured output validation. @default 2 */
|
|
1249
|
+
maxSchemaRetries?: number;
|
|
1250
|
+
/** Custom JSON extractor for structured output */
|
|
1251
|
+
extractJson?: (output: string) => unknown;
|
|
1252
|
+
/** Description of the schema for structured output prompting */
|
|
1253
|
+
schemaDescription?: string;
|
|
1254
|
+
}
|
|
1255
|
+
/** Agent registry configuration */
|
|
1256
|
+
interface AgentRegistry {
|
|
1257
|
+
[agentId: string]: AgentRegistration;
|
|
1258
|
+
}
|
|
1259
|
+
/** Parallel execution pattern - run agents concurrently and merge results */
|
|
1260
|
+
interface ParallelPattern<T = unknown> {
|
|
1261
|
+
type: "parallel";
|
|
1262
|
+
/** Agent IDs to run in parallel (can repeat for multiple instances) */
|
|
1263
|
+
agents: string[];
|
|
1264
|
+
/** Function to merge results from all agents */
|
|
1265
|
+
merge: (results: RunResult<unknown>[]) => T | Promise<T>;
|
|
1266
|
+
/** Minimum successful results required. @default agents.length */
|
|
1267
|
+
minSuccess?: number;
|
|
1268
|
+
/** Overall timeout (ms) */
|
|
1269
|
+
timeout?: number;
|
|
1270
|
+
}
|
|
1271
|
+
/** Sequential execution pattern - pipeline of agents */
|
|
1272
|
+
interface SequentialPattern<T = unknown> {
|
|
1273
|
+
type: "sequential";
|
|
1274
|
+
/** Agent IDs in execution order */
|
|
1275
|
+
agents: string[];
|
|
1276
|
+
/** Transform output to next input. @default JSON.stringify */
|
|
1277
|
+
transform?: (output: unknown, agentId: string, index: number) => string;
|
|
1278
|
+
/** Final result extractor */
|
|
1279
|
+
extract?: (output: unknown) => T;
|
|
1280
|
+
/** Continue on error. @default false */
|
|
1281
|
+
continueOnError?: boolean;
|
|
1282
|
+
/** Checkpoint configuration for mid-execution fault tolerance */
|
|
1283
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1284
|
+
}
|
|
1285
|
+
/** Supervisor pattern - one agent directs others */
|
|
1286
|
+
interface SupervisorPattern<T = unknown> {
|
|
1287
|
+
type: "supervisor";
|
|
1288
|
+
/** Supervisor agent ID */
|
|
1289
|
+
supervisor: string;
|
|
1290
|
+
/** Worker agent IDs */
|
|
1291
|
+
workers: string[];
|
|
1292
|
+
/** Maximum delegation rounds. @default 5 */
|
|
1293
|
+
maxRounds?: number;
|
|
1294
|
+
/** Extract final result */
|
|
1295
|
+
extract?: (supervisorOutput: unknown, workerResults: RunResult<unknown>[]) => T;
|
|
1296
|
+
/** Checkpoint configuration for mid-execution fault tolerance */
|
|
1297
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1298
|
+
}
|
|
1299
|
+
/** Record of a single reflection iteration (for score history) */
|
|
1300
|
+
interface ReflectIterationRecord {
|
|
1301
|
+
iteration: number;
|
|
1302
|
+
passed: boolean;
|
|
1303
|
+
score?: number;
|
|
1304
|
+
feedback?: string;
|
|
1305
|
+
durationMs: number;
|
|
1306
|
+
producerTokens: number;
|
|
1307
|
+
evaluatorTokens: number;
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Reflect pattern - produce, evaluate, retry with feedback.
|
|
1311
|
+
* @see reflect — factory helper
|
|
1312
|
+
* @see ReflectIterationRecord — per-iteration history entries
|
|
1313
|
+
*/
|
|
1314
|
+
interface ReflectPattern<T = unknown> {
|
|
1315
|
+
type: "reflect";
|
|
1316
|
+
/** Producer agent ID */
|
|
1317
|
+
agent: string;
|
|
1318
|
+
/** Evaluator agent ID (receives output as input) */
|
|
1319
|
+
evaluator: string;
|
|
1320
|
+
/** Maximum iterations. @default 2 */
|
|
1321
|
+
maxIterations?: number;
|
|
1322
|
+
/** Parse evaluator output into ReflectionEvaluation. @default JSON.parse */
|
|
1323
|
+
parseEvaluation?: (output: unknown) => ReflectionEvaluation;
|
|
1324
|
+
/** Build retry input from original input + feedback */
|
|
1325
|
+
buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
|
|
1326
|
+
/** Extract result from raw producer output. Unlike race's extract (which receives RunResult), this receives the output directly since the producer is already selected. */
|
|
1327
|
+
extract?: (output: unknown) => T;
|
|
1328
|
+
/** Behavior when maxIterations exhausted. @default "accept-last" */
|
|
1329
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
1330
|
+
/** Callback fired after each iteration with score/feedback data. @see ReflectIterationRecord */
|
|
1331
|
+
onIteration?: (record: ReflectIterationRecord) => void;
|
|
1332
|
+
/** AbortSignal for external cancellation of the reflection loop */
|
|
1333
|
+
signal?: AbortSignal;
|
|
1334
|
+
/** Overall timeout (ms). Creates an internal AbortSignal. */
|
|
1335
|
+
timeout?: number;
|
|
1336
|
+
/** Score threshold for acceptance. Number or function of iteration. When set, evaluator score >= threshold is treated as passed. */
|
|
1337
|
+
threshold?: number | ((iteration: number) => number);
|
|
1338
|
+
/** Checkpoint configuration for mid-execution fault tolerance */
|
|
1339
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Race pattern - first successful agent wins, rest cancelled.
|
|
1343
|
+
* @see race — factory helper
|
|
1344
|
+
* @see RaceResult — return type
|
|
1345
|
+
*/
|
|
1346
|
+
interface RacePattern<T = unknown> {
|
|
1347
|
+
type: "race";
|
|
1348
|
+
/** Agent IDs to race */
|
|
1349
|
+
agents: string[];
|
|
1350
|
+
/** Extract result from winning RunResult (receives full RunResult for access to tokens/metadata). @default output field */
|
|
1351
|
+
extract?: (result: RunResult<unknown>) => T;
|
|
1352
|
+
/** Overall timeout (ms) */
|
|
1353
|
+
timeout?: number;
|
|
1354
|
+
/** Require N successful results before resolving. @default 1 */
|
|
1355
|
+
minSuccess?: number;
|
|
1356
|
+
/** AbortSignal for external cancellation */
|
|
1357
|
+
signal?: AbortSignal;
|
|
1358
|
+
}
|
|
1359
|
+
/** Return type from debate pattern execution */
|
|
1360
|
+
interface DebateResult<T = unknown> {
|
|
1361
|
+
winnerId: string;
|
|
1362
|
+
result: T;
|
|
1363
|
+
rounds: Array<{
|
|
1364
|
+
proposals: Array<{
|
|
1365
|
+
agentId: string;
|
|
1366
|
+
output: unknown;
|
|
1367
|
+
}>;
|
|
1368
|
+
judgement: {
|
|
1369
|
+
winnerId: string;
|
|
1370
|
+
feedback?: string;
|
|
1371
|
+
score?: number;
|
|
1372
|
+
};
|
|
1373
|
+
}>;
|
|
1374
|
+
}
|
|
1375
|
+
/** Individual result entry returned when minSuccess > 1 */
|
|
1376
|
+
interface RaceSuccessEntry<T = unknown> {
|
|
1377
|
+
agentId: string;
|
|
1378
|
+
result: T;
|
|
1379
|
+
}
|
|
1380
|
+
/** Return type from race pattern execution */
|
|
1381
|
+
interface RaceResult<T = unknown> {
|
|
1382
|
+
winnerId: string;
|
|
1383
|
+
result: T;
|
|
1384
|
+
allResults?: Array<RaceSuccessEntry<T>>;
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* Debate pattern - agents compete, evaluator judges across rounds.
|
|
1388
|
+
* @see debate — factory helper
|
|
1389
|
+
* @see runDebate — imperative API
|
|
1390
|
+
* @see DebateResult — return type
|
|
1391
|
+
*/
|
|
1392
|
+
interface DebatePattern<T = unknown> {
|
|
1393
|
+
type: "debate";
|
|
1394
|
+
/** Agent IDs that will generate competing proposals */
|
|
1395
|
+
agents: string[];
|
|
1396
|
+
/** Evaluator agent ID that judges proposals */
|
|
1397
|
+
evaluator: string;
|
|
1398
|
+
/** Maximum rounds of debate. @default 2 */
|
|
1399
|
+
maxRounds?: number;
|
|
1400
|
+
/** Extract final result from the winning proposal */
|
|
1401
|
+
extract?: (output: unknown) => T;
|
|
1402
|
+
/** Parse evaluator output. @default JSON.parse expecting `{ winnerId, feedback }` */
|
|
1403
|
+
parseJudgement?: (output: unknown) => {
|
|
1404
|
+
winnerId: string;
|
|
1405
|
+
feedback?: string;
|
|
1406
|
+
score?: number;
|
|
1407
|
+
};
|
|
1408
|
+
/** AbortSignal for external cancellation */
|
|
1409
|
+
signal?: AbortSignal;
|
|
1410
|
+
/** Overall timeout (ms). Creates an internal AbortSignal. */
|
|
1411
|
+
timeout?: number;
|
|
1412
|
+
/** Checkpoint configuration for mid-execution fault tolerance */
|
|
1413
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/** Union of all patterns */
|
|
1417
|
+
type ExecutionPattern<T = unknown> = ParallelPattern<T> | SequentialPattern<T> | SupervisorPattern<T> | DagPattern<T> | ReflectPattern<T> | RacePattern<T> | DebatePattern<T> | GoalPattern<T>;
|
|
1418
|
+
/** Handoff request between agents */
|
|
1419
|
+
interface HandoffRequest {
|
|
1420
|
+
id: string;
|
|
1421
|
+
fromAgent: string;
|
|
1422
|
+
toAgent: string;
|
|
1423
|
+
input: string;
|
|
1424
|
+
context?: Record<string, unknown>;
|
|
1425
|
+
requestedAt: number;
|
|
1426
|
+
}
|
|
1427
|
+
/** Handoff result */
|
|
1428
|
+
interface HandoffResult {
|
|
1429
|
+
request: HandoffRequest;
|
|
1430
|
+
result: RunResult<unknown>;
|
|
1431
|
+
completedAt: number;
|
|
1432
|
+
}
|
|
1433
|
+
/** Run agent requirement */
|
|
1434
|
+
interface RunAgentRequirement extends Requirement {
|
|
1435
|
+
type: "RUN_AGENT";
|
|
1436
|
+
agent: string;
|
|
1437
|
+
input: string;
|
|
1438
|
+
context?: Record<string, unknown>;
|
|
1439
|
+
}
|
|
1440
|
+
/** Multi-agent orchestrator options */
|
|
1441
|
+
interface MultiAgentOrchestratorOptions {
|
|
1442
|
+
/** Base run function */
|
|
1443
|
+
runner: AgentRunner;
|
|
1444
|
+
/** Registered agents */
|
|
1445
|
+
agents: AgentRegistry;
|
|
1446
|
+
/** Execution patterns */
|
|
1447
|
+
patterns?: Record<string, ExecutionPattern>;
|
|
1448
|
+
/** Handoff callbacks */
|
|
1449
|
+
onHandoff?: (request: HandoffRequest) => void;
|
|
1450
|
+
/** Handoff completion callbacks */
|
|
1451
|
+
onHandoffComplete?: (result: HandoffResult) => void;
|
|
1452
|
+
/** Maximum number of handoff results to retain. @default 1000 */
|
|
1453
|
+
maxHandoffHistory?: number;
|
|
1454
|
+
/** Debug mode — `true` for default debug, or config object for advanced options */
|
|
1455
|
+
debug?: boolean | OrchestratorDebugConfig;
|
|
1456
|
+
/** Orchestrator-level guardrails (applied to all agents) */
|
|
1457
|
+
guardrails?: GuardrailsConfig;
|
|
1458
|
+
/** Lifecycle hooks */
|
|
1459
|
+
hooks?: MultiAgentLifecycleHooks;
|
|
1460
|
+
/** Shared memory across all agents */
|
|
1461
|
+
memory?: AgentMemory;
|
|
1462
|
+
/** Default retry config for all agents (per-agent overrides this) */
|
|
1463
|
+
agentRetry?: AgentRetryConfig;
|
|
1464
|
+
/** Maximum token budget across all agent runs */
|
|
1465
|
+
maxTokenBudget?: number;
|
|
1466
|
+
/** Fires when token usage reaches this percentage of maxTokenBudget (0-1). @default 0.8 */
|
|
1467
|
+
budgetWarningThreshold?: number;
|
|
1468
|
+
/** Callback when budget warning threshold is reached */
|
|
1469
|
+
onBudgetWarning?: (event: {
|
|
1470
|
+
currentTokens: number;
|
|
1471
|
+
maxBudget: number;
|
|
1472
|
+
percentage: number;
|
|
1473
|
+
}) => void;
|
|
1474
|
+
/** Plugins to attach to the underlying Directive System */
|
|
1475
|
+
plugins?: Plugin[];
|
|
1476
|
+
/** Callback for approval requests */
|
|
1477
|
+
onApprovalRequest?: (request: ApprovalRequest) => void;
|
|
1478
|
+
/** Auto-approve tool calls. @default true */
|
|
1479
|
+
autoApproveToolCalls?: boolean;
|
|
1480
|
+
/** Approval timeout in milliseconds. @default 300000 */
|
|
1481
|
+
approvalTimeoutMs?: number;
|
|
1482
|
+
/** Orchestrator-level constraints */
|
|
1483
|
+
constraints?: Record<string, OrchestratorConstraint<Record<string, unknown>>>;
|
|
1484
|
+
/** Orchestrator-level resolvers */
|
|
1485
|
+
resolvers?: Record<string, OrchestratorResolver<Record<string, unknown>, Requirement>>;
|
|
1486
|
+
/** Orchestrator-level circuit breaker */
|
|
1487
|
+
circuitBreaker?: CircuitBreaker;
|
|
1488
|
+
/** Self-healing configuration for automatic agent rerouting */
|
|
1489
|
+
selfHealing?: MultiAgentSelfHealingConfig;
|
|
1490
|
+
/** Checkpoint store for persistent state */
|
|
1491
|
+
checkpointStore?: CheckpointStore;
|
|
1492
|
+
/** Breakpoints for human-in-the-loop pause/inspect/modify */
|
|
1493
|
+
breakpoints?: BreakpointConfig<MultiAgentBreakpointType>[];
|
|
1494
|
+
/** Callback when a breakpoint fires */
|
|
1495
|
+
onBreakpoint?: (request: BreakpointRequest) => void;
|
|
1496
|
+
/** Timeout for breakpoint resolution (ms). @default 300000 */
|
|
1497
|
+
breakpointTimeoutMs?: number;
|
|
1498
|
+
/** Cross-agent derivation functions — compute values from combined agent states */
|
|
1499
|
+
derive?: Record<string, CrossAgentDerivationFn>;
|
|
1500
|
+
/** Shared scratchpad configuration */
|
|
1501
|
+
scratchpad?: {
|
|
1502
|
+
init: Record<string, unknown>;
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
/** Multi-agent state in facts */
|
|
1506
|
+
interface MultiAgentState {
|
|
1507
|
+
/** Namespace for each agent's state */
|
|
1508
|
+
__agents: Record<string, {
|
|
1509
|
+
status: "idle" | "running" | "completed" | "error";
|
|
1510
|
+
lastInput?: string;
|
|
1511
|
+
lastOutput?: unknown;
|
|
1512
|
+
lastError?: string;
|
|
1513
|
+
runCount: number;
|
|
1514
|
+
totalTokens: number;
|
|
1515
|
+
}>;
|
|
1516
|
+
/** Pending handoffs */
|
|
1517
|
+
__handoffs: HandoffRequest[];
|
|
1518
|
+
/** Completed handoffs */
|
|
1519
|
+
__handoffResults: HandoffResult[];
|
|
1520
|
+
}
|
|
1521
|
+
/** Per-call options for multi-agent runAgent/run */
|
|
1522
|
+
interface MultiAgentRunCallOptions extends RunOptions {
|
|
1523
|
+
/** Override structured output schema for this call. Set to `null` to opt out of per-agent schema. */
|
|
1524
|
+
outputSchema?: SafeParseable<unknown> | null;
|
|
1525
|
+
/** Override max schema retries for this call. */
|
|
1526
|
+
maxSchemaRetries?: number;
|
|
1527
|
+
}
|
|
1528
|
+
/** Multi-agent orchestrator instance */
|
|
1529
|
+
interface MultiAgentOrchestrator {
|
|
1530
|
+
/** The underlying Directive System */
|
|
1531
|
+
system: System<any>;
|
|
1532
|
+
/** Combined facts from all agent modules + coordinator */
|
|
1533
|
+
facts: Record<string, unknown>;
|
|
1534
|
+
/** Run a single agent */
|
|
1535
|
+
runAgent<T>(agentId: string, input: string, options?: MultiAgentRunCallOptions): Promise<RunResult<T>>;
|
|
1536
|
+
/** Run an agent with streaming support */
|
|
1537
|
+
runAgentStream<T>(agentId: string, input: string, options?: {
|
|
1538
|
+
signal?: AbortSignal;
|
|
1539
|
+
}): OrchestratorStreamResult<T>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Run an execution pattern by its registered pattern ID.
|
|
1542
|
+
*
|
|
1543
|
+
* Note: For race and debate patterns, `runPattern` returns only the extracted result value.
|
|
1544
|
+
* Use `runRace()` or `runDebate()` to access full results including `winnerId` and `allResults`.
|
|
1545
|
+
*/
|
|
1546
|
+
runPattern<T>(patternId: string, input: string): Promise<T>;
|
|
1547
|
+
/** Run agents in parallel. Note: parallel does not support checkpoint/resume (single-step pattern). */
|
|
1548
|
+
runParallel<T>(agentIds: string[], inputs: string | string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
|
|
1549
|
+
minSuccess?: number;
|
|
1550
|
+
timeout?: number;
|
|
1551
|
+
}): Promise<T>;
|
|
1552
|
+
/** Run agents sequentially */
|
|
1553
|
+
runSequential<T>(agentIds: string[], initialInput: string, options?: {
|
|
1554
|
+
transform?: (output: unknown, agentId: string, index: number) => string;
|
|
1555
|
+
}): Promise<RunResult<T>[]>;
|
|
1556
|
+
/** Request a handoff between agents */
|
|
1557
|
+
handoff(fromAgent: string, toAgent: string, input: string, context?: Record<string, unknown>): Promise<RunResult<unknown>>;
|
|
1558
|
+
/** Approve a pending request */
|
|
1559
|
+
approve(requestId: string): void;
|
|
1560
|
+
/** Reject a pending request */
|
|
1561
|
+
reject(requestId: string, reason?: string): void;
|
|
1562
|
+
/** Pause all agents */
|
|
1563
|
+
pause(): void;
|
|
1564
|
+
/** Resume agents */
|
|
1565
|
+
resume(): void;
|
|
1566
|
+
/** Total tokens consumed across all agents */
|
|
1567
|
+
readonly totalTokens: number;
|
|
1568
|
+
/** Wait until all agents are idle */
|
|
1569
|
+
waitForIdle(timeoutMs?: number): Promise<void>;
|
|
1570
|
+
/** Alias for runAgent */
|
|
1571
|
+
run<T>(agentId: string, input: string, options?: MultiAgentRunCallOptions): Promise<RunResult<T>>;
|
|
1572
|
+
/** Alias for runAgentStream */
|
|
1573
|
+
runStream<T>(agentId: string, input: string, options?: {
|
|
1574
|
+
signal?: AbortSignal;
|
|
1575
|
+
}): OrchestratorStreamResult<T>;
|
|
1576
|
+
/** Register a new agent dynamically */
|
|
1577
|
+
registerAgent(agentId: string, registration: AgentRegistration): void;
|
|
1578
|
+
/** Unregister an agent (must be idle) */
|
|
1579
|
+
unregisterAgent(agentId: string): void;
|
|
1580
|
+
/** Get registered agent IDs */
|
|
1581
|
+
getAgentIds(): string[];
|
|
1582
|
+
/** Get agent state */
|
|
1583
|
+
getAgentState(agentId: string): MultiAgentState["__agents"][string] | undefined;
|
|
1584
|
+
/** Get all agent states */
|
|
1585
|
+
getAllAgentStates(): Record<string, MultiAgentState["__agents"][string]>;
|
|
1586
|
+
/** Get pending handoffs */
|
|
1587
|
+
getPendingHandoffs(): HandoffRequest[];
|
|
1588
|
+
/** Reset all agent states */
|
|
1589
|
+
reset(): void;
|
|
1590
|
+
/** Debug timeline (null when debug is false) */
|
|
1591
|
+
readonly timeline: DebugTimeline | null;
|
|
1592
|
+
/** Health monitor (null when selfHealing is not configured) */
|
|
1593
|
+
readonly healthMonitor: HealthMonitor | null;
|
|
1594
|
+
/** Create a checkpoint of the current state */
|
|
1595
|
+
checkpoint(options?: {
|
|
1596
|
+
label?: string;
|
|
1597
|
+
}): Promise<Checkpoint>;
|
|
1598
|
+
/** Restore from a checkpoint */
|
|
1599
|
+
restore(checkpoint: Checkpoint, options?: {
|
|
1600
|
+
restoreTimeline?: boolean;
|
|
1601
|
+
}): void;
|
|
1602
|
+
/** Run multiple agents with multiplexed streaming */
|
|
1603
|
+
runParallelStream<T>(agentIds: string[], inputs: string | string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
|
|
1604
|
+
minSuccess?: number;
|
|
1605
|
+
timeout?: number;
|
|
1606
|
+
signal?: AbortSignal;
|
|
1607
|
+
}): MultiplexedStreamResult<T>;
|
|
1608
|
+
/** Resume a paused breakpoint */
|
|
1609
|
+
resumeBreakpoint(id: string, modifications?: BreakpointModifications): void;
|
|
1610
|
+
/** Cancel a paused breakpoint */
|
|
1611
|
+
cancelBreakpoint(id: string, reason?: string): void;
|
|
1612
|
+
/** Get pending breakpoints */
|
|
1613
|
+
getPendingBreakpoints(): BreakpointRequest[];
|
|
1614
|
+
/** Race multiple agents — first successful result wins, rest cancelled. Note: race does not support checkpoint/resume (single-step pattern). */
|
|
1615
|
+
runRace<T>(agentIds: string[], input: string, options?: {
|
|
1616
|
+
extract?: (result: RunResult<unknown>) => T;
|
|
1617
|
+
timeout?: number;
|
|
1618
|
+
minSuccess?: number;
|
|
1619
|
+
signal?: AbortSignal;
|
|
1620
|
+
}): Promise<RaceResult<T>>;
|
|
1621
|
+
/** Run a reflect pattern imperatively (no pre-registration needed) */
|
|
1622
|
+
runReflect<T>(producerId: string, evaluatorId: string, input: string, options?: {
|
|
1623
|
+
maxIterations?: number;
|
|
1624
|
+
parseEvaluation?: (output: unknown) => ReflectionEvaluation;
|
|
1625
|
+
buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
|
|
1626
|
+
extract?: (output: unknown) => T;
|
|
1627
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
1628
|
+
onIteration?: (record: ReflectIterationRecord) => void;
|
|
1629
|
+
signal?: AbortSignal;
|
|
1630
|
+
timeout?: number;
|
|
1631
|
+
threshold?: number | ((iteration: number) => number);
|
|
1632
|
+
}): Promise<{
|
|
1633
|
+
result: T;
|
|
1634
|
+
iterations: number;
|
|
1635
|
+
history: ReflectIterationRecord[];
|
|
1636
|
+
exhausted: boolean;
|
|
1637
|
+
}>;
|
|
1638
|
+
/** Run a debate imperatively (no pre-registration needed) */
|
|
1639
|
+
runDebate<T>(agentIds: string[], evaluatorId: string, input: string, options?: {
|
|
1640
|
+
maxRounds?: number;
|
|
1641
|
+
extract?: (output: unknown) => T;
|
|
1642
|
+
parseJudgement?: (output: unknown) => {
|
|
1643
|
+
winnerId: string;
|
|
1644
|
+
feedback?: string;
|
|
1645
|
+
score?: number;
|
|
1646
|
+
};
|
|
1647
|
+
signal?: AbortSignal;
|
|
1648
|
+
timeout?: number;
|
|
1649
|
+
}): Promise<DebateResult<T>>;
|
|
1650
|
+
/** Run a goal pattern imperatively — declare desired state, let the runtime resolve */
|
|
1651
|
+
runGoal<T>(nodes: Record<string, GoalNode>, initialInput: string | Record<string, unknown>, when: (facts: Record<string, unknown>) => boolean, options?: {
|
|
1652
|
+
satisfaction?: (facts: Record<string, unknown>) => number;
|
|
1653
|
+
maxSteps?: number;
|
|
1654
|
+
extract?: (facts: Record<string, unknown>) => T;
|
|
1655
|
+
timeout?: number;
|
|
1656
|
+
signal?: AbortSignal;
|
|
1657
|
+
selectionStrategy?: AgentSelectionStrategy;
|
|
1658
|
+
relaxation?: RelaxationTier[];
|
|
1659
|
+
onStep?: GoalPattern["onStep"];
|
|
1660
|
+
onStall?: GoalPattern["onStall"];
|
|
1661
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1662
|
+
}): Promise<GoalResult<T>>;
|
|
1663
|
+
/** Resume a goal pattern from a saved checkpoint */
|
|
1664
|
+
resumeGoal<T>(checkpointState: GoalCheckpointState, pattern: GoalPattern<T>): Promise<GoalResult<T>>;
|
|
1665
|
+
/** Resume a sequential pattern from a saved checkpoint */
|
|
1666
|
+
resumeSequential<T>(checkpointState: SequentialCheckpointState, pattern: SequentialPattern<T>): Promise<T>;
|
|
1667
|
+
/** Resume a supervisor pattern from a saved checkpoint */
|
|
1668
|
+
resumeSupervisor<T>(checkpointState: SupervisorCheckpointState, pattern: SupervisorPattern<T>, options?: {
|
|
1669
|
+
input?: string;
|
|
1670
|
+
}): Promise<T>;
|
|
1671
|
+
/** Resume a reflect pattern from a saved checkpoint */
|
|
1672
|
+
resumeReflect<T>(checkpointState: ReflectCheckpointState, pattern: ReflectPattern<T>, options?: {
|
|
1673
|
+
input?: string;
|
|
1674
|
+
}): Promise<T>;
|
|
1675
|
+
/** Resume a debate pattern from a saved checkpoint */
|
|
1676
|
+
resumeDebate<T>(checkpointState: DebateCheckpointState, pattern: DebatePattern<T>): Promise<DebateResult<T>>;
|
|
1677
|
+
/** Resume a DAG pattern from a saved checkpoint */
|
|
1678
|
+
resumeDag<T>(checkpointState: DagCheckpointState, pattern: DagPattern<T>, options?: {
|
|
1679
|
+
input?: string;
|
|
1680
|
+
}): Promise<T>;
|
|
1681
|
+
/** Replay from a saved checkpoint (auto-detects pattern type) */
|
|
1682
|
+
replay<T>(checkpointId: string, pattern: ExecutionPattern, options?: {
|
|
1683
|
+
input?: string;
|
|
1684
|
+
}): Promise<T>;
|
|
1685
|
+
/**
|
|
1686
|
+
* Get reflection iteration history from last runReflectPattern call.
|
|
1687
|
+
* @deprecated Use the `history` field on the return value from `runReflect()` instead.
|
|
1688
|
+
*/
|
|
1689
|
+
getLastReflectionHistory(): ReflectIterationRecord[] | null;
|
|
1690
|
+
/** Cross-agent derived values (frozen snapshot). Empty when derive not configured. */
|
|
1691
|
+
readonly derived: Record<string, unknown>;
|
|
1692
|
+
/** Subscribe to cross-agent derivation changes */
|
|
1693
|
+
onDerivedChange(callback: (id: string, value: unknown) => void): () => void;
|
|
1694
|
+
/** Shared scratchpad (null when not configured) */
|
|
1695
|
+
readonly scratchpad: Scratchpad | null;
|
|
1696
|
+
/** Dispose of the orchestrator, resetting all state */
|
|
1697
|
+
dispose(): void;
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Create a multi-agent orchestrator backed by a Directive System.
|
|
1701
|
+
*
|
|
1702
|
+
* Each registered agent becomes a namespaced Directive module with reactive state,
|
|
1703
|
+
* constraint evaluation, guardrails, streaming, approval, memory, retry, budget,
|
|
1704
|
+
* hooks, and time-travel debugging — all features at parity with `createAgentOrchestrator`.
|
|
1705
|
+
*
|
|
1706
|
+
* @example
|
|
1707
|
+
* ```typescript
|
|
1708
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
1709
|
+
* runner,
|
|
1710
|
+
* agents: {
|
|
1711
|
+
* researcher: { agent: researchAgent, maxConcurrent: 3 },
|
|
1712
|
+
* writer: { agent: writerAgent },
|
|
1713
|
+
* reviewer: { agent: reviewerAgent },
|
|
1714
|
+
* },
|
|
1715
|
+
* guardrails: {
|
|
1716
|
+
* input: [detectPII],
|
|
1717
|
+
* output: [checkToxicity],
|
|
1718
|
+
* },
|
|
1719
|
+
* hooks: {
|
|
1720
|
+
* onAgentStart: ({ agentId, input }) => console.log(`${agentId}: ${input}`),
|
|
1721
|
+
* },
|
|
1722
|
+
* maxTokenBudget: 50000,
|
|
1723
|
+
* debug: true,
|
|
1724
|
+
* });
|
|
1725
|
+
*
|
|
1726
|
+
* // Run with full guardrails + approval + streaming
|
|
1727
|
+
* const result = await orchestrator.runAgent('researcher', 'What is AI?');
|
|
1728
|
+
*
|
|
1729
|
+
* // Stream agent output
|
|
1730
|
+
* const { stream } = orchestrator.runAgentStream('writer', 'Write about AI');
|
|
1731
|
+
* for await (const chunk of stream) {
|
|
1732
|
+
* if (chunk.type === 'token') process.stdout.write(chunk.data);
|
|
1733
|
+
* }
|
|
1734
|
+
* ```
|
|
1735
|
+
*
|
|
1736
|
+
* @throws {Error} If a pattern references an agent that is not in the registry
|
|
1737
|
+
* @throws {Error} If autoApproveToolCalls is false but no onApprovalRequest callback is provided
|
|
1738
|
+
*/
|
|
1739
|
+
declare function createMultiAgentOrchestrator(options: MultiAgentOrchestratorOptions): MultiAgentOrchestrator;
|
|
1740
|
+
/**
|
|
1741
|
+
* Create a parallel pattern configuration.
|
|
1742
|
+
*
|
|
1743
|
+
* @param agents - Agent IDs to run concurrently
|
|
1744
|
+
* @param merge - Combine all agent results into a single output
|
|
1745
|
+
* @param config.merge - Receives all successful RunResults (array may be shorter than agents.length when minSuccess is set). Returns the merged result.
|
|
1746
|
+
* @param options - Optional `minSuccess` and `timeout` overrides
|
|
1747
|
+
*
|
|
1748
|
+
* @example
|
|
1749
|
+
* ```typescript
|
|
1750
|
+
* const researchPattern = parallel(
|
|
1751
|
+
* ['researcher', 'researcher', 'researcher'],
|
|
1752
|
+
* (results) => results.map(r => r.output).join('\n')
|
|
1753
|
+
* );
|
|
1754
|
+
* ```
|
|
1755
|
+
*/
|
|
1756
|
+
declare function parallel<T>(agents: string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
|
|
1757
|
+
minSuccess?: number;
|
|
1758
|
+
timeout?: number;
|
|
1759
|
+
}): ParallelPattern<T>;
|
|
1760
|
+
/**
|
|
1761
|
+
* Create a sequential pattern configuration.
|
|
1762
|
+
*
|
|
1763
|
+
* @param agents - Agent IDs to run in order (output of each feeds into the next)
|
|
1764
|
+
* @param options - Optional `transform`, `extract`, `continueOnError`
|
|
1765
|
+
*
|
|
1766
|
+
* @example
|
|
1767
|
+
* ```typescript
|
|
1768
|
+
* const writeReviewPattern = sequential(
|
|
1769
|
+
* ['writer', 'reviewer'],
|
|
1770
|
+
* { transform: (output) => `Review this: ${output}` }
|
|
1771
|
+
* );
|
|
1772
|
+
* ```
|
|
1773
|
+
*/
|
|
1774
|
+
declare function sequential<T>(agents: string[], options?: {
|
|
1775
|
+
transform?: (output: unknown, agentId: string, index: number) => string;
|
|
1776
|
+
extract?: (output: unknown) => T;
|
|
1777
|
+
continueOnError?: boolean;
|
|
1778
|
+
}): SequentialPattern<T>;
|
|
1779
|
+
/**
|
|
1780
|
+
* Create a supervisor pattern configuration.
|
|
1781
|
+
*
|
|
1782
|
+
* @param supervisorAgent - Agent ID that coordinates the workers
|
|
1783
|
+
* @param workers - Agent IDs for the worker pool
|
|
1784
|
+
* @param options - Optional `maxRounds` and `extract`
|
|
1785
|
+
*
|
|
1786
|
+
* @example
|
|
1787
|
+
* ```typescript
|
|
1788
|
+
* const managedPattern = supervisor(
|
|
1789
|
+
* 'manager',
|
|
1790
|
+
* ['worker1', 'worker2'],
|
|
1791
|
+
* { maxRounds: 3 }
|
|
1792
|
+
* );
|
|
1793
|
+
* ```
|
|
1794
|
+
*/
|
|
1795
|
+
declare function supervisor<T>(supervisorAgent: string, workers: string[], options?: {
|
|
1796
|
+
maxRounds?: number;
|
|
1797
|
+
extract?: (supervisorOutput: unknown, workerResults: RunResult<unknown>[]) => T;
|
|
1798
|
+
}): SupervisorPattern<T>;
|
|
1799
|
+
/**
|
|
1800
|
+
* Create a DAG execution pattern.
|
|
1801
|
+
*
|
|
1802
|
+
* @param nodes - Node definitions keyed by ID, each with `agent` and optional `deps`
|
|
1803
|
+
* @param merge - Combine DAG outputs into a single result (defaults to `context.outputs`)
|
|
1804
|
+
* @param options - Optional `timeout`, `maxConcurrent`, `onNodeError`
|
|
1805
|
+
*
|
|
1806
|
+
* @example
|
|
1807
|
+
* ```typescript
|
|
1808
|
+
* const researchPipeline = dag(
|
|
1809
|
+
* {
|
|
1810
|
+
* fetch: { agent: 'fetcher' },
|
|
1811
|
+
* analyze: { agent: 'analyzer', deps: ['fetch'] },
|
|
1812
|
+
* summarize: { agent: 'summarizer', deps: ['analyze'] },
|
|
1813
|
+
* },
|
|
1814
|
+
* (context) => context.outputs.summarize,
|
|
1815
|
+
* );
|
|
1816
|
+
* ```
|
|
1817
|
+
*/
|
|
1818
|
+
declare function dag<T = Record<string, unknown>>(nodes: Record<string, DagNode>, merge?: (context: DagExecutionContext) => T | Promise<T>, options?: {
|
|
1819
|
+
/** Overall timeout in ms for the entire DAG. */
|
|
1820
|
+
timeout?: number;
|
|
1821
|
+
/** Max nodes running concurrently. Default: Infinity */
|
|
1822
|
+
maxConcurrent?: number;
|
|
1823
|
+
/**
|
|
1824
|
+
* Error handling strategy.
|
|
1825
|
+
* - `"fail"` — abort entire DAG on first node error (default)
|
|
1826
|
+
* - `"skip-downstream"` — mark downstream nodes as skipped, other branches continue
|
|
1827
|
+
* - `"continue"` — ignore errors, other branches continue
|
|
1828
|
+
*/
|
|
1829
|
+
onNodeError?: "fail" | "skip-downstream" | "continue";
|
|
1830
|
+
}): DagPattern<T>;
|
|
1831
|
+
/**
|
|
1832
|
+
* Create a reflect pattern configuration.
|
|
1833
|
+
*
|
|
1834
|
+
* @param agent - Producer agent ID that generates output
|
|
1835
|
+
* @param evaluator - Evaluator agent ID that judges quality
|
|
1836
|
+
* @param options - Optional iteration, parsing, signal, and threshold config
|
|
1837
|
+
*
|
|
1838
|
+
* @example
|
|
1839
|
+
* ```typescript
|
|
1840
|
+
* const reviewPattern = reflect('writer', 'reviewer', { maxIterations: 2 });
|
|
1841
|
+
* ```
|
|
1842
|
+
*/
|
|
1843
|
+
declare function reflect<T>(agent: string, evaluator: string, options?: {
|
|
1844
|
+
maxIterations?: number;
|
|
1845
|
+
parseEvaluation?: (output: unknown) => ReflectionEvaluation;
|
|
1846
|
+
buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
|
|
1847
|
+
extract?: (output: unknown) => T;
|
|
1848
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
1849
|
+
onIteration?: (record: ReflectIterationRecord) => void;
|
|
1850
|
+
signal?: AbortSignal;
|
|
1851
|
+
timeout?: number;
|
|
1852
|
+
threshold?: number | ((iteration: number) => number);
|
|
1853
|
+
}): ReflectPattern<T>;
|
|
1854
|
+
/**
|
|
1855
|
+
* Create a race pattern configuration.
|
|
1856
|
+
*
|
|
1857
|
+
* @param agents - Agent IDs to race concurrently
|
|
1858
|
+
* @param options - Optional `extract`, `timeout`, `minSuccess`, `signal`
|
|
1859
|
+
*
|
|
1860
|
+
* @example
|
|
1861
|
+
* ```typescript
|
|
1862
|
+
* const fastest = race(['fast-model', 'smart-model'], { timeout: 5000 });
|
|
1863
|
+
* ```
|
|
1864
|
+
*/
|
|
1865
|
+
declare function race<T>(agents: string[], options?: {
|
|
1866
|
+
extract?: (result: RunResult<unknown>) => T;
|
|
1867
|
+
timeout?: number;
|
|
1868
|
+
minSuccess?: number;
|
|
1869
|
+
signal?: AbortSignal;
|
|
1870
|
+
}): RacePattern<T>;
|
|
1871
|
+
/**
|
|
1872
|
+
* Create a goal execution pattern.
|
|
1873
|
+
*
|
|
1874
|
+
* Declare what each agent produces and requires. The runtime automatically
|
|
1875
|
+
* infers the execution graph from dependency analysis and drives agents
|
|
1876
|
+
* to goal achievement.
|
|
1877
|
+
*
|
|
1878
|
+
* @example
|
|
1879
|
+
* ```typescript
|
|
1880
|
+
* const pipeline = goal(
|
|
1881
|
+
* {
|
|
1882
|
+
* researcher: {
|
|
1883
|
+
* agent: "researcher",
|
|
1884
|
+
* produces: ["research.findings"],
|
|
1885
|
+
* requires: ["research.topic"],
|
|
1886
|
+
* extractOutput: (r) => ({ "research.findings": r.output }),
|
|
1887
|
+
* },
|
|
1888
|
+
* writer: {
|
|
1889
|
+
* agent: "writer",
|
|
1890
|
+
* produces: ["article.draft"],
|
|
1891
|
+
* requires: ["research.findings"],
|
|
1892
|
+
* extractOutput: (r) => ({ "article.draft": r.output }),
|
|
1893
|
+
* },
|
|
1894
|
+
* },
|
|
1895
|
+
* (facts) => facts["article.draft"] != null,
|
|
1896
|
+
* { maxSteps: 10, extract: (facts) => facts["article.draft"] },
|
|
1897
|
+
* );
|
|
1898
|
+
* ```
|
|
1899
|
+
*/
|
|
1900
|
+
declare function goal<T = Record<string, unknown>>(nodes: Record<string, GoalNode>, when: (facts: Record<string, unknown>) => boolean, options?: {
|
|
1901
|
+
satisfaction?: (facts: Record<string, unknown>) => number;
|
|
1902
|
+
maxSteps?: number;
|
|
1903
|
+
extract?: (facts: Record<string, unknown>) => T;
|
|
1904
|
+
timeout?: number;
|
|
1905
|
+
signal?: AbortSignal;
|
|
1906
|
+
selectionStrategy?: AgentSelectionStrategy;
|
|
1907
|
+
relaxation?: RelaxationTier[];
|
|
1908
|
+
onStep?: (step: number, facts: Record<string, unknown>, readyNodes: string[]) => void;
|
|
1909
|
+
onStall?: (step: number, metrics: GoalMetrics) => void;
|
|
1910
|
+
checkpoint?: PatternCheckpointConfig;
|
|
1911
|
+
}): GoalPattern<T>;
|
|
1912
|
+
/**
|
|
1913
|
+
* Selection strategy: run all ready agents (default).
|
|
1914
|
+
*/
|
|
1915
|
+
declare function allReadyStrategy(): AgentSelectionStrategy;
|
|
1916
|
+
/**
|
|
1917
|
+
* Selection strategy: pick agents with the highest historical impact.
|
|
1918
|
+
*
|
|
1919
|
+
* Sorts by average satisfaction delta (descending) and picks the top N.
|
|
1920
|
+
*/
|
|
1921
|
+
declare function highestImpactStrategy(opts?: {
|
|
1922
|
+
topN?: number;
|
|
1923
|
+
}): AgentSelectionStrategy;
|
|
1924
|
+
/**
|
|
1925
|
+
* Selection strategy: prefer agents that consume fewer tokens per satisfaction delta.
|
|
1926
|
+
*/
|
|
1927
|
+
declare function costEfficientStrategy(): AgentSelectionStrategy;
|
|
1928
|
+
/**
|
|
1929
|
+
* Create an agent selection constraint.
|
|
1930
|
+
*
|
|
1931
|
+
* @example
|
|
1932
|
+
* ```typescript
|
|
1933
|
+
* const constraints = {
|
|
1934
|
+
* routeToExpert: selectAgent(
|
|
1935
|
+
* (facts) => facts.complexity > 0.8,
|
|
1936
|
+
* 'expert',
|
|
1937
|
+
* (facts) => facts.query
|
|
1938
|
+
* ),
|
|
1939
|
+
* };
|
|
1940
|
+
* ```
|
|
1941
|
+
*/
|
|
1942
|
+
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>>;
|
|
1943
|
+
/**
|
|
1944
|
+
* Create a RUN_AGENT requirement.
|
|
1945
|
+
*
|
|
1946
|
+
* @example
|
|
1947
|
+
* ```typescript
|
|
1948
|
+
* constraints: {
|
|
1949
|
+
* needsResearch: {
|
|
1950
|
+
* when: (facts) => facts.hasUnknowns,
|
|
1951
|
+
* require: (facts) => runAgentRequirement('researcher', facts.query as string),
|
|
1952
|
+
* },
|
|
1953
|
+
* }
|
|
1954
|
+
* ```
|
|
1955
|
+
*/
|
|
1956
|
+
declare function runAgentRequirement(agent: string, input: string, context?: Record<string, unknown>): RunAgentRequirement;
|
|
1957
|
+
/**
|
|
1958
|
+
* Merge results by concatenating outputs.
|
|
1959
|
+
*/
|
|
1960
|
+
declare function concatResults(results: RunResult<unknown>[], separator?: string): string;
|
|
1961
|
+
/**
|
|
1962
|
+
* Merge results by picking the best one based on a scoring function.
|
|
1963
|
+
*/
|
|
1964
|
+
declare function pickBestResult<T>(results: RunResult<T>[], score: (result: RunResult<T>) => number): RunResult<T>;
|
|
1965
|
+
/**
|
|
1966
|
+
* Merge results into an array of outputs.
|
|
1967
|
+
*/
|
|
1968
|
+
declare function collectOutputs<T>(results: RunResult<T>[]): T[];
|
|
1969
|
+
/**
|
|
1970
|
+
* Aggregate token counts from results.
|
|
1971
|
+
*/
|
|
1972
|
+
declare function aggregateTokens(results: RunResult<unknown>[]): number;
|
|
1973
|
+
/**
|
|
1974
|
+
* Compose multiple patterns into a pipeline where each pattern's
|
|
1975
|
+
* output feeds as input to the next. Returns an async function
|
|
1976
|
+
* that runs the pipeline on a given orchestrator.
|
|
1977
|
+
*
|
|
1978
|
+
* Between patterns, output is converted to a string input:
|
|
1979
|
+
* - `string` output passes through directly
|
|
1980
|
+
* - Objects are JSON-stringified
|
|
1981
|
+
* - Optionally provide a `transform` to customize between steps
|
|
1982
|
+
*
|
|
1983
|
+
* @example
|
|
1984
|
+
* ```typescript
|
|
1985
|
+
* const workflow = composePatterns(
|
|
1986
|
+
* parallel(['researcher', 'researcher'], concatResults),
|
|
1987
|
+
* sequential(['writer', 'reviewer']),
|
|
1988
|
+
* );
|
|
1989
|
+
*
|
|
1990
|
+
* const result = await workflow(orchestrator, 'Research topic X');
|
|
1991
|
+
* ```
|
|
1992
|
+
*/
|
|
1993
|
+
declare function composePatterns(...patterns: ExecutionPattern[]): (orchestrator: MultiAgentOrchestrator, input: string) => Promise<unknown>;
|
|
1994
|
+
/**
|
|
1995
|
+
* Create a capability-based agent selector.
|
|
1996
|
+
*
|
|
1997
|
+
* Given a registry and required capabilities, returns the agent IDs
|
|
1998
|
+
* that match all required capabilities.
|
|
1999
|
+
*
|
|
2000
|
+
* @example
|
|
2001
|
+
* ```typescript
|
|
2002
|
+
* const agents = {
|
|
2003
|
+
* researcher: { agent: researchAgent, capabilities: ['search', 'summarize'] },
|
|
2004
|
+
* coder: { agent: coderAgent, capabilities: ['code', 'debug'] },
|
|
2005
|
+
* writer: { agent: writerAgent, capabilities: ['write', 'edit'] },
|
|
2006
|
+
* };
|
|
2007
|
+
*
|
|
2008
|
+
* const matches = findAgentsByCapability(agents, ['search']);
|
|
2009
|
+
* // Returns ['researcher']
|
|
2010
|
+
*
|
|
2011
|
+
* const matches2 = findAgentsByCapability(agents, ['write', 'edit']);
|
|
2012
|
+
* // Returns ['writer']
|
|
2013
|
+
* ```
|
|
2014
|
+
*/
|
|
2015
|
+
declare function findAgentsByCapability(registry: AgentRegistry, requiredCapabilities: string[]): string[];
|
|
2016
|
+
/**
|
|
2017
|
+
* Create a constraint that auto-routes to an agent based on capabilities.
|
|
2018
|
+
*
|
|
2019
|
+
* @example
|
|
2020
|
+
* ```typescript
|
|
2021
|
+
* const routeByCapability = capabilityRoute(
|
|
2022
|
+
* agents,
|
|
2023
|
+
* (facts) => facts.requiredCapabilities as string[],
|
|
2024
|
+
* (facts) => facts.query as string,
|
|
2025
|
+
* );
|
|
2026
|
+
* ```
|
|
2027
|
+
*/
|
|
2028
|
+
declare function capabilityRoute(registry: AgentRegistry, getCapabilities: (facts: Record<string, unknown>) => string[], getInput: (facts: Record<string, unknown>) => string, options?: {
|
|
2029
|
+
priority?: number;
|
|
2030
|
+
select?: (matches: string[], registry: AgentRegistry) => string;
|
|
2031
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
2032
|
+
/**
|
|
2033
|
+
* Options for spawnOnCondition.
|
|
2034
|
+
*/
|
|
2035
|
+
interface SpawnOnConditionOptions {
|
|
2036
|
+
/** Priority for the constraint (higher = evaluated first) */
|
|
2037
|
+
priority?: number;
|
|
2038
|
+
/** Additional context passed to the agent */
|
|
2039
|
+
context?: Record<string, unknown>;
|
|
2040
|
+
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Create a constraint that auto-runs an agent when a condition is met.
|
|
2043
|
+
*
|
|
2044
|
+
* The orchestrator's built-in RUN_AGENT resolver handles execution —
|
|
2045
|
+
* you only need to add this to your `constraints` config.
|
|
2046
|
+
*
|
|
2047
|
+
* @example
|
|
2048
|
+
* ```typescript
|
|
2049
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
2050
|
+
* agents: { reviewer: { agent: reviewerAgent } },
|
|
2051
|
+
* constraints: {
|
|
2052
|
+
* autoReview: spawnOnCondition({
|
|
2053
|
+
* when: (facts) => (facts.confidence as number) < 0.7,
|
|
2054
|
+
* agent: 'reviewer',
|
|
2055
|
+
* input: (facts) => `Review this: ${facts.lastOutput}`,
|
|
2056
|
+
* }),
|
|
2057
|
+
* },
|
|
2058
|
+
* });
|
|
2059
|
+
* ```
|
|
2060
|
+
*/
|
|
2061
|
+
declare function spawnOnCondition(config: {
|
|
2062
|
+
when: (facts: Record<string, unknown>) => boolean;
|
|
2063
|
+
agent: string;
|
|
2064
|
+
input: (facts: Record<string, unknown>) => string;
|
|
2065
|
+
/** Priority for the constraint (higher = evaluated first) */
|
|
2066
|
+
priority?: number;
|
|
2067
|
+
/** Additional context passed to the agent */
|
|
2068
|
+
context?: Record<string, unknown>;
|
|
2069
|
+
/** @deprecated Use top-level `priority` and `context` instead */
|
|
2070
|
+
options?: SpawnOnConditionOptions;
|
|
2071
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
2072
|
+
/** Configuration for the debate() factory and runDebate() imperative API. @see DebatePattern */
|
|
2073
|
+
type DebateConfig<T = unknown> = Omit<DebatePattern<T>, "type">;
|
|
2074
|
+
/**
|
|
2075
|
+
* Create a debate pattern where agents compete and an evaluator picks the best.
|
|
2076
|
+
*
|
|
2077
|
+
* Flow:
|
|
2078
|
+
* 1. All agents produce proposals in parallel
|
|
2079
|
+
* 2. Evaluator receives all proposals and picks a winner
|
|
2080
|
+
* 3. Optionally repeat with evaluator feedback for refinement
|
|
2081
|
+
*
|
|
2082
|
+
* @param config - Debate configuration with `agents`, `evaluator`, and optional settings
|
|
2083
|
+
* @see runDebate for the imperative API
|
|
2084
|
+
*
|
|
2085
|
+
* @example
|
|
2086
|
+
* ```typescript
|
|
2087
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
2088
|
+
* agents: {
|
|
2089
|
+
* optimist: { agent: optimistAgent },
|
|
2090
|
+
* pessimist: { agent: pessimistAgent },
|
|
2091
|
+
* judge: { agent: judgeAgent },
|
|
2092
|
+
* },
|
|
2093
|
+
* patterns: {
|
|
2094
|
+
* debate: debate({
|
|
2095
|
+
* agents: ['optimist', 'pessimist'],
|
|
2096
|
+
* evaluator: 'judge',
|
|
2097
|
+
* maxRounds: 2,
|
|
2098
|
+
* }),
|
|
2099
|
+
* },
|
|
2100
|
+
* });
|
|
2101
|
+
*
|
|
2102
|
+
* const result = await orchestrator.runPattern('debate', 'Should we invest in X?');
|
|
2103
|
+
* ```
|
|
2104
|
+
*/
|
|
2105
|
+
declare function debate<T = unknown>(config: DebateConfig<T>): DebatePattern<T>;
|
|
2106
|
+
/**
|
|
2107
|
+
* Run a debate imperatively on an orchestrator (no pattern registration needed).
|
|
2108
|
+
* Delegates to `orchestrator.runDebate()` so that lifecycle hooks, debug timeline,
|
|
2109
|
+
* and signal propagation all work correctly.
|
|
2110
|
+
*
|
|
2111
|
+
* @param orchestrator - The multi-agent orchestrator instance
|
|
2112
|
+
* @param config - Debate configuration with agents, evaluator, and optional settings
|
|
2113
|
+
* @param input - The initial input/prompt for the debate
|
|
2114
|
+
* @see debate for the declarative pattern API
|
|
2115
|
+
* @returns The winning agent's output, the winner ID, and all proposals from each round
|
|
2116
|
+
*/
|
|
2117
|
+
declare function runDebate<T>(orchestrator: MultiAgentOrchestrator, config: DebateConfig<T>, input: string): Promise<DebateResult<T>>;
|
|
2118
|
+
/**
|
|
2119
|
+
* Create a constraint that fires when a cross-agent derivation meets a condition.
|
|
2120
|
+
*
|
|
2121
|
+
* Wire this into the orchestrator's `derive` config and `constraints` config together.
|
|
2122
|
+
* The constraint's `when()` reads the derivation value from the orchestrator's derived snapshot.
|
|
2123
|
+
*
|
|
2124
|
+
* @example
|
|
2125
|
+
* ```typescript
|
|
2126
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
2127
|
+
* agents: { ... },
|
|
2128
|
+
* derive: {
|
|
2129
|
+
* totalCost: (snap) => snap.coordinator.globalTokens * 0.001,
|
|
2130
|
+
* },
|
|
2131
|
+
* constraints: {
|
|
2132
|
+
* budgetAlert: derivedConstraint('totalCost', (cost) => cost > 5.0, {
|
|
2133
|
+
* agent: 'budget-manager',
|
|
2134
|
+
* input: (value) => `Budget exceeded: $${value}`,
|
|
2135
|
+
* }),
|
|
2136
|
+
* },
|
|
2137
|
+
* });
|
|
2138
|
+
* ```
|
|
2139
|
+
*/
|
|
2140
|
+
declare function derivedConstraint(derivationId: string, condition: (value: unknown) => boolean, action: {
|
|
2141
|
+
agent: string;
|
|
2142
|
+
input: (value: unknown) => string;
|
|
2143
|
+
priority?: number;
|
|
2144
|
+
context?: Record<string, unknown>;
|
|
2145
|
+
}): OrchestratorConstraint<Record<string, unknown>>;
|
|
2146
|
+
/** Configuration for spawnPool constraint-driven auto-scaling */
|
|
2147
|
+
interface SpawnPoolConfig {
|
|
2148
|
+
/** Agent ID to spawn (must be registered in the orchestrator) */
|
|
2149
|
+
agent: string;
|
|
2150
|
+
/** Build the input for each spawned agent. Receives current facts and spawn index (0-based). */
|
|
2151
|
+
input: (facts: Record<string, unknown>, index: number) => string;
|
|
2152
|
+
/** How many agents to spawn. Number or function of facts for dynamic scaling. */
|
|
2153
|
+
count: number | ((facts: Record<string, unknown>) => number);
|
|
2154
|
+
/** Priority for the constraint. @default undefined */
|
|
2155
|
+
priority?: number;
|
|
2156
|
+
/** Additional context passed to each spawned agent */
|
|
2157
|
+
context?: Record<string, unknown>;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Create a constraint that spawns a pool of agent instances when a condition is met.
|
|
2161
|
+
*
|
|
2162
|
+
* Unlike `spawnOnCondition` (which spawns one agent), `spawnPool` can target N agents.
|
|
2163
|
+
* However, only **one requirement is emitted per constraint evaluation cycle** — the constraint
|
|
2164
|
+
* re-fires on subsequent cycles as long as `when()` returns true, spawning one agent per cycle.
|
|
2165
|
+
*
|
|
2166
|
+
* @see spawnOnCondition — for spawning a single agent
|
|
2167
|
+
*
|
|
2168
|
+
* @example
|
|
2169
|
+
* ```typescript
|
|
2170
|
+
* const orchestrator = createMultiAgentOrchestrator({
|
|
2171
|
+
* agents: { worker: { agent: workerAgent } },
|
|
2172
|
+
* constraints: {
|
|
2173
|
+
* scaleWorkers: spawnPool(
|
|
2174
|
+
* (facts) => (facts.pendingTasks as number) > 0,
|
|
2175
|
+
* {
|
|
2176
|
+
* agent: 'worker',
|
|
2177
|
+
* count: (facts) => Math.min(facts.pendingTasks as number, 5),
|
|
2178
|
+
* input: (facts, i) => `Process task ${i + 1}`,
|
|
2179
|
+
* },
|
|
2180
|
+
* ),
|
|
2181
|
+
* },
|
|
2182
|
+
* });
|
|
2183
|
+
* ```
|
|
2184
|
+
*/
|
|
2185
|
+
declare function spawnPool(when: (facts: Record<string, unknown>) => boolean, config: SpawnPoolConfig): OrchestratorConstraint<Record<string, unknown>>;
|
|
2186
|
+
/** Serialized DAG node (functions stripped) */
|
|
2187
|
+
interface SerializedDagNode {
|
|
2188
|
+
agent: string;
|
|
2189
|
+
deps?: string[];
|
|
2190
|
+
timeout?: number;
|
|
2191
|
+
priority?: number;
|
|
2192
|
+
}
|
|
2193
|
+
/** JSON-safe representation of any execution pattern (all functions stripped) */
|
|
2194
|
+
type SerializedPattern = {
|
|
2195
|
+
type: "parallel";
|
|
2196
|
+
agents: string[];
|
|
2197
|
+
minSuccess?: number;
|
|
2198
|
+
timeout?: number;
|
|
2199
|
+
} | {
|
|
2200
|
+
type: "sequential";
|
|
2201
|
+
agents: string[];
|
|
2202
|
+
continueOnError?: boolean;
|
|
2203
|
+
} | {
|
|
2204
|
+
type: "supervisor";
|
|
2205
|
+
supervisor: string;
|
|
2206
|
+
workers: string[];
|
|
2207
|
+
maxRounds?: number;
|
|
2208
|
+
} | {
|
|
2209
|
+
type: "dag";
|
|
2210
|
+
nodes: Record<string, SerializedDagNode>;
|
|
2211
|
+
timeout?: number;
|
|
2212
|
+
maxConcurrent?: number;
|
|
2213
|
+
onNodeError?: "fail" | "skip-downstream" | "continue";
|
|
2214
|
+
} | {
|
|
2215
|
+
type: "reflect";
|
|
2216
|
+
agent: string;
|
|
2217
|
+
evaluator: string;
|
|
2218
|
+
maxIterations?: number;
|
|
2219
|
+
onExhausted?: "accept-last" | "accept-best" | "throw";
|
|
2220
|
+
timeout?: number;
|
|
2221
|
+
threshold?: number;
|
|
2222
|
+
} | {
|
|
2223
|
+
type: "race";
|
|
2224
|
+
agents: string[];
|
|
2225
|
+
timeout?: number;
|
|
2226
|
+
minSuccess?: number;
|
|
2227
|
+
} | {
|
|
2228
|
+
type: "debate";
|
|
2229
|
+
agents: string[];
|
|
2230
|
+
evaluator: string;
|
|
2231
|
+
maxRounds?: number;
|
|
2232
|
+
timeout?: number;
|
|
2233
|
+
} | {
|
|
2234
|
+
type: "goal";
|
|
2235
|
+
nodes: Record<string, SerializedGoalNode>;
|
|
2236
|
+
maxSteps?: number;
|
|
2237
|
+
timeout?: number;
|
|
2238
|
+
};
|
|
2239
|
+
/** Serialized goal node (functions stripped) */
|
|
2240
|
+
interface SerializedGoalNode {
|
|
2241
|
+
agent: string;
|
|
2242
|
+
produces: string[];
|
|
2243
|
+
requires?: string[];
|
|
2244
|
+
allowRerun?: boolean;
|
|
2245
|
+
priority?: number;
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* Serialize an execution pattern to a JSON-safe object.
|
|
2249
|
+
*
|
|
2250
|
+
* Strips all function callbacks and runtime objects (AbortSignal) while
|
|
2251
|
+
* preserving the topology — which agents, in what structure, with what
|
|
2252
|
+
* numeric/string/boolean options.
|
|
2253
|
+
*
|
|
2254
|
+
* Use this for visual editors, LLM-generated plans, persistence, or
|
|
2255
|
+
* debugging. Restore with {@link patternFromJSON}.
|
|
2256
|
+
*
|
|
2257
|
+
* Note: Function-form `threshold` on reflect patterns is not serializable and will be dropped.
|
|
2258
|
+
* Re-supply it via `overrides` when calling {@link patternFromJSON}.
|
|
2259
|
+
*
|
|
2260
|
+
* @example
|
|
2261
|
+
* ```typescript
|
|
2262
|
+
* const p = parallel({ agents: ["a", "b"], merge: (r) => r });
|
|
2263
|
+
* const json = patternToJSON(p);
|
|
2264
|
+
* // { type: "parallel", agents: ["a", "b"] }
|
|
2265
|
+
* localStorage.setItem("plan", JSON.stringify(json));
|
|
2266
|
+
* ```
|
|
2267
|
+
*/
|
|
2268
|
+
declare function patternToJSON(pattern: ExecutionPattern<unknown>): SerializedPattern;
|
|
2269
|
+
/**
|
|
2270
|
+
* Restore an execution pattern from its serialized form.
|
|
2271
|
+
*
|
|
2272
|
+
* Returns the data structure with all function fields set to `undefined`.
|
|
2273
|
+
* Supply callbacks via the optional `overrides` parameter to re-attach
|
|
2274
|
+
* runtime behavior.
|
|
2275
|
+
*
|
|
2276
|
+
* @example
|
|
2277
|
+
* ```typescript
|
|
2278
|
+
* const json = JSON.parse(localStorage.getItem("plan")!);
|
|
2279
|
+
* const pattern = patternFromJSON<string[]>(json, {
|
|
2280
|
+
* merge: (results) => results.map(r => r.output as string),
|
|
2281
|
+
* });
|
|
2282
|
+
* // Use the imperative API — runPattern takes a registered pattern ID, not an object
|
|
2283
|
+
* if (pattern.type === "parallel") {
|
|
2284
|
+
* const result = await orchestrator.runParallel(pattern.agents, input, pattern.merge);
|
|
2285
|
+
* }
|
|
2286
|
+
* ```
|
|
2287
|
+
*/
|
|
2288
|
+
declare function patternFromJSON<T = unknown>(json: SerializedPattern, overrides?: Partial<ExecutionPattern<T>>): ExecutionPattern<T>;
|
|
2289
|
+
|
|
2290
|
+
export { type SafeParseResult as $, type AgentHealthMetrics as A, type BackpressureStrategy as B, type MultiplexedStreamChunk as C, type DebugTimeline as D, type ExecutionPattern as E, type MultiplexedStreamResult as F, type GuardrailTriggeredChunk as G, type HealthMonitor as H, type OrchestratorStreamChunk as I, type OrchestratorStreamResult as J, type ProgressChunk as K, type RaceResult as L, type MemoryManageResult as M, type RaceSuccessEntry as N, type OrchestratorOptions as O, type ParallelPattern as P, type ReflectIterationRecord as Q, type RacePattern as R, type SerializedPattern as S, type ReflectPattern as T, type ReflectionConfig as U, type ReflectionContext as V, type ReflectionEvaluation as W, type ReflectionEvaluator as X, ReflectionExhaustedError as Y, type RunAgentRequirement as Z, type RunCallOptions as _, type AgentMemory as a, race as a$, type SafeParseable as a0, Semaphore as a1, type SequentialPattern as a2, type SerializedDagNode as a3, type SerializedGoalNode as a4, type SpawnOnConditionOptions as a5, type SpawnPoolConfig as a6, type StreamChunk as a7, type StreamRunOptions as a8, type StreamRunner as a9, createLLMSummarizer as aA, createLengthStreamingGuardrail as aB, createMultiAgentOrchestrator as aC, createPatternStreamingGuardrail as aD, createSlidingWindowStrategy as aE, createStreamingRunner as aF, createTokenBasedStrategy as aG, createToxicityStreamingGuardrail as aH, createTruncationSummarizer as aI, dag as aJ, debate as aK, derivedConstraint as aL, diffCheckpoints as aM, extractJsonFromOutput as aN, filterStream as aO, findAgentsByCapability as aP, forkFromCheckpoint as aQ, getCheckpointProgress as aR, getPatternStep as aS, goal as aT, highestImpactStrategy as aU, mapStream as aV, mergeTaggedStreams as aW, parallel as aX, patternFromJSON as aY, patternToJSON as aZ, pickBestResult as a_, type StreamingGuardrail as aa, type StreamingGuardrailResult as ab, type StreamingRunResult as ac, type StructuredOutputConfig as ad, StructuredOutputError as ae, type SupervisorPattern as af, type TokenChunk as ag, type ToolEndChunk as ah, type ToolStartChunk as ai, adaptOutputGuardrail as aj, aggregateTokens as ak, allReadyStrategy as al, capabilityRoute as am, collectOutputs as an, collectTokens as ao, combineStreamingGuardrails as ap, composePatterns as aq, concatResults as ar, costEfficientStrategy as as, createAgentMemory as at, createAgentOrchestrator as au, createDebugTimeline as av, createDebugTimelinePlugin as aw, createHealthMonitor as ax, createHybridStrategy as ay, createKeyPointsSummarizer as az, type AgentMemoryConfig as b, reflect as b0, runAgentRequirement as b1, runDebate as b2, selectAgent as b3, sequential as b4, spawnOnCondition as b5, spawnPool as b6, supervisor as b7, tapStream as b8, withReflection as b9, withStructuredOutput as ba, type AgentOrchestrator as c, type AgentRegistration as d, type AgentRegistry as e, type DebateConfig as f, type DebatePattern as g, type DebateResult as h, type DebugTimelineListener as i, type DebugTimelineOptions as j, type DoneChunk as k, type ErrorChunk as l, type HandoffRequest as m, type HandoffResult as n, type HealthCircuitState as o, type MemoryState as p, type MemoryStrategy as q, type MemoryStrategyConfig as r, type MemoryStrategyResult as s, type MergedTaggedStreamResult as t, type MessageChunk as u, type MessageSummarizer as v, type MultiAgentOrchestrator as w, type MultiAgentOrchestratorOptions as x, type MultiAgentRunCallOptions as y, type MultiAgentState as z };
|