@agentionai/agents 0.3.0-beta
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 +517 -0
- package/dist/agents/Agent.d.ts +29 -0
- package/dist/agents/Agent.js +28 -0
- package/dist/agents/AgentConfig.d.ts +118 -0
- package/dist/agents/AgentConfig.js +3 -0
- package/dist/agents/AgentEvent.d.ts +18 -0
- package/dist/agents/AgentEvent.js +26 -0
- package/dist/agents/BaseAgent.d.ts +82 -0
- package/dist/agents/BaseAgent.js +121 -0
- package/dist/agents/anthropic/ClaudeAgent.d.ts +46 -0
- package/dist/agents/anthropic/ClaudeAgent.js +262 -0
- package/dist/agents/errors/AgentError.d.ts +47 -0
- package/dist/agents/errors/AgentError.js +74 -0
- package/dist/agents/google/GeminiAgent.d.ts +63 -0
- package/dist/agents/google/GeminiAgent.js +395 -0
- package/dist/agents/mistral/MistralAgent.d.ts +47 -0
- package/dist/agents/mistral/MistralAgent.js +313 -0
- package/dist/agents/model-types.d.ts +30 -0
- package/dist/agents/model-types.js +8 -0
- package/dist/agents/openai/OpenAiAgent.d.ts +48 -0
- package/dist/agents/openai/OpenAiAgent.js +338 -0
- package/dist/chunkers/Chunker.d.ts +53 -0
- package/dist/chunkers/Chunker.js +174 -0
- package/dist/chunkers/RecursiveChunker.d.ts +52 -0
- package/dist/chunkers/RecursiveChunker.js +166 -0
- package/dist/chunkers/TextChunker.d.ts +27 -0
- package/dist/chunkers/TextChunker.js +50 -0
- package/dist/chunkers/TokenChunker.d.ts +60 -0
- package/dist/chunkers/TokenChunker.js +176 -0
- package/dist/chunkers/index.d.ts +6 -0
- package/dist/chunkers/index.js +14 -0
- package/dist/chunkers/types.d.ts +95 -0
- package/dist/chunkers/types.js +3 -0
- package/dist/graph/AgentGraph.d.ts +99 -0
- package/dist/graph/AgentGraph.js +115 -0
- package/dist/graph/BaseExecutor.d.ts +86 -0
- package/dist/graph/BaseExecutor.js +61 -0
- package/dist/graph/GraphMetrics.d.ts +143 -0
- package/dist/graph/GraphMetrics.js +264 -0
- package/dist/graph/MapExecutor.d.ts +39 -0
- package/dist/graph/MapExecutor.js +123 -0
- package/dist/graph/ParallelExecutor.d.ts +51 -0
- package/dist/graph/ParallelExecutor.js +103 -0
- package/dist/graph/Pipeline.d.ts +44 -0
- package/dist/graph/Pipeline.js +109 -0
- package/dist/graph/RouterExecutor.d.ts +89 -0
- package/dist/graph/RouterExecutor.js +209 -0
- package/dist/graph/SequentialExecutor.d.ts +44 -0
- package/dist/graph/SequentialExecutor.js +115 -0
- package/dist/graph/VotingSystem.d.ts +54 -0
- package/dist/graph/VotingSystem.js +106 -0
- package/dist/history/History.d.ts +107 -0
- package/dist/history/History.js +166 -0
- package/dist/history/RedisHistory.d.ts +27 -0
- package/dist/history/RedisHistory.js +55 -0
- package/dist/history/transformers.d.ts +102 -0
- package/dist/history/transformers.js +415 -0
- package/dist/history/types.d.ts +130 -0
- package/dist/history/types.js +55 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +48 -0
- package/dist/ingestion/IngestionPipeline.d.ts +86 -0
- package/dist/ingestion/IngestionPipeline.js +266 -0
- package/dist/ingestion/index.d.ts +3 -0
- package/dist/ingestion/index.js +7 -0
- package/dist/ingestion/types.d.ts +74 -0
- package/dist/ingestion/types.js +3 -0
- package/dist/team/Team.d.ts +46 -0
- package/dist/team/Team.js +104 -0
- package/dist/tools/Tool.d.ts +75 -0
- package/dist/tools/Tool.js +137 -0
- package/dist/vectorstore/Embeddings.d.ts +67 -0
- package/dist/vectorstore/Embeddings.js +54 -0
- package/dist/vectorstore/LanceDBVectorStore.d.ts +149 -0
- package/dist/vectorstore/LanceDBVectorStore.js +338 -0
- package/dist/vectorstore/OpenAIEmbeddings.d.ts +45 -0
- package/dist/vectorstore/OpenAIEmbeddings.js +109 -0
- package/dist/vectorstore/VectorStore.d.ts +255 -0
- package/dist/vectorstore/VectorStore.js +216 -0
- package/dist/vectorstore/index.d.ts +28 -0
- package/dist/vectorstore/index.js +35 -0
- package/dist/viz/VizConfig.d.ts +54 -0
- package/dist/viz/VizConfig.js +100 -0
- package/dist/viz/VizReporter.d.ts +127 -0
- package/dist/viz/VizReporter.js +595 -0
- package/dist/viz/index.d.ts +31 -0
- package/dist/viz/index.js +51 -0
- package/dist/viz/types.d.ts +105 -0
- package/dist/viz/types.js +7 -0
- package/package.json +109 -0
- package/readme.md +1 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Metrics and observability for graph execution.
|
|
4
|
+
* Tracks timing, token usage, and pipeline structure for analysis and visualization.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.MetricsCollector = void 0;
|
|
8
|
+
exports.getMetricsCollector = getMetricsCollector;
|
|
9
|
+
exports.setMetricsCollector = setMetricsCollector;
|
|
10
|
+
exports.createMetricsCollector = createMetricsCollector;
|
|
11
|
+
/**
|
|
12
|
+
* Collector for gathering metrics during graph execution.
|
|
13
|
+
*/
|
|
14
|
+
class MetricsCollector {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.executions = [];
|
|
17
|
+
this.currentExecution = null;
|
|
18
|
+
this.executionStack = [];
|
|
19
|
+
this.idCounter = 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generate a unique execution ID.
|
|
23
|
+
*/
|
|
24
|
+
generateId() {
|
|
25
|
+
return `exec_${++this.idCounter}_${Date.now()}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Truncate a string for summary display.
|
|
29
|
+
*/
|
|
30
|
+
truncate(value, maxLength = 100) {
|
|
31
|
+
const str = typeof value === "string" ? value : JSON.stringify(value);
|
|
32
|
+
if (str.length <= maxLength)
|
|
33
|
+
return str;
|
|
34
|
+
return str.substring(0, maxLength - 3) + "...";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Start tracking a node execution.
|
|
38
|
+
*/
|
|
39
|
+
startExecution(name, type, input) {
|
|
40
|
+
const id = this.generateId();
|
|
41
|
+
const metrics = {
|
|
42
|
+
id,
|
|
43
|
+
name,
|
|
44
|
+
type,
|
|
45
|
+
startTime: Date.now(),
|
|
46
|
+
endTime: 0,
|
|
47
|
+
durationMs: 0,
|
|
48
|
+
success: false,
|
|
49
|
+
inputSummary: input !== undefined ? this.truncate(input) : undefined,
|
|
50
|
+
children: [],
|
|
51
|
+
};
|
|
52
|
+
if (this.executionStack.length > 0) {
|
|
53
|
+
// Nested execution - add as child
|
|
54
|
+
const parent = this.executionStack[this.executionStack.length - 1];
|
|
55
|
+
metrics.order = parent.children?.length ?? 0;
|
|
56
|
+
parent.children?.push(metrics);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Top-level execution
|
|
60
|
+
this.executions.push(metrics);
|
|
61
|
+
}
|
|
62
|
+
this.executionStack.push(metrics);
|
|
63
|
+
this.currentExecution = metrics;
|
|
64
|
+
return id;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Complete a node execution.
|
|
68
|
+
*/
|
|
69
|
+
endExecution(id, success, output, tokenUsage, error) {
|
|
70
|
+
const metrics = this.findExecution(id);
|
|
71
|
+
if (!metrics)
|
|
72
|
+
return;
|
|
73
|
+
metrics.endTime = Date.now();
|
|
74
|
+
metrics.durationMs = metrics.endTime - metrics.startTime;
|
|
75
|
+
metrics.success = success;
|
|
76
|
+
metrics.outputSummary =
|
|
77
|
+
output !== undefined ? this.truncate(output) : undefined;
|
|
78
|
+
metrics.tokenUsage = tokenUsage;
|
|
79
|
+
metrics.error = error;
|
|
80
|
+
// Pop from stack
|
|
81
|
+
const index = this.executionStack.findIndex((e) => e.id === id);
|
|
82
|
+
if (index !== -1) {
|
|
83
|
+
this.executionStack.splice(index, 1);
|
|
84
|
+
}
|
|
85
|
+
this.currentExecution =
|
|
86
|
+
this.executionStack[this.executionStack.length - 1] ?? null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Find an execution by ID.
|
|
90
|
+
*/
|
|
91
|
+
findExecution(id) {
|
|
92
|
+
const search = (metrics) => {
|
|
93
|
+
for (const m of metrics) {
|
|
94
|
+
if (m.id === id)
|
|
95
|
+
return m;
|
|
96
|
+
if (m.children) {
|
|
97
|
+
const found = search(m.children);
|
|
98
|
+
if (found)
|
|
99
|
+
return found;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
return search(this.executions);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Add token usage to the current execution.
|
|
108
|
+
*/
|
|
109
|
+
addTokenUsage(usage) {
|
|
110
|
+
if (this.currentExecution) {
|
|
111
|
+
if (this.currentExecution.tokenUsage) {
|
|
112
|
+
this.currentExecution.tokenUsage.inputTokens += usage.inputTokens;
|
|
113
|
+
this.currentExecution.tokenUsage.outputTokens += usage.outputTokens;
|
|
114
|
+
this.currentExecution.tokenUsage.totalTokens += usage.totalTokens;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.currentExecution.tokenUsage = { ...usage };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get all collected metrics.
|
|
123
|
+
*/
|
|
124
|
+
getExecutions() {
|
|
125
|
+
return this.executions;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Calculate aggregate metrics.
|
|
129
|
+
*/
|
|
130
|
+
getAggregateMetrics() {
|
|
131
|
+
const totalTokens = {
|
|
132
|
+
inputTokens: 0,
|
|
133
|
+
outputTokens: 0,
|
|
134
|
+
totalTokens: 0,
|
|
135
|
+
};
|
|
136
|
+
let nodeCount = 0;
|
|
137
|
+
let successCount = 0;
|
|
138
|
+
let failureCount = 0;
|
|
139
|
+
let totalDurationMs = 0;
|
|
140
|
+
const aggregate = (metrics) => {
|
|
141
|
+
for (const m of metrics) {
|
|
142
|
+
nodeCount++;
|
|
143
|
+
if (m.success)
|
|
144
|
+
successCount++;
|
|
145
|
+
else
|
|
146
|
+
failureCount++;
|
|
147
|
+
if (m.tokenUsage) {
|
|
148
|
+
totalTokens.inputTokens += m.tokenUsage.inputTokens;
|
|
149
|
+
totalTokens.outputTokens += m.tokenUsage.outputTokens;
|
|
150
|
+
totalTokens.totalTokens += m.tokenUsage.totalTokens;
|
|
151
|
+
}
|
|
152
|
+
if (m.children) {
|
|
153
|
+
aggregate(m.children);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
aggregate(this.executions);
|
|
158
|
+
// Total duration is from first start to last end
|
|
159
|
+
if (this.executions.length > 0) {
|
|
160
|
+
const firstStart = Math.min(...this.executions.map((e) => e.startTime));
|
|
161
|
+
const lastEnd = Math.max(...this.executions.map((e) => e.endTime));
|
|
162
|
+
totalDurationMs = lastEnd - firstStart;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
totalDurationMs,
|
|
166
|
+
totalTokens,
|
|
167
|
+
nodeCount,
|
|
168
|
+
successCount,
|
|
169
|
+
failureCount,
|
|
170
|
+
stages: this.executions,
|
|
171
|
+
structure: this.buildStructure(),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build pipeline structure for visualization.
|
|
176
|
+
*/
|
|
177
|
+
buildStructure() {
|
|
178
|
+
const buildNode = (metrics) => {
|
|
179
|
+
const node = {
|
|
180
|
+
type: metrics.type,
|
|
181
|
+
name: metrics.name,
|
|
182
|
+
};
|
|
183
|
+
if (metrics.children && metrics.children.length > 0) {
|
|
184
|
+
node.children = metrics.children.map(buildNode);
|
|
185
|
+
}
|
|
186
|
+
return node;
|
|
187
|
+
};
|
|
188
|
+
if (this.executions.length === 1) {
|
|
189
|
+
return buildNode(this.executions[0]);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
type: "pipeline",
|
|
193
|
+
name: "root",
|
|
194
|
+
children: this.executions.map(buildNode),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Reset all collected metrics.
|
|
199
|
+
*/
|
|
200
|
+
reset() {
|
|
201
|
+
this.executions = [];
|
|
202
|
+
this.currentExecution = null;
|
|
203
|
+
this.executionStack = [];
|
|
204
|
+
this.idCounter = 0;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Generate a simple text-based visualization of the pipeline.
|
|
208
|
+
*/
|
|
209
|
+
toTextVisualization() {
|
|
210
|
+
const lines = [];
|
|
211
|
+
const render = (metrics, indent = 0) => {
|
|
212
|
+
const prefix = " ".repeat(indent);
|
|
213
|
+
const status = metrics.success ? "✓" : "✗";
|
|
214
|
+
const duration = `${metrics.durationMs}ms`;
|
|
215
|
+
const tokens = metrics.tokenUsage
|
|
216
|
+
? ` [${metrics.tokenUsage.totalTokens} tokens]`
|
|
217
|
+
: "";
|
|
218
|
+
lines.push(`${prefix}${status} ${metrics.name} (${metrics.type}) - ${duration}${tokens}`);
|
|
219
|
+
if (metrics.children) {
|
|
220
|
+
for (const child of metrics.children) {
|
|
221
|
+
render(child, indent + 1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
for (const execution of this.executions) {
|
|
226
|
+
render(execution);
|
|
227
|
+
}
|
|
228
|
+
return lines.join("\n");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Generate a JSON representation suitable for external visualization tools.
|
|
232
|
+
*/
|
|
233
|
+
toJSON() {
|
|
234
|
+
return JSON.stringify(this.getAggregateMetrics(), null, 2);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.MetricsCollector = MetricsCollector;
|
|
238
|
+
/**
|
|
239
|
+
* Global metrics collector instance.
|
|
240
|
+
* Can be replaced with a custom instance if needed.
|
|
241
|
+
*/
|
|
242
|
+
let globalCollector = null;
|
|
243
|
+
/**
|
|
244
|
+
* Get or create the global metrics collector.
|
|
245
|
+
*/
|
|
246
|
+
function getMetricsCollector() {
|
|
247
|
+
if (!globalCollector) {
|
|
248
|
+
globalCollector = new MetricsCollector();
|
|
249
|
+
}
|
|
250
|
+
return globalCollector;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Set a custom global metrics collector.
|
|
254
|
+
*/
|
|
255
|
+
function setMetricsCollector(collector) {
|
|
256
|
+
globalCollector = collector;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Create a new metrics collector (for isolated tracking).
|
|
260
|
+
*/
|
|
261
|
+
function createMetricsCollector() {
|
|
262
|
+
return new MetricsCollector();
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=GraphMetrics.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BaseExecutor, GraphNode } from "./BaseExecutor";
|
|
2
|
+
/**
|
|
3
|
+
* Options for configuring map execution behavior.
|
|
4
|
+
*/
|
|
5
|
+
export interface MapExecutorOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Maximum number of concurrent executions.
|
|
8
|
+
* If undefined, all items are processed in parallel.
|
|
9
|
+
* @default undefined (unlimited)
|
|
10
|
+
*/
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Maps a processor over each item in an array of inputs.
|
|
15
|
+
* Similar to Array.map but for async GraphNode processing.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const mapper = new MapExecutor(summaryAgent);
|
|
20
|
+
* const summaries = await mapper.execute(["doc1", "doc2", "doc3"]);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class MapExecutor<TItem = string, TResult = string> extends BaseExecutor<TItem[], TResult[]> {
|
|
24
|
+
private processor;
|
|
25
|
+
private options;
|
|
26
|
+
constructor(processor: GraphNode<TItem, TResult>, options?: MapExecutorOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Processes each item in the input array through the processor.
|
|
29
|
+
* @param input - Array of items to process
|
|
30
|
+
* @returns Array of processed results
|
|
31
|
+
* @throws Error if input is not an array
|
|
32
|
+
*/
|
|
33
|
+
execute(input: TItem[]): Promise<TResult[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Processes items with a concurrency limit.
|
|
36
|
+
*/
|
|
37
|
+
private executeWithConcurrency;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=MapExecutor.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MapExecutor = void 0;
|
|
4
|
+
const BaseExecutor_1 = require("./BaseExecutor");
|
|
5
|
+
/**
|
|
6
|
+
* Maps a processor over each item in an array of inputs.
|
|
7
|
+
* Similar to Array.map but for async GraphNode processing.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const mapper = new MapExecutor(summaryAgent);
|
|
12
|
+
* const summaries = await mapper.execute(["doc1", "doc2", "doc3"]);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
class MapExecutor extends BaseExecutor_1.BaseExecutor {
|
|
16
|
+
constructor(processor, options = {}) {
|
|
17
|
+
super();
|
|
18
|
+
this.name = "MapExecutor";
|
|
19
|
+
this.nodeType = "map";
|
|
20
|
+
this.processor = processor;
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Processes each item in the input array through the processor.
|
|
25
|
+
* @param input - Array of items to process
|
|
26
|
+
* @returns Array of processed results
|
|
27
|
+
* @throws Error if input is not an array
|
|
28
|
+
*/
|
|
29
|
+
async execute(input) {
|
|
30
|
+
const collector = this.getCollector();
|
|
31
|
+
const execId = collector?.startExecution(this.name, "map", input);
|
|
32
|
+
if (!Array.isArray(input)) {
|
|
33
|
+
const error = new Error("MapExecutor requires an array input");
|
|
34
|
+
if (execId)
|
|
35
|
+
collector?.endExecution(execId, false, undefined, undefined, error.message);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
if (input.length === 0) {
|
|
39
|
+
if (execId)
|
|
40
|
+
collector?.endExecution(execId, true, []);
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
let results;
|
|
45
|
+
if (this.options.concurrency !== undefined) {
|
|
46
|
+
results = await this.executeWithConcurrency(input, this.options.concurrency);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Process all items in parallel with metrics
|
|
50
|
+
results = await Promise.all(input.map(async (item, index) => {
|
|
51
|
+
const itemExecId = collector?.startExecution(`${this.processor.name ?? "Processor"} [${index}]`, "agent", item);
|
|
52
|
+
try {
|
|
53
|
+
const result = await this.processor.execute(item);
|
|
54
|
+
if (itemExecId)
|
|
55
|
+
collector?.endExecution(itemExecId, true, result);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (itemExecId) {
|
|
60
|
+
collector?.endExecution(itemExecId, false, undefined, undefined, error instanceof Error ? error.message : String(error));
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
if (execId)
|
|
67
|
+
collector?.endExecution(execId, true, results);
|
|
68
|
+
return results;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (execId) {
|
|
72
|
+
collector?.endExecution(execId, false, undefined, undefined, error instanceof Error ? error.message : String(error));
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Processes items with a concurrency limit.
|
|
79
|
+
*/
|
|
80
|
+
async executeWithConcurrency(items, concurrency) {
|
|
81
|
+
const results = new Array(items.length);
|
|
82
|
+
const executing = [];
|
|
83
|
+
const collector = this.getCollector();
|
|
84
|
+
for (let i = 0; i < items.length; i++) {
|
|
85
|
+
const index = i;
|
|
86
|
+
const item = items[i];
|
|
87
|
+
const promise = (async () => {
|
|
88
|
+
const itemExecId = collector?.startExecution(`${this.processor.name ?? "Processor"} [${index}]`, "agent", item);
|
|
89
|
+
try {
|
|
90
|
+
const result = await this.processor.execute(item);
|
|
91
|
+
results[index] = result;
|
|
92
|
+
if (itemExecId)
|
|
93
|
+
collector?.endExecution(itemExecId, true, result);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (itemExecId) {
|
|
97
|
+
collector?.endExecution(itemExecId, false, undefined, undefined, error instanceof Error ? error.message : String(error));
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
executing.push(promise);
|
|
103
|
+
if (executing.length >= concurrency) {
|
|
104
|
+
await Promise.race(executing);
|
|
105
|
+
// Remove completed promises
|
|
106
|
+
for (let j = executing.length - 1; j >= 0; j--) {
|
|
107
|
+
// Check if promise is settled by racing with an immediate resolve
|
|
108
|
+
const isSettled = await Promise.race([
|
|
109
|
+
executing[j].then(() => true).catch(() => true),
|
|
110
|
+
Promise.resolve(false),
|
|
111
|
+
]);
|
|
112
|
+
if (isSettled) {
|
|
113
|
+
executing.splice(j, 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
await Promise.all(executing);
|
|
119
|
+
return results;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.MapExecutor = MapExecutor;
|
|
123
|
+
//# sourceMappingURL=MapExecutor.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { BaseAgent } from "../agents/BaseAgent";
|
|
2
|
+
import { BaseExecutor } from "./BaseExecutor";
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring parallel execution behavior.
|
|
5
|
+
*/
|
|
6
|
+
export interface ParallelExecutorOptions {
|
|
7
|
+
/**
|
|
8
|
+
* If true, each agent receives only the original input.
|
|
9
|
+
* If false, agents receive the input with shared context.
|
|
10
|
+
* @default true
|
|
11
|
+
*/
|
|
12
|
+
isolatedExecution?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* If true, wraps the input in a JSON object with originalQuestion.
|
|
15
|
+
* If false, passes the raw input to each agent.
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
wrapInput?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Executes multiple agents in parallel on the same input.
|
|
22
|
+
* Returns an array of results from all agents.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const executor = new ParallelExecutor({}, expertA, expertB, expertC);
|
|
27
|
+
* const results = await executor.execute("Analyze this data");
|
|
28
|
+
* // results is string[] with each expert's response
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class ParallelExecutor extends BaseExecutor<string, string[]> {
|
|
32
|
+
private agents;
|
|
33
|
+
private options;
|
|
34
|
+
constructor(options?: ParallelExecutorOptions, ...agents: BaseAgent[]);
|
|
35
|
+
/**
|
|
36
|
+
* Executes all agents in parallel with the same input.
|
|
37
|
+
* @param input - The input string to send to all agents
|
|
38
|
+
* @returns Array of results from each agent
|
|
39
|
+
*/
|
|
40
|
+
execute(input: string): Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Attempt to extract token usage from an agent.
|
|
43
|
+
* Converts from agent's snake_case format to metrics camelCase format.
|
|
44
|
+
*/
|
|
45
|
+
private extractTokenUsage;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the number of agents that will execute in parallel.
|
|
48
|
+
*/
|
|
49
|
+
get length(): number;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=ParallelExecutor.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParallelExecutor = void 0;
|
|
4
|
+
const BaseExecutor_1 = require("./BaseExecutor");
|
|
5
|
+
/**
|
|
6
|
+
* Executes multiple agents in parallel on the same input.
|
|
7
|
+
* Returns an array of results from all agents.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const executor = new ParallelExecutor({}, expertA, expertB, expertC);
|
|
12
|
+
* const results = await executor.execute("Analyze this data");
|
|
13
|
+
* // results is string[] with each expert's response
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
class ParallelExecutor extends BaseExecutor_1.BaseExecutor {
|
|
17
|
+
constructor(options = {}, ...agents) {
|
|
18
|
+
super();
|
|
19
|
+
this.name = "ParallelExecutor";
|
|
20
|
+
this.nodeType = "parallel";
|
|
21
|
+
this.agents = agents;
|
|
22
|
+
this.options = {
|
|
23
|
+
isolatedExecution: options.isolatedExecution ?? true,
|
|
24
|
+
wrapInput: options.wrapInput ?? true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Executes all agents in parallel with the same input.
|
|
29
|
+
* @param input - The input string to send to all agents
|
|
30
|
+
* @returns Array of results from each agent
|
|
31
|
+
*/
|
|
32
|
+
async execute(input) {
|
|
33
|
+
const collector = this.getCollector();
|
|
34
|
+
const execId = collector?.startExecution(this.name, "parallel", input);
|
|
35
|
+
if (this.agents.length === 0) {
|
|
36
|
+
if (execId)
|
|
37
|
+
collector?.endExecution(execId, true, []);
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const executionPromises = this.agents.map(async (agent, index) => {
|
|
42
|
+
const agentName = agent.getName?.() ?? `Agent ${index + 1}`;
|
|
43
|
+
const agentExecId = collector?.startExecution(agentName, "agent", input);
|
|
44
|
+
const agentInput = this.options.wrapInput
|
|
45
|
+
? JSON.stringify({
|
|
46
|
+
originalQuestion: input,
|
|
47
|
+
...(this.options.isolatedExecution
|
|
48
|
+
? {}
|
|
49
|
+
: { sharedContext: true }),
|
|
50
|
+
})
|
|
51
|
+
: input;
|
|
52
|
+
try {
|
|
53
|
+
const result = await agent.execute(agentInput);
|
|
54
|
+
// Try to get token usage from agent
|
|
55
|
+
const tokenUsage = this.extractTokenUsage(agent);
|
|
56
|
+
if (agentExecId) {
|
|
57
|
+
collector?.endExecution(agentExecId, true, result, tokenUsage);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (agentExecId) {
|
|
63
|
+
collector?.endExecution(agentExecId, false, undefined, undefined, error instanceof Error ? error.message : String(error));
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const results = await Promise.all(executionPromises);
|
|
69
|
+
if (execId)
|
|
70
|
+
collector?.endExecution(execId, true, results);
|
|
71
|
+
return results;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (execId) {
|
|
75
|
+
collector?.endExecution(execId, false, undefined, undefined, error instanceof Error ? error.message : String(error));
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Attempt to extract token usage from an agent.
|
|
82
|
+
* Converts from agent's snake_case format to metrics camelCase format.
|
|
83
|
+
*/
|
|
84
|
+
extractTokenUsage(agent) {
|
|
85
|
+
const agentWithUsage = agent;
|
|
86
|
+
if (!agentWithUsage.lastTokenUsage)
|
|
87
|
+
return undefined;
|
|
88
|
+
// Convert from snake_case to camelCase
|
|
89
|
+
return {
|
|
90
|
+
inputTokens: agentWithUsage.lastTokenUsage.input_tokens,
|
|
91
|
+
outputTokens: agentWithUsage.lastTokenUsage.output_tokens,
|
|
92
|
+
totalTokens: agentWithUsage.lastTokenUsage.total_tokens,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns the number of agents that will execute in parallel.
|
|
97
|
+
*/
|
|
98
|
+
get length() {
|
|
99
|
+
return this.agents.length;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.ParallelExecutor = ParallelExecutor;
|
|
103
|
+
//# sourceMappingURL=ParallelExecutor.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GraphNode, BaseExecutor, MetricsCollector } from "./BaseExecutor";
|
|
2
|
+
/**
|
|
3
|
+
* Builds a pipeline of graph nodes that execute in sequence,
|
|
4
|
+
* where the output of each stage becomes the input of the next.
|
|
5
|
+
*
|
|
6
|
+
* Unlike SequentialExecutor which is specific to agents,
|
|
7
|
+
* Pipeline can chain any GraphNode implementations together.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const pipeline = new Pipeline(
|
|
12
|
+
* AgentGraph.sequential(researchAgent, factChecker),
|
|
13
|
+
* AgentGraph.parallel({}, expertA, expertB),
|
|
14
|
+
* customTransformer,
|
|
15
|
+
* AgentGraph.votingSystem(judgeAgent)
|
|
16
|
+
* );
|
|
17
|
+
* const result = await pipeline.execute("Research topic X");
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class Pipeline<TInput = unknown, TOutput = unknown> extends BaseExecutor<TInput, TOutput> implements GraphNode<TInput, TOutput> {
|
|
21
|
+
private stages;
|
|
22
|
+
constructor(...stages: GraphNode<unknown, unknown>[]);
|
|
23
|
+
/**
|
|
24
|
+
* Adds a stage to the end of the pipeline.
|
|
25
|
+
* @param stage - The GraphNode to add
|
|
26
|
+
* @returns The pipeline instance for chaining
|
|
27
|
+
*/
|
|
28
|
+
addStage<TStageOutput>(stage: GraphNode<TOutput, TStageOutput>): Pipeline<TInput, TStageOutput>;
|
|
29
|
+
/**
|
|
30
|
+
* Executes all stages in sequence.
|
|
31
|
+
* @param input - The initial input
|
|
32
|
+
* @returns The output from the final stage
|
|
33
|
+
*/
|
|
34
|
+
execute(input: TInput): Promise<TOutput>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the number of stages in the pipeline.
|
|
37
|
+
*/
|
|
38
|
+
get length(): number;
|
|
39
|
+
/**
|
|
40
|
+
* Enable metrics collection and return the pipeline for chaining.
|
|
41
|
+
*/
|
|
42
|
+
withMetrics(collector?: MetricsCollector): this;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=Pipeline.d.ts.map
|