@wundr.io/langgraph-orchestrator 1.0.3
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 +842 -0
- package/dist/checkpointing.d.ts +265 -0
- package/dist/checkpointing.d.ts.map +1 -0
- package/dist/checkpointing.js +577 -0
- package/dist/checkpointing.js.map +1 -0
- package/dist/edges/conditional-edge.d.ts +230 -0
- package/dist/edges/conditional-edge.d.ts.map +1 -0
- package/dist/edges/conditional-edge.js +439 -0
- package/dist/edges/conditional-edge.js.map +1 -0
- package/dist/edges/loop-edge.d.ts +290 -0
- package/dist/edges/loop-edge.d.ts.map +1 -0
- package/dist/edges/loop-edge.js +503 -0
- package/dist/edges/loop-edge.js.map +1 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +269 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/decision-node.d.ts +276 -0
- package/dist/nodes/decision-node.d.ts.map +1 -0
- package/dist/nodes/decision-node.js +403 -0
- package/dist/nodes/decision-node.js.map +1 -0
- package/dist/nodes/human-node.d.ts +272 -0
- package/dist/nodes/human-node.d.ts.map +1 -0
- package/dist/nodes/human-node.js +394 -0
- package/dist/nodes/human-node.js.map +1 -0
- package/dist/nodes/llm-node.d.ts +173 -0
- package/dist/nodes/llm-node.d.ts.map +1 -0
- package/dist/nodes/llm-node.js +325 -0
- package/dist/nodes/llm-node.js.map +1 -0
- package/dist/nodes/tool-node.d.ts +151 -0
- package/dist/nodes/tool-node.d.ts.map +1 -0
- package/dist/nodes/tool-node.js +373 -0
- package/dist/nodes/tool-node.js.map +1 -0
- package/dist/prebuilt-graphs/plan-execute-refine.d.ts +149 -0
- package/dist/prebuilt-graphs/plan-execute-refine.d.ts.map +1 -0
- package/dist/prebuilt-graphs/plan-execute-refine.js +600 -0
- package/dist/prebuilt-graphs/plan-execute-refine.js.map +1 -0
- package/dist/state-graph.d.ts +158 -0
- package/dist/state-graph.d.ts.map +1 -0
- package/dist/state-graph.js +756 -0
- package/dist/state-graph.js.map +1 -0
- package/dist/types.d.ts +762 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +73 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
- package/src/checkpointing.ts +702 -0
- package/src/edges/conditional-edge.ts +518 -0
- package/src/edges/loop-edge.ts +623 -0
- package/src/index.ts +416 -0
- package/src/nodes/decision-node.ts +538 -0
- package/src/nodes/human-node.ts +572 -0
- package/src/nodes/llm-node.ts +448 -0
- package/src/nodes/tool-node.ts +525 -0
- package/src/prebuilt-graphs/plan-execute-refine.ts +769 -0
- package/src/state-graph.ts +990 -0
- package/src/types.ts +729 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LLM Node - LLM-based decision and generation node
|
|
4
|
+
* @module @wundr.io/langgraph-orchestrator
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LLMNodeConfigSchema = void 0;
|
|
8
|
+
exports.createLLMNode = createLLMNode;
|
|
9
|
+
exports.createLLMRouter = createLLMRouter;
|
|
10
|
+
exports.createStructuredLLMNode = createStructuredLLMNode;
|
|
11
|
+
exports.createConversationalLLMNode = createConversationalLLMNode;
|
|
12
|
+
const uuid_1 = require("uuid");
|
|
13
|
+
const zod_1 = require("zod");
|
|
14
|
+
/**
|
|
15
|
+
* Schema for LLM node configuration validation
|
|
16
|
+
*/
|
|
17
|
+
exports.LLMNodeConfigSchema = zod_1.z.object({
|
|
18
|
+
model: zod_1.z.string().optional(),
|
|
19
|
+
systemPrompt: zod_1.z.string().optional(),
|
|
20
|
+
temperature: zod_1.z.number().min(0).max(2).optional(),
|
|
21
|
+
maxTokens: zod_1.z.number().min(1).optional(),
|
|
22
|
+
stop: zod_1.z.array(zod_1.z.string()).optional(),
|
|
23
|
+
stream: zod_1.z.boolean().optional(),
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Create an LLM node for the workflow graph
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const llmNode = createLLMNode({
|
|
31
|
+
* id: 'agent',
|
|
32
|
+
* name: 'Agent Node',
|
|
33
|
+
* config: {
|
|
34
|
+
* model: 'claude-3-sonnet-20240229',
|
|
35
|
+
* systemPrompt: 'You are a helpful assistant.',
|
|
36
|
+
* temperature: 0.7
|
|
37
|
+
* }
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* graph.addNode('agent', llmNode);
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param options - Node creation options
|
|
44
|
+
* @returns NodeDefinition for use in StateGraph
|
|
45
|
+
*/
|
|
46
|
+
function createLLMNode(options) {
|
|
47
|
+
const { id, name, config, nodeConfig = {} } = options;
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
name,
|
|
51
|
+
type: 'llm',
|
|
52
|
+
config: nodeConfig,
|
|
53
|
+
execute: async (state, context) => {
|
|
54
|
+
const llmProvider = context.services.llmProvider;
|
|
55
|
+
if (!llmProvider) {
|
|
56
|
+
throw new Error('LLM provider not configured in node services');
|
|
57
|
+
}
|
|
58
|
+
// Build messages for the request
|
|
59
|
+
const messages = buildMessages(state, config);
|
|
60
|
+
// Build the request
|
|
61
|
+
const request = {
|
|
62
|
+
messages,
|
|
63
|
+
model: config.model,
|
|
64
|
+
temperature: config.temperature,
|
|
65
|
+
maxTokens: config.maxTokens,
|
|
66
|
+
stop: config.stop,
|
|
67
|
+
tools: config.tools,
|
|
68
|
+
};
|
|
69
|
+
context.services.logger.debug('Sending LLM request', {
|
|
70
|
+
model: config.model,
|
|
71
|
+
messageCount: messages.length,
|
|
72
|
+
hasTools: Boolean(config.tools?.length),
|
|
73
|
+
});
|
|
74
|
+
// Execute the request
|
|
75
|
+
const response = await llmProvider.generate(request);
|
|
76
|
+
context.services.logger.debug('Received LLM response', {
|
|
77
|
+
model: response.model,
|
|
78
|
+
finishReason: response.finishReason,
|
|
79
|
+
tokensUsed: response.usage.totalTokens,
|
|
80
|
+
});
|
|
81
|
+
// Build updated state
|
|
82
|
+
const newMessages = [...state.messages, response.message];
|
|
83
|
+
let newData = { ...state.data };
|
|
84
|
+
// Apply post-processing if configured
|
|
85
|
+
if (config.postProcess) {
|
|
86
|
+
const processed = config.postProcess(response, state);
|
|
87
|
+
newData = { ...newData, ...processed.data };
|
|
88
|
+
}
|
|
89
|
+
// Update token count in metadata
|
|
90
|
+
const tokensUsed = (state.metadata.tokensUsed ?? 0) + response.usage.totalTokens;
|
|
91
|
+
const newState = {
|
|
92
|
+
...state,
|
|
93
|
+
messages: newMessages,
|
|
94
|
+
data: newData,
|
|
95
|
+
metadata: {
|
|
96
|
+
...state.metadata,
|
|
97
|
+
tokensUsed,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
// Determine next node
|
|
101
|
+
let next;
|
|
102
|
+
// Check if there are tool calls - if so, route to tool node
|
|
103
|
+
if (response.finishReason === 'tool_calls' &&
|
|
104
|
+
response.message.toolCalls?.length) {
|
|
105
|
+
// Store tool calls in state for tool node to process
|
|
106
|
+
newState.data['pendingToolCalls'] = response.message.toolCalls;
|
|
107
|
+
next = 'tools'; // Default name for tool node
|
|
108
|
+
}
|
|
109
|
+
else if (config.router) {
|
|
110
|
+
next = config.router(response, state);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
state: newState,
|
|
114
|
+
next,
|
|
115
|
+
metadata: {
|
|
116
|
+
duration: 0, // Will be set by executor
|
|
117
|
+
tokensUsed: response.usage.totalTokens,
|
|
118
|
+
toolCalls: response.message.toolCalls,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Build messages array for LLM request
|
|
126
|
+
*/
|
|
127
|
+
function buildMessages(state, config) {
|
|
128
|
+
const messages = [];
|
|
129
|
+
// Add system prompt if configured
|
|
130
|
+
if (config.systemPrompt) {
|
|
131
|
+
messages.push({
|
|
132
|
+
id: (0, uuid_1.v4)(),
|
|
133
|
+
role: 'system',
|
|
134
|
+
content: config.systemPrompt,
|
|
135
|
+
timestamp: new Date(),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Add existing messages from state
|
|
139
|
+
messages.push(...state.messages);
|
|
140
|
+
// If there's a custom prompt template, add it as a user message
|
|
141
|
+
if (config.promptTemplate) {
|
|
142
|
+
const prompt = config.promptTemplate(state);
|
|
143
|
+
messages.push({
|
|
144
|
+
id: (0, uuid_1.v4)(),
|
|
145
|
+
role: 'user',
|
|
146
|
+
content: prompt,
|
|
147
|
+
timestamp: new Date(),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return messages;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a router function for LLM decision-making
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const router = createLLMRouter({
|
|
158
|
+
* routes: {
|
|
159
|
+
* 'continue': 'process-node',
|
|
160
|
+
* 'finish': 'end-node',
|
|
161
|
+
* 'error': 'error-handler'
|
|
162
|
+
* },
|
|
163
|
+
* defaultRoute: 'continue',
|
|
164
|
+
* extractDecision: (response) => {
|
|
165
|
+
* const content = response.message.content;
|
|
166
|
+
* if (content.includes('DONE')) return 'finish';
|
|
167
|
+
* if (content.includes('ERROR')) return 'error';
|
|
168
|
+
* return 'continue';
|
|
169
|
+
* }
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @param options - Router configuration
|
|
174
|
+
* @returns Router function for use in LLM node config
|
|
175
|
+
*/
|
|
176
|
+
function createLLMRouter(options) {
|
|
177
|
+
return (response, state) => {
|
|
178
|
+
const decision = options.extractDecision(response, state);
|
|
179
|
+
return options.routes[decision] ?? options.defaultRoute;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Create a structured output LLM node that validates responses
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const responseSchema = z.object({
|
|
188
|
+
* action: z.enum(['search', 'answer', 'clarify']),
|
|
189
|
+
* content: z.string(),
|
|
190
|
+
* confidence: z.number()
|
|
191
|
+
* });
|
|
192
|
+
*
|
|
193
|
+
* const structuredNode = createStructuredLLMNode({
|
|
194
|
+
* id: 'structured-agent',
|
|
195
|
+
* name: 'Structured Agent',
|
|
196
|
+
* config: {
|
|
197
|
+
* model: 'claude-3-sonnet-20240229',
|
|
198
|
+
* systemPrompt: 'Respond in JSON format with action, content, and confidence fields.'
|
|
199
|
+
* },
|
|
200
|
+
* outputSchema: responseSchema,
|
|
201
|
+
* stateMapper: (parsed) => ({ agentDecision: parsed })
|
|
202
|
+
* });
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* @param options - Structured node options
|
|
206
|
+
* @returns NodeDefinition for use in StateGraph
|
|
207
|
+
*/
|
|
208
|
+
function createStructuredLLMNode(options) {
|
|
209
|
+
const { id, name, config, outputSchema, stateMapper, nodeConfig = {}, } = options;
|
|
210
|
+
const baseNode = createLLMNode({
|
|
211
|
+
id,
|
|
212
|
+
name,
|
|
213
|
+
config: {
|
|
214
|
+
...config,
|
|
215
|
+
postProcess: (response, state) => {
|
|
216
|
+
// Try to parse JSON from response
|
|
217
|
+
const content = response.message.content;
|
|
218
|
+
let parsed;
|
|
219
|
+
try {
|
|
220
|
+
// Try to extract JSON from the response
|
|
221
|
+
const jsonMatch = content.match(/\{[\s\S]*\}/);
|
|
222
|
+
if (jsonMatch) {
|
|
223
|
+
const raw = JSON.parse(jsonMatch[0]);
|
|
224
|
+
parsed = outputSchema.parse(raw);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
throw new Error('No JSON object found in response');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
throw new Error(`Failed to parse structured output: ${error instanceof Error ? error.message : String(error)}`);
|
|
232
|
+
}
|
|
233
|
+
// Map parsed output to state
|
|
234
|
+
const mappedData = stateMapper(parsed);
|
|
235
|
+
return { data: { ...state.data, ...mappedData } };
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
nodeConfig,
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
...baseNode,
|
|
242
|
+
outputSchema,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Create a conversational LLM node that maintains chat history
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* const chatNode = createConversationalLLMNode({
|
|
251
|
+
* id: 'chat',
|
|
252
|
+
* name: 'Chat Node',
|
|
253
|
+
* config: {
|
|
254
|
+
* model: 'claude-3-sonnet-20240229',
|
|
255
|
+
* systemPrompt: 'You are a helpful assistant.'
|
|
256
|
+
* },
|
|
257
|
+
* maxHistoryLength: 10
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @param options - Conversational node options
|
|
262
|
+
* @returns NodeDefinition for use in StateGraph
|
|
263
|
+
*/
|
|
264
|
+
function createConversationalLLMNode(options) {
|
|
265
|
+
const { id, name, config, maxHistoryLength = 50, nodeConfig = {} } = options;
|
|
266
|
+
return {
|
|
267
|
+
id,
|
|
268
|
+
name,
|
|
269
|
+
type: 'llm',
|
|
270
|
+
config: nodeConfig,
|
|
271
|
+
execute: async (state, context) => {
|
|
272
|
+
const llmProvider = context.services.llmProvider;
|
|
273
|
+
if (!llmProvider) {
|
|
274
|
+
throw new Error('LLM provider not configured in node services');
|
|
275
|
+
}
|
|
276
|
+
// Trim history if needed
|
|
277
|
+
let historyMessages = state.messages;
|
|
278
|
+
if (historyMessages.length > maxHistoryLength) {
|
|
279
|
+
// Keep system message if present, then most recent messages
|
|
280
|
+
const systemMessages = historyMessages.filter(m => m.role === 'system');
|
|
281
|
+
const nonSystemMessages = historyMessages.filter(m => m.role !== 'system');
|
|
282
|
+
const trimmedNonSystem = nonSystemMessages.slice(-maxHistoryLength);
|
|
283
|
+
historyMessages = [...systemMessages, ...trimmedNonSystem];
|
|
284
|
+
}
|
|
285
|
+
// Build messages
|
|
286
|
+
const messages = [];
|
|
287
|
+
if (config.systemPrompt) {
|
|
288
|
+
messages.push({
|
|
289
|
+
id: (0, uuid_1.v4)(),
|
|
290
|
+
role: 'system',
|
|
291
|
+
content: config.systemPrompt,
|
|
292
|
+
timestamp: new Date(),
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
messages.push(...historyMessages.filter(m => m.role !== 'system'));
|
|
296
|
+
const request = {
|
|
297
|
+
messages,
|
|
298
|
+
model: config.model,
|
|
299
|
+
temperature: config.temperature,
|
|
300
|
+
maxTokens: config.maxTokens,
|
|
301
|
+
stop: config.stop,
|
|
302
|
+
tools: config.tools,
|
|
303
|
+
};
|
|
304
|
+
const response = await llmProvider.generate(request);
|
|
305
|
+
const newMessages = [...state.messages, response.message];
|
|
306
|
+
const tokensUsed = (state.metadata.tokensUsed ?? 0) + response.usage.totalTokens;
|
|
307
|
+
const newState = {
|
|
308
|
+
...state,
|
|
309
|
+
messages: newMessages,
|
|
310
|
+
metadata: {
|
|
311
|
+
...state.metadata,
|
|
312
|
+
tokensUsed,
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
return {
|
|
316
|
+
state: newState,
|
|
317
|
+
metadata: {
|
|
318
|
+
duration: 0,
|
|
319
|
+
tokensUsed: response.usage.totalTokens,
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=llm-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-node.js","sourceRoot":"","sources":["../../src/nodes/llm-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Node - Tool execution node for agent workflows
|
|
3
|
+
* @module @wundr.io/langgraph-orchestrator
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { AgentState, NodeDefinition, Tool, ToolCall, ToolResult, ToolRegistry } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for tool node
|
|
9
|
+
*/
|
|
10
|
+
export interface ToolNodeConfig {
|
|
11
|
+
/** Available tools (if not using registry) */
|
|
12
|
+
readonly tools?: Tool[];
|
|
13
|
+
/** Whether to execute tools in parallel */
|
|
14
|
+
readonly parallel?: boolean;
|
|
15
|
+
/** Maximum concurrent tool executions */
|
|
16
|
+
readonly maxConcurrency?: number;
|
|
17
|
+
/** Timeout per tool execution in milliseconds */
|
|
18
|
+
readonly toolTimeout?: number;
|
|
19
|
+
/** Whether to continue on tool error */
|
|
20
|
+
readonly continueOnError?: boolean;
|
|
21
|
+
/** Custom error handler */
|
|
22
|
+
readonly onError?: (error: Error, toolCall: ToolCall) => ToolResult;
|
|
23
|
+
/** Post-processing for tool results */
|
|
24
|
+
readonly postProcess?: (results: ToolResult[], state: AgentState) => Partial<AgentState['data']>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Schema for tool node configuration validation
|
|
28
|
+
*/
|
|
29
|
+
export declare const ToolNodeConfigSchema: z.ZodObject<{
|
|
30
|
+
parallel: z.ZodOptional<z.ZodBoolean>;
|
|
31
|
+
maxConcurrency: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
toolTimeout: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
parallel?: boolean | undefined;
|
|
36
|
+
maxConcurrency?: number | undefined;
|
|
37
|
+
toolTimeout?: number | undefined;
|
|
38
|
+
continueOnError?: boolean | undefined;
|
|
39
|
+
}, {
|
|
40
|
+
parallel?: boolean | undefined;
|
|
41
|
+
maxConcurrency?: number | undefined;
|
|
42
|
+
toolTimeout?: number | undefined;
|
|
43
|
+
continueOnError?: boolean | undefined;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Create a tool execution node
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const toolNode = createToolNode({
|
|
51
|
+
* id: 'tools',
|
|
52
|
+
* name: 'Tool Executor',
|
|
53
|
+
* config: {
|
|
54
|
+
* parallel: true,
|
|
55
|
+
* maxConcurrency: 3,
|
|
56
|
+
* continueOnError: true
|
|
57
|
+
* }
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* graph.addNode('tools', toolNode);
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @param options - Node creation options
|
|
64
|
+
* @returns NodeDefinition for use in StateGraph
|
|
65
|
+
*/
|
|
66
|
+
export declare function createToolNode<TState extends AgentState = AgentState>(options: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
config?: ToolNodeConfig;
|
|
70
|
+
nodeConfig?: NodeDefinition<TState>['config'];
|
|
71
|
+
}): NodeDefinition<TState>;
|
|
72
|
+
/**
|
|
73
|
+
* Create a simple in-memory tool registry
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const registry = createToolRegistry();
|
|
78
|
+
* registry.register({
|
|
79
|
+
* name: 'search',
|
|
80
|
+
* description: 'Search the web',
|
|
81
|
+
* inputSchema: z.object({ query: z.string() }),
|
|
82
|
+
* execute: async ({ query }) => searchWeb(query)
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* graph.setServices({ toolRegistry: registry });
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @returns ToolRegistry implementation
|
|
89
|
+
*/
|
|
90
|
+
export declare function createToolRegistry(): ToolRegistry;
|
|
91
|
+
/**
|
|
92
|
+
* Create a tool definition with type-safe input/output
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const searchTool = createTool({
|
|
97
|
+
* name: 'search',
|
|
98
|
+
* description: 'Search the web for information',
|
|
99
|
+
* inputSchema: z.object({
|
|
100
|
+
* query: z.string(),
|
|
101
|
+
* maxResults: z.number().optional()
|
|
102
|
+
* }),
|
|
103
|
+
* outputSchema: z.array(z.object({
|
|
104
|
+
* title: z.string(),
|
|
105
|
+
* url: z.string(),
|
|
106
|
+
* snippet: z.string()
|
|
107
|
+
* })),
|
|
108
|
+
* execute: async ({ query, maxResults = 10 }) => {
|
|
109
|
+
* return await searchWeb(query, maxResults);
|
|
110
|
+
* }
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @param options - Tool definition options
|
|
115
|
+
* @returns Tool definition
|
|
116
|
+
*/
|
|
117
|
+
export declare function createTool<TInput, TOutput = unknown>(options: {
|
|
118
|
+
name: string;
|
|
119
|
+
description: string;
|
|
120
|
+
inputSchema: z.ZodSchema<TInput>;
|
|
121
|
+
outputSchema?: z.ZodSchema<TOutput>;
|
|
122
|
+
execute: (input: TInput) => Promise<TOutput>;
|
|
123
|
+
}): Tool;
|
|
124
|
+
/**
|
|
125
|
+
* Create a batch tool node that groups tool calls
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const batchToolNode = createBatchToolNode({
|
|
130
|
+
* id: 'batch-tools',
|
|
131
|
+
* name: 'Batch Tool Executor',
|
|
132
|
+
* config: {
|
|
133
|
+
* batchSize: 5,
|
|
134
|
+
* batchTimeout: 1000
|
|
135
|
+
* }
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @param options - Node creation options
|
|
140
|
+
* @returns NodeDefinition for use in StateGraph
|
|
141
|
+
*/
|
|
142
|
+
export declare function createBatchToolNode<TState extends AgentState = AgentState>(options: {
|
|
143
|
+
id: string;
|
|
144
|
+
name: string;
|
|
145
|
+
config?: ToolNodeConfig & {
|
|
146
|
+
batchSize?: number;
|
|
147
|
+
batchTimeout?: number;
|
|
148
|
+
};
|
|
149
|
+
nodeConfig?: NodeDefinition<TState>['config'];
|
|
150
|
+
}): NodeDefinition<TState>;
|
|
151
|
+
//# sourceMappingURL=tool-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-node.d.ts","sourceRoot":"","sources":["../../src/nodes/tool-node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EAId,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,YAAY,EACb,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wCAAwC;IACxC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,2BAA2B;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,KAAK,UAAU,CAAC;IACpE,uCAAuC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,CACrB,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,EAAE,UAAU,KACd,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;EAK/B,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,SAAS,UAAU,GAAG,UAAU,EACtC,OAAO,EAAE;IACT,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;CAC/C,GAAG,cAAc,CAAC,MAAM,CAAC,CA2FzB;AAgLD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAuBjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9C,GAAG,IAAI,CAWP;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,SAAS,UAAU,GAAG,UAAU,EACtC,OAAO,EAAE;IACT,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,GAAG;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,UAAU,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;CAC/C,GAAG,cAAc,CAAC,MAAM,CAAC,CA4DzB"}
|