@open-multi-agent/core 1.4.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/LICENSE +21 -0
- package/README.md +373 -0
- package/dist/agent/agent.d.ts +153 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +559 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/loop-detector.d.ts +39 -0
- package/dist/agent/loop-detector.d.ts.map +1 -0
- package/dist/agent/loop-detector.js +122 -0
- package/dist/agent/loop-detector.js.map +1 -0
- package/dist/agent/pool.d.ts +158 -0
- package/dist/agent/pool.d.ts.map +1 -0
- package/dist/agent/pool.js +320 -0
- package/dist/agent/pool.js.map +1 -0
- package/dist/agent/runner.d.ts +242 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +943 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/structured-output.d.ts +33 -0
- package/dist/agent/structured-output.d.ts.map +1 -0
- package/dist/agent/structured-output.js +116 -0
- package/dist/agent/structured-output.js.map +1 -0
- package/dist/cli/oma.d.ts +30 -0
- package/dist/cli/oma.d.ts.map +1 -0
- package/dist/cli/oma.js +433 -0
- package/dist/cli/oma.js.map +1 -0
- package/dist/dashboard/layout-tasks.d.ts +23 -0
- package/dist/dashboard/layout-tasks.d.ts.map +1 -0
- package/dist/dashboard/layout-tasks.js +79 -0
- package/dist/dashboard/layout-tasks.js.map +1 -0
- package/dist/dashboard/render-team-run-dashboard.d.ts +11 -0
- package/dist/dashboard/render-team-run-dashboard.d.ts.map +1 -0
- package/dist/dashboard/render-team-run-dashboard.js +456 -0
- package/dist/dashboard/render-team-run-dashboard.js.map +1 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/adapter.d.ts +54 -0
- package/dist/llm/adapter.d.ts.map +1 -0
- package/dist/llm/adapter.js +101 -0
- package/dist/llm/adapter.js.map +1 -0
- package/dist/llm/anthropic.d.ts +57 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +432 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/azure-openai.d.ts +74 -0
- package/dist/llm/azure-openai.d.ts.map +1 -0
- package/dist/llm/azure-openai.js +267 -0
- package/dist/llm/azure-openai.js.map +1 -0
- package/dist/llm/bedrock.d.ts +41 -0
- package/dist/llm/bedrock.d.ts.map +1 -0
- package/dist/llm/bedrock.js +345 -0
- package/dist/llm/bedrock.js.map +1 -0
- package/dist/llm/copilot.d.ts +92 -0
- package/dist/llm/copilot.d.ts.map +1 -0
- package/dist/llm/copilot.js +433 -0
- package/dist/llm/copilot.js.map +1 -0
- package/dist/llm/deepseek.d.ts +21 -0
- package/dist/llm/deepseek.d.ts.map +1 -0
- package/dist/llm/deepseek.js +24 -0
- package/dist/llm/deepseek.js.map +1 -0
- package/dist/llm/gemini.d.ts +65 -0
- package/dist/llm/gemini.d.ts.map +1 -0
- package/dist/llm/gemini.js +427 -0
- package/dist/llm/gemini.js.map +1 -0
- package/dist/llm/grok.d.ts +21 -0
- package/dist/llm/grok.d.ts.map +1 -0
- package/dist/llm/grok.js +24 -0
- package/dist/llm/grok.js.map +1 -0
- package/dist/llm/minimax.d.ts +21 -0
- package/dist/llm/minimax.d.ts.map +1 -0
- package/dist/llm/minimax.js +24 -0
- package/dist/llm/minimax.js.map +1 -0
- package/dist/llm/openai-common.d.ts +65 -0
- package/dist/llm/openai-common.d.ts.map +1 -0
- package/dist/llm/openai-common.js +286 -0
- package/dist/llm/openai-common.js.map +1 -0
- package/dist/llm/openai.d.ts +63 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +256 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/qiniu.d.ts +21 -0
- package/dist/llm/qiniu.d.ts.map +1 -0
- package/dist/llm/qiniu.js +24 -0
- package/dist/llm/qiniu.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +2 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory/shared.d.ts +162 -0
- package/dist/memory/shared.d.ts.map +1 -0
- package/dist/memory/shared.js +294 -0
- package/dist/memory/shared.js.map +1 -0
- package/dist/memory/store.d.ts +72 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +121 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +245 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +1400 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +112 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +256 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/task/queue.d.ts +191 -0
- package/dist/task/queue.d.ts.map +1 -0
- package/dist/task/queue.js +408 -0
- package/dist/task/queue.js.map +1 -0
- package/dist/task/task.d.ts +90 -0
- package/dist/task/task.d.ts.map +1 -0
- package/dist/task/task.js +206 -0
- package/dist/task/task.js.map +1 -0
- package/dist/team/messaging.d.ts +106 -0
- package/dist/team/messaging.d.ts.map +1 -0
- package/dist/team/messaging.js +183 -0
- package/dist/team/messaging.js.map +1 -0
- package/dist/team/team.d.ts +141 -0
- package/dist/team/team.d.ts.map +1 -0
- package/dist/team/team.js +293 -0
- package/dist/team/team.js.map +1 -0
- package/dist/tool/built-in/bash.d.ts +12 -0
- package/dist/tool/built-in/bash.d.ts.map +1 -0
- package/dist/tool/built-in/bash.js +133 -0
- package/dist/tool/built-in/bash.js.map +1 -0
- package/dist/tool/built-in/delegate.d.ts +29 -0
- package/dist/tool/built-in/delegate.d.ts.map +1 -0
- package/dist/tool/built-in/delegate.js +92 -0
- package/dist/tool/built-in/delegate.js.map +1 -0
- package/dist/tool/built-in/file-edit.d.ts +14 -0
- package/dist/tool/built-in/file-edit.d.ts.map +1 -0
- package/dist/tool/built-in/file-edit.js +130 -0
- package/dist/tool/built-in/file-edit.js.map +1 -0
- package/dist/tool/built-in/file-read.d.ts +12 -0
- package/dist/tool/built-in/file-read.d.ts.map +1 -0
- package/dist/tool/built-in/file-read.js +82 -0
- package/dist/tool/built-in/file-read.js.map +1 -0
- package/dist/tool/built-in/file-write.d.ts +11 -0
- package/dist/tool/built-in/file-write.d.ts.map +1 -0
- package/dist/tool/built-in/file-write.js +70 -0
- package/dist/tool/built-in/file-write.js.map +1 -0
- package/dist/tool/built-in/fs-walk.d.ts +23 -0
- package/dist/tool/built-in/fs-walk.d.ts.map +1 -0
- package/dist/tool/built-in/fs-walk.js +78 -0
- package/dist/tool/built-in/fs-walk.js.map +1 -0
- package/dist/tool/built-in/glob.d.ts +12 -0
- package/dist/tool/built-in/glob.d.ts.map +1 -0
- package/dist/tool/built-in/glob.js +82 -0
- package/dist/tool/built-in/glob.js.map +1 -0
- package/dist/tool/built-in/grep.d.ts +15 -0
- package/dist/tool/built-in/grep.d.ts.map +1 -0
- package/dist/tool/built-in/grep.js +218 -0
- package/dist/tool/built-in/grep.js.map +1 -0
- package/dist/tool/built-in/index.d.ts +48 -0
- package/dist/tool/built-in/index.d.ts.map +1 -0
- package/dist/tool/built-in/index.js +56 -0
- package/dist/tool/built-in/index.js.map +1 -0
- package/dist/tool/executor.d.ts +100 -0
- package/dist/tool/executor.d.ts.map +1 -0
- package/dist/tool/executor.js +184 -0
- package/dist/tool/executor.js.map +1 -0
- package/dist/tool/framework.d.ts +167 -0
- package/dist/tool/framework.d.ts.map +1 -0
- package/dist/tool/framework.js +402 -0
- package/dist/tool/framework.js.map +1 -0
- package/dist/tool/mcp.d.ts +31 -0
- package/dist/tool/mcp.d.ts.map +1 -0
- package/dist/tool/mcp.js +175 -0
- package/dist/tool/mcp.js.map +1 -0
- package/dist/tool/text-tool-extractor.d.ts +32 -0
- package/dist/tool/text-tool-extractor.d.ts.map +1 -0
- package/dist/tool/text-tool-extractor.js +195 -0
- package/dist/tool/text-tool-extractor.js.map +1 -0
- package/dist/types.d.ts +916 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/keywords.d.ts +18 -0
- package/dist/utils/keywords.d.ts.map +1 -0
- package/dist/utils/keywords.js +32 -0
- package/dist/utils/keywords.js.map +1 -0
- package/dist/utils/semaphore.d.ts +49 -0
- package/dist/utils/semaphore.d.ts.map +1 -0
- package/dist/utils/semaphore.js +89 -0
- package/dist/utils/semaphore.js.map +1 -0
- package/dist/utils/tokens.d.ts +7 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +30 -0
- package/dist/utils/tokens.js.map +1 -0
- package/dist/utils/trace.d.ts +12 -0
- package/dist/utils/trace.d.ts.map +1 -0
- package/dist/utils/trace.js +30 -0
- package/dist/utils/trace.js.map +1 -0
- package/docs/DECISIONS.md +49 -0
- package/docs/cli.md +265 -0
- package/docs/context-management.md +24 -0
- package/docs/featured-partner.md +28 -0
- package/docs/observability.md +56 -0
- package/docs/providers.md +78 -0
- package/docs/shared-memory.md +27 -0
- package/docs/tool-configuration.md +152 -0
- package/package.json +96 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,916 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Core type definitions for the open-multi-agent orchestration framework.
|
|
3
|
+
*
|
|
4
|
+
* All public types are exported from this single module. Downstream modules
|
|
5
|
+
* import only what they need, keeping the dependency graph acyclic.
|
|
6
|
+
*/
|
|
7
|
+
import type { ZodSchema } from 'zod';
|
|
8
|
+
import type { SupportedProvider } from './llm/adapter.js';
|
|
9
|
+
/** Plain-text content produced by a model or supplied by the user. */
|
|
10
|
+
export interface TextBlock {
|
|
11
|
+
readonly type: 'text';
|
|
12
|
+
readonly text: string;
|
|
13
|
+
}
|
|
14
|
+
/** Provider-native reasoning / thinking content emitted alongside normal text. */
|
|
15
|
+
export interface ReasoningBlock {
|
|
16
|
+
readonly type: 'reasoning';
|
|
17
|
+
readonly text: string;
|
|
18
|
+
/**
|
|
19
|
+
* Provider-issued signature proving the reasoning was generated by the
|
|
20
|
+
* model. Used by:
|
|
21
|
+
* - Anthropic / Bedrock: required to echo back unchanged on the next
|
|
22
|
+
* turn to continue a multi-turn tool-use conversation with extended
|
|
23
|
+
* thinking; the API rejects edited or missing signatures.
|
|
24
|
+
* - Gemini 3: optional `thoughtSignature` attached to thought-summary
|
|
25
|
+
* Parts; recommended to round-trip per Gemini docs ("always pass all
|
|
26
|
+
* signatures back as received") but not strictly required.
|
|
27
|
+
* Absent for providers that don't sign reasoning (Gemini 2.5 thought
|
|
28
|
+
* summaries, OpenAI o-series) and for reasoning that originated outside
|
|
29
|
+
* the provider being addressed.
|
|
30
|
+
*/
|
|
31
|
+
readonly signature?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Opaque encrypted thinking content returned by Anthropic when its safety
|
|
34
|
+
* system blocks the raw reasoning text. The block must still be echoed
|
|
35
|
+
* back on subsequent turns to satisfy the protocol, but its contents are
|
|
36
|
+
* not human-readable. Carried separately from `text` because the wire
|
|
37
|
+
* format for redacted blocks is distinct (`redacted_thinking` vs
|
|
38
|
+
* `thinking`).
|
|
39
|
+
*/
|
|
40
|
+
readonly redactedData?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A request by the model to invoke a named tool with a structured input.
|
|
44
|
+
* The `id` is unique per turn and is referenced by {@link ToolResultBlock}.
|
|
45
|
+
*/
|
|
46
|
+
export interface ToolUseBlock {
|
|
47
|
+
readonly type: 'tool_use';
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly name: string;
|
|
50
|
+
readonly input: Record<string, unknown>;
|
|
51
|
+
/**
|
|
52
|
+
* Provider-issued signature attached to a tool call to prove the call was
|
|
53
|
+
* generated under extended thinking. Currently only used by Gemini
|
|
54
|
+
* (`thoughtSignature`), which is a top-level field on the Part containing
|
|
55
|
+
* the functionCall — an asymmetry from Anthropic, which signs the
|
|
56
|
+
* preceding {@link ReasoningBlock} instead. Echo back unchanged on
|
|
57
|
+
* subsequent turns to satisfy Gemini 3+'s strict validation.
|
|
58
|
+
*/
|
|
59
|
+
readonly signature?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The result of executing a tool, keyed back to the originating
|
|
63
|
+
* {@link ToolUseBlock} via `tool_use_id`.
|
|
64
|
+
*/
|
|
65
|
+
export interface ToolResultBlock {
|
|
66
|
+
readonly type: 'tool_result';
|
|
67
|
+
readonly tool_use_id: string;
|
|
68
|
+
readonly content: string;
|
|
69
|
+
readonly is_error?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** A base64-encoded image passed to or returned from a model. */
|
|
72
|
+
export interface ImageBlock {
|
|
73
|
+
readonly type: 'image';
|
|
74
|
+
readonly source: {
|
|
75
|
+
readonly type: 'base64';
|
|
76
|
+
readonly media_type: string;
|
|
77
|
+
readonly data: string;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** Union of all content block variants that may appear in a message. */
|
|
81
|
+
export type ContentBlock = ReasoningBlock | TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock;
|
|
82
|
+
/**
|
|
83
|
+
* A single message in a conversation thread.
|
|
84
|
+
* System messages are passed separately via {@link LLMChatOptions.systemPrompt}.
|
|
85
|
+
*/
|
|
86
|
+
export interface LLMMessage {
|
|
87
|
+
readonly role: 'user' | 'assistant';
|
|
88
|
+
readonly content: ContentBlock[];
|
|
89
|
+
}
|
|
90
|
+
/** Context management strategy for long-running agent conversations. */
|
|
91
|
+
export type ContextStrategy = {
|
|
92
|
+
type: 'sliding-window';
|
|
93
|
+
maxTurns: number;
|
|
94
|
+
} | {
|
|
95
|
+
type: 'summarize';
|
|
96
|
+
maxTokens: number;
|
|
97
|
+
summaryModel?: string;
|
|
98
|
+
} | {
|
|
99
|
+
type: 'compact';
|
|
100
|
+
/** Estimated token threshold that triggers compaction. Compaction is skipped when below this. */
|
|
101
|
+
maxTokens: number;
|
|
102
|
+
/** Number of recent turn pairs (assistant+user) to keep intact. Default: 4. */
|
|
103
|
+
preserveRecentTurns?: number;
|
|
104
|
+
/** Minimum chars in a tool_result content to qualify for compaction. Default: 200. */
|
|
105
|
+
minToolResultChars?: number;
|
|
106
|
+
/** Minimum chars in an assistant text block to qualify for truncation. Default: 2000. */
|
|
107
|
+
minTextBlockChars?: number;
|
|
108
|
+
/** Maximum chars to keep from a truncated text block (head excerpt). Default: 200. */
|
|
109
|
+
textBlockExcerptChars?: number;
|
|
110
|
+
} | {
|
|
111
|
+
type: 'custom';
|
|
112
|
+
/**
|
|
113
|
+
* Compaction callback. Invoked before every LLM turn including the first,
|
|
114
|
+
* so implementations that should only fire past a token threshold must
|
|
115
|
+
* self-gate inside this function.
|
|
116
|
+
*/
|
|
117
|
+
compress: (messages: LLMMessage[], estimatedTokens: number) => Promise<LLMMessage[]> | LLMMessage[];
|
|
118
|
+
};
|
|
119
|
+
/** Token accounting for a single API call. */
|
|
120
|
+
export interface TokenUsage {
|
|
121
|
+
readonly input_tokens: number;
|
|
122
|
+
readonly output_tokens: number;
|
|
123
|
+
}
|
|
124
|
+
/** Normalised response returned by every {@link LLMAdapter} implementation. */
|
|
125
|
+
export interface LLMResponse {
|
|
126
|
+
readonly id: string;
|
|
127
|
+
readonly content: ContentBlock[];
|
|
128
|
+
readonly model: string;
|
|
129
|
+
readonly stop_reason: string;
|
|
130
|
+
readonly usage: TokenUsage;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A discrete event emitted during streaming generation.
|
|
134
|
+
*
|
|
135
|
+
* - `text` — incremental text delta
|
|
136
|
+
* - `reasoning` — incremental reasoning / thinking delta
|
|
137
|
+
* - `tool_use` — the model has begun or completed a tool-use block
|
|
138
|
+
* - `tool_result` — a tool result has been appended to the stream
|
|
139
|
+
* - `budget_exceeded` — token budget threshold reached for this run
|
|
140
|
+
* - `done` — the stream has ended; `data` is the final {@link LLMResponse}
|
|
141
|
+
* - `error` — an unrecoverable error occurred; `data` is an `Error`
|
|
142
|
+
*/
|
|
143
|
+
export interface StreamEvent {
|
|
144
|
+
readonly type: 'text' | 'reasoning' | 'tool_use' | 'tool_result' | 'loop_detected' | 'budget_exceeded' | 'done' | 'error';
|
|
145
|
+
readonly data: unknown;
|
|
146
|
+
}
|
|
147
|
+
/** The serialisable tool schema sent to the LLM provider. */
|
|
148
|
+
export interface LLMToolDef {
|
|
149
|
+
readonly name: string;
|
|
150
|
+
readonly description: string;
|
|
151
|
+
/** JSON Schema object describing the tool's `input` parameter. */
|
|
152
|
+
readonly inputSchema: Record<string, unknown>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Context injected into every tool execution.
|
|
156
|
+
*
|
|
157
|
+
* Both `abortSignal` and `abortController` are provided so that tools and the
|
|
158
|
+
* executor can choose the most ergonomic API for their use-case:
|
|
159
|
+
*
|
|
160
|
+
* - Long-running shell commands that need to kill a child process can use
|
|
161
|
+
* `abortController.signal` directly.
|
|
162
|
+
* - Simple cancellation checks can read `abortSignal?.aborted`.
|
|
163
|
+
*
|
|
164
|
+
* When constructing a context, set `abortController` and derive `abortSignal`
|
|
165
|
+
* from it, or provide both independently.
|
|
166
|
+
*/
|
|
167
|
+
export interface ToolUseContext {
|
|
168
|
+
/** High-level description of the agent invoking this tool. */
|
|
169
|
+
readonly agent: AgentInfo;
|
|
170
|
+
/** Team context, present when the tool runs inside a multi-agent team. */
|
|
171
|
+
readonly team?: TeamInfo;
|
|
172
|
+
/**
|
|
173
|
+
* Convenience reference to the abort signal.
|
|
174
|
+
* Equivalent to `abortController?.signal` when an `abortController` is set.
|
|
175
|
+
*/
|
|
176
|
+
readonly abortSignal?: AbortSignal;
|
|
177
|
+
/**
|
|
178
|
+
* Full abort controller, available when the caller needs to inspect or
|
|
179
|
+
* programmatically abort the signal.
|
|
180
|
+
* Tools should prefer `abortSignal` for simple cancellation checks.
|
|
181
|
+
*/
|
|
182
|
+
readonly abortController?: AbortController;
|
|
183
|
+
/** Working directory hint for file-system tools. */
|
|
184
|
+
readonly cwd?: string;
|
|
185
|
+
/** Arbitrary caller-supplied metadata (session ID, request ID, etc.). */
|
|
186
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
187
|
+
}
|
|
188
|
+
/** Minimal descriptor for the agent that is invoking a tool. */
|
|
189
|
+
export interface AgentInfo {
|
|
190
|
+
readonly name: string;
|
|
191
|
+
readonly role: string;
|
|
192
|
+
readonly model: string;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Minimal pool surface used by `delegate_to_agent` to detect nested-run capacity.
|
|
196
|
+
* {@link AgentPool} satisfies this structurally via {@link AgentPool.availableRunSlots}.
|
|
197
|
+
*/
|
|
198
|
+
export interface DelegationPoolView {
|
|
199
|
+
readonly availableRunSlots: number;
|
|
200
|
+
}
|
|
201
|
+
/** Descriptor for a team of agents (orchestrator-injected into tool context). */
|
|
202
|
+
export interface TeamInfo {
|
|
203
|
+
readonly name: string;
|
|
204
|
+
readonly agents: readonly string[];
|
|
205
|
+
/** When the team has shared memory enabled; used for delegation audit writes. */
|
|
206
|
+
readonly sharedMemory?: MemoryStore;
|
|
207
|
+
/** Zero-based depth of nested delegation from the root task run. */
|
|
208
|
+
readonly delegationDepth?: number;
|
|
209
|
+
readonly maxDelegationDepth?: number;
|
|
210
|
+
readonly delegationPool?: DelegationPoolView;
|
|
211
|
+
/**
|
|
212
|
+
* Ordered chain of agent names from the root task to the current agent.
|
|
213
|
+
* Used to block `A -> B -> A` cycles before they burn turns against `maxDelegationDepth`.
|
|
214
|
+
*/
|
|
215
|
+
readonly delegationChain?: readonly string[];
|
|
216
|
+
/**
|
|
217
|
+
* Run another roster agent to completion and return its result.
|
|
218
|
+
* Only set during orchestrated pool execution (`runTeam` / `runTasks`).
|
|
219
|
+
*/
|
|
220
|
+
readonly runDelegatedAgent?: (targetAgent: string, prompt: string) => Promise<AgentRunResult>;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Optional side-channel metadata a tool may attach to its result.
|
|
224
|
+
* Not shown to the LLM — the runner reads it for accounting purposes.
|
|
225
|
+
*/
|
|
226
|
+
export interface ToolResultMetadata {
|
|
227
|
+
/**
|
|
228
|
+
* Token usage consumed inside the tool execution itself (e.g. nested LLM
|
|
229
|
+
* calls from `delegate_to_agent`). Accumulated into the parent runner's
|
|
230
|
+
* total so budgets/cost tracking stay accurate across delegation.
|
|
231
|
+
*/
|
|
232
|
+
readonly tokenUsage?: TokenUsage;
|
|
233
|
+
}
|
|
234
|
+
/** Value returned by a tool's `execute` function. */
|
|
235
|
+
export interface ToolResult {
|
|
236
|
+
readonly data: string;
|
|
237
|
+
readonly isError?: boolean;
|
|
238
|
+
readonly metadata?: ToolResultMetadata;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* A tool registered with the framework.
|
|
242
|
+
*
|
|
243
|
+
* `inputSchema` is a Zod schema used for validation before `execute` is called.
|
|
244
|
+
* At API call time it is converted to JSON Schema for {@link LLMToolDef}, unless
|
|
245
|
+
* `llmInputSchema` is set (e.g. MCP tools ship JSON Schema from the server).
|
|
246
|
+
*
|
|
247
|
+
* `outputSchema` is optional runtime validation for `ToolResult.data`. When
|
|
248
|
+
* set and validation fails, execution returns an error ToolResult instead of
|
|
249
|
+
* propagating invalid output.
|
|
250
|
+
*/
|
|
251
|
+
export interface ToolDefinition<TInput = Record<string, unknown>> {
|
|
252
|
+
readonly name: string;
|
|
253
|
+
readonly description: string;
|
|
254
|
+
readonly inputSchema: ZodSchema<TInput>;
|
|
255
|
+
/**
|
|
256
|
+
* Optional runtime validator for `ToolResult.data` (always a string).
|
|
257
|
+
*
|
|
258
|
+
* **Not to be confused with {@link AgentConfig.outputSchema}**, which
|
|
259
|
+
* validates an agent's final JSON answer. This one only guards a single
|
|
260
|
+
* tool's serialised output.
|
|
261
|
+
*/
|
|
262
|
+
readonly outputSchema?: ZodSchema<string>;
|
|
263
|
+
/**
|
|
264
|
+
* When present, used as {@link LLMToolDef.inputSchema} as-is instead of
|
|
265
|
+
* deriving JSON Schema from `inputSchema` (Zod).
|
|
266
|
+
*/
|
|
267
|
+
readonly llmInputSchema?: Record<string, unknown>;
|
|
268
|
+
/**
|
|
269
|
+
* Per-tool maximum output length in characters. When set, tool output
|
|
270
|
+
* exceeding this limit is truncated (head + tail with a marker in between).
|
|
271
|
+
* Takes priority over {@link AgentConfig.maxToolOutputChars}.
|
|
272
|
+
*/
|
|
273
|
+
readonly maxOutputChars?: number;
|
|
274
|
+
execute(input: TInput, context: ToolUseContext): Promise<ToolResult>;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Extended thinking / reasoning configuration shared by {@link AgentConfig}
|
|
278
|
+
* and {@link LLMChatOptions}.
|
|
279
|
+
*
|
|
280
|
+
* - `budgetTokens` maps to Anthropic's `thinking.budget_tokens` and Gemini's
|
|
281
|
+
* `thinkingConfig.thinkingBudget`.
|
|
282
|
+
* - `effort` maps to OpenAI o-series / gpt-5 `reasoning_effort`. Carried as
|
|
283
|
+
* an explicit value rather than derived from `budgetTokens` so the call
|
|
284
|
+
* site stays unambiguous across providers.
|
|
285
|
+
*
|
|
286
|
+
* The `effort` union is intentionally narrowed to the values declared by
|
|
287
|
+
* the pinned `openai` SDK (`'low' | 'medium' | 'high'`). Newer values
|
|
288
|
+
* shipped by the API but not yet in the SDK type union (e.g. gpt-5's
|
|
289
|
+
* `'minimal'`, GPT-5.5's `'none'`) should be passed via `extraBody:
|
|
290
|
+
* { reasoning_effort: '<value>' }`, matching how `top_k` / `min_p` are
|
|
291
|
+
* handled for vLLM.
|
|
292
|
+
*
|
|
293
|
+
* Adapters that don't recognise a given field ignore it.
|
|
294
|
+
*/
|
|
295
|
+
export interface ThinkingConfig {
|
|
296
|
+
readonly enabled: boolean;
|
|
297
|
+
readonly budgetTokens?: number;
|
|
298
|
+
readonly effort?: 'low' | 'medium' | 'high';
|
|
299
|
+
}
|
|
300
|
+
/** Context passed to the {@link AgentConfig.beforeRun} hook. */
|
|
301
|
+
export interface BeforeRunHookContext {
|
|
302
|
+
/** The user prompt text. */
|
|
303
|
+
readonly prompt: string;
|
|
304
|
+
/** The agent's static configuration. */
|
|
305
|
+
readonly agent: AgentConfig;
|
|
306
|
+
}
|
|
307
|
+
/** Static configuration for a single agent. */
|
|
308
|
+
export interface AgentConfig {
|
|
309
|
+
readonly name: string;
|
|
310
|
+
readonly model: string;
|
|
311
|
+
readonly provider?: SupportedProvider;
|
|
312
|
+
/**
|
|
313
|
+
* Custom base URL for OpenAI-compatible APIs (Ollama, vLLM, LM Studio, etc.).
|
|
314
|
+
* Note: local servers that don't require auth still need `apiKey` set to a
|
|
315
|
+
* non-empty placeholder (e.g. `'ollama'`) because the OpenAI SDK validates it.
|
|
316
|
+
*/
|
|
317
|
+
readonly baseURL?: string;
|
|
318
|
+
/** API key override; falls back to the provider's standard env var. */
|
|
319
|
+
readonly apiKey?: string;
|
|
320
|
+
/** AWS region override for the `bedrock` provider; falls back to `AWS_REGION` env var, then `'us-east-1'`. Ignored by all other providers. */
|
|
321
|
+
readonly region?: string;
|
|
322
|
+
readonly systemPrompt?: string;
|
|
323
|
+
/**
|
|
324
|
+
* Custom tool definitions to register alongside built-in tools.
|
|
325
|
+
* Created via `defineTool()`. Custom tools bypass `tools` (allowlist)
|
|
326
|
+
* and `toolPreset` filtering, but can still be blocked by `disallowedTools`.
|
|
327
|
+
*
|
|
328
|
+
* Tool names must not collide with built-in tool names; a duplicate name
|
|
329
|
+
* will throw at registration time.
|
|
330
|
+
*/
|
|
331
|
+
readonly customTools?: readonly ToolDefinition<any>[];
|
|
332
|
+
/** Names of tools (from the tool registry) available to this agent. */
|
|
333
|
+
readonly tools?: readonly string[];
|
|
334
|
+
/** Names of tools explicitly disallowed for this agent. */
|
|
335
|
+
readonly disallowedTools?: readonly string[];
|
|
336
|
+
/** Predefined tool preset for common use cases. */
|
|
337
|
+
readonly toolPreset?: 'readonly' | 'readwrite' | 'full';
|
|
338
|
+
readonly maxTurns?: number;
|
|
339
|
+
readonly maxTokens?: number;
|
|
340
|
+
/** Maximum cumulative tokens (input + output) allowed for this run. */
|
|
341
|
+
readonly maxTokenBudget?: number;
|
|
342
|
+
/** Optional context compression policy to control input growth across turns. */
|
|
343
|
+
readonly contextStrategy?: ContextStrategy;
|
|
344
|
+
readonly temperature?: number;
|
|
345
|
+
/**
|
|
346
|
+
* OpenAI-track sampling penalty for token frequency. Forwarded to OpenAI
|
|
347
|
+
* cloud and OpenAI-compatible local servers (vLLM, llama-server). The
|
|
348
|
+
* Anthropic adapter ignores this field.
|
|
349
|
+
*/
|
|
350
|
+
readonly frequencyPenalty?: number;
|
|
351
|
+
/**
|
|
352
|
+
* OpenAI-track sampling penalty for token presence. Forwarded to OpenAI
|
|
353
|
+
* cloud and OpenAI-compatible local servers. The Anthropic adapter
|
|
354
|
+
* ignores this field.
|
|
355
|
+
*/
|
|
356
|
+
readonly presencePenalty?: number;
|
|
357
|
+
/**
|
|
358
|
+
* Nucleus sampling cutoff. Forwarded to all adapters (OpenAI cloud,
|
|
359
|
+
* OpenAI-compatible local, Anthropic).
|
|
360
|
+
*/
|
|
361
|
+
readonly topP?: number;
|
|
362
|
+
/**
|
|
363
|
+
* Top-k sampling cutoff. Forwarded to Anthropic and OpenAI-compatible
|
|
364
|
+
* local servers. Cloud OpenAI rejects this parameter.
|
|
365
|
+
*/
|
|
366
|
+
readonly topK?: number;
|
|
367
|
+
/**
|
|
368
|
+
* Min-p sampling cutoff. Only supported by OpenAI-compatible local
|
|
369
|
+
* servers (vLLM, llama-server, etc.). Cloud OpenAI rejects this parameter
|
|
370
|
+
* and the Anthropic adapter ignores it.
|
|
371
|
+
*/
|
|
372
|
+
readonly minP?: number;
|
|
373
|
+
/**
|
|
374
|
+
* Whether the model may emit multiple tool calls in a single assistant
|
|
375
|
+
* turn. Forwarded to OpenAI cloud and OpenAI-compatible local servers as
|
|
376
|
+
* `parallel_tool_calls`. The Anthropic adapter ignores this field.
|
|
377
|
+
*
|
|
378
|
+
* - `undefined` (default): omit the field, server default applies. Cloud
|
|
379
|
+
* OpenAI defaults to `true`.
|
|
380
|
+
* - `false`: force serial tool calling. Required by some local servers
|
|
381
|
+
* (vLLM, llama-server, certain quantized setups) that truncate
|
|
382
|
+
* concurrent `tool_call` deltas during streaming or return malformed
|
|
383
|
+
* `tool_calls` when more than one is emitted.
|
|
384
|
+
* - `true`: explicit opt-in (matches the cloud default; no behavior
|
|
385
|
+
* change for cloud OpenAI users).
|
|
386
|
+
*/
|
|
387
|
+
readonly parallelToolCalls?: boolean;
|
|
388
|
+
/**
|
|
389
|
+
* Adapter-specific escape hatch merged into the outgoing request payload.
|
|
390
|
+
* Spread between the sampling params and the structural fields, so values
|
|
391
|
+
* here can override the standard sampling defaults (`temperature`, `topP`,
|
|
392
|
+
* etc.) but cannot override transport-level fields (`model`, `messages`,
|
|
393
|
+
* `tools`, `stream`, and Anthropic's `system`).
|
|
394
|
+
*/
|
|
395
|
+
readonly extraBody?: Record<string, unknown>;
|
|
396
|
+
/**
|
|
397
|
+
* Extended thinking / reasoning configuration. Provider mapping:
|
|
398
|
+
* - Anthropic: forwards `enabled` + `budgetTokens` as the `thinking` request
|
|
399
|
+
* param (see `toAnthropicThinkingParam`).
|
|
400
|
+
* - Gemini: forwards `enabled` + `budgetTokens` as `thinkingConfig`
|
|
401
|
+
* (`includeThoughts` defaults on when enabled).
|
|
402
|
+
* - OpenAI: forwards `effort` as `reasoning_effort` (o-series, gpt-5).
|
|
403
|
+
* The `enabled`/`budgetTokens` fields are ignored — OpenAI's reasoning
|
|
404
|
+
* surface is qualitative (`effort`), not quantitative.
|
|
405
|
+
* - All other providers (Bedrock, local servers, etc.): ignored. Use
|
|
406
|
+
* {@link extraBody} for provider-specific reasoning controls instead.
|
|
407
|
+
*/
|
|
408
|
+
readonly thinking?: ThinkingConfig;
|
|
409
|
+
/**
|
|
410
|
+
* Maximum wall-clock time (in milliseconds) for the entire agent run.
|
|
411
|
+
* When exceeded, the run is aborted via `AbortSignal.timeout()`.
|
|
412
|
+
* Useful for local models where inference can be unpredictably slow.
|
|
413
|
+
*/
|
|
414
|
+
readonly timeoutMs?: number;
|
|
415
|
+
/**
|
|
416
|
+
* Loop detection configuration. When set, the agent tracks repeated tool
|
|
417
|
+
* calls and text outputs to detect stuck loops before `maxTurns` is reached.
|
|
418
|
+
*/
|
|
419
|
+
readonly loopDetection?: LoopDetectionConfig;
|
|
420
|
+
/**
|
|
421
|
+
* Maximum tool output length in characters for all tools used by this agent.
|
|
422
|
+
* When set, tool outputs exceeding this limit are truncated (head + tail
|
|
423
|
+
* with a marker in between). Per-tool {@link ToolDefinition.maxOutputChars}
|
|
424
|
+
* takes priority over this value.
|
|
425
|
+
*/
|
|
426
|
+
readonly maxToolOutputChars?: number;
|
|
427
|
+
/**
|
|
428
|
+
* Compress tool results that the agent has already processed.
|
|
429
|
+
*
|
|
430
|
+
* In multi-turn runs, tool results persist in the conversation even after the
|
|
431
|
+
* agent has acted on them. When enabled, consumed tool results (those followed
|
|
432
|
+
* by an assistant response) are replaced with a short marker before the next
|
|
433
|
+
* LLM call, freeing context budget for new reasoning.
|
|
434
|
+
*
|
|
435
|
+
* - `true` — enable with default threshold (500 chars)
|
|
436
|
+
* - `{ minChars: N }` — only compress results longer than N characters
|
|
437
|
+
* - `false` / `undefined` — disabled (default)
|
|
438
|
+
*
|
|
439
|
+
* Error tool results are never compressed.
|
|
440
|
+
*/
|
|
441
|
+
readonly compressToolResults?: boolean | {
|
|
442
|
+
readonly minChars?: number;
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Optional Zod schema for structured output. When set, the agent's final
|
|
446
|
+
* output is parsed as JSON and validated against this schema. A single
|
|
447
|
+
* retry with error feedback is attempted on validation failure.
|
|
448
|
+
*
|
|
449
|
+
* **Distinct from {@link ToolDefinition.outputSchema}**, which validates an
|
|
450
|
+
* individual tool's `ToolResult.data` string. This one operates on the
|
|
451
|
+
* agent's final answer as parsed JSON.
|
|
452
|
+
*/
|
|
453
|
+
readonly outputSchema?: ZodSchema;
|
|
454
|
+
/**
|
|
455
|
+
* Called before each agent run. Receives the prompt and agent config.
|
|
456
|
+
* Return a (possibly modified) context to continue, or throw to abort the run.
|
|
457
|
+
* Only `prompt` from the returned context is applied; `agent` is read-only informational.
|
|
458
|
+
*/
|
|
459
|
+
readonly beforeRun?: (context: BeforeRunHookContext) => Promise<BeforeRunHookContext> | BeforeRunHookContext;
|
|
460
|
+
/**
|
|
461
|
+
* Called after each agent run completes successfully. Receives the run result.
|
|
462
|
+
* Return a (possibly modified) result, or throw to mark the run as failed.
|
|
463
|
+
* Not called when the run throws. For error observation, handle errors at the call site.
|
|
464
|
+
*/
|
|
465
|
+
readonly afterRun?: (result: AgentRunResult) => Promise<AgentRunResult> | AgentRunResult;
|
|
466
|
+
}
|
|
467
|
+
/** Configuration for agent loop detection. */
|
|
468
|
+
export interface LoopDetectionConfig {
|
|
469
|
+
/**
|
|
470
|
+
* Maximum consecutive times the same tool call (name + args) or text
|
|
471
|
+
* output can repeat before detection triggers. Default: `3`.
|
|
472
|
+
*/
|
|
473
|
+
readonly maxRepetitions?: number;
|
|
474
|
+
/**
|
|
475
|
+
* Number of recent turns to track for repetition analysis. Default: `4`.
|
|
476
|
+
*/
|
|
477
|
+
readonly loopDetectionWindow?: number;
|
|
478
|
+
/**
|
|
479
|
+
* Action to take when a loop is detected.
|
|
480
|
+
* - `'warn'` — inject a "you appear stuck" message, give the LLM one
|
|
481
|
+
* more chance; terminate if the loop persists (default)
|
|
482
|
+
* - `'terminate'` — stop the run immediately
|
|
483
|
+
* - `function` — custom callback (sync or async); return `'continue'`,
|
|
484
|
+
* `'inject'`, or `'terminate'` to control the outcome
|
|
485
|
+
*/
|
|
486
|
+
readonly onLoopDetected?: 'warn' | 'terminate' | ((info: LoopDetectionInfo) => 'continue' | 'inject' | 'terminate' | Promise<'continue' | 'inject' | 'terminate'>);
|
|
487
|
+
}
|
|
488
|
+
/** Diagnostic payload emitted when a loop is detected. */
|
|
489
|
+
export interface LoopDetectionInfo {
|
|
490
|
+
readonly kind: 'tool_repetition' | 'text_repetition';
|
|
491
|
+
/** Number of consecutive identical occurrences observed. */
|
|
492
|
+
readonly repetitions: number;
|
|
493
|
+
/** Human-readable description of the detected loop. */
|
|
494
|
+
readonly detail: string;
|
|
495
|
+
}
|
|
496
|
+
/** Lifecycle state tracked during an agent run. */
|
|
497
|
+
export interface AgentState {
|
|
498
|
+
status: 'idle' | 'running' | 'completed' | 'error';
|
|
499
|
+
messages: LLMMessage[];
|
|
500
|
+
tokenUsage: TokenUsage;
|
|
501
|
+
error?: Error;
|
|
502
|
+
}
|
|
503
|
+
/** A single recorded tool invocation within a run. */
|
|
504
|
+
export interface ToolCallRecord {
|
|
505
|
+
readonly toolName: string;
|
|
506
|
+
readonly input: Record<string, unknown>;
|
|
507
|
+
readonly output: string;
|
|
508
|
+
/** Wall-clock duration in milliseconds. */
|
|
509
|
+
readonly duration: number;
|
|
510
|
+
}
|
|
511
|
+
/** The final result produced when an agent run completes (or fails). */
|
|
512
|
+
export interface AgentRunResult {
|
|
513
|
+
readonly success: boolean;
|
|
514
|
+
readonly output: string;
|
|
515
|
+
readonly messages: LLMMessage[];
|
|
516
|
+
readonly tokenUsage: TokenUsage;
|
|
517
|
+
readonly toolCalls: ToolCallRecord[];
|
|
518
|
+
/**
|
|
519
|
+
* Parsed and validated structured output when `outputSchema` is set on the
|
|
520
|
+
* agent config. `undefined` when no schema is configured or validation
|
|
521
|
+
* failed after retry.
|
|
522
|
+
*/
|
|
523
|
+
readonly structured?: unknown;
|
|
524
|
+
/** True when the run was terminated or warned due to loop detection. */
|
|
525
|
+
readonly loopDetected?: boolean;
|
|
526
|
+
/** True when the run stopped because token budget was exceeded. */
|
|
527
|
+
readonly budgetExceeded?: boolean;
|
|
528
|
+
}
|
|
529
|
+
/** Static configuration for a team of cooperating agents. */
|
|
530
|
+
export interface TeamConfig {
|
|
531
|
+
readonly name: string;
|
|
532
|
+
readonly agents: readonly AgentConfig[];
|
|
533
|
+
readonly sharedMemory?: boolean;
|
|
534
|
+
/**
|
|
535
|
+
* Custom {@link MemoryStore} backing the team's shared memory (e.g. Redis,
|
|
536
|
+
* Postgres, or a remote service). When provided, shared memory is enabled
|
|
537
|
+
* regardless of `sharedMemory`. When both are set, `sharedMemoryStore` wins.
|
|
538
|
+
* When omitted and `sharedMemory` is `true`, the default in-memory store is used.
|
|
539
|
+
*
|
|
540
|
+
* SDK-only: the CLI (`oma`) cannot pass runtime objects through its JSON config.
|
|
541
|
+
*/
|
|
542
|
+
readonly sharedMemoryStore?: MemoryStore;
|
|
543
|
+
readonly maxConcurrency?: number;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Per-call options for {@link OpenMultiAgent.runTeam}. Differs from
|
|
547
|
+
* {@link OrchestratorConfig} by being scoped to a single invocation.
|
|
548
|
+
*/
|
|
549
|
+
export interface RunTeamOptions {
|
|
550
|
+
readonly abortSignal?: AbortSignal;
|
|
551
|
+
readonly coordinator?: CoordinatorConfig;
|
|
552
|
+
/**
|
|
553
|
+
* When true, the coordinator decomposes the goal but no task agents run.
|
|
554
|
+
* The returned {@link TeamRunResult} has `planOnly: true`, `success: true`,
|
|
555
|
+
* `tasks` populated (all `pending`, no metrics), and `agentResults`
|
|
556
|
+
* containing only the coordinator's decomposition call. `totalTokenUsage`
|
|
557
|
+
* reflects the coordinator only.
|
|
558
|
+
*
|
|
559
|
+
* Bypasses the simple-goal short-circuit so the coordinator always runs.
|
|
560
|
+
*
|
|
561
|
+
* If {@link OrchestratorConfig.onPlanReady} is wired up and returns false,
|
|
562
|
+
* the rejection wins: result is `success: false` and `planOnly` is undefined.
|
|
563
|
+
*/
|
|
564
|
+
readonly planOnly?: boolean;
|
|
565
|
+
}
|
|
566
|
+
/** Aggregated result for a full team run. */
|
|
567
|
+
export interface TeamRunResult {
|
|
568
|
+
readonly success: boolean;
|
|
569
|
+
readonly goal?: string;
|
|
570
|
+
readonly tasks?: readonly TaskExecutionRecord[];
|
|
571
|
+
/**
|
|
572
|
+
* True when the run was a plan-only invocation (`runTeam(team, goal, { planOnly: true })`).
|
|
573
|
+
* The coordinator decomposed the goal but no task agents executed.
|
|
574
|
+
* Undefined on normal runs and on `onPlanReady`-rejection results.
|
|
575
|
+
*/
|
|
576
|
+
readonly planOnly?: boolean;
|
|
577
|
+
/** Keyed by agent name. */
|
|
578
|
+
readonly agentResults: Map<string, AgentRunResult>;
|
|
579
|
+
readonly totalTokenUsage: TokenUsage;
|
|
580
|
+
}
|
|
581
|
+
/** Valid states for a {@link Task}. */
|
|
582
|
+
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'blocked' | 'skipped';
|
|
583
|
+
/**
|
|
584
|
+
* Metrics shown in the team-run dashboard detail panel for a single task.
|
|
585
|
+
* Mirrors execution data collected during orchestration.
|
|
586
|
+
*/
|
|
587
|
+
export interface TaskExecutionMetrics {
|
|
588
|
+
readonly startMs: number;
|
|
589
|
+
readonly endMs: number;
|
|
590
|
+
readonly durationMs: number;
|
|
591
|
+
readonly tokenUsage: TokenUsage;
|
|
592
|
+
readonly toolCalls: AgentRunResult['toolCalls'];
|
|
593
|
+
}
|
|
594
|
+
/** Serializable task snapshot embedded in the static HTML dashboard. */
|
|
595
|
+
export interface TaskExecutionRecord {
|
|
596
|
+
readonly id: string;
|
|
597
|
+
readonly title: string;
|
|
598
|
+
readonly assignee?: string;
|
|
599
|
+
readonly status: TaskStatus;
|
|
600
|
+
readonly dependsOn: readonly string[];
|
|
601
|
+
readonly metrics?: TaskExecutionMetrics;
|
|
602
|
+
}
|
|
603
|
+
/** A discrete unit of work tracked by the orchestrator. */
|
|
604
|
+
export interface Task {
|
|
605
|
+
readonly id: string;
|
|
606
|
+
readonly title: string;
|
|
607
|
+
readonly description: string;
|
|
608
|
+
status: TaskStatus;
|
|
609
|
+
/** Agent name responsible for executing this task. */
|
|
610
|
+
assignee?: string;
|
|
611
|
+
/** IDs of tasks that must complete before this one can start. */
|
|
612
|
+
dependsOn?: readonly string[];
|
|
613
|
+
/**
|
|
614
|
+
* Controls what prior team context is injected into this task's prompt.
|
|
615
|
+
* - `dependencies` (default): only direct dependency task results
|
|
616
|
+
* - `all`: full shared-memory summary
|
|
617
|
+
*/
|
|
618
|
+
readonly memoryScope?: 'dependencies' | 'all';
|
|
619
|
+
result?: string;
|
|
620
|
+
readonly createdAt: Date;
|
|
621
|
+
updatedAt: Date;
|
|
622
|
+
/** Maximum number of retry attempts on failure (default: 0 — no retry). */
|
|
623
|
+
readonly maxRetries?: number;
|
|
624
|
+
/** Base delay in ms before the first retry (default: 1000). */
|
|
625
|
+
readonly retryDelayMs?: number;
|
|
626
|
+
/** Exponential backoff multiplier (default: 2). */
|
|
627
|
+
readonly retryBackoff?: number;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Progress event emitted by the orchestrator during a run.
|
|
631
|
+
*
|
|
632
|
+
* **v0.3 addition:** `'task_skipped'` — consumers with exhaustive switches
|
|
633
|
+
* on `type` will need to add a case for this variant.
|
|
634
|
+
*/
|
|
635
|
+
export interface OrchestratorEvent {
|
|
636
|
+
readonly type: 'agent_start' | 'agent_complete' | 'task_start' | 'task_complete' | 'task_skipped' | 'task_retry' | 'budget_exceeded' | 'message' | 'error';
|
|
637
|
+
readonly agent?: string;
|
|
638
|
+
readonly task?: string;
|
|
639
|
+
readonly data?: unknown;
|
|
640
|
+
}
|
|
641
|
+
/** Top-level configuration for the orchestrator. */
|
|
642
|
+
export interface OrchestratorConfig {
|
|
643
|
+
readonly maxConcurrency?: number;
|
|
644
|
+
/**
|
|
645
|
+
* Maximum depth of `delegate_to_agent` chains from a task run (default `3`).
|
|
646
|
+
* Depth is per nested delegated run, not per team.
|
|
647
|
+
*/
|
|
648
|
+
readonly maxDelegationDepth?: number;
|
|
649
|
+
/** Maximum cumulative tokens (input + output) allowed per orchestrator run. */
|
|
650
|
+
readonly maxTokenBudget?: number;
|
|
651
|
+
readonly defaultModel?: string;
|
|
652
|
+
readonly defaultProvider?: SupportedProvider;
|
|
653
|
+
readonly defaultBaseURL?: string;
|
|
654
|
+
readonly defaultApiKey?: string;
|
|
655
|
+
readonly onProgress?: (event: OrchestratorEvent) => void;
|
|
656
|
+
readonly onTrace?: (event: TraceEvent) => void | Promise<void>;
|
|
657
|
+
/**
|
|
658
|
+
* Optional approval gate called between task execution rounds.
|
|
659
|
+
*
|
|
660
|
+
* After a batch of tasks completes, this callback receives all
|
|
661
|
+
* completed {@link Task}s from that round and the list of tasks about
|
|
662
|
+
* to start next. Return `true` to continue or `false` to abort —
|
|
663
|
+
* remaining tasks will be marked `'skipped'`.
|
|
664
|
+
*
|
|
665
|
+
* Not called when:
|
|
666
|
+
* - No tasks succeeded in the round (all failed).
|
|
667
|
+
* - No pending tasks remain after the round (final batch).
|
|
668
|
+
*
|
|
669
|
+
* **Note:** Do not mutate the {@link Task} objects passed to this
|
|
670
|
+
* callback — they are live references to queue state. Mutation is
|
|
671
|
+
* undefined behavior.
|
|
672
|
+
*/
|
|
673
|
+
readonly onApproval?: (completedTasks: readonly Task[], nextTasks: readonly Task[]) => Promise<boolean>;
|
|
674
|
+
/**
|
|
675
|
+
* Optional approval gate called once after the coordinator decomposes the
|
|
676
|
+
* goal into tasks and before execution begins.
|
|
677
|
+
*
|
|
678
|
+
* Receives the full plan as a {@link Task} array. Return `true` to proceed
|
|
679
|
+
* or `false` to abort. A thrown callback is treated as an abort.
|
|
680
|
+
*
|
|
681
|
+
* Only invoked by `runTeam()`. `runAgent()` and `runTasks()` are
|
|
682
|
+
* unaffected. The `TeamRunResult` returned on abort still reflects the
|
|
683
|
+
* coordinator's decomposition tokens.
|
|
684
|
+
*
|
|
685
|
+
* **Note:** Do not mutate the {@link Task} objects passed to this
|
|
686
|
+
* callback. They are live references to queue state; mutation is
|
|
687
|
+
* undefined behavior.
|
|
688
|
+
*/
|
|
689
|
+
readonly onPlanReady?: (tasks: readonly Task[]) => Promise<boolean>;
|
|
690
|
+
/**
|
|
691
|
+
* Called for each streaming event emitted by an agent during runTeam().
|
|
692
|
+
* When provided, agents run in streaming mode so the TUI can receive
|
|
693
|
+
* real-time text deltas and tool-call events.
|
|
694
|
+
* Only invoked by runTeam(). Not called for runAgent() or runTasks().
|
|
695
|
+
*/
|
|
696
|
+
readonly onAgentStream?: (agentName: string, event: StreamEvent) => void;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Optional overrides for the temporary coordinator agent created by `runTeam`.
|
|
700
|
+
*
|
|
701
|
+
* All fields are optional. Unset fields fall back to orchestrator defaults
|
|
702
|
+
* (or coordinator built-in defaults where applicable).
|
|
703
|
+
*/
|
|
704
|
+
export interface CoordinatorConfig {
|
|
705
|
+
/** Coordinator model. Defaults to `OrchestratorConfig.defaultModel`. */
|
|
706
|
+
readonly model?: string;
|
|
707
|
+
readonly provider?: SupportedProvider;
|
|
708
|
+
readonly baseURL?: string;
|
|
709
|
+
readonly apiKey?: string;
|
|
710
|
+
/**
|
|
711
|
+
* Full system prompt override. When set, this replaces the default
|
|
712
|
+
* coordinator preamble and decomposition guidance.
|
|
713
|
+
*
|
|
714
|
+
* Team roster, output format, and synthesis sections are still appended.
|
|
715
|
+
*/
|
|
716
|
+
readonly systemPrompt?: string;
|
|
717
|
+
/**
|
|
718
|
+
* Additional instructions appended to the default coordinator prompt.
|
|
719
|
+
* Ignored when `systemPrompt` is provided.
|
|
720
|
+
*/
|
|
721
|
+
readonly instructions?: string;
|
|
722
|
+
readonly maxTurns?: number;
|
|
723
|
+
readonly maxTokens?: number;
|
|
724
|
+
readonly temperature?: number;
|
|
725
|
+
/** See {@link AgentConfig.frequencyPenalty}. */
|
|
726
|
+
readonly frequencyPenalty?: number;
|
|
727
|
+
/** See {@link AgentConfig.presencePenalty}. */
|
|
728
|
+
readonly presencePenalty?: number;
|
|
729
|
+
/** See {@link AgentConfig.topP}. */
|
|
730
|
+
readonly topP?: number;
|
|
731
|
+
/** See {@link AgentConfig.topK}. */
|
|
732
|
+
readonly topK?: number;
|
|
733
|
+
/** See {@link AgentConfig.minP}. */
|
|
734
|
+
readonly minP?: number;
|
|
735
|
+
/** See {@link AgentConfig.parallelToolCalls}. */
|
|
736
|
+
readonly parallelToolCalls?: boolean;
|
|
737
|
+
/**
|
|
738
|
+
* Adapter-specific escape hatch merged into the outgoing request payload.
|
|
739
|
+
* Spread between the sampling params and the structural fields, so values
|
|
740
|
+
* here can override the standard sampling defaults (`temperature`, `topP`,
|
|
741
|
+
* etc.) but cannot override transport-level fields (`model`, `messages`,
|
|
742
|
+
* `tools`, `stream`, and Anthropic's `system`).
|
|
743
|
+
*/
|
|
744
|
+
readonly extraBody?: Record<string, unknown>;
|
|
745
|
+
/** Predefined tool preset for common coordinator use cases. */
|
|
746
|
+
readonly toolPreset?: 'readonly' | 'readwrite' | 'full';
|
|
747
|
+
/** Tool names available to the coordinator. */
|
|
748
|
+
readonly tools?: readonly string[];
|
|
749
|
+
/** Tool names explicitly denied to the coordinator. */
|
|
750
|
+
readonly disallowedTools?: readonly string[];
|
|
751
|
+
readonly loopDetection?: LoopDetectionConfig;
|
|
752
|
+
readonly timeoutMs?: number;
|
|
753
|
+
}
|
|
754
|
+
/** Trace event type discriminants. */
|
|
755
|
+
export type TraceEventType = 'llm_call' | 'tool_call' | 'task' | 'agent' | 'plan_ready' | 'agent_stream';
|
|
756
|
+
/** Shared fields present on every trace event. */
|
|
757
|
+
export interface TraceEventBase {
|
|
758
|
+
/** Unique identifier for the entire run (runTeam / runTasks / runAgent call). */
|
|
759
|
+
readonly runId: string;
|
|
760
|
+
readonly type: TraceEventType;
|
|
761
|
+
/** Unix epoch ms when the span started. */
|
|
762
|
+
readonly startMs: number;
|
|
763
|
+
/** Unix epoch ms when the span ended. */
|
|
764
|
+
readonly endMs: number;
|
|
765
|
+
/** Wall-clock duration in milliseconds (`endMs - startMs`). */
|
|
766
|
+
readonly durationMs: number;
|
|
767
|
+
/** Agent name associated with this span. */
|
|
768
|
+
readonly agent: string;
|
|
769
|
+
/** Task ID associated with this span. */
|
|
770
|
+
readonly taskId?: string;
|
|
771
|
+
}
|
|
772
|
+
/** Emitted for each LLM API call (one per agent turn). */
|
|
773
|
+
export interface LLMCallTrace extends TraceEventBase {
|
|
774
|
+
readonly type: 'llm_call';
|
|
775
|
+
readonly model: string;
|
|
776
|
+
/** Distinguishes normal turn calls from context-summary calls. */
|
|
777
|
+
readonly phase?: 'turn' | 'summary';
|
|
778
|
+
readonly turn: number;
|
|
779
|
+
readonly tokens: TokenUsage;
|
|
780
|
+
}
|
|
781
|
+
/** Emitted for each tool execution. */
|
|
782
|
+
export interface ToolCallTrace extends TraceEventBase {
|
|
783
|
+
readonly type: 'tool_call';
|
|
784
|
+
readonly tool: string;
|
|
785
|
+
readonly isError: boolean;
|
|
786
|
+
/** The input arguments passed to the tool — mirrors the originating ToolUseBlock.input. */
|
|
787
|
+
readonly input: Record<string, unknown>;
|
|
788
|
+
/** The serialised output returned by the tool — mirrors ToolResult.data (truncation, if any, has already been applied by the executor). */
|
|
789
|
+
readonly output: string;
|
|
790
|
+
}
|
|
791
|
+
/** Emitted when a task completes (wraps the full retry sequence). */
|
|
792
|
+
export interface TaskTrace extends TraceEventBase {
|
|
793
|
+
readonly type: 'task';
|
|
794
|
+
readonly taskId: string;
|
|
795
|
+
readonly taskTitle: string;
|
|
796
|
+
readonly success: boolean;
|
|
797
|
+
readonly retries: number;
|
|
798
|
+
}
|
|
799
|
+
/** Emitted when an agent run completes (wraps the full conversation loop). */
|
|
800
|
+
export interface AgentTrace extends TraceEventBase {
|
|
801
|
+
readonly type: 'agent';
|
|
802
|
+
readonly turns: number;
|
|
803
|
+
readonly tokens: TokenUsage;
|
|
804
|
+
readonly toolCalls: number;
|
|
805
|
+
}
|
|
806
|
+
/** Emitted when runTeam reaches the plan approval boundary. */
|
|
807
|
+
export interface PlanReadyTrace extends TraceEventBase {
|
|
808
|
+
readonly type: 'plan_ready';
|
|
809
|
+
/** Number of tasks produced by coordinator decomposition. */
|
|
810
|
+
readonly taskCount: number;
|
|
811
|
+
/** Approval decision returned by onPlanReady callback. */
|
|
812
|
+
readonly approved: boolean;
|
|
813
|
+
}
|
|
814
|
+
/** Emitted for each streaming event forwarded through onAgentStream in runTeam. */
|
|
815
|
+
export interface AgentStreamTrace extends TraceEventBase {
|
|
816
|
+
readonly type: 'agent_stream';
|
|
817
|
+
/** Underlying stream event type (`text`, `tool_use`, `done`, etc.). */
|
|
818
|
+
readonly streamType: StreamEvent['type'];
|
|
819
|
+
}
|
|
820
|
+
/** Discriminated union of all trace event types. */
|
|
821
|
+
export type TraceEvent = LLMCallTrace | ToolCallTrace | TaskTrace | AgentTrace | PlanReadyTrace | AgentStreamTrace;
|
|
822
|
+
/** A single key-value record stored in a {@link MemoryStore}. */
|
|
823
|
+
export interface MemoryEntry {
|
|
824
|
+
readonly key: string;
|
|
825
|
+
readonly value: string;
|
|
826
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
827
|
+
readonly createdAt: Date;
|
|
828
|
+
/**
|
|
829
|
+
* Optional turn-count expiry. When set, the entry is considered expired
|
|
830
|
+
* once the {@link SharedMemory} turn counter reaches or exceeds this value.
|
|
831
|
+
* Computed at write time as `currentTurn + ttlTurns`. Stores that don't
|
|
832
|
+
* implement {@link MemoryStore.setWithExpiry} will not have this field set.
|
|
833
|
+
*/
|
|
834
|
+
readonly expiresAtTurn?: number;
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Persistent (or in-memory) key-value store shared across agents.
|
|
838
|
+
* Implementations may be backed by Redis, SQLite, or plain objects.
|
|
839
|
+
*/
|
|
840
|
+
export interface MemoryStore {
|
|
841
|
+
get(key: string): Promise<MemoryEntry | null>;
|
|
842
|
+
set(key: string, value: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
843
|
+
/**
|
|
844
|
+
* Optional: write an entry with a turn-count expiry. Stores that don't
|
|
845
|
+
* implement this method silently lose TTL semantics — callers (e.g.
|
|
846
|
+
* {@link SharedMemory}) should fall back to {@link set} and not enforce
|
|
847
|
+
* expiry on entries from those backends.
|
|
848
|
+
*/
|
|
849
|
+
setWithExpiry?(key: string, value: string, expiresAtTurn: number, metadata?: Record<string, unknown>): Promise<void>;
|
|
850
|
+
list(): Promise<MemoryEntry[]>;
|
|
851
|
+
delete(key: string): Promise<void>;
|
|
852
|
+
clear(): Promise<void>;
|
|
853
|
+
}
|
|
854
|
+
/** Options shared by both chat and streaming calls. */
|
|
855
|
+
export interface LLMChatOptions {
|
|
856
|
+
readonly model: string;
|
|
857
|
+
readonly tools?: readonly LLMToolDef[];
|
|
858
|
+
readonly maxTokens?: number;
|
|
859
|
+
readonly temperature?: number;
|
|
860
|
+
/** See {@link AgentConfig.frequencyPenalty}. */
|
|
861
|
+
readonly frequencyPenalty?: number;
|
|
862
|
+
/** See {@link AgentConfig.presencePenalty}. */
|
|
863
|
+
readonly presencePenalty?: number;
|
|
864
|
+
/** See {@link AgentConfig.topP}. */
|
|
865
|
+
readonly topP?: number;
|
|
866
|
+
/** See {@link AgentConfig.topK}. */
|
|
867
|
+
readonly topK?: number;
|
|
868
|
+
/** See {@link AgentConfig.minP}. */
|
|
869
|
+
readonly minP?: number;
|
|
870
|
+
/** See {@link AgentConfig.parallelToolCalls}. */
|
|
871
|
+
readonly parallelToolCalls?: boolean;
|
|
872
|
+
/**
|
|
873
|
+
* Adapter-specific escape hatch merged into the outgoing request payload.
|
|
874
|
+
* Spread between the sampling params and the structural fields, so values
|
|
875
|
+
* here can override the standard sampling defaults (`temperature`, `topP`,
|
|
876
|
+
* etc.) but cannot override transport-level fields (`model`, `messages`,
|
|
877
|
+
* `tools`, `stream`, and Anthropic's `system`).
|
|
878
|
+
*/
|
|
879
|
+
readonly extraBody?: Record<string, unknown>;
|
|
880
|
+
/** See {@link AgentConfig.thinking}. */
|
|
881
|
+
readonly thinking?: ThinkingConfig;
|
|
882
|
+
readonly systemPrompt?: string;
|
|
883
|
+
readonly abortSignal?: AbortSignal;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Options for streaming calls.
|
|
887
|
+
* Extends {@link LLMChatOptions} without additional fields — the separation
|
|
888
|
+
* exists so callers can type-narrow and implementations can diverge later.
|
|
889
|
+
*/
|
|
890
|
+
export interface LLMStreamOptions extends LLMChatOptions {
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Provider-agnostic interface that every LLM backend must implement.
|
|
894
|
+
*
|
|
895
|
+
* @example
|
|
896
|
+
* ```ts
|
|
897
|
+
* const adapter: LLMAdapter = createAdapter('anthropic')
|
|
898
|
+
* const response = await adapter.chat(messages, { model: 'claude-opus-4-6' })
|
|
899
|
+
* ```
|
|
900
|
+
*/
|
|
901
|
+
export interface LLMAdapter {
|
|
902
|
+
/** Human-readable provider name, e.g. `'anthropic'` or `'openai'`. */
|
|
903
|
+
readonly name: string;
|
|
904
|
+
/**
|
|
905
|
+
* Send a chat request and return the complete response.
|
|
906
|
+
* Throws on non-retryable API errors.
|
|
907
|
+
*/
|
|
908
|
+
chat(messages: LLMMessage[], options: LLMChatOptions): Promise<LLMResponse>;
|
|
909
|
+
/**
|
|
910
|
+
* Send a chat request and yield {@link StreamEvent}s incrementally.
|
|
911
|
+
* The final event in the sequence always has `type === 'done'` on success,
|
|
912
|
+
* or `type === 'error'` on failure.
|
|
913
|
+
*/
|
|
914
|
+
stream(messages: LLMMessage[], options: LLMStreamOptions): AsyncIterable<StreamEvent>;
|
|
915
|
+
}
|
|
916
|
+
//# sourceMappingURL=types.d.ts.map
|