@agentforge/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -0
- package/dist/index.cjs +4048 -0
- package/dist/index.d.cts +4076 -0
- package/dist/index.d.ts +4076 -0
- package/dist/index.js +3905 -0
- package/package.json +68 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,4076 @@
|
|
|
1
|
+
import { z, ZodType, ZodTypeDef } from 'zod';
|
|
2
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
3
|
+
import { AnnotationRoot, StateDefinition, StateGraph, END, MemorySaver, BaseCheckpointSaver, CheckpointTuple } from '@langchain/langgraph';
|
|
4
|
+
import { RunnableConfig } from '@langchain/core/runnables';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tool System Types
|
|
8
|
+
*
|
|
9
|
+
* Core type definitions for the AgentForge tool system.
|
|
10
|
+
* These types define the structure and metadata for tools.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* ToolCategory - Categories for organizing tools
|
|
15
|
+
*
|
|
16
|
+
* Why use an enum?
|
|
17
|
+
* - Type safety: Can't use invalid categories
|
|
18
|
+
* - Autocomplete: IDE suggests valid options
|
|
19
|
+
* - Consistency: Everyone uses the same category names
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* ```ts
|
|
23
|
+
* const tool = { category: ToolCategory.FILE_SYSTEM };
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare enum ToolCategory {
|
|
27
|
+
/**
|
|
28
|
+
* Tools for file system operations
|
|
29
|
+
* Examples: read-file, write-file, list-directory
|
|
30
|
+
*/
|
|
31
|
+
FILE_SYSTEM = "file-system",
|
|
32
|
+
/**
|
|
33
|
+
* Tools for web/HTTP operations
|
|
34
|
+
* Examples: http-request, web-scrape, download-file
|
|
35
|
+
*/
|
|
36
|
+
WEB = "web",
|
|
37
|
+
/**
|
|
38
|
+
* Tools for code operations
|
|
39
|
+
* Examples: execute-code, analyze-syntax, format-code
|
|
40
|
+
*/
|
|
41
|
+
CODE = "code",
|
|
42
|
+
/**
|
|
43
|
+
* Tools for database operations
|
|
44
|
+
* Examples: query-database, insert-record, update-record
|
|
45
|
+
*/
|
|
46
|
+
DATABASE = "database",
|
|
47
|
+
/**
|
|
48
|
+
* Tools for API integrations
|
|
49
|
+
* Examples: github-api, slack-api, stripe-api
|
|
50
|
+
*/
|
|
51
|
+
API = "api",
|
|
52
|
+
/**
|
|
53
|
+
* General utility tools
|
|
54
|
+
* Examples: calculate, format-date, generate-uuid
|
|
55
|
+
*/
|
|
56
|
+
UTILITY = "utility",
|
|
57
|
+
/**
|
|
58
|
+
* Custom/user-defined tools
|
|
59
|
+
* Use this for tools that don't fit other categories
|
|
60
|
+
*/
|
|
61
|
+
CUSTOM = "custom"
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* ToolExample - Example usage of a tool
|
|
65
|
+
*
|
|
66
|
+
* Why examples?
|
|
67
|
+
* - Help LLMs understand how to use the tool
|
|
68
|
+
* - Provide documentation for developers
|
|
69
|
+
* - Enable few-shot learning in prompts
|
|
70
|
+
*
|
|
71
|
+
* Example:
|
|
72
|
+
* ```ts
|
|
73
|
+
* const example: ToolExample = {
|
|
74
|
+
* description: 'Read a text file',
|
|
75
|
+
* input: { path: './README.md' },
|
|
76
|
+
* output: '# My Project\n\nWelcome...',
|
|
77
|
+
* explanation: 'Reads the file and returns its contents as a string'
|
|
78
|
+
* };
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
interface ToolExample {
|
|
82
|
+
/**
|
|
83
|
+
* What this example demonstrates
|
|
84
|
+
* Should be concise and clear
|
|
85
|
+
*/
|
|
86
|
+
description: string;
|
|
87
|
+
/**
|
|
88
|
+
* Example input parameters
|
|
89
|
+
* Must match the tool's schema
|
|
90
|
+
*/
|
|
91
|
+
input: Record<string, unknown>;
|
|
92
|
+
/**
|
|
93
|
+
* Expected output (optional)
|
|
94
|
+
* Helps users understand what to expect
|
|
95
|
+
*/
|
|
96
|
+
output?: unknown;
|
|
97
|
+
/**
|
|
98
|
+
* Additional explanation (optional)
|
|
99
|
+
* Why this example works, edge cases, etc.
|
|
100
|
+
*/
|
|
101
|
+
explanation?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* ToolMetadata - Rich metadata for a tool
|
|
105
|
+
*
|
|
106
|
+
* Why so much metadata?
|
|
107
|
+
* - Better LLM understanding: More context = better tool selection
|
|
108
|
+
* - Better developer experience: Clear documentation
|
|
109
|
+
* - Better discoverability: Search by tags, categories
|
|
110
|
+
* - Better maintenance: Version tracking, deprecation warnings
|
|
111
|
+
*
|
|
112
|
+
* Example:
|
|
113
|
+
* ```ts
|
|
114
|
+
* const metadata: ToolMetadata = {
|
|
115
|
+
* name: 'read-file',
|
|
116
|
+
* displayName: 'Read File',
|
|
117
|
+
* description: 'Read contents of a file from the file system',
|
|
118
|
+
* category: ToolCategory.FILE_SYSTEM,
|
|
119
|
+
* tags: ['file', 'read', 'io'],
|
|
120
|
+
* examples: [{ description: 'Read README', input: { path: './README.md' } }],
|
|
121
|
+
* usageNotes: 'Paths are relative to current working directory',
|
|
122
|
+
* limitations: ['Cannot read files larger than 10MB'],
|
|
123
|
+
* version: '1.0.0',
|
|
124
|
+
* author: 'AgentForge'
|
|
125
|
+
* };
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
interface ToolMetadata {
|
|
129
|
+
/**
|
|
130
|
+
* Unique identifier for the tool
|
|
131
|
+
* Must be kebab-case (lowercase with hyphens)
|
|
132
|
+
* Examples: 'read-file', 'http-request', 'query-database'
|
|
133
|
+
*/
|
|
134
|
+
name: string;
|
|
135
|
+
/**
|
|
136
|
+
* Clear description of what the tool does
|
|
137
|
+
* Should be 1-2 sentences, written for LLMs to understand
|
|
138
|
+
* Example: 'Read the contents of a file from the file system'
|
|
139
|
+
*/
|
|
140
|
+
description: string;
|
|
141
|
+
/**
|
|
142
|
+
* Primary category for this tool
|
|
143
|
+
* Used for grouping and filtering
|
|
144
|
+
*/
|
|
145
|
+
category: ToolCategory;
|
|
146
|
+
/**
|
|
147
|
+
* Human-readable display name (optional)
|
|
148
|
+
* Example: 'Read File' instead of 'read-file'
|
|
149
|
+
*/
|
|
150
|
+
displayName?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Tags for search and filtering (optional)
|
|
153
|
+
* Example: ['file', 'read', 'io', 'filesystem']
|
|
154
|
+
*/
|
|
155
|
+
tags?: string[];
|
|
156
|
+
/**
|
|
157
|
+
* Usage examples (optional but highly recommended)
|
|
158
|
+
* Helps LLMs understand how to use the tool
|
|
159
|
+
*/
|
|
160
|
+
examples?: ToolExample[];
|
|
161
|
+
/**
|
|
162
|
+
* Additional usage notes (optional)
|
|
163
|
+
* Important details about how to use the tool
|
|
164
|
+
* Example: 'Paths are relative to the current working directory'
|
|
165
|
+
*/
|
|
166
|
+
usageNotes?: string;
|
|
167
|
+
/**
|
|
168
|
+
* Known limitations (optional)
|
|
169
|
+
* What the tool cannot do
|
|
170
|
+
* Example: ['Cannot read files larger than 10MB', 'Requires read permissions']
|
|
171
|
+
*/
|
|
172
|
+
limitations?: string[];
|
|
173
|
+
/**
|
|
174
|
+
* Tool version (optional)
|
|
175
|
+
* Semantic versioning recommended
|
|
176
|
+
* Example: '1.0.0'
|
|
177
|
+
*/
|
|
178
|
+
version?: string;
|
|
179
|
+
/**
|
|
180
|
+
* Tool author (optional)
|
|
181
|
+
* Who created/maintains this tool
|
|
182
|
+
* Example: 'AgentForge Team'
|
|
183
|
+
*/
|
|
184
|
+
author?: string;
|
|
185
|
+
/**
|
|
186
|
+
* Deprecation flag (optional)
|
|
187
|
+
* Set to true if this tool should no longer be used
|
|
188
|
+
*/
|
|
189
|
+
deprecated?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Replacement tool name (optional)
|
|
192
|
+
* If deprecated, what tool should be used instead?
|
|
193
|
+
* Example: 'read-file-v2'
|
|
194
|
+
*/
|
|
195
|
+
replacedBy?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Tool - Complete tool definition
|
|
199
|
+
*
|
|
200
|
+
* This is the main interface that combines:
|
|
201
|
+
* - Metadata: What the tool is and how to use it
|
|
202
|
+
* - Schema: What inputs it accepts (validated with Zod)
|
|
203
|
+
* - Execute: The actual implementation
|
|
204
|
+
*
|
|
205
|
+
* Why generic types?
|
|
206
|
+
* - TInput: Type of the input parameters (inferred from schema)
|
|
207
|
+
* - TOutput: Type of the return value
|
|
208
|
+
* - This gives us full type safety!
|
|
209
|
+
*
|
|
210
|
+
* Example:
|
|
211
|
+
* ```ts
|
|
212
|
+
* const readFileTool: Tool<{ path: string }, string> = {
|
|
213
|
+
* metadata: { name: 'read-file', ... },
|
|
214
|
+
* schema: z.object({ path: z.string() }),
|
|
215
|
+
* execute: async ({ path }) => {
|
|
216
|
+
* // Implementation here
|
|
217
|
+
* return fileContents;
|
|
218
|
+
* }
|
|
219
|
+
* };
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
interface Tool<TInput = unknown, TOutput = unknown> {
|
|
223
|
+
/**
|
|
224
|
+
* Rich metadata about the tool
|
|
225
|
+
*/
|
|
226
|
+
metadata: ToolMetadata;
|
|
227
|
+
/**
|
|
228
|
+
* Zod schema for input validation
|
|
229
|
+
*
|
|
230
|
+
* Why Zod?
|
|
231
|
+
* - Runtime validation: Catch errors before execution
|
|
232
|
+
* - Type inference: TypeScript types from schema
|
|
233
|
+
* - Great error messages: Clear validation errors
|
|
234
|
+
* - JSON Schema conversion: For LangChain integration
|
|
235
|
+
*/
|
|
236
|
+
schema: z.ZodSchema<TInput>;
|
|
237
|
+
/**
|
|
238
|
+
* Tool implementation
|
|
239
|
+
*
|
|
240
|
+
* Why async?
|
|
241
|
+
* - Most tools do I/O (files, network, database)
|
|
242
|
+
* - Async is more flexible (can handle both sync and async)
|
|
243
|
+
*
|
|
244
|
+
* The input is automatically validated against the schema
|
|
245
|
+
* before this function is called.
|
|
246
|
+
*/
|
|
247
|
+
execute: (input: TInput) => Promise<TOutput>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Tool System Schemas
|
|
252
|
+
*
|
|
253
|
+
* Zod schemas for runtime validation of tool metadata and configuration.
|
|
254
|
+
*
|
|
255
|
+
* Why Zod schemas?
|
|
256
|
+
* - Runtime validation: Catch errors when tools are created
|
|
257
|
+
* - Type inference: TypeScript types are automatically inferred
|
|
258
|
+
* - Great errors: Clear messages when validation fails
|
|
259
|
+
* - JSON Schema: Can convert to JSON Schema for LangChain
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Schema for ToolCategory
|
|
264
|
+
*
|
|
265
|
+
* This validates that a value is one of the valid ToolCategory enum values.
|
|
266
|
+
*
|
|
267
|
+
* Example:
|
|
268
|
+
* ```ts
|
|
269
|
+
* ToolCategorySchema.parse('file-system'); // ✅ Valid
|
|
270
|
+
* ToolCategorySchema.parse('invalid'); // ❌ Throws ZodError
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare const ToolCategorySchema: z.ZodNativeEnum<typeof ToolCategory>;
|
|
274
|
+
/**
|
|
275
|
+
* Schema for ToolExample
|
|
276
|
+
*
|
|
277
|
+
* Validates the structure of tool usage examples.
|
|
278
|
+
*
|
|
279
|
+
* Example:
|
|
280
|
+
* ```ts
|
|
281
|
+
* ToolExampleSchema.parse({
|
|
282
|
+
* description: 'Read a file',
|
|
283
|
+
* input: { path: './file.txt' },
|
|
284
|
+
* output: 'file contents',
|
|
285
|
+
* explanation: 'Reads and returns file contents'
|
|
286
|
+
* });
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
declare const ToolExampleSchema: z.ZodObject<{
|
|
290
|
+
/**
|
|
291
|
+
* Description must be a non-empty string
|
|
292
|
+
*/
|
|
293
|
+
description: z.ZodString;
|
|
294
|
+
/**
|
|
295
|
+
* Input must be an object (can have any properties)
|
|
296
|
+
*/
|
|
297
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
298
|
+
/**
|
|
299
|
+
* Output is optional and can be anything
|
|
300
|
+
*/
|
|
301
|
+
output: z.ZodOptional<z.ZodUnknown>;
|
|
302
|
+
/**
|
|
303
|
+
* Explanation is optional but must be non-empty if provided
|
|
304
|
+
*/
|
|
305
|
+
explanation: z.ZodOptional<z.ZodString>;
|
|
306
|
+
}, "strip", z.ZodTypeAny, {
|
|
307
|
+
description: string;
|
|
308
|
+
input: Record<string, unknown>;
|
|
309
|
+
output?: unknown;
|
|
310
|
+
explanation?: string | undefined;
|
|
311
|
+
}, {
|
|
312
|
+
description: string;
|
|
313
|
+
input: Record<string, unknown>;
|
|
314
|
+
output?: unknown;
|
|
315
|
+
explanation?: string | undefined;
|
|
316
|
+
}>;
|
|
317
|
+
/**
|
|
318
|
+
* Schema for tool names
|
|
319
|
+
*
|
|
320
|
+
* Tool names must be:
|
|
321
|
+
* - Lowercase letters, numbers, and hyphens only
|
|
322
|
+
* - Start with a letter
|
|
323
|
+
* - Not start or end with a hyphen
|
|
324
|
+
* - Between 2 and 50 characters
|
|
325
|
+
*
|
|
326
|
+
* Valid: 'read-file', 'http-request', 'query-db'
|
|
327
|
+
* Invalid: 'ReadFile', 'read_file', '-read-file', 'r'
|
|
328
|
+
*/
|
|
329
|
+
declare const ToolNameSchema: z.ZodString;
|
|
330
|
+
/**
|
|
331
|
+
* Schema for ToolMetadata
|
|
332
|
+
*
|
|
333
|
+
* Validates all tool metadata fields with appropriate constraints.
|
|
334
|
+
*
|
|
335
|
+
* Example:
|
|
336
|
+
* ```ts
|
|
337
|
+
* ToolMetadataSchema.parse({
|
|
338
|
+
* name: 'read-file',
|
|
339
|
+
* description: 'Read a file from the file system',
|
|
340
|
+
* category: ToolCategory.FILE_SYSTEM,
|
|
341
|
+
* tags: ['file', 'read'],
|
|
342
|
+
* examples: [{ description: 'Read README', input: { path: './README.md' } }]
|
|
343
|
+
* });
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
declare const ToolMetadataSchema: z.ZodObject<{
|
|
347
|
+
/**
|
|
348
|
+
* Tool name - must be valid kebab-case
|
|
349
|
+
*/
|
|
350
|
+
name: z.ZodString;
|
|
351
|
+
/**
|
|
352
|
+
* Description - must be meaningful (at least 10 characters)
|
|
353
|
+
*/
|
|
354
|
+
description: z.ZodString;
|
|
355
|
+
/**
|
|
356
|
+
* Category - must be a valid ToolCategory
|
|
357
|
+
*/
|
|
358
|
+
category: z.ZodNativeEnum<typeof ToolCategory>;
|
|
359
|
+
/**
|
|
360
|
+
* Display name - if provided, must be non-empty
|
|
361
|
+
*/
|
|
362
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
363
|
+
/**
|
|
364
|
+
* Tags - array of non-empty strings
|
|
365
|
+
*/
|
|
366
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
367
|
+
/**
|
|
368
|
+
* Examples - array of valid ToolExample objects
|
|
369
|
+
*/
|
|
370
|
+
examples: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
371
|
+
/**
|
|
372
|
+
* Description must be a non-empty string
|
|
373
|
+
*/
|
|
374
|
+
description: z.ZodString;
|
|
375
|
+
/**
|
|
376
|
+
* Input must be an object (can have any properties)
|
|
377
|
+
*/
|
|
378
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
379
|
+
/**
|
|
380
|
+
* Output is optional and can be anything
|
|
381
|
+
*/
|
|
382
|
+
output: z.ZodOptional<z.ZodUnknown>;
|
|
383
|
+
/**
|
|
384
|
+
* Explanation is optional but must be non-empty if provided
|
|
385
|
+
*/
|
|
386
|
+
explanation: z.ZodOptional<z.ZodString>;
|
|
387
|
+
}, "strip", z.ZodTypeAny, {
|
|
388
|
+
description: string;
|
|
389
|
+
input: Record<string, unknown>;
|
|
390
|
+
output?: unknown;
|
|
391
|
+
explanation?: string | undefined;
|
|
392
|
+
}, {
|
|
393
|
+
description: string;
|
|
394
|
+
input: Record<string, unknown>;
|
|
395
|
+
output?: unknown;
|
|
396
|
+
explanation?: string | undefined;
|
|
397
|
+
}>, "many">>;
|
|
398
|
+
/**
|
|
399
|
+
* Usage notes - if provided, must be meaningful
|
|
400
|
+
*/
|
|
401
|
+
usageNotes: z.ZodOptional<z.ZodString>;
|
|
402
|
+
/**
|
|
403
|
+
* Limitations - array of non-empty strings
|
|
404
|
+
*/
|
|
405
|
+
limitations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
406
|
+
/**
|
|
407
|
+
* Version - if provided, should follow semver format
|
|
408
|
+
* Examples: '1.0.0', '2.1.3', '0.1.0-beta', '1.0.0-alpha.1'
|
|
409
|
+
*/
|
|
410
|
+
version: z.ZodOptional<z.ZodString>;
|
|
411
|
+
/**
|
|
412
|
+
* Author - if provided, must be non-empty
|
|
413
|
+
*/
|
|
414
|
+
author: z.ZodOptional<z.ZodString>;
|
|
415
|
+
/**
|
|
416
|
+
* Deprecated flag
|
|
417
|
+
*/
|
|
418
|
+
deprecated: z.ZodOptional<z.ZodBoolean>;
|
|
419
|
+
/**
|
|
420
|
+
* Replacement tool name - if provided, must be valid tool name
|
|
421
|
+
*/
|
|
422
|
+
replacedBy: z.ZodOptional<z.ZodString>;
|
|
423
|
+
}, "strip", z.ZodTypeAny, {
|
|
424
|
+
description: string;
|
|
425
|
+
name: string;
|
|
426
|
+
category: ToolCategory;
|
|
427
|
+
displayName?: string | undefined;
|
|
428
|
+
tags?: string[] | undefined;
|
|
429
|
+
examples?: {
|
|
430
|
+
description: string;
|
|
431
|
+
input: Record<string, unknown>;
|
|
432
|
+
output?: unknown;
|
|
433
|
+
explanation?: string | undefined;
|
|
434
|
+
}[] | undefined;
|
|
435
|
+
usageNotes?: string | undefined;
|
|
436
|
+
limitations?: string[] | undefined;
|
|
437
|
+
version?: string | undefined;
|
|
438
|
+
author?: string | undefined;
|
|
439
|
+
deprecated?: boolean | undefined;
|
|
440
|
+
replacedBy?: string | undefined;
|
|
441
|
+
}, {
|
|
442
|
+
description: string;
|
|
443
|
+
name: string;
|
|
444
|
+
category: ToolCategory;
|
|
445
|
+
displayName?: string | undefined;
|
|
446
|
+
tags?: string[] | undefined;
|
|
447
|
+
examples?: {
|
|
448
|
+
description: string;
|
|
449
|
+
input: Record<string, unknown>;
|
|
450
|
+
output?: unknown;
|
|
451
|
+
explanation?: string | undefined;
|
|
452
|
+
}[] | undefined;
|
|
453
|
+
usageNotes?: string | undefined;
|
|
454
|
+
limitations?: string[] | undefined;
|
|
455
|
+
version?: string | undefined;
|
|
456
|
+
author?: string | undefined;
|
|
457
|
+
deprecated?: boolean | undefined;
|
|
458
|
+
replacedBy?: string | undefined;
|
|
459
|
+
}>;
|
|
460
|
+
/**
|
|
461
|
+
* Helper function to validate tool metadata
|
|
462
|
+
*
|
|
463
|
+
* This is a convenience function that validates metadata and returns
|
|
464
|
+
* a typed result with helpful error messages.
|
|
465
|
+
*
|
|
466
|
+
* Example:
|
|
467
|
+
* ```ts
|
|
468
|
+
* const result = validateToolMetadata({
|
|
469
|
+
* name: 'read-file',
|
|
470
|
+
* description: 'Read a file',
|
|
471
|
+
* category: ToolCategory.FILE_SYSTEM
|
|
472
|
+
* });
|
|
473
|
+
*
|
|
474
|
+
* if (result.success) {
|
|
475
|
+
* console.log('Valid metadata:', result.data);
|
|
476
|
+
* } else {
|
|
477
|
+
* console.error('Validation errors:', result.error.errors);
|
|
478
|
+
* }
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
declare function validateToolMetadata(metadata: unknown): z.SafeParseReturnType<{
|
|
482
|
+
description: string;
|
|
483
|
+
name: string;
|
|
484
|
+
category: ToolCategory;
|
|
485
|
+
displayName?: string | undefined;
|
|
486
|
+
tags?: string[] | undefined;
|
|
487
|
+
examples?: {
|
|
488
|
+
description: string;
|
|
489
|
+
input: Record<string, unknown>;
|
|
490
|
+
output?: unknown;
|
|
491
|
+
explanation?: string | undefined;
|
|
492
|
+
}[] | undefined;
|
|
493
|
+
usageNotes?: string | undefined;
|
|
494
|
+
limitations?: string[] | undefined;
|
|
495
|
+
version?: string | undefined;
|
|
496
|
+
author?: string | undefined;
|
|
497
|
+
deprecated?: boolean | undefined;
|
|
498
|
+
replacedBy?: string | undefined;
|
|
499
|
+
}, {
|
|
500
|
+
description: string;
|
|
501
|
+
name: string;
|
|
502
|
+
category: ToolCategory;
|
|
503
|
+
displayName?: string | undefined;
|
|
504
|
+
tags?: string[] | undefined;
|
|
505
|
+
examples?: {
|
|
506
|
+
description: string;
|
|
507
|
+
input: Record<string, unknown>;
|
|
508
|
+
output?: unknown;
|
|
509
|
+
explanation?: string | undefined;
|
|
510
|
+
}[] | undefined;
|
|
511
|
+
usageNotes?: string | undefined;
|
|
512
|
+
limitations?: string[] | undefined;
|
|
513
|
+
version?: string | undefined;
|
|
514
|
+
author?: string | undefined;
|
|
515
|
+
deprecated?: boolean | undefined;
|
|
516
|
+
replacedBy?: string | undefined;
|
|
517
|
+
}>;
|
|
518
|
+
/**
|
|
519
|
+
* Helper function to validate tool name
|
|
520
|
+
*
|
|
521
|
+
* Quick validation for just the tool name.
|
|
522
|
+
*
|
|
523
|
+
* Example:
|
|
524
|
+
* ```ts
|
|
525
|
+
* validateToolName('read-file'); // ✅ Returns true
|
|
526
|
+
* validateToolName('ReadFile'); // ❌ Returns false
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
declare function validateToolName(name: string): boolean;
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Schema Validation Utilities
|
|
533
|
+
*
|
|
534
|
+
* Helpers to ensure schemas are properly configured for LLM usage,
|
|
535
|
+
* including enforcing descriptions on all fields.
|
|
536
|
+
*/
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Error thrown when a schema field is missing a description
|
|
540
|
+
*/
|
|
541
|
+
declare class MissingDescriptionError extends Error {
|
|
542
|
+
readonly fieldPath: string[];
|
|
543
|
+
readonly fieldType: string;
|
|
544
|
+
constructor(fieldPath: string[], fieldType: string);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Validates that all fields in a Zod schema have descriptions
|
|
548
|
+
*
|
|
549
|
+
* Why enforce descriptions?
|
|
550
|
+
* - LLMs need context to understand what each parameter does
|
|
551
|
+
* - Descriptions are converted to JSON Schema for tool calling
|
|
552
|
+
* - Better descriptions = Better tool selection and usage
|
|
553
|
+
*
|
|
554
|
+
* @param schema - The Zod schema to validate
|
|
555
|
+
* @param fieldPath - Internal: current field path for nested objects
|
|
556
|
+
* @throws {MissingDescriptionError} If any field lacks a description
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* // ❌ This will throw - no descriptions
|
|
561
|
+
* const badSchema = z.object({
|
|
562
|
+
* name: z.string(),
|
|
563
|
+
* age: z.number()
|
|
564
|
+
* });
|
|
565
|
+
* validateSchemaDescriptions(badSchema); // Throws!
|
|
566
|
+
*
|
|
567
|
+
* // ✅ This is valid - all fields have descriptions
|
|
568
|
+
* const goodSchema = z.object({
|
|
569
|
+
* name: z.string().describe('User name'),
|
|
570
|
+
* age: z.number().describe('User age in years')
|
|
571
|
+
* });
|
|
572
|
+
* validateSchemaDescriptions(goodSchema); // OK!
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
575
|
+
declare function validateSchemaDescriptions(schema: z.ZodTypeAny, fieldPath?: string[]): void;
|
|
576
|
+
/**
|
|
577
|
+
* Safe version of validateSchemaDescriptions that returns a result
|
|
578
|
+
* instead of throwing
|
|
579
|
+
*
|
|
580
|
+
* @param schema - The Zod schema to validate
|
|
581
|
+
* @returns Object with success flag and optional error
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```ts
|
|
585
|
+
* const result = safeValidateSchemaDescriptions(schema);
|
|
586
|
+
* if (!result.success) {
|
|
587
|
+
* console.error('Missing descriptions:', result.error.message);
|
|
588
|
+
* }
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
declare function safeValidateSchemaDescriptions(schema: z.ZodTypeAny): {
|
|
592
|
+
success: boolean;
|
|
593
|
+
error?: MissingDescriptionError;
|
|
594
|
+
};
|
|
595
|
+
/**
|
|
596
|
+
* Helper to get all missing descriptions from a schema
|
|
597
|
+
*
|
|
598
|
+
* @param schema - The Zod schema to check
|
|
599
|
+
* @returns Array of field paths that are missing descriptions
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```ts
|
|
603
|
+
* const missing = getMissingDescriptions(schema);
|
|
604
|
+
* if (missing.length > 0) {
|
|
605
|
+
* console.log('Fields missing descriptions:', missing);
|
|
606
|
+
* }
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
declare function getMissingDescriptions(schema: z.ZodTypeAny): string[];
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Tool Creation Helpers
|
|
613
|
+
*
|
|
614
|
+
* Utility functions to create tools with automatic validation.
|
|
615
|
+
*/
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Create a tool with automatic validation
|
|
619
|
+
*
|
|
620
|
+
* This function validates:
|
|
621
|
+
* 1. Metadata is valid (name, description, category, etc.)
|
|
622
|
+
* 2. Schema has descriptions on ALL fields (enforced!)
|
|
623
|
+
*
|
|
624
|
+
* Why enforce descriptions?
|
|
625
|
+
* - LLMs need context to understand parameters
|
|
626
|
+
* - Better descriptions = Better tool usage
|
|
627
|
+
* - Prevents common mistakes
|
|
628
|
+
*
|
|
629
|
+
* @param metadata - Tool metadata
|
|
630
|
+
* @param schema - Zod schema for input validation (must have descriptions!)
|
|
631
|
+
* @param execute - Tool implementation
|
|
632
|
+
* @returns Validated tool
|
|
633
|
+
* @throws {Error} If metadata is invalid or schema is missing descriptions
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```ts
|
|
637
|
+
* // ✅ This works - all fields have descriptions
|
|
638
|
+
* const tool = createTool(
|
|
639
|
+
* {
|
|
640
|
+
* name: 'read-file',
|
|
641
|
+
* description: 'Read a file from the file system',
|
|
642
|
+
* category: ToolCategory.FILE_SYSTEM,
|
|
643
|
+
* },
|
|
644
|
+
* z.object({
|
|
645
|
+
* path: z.string().describe('Path to the file to read'),
|
|
646
|
+
* }),
|
|
647
|
+
* async ({ path }) => {
|
|
648
|
+
* // Implementation
|
|
649
|
+
* }
|
|
650
|
+
* );
|
|
651
|
+
*
|
|
652
|
+
* // ❌ This throws - missing description on 'path'
|
|
653
|
+
* const badTool = createTool(
|
|
654
|
+
* { name: 'bad', description: 'Bad tool', category: ToolCategory.UTILITY },
|
|
655
|
+
* z.object({
|
|
656
|
+
* path: z.string(), // No .describe()!
|
|
657
|
+
* }),
|
|
658
|
+
* async ({ path }) => {}
|
|
659
|
+
* );
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
declare function createTool<TInput = unknown, TOutput = unknown>(metadata: ToolMetadata, schema: z.ZodSchema<TInput>, execute: (input: TInput) => Promise<TOutput>): Tool<TInput, TOutput>;
|
|
663
|
+
/**
|
|
664
|
+
* Create a tool without enforcing schema descriptions
|
|
665
|
+
*
|
|
666
|
+
* ⚠️ WARNING: Only use this if you have a good reason to skip description validation.
|
|
667
|
+
* In most cases, you should use `createTool()` instead.
|
|
668
|
+
*
|
|
669
|
+
* This is useful for:
|
|
670
|
+
* - Migration from existing code
|
|
671
|
+
* - Tools with dynamic schemas
|
|
672
|
+
* - Testing
|
|
673
|
+
*
|
|
674
|
+
* @param metadata - Tool metadata
|
|
675
|
+
* @param schema - Zod schema for input validation
|
|
676
|
+
* @param execute - Tool implementation
|
|
677
|
+
* @returns Tool (without schema validation)
|
|
678
|
+
*/
|
|
679
|
+
declare function createToolUnsafe<TInput = unknown, TOutput = unknown>(metadata: ToolMetadata, schema: z.ZodSchema<TInput>, execute: (input: TInput) => Promise<TOutput>): Tool<TInput, TOutput>;
|
|
680
|
+
/**
|
|
681
|
+
* Validate an existing tool
|
|
682
|
+
*
|
|
683
|
+
* Checks both metadata and schema descriptions.
|
|
684
|
+
*
|
|
685
|
+
* @param tool - The tool to validate
|
|
686
|
+
* @returns Validation result with success flag and errors
|
|
687
|
+
*
|
|
688
|
+
* @example
|
|
689
|
+
* ```ts
|
|
690
|
+
* const result = validateTool(myTool);
|
|
691
|
+
* if (!result.success) {
|
|
692
|
+
* console.error('Tool validation failed:', result.errors);
|
|
693
|
+
* }
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
declare function validateTool(tool: Tool): {
|
|
697
|
+
success: boolean;
|
|
698
|
+
errors: string[];
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Tool Builder API
|
|
703
|
+
*
|
|
704
|
+
* Fluent interface for creating tools with automatic validation.
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```ts
|
|
708
|
+
* const tool = createToolBuilder()
|
|
709
|
+
* .name('read-file')
|
|
710
|
+
* .description('Read a file from the file system')
|
|
711
|
+
* .category(ToolCategory.FILE_SYSTEM)
|
|
712
|
+
* .tags(['file', 'read', 'io'])
|
|
713
|
+
* .schema(z.object({
|
|
714
|
+
* path: z.string().describe('Path to the file')
|
|
715
|
+
* }))
|
|
716
|
+
* .implement(async ({ path }) => {
|
|
717
|
+
* // Implementation
|
|
718
|
+
* })
|
|
719
|
+
* .build();
|
|
720
|
+
* ```
|
|
721
|
+
*/
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Builder for creating tools with a fluent API
|
|
725
|
+
*
|
|
726
|
+
* This provides a more ergonomic way to create tools compared to
|
|
727
|
+
* manually constructing the metadata object.
|
|
728
|
+
*/
|
|
729
|
+
declare class ToolBuilder<TInput = unknown, TOutput = unknown> {
|
|
730
|
+
private metadata;
|
|
731
|
+
private _schema?;
|
|
732
|
+
private _execute?;
|
|
733
|
+
/**
|
|
734
|
+
* Set the tool name (required)
|
|
735
|
+
*
|
|
736
|
+
* @param name - Tool name in kebab-case (e.g., 'read-file')
|
|
737
|
+
*/
|
|
738
|
+
name(name: string): this;
|
|
739
|
+
/**
|
|
740
|
+
* Set the tool description (required)
|
|
741
|
+
*
|
|
742
|
+
* @param description - Clear description of what the tool does
|
|
743
|
+
*/
|
|
744
|
+
description(description: string): this;
|
|
745
|
+
/**
|
|
746
|
+
* Set the tool category (required)
|
|
747
|
+
*
|
|
748
|
+
* @param category - Tool category for organization
|
|
749
|
+
*/
|
|
750
|
+
category(category: ToolCategory): this;
|
|
751
|
+
/**
|
|
752
|
+
* Set the display name (optional)
|
|
753
|
+
*
|
|
754
|
+
* @param displayName - Human-friendly name for UI display
|
|
755
|
+
*/
|
|
756
|
+
displayName(displayName: string): this;
|
|
757
|
+
/**
|
|
758
|
+
* Set tags for searchability (optional)
|
|
759
|
+
*
|
|
760
|
+
* @param tags - Array of tags for categorization and search
|
|
761
|
+
*/
|
|
762
|
+
tags(tags: string[]): this;
|
|
763
|
+
/**
|
|
764
|
+
* Add a single tag (optional)
|
|
765
|
+
*
|
|
766
|
+
* @param tag - Tag to add
|
|
767
|
+
*/
|
|
768
|
+
tag(tag: string): this;
|
|
769
|
+
/**
|
|
770
|
+
* Add an example (optional)
|
|
771
|
+
*
|
|
772
|
+
* @param example - Usage example for the tool
|
|
773
|
+
*/
|
|
774
|
+
example(example: ToolExample): this;
|
|
775
|
+
/**
|
|
776
|
+
* Set usage notes (optional)
|
|
777
|
+
*
|
|
778
|
+
* @param notes - Important usage information
|
|
779
|
+
*/
|
|
780
|
+
usageNotes(notes: string): this;
|
|
781
|
+
/**
|
|
782
|
+
* Set limitations (optional)
|
|
783
|
+
*
|
|
784
|
+
* @param limitations - Array of known limitations
|
|
785
|
+
*/
|
|
786
|
+
limitations(limitations: string[]): this;
|
|
787
|
+
/**
|
|
788
|
+
* Add a single limitation (optional)
|
|
789
|
+
*
|
|
790
|
+
* @param limitation - Limitation to add
|
|
791
|
+
*/
|
|
792
|
+
limitation(limitation: string): this;
|
|
793
|
+
/**
|
|
794
|
+
* Set version (optional)
|
|
795
|
+
*
|
|
796
|
+
* @param version - Semantic version string
|
|
797
|
+
*/
|
|
798
|
+
version(version: string): this;
|
|
799
|
+
/**
|
|
800
|
+
* Set author (optional)
|
|
801
|
+
*
|
|
802
|
+
* @param author - Tool author name
|
|
803
|
+
*/
|
|
804
|
+
author(author: string): this;
|
|
805
|
+
/**
|
|
806
|
+
* Set the input schema (required)
|
|
807
|
+
*
|
|
808
|
+
* All fields MUST have .describe() for LLM understanding!
|
|
809
|
+
*
|
|
810
|
+
* @param schema - Zod schema for input validation
|
|
811
|
+
*/
|
|
812
|
+
schema<T>(schema: z.ZodSchema<T>): ToolBuilder<T, TOutput>;
|
|
813
|
+
/**
|
|
814
|
+
* Set the implementation function (required)
|
|
815
|
+
*
|
|
816
|
+
* @param execute - Async function that implements the tool
|
|
817
|
+
*/
|
|
818
|
+
implement<T>(execute: (input: TInput) => Promise<T>): ToolBuilder<TInput, T>;
|
|
819
|
+
/**
|
|
820
|
+
* Build the tool with validation
|
|
821
|
+
*
|
|
822
|
+
* Validates:
|
|
823
|
+
* - All required fields are present
|
|
824
|
+
* - Metadata is valid
|
|
825
|
+
* - Schema has descriptions on all fields
|
|
826
|
+
*
|
|
827
|
+
* @returns The validated tool
|
|
828
|
+
* @throws {Error} If validation fails
|
|
829
|
+
*/
|
|
830
|
+
build(): Tool<TInput, TOutput>;
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Create a new tool builder
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```ts
|
|
837
|
+
* const tool = toolBuilder()
|
|
838
|
+
* .name('my-tool')
|
|
839
|
+
* .description('Does something useful')
|
|
840
|
+
* .category(ToolCategory.UTILITY)
|
|
841
|
+
* .schema(z.object({ input: z.string().describe('Input') }))
|
|
842
|
+
* .implement(async ({ input }) => input)
|
|
843
|
+
* .build();
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
846
|
+
declare function toolBuilder(): ToolBuilder;
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Tool Registry
|
|
850
|
+
*
|
|
851
|
+
* Central registry for managing and querying tools.
|
|
852
|
+
* Provides CRUD operations, querying, and event notifications.
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```ts
|
|
856
|
+
* const registry = new ToolRegistry();
|
|
857
|
+
*
|
|
858
|
+
* registry.register(readFileTool);
|
|
859
|
+
* registry.register(writeFileTool);
|
|
860
|
+
*
|
|
861
|
+
* const fileTool = registry.get('read-file');
|
|
862
|
+
* const fileTools = registry.getByCategory(ToolCategory.FILE_SYSTEM);
|
|
863
|
+
* ```
|
|
864
|
+
*/
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Registry events
|
|
868
|
+
*/
|
|
869
|
+
declare enum RegistryEvent {
|
|
870
|
+
TOOL_REGISTERED = "tool:registered",
|
|
871
|
+
TOOL_REMOVED = "tool:removed",
|
|
872
|
+
TOOL_UPDATED = "tool:updated",
|
|
873
|
+
REGISTRY_CLEARED = "registry:cleared"
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Event handler type
|
|
877
|
+
*/
|
|
878
|
+
type EventHandler = (data: any) => void;
|
|
879
|
+
/**
|
|
880
|
+
* Options for generating tool prompts
|
|
881
|
+
*/
|
|
882
|
+
interface PromptOptions {
|
|
883
|
+
/** Include usage examples in the prompt */
|
|
884
|
+
includeExamples?: boolean;
|
|
885
|
+
/** Include usage notes in the prompt */
|
|
886
|
+
includeNotes?: boolean;
|
|
887
|
+
/** Include limitations in the prompt */
|
|
888
|
+
includeLimitations?: boolean;
|
|
889
|
+
/** Group tools by category */
|
|
890
|
+
groupByCategory?: boolean;
|
|
891
|
+
/** Filter by specific categories */
|
|
892
|
+
categories?: ToolCategory[];
|
|
893
|
+
/** Maximum number of examples to include per tool */
|
|
894
|
+
maxExamplesPerTool?: number;
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Tool Registry - Central registry for managing tools
|
|
898
|
+
*
|
|
899
|
+
* Features:
|
|
900
|
+
* - CRUD operations (register, get, remove, update)
|
|
901
|
+
* - Query operations (by category, tag, search)
|
|
902
|
+
* - Bulk operations (registerMany, clear)
|
|
903
|
+
* - Event system for observability
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* ```ts
|
|
907
|
+
* const registry = new ToolRegistry();
|
|
908
|
+
*
|
|
909
|
+
* // Register tools
|
|
910
|
+
* registry.register(myTool);
|
|
911
|
+
* registry.registerMany([tool1, tool2, tool3]);
|
|
912
|
+
*
|
|
913
|
+
* // Query tools
|
|
914
|
+
* const tool = registry.get('my-tool');
|
|
915
|
+
* const fileTools = registry.getByCategory(ToolCategory.FILE_SYSTEM);
|
|
916
|
+
* const searchResults = registry.search('file');
|
|
917
|
+
*
|
|
918
|
+
* // Listen to events
|
|
919
|
+
* registry.on(RegistryEvent.TOOL_REGISTERED, (tool) => {
|
|
920
|
+
* console.log('Tool registered:', tool.metadata.name);
|
|
921
|
+
* });
|
|
922
|
+
* ```
|
|
923
|
+
*/
|
|
924
|
+
declare class ToolRegistry {
|
|
925
|
+
private tools;
|
|
926
|
+
private eventHandlers;
|
|
927
|
+
/**
|
|
928
|
+
* Register a tool in the registry
|
|
929
|
+
*
|
|
930
|
+
* @param tool - The tool to register
|
|
931
|
+
* @throws Error if a tool with the same name already exists
|
|
932
|
+
*
|
|
933
|
+
* @example
|
|
934
|
+
* ```ts
|
|
935
|
+
* registry.register(readFileTool);
|
|
936
|
+
* ```
|
|
937
|
+
*/
|
|
938
|
+
register(tool: Tool<any, any>): void;
|
|
939
|
+
/**
|
|
940
|
+
* Get a tool by name
|
|
941
|
+
*
|
|
942
|
+
* @param name - The tool name
|
|
943
|
+
* @returns The tool, or undefined if not found
|
|
944
|
+
*
|
|
945
|
+
* @example
|
|
946
|
+
* ```ts
|
|
947
|
+
* const tool = registry.get('read-file');
|
|
948
|
+
* if (tool) {
|
|
949
|
+
* const result = await tool.execute({ path: './file.txt' });
|
|
950
|
+
* }
|
|
951
|
+
* ```
|
|
952
|
+
*/
|
|
953
|
+
get(name: string): Tool<any, any> | undefined;
|
|
954
|
+
/**
|
|
955
|
+
* Check if a tool exists in the registry
|
|
956
|
+
*
|
|
957
|
+
* @param name - The tool name
|
|
958
|
+
* @returns True if the tool exists
|
|
959
|
+
*
|
|
960
|
+
* @example
|
|
961
|
+
* ```ts
|
|
962
|
+
* if (registry.has('read-file')) {
|
|
963
|
+
* console.log('Tool exists!');
|
|
964
|
+
* }
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
967
|
+
has(name: string): boolean;
|
|
968
|
+
/**
|
|
969
|
+
* Remove a tool from the registry
|
|
970
|
+
*
|
|
971
|
+
* @param name - The tool name
|
|
972
|
+
* @returns True if the tool was removed, false if it didn't exist
|
|
973
|
+
*
|
|
974
|
+
* @example
|
|
975
|
+
* ```ts
|
|
976
|
+
* const removed = registry.remove('read-file');
|
|
977
|
+
* console.log(removed ? 'Removed' : 'Not found');
|
|
978
|
+
* ```
|
|
979
|
+
*/
|
|
980
|
+
remove(name: string): boolean;
|
|
981
|
+
/**
|
|
982
|
+
* Update an existing tool
|
|
983
|
+
*
|
|
984
|
+
* @param name - The tool name
|
|
985
|
+
* @param tool - The new tool definition
|
|
986
|
+
* @returns True if updated, false if the tool didn't exist
|
|
987
|
+
*
|
|
988
|
+
* @example
|
|
989
|
+
* ```ts
|
|
990
|
+
* const updated = registry.update('read-file', newReadFileTool);
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
update(name: string, tool: Tool<any, any>): boolean;
|
|
994
|
+
/**
|
|
995
|
+
* Get all registered tools
|
|
996
|
+
*
|
|
997
|
+
* @returns Array of all tools
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* ```ts
|
|
1001
|
+
* const allTools = registry.getAll();
|
|
1002
|
+
* console.log(`Total tools: ${allTools.length}`);
|
|
1003
|
+
* ```
|
|
1004
|
+
*/
|
|
1005
|
+
getAll(): Tool<any, any>[];
|
|
1006
|
+
/**
|
|
1007
|
+
* Get tools by category
|
|
1008
|
+
*
|
|
1009
|
+
* @param category - The tool category
|
|
1010
|
+
* @returns Array of tools in the category
|
|
1011
|
+
*
|
|
1012
|
+
* @example
|
|
1013
|
+
* ```ts
|
|
1014
|
+
* const fileTools = registry.getByCategory(ToolCategory.FILE_SYSTEM);
|
|
1015
|
+
* ```
|
|
1016
|
+
*/
|
|
1017
|
+
getByCategory(category: ToolCategory): Tool<any, any>[];
|
|
1018
|
+
/**
|
|
1019
|
+
* Get tools by tag
|
|
1020
|
+
*
|
|
1021
|
+
* @param tag - The tag to search for
|
|
1022
|
+
* @returns Array of tools with the tag
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```ts
|
|
1026
|
+
* const fileTools = registry.getByTag('file');
|
|
1027
|
+
* ```
|
|
1028
|
+
*/
|
|
1029
|
+
getByTag(tag: string): Tool<any, any>[];
|
|
1030
|
+
/**
|
|
1031
|
+
* Search tools by name or description
|
|
1032
|
+
*
|
|
1033
|
+
* Case-insensitive search across tool names, display names, and descriptions.
|
|
1034
|
+
*
|
|
1035
|
+
* @param query - The search query
|
|
1036
|
+
* @returns Array of matching tools
|
|
1037
|
+
*
|
|
1038
|
+
* @example
|
|
1039
|
+
* ```ts
|
|
1040
|
+
* const results = registry.search('file');
|
|
1041
|
+
* // Returns tools with 'file' in name or description
|
|
1042
|
+
* ```
|
|
1043
|
+
*/
|
|
1044
|
+
search(query: string): Tool<any, any>[];
|
|
1045
|
+
/**
|
|
1046
|
+
* Register multiple tools at once
|
|
1047
|
+
*
|
|
1048
|
+
* @param tools - Array of tools to register
|
|
1049
|
+
* @throws Error if any tool name conflicts with existing tools
|
|
1050
|
+
*
|
|
1051
|
+
* @example
|
|
1052
|
+
* ```ts
|
|
1053
|
+
* registry.registerMany([tool1, tool2, tool3]);
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
registerMany(tools: Tool<any, any>[]): void;
|
|
1057
|
+
/**
|
|
1058
|
+
* Clear all tools from the registry
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* registry.clear();
|
|
1063
|
+
* console.log(registry.size()); // 0
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
clear(): void;
|
|
1067
|
+
/**
|
|
1068
|
+
* Get the number of registered tools
|
|
1069
|
+
*
|
|
1070
|
+
* @returns Number of tools in the registry
|
|
1071
|
+
*
|
|
1072
|
+
* @example
|
|
1073
|
+
* ```ts
|
|
1074
|
+
* console.log(`Registry has ${registry.size()} tools`);
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
size(): number;
|
|
1078
|
+
/**
|
|
1079
|
+
* Get all tool names
|
|
1080
|
+
*
|
|
1081
|
+
* @returns Array of tool names
|
|
1082
|
+
*
|
|
1083
|
+
* @example
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* const names = registry.getNames();
|
|
1086
|
+
* console.log('Available tools:', names.join(', '));
|
|
1087
|
+
* ```
|
|
1088
|
+
*/
|
|
1089
|
+
getNames(): string[];
|
|
1090
|
+
/**
|
|
1091
|
+
* Register an event handler
|
|
1092
|
+
*
|
|
1093
|
+
* @param event - The event to listen for
|
|
1094
|
+
* @param handler - The handler function
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```ts
|
|
1098
|
+
* registry.on(RegistryEvent.TOOL_REGISTERED, (tool) => {
|
|
1099
|
+
* console.log('New tool:', tool.metadata.name);
|
|
1100
|
+
* });
|
|
1101
|
+
* ```
|
|
1102
|
+
*/
|
|
1103
|
+
on(event: RegistryEvent, handler: EventHandler): void;
|
|
1104
|
+
/**
|
|
1105
|
+
* Unregister an event handler
|
|
1106
|
+
*
|
|
1107
|
+
* @param event - The event to stop listening for
|
|
1108
|
+
* @param handler - The handler function to remove
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```ts
|
|
1112
|
+
* const handler = (tool) => console.log(tool);
|
|
1113
|
+
* registry.on(RegistryEvent.TOOL_REGISTERED, handler);
|
|
1114
|
+
* registry.off(RegistryEvent.TOOL_REGISTERED, handler);
|
|
1115
|
+
* ```
|
|
1116
|
+
*/
|
|
1117
|
+
off(event: RegistryEvent, handler: EventHandler): void;
|
|
1118
|
+
/**
|
|
1119
|
+
* Emit an event to all registered handlers
|
|
1120
|
+
*
|
|
1121
|
+
* @param event - The event to emit
|
|
1122
|
+
* @param data - The event data
|
|
1123
|
+
* @private
|
|
1124
|
+
*/
|
|
1125
|
+
private emit;
|
|
1126
|
+
/**
|
|
1127
|
+
* Convert all registered tools to LangChain format
|
|
1128
|
+
*
|
|
1129
|
+
* This allows the entire registry to be used with LangChain agents.
|
|
1130
|
+
*
|
|
1131
|
+
* @returns Array of LangChain DynamicStructuredTools
|
|
1132
|
+
*
|
|
1133
|
+
* @example
|
|
1134
|
+
* ```ts
|
|
1135
|
+
* const registry = new ToolRegistry();
|
|
1136
|
+
* registry.registerMany([tool1, tool2, tool3]);
|
|
1137
|
+
*
|
|
1138
|
+
* const langchainTools = registry.toLangChainTools();
|
|
1139
|
+
*
|
|
1140
|
+
* const agent = createAgent({
|
|
1141
|
+
* model: new ChatOpenAI(),
|
|
1142
|
+
* tools: langchainTools,
|
|
1143
|
+
* });
|
|
1144
|
+
* ```
|
|
1145
|
+
*/
|
|
1146
|
+
toLangChainTools(): DynamicStructuredTool[];
|
|
1147
|
+
/**
|
|
1148
|
+
* Generate a formatted prompt describing all tools
|
|
1149
|
+
*
|
|
1150
|
+
* Creates a human-readable description of all tools in the registry,
|
|
1151
|
+
* suitable for inclusion in LLM prompts.
|
|
1152
|
+
*
|
|
1153
|
+
* @param options - Options for customizing the prompt
|
|
1154
|
+
* @returns Formatted prompt string
|
|
1155
|
+
*
|
|
1156
|
+
* @example
|
|
1157
|
+
* ```ts
|
|
1158
|
+
* const prompt = registry.generatePrompt({
|
|
1159
|
+
* includeExamples: true,
|
|
1160
|
+
* groupByCategory: true,
|
|
1161
|
+
* maxExamplesPerTool: 2,
|
|
1162
|
+
* });
|
|
1163
|
+
*
|
|
1164
|
+
* console.log(prompt);
|
|
1165
|
+
* // Available Tools:
|
|
1166
|
+
* //
|
|
1167
|
+
* // FILE SYSTEM TOOLS:
|
|
1168
|
+
* // - read-file: Read a file from the file system
|
|
1169
|
+
* // Parameters: path (string)
|
|
1170
|
+
* // Example: Read a text file
|
|
1171
|
+
* // Input: { "path": "./README.md" }
|
|
1172
|
+
* // ...
|
|
1173
|
+
* ```
|
|
1174
|
+
*/
|
|
1175
|
+
generatePrompt(options?: PromptOptions): string;
|
|
1176
|
+
/**
|
|
1177
|
+
* Format a single tool for inclusion in a prompt
|
|
1178
|
+
*
|
|
1179
|
+
* @param tool - The tool to format
|
|
1180
|
+
* @param options - Formatting options
|
|
1181
|
+
* @returns Array of formatted lines
|
|
1182
|
+
* @private
|
|
1183
|
+
*/
|
|
1184
|
+
private formatToolForPrompt;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* Tool Executor - Async tool execution with resource management
|
|
1189
|
+
* @module tools/executor
|
|
1190
|
+
*/
|
|
1191
|
+
type Priority = 'low' | 'normal' | 'high' | 'critical';
|
|
1192
|
+
type BackoffStrategy$1 = 'linear' | 'exponential' | 'fixed';
|
|
1193
|
+
interface RetryPolicy {
|
|
1194
|
+
maxAttempts: number;
|
|
1195
|
+
backoff: BackoffStrategy$1;
|
|
1196
|
+
initialDelay?: number;
|
|
1197
|
+
maxDelay?: number;
|
|
1198
|
+
retryableErrors?: string[];
|
|
1199
|
+
}
|
|
1200
|
+
interface ToolExecutorConfig {
|
|
1201
|
+
maxConcurrent?: number;
|
|
1202
|
+
timeout?: number;
|
|
1203
|
+
retryPolicy?: RetryPolicy;
|
|
1204
|
+
priorityFn?: (tool: any) => Priority;
|
|
1205
|
+
onExecutionStart?: (tool: any, input: any) => void;
|
|
1206
|
+
onExecutionComplete?: (tool: any, input: any, result: any, duration: number) => void;
|
|
1207
|
+
onExecutionError?: (tool: any, input: any, error: Error, duration: number) => void;
|
|
1208
|
+
}
|
|
1209
|
+
interface ToolExecution {
|
|
1210
|
+
tool: any;
|
|
1211
|
+
input: any;
|
|
1212
|
+
priority?: Priority;
|
|
1213
|
+
}
|
|
1214
|
+
interface ExecutionMetrics {
|
|
1215
|
+
totalExecutions: number;
|
|
1216
|
+
successfulExecutions: number;
|
|
1217
|
+
failedExecutions: number;
|
|
1218
|
+
totalDuration: number;
|
|
1219
|
+
averageDuration: number;
|
|
1220
|
+
byPriority: Record<Priority, number>;
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Create a tool executor with resource management
|
|
1224
|
+
*/
|
|
1225
|
+
declare function createToolExecutor(config?: ToolExecutorConfig): {
|
|
1226
|
+
execute: (tool: any, input: any, options?: {
|
|
1227
|
+
priority?: Priority;
|
|
1228
|
+
}) => Promise<any>;
|
|
1229
|
+
executeParallel: (executions: ToolExecution[]) => Promise<any[]>;
|
|
1230
|
+
getMetrics: () => ExecutionMetrics;
|
|
1231
|
+
resetMetrics: () => void;
|
|
1232
|
+
getQueueStatus: () => {
|
|
1233
|
+
queueLength: number;
|
|
1234
|
+
activeExecutions: number;
|
|
1235
|
+
maxConcurrent: number;
|
|
1236
|
+
};
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
/**
|
|
1240
|
+
* Tool Lifecycle Management - Manage tool initialization, cleanup, and resources
|
|
1241
|
+
* @module tools/lifecycle
|
|
1242
|
+
*/
|
|
1243
|
+
interface HealthCheckResult {
|
|
1244
|
+
healthy: boolean;
|
|
1245
|
+
error?: string;
|
|
1246
|
+
metadata?: Record<string, any>;
|
|
1247
|
+
}
|
|
1248
|
+
interface ManagedToolConfig<TContext = any, TInput = any, TOutput = any> {
|
|
1249
|
+
name: string;
|
|
1250
|
+
description: string;
|
|
1251
|
+
initialize?: (this: ManagedTool<TContext, TInput, TOutput>) => Promise<void>;
|
|
1252
|
+
execute: (this: ManagedTool<TContext, TInput, TOutput>, input: TInput) => Promise<TOutput>;
|
|
1253
|
+
cleanup?: (this: ManagedTool<TContext, TInput, TOutput>) => Promise<void>;
|
|
1254
|
+
healthCheck?: (this: ManagedTool<TContext, TInput, TOutput>) => Promise<HealthCheckResult>;
|
|
1255
|
+
context?: TContext;
|
|
1256
|
+
autoCleanup?: boolean;
|
|
1257
|
+
healthCheckInterval?: number;
|
|
1258
|
+
}
|
|
1259
|
+
interface ManagedToolStats {
|
|
1260
|
+
initialized: boolean;
|
|
1261
|
+
totalExecutions: number;
|
|
1262
|
+
successfulExecutions: number;
|
|
1263
|
+
failedExecutions: number;
|
|
1264
|
+
lastExecutionTime?: number;
|
|
1265
|
+
lastHealthCheck?: HealthCheckResult;
|
|
1266
|
+
lastHealthCheckTime?: number;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Managed tool with lifecycle hooks
|
|
1270
|
+
*/
|
|
1271
|
+
declare class ManagedTool<TContext = any, TInput = any, TOutput = any> {
|
|
1272
|
+
readonly name: string;
|
|
1273
|
+
readonly description: string;
|
|
1274
|
+
private readonly initializeFn?;
|
|
1275
|
+
private readonly executeFn;
|
|
1276
|
+
private readonly cleanupFn?;
|
|
1277
|
+
private readonly healthCheckFn?;
|
|
1278
|
+
private readonly autoCleanup;
|
|
1279
|
+
private readonly healthCheckInterval?;
|
|
1280
|
+
private _initialized;
|
|
1281
|
+
private _context;
|
|
1282
|
+
private _stats;
|
|
1283
|
+
private _healthCheckTimer?;
|
|
1284
|
+
constructor(config: ManagedToolConfig<TContext, TInput, TOutput>);
|
|
1285
|
+
/**
|
|
1286
|
+
* Get the tool context (e.g., connection pool, API client)
|
|
1287
|
+
*/
|
|
1288
|
+
get context(): TContext;
|
|
1289
|
+
/**
|
|
1290
|
+
* Set the tool context
|
|
1291
|
+
*/
|
|
1292
|
+
set context(value: TContext);
|
|
1293
|
+
/**
|
|
1294
|
+
* Check if tool is initialized
|
|
1295
|
+
*/
|
|
1296
|
+
get initialized(): boolean;
|
|
1297
|
+
/**
|
|
1298
|
+
* Initialize the tool
|
|
1299
|
+
*/
|
|
1300
|
+
initialize(): Promise<void>;
|
|
1301
|
+
/**
|
|
1302
|
+
* Execute the tool
|
|
1303
|
+
*/
|
|
1304
|
+
execute(input: TInput): Promise<TOutput>;
|
|
1305
|
+
/**
|
|
1306
|
+
* Cleanup the tool
|
|
1307
|
+
*/
|
|
1308
|
+
cleanup(): Promise<void>;
|
|
1309
|
+
/**
|
|
1310
|
+
* Run health check
|
|
1311
|
+
*/
|
|
1312
|
+
healthCheck(): Promise<HealthCheckResult>;
|
|
1313
|
+
/**
|
|
1314
|
+
* Get tool statistics
|
|
1315
|
+
*/
|
|
1316
|
+
getStats(): ManagedToolStats;
|
|
1317
|
+
/**
|
|
1318
|
+
* Reset statistics
|
|
1319
|
+
*/
|
|
1320
|
+
resetStats(): void;
|
|
1321
|
+
/**
|
|
1322
|
+
* Convert to LangChain tool format
|
|
1323
|
+
*/
|
|
1324
|
+
toLangChainTool(): {
|
|
1325
|
+
name: string;
|
|
1326
|
+
description: string;
|
|
1327
|
+
invoke: (input: TInput) => Promise<TOutput>;
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Create a managed tool
|
|
1332
|
+
*/
|
|
1333
|
+
declare function createManagedTool<TContext = any, TInput = any, TOutput = any>(config: ManagedToolConfig<TContext, TInput, TOutput>): ManagedTool<TContext, TInput, TOutput>;
|
|
1334
|
+
|
|
1335
|
+
/**
|
|
1336
|
+
* Tool Composition - Compose tools into higher-level operations
|
|
1337
|
+
* @module tools/composition
|
|
1338
|
+
*/
|
|
1339
|
+
interface ComposedTool {
|
|
1340
|
+
name: string;
|
|
1341
|
+
description: string;
|
|
1342
|
+
invoke: (input: any) => Promise<any>;
|
|
1343
|
+
}
|
|
1344
|
+
interface ConditionalConfig {
|
|
1345
|
+
condition: (input: any) => boolean | Promise<boolean>;
|
|
1346
|
+
onTrue: ComposedTool;
|
|
1347
|
+
onFalse: ComposedTool;
|
|
1348
|
+
}
|
|
1349
|
+
interface ComposeToolConfig {
|
|
1350
|
+
name: string;
|
|
1351
|
+
description?: string;
|
|
1352
|
+
steps: Array<ComposedTool | ComposedTool[] | ConditionalConfig>;
|
|
1353
|
+
transformResult?: (result: any) => any;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Execute tools sequentially
|
|
1357
|
+
*/
|
|
1358
|
+
declare function sequential(tools: ComposedTool[]): ComposedTool;
|
|
1359
|
+
/**
|
|
1360
|
+
* Execute tools in parallel
|
|
1361
|
+
*/
|
|
1362
|
+
declare function parallel(tools: ComposedTool[]): ComposedTool;
|
|
1363
|
+
/**
|
|
1364
|
+
* Execute tool conditionally
|
|
1365
|
+
*/
|
|
1366
|
+
declare function conditional(config: ConditionalConfig): ComposedTool;
|
|
1367
|
+
/**
|
|
1368
|
+
* Compose tools into a complex workflow
|
|
1369
|
+
*/
|
|
1370
|
+
declare function composeTool(config: ComposeToolConfig): ComposedTool;
|
|
1371
|
+
/**
|
|
1372
|
+
* Create a tool that retries on failure
|
|
1373
|
+
*/
|
|
1374
|
+
declare function retry(tool: ComposedTool, options?: {
|
|
1375
|
+
maxAttempts?: number;
|
|
1376
|
+
delay?: number;
|
|
1377
|
+
backoff?: 'linear' | 'exponential';
|
|
1378
|
+
}): ComposedTool;
|
|
1379
|
+
/**
|
|
1380
|
+
* Create a tool that times out
|
|
1381
|
+
*/
|
|
1382
|
+
declare function timeout(tool: ComposedTool, ms: number): ComposedTool;
|
|
1383
|
+
/**
|
|
1384
|
+
* Create a tool that caches results
|
|
1385
|
+
*/
|
|
1386
|
+
declare function cache(tool: ComposedTool, ttl?: number): ComposedTool;
|
|
1387
|
+
|
|
1388
|
+
/**
|
|
1389
|
+
* Tool Mocking & Testing - Mock tools for testing
|
|
1390
|
+
* @module tools/testing
|
|
1391
|
+
*/
|
|
1392
|
+
interface MockToolResponse {
|
|
1393
|
+
input: any;
|
|
1394
|
+
output?: any;
|
|
1395
|
+
error?: Error;
|
|
1396
|
+
}
|
|
1397
|
+
interface MockToolConfig {
|
|
1398
|
+
name: string;
|
|
1399
|
+
description?: string;
|
|
1400
|
+
responses?: MockToolResponse[];
|
|
1401
|
+
defaultResponse?: any;
|
|
1402
|
+
latency?: {
|
|
1403
|
+
min: number;
|
|
1404
|
+
max: number;
|
|
1405
|
+
} | number;
|
|
1406
|
+
errorRate?: number;
|
|
1407
|
+
}
|
|
1408
|
+
interface ToolInvocation {
|
|
1409
|
+
input: any;
|
|
1410
|
+
output?: any;
|
|
1411
|
+
error?: Error;
|
|
1412
|
+
timestamp: number;
|
|
1413
|
+
duration: number;
|
|
1414
|
+
}
|
|
1415
|
+
interface ToolSimulatorConfig {
|
|
1416
|
+
tools: Array<{
|
|
1417
|
+
name: string;
|
|
1418
|
+
invoke: (input: any) => Promise<any>;
|
|
1419
|
+
}>;
|
|
1420
|
+
errorRate?: number;
|
|
1421
|
+
latency?: {
|
|
1422
|
+
mean: number;
|
|
1423
|
+
stddev: number;
|
|
1424
|
+
};
|
|
1425
|
+
recordInvocations?: boolean;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Create a mock tool for testing
|
|
1429
|
+
*/
|
|
1430
|
+
declare function createMockTool(config: MockToolConfig): {
|
|
1431
|
+
name: string;
|
|
1432
|
+
description: string;
|
|
1433
|
+
invoke: (input: any) => Promise<any>;
|
|
1434
|
+
getInvocations: () => ToolInvocation[];
|
|
1435
|
+
clearInvocations: () => void;
|
|
1436
|
+
};
|
|
1437
|
+
/**
|
|
1438
|
+
* Create a tool simulator for testing
|
|
1439
|
+
*/
|
|
1440
|
+
declare function createToolSimulator(config: ToolSimulatorConfig): {
|
|
1441
|
+
execute: (toolName: string, input: any) => Promise<any>;
|
|
1442
|
+
getInvocations: (toolName: string) => ToolInvocation[];
|
|
1443
|
+
getAllInvocations: () => Record<string, ToolInvocation[]>;
|
|
1444
|
+
clearInvocations: (toolName?: string) => void;
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* LangChain Integration - Tool Converter
|
|
1449
|
+
*
|
|
1450
|
+
* Converts AgentForge tools to LangChain StructuredTool format.
|
|
1451
|
+
*
|
|
1452
|
+
* @example
|
|
1453
|
+
* ```ts
|
|
1454
|
+
* import { toLangChainTool } from '@agentforge/core';
|
|
1455
|
+
*
|
|
1456
|
+
* const langchainTool = toLangChainTool(agentforgeTool);
|
|
1457
|
+
* ```
|
|
1458
|
+
*/
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* Convert an AgentForge tool to a LangChain DynamicStructuredTool
|
|
1462
|
+
*
|
|
1463
|
+
* This allows AgentForge tools to be used with LangChain agents and chains.
|
|
1464
|
+
*
|
|
1465
|
+
* @param tool - The AgentForge tool to convert
|
|
1466
|
+
* @returns A LangChain DynamicStructuredTool
|
|
1467
|
+
*
|
|
1468
|
+
* @example
|
|
1469
|
+
* ```ts
|
|
1470
|
+
* const readFileTool = toolBuilder()
|
|
1471
|
+
* .name('read-file')
|
|
1472
|
+
* .description('Read a file from the file system')
|
|
1473
|
+
* .category(ToolCategory.FILE_SYSTEM)
|
|
1474
|
+
* .schema(z.object({
|
|
1475
|
+
* path: z.string().describe('Path to the file'),
|
|
1476
|
+
* }))
|
|
1477
|
+
* .implement(async ({ path }) => {
|
|
1478
|
+
* return fs.readFileSync(path, 'utf-8');
|
|
1479
|
+
* })
|
|
1480
|
+
* .build();
|
|
1481
|
+
*
|
|
1482
|
+
* // Convert to LangChain tool
|
|
1483
|
+
* const langchainTool = toLangChainTool(readFileTool);
|
|
1484
|
+
*
|
|
1485
|
+
* // Use with LangChain agent
|
|
1486
|
+
* const agent = createAgent({
|
|
1487
|
+
* model: new ChatOpenAI(),
|
|
1488
|
+
* tools: [langchainTool],
|
|
1489
|
+
* });
|
|
1490
|
+
* ```
|
|
1491
|
+
*/
|
|
1492
|
+
declare function toLangChainTool(tool: Tool<any, any>): DynamicStructuredTool<any>;
|
|
1493
|
+
/**
|
|
1494
|
+
* Convert multiple AgentForge tools to LangChain tools
|
|
1495
|
+
*
|
|
1496
|
+
* @param tools - Array of AgentForge tools
|
|
1497
|
+
* @returns Array of LangChain DynamicStructuredTools
|
|
1498
|
+
*
|
|
1499
|
+
* @example
|
|
1500
|
+
* ```ts
|
|
1501
|
+
* const tools = [readFileTool, writeFileTool, searchTool];
|
|
1502
|
+
* const langchainTools = toLangChainTools(tools);
|
|
1503
|
+
*
|
|
1504
|
+
* const agent = createAgent({
|
|
1505
|
+
* model: new ChatOpenAI(),
|
|
1506
|
+
* tools: langchainTools,
|
|
1507
|
+
* });
|
|
1508
|
+
* ```
|
|
1509
|
+
*/
|
|
1510
|
+
declare function toLangChainTools(tools: Tool<any, any>[]): DynamicStructuredTool<any>[];
|
|
1511
|
+
/**
|
|
1512
|
+
* Get the JSON Schema representation of a tool's input schema
|
|
1513
|
+
*
|
|
1514
|
+
* This is useful for debugging or for integrations that need the raw JSON Schema.
|
|
1515
|
+
*
|
|
1516
|
+
* @param tool - The AgentForge tool
|
|
1517
|
+
* @returns JSON Schema object
|
|
1518
|
+
*
|
|
1519
|
+
* @example
|
|
1520
|
+
* ```ts
|
|
1521
|
+
* const schema = getToolJsonSchema(readFileTool);
|
|
1522
|
+
* console.log(JSON.stringify(schema, null, 2));
|
|
1523
|
+
* ```
|
|
1524
|
+
*/
|
|
1525
|
+
declare function getToolJsonSchema(tool: Tool<any, any>): Record<string, any>;
|
|
1526
|
+
/**
|
|
1527
|
+
* Get tool metadata in a format suitable for LLM prompts
|
|
1528
|
+
*
|
|
1529
|
+
* This creates a human-readable description of the tool including
|
|
1530
|
+
* its metadata, usage notes, limitations, and examples.
|
|
1531
|
+
*
|
|
1532
|
+
* @param tool - The AgentForge tool
|
|
1533
|
+
* @returns Formatted tool description
|
|
1534
|
+
*
|
|
1535
|
+
* @example
|
|
1536
|
+
* ```ts
|
|
1537
|
+
* const description = getToolDescription(readFileTool);
|
|
1538
|
+
* console.log(description);
|
|
1539
|
+
* // Output:
|
|
1540
|
+
* // read-file: Read a file from the file system
|
|
1541
|
+
* // Category: file-system
|
|
1542
|
+
* // Tags: file, read, io
|
|
1543
|
+
* // ...
|
|
1544
|
+
* ```
|
|
1545
|
+
*/
|
|
1546
|
+
declare function getToolDescription(tool: Tool<any, any>): string;
|
|
1547
|
+
|
|
1548
|
+
/**
|
|
1549
|
+
* LangGraph State Utilities
|
|
1550
|
+
*
|
|
1551
|
+
* Type-safe helpers for working with LangGraph state management.
|
|
1552
|
+
* These utilities wrap LangGraph's Annotation API to provide better TypeScript ergonomics.
|
|
1553
|
+
*
|
|
1554
|
+
* @module langgraph/state
|
|
1555
|
+
*/
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* State channel configuration with optional Zod schema validation
|
|
1559
|
+
*/
|
|
1560
|
+
interface StateChannelConfig<T = any, U = T> {
|
|
1561
|
+
/**
|
|
1562
|
+
* Optional Zod schema for runtime validation
|
|
1563
|
+
*/
|
|
1564
|
+
schema?: ZodType<T, ZodTypeDef, any>;
|
|
1565
|
+
/**
|
|
1566
|
+
* Optional reducer function for aggregating updates
|
|
1567
|
+
*/
|
|
1568
|
+
reducer?: (left: T, right: U) => T;
|
|
1569
|
+
/**
|
|
1570
|
+
* Optional default value factory
|
|
1571
|
+
*/
|
|
1572
|
+
default?: () => T;
|
|
1573
|
+
/**
|
|
1574
|
+
* Description of this state channel (for documentation)
|
|
1575
|
+
*/
|
|
1576
|
+
description?: string;
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Create a type-safe state annotation with optional Zod validation
|
|
1580
|
+
*
|
|
1581
|
+
* This is a thin wrapper around LangGraph's Annotation.Root that adds:
|
|
1582
|
+
* - Zod schema validation support
|
|
1583
|
+
* - Better TypeScript inference
|
|
1584
|
+
* - Documentation/description support
|
|
1585
|
+
*
|
|
1586
|
+
* @example
|
|
1587
|
+
* ```typescript
|
|
1588
|
+
* import { createStateAnnotation } from '@agentforge/core';
|
|
1589
|
+
* import { z } from 'zod';
|
|
1590
|
+
*
|
|
1591
|
+
* const AgentState = createStateAnnotation({
|
|
1592
|
+
* messages: {
|
|
1593
|
+
* schema: z.array(z.string()),
|
|
1594
|
+
* reducer: (left, right) => [...left, ...right],
|
|
1595
|
+
* default: () => [],
|
|
1596
|
+
* description: 'Chat messages'
|
|
1597
|
+
* },
|
|
1598
|
+
* context: {
|
|
1599
|
+
* schema: z.record(z.any()),
|
|
1600
|
+
* default: () => ({}),
|
|
1601
|
+
* description: 'Agent context'
|
|
1602
|
+
* }
|
|
1603
|
+
* });
|
|
1604
|
+
*
|
|
1605
|
+
* type State = typeof AgentState.State;
|
|
1606
|
+
* ```
|
|
1607
|
+
*/
|
|
1608
|
+
declare function createStateAnnotation<T extends Record<string, StateChannelConfig>>(config: T): AnnotationRoot<StateDefinition>;
|
|
1609
|
+
/**
|
|
1610
|
+
* Validate state against Zod schemas
|
|
1611
|
+
*
|
|
1612
|
+
* @param state - The state object to validate
|
|
1613
|
+
* @param config - The state channel configuration with schemas
|
|
1614
|
+
* @returns Validated state
|
|
1615
|
+
* @throws {z.ZodError} If validation fails
|
|
1616
|
+
*
|
|
1617
|
+
* @example
|
|
1618
|
+
* ```typescript
|
|
1619
|
+
* const config = {
|
|
1620
|
+
* messages: { schema: z.array(z.string()) },
|
|
1621
|
+
* count: { schema: z.number() }
|
|
1622
|
+
* };
|
|
1623
|
+
*
|
|
1624
|
+
* const validatedState = validateState(
|
|
1625
|
+
* { messages: ['hello'], count: 42 },
|
|
1626
|
+
* config
|
|
1627
|
+
* );
|
|
1628
|
+
* ```
|
|
1629
|
+
*/
|
|
1630
|
+
declare function validateState<T extends Record<string, StateChannelConfig>>(state: Record<string, any>, config: T): Record<string, any>;
|
|
1631
|
+
/**
|
|
1632
|
+
* Merge state updates using configured reducers
|
|
1633
|
+
*
|
|
1634
|
+
* @param currentState - Current state
|
|
1635
|
+
* @param update - State update
|
|
1636
|
+
* @param config - State channel configuration
|
|
1637
|
+
* @returns Merged state
|
|
1638
|
+
*
|
|
1639
|
+
* @example
|
|
1640
|
+
* ```typescript
|
|
1641
|
+
* const config = {
|
|
1642
|
+
* messages: {
|
|
1643
|
+
* reducer: (left, right) => [...left, ...right]
|
|
1644
|
+
* }
|
|
1645
|
+
* };
|
|
1646
|
+
*
|
|
1647
|
+
* const merged = mergeState(
|
|
1648
|
+
* { messages: ['a', 'b'] },
|
|
1649
|
+
* { messages: ['c'] },
|
|
1650
|
+
* config
|
|
1651
|
+
* );
|
|
1652
|
+
* // Result: { messages: ['a', 'b', 'c'] }
|
|
1653
|
+
* ```
|
|
1654
|
+
*/
|
|
1655
|
+
declare function mergeState<T extends Record<string, StateChannelConfig>>(currentState: Record<string, any>, update: Record<string, any>, config: T): Record<string, any>;
|
|
1656
|
+
|
|
1657
|
+
/**
|
|
1658
|
+
* Sequential Workflow Builder
|
|
1659
|
+
*
|
|
1660
|
+
* Provides utilities for building linear workflows where nodes execute in sequence.
|
|
1661
|
+
* This is a thin wrapper around LangGraph's StateGraph that simplifies the common
|
|
1662
|
+
* pattern of chaining nodes together.
|
|
1663
|
+
*
|
|
1664
|
+
* @module langgraph/builders/sequential
|
|
1665
|
+
*/
|
|
1666
|
+
|
|
1667
|
+
/**
|
|
1668
|
+
* Configuration for a node in a sequential workflow
|
|
1669
|
+
*/
|
|
1670
|
+
interface SequentialNode<State> {
|
|
1671
|
+
/**
|
|
1672
|
+
* Unique name for the node
|
|
1673
|
+
*/
|
|
1674
|
+
name: string;
|
|
1675
|
+
/**
|
|
1676
|
+
* The node function that processes the state
|
|
1677
|
+
*/
|
|
1678
|
+
node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>;
|
|
1679
|
+
/**
|
|
1680
|
+
* Optional description of what this node does
|
|
1681
|
+
*/
|
|
1682
|
+
description?: string;
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Options for creating a sequential workflow
|
|
1686
|
+
*/
|
|
1687
|
+
interface SequentialWorkflowOptions {
|
|
1688
|
+
/**
|
|
1689
|
+
* Whether to automatically add START and END nodes
|
|
1690
|
+
* @default true
|
|
1691
|
+
*/
|
|
1692
|
+
autoStartEnd?: boolean;
|
|
1693
|
+
/**
|
|
1694
|
+
* Custom name for the workflow (for debugging)
|
|
1695
|
+
*/
|
|
1696
|
+
name?: string;
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Creates a sequential workflow where nodes execute in order.
|
|
1700
|
+
*
|
|
1701
|
+
* This is a convenience function that creates a StateGraph and chains
|
|
1702
|
+
* the provided nodes together with edges.
|
|
1703
|
+
*
|
|
1704
|
+
* @example
|
|
1705
|
+
* ```typescript
|
|
1706
|
+
* const workflow = createSequentialWorkflow(AgentState, [
|
|
1707
|
+
* { name: 'fetch', node: fetchNode },
|
|
1708
|
+
* { name: 'process', node: processNode },
|
|
1709
|
+
* { name: 'save', node: saveNode },
|
|
1710
|
+
* ]);
|
|
1711
|
+
*
|
|
1712
|
+
* const app = workflow.compile();
|
|
1713
|
+
* const result = await app.invoke({ input: 'data' });
|
|
1714
|
+
* ```
|
|
1715
|
+
*
|
|
1716
|
+
* @param stateSchema - The state annotation for the graph
|
|
1717
|
+
* @param nodes - Array of nodes to execute in sequence
|
|
1718
|
+
* @param options - Optional configuration
|
|
1719
|
+
* @returns A configured StateGraph ready to compile
|
|
1720
|
+
*/
|
|
1721
|
+
declare function createSequentialWorkflow<State>(stateSchema: any, nodes: SequentialNode<State>[], options?: SequentialWorkflowOptions): StateGraph<State>;
|
|
1722
|
+
/**
|
|
1723
|
+
* Creates a sequential workflow builder with a fluent API.
|
|
1724
|
+
*
|
|
1725
|
+
* This provides a more flexible way to build sequential workflows
|
|
1726
|
+
* by allowing you to add nodes one at a time.
|
|
1727
|
+
*
|
|
1728
|
+
* @example
|
|
1729
|
+
* ```typescript
|
|
1730
|
+
* const workflow = sequentialBuilder(AgentState)
|
|
1731
|
+
* .addNode('fetch', fetchNode)
|
|
1732
|
+
* .addNode('process', processNode)
|
|
1733
|
+
* .addNode('save', saveNode)
|
|
1734
|
+
* .build();
|
|
1735
|
+
*
|
|
1736
|
+
* const app = workflow.compile();
|
|
1737
|
+
* ```
|
|
1738
|
+
*
|
|
1739
|
+
* @param stateSchema - The state annotation for the graph
|
|
1740
|
+
* @returns A fluent builder for sequential workflows
|
|
1741
|
+
*/
|
|
1742
|
+
declare function sequentialBuilder<State>(stateSchema: any): {
|
|
1743
|
+
/**
|
|
1744
|
+
* Add a node to the sequential workflow
|
|
1745
|
+
*/
|
|
1746
|
+
addNode(name: string, node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, description?: string): /*elided*/ any;
|
|
1747
|
+
/**
|
|
1748
|
+
* Set options for the workflow
|
|
1749
|
+
*/
|
|
1750
|
+
options(opts: SequentialWorkflowOptions): /*elided*/ any;
|
|
1751
|
+
/**
|
|
1752
|
+
* Build the StateGraph
|
|
1753
|
+
*/
|
|
1754
|
+
build(): StateGraph<State>;
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1757
|
+
/**
|
|
1758
|
+
* Parallel Execution Builder
|
|
1759
|
+
*
|
|
1760
|
+
* Provides utilities for building workflows where multiple nodes execute in parallel.
|
|
1761
|
+
* This implements the fan-out/fan-in pattern using LangGraph's native parallel execution.
|
|
1762
|
+
*
|
|
1763
|
+
* @module langgraph/builders/parallel
|
|
1764
|
+
*/
|
|
1765
|
+
|
|
1766
|
+
/**
|
|
1767
|
+
* Configuration for a parallel node
|
|
1768
|
+
*/
|
|
1769
|
+
interface ParallelNode<State> {
|
|
1770
|
+
/**
|
|
1771
|
+
* Unique name for the node
|
|
1772
|
+
*/
|
|
1773
|
+
name: string;
|
|
1774
|
+
/**
|
|
1775
|
+
* The node function that processes the state
|
|
1776
|
+
*/
|
|
1777
|
+
node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>;
|
|
1778
|
+
/**
|
|
1779
|
+
* Optional description of what this node does
|
|
1780
|
+
*/
|
|
1781
|
+
description?: string;
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Configuration for an aggregation node that combines parallel results
|
|
1785
|
+
*/
|
|
1786
|
+
interface AggregateNode<State> {
|
|
1787
|
+
/**
|
|
1788
|
+
* Name for the aggregation node
|
|
1789
|
+
*/
|
|
1790
|
+
name: string;
|
|
1791
|
+
/**
|
|
1792
|
+
* The aggregation function that combines results from parallel nodes
|
|
1793
|
+
*/
|
|
1794
|
+
node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>;
|
|
1795
|
+
/**
|
|
1796
|
+
* Optional description
|
|
1797
|
+
*/
|
|
1798
|
+
description?: string;
|
|
1799
|
+
}
|
|
1800
|
+
/**
|
|
1801
|
+
* Options for creating a parallel workflow
|
|
1802
|
+
*/
|
|
1803
|
+
interface ParallelWorkflowOptions {
|
|
1804
|
+
/**
|
|
1805
|
+
* Whether to automatically add START and END nodes
|
|
1806
|
+
* @default true
|
|
1807
|
+
*/
|
|
1808
|
+
autoStartEnd?: boolean;
|
|
1809
|
+
/**
|
|
1810
|
+
* Custom name for the workflow (for debugging)
|
|
1811
|
+
*/
|
|
1812
|
+
name?: string;
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Configuration for a parallel workflow
|
|
1816
|
+
*/
|
|
1817
|
+
interface ParallelWorkflowConfig<State> {
|
|
1818
|
+
/**
|
|
1819
|
+
* Nodes that execute in parallel
|
|
1820
|
+
*/
|
|
1821
|
+
parallel: ParallelNode<State>[];
|
|
1822
|
+
/**
|
|
1823
|
+
* Optional aggregation node that runs after all parallel nodes complete
|
|
1824
|
+
*/
|
|
1825
|
+
aggregate?: AggregateNode<State>;
|
|
1826
|
+
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Creates a parallel workflow where multiple nodes execute concurrently.
|
|
1829
|
+
*
|
|
1830
|
+
* This implements the fan-out/fan-in pattern:
|
|
1831
|
+
* - Fan-out: Multiple nodes execute in parallel
|
|
1832
|
+
* - Fan-in: Optional aggregation node combines results
|
|
1833
|
+
*
|
|
1834
|
+
* @example
|
|
1835
|
+
* ```typescript
|
|
1836
|
+
* const workflow = createParallelWorkflow(AgentState, {
|
|
1837
|
+
* parallel: [
|
|
1838
|
+
* { name: 'fetch_news', node: fetchNewsNode },
|
|
1839
|
+
* { name: 'fetch_weather', node: fetchWeatherNode },
|
|
1840
|
+
* { name: 'fetch_stocks', node: fetchStocksNode },
|
|
1841
|
+
* ],
|
|
1842
|
+
* aggregate: { name: 'combine', node: combineNode },
|
|
1843
|
+
* });
|
|
1844
|
+
*
|
|
1845
|
+
* const app = workflow.compile();
|
|
1846
|
+
* const result = await app.invoke({ input: 'data' });
|
|
1847
|
+
* ```
|
|
1848
|
+
*
|
|
1849
|
+
* @param stateSchema - The state annotation for the graph
|
|
1850
|
+
* @param config - Configuration for parallel nodes and optional aggregation
|
|
1851
|
+
* @param options - Optional configuration
|
|
1852
|
+
* @returns A configured StateGraph ready to compile
|
|
1853
|
+
*/
|
|
1854
|
+
declare function createParallelWorkflow<State>(stateSchema: any, config: ParallelWorkflowConfig<State>, options?: ParallelWorkflowOptions): StateGraph<State>;
|
|
1855
|
+
|
|
1856
|
+
/**
|
|
1857
|
+
* Conditional Routing Utilities
|
|
1858
|
+
*
|
|
1859
|
+
* Provides type-safe utilities for adding conditional edges to LangGraph workflows.
|
|
1860
|
+
* This simplifies the common pattern of routing based on state conditions.
|
|
1861
|
+
*
|
|
1862
|
+
* @module langgraph/builders/conditional
|
|
1863
|
+
*/
|
|
1864
|
+
|
|
1865
|
+
/**
|
|
1866
|
+
* A route name that can be either a node name or END
|
|
1867
|
+
*/
|
|
1868
|
+
type RouteName = string | typeof END;
|
|
1869
|
+
/**
|
|
1870
|
+
* A mapping of route keys to node names
|
|
1871
|
+
*/
|
|
1872
|
+
type RouteMap = Record<string, RouteName>;
|
|
1873
|
+
/**
|
|
1874
|
+
* A condition function that determines which route to take
|
|
1875
|
+
*/
|
|
1876
|
+
type RouteCondition<State> = (state: State) => string;
|
|
1877
|
+
/**
|
|
1878
|
+
* Configuration for a conditional router
|
|
1879
|
+
*/
|
|
1880
|
+
interface ConditionalRouterConfig<State, Routes extends RouteMap> {
|
|
1881
|
+
/**
|
|
1882
|
+
* Map of route keys to node names
|
|
1883
|
+
*/
|
|
1884
|
+
routes: Routes;
|
|
1885
|
+
/**
|
|
1886
|
+
* Condition function that returns a route key
|
|
1887
|
+
*/
|
|
1888
|
+
condition: RouteCondition<State>;
|
|
1889
|
+
/**
|
|
1890
|
+
* Optional description of the routing logic
|
|
1891
|
+
*/
|
|
1892
|
+
description?: string;
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* A conditional router that can be used with StateGraph.addConditionalEdges
|
|
1896
|
+
*/
|
|
1897
|
+
interface ConditionalRouter<State, Routes extends RouteMap> {
|
|
1898
|
+
/**
|
|
1899
|
+
* The route map
|
|
1900
|
+
*/
|
|
1901
|
+
routes: Routes;
|
|
1902
|
+
/**
|
|
1903
|
+
* The condition function
|
|
1904
|
+
*/
|
|
1905
|
+
condition: RouteCondition<State>;
|
|
1906
|
+
/**
|
|
1907
|
+
* Optional description
|
|
1908
|
+
*/
|
|
1909
|
+
description?: string;
|
|
1910
|
+
}
|
|
1911
|
+
/**
|
|
1912
|
+
* Creates a type-safe conditional router for LangGraph workflows.
|
|
1913
|
+
*
|
|
1914
|
+
* This provides a cleaner API for conditional routing with better type safety
|
|
1915
|
+
* and validation.
|
|
1916
|
+
*
|
|
1917
|
+
* @example
|
|
1918
|
+
* ```typescript
|
|
1919
|
+
* const router = createConditionalRouter<AgentState>({
|
|
1920
|
+
* routes: {
|
|
1921
|
+
* 'continue': 'agent',
|
|
1922
|
+
* 'end': END,
|
|
1923
|
+
* 'tools': 'tools',
|
|
1924
|
+
* },
|
|
1925
|
+
* condition: (state) => {
|
|
1926
|
+
* if (state.shouldEnd) return 'end';
|
|
1927
|
+
* if (state.needsTools) return 'tools';
|
|
1928
|
+
* return 'continue';
|
|
1929
|
+
* },
|
|
1930
|
+
* });
|
|
1931
|
+
*
|
|
1932
|
+
* // Use with StateGraph
|
|
1933
|
+
* graph.addConditionalEdges('agent', router.condition, router.routes);
|
|
1934
|
+
* ```
|
|
1935
|
+
*
|
|
1936
|
+
* @param config - Configuration for the conditional router
|
|
1937
|
+
* @returns A conditional router object
|
|
1938
|
+
*/
|
|
1939
|
+
declare function createConditionalRouter<State, Routes extends RouteMap = RouteMap>(config: ConditionalRouterConfig<State, Routes>): ConditionalRouter<State, Routes>;
|
|
1940
|
+
/**
|
|
1941
|
+
* Creates a simple binary router (true/false condition).
|
|
1942
|
+
*
|
|
1943
|
+
* This is a convenience function for the common case of routing based on
|
|
1944
|
+
* a boolean condition.
|
|
1945
|
+
*
|
|
1946
|
+
* @example
|
|
1947
|
+
* ```typescript
|
|
1948
|
+
* const router = createBinaryRouter<AgentState>({
|
|
1949
|
+
* condition: (state) => state.isComplete,
|
|
1950
|
+
* ifTrue: END,
|
|
1951
|
+
* ifFalse: 'continue',
|
|
1952
|
+
* });
|
|
1953
|
+
*
|
|
1954
|
+
* graph.addConditionalEdges('check', router.condition, router.routes);
|
|
1955
|
+
* ```
|
|
1956
|
+
*
|
|
1957
|
+
* @param config - Configuration for the binary router
|
|
1958
|
+
* @returns A conditional router object
|
|
1959
|
+
*/
|
|
1960
|
+
declare function createBinaryRouter<State>(config: {
|
|
1961
|
+
condition: (state: State) => boolean;
|
|
1962
|
+
ifTrue: RouteName;
|
|
1963
|
+
ifFalse: RouteName;
|
|
1964
|
+
description?: string;
|
|
1965
|
+
}): ConditionalRouter<State, {
|
|
1966
|
+
true: RouteName;
|
|
1967
|
+
false: RouteName;
|
|
1968
|
+
}>;
|
|
1969
|
+
/**
|
|
1970
|
+
* Creates a multi-way router based on a discriminator function.
|
|
1971
|
+
*
|
|
1972
|
+
* This is useful when you have multiple possible routes based on a
|
|
1973
|
+
* state property or computed value.
|
|
1974
|
+
*
|
|
1975
|
+
* @example
|
|
1976
|
+
* ```typescript
|
|
1977
|
+
* const router = createMultiRouter<AgentState>({
|
|
1978
|
+
* discriminator: (state) => state.status,
|
|
1979
|
+
* routes: {
|
|
1980
|
+
* 'pending': 'process',
|
|
1981
|
+
* 'complete': END,
|
|
1982
|
+
* 'error': 'error_handler',
|
|
1983
|
+
* },
|
|
1984
|
+
* default: 'unknown',
|
|
1985
|
+
* });
|
|
1986
|
+
*
|
|
1987
|
+
* graph.addConditionalEdges('check', router.condition, router.routes);
|
|
1988
|
+
* ```
|
|
1989
|
+
*
|
|
1990
|
+
* @param config - Configuration for the multi-way router
|
|
1991
|
+
* @returns A conditional router object
|
|
1992
|
+
*/
|
|
1993
|
+
declare function createMultiRouter<State, Routes extends RouteMap = RouteMap>(config: {
|
|
1994
|
+
discriminator: (state: State) => string;
|
|
1995
|
+
routes: Routes;
|
|
1996
|
+
default?: keyof Routes;
|
|
1997
|
+
description?: string;
|
|
1998
|
+
}): ConditionalRouter<State, Routes>;
|
|
1999
|
+
|
|
2000
|
+
/**
|
|
2001
|
+
* Subgraph composition utilities for LangGraph
|
|
2002
|
+
*
|
|
2003
|
+
* Helpers for creating and composing subgraphs.
|
|
2004
|
+
*/
|
|
2005
|
+
|
|
2006
|
+
/**
|
|
2007
|
+
* Configuration function for building a subgraph
|
|
2008
|
+
*/
|
|
2009
|
+
type SubgraphBuilder<State> = (graph: StateGraph<State>) => StateGraph<State>;
|
|
2010
|
+
/**
|
|
2011
|
+
* Creates a reusable subgraph that can be added as a node to other graphs.
|
|
2012
|
+
*
|
|
2013
|
+
* This is a helper function that creates a StateGraph, applies the builder function,
|
|
2014
|
+
* and returns the compiled graph which can be added as a node to another graph.
|
|
2015
|
+
*
|
|
2016
|
+
* @example
|
|
2017
|
+
* ```typescript
|
|
2018
|
+
* // Create a reusable research subgraph
|
|
2019
|
+
* const researchSubgraph = createSubgraph(ResearchState, (graph) => {
|
|
2020
|
+
* graph.addNode('search', searchNode);
|
|
2021
|
+
* graph.addNode('analyze', analyzeNode);
|
|
2022
|
+
* graph.addEdge('__start__', 'search');
|
|
2023
|
+
* graph.addEdge('search', 'analyze');
|
|
2024
|
+
* graph.addEdge('analyze', '__end__');
|
|
2025
|
+
* return graph;
|
|
2026
|
+
* });
|
|
2027
|
+
*
|
|
2028
|
+
* // Use in main graph
|
|
2029
|
+
* const mainGraph = new StateGraph(MainState);
|
|
2030
|
+
* mainGraph.addNode('research', researchSubgraph);
|
|
2031
|
+
* ```
|
|
2032
|
+
*
|
|
2033
|
+
* @param stateSchema - The state annotation for the subgraph
|
|
2034
|
+
* @param builder - Function that configures the subgraph
|
|
2035
|
+
* @returns A compiled graph that can be used as a node
|
|
2036
|
+
*/
|
|
2037
|
+
declare function createSubgraph<State>(stateSchema: any, builder: SubgraphBuilder<State>): ReturnType<StateGraph<State>['compile']>;
|
|
2038
|
+
/**
|
|
2039
|
+
* Options for composing graphs
|
|
2040
|
+
*/
|
|
2041
|
+
interface ComposeGraphsOptions {
|
|
2042
|
+
/**
|
|
2043
|
+
* Name for the subgraph node
|
|
2044
|
+
*/
|
|
2045
|
+
name: string;
|
|
2046
|
+
/**
|
|
2047
|
+
* Optional description for documentation
|
|
2048
|
+
*/
|
|
2049
|
+
description?: string;
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Adds a compiled subgraph as a node to a parent graph.
|
|
2053
|
+
*
|
|
2054
|
+
* This is a convenience function that wraps the common pattern of
|
|
2055
|
+
* adding a compiled graph as a node.
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```typescript
|
|
2059
|
+
* const subgraph = createSubgraph(SubState, (graph) => {
|
|
2060
|
+
* // Configure subgraph
|
|
2061
|
+
* return graph;
|
|
2062
|
+
* });
|
|
2063
|
+
*
|
|
2064
|
+
* const mainGraph = new StateGraph(MainState);
|
|
2065
|
+
* composeGraphs(mainGraph, subgraph, { name: 'sub_workflow' });
|
|
2066
|
+
* ```
|
|
2067
|
+
*
|
|
2068
|
+
* @param parentGraph - The parent graph to add the subgraph to
|
|
2069
|
+
* @param subgraph - The compiled subgraph to add as a node
|
|
2070
|
+
* @param options - Configuration options
|
|
2071
|
+
* @returns The parent graph for chaining
|
|
2072
|
+
*/
|
|
2073
|
+
declare function composeGraphs<ParentState, SubState>(parentGraph: StateGraph<ParentState>, subgraph: ReturnType<StateGraph<SubState>['compile']>, options: ComposeGraphsOptions): StateGraph<ParentState>;
|
|
2074
|
+
|
|
2075
|
+
/**
|
|
2076
|
+
* Retry pattern for LangGraph nodes
|
|
2077
|
+
*
|
|
2078
|
+
* Wraps a node function with retry logic.
|
|
2079
|
+
*/
|
|
2080
|
+
/**
|
|
2081
|
+
* Backoff strategy for retries
|
|
2082
|
+
*/
|
|
2083
|
+
type BackoffStrategy = 'constant' | 'linear' | 'exponential';
|
|
2084
|
+
/**
|
|
2085
|
+
* Options for retry behavior
|
|
2086
|
+
*/
|
|
2087
|
+
interface RetryOptions {
|
|
2088
|
+
/**
|
|
2089
|
+
* Maximum number of retry attempts
|
|
2090
|
+
* @default 3
|
|
2091
|
+
*/
|
|
2092
|
+
maxAttempts?: number;
|
|
2093
|
+
/**
|
|
2094
|
+
* Backoff strategy between retries
|
|
2095
|
+
* @default 'exponential'
|
|
2096
|
+
*/
|
|
2097
|
+
backoff?: BackoffStrategy;
|
|
2098
|
+
/**
|
|
2099
|
+
* Initial delay in milliseconds
|
|
2100
|
+
* @default 1000
|
|
2101
|
+
*/
|
|
2102
|
+
initialDelay?: number;
|
|
2103
|
+
/**
|
|
2104
|
+
* Maximum delay in milliseconds
|
|
2105
|
+
* @default 30000
|
|
2106
|
+
*/
|
|
2107
|
+
maxDelay?: number;
|
|
2108
|
+
/**
|
|
2109
|
+
* Optional callback when a retry occurs
|
|
2110
|
+
*/
|
|
2111
|
+
onRetry?: (error: Error, attempt: number) => void;
|
|
2112
|
+
/**
|
|
2113
|
+
* Optional predicate to determine if error should be retried
|
|
2114
|
+
* @default () => true (retry all errors)
|
|
2115
|
+
*/
|
|
2116
|
+
shouldRetry?: (error: Error) => boolean;
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Wraps a node function with retry logic.
|
|
2120
|
+
*
|
|
2121
|
+
* @example
|
|
2122
|
+
* ```typescript
|
|
2123
|
+
* const robustNode = withRetry(myNode, {
|
|
2124
|
+
* maxAttempts: 3,
|
|
2125
|
+
* backoff: 'exponential',
|
|
2126
|
+
* initialDelay: 1000,
|
|
2127
|
+
* onRetry: (error, attempt) => {
|
|
2128
|
+
* console.log(`Retry attempt ${attempt}: ${error.message}`);
|
|
2129
|
+
* },
|
|
2130
|
+
* });
|
|
2131
|
+
*
|
|
2132
|
+
* graph.addNode('robust', robustNode);
|
|
2133
|
+
* ```
|
|
2134
|
+
*
|
|
2135
|
+
* @param node - The node function to wrap
|
|
2136
|
+
* @param options - Retry configuration options
|
|
2137
|
+
* @returns A wrapped node function with retry logic
|
|
2138
|
+
*/
|
|
2139
|
+
declare function withRetry<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, options?: RetryOptions): (state: State) => Promise<State | Partial<State>>;
|
|
2140
|
+
|
|
2141
|
+
/**
|
|
2142
|
+
* Error handler pattern for LangGraph nodes
|
|
2143
|
+
*
|
|
2144
|
+
* Wraps a node function with error handling logic.
|
|
2145
|
+
*/
|
|
2146
|
+
/**
|
|
2147
|
+
* Options for error handling behavior
|
|
2148
|
+
*/
|
|
2149
|
+
interface ErrorHandlerOptions<State> {
|
|
2150
|
+
/**
|
|
2151
|
+
* Callback function to handle errors
|
|
2152
|
+
* Should return a state update to apply when an error occurs
|
|
2153
|
+
*/
|
|
2154
|
+
onError: (error: Error, state: State) => State | Partial<State> | Promise<State | Partial<State>>;
|
|
2155
|
+
/**
|
|
2156
|
+
* Optional callback for logging errors
|
|
2157
|
+
*/
|
|
2158
|
+
logError?: (error: Error, state: State) => void;
|
|
2159
|
+
/**
|
|
2160
|
+
* Whether to rethrow the error after handling
|
|
2161
|
+
* @default false
|
|
2162
|
+
*/
|
|
2163
|
+
rethrow?: boolean;
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Wraps a node function with error handling logic.
|
|
2167
|
+
*
|
|
2168
|
+
* @example
|
|
2169
|
+
* ```typescript
|
|
2170
|
+
* const safeNode = withErrorHandler(myNode, {
|
|
2171
|
+
* onError: (error, state) => {
|
|
2172
|
+
* return { ...state, error: error.message, failed: true };
|
|
2173
|
+
* },
|
|
2174
|
+
* logError: (error) => {
|
|
2175
|
+
* console.error('Node failed:', error);
|
|
2176
|
+
* },
|
|
2177
|
+
* });
|
|
2178
|
+
*
|
|
2179
|
+
* graph.addNode('safe', safeNode);
|
|
2180
|
+
* ```
|
|
2181
|
+
*
|
|
2182
|
+
* @param node - The node function to wrap
|
|
2183
|
+
* @param options - Error handling configuration options
|
|
2184
|
+
* @returns A wrapped node function with error handling
|
|
2185
|
+
*/
|
|
2186
|
+
declare function withErrorHandler<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, options: ErrorHandlerOptions<State>): (state: State) => Promise<State | Partial<State>>;
|
|
2187
|
+
|
|
2188
|
+
/**
|
|
2189
|
+
* Timeout pattern for LangGraph nodes
|
|
2190
|
+
*
|
|
2191
|
+
* Wraps a node function with timeout logic.
|
|
2192
|
+
*/
|
|
2193
|
+
/**
|
|
2194
|
+
* Options for timeout behavior
|
|
2195
|
+
*/
|
|
2196
|
+
interface TimeoutOptions<State> {
|
|
2197
|
+
/**
|
|
2198
|
+
* Timeout duration in milliseconds
|
|
2199
|
+
*/
|
|
2200
|
+
timeout: number;
|
|
2201
|
+
/**
|
|
2202
|
+
* Callback function to handle timeouts
|
|
2203
|
+
* Should return a state update to apply when a timeout occurs
|
|
2204
|
+
*/
|
|
2205
|
+
onTimeout: (state: State) => State | Partial<State> | Promise<State | Partial<State>>;
|
|
2206
|
+
/**
|
|
2207
|
+
* Optional callback for logging timeouts
|
|
2208
|
+
*/
|
|
2209
|
+
logTimeout?: (state: State) => void;
|
|
2210
|
+
/**
|
|
2211
|
+
* Whether to throw an error on timeout
|
|
2212
|
+
* @default false
|
|
2213
|
+
*/
|
|
2214
|
+
throwOnTimeout?: boolean;
|
|
2215
|
+
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Error thrown when a node times out
|
|
2218
|
+
*/
|
|
2219
|
+
declare class TimeoutError extends Error {
|
|
2220
|
+
constructor(timeout: number);
|
|
2221
|
+
}
|
|
2222
|
+
/**
|
|
2223
|
+
* Wraps a node function with timeout logic.
|
|
2224
|
+
*
|
|
2225
|
+
* @example
|
|
2226
|
+
* ```typescript
|
|
2227
|
+
* const timedNode = withTimeout(myNode, {
|
|
2228
|
+
* timeout: 5000,
|
|
2229
|
+
* onTimeout: (state) => ({
|
|
2230
|
+
* ...state,
|
|
2231
|
+
* timedOut: true,
|
|
2232
|
+
* error: 'Operation timed out',
|
|
2233
|
+
* }),
|
|
2234
|
+
* logTimeout: () => {
|
|
2235
|
+
* console.warn('Node timed out');
|
|
2236
|
+
* },
|
|
2237
|
+
* });
|
|
2238
|
+
*
|
|
2239
|
+
* graph.addNode('timed', timedNode);
|
|
2240
|
+
* ```
|
|
2241
|
+
*
|
|
2242
|
+
* @param node - The node function to wrap
|
|
2243
|
+
* @param options - Timeout configuration options
|
|
2244
|
+
* @returns A wrapped node function with timeout logic
|
|
2245
|
+
*/
|
|
2246
|
+
declare function withTimeout<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, options: TimeoutOptions<State>): (state: State) => Promise<State | Partial<State>>;
|
|
2247
|
+
|
|
2248
|
+
/**
|
|
2249
|
+
* Checkpointer Factory Functions
|
|
2250
|
+
*
|
|
2251
|
+
* Provides factory functions for creating LangGraph checkpointers with sensible defaults.
|
|
2252
|
+
*
|
|
2253
|
+
* @module langgraph/persistence/checkpointer
|
|
2254
|
+
*/
|
|
2255
|
+
|
|
2256
|
+
/**
|
|
2257
|
+
* Serializer protocol for checkpoint data
|
|
2258
|
+
*/
|
|
2259
|
+
interface SerializerProtocol {
|
|
2260
|
+
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Common options for all checkpointers
|
|
2263
|
+
*/
|
|
2264
|
+
interface CheckpointerOptions {
|
|
2265
|
+
/**
|
|
2266
|
+
* Custom serializer for checkpoint data
|
|
2267
|
+
* @default undefined (uses default serializer)
|
|
2268
|
+
*/
|
|
2269
|
+
serializer?: SerializerProtocol;
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Options for SQLite checkpointer
|
|
2273
|
+
*/
|
|
2274
|
+
interface SqliteCheckpointerOptions extends CheckpointerOptions {
|
|
2275
|
+
/**
|
|
2276
|
+
* Path to the SQLite database file
|
|
2277
|
+
* @default ':memory:' (in-memory database)
|
|
2278
|
+
*/
|
|
2279
|
+
path?: string;
|
|
2280
|
+
/**
|
|
2281
|
+
* Whether to automatically run migrations
|
|
2282
|
+
* @default true
|
|
2283
|
+
*/
|
|
2284
|
+
autoMigrate?: boolean;
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Create an in-memory checkpointer for development and testing.
|
|
2288
|
+
*
|
|
2289
|
+
* This checkpointer stores all checkpoints in memory and is lost when the process exits.
|
|
2290
|
+
* Ideal for development, testing, and experimentation.
|
|
2291
|
+
*
|
|
2292
|
+
* @example
|
|
2293
|
+
* ```typescript
|
|
2294
|
+
* import { createMemoryCheckpointer } from '@agentforge/core';
|
|
2295
|
+
*
|
|
2296
|
+
* const checkpointer = createMemoryCheckpointer();
|
|
2297
|
+
*
|
|
2298
|
+
* const app = workflow.compile({ checkpointer });
|
|
2299
|
+
* ```
|
|
2300
|
+
*
|
|
2301
|
+
* @param options - Optional checkpointer configuration
|
|
2302
|
+
* @returns A MemorySaver instance
|
|
2303
|
+
*/
|
|
2304
|
+
declare function createMemoryCheckpointer(options?: CheckpointerOptions): MemorySaver;
|
|
2305
|
+
/**
|
|
2306
|
+
* Create a SQLite-based checkpointer for local persistence.
|
|
2307
|
+
*
|
|
2308
|
+
* This checkpointer stores checkpoints in a SQLite database file, providing
|
|
2309
|
+
* persistence across process restarts. Ideal for local development and
|
|
2310
|
+
* single-machine deployments.
|
|
2311
|
+
*
|
|
2312
|
+
* Note: Requires `@langchain/langgraph-checkpoint-sqlite` to be installed.
|
|
2313
|
+
*
|
|
2314
|
+
* @example
|
|
2315
|
+
* ```typescript
|
|
2316
|
+
* import { createSqliteCheckpointer } from '@agentforge/core';
|
|
2317
|
+
*
|
|
2318
|
+
* // Use a file-based database
|
|
2319
|
+
* const checkpointer = await createSqliteCheckpointer({
|
|
2320
|
+
* path: './checkpoints.db',
|
|
2321
|
+
* autoMigrate: true,
|
|
2322
|
+
* });
|
|
2323
|
+
*
|
|
2324
|
+
* const app = workflow.compile({ checkpointer });
|
|
2325
|
+
* ```
|
|
2326
|
+
*
|
|
2327
|
+
* @param options - SQLite checkpointer configuration
|
|
2328
|
+
* @returns A Promise that resolves to a SqliteSaver instance
|
|
2329
|
+
* @throws Error if @langchain/langgraph-checkpoint-sqlite is not installed
|
|
2330
|
+
*/
|
|
2331
|
+
declare function createSqliteCheckpointer(options?: SqliteCheckpointerOptions): Promise<BaseCheckpointSaver>;
|
|
2332
|
+
/**
|
|
2333
|
+
* Type guard to check if a checkpointer is a MemorySaver
|
|
2334
|
+
*
|
|
2335
|
+
* @param checkpointer - The checkpointer to check
|
|
2336
|
+
* @returns True if the checkpointer is a MemorySaver
|
|
2337
|
+
*/
|
|
2338
|
+
declare function isMemoryCheckpointer(checkpointer: BaseCheckpointSaver): checkpointer is MemorySaver;
|
|
2339
|
+
|
|
2340
|
+
/**
|
|
2341
|
+
* Thread Management Utilities
|
|
2342
|
+
*
|
|
2343
|
+
* Provides utilities for managing conversation threads and configurations.
|
|
2344
|
+
*
|
|
2345
|
+
* @module langgraph/persistence/thread
|
|
2346
|
+
*/
|
|
2347
|
+
|
|
2348
|
+
/**
|
|
2349
|
+
* Configuration for a thread
|
|
2350
|
+
*/
|
|
2351
|
+
interface ThreadConfig {
|
|
2352
|
+
/**
|
|
2353
|
+
* Unique identifier for the thread
|
|
2354
|
+
*/
|
|
2355
|
+
threadId: string;
|
|
2356
|
+
/**
|
|
2357
|
+
* Optional checkpoint ID to resume from
|
|
2358
|
+
*/
|
|
2359
|
+
checkpointId?: string;
|
|
2360
|
+
/**
|
|
2361
|
+
* Optional checkpoint namespace
|
|
2362
|
+
*/
|
|
2363
|
+
checkpointNamespace?: string;
|
|
2364
|
+
/**
|
|
2365
|
+
* Additional metadata for the thread
|
|
2366
|
+
*/
|
|
2367
|
+
metadata?: Record<string, any>;
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Configuration for a conversation
|
|
2371
|
+
*/
|
|
2372
|
+
interface ConversationConfig {
|
|
2373
|
+
/**
|
|
2374
|
+
* User ID for the conversation
|
|
2375
|
+
*/
|
|
2376
|
+
userId: string;
|
|
2377
|
+
/**
|
|
2378
|
+
* Optional session ID
|
|
2379
|
+
*/
|
|
2380
|
+
sessionId?: string;
|
|
2381
|
+
/**
|
|
2382
|
+
* Additional metadata
|
|
2383
|
+
*/
|
|
2384
|
+
metadata?: Record<string, any>;
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Generate a unique thread ID.
|
|
2388
|
+
*
|
|
2389
|
+
* If a seed is provided, generates a deterministic UUID v5 based on the seed.
|
|
2390
|
+
* Otherwise, generates a random UUID v4.
|
|
2391
|
+
*
|
|
2392
|
+
* @example
|
|
2393
|
+
* ```typescript
|
|
2394
|
+
* import { generateThreadId } from '@agentforge/core';
|
|
2395
|
+
*
|
|
2396
|
+
* // Random thread ID
|
|
2397
|
+
* const threadId = generateThreadId();
|
|
2398
|
+
*
|
|
2399
|
+
* // Deterministic thread ID from seed
|
|
2400
|
+
* const threadId2 = generateThreadId('user-123');
|
|
2401
|
+
* ```
|
|
2402
|
+
*
|
|
2403
|
+
* @param seed - Optional seed for deterministic ID generation
|
|
2404
|
+
* @returns A unique thread ID
|
|
2405
|
+
*/
|
|
2406
|
+
declare function generateThreadId(seed?: string): string;
|
|
2407
|
+
/**
|
|
2408
|
+
* Create a thread configuration for LangGraph.
|
|
2409
|
+
*
|
|
2410
|
+
* This creates a RunnableConfig object with the thread configuration
|
|
2411
|
+
* that can be passed to graph.invoke() or graph.stream().
|
|
2412
|
+
*
|
|
2413
|
+
* @example
|
|
2414
|
+
* ```typescript
|
|
2415
|
+
* import { createThreadConfig } from '@agentforge/core';
|
|
2416
|
+
*
|
|
2417
|
+
* const config = createThreadConfig({
|
|
2418
|
+
* threadId: 'conversation-1',
|
|
2419
|
+
* metadata: { userId: 'user-123' },
|
|
2420
|
+
* });
|
|
2421
|
+
*
|
|
2422
|
+
* const result = await app.invoke(input, config);
|
|
2423
|
+
* ```
|
|
2424
|
+
*
|
|
2425
|
+
* @param config - Thread configuration
|
|
2426
|
+
* @returns A RunnableConfig object
|
|
2427
|
+
*/
|
|
2428
|
+
declare function createThreadConfig(config?: Partial<ThreadConfig>): RunnableConfig;
|
|
2429
|
+
/**
|
|
2430
|
+
* Create a conversation configuration for LangGraph.
|
|
2431
|
+
*
|
|
2432
|
+
* This is a convenience function that creates a thread configuration
|
|
2433
|
+
* with user and session information, commonly used for chat applications.
|
|
2434
|
+
*
|
|
2435
|
+
* @example
|
|
2436
|
+
* ```typescript
|
|
2437
|
+
* import { createConversationConfig } from '@agentforge/core';
|
|
2438
|
+
*
|
|
2439
|
+
* const config = createConversationConfig({
|
|
2440
|
+
* userId: 'user-123',
|
|
2441
|
+
* sessionId: 'session-456',
|
|
2442
|
+
* });
|
|
2443
|
+
*
|
|
2444
|
+
* const result = await app.invoke(input, config);
|
|
2445
|
+
* ```
|
|
2446
|
+
*
|
|
2447
|
+
* @param config - Conversation configuration
|
|
2448
|
+
* @returns A RunnableConfig object
|
|
2449
|
+
*/
|
|
2450
|
+
declare function createConversationConfig(config: ConversationConfig): RunnableConfig;
|
|
2451
|
+
|
|
2452
|
+
/**
|
|
2453
|
+
* Checkpointer Utility Functions
|
|
2454
|
+
*
|
|
2455
|
+
* Provides utility functions for working with LangGraph checkpointers.
|
|
2456
|
+
*
|
|
2457
|
+
* @module langgraph/persistence/utils
|
|
2458
|
+
*/
|
|
2459
|
+
|
|
2460
|
+
/**
|
|
2461
|
+
* Options for getting checkpoint history
|
|
2462
|
+
*/
|
|
2463
|
+
interface CheckpointHistoryOptions {
|
|
2464
|
+
/**
|
|
2465
|
+
* Thread ID to get history for
|
|
2466
|
+
*/
|
|
2467
|
+
threadId: string;
|
|
2468
|
+
/**
|
|
2469
|
+
* Maximum number of checkpoints to return
|
|
2470
|
+
* @default 10
|
|
2471
|
+
*/
|
|
2472
|
+
limit?: number;
|
|
2473
|
+
/**
|
|
2474
|
+
* Get checkpoints before this checkpoint ID
|
|
2475
|
+
*/
|
|
2476
|
+
before?: string;
|
|
2477
|
+
}
|
|
2478
|
+
/**
|
|
2479
|
+
* Get the checkpoint history for a thread.
|
|
2480
|
+
*
|
|
2481
|
+
* Returns a list of checkpoints for the specified thread, ordered from
|
|
2482
|
+
* most recent to oldest.
|
|
2483
|
+
*
|
|
2484
|
+
* @example
|
|
2485
|
+
* ```typescript
|
|
2486
|
+
* import { getCheckpointHistory } from '@agentforge/core';
|
|
2487
|
+
*
|
|
2488
|
+
* const history = await getCheckpointHistory(checkpointer, {
|
|
2489
|
+
* threadId: 'conversation-1',
|
|
2490
|
+
* limit: 10,
|
|
2491
|
+
* });
|
|
2492
|
+
*
|
|
2493
|
+
* for (const checkpoint of history) {
|
|
2494
|
+
* console.log(checkpoint.checkpoint.id);
|
|
2495
|
+
* }
|
|
2496
|
+
* ```
|
|
2497
|
+
*
|
|
2498
|
+
* @param checkpointer - The checkpointer to query
|
|
2499
|
+
* @param options - History query options
|
|
2500
|
+
* @returns A promise that resolves to an array of checkpoint tuples
|
|
2501
|
+
*/
|
|
2502
|
+
declare function getCheckpointHistory(checkpointer: BaseCheckpointSaver, options: CheckpointHistoryOptions): Promise<CheckpointTuple[]>;
|
|
2503
|
+
/**
|
|
2504
|
+
* Get the latest checkpoint for a thread.
|
|
2505
|
+
*
|
|
2506
|
+
* Returns the most recent checkpoint for the specified thread, or null
|
|
2507
|
+
* if no checkpoints exist.
|
|
2508
|
+
*
|
|
2509
|
+
* @example
|
|
2510
|
+
* ```typescript
|
|
2511
|
+
* import { getLatestCheckpoint } from '@agentforge/core';
|
|
2512
|
+
*
|
|
2513
|
+
* const latest = await getLatestCheckpoint(checkpointer, {
|
|
2514
|
+
* threadId: 'conversation-1',
|
|
2515
|
+
* });
|
|
2516
|
+
*
|
|
2517
|
+
* if (latest) {
|
|
2518
|
+
* console.log('Latest checkpoint:', latest.checkpoint.id);
|
|
2519
|
+
* }
|
|
2520
|
+
* ```
|
|
2521
|
+
*
|
|
2522
|
+
* @param checkpointer - The checkpointer to query
|
|
2523
|
+
* @param options - Query options
|
|
2524
|
+
* @returns A promise that resolves to the latest checkpoint tuple or null
|
|
2525
|
+
*/
|
|
2526
|
+
declare function getLatestCheckpoint(checkpointer: BaseCheckpointSaver, options: {
|
|
2527
|
+
threadId: string;
|
|
2528
|
+
}): Promise<CheckpointTuple | null>;
|
|
2529
|
+
/**
|
|
2530
|
+
* Clear all checkpoints for a thread.
|
|
2531
|
+
*
|
|
2532
|
+
* Note: This functionality depends on the checkpointer implementation.
|
|
2533
|
+
* Not all checkpointers support deletion.
|
|
2534
|
+
*
|
|
2535
|
+
* @example
|
|
2536
|
+
* ```typescript
|
|
2537
|
+
* import { clearThread } from '@agentforge/core';
|
|
2538
|
+
*
|
|
2539
|
+
* await clearThread(checkpointer, {
|
|
2540
|
+
* threadId: 'conversation-1',
|
|
2541
|
+
* });
|
|
2542
|
+
* ```
|
|
2543
|
+
*
|
|
2544
|
+
* @param checkpointer - The checkpointer to modify
|
|
2545
|
+
* @param options - Clear options
|
|
2546
|
+
* @returns A promise that resolves when the thread is cleared
|
|
2547
|
+
* @throws Error if the checkpointer doesn't support deletion
|
|
2548
|
+
*/
|
|
2549
|
+
declare function clearThread(checkpointer: BaseCheckpointSaver, options: {
|
|
2550
|
+
threadId: string;
|
|
2551
|
+
}): Promise<void>;
|
|
2552
|
+
|
|
2553
|
+
/**
|
|
2554
|
+
* LangSmith Integration Utilities
|
|
2555
|
+
*
|
|
2556
|
+
* Helpers for configuring and using LangSmith tracing with LangGraph.
|
|
2557
|
+
*/
|
|
2558
|
+
/**
|
|
2559
|
+
* LangSmith configuration options
|
|
2560
|
+
*/
|
|
2561
|
+
interface LangSmithConfig {
|
|
2562
|
+
/**
|
|
2563
|
+
* LangSmith API key
|
|
2564
|
+
* Can also be set via LANGSMITH_API_KEY environment variable
|
|
2565
|
+
*/
|
|
2566
|
+
apiKey?: string;
|
|
2567
|
+
/**
|
|
2568
|
+
* Project name for organizing traces
|
|
2569
|
+
* Can also be set via LANGSMITH_PROJECT environment variable
|
|
2570
|
+
*/
|
|
2571
|
+
projectName?: string;
|
|
2572
|
+
/**
|
|
2573
|
+
* Whether tracing is enabled
|
|
2574
|
+
* Can also be set via LANGSMITH_TRACING environment variable
|
|
2575
|
+
* @default true if apiKey is provided
|
|
2576
|
+
*/
|
|
2577
|
+
tracingEnabled?: boolean;
|
|
2578
|
+
/**
|
|
2579
|
+
* LangSmith API endpoint
|
|
2580
|
+
* @default 'https://api.smith.langchain.com'
|
|
2581
|
+
*/
|
|
2582
|
+
endpoint?: string;
|
|
2583
|
+
/**
|
|
2584
|
+
* Additional metadata to include in all traces
|
|
2585
|
+
*/
|
|
2586
|
+
metadata?: Record<string, any>;
|
|
2587
|
+
}
|
|
2588
|
+
/**
|
|
2589
|
+
* Configure LangSmith for tracing.
|
|
2590
|
+
*
|
|
2591
|
+
* This sets environment variables that LangChain/LangGraph use for tracing.
|
|
2592
|
+
*
|
|
2593
|
+
* @example
|
|
2594
|
+
* ```typescript
|
|
2595
|
+
* import { configureLangSmith } from '@agentforge/core';
|
|
2596
|
+
*
|
|
2597
|
+
* configureLangSmith({
|
|
2598
|
+
* apiKey: process.env.LANGSMITH_API_KEY,
|
|
2599
|
+
* projectName: 'my-agent',
|
|
2600
|
+
* tracingEnabled: true,
|
|
2601
|
+
* });
|
|
2602
|
+
* ```
|
|
2603
|
+
*
|
|
2604
|
+
* @param config - LangSmith configuration
|
|
2605
|
+
*/
|
|
2606
|
+
declare function configureLangSmith(config: LangSmithConfig): void;
|
|
2607
|
+
/**
|
|
2608
|
+
* Get the current LangSmith configuration.
|
|
2609
|
+
*
|
|
2610
|
+
* @returns The current configuration or null if not configured
|
|
2611
|
+
*/
|
|
2612
|
+
declare function getLangSmithConfig(): LangSmithConfig | null;
|
|
2613
|
+
/**
|
|
2614
|
+
* Check if LangSmith tracing is enabled.
|
|
2615
|
+
*
|
|
2616
|
+
* @returns True if tracing is enabled
|
|
2617
|
+
*/
|
|
2618
|
+
declare function isTracingEnabled(): boolean;
|
|
2619
|
+
/**
|
|
2620
|
+
* Options for tracing a node
|
|
2621
|
+
*/
|
|
2622
|
+
interface TracingOptions {
|
|
2623
|
+
/**
|
|
2624
|
+
* Name for the traced operation
|
|
2625
|
+
*/
|
|
2626
|
+
name: string;
|
|
2627
|
+
/**
|
|
2628
|
+
* Additional metadata to include in the trace
|
|
2629
|
+
*/
|
|
2630
|
+
metadata?: Record<string, any>;
|
|
2631
|
+
/**
|
|
2632
|
+
* Tags to categorize the trace
|
|
2633
|
+
*/
|
|
2634
|
+
tags?: string[];
|
|
2635
|
+
/**
|
|
2636
|
+
* Run name for the trace
|
|
2637
|
+
*/
|
|
2638
|
+
runName?: string;
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Wrap a node function with LangSmith tracing.
|
|
2642
|
+
*
|
|
2643
|
+
* This adds metadata to the execution context that LangSmith can use for tracing.
|
|
2644
|
+
*
|
|
2645
|
+
* @example
|
|
2646
|
+
* ```typescript
|
|
2647
|
+
* import { withTracing } from '@agentforge/core';
|
|
2648
|
+
*
|
|
2649
|
+
* const tracedNode = withTracing(myNode, {
|
|
2650
|
+
* name: 'research-node',
|
|
2651
|
+
* metadata: { category: 'research' },
|
|
2652
|
+
* tags: ['research', 'web'],
|
|
2653
|
+
* });
|
|
2654
|
+
* ```
|
|
2655
|
+
*
|
|
2656
|
+
* @param node - The node function to wrap
|
|
2657
|
+
* @param options - Tracing options
|
|
2658
|
+
* @returns A wrapped node function with tracing
|
|
2659
|
+
*/
|
|
2660
|
+
declare function withTracing<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, options: TracingOptions): (state: State) => Promise<State | Partial<State>>;
|
|
2661
|
+
|
|
2662
|
+
/**
|
|
2663
|
+
* Structured Logging Utilities
|
|
2664
|
+
*
|
|
2665
|
+
* Provides consistent, structured logging for LangGraph agents.
|
|
2666
|
+
*/
|
|
2667
|
+
/**
|
|
2668
|
+
* Log levels
|
|
2669
|
+
*/
|
|
2670
|
+
declare enum LogLevel {
|
|
2671
|
+
DEBUG = "debug",
|
|
2672
|
+
INFO = "info",
|
|
2673
|
+
WARN = "warn",
|
|
2674
|
+
ERROR = "error"
|
|
2675
|
+
}
|
|
2676
|
+
/**
|
|
2677
|
+
* Logger configuration options
|
|
2678
|
+
*/
|
|
2679
|
+
interface LoggerOptions {
|
|
2680
|
+
/**
|
|
2681
|
+
* Minimum log level to output
|
|
2682
|
+
* @default LogLevel.INFO
|
|
2683
|
+
*/
|
|
2684
|
+
level?: LogLevel;
|
|
2685
|
+
/**
|
|
2686
|
+
* Output format
|
|
2687
|
+
* @default 'pretty'
|
|
2688
|
+
*/
|
|
2689
|
+
format?: 'json' | 'pretty';
|
|
2690
|
+
/**
|
|
2691
|
+
* Output destination
|
|
2692
|
+
* @default process.stdout
|
|
2693
|
+
*/
|
|
2694
|
+
destination?: NodeJS.WritableStream;
|
|
2695
|
+
/**
|
|
2696
|
+
* Whether to include timestamps
|
|
2697
|
+
* @default true
|
|
2698
|
+
*/
|
|
2699
|
+
includeTimestamp?: boolean;
|
|
2700
|
+
/**
|
|
2701
|
+
* Whether to include context in logs
|
|
2702
|
+
* @default true
|
|
2703
|
+
*/
|
|
2704
|
+
includeContext?: boolean;
|
|
2705
|
+
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Log entry structure
|
|
2708
|
+
*/
|
|
2709
|
+
interface LogEntry {
|
|
2710
|
+
level: LogLevel;
|
|
2711
|
+
name: string;
|
|
2712
|
+
message: string;
|
|
2713
|
+
timestamp?: string;
|
|
2714
|
+
context?: Record<string, any>;
|
|
2715
|
+
data?: Record<string, any>;
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Logger interface
|
|
2719
|
+
*/
|
|
2720
|
+
interface Logger {
|
|
2721
|
+
/**
|
|
2722
|
+
* Log a debug message
|
|
2723
|
+
*/
|
|
2724
|
+
debug(message: string, data?: Record<string, any>): void;
|
|
2725
|
+
/**
|
|
2726
|
+
* Log an info message
|
|
2727
|
+
*/
|
|
2728
|
+
info(message: string, data?: Record<string, any>): void;
|
|
2729
|
+
/**
|
|
2730
|
+
* Log a warning message
|
|
2731
|
+
*/
|
|
2732
|
+
warn(message: string, data?: Record<string, any>): void;
|
|
2733
|
+
/**
|
|
2734
|
+
* Log an error message
|
|
2735
|
+
*/
|
|
2736
|
+
error(message: string, data?: Record<string, any>): void;
|
|
2737
|
+
/**
|
|
2738
|
+
* Create a child logger with additional context
|
|
2739
|
+
*/
|
|
2740
|
+
withContext(context: Record<string, any>): Logger;
|
|
2741
|
+
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Create a structured logger.
|
|
2744
|
+
*
|
|
2745
|
+
* @example
|
|
2746
|
+
* ```typescript
|
|
2747
|
+
* import { createLogger, LogLevel } from '@agentforge/core';
|
|
2748
|
+
*
|
|
2749
|
+
* const logger = createLogger('my-agent', {
|
|
2750
|
+
* level: LogLevel.INFO,
|
|
2751
|
+
* format: 'json',
|
|
2752
|
+
* });
|
|
2753
|
+
*
|
|
2754
|
+
* logger.info('Processing request', { userId: 'user-123' });
|
|
2755
|
+
* logger.error('Request failed', { error: err.message });
|
|
2756
|
+
* ```
|
|
2757
|
+
*
|
|
2758
|
+
* @param name - Logger name (typically the agent or component name)
|
|
2759
|
+
* @param options - Logger configuration options
|
|
2760
|
+
* @returns A logger instance
|
|
2761
|
+
*/
|
|
2762
|
+
declare function createLogger(name: string, options?: LoggerOptions): Logger;
|
|
2763
|
+
|
|
2764
|
+
/**
|
|
2765
|
+
* Metrics Collection Utilities
|
|
2766
|
+
*
|
|
2767
|
+
* Provides utilities for collecting performance and usage metrics.
|
|
2768
|
+
*/
|
|
2769
|
+
/**
|
|
2770
|
+
* Metric types
|
|
2771
|
+
*/
|
|
2772
|
+
declare enum MetricType {
|
|
2773
|
+
COUNTER = "counter",
|
|
2774
|
+
GAUGE = "gauge",
|
|
2775
|
+
HISTOGRAM = "histogram"
|
|
2776
|
+
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Metric entry
|
|
2779
|
+
*/
|
|
2780
|
+
interface MetricEntry {
|
|
2781
|
+
type: MetricType;
|
|
2782
|
+
name: string;
|
|
2783
|
+
value: number;
|
|
2784
|
+
timestamp: number;
|
|
2785
|
+
labels?: Record<string, string>;
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Timer interface for measuring durations
|
|
2789
|
+
*/
|
|
2790
|
+
interface Timer {
|
|
2791
|
+
/**
|
|
2792
|
+
* End the timer and record the duration
|
|
2793
|
+
*/
|
|
2794
|
+
end(): number;
|
|
2795
|
+
}
|
|
2796
|
+
/**
|
|
2797
|
+
* Metrics collector interface
|
|
2798
|
+
*/
|
|
2799
|
+
interface Metrics {
|
|
2800
|
+
/**
|
|
2801
|
+
* Increment a counter metric
|
|
2802
|
+
*/
|
|
2803
|
+
increment(name: string, value?: number, labels?: Record<string, string>): void;
|
|
2804
|
+
/**
|
|
2805
|
+
* Decrement a counter metric
|
|
2806
|
+
*/
|
|
2807
|
+
decrement(name: string, value?: number, labels?: Record<string, string>): void;
|
|
2808
|
+
/**
|
|
2809
|
+
* Set a gauge metric
|
|
2810
|
+
*/
|
|
2811
|
+
gauge(name: string, value: number, labels?: Record<string, string>): void;
|
|
2812
|
+
/**
|
|
2813
|
+
* Record a histogram value
|
|
2814
|
+
*/
|
|
2815
|
+
histogram(name: string, value: number, labels?: Record<string, string>): void;
|
|
2816
|
+
/**
|
|
2817
|
+
* Start a timer for measuring duration
|
|
2818
|
+
*/
|
|
2819
|
+
startTimer(name: string, labels?: Record<string, string>): Timer;
|
|
2820
|
+
/**
|
|
2821
|
+
* Get all recorded metrics
|
|
2822
|
+
*/
|
|
2823
|
+
getMetrics(): MetricEntry[];
|
|
2824
|
+
/**
|
|
2825
|
+
* Clear all metrics
|
|
2826
|
+
*/
|
|
2827
|
+
clear(): void;
|
|
2828
|
+
}
|
|
2829
|
+
/**
|
|
2830
|
+
* Create a metrics collector.
|
|
2831
|
+
*
|
|
2832
|
+
* @example
|
|
2833
|
+
* ```typescript
|
|
2834
|
+
* import { createMetrics } from '@agentforge/core';
|
|
2835
|
+
*
|
|
2836
|
+
* const metrics = createMetrics('my-agent');
|
|
2837
|
+
*
|
|
2838
|
+
* // Track counters
|
|
2839
|
+
* metrics.increment('requests.total');
|
|
2840
|
+
* metrics.increment('requests.success');
|
|
2841
|
+
*
|
|
2842
|
+
* // Track gauges
|
|
2843
|
+
* metrics.gauge('active.connections', 5);
|
|
2844
|
+
*
|
|
2845
|
+
* // Track histograms
|
|
2846
|
+
* metrics.histogram('request.duration', 150);
|
|
2847
|
+
*
|
|
2848
|
+
* // Track timers
|
|
2849
|
+
* const timer = metrics.startTimer('operation.duration');
|
|
2850
|
+
* // ... do work ...
|
|
2851
|
+
* timer.end();
|
|
2852
|
+
* ```
|
|
2853
|
+
*
|
|
2854
|
+
* @param name - Metrics namespace (typically the agent or component name)
|
|
2855
|
+
* @returns A metrics collector instance
|
|
2856
|
+
*/
|
|
2857
|
+
declare function createMetrics(name: string): Metrics;
|
|
2858
|
+
/**
|
|
2859
|
+
* Options for metrics tracking on nodes
|
|
2860
|
+
*/
|
|
2861
|
+
interface MetricsNodeOptions {
|
|
2862
|
+
/**
|
|
2863
|
+
* Name for the metrics
|
|
2864
|
+
*/
|
|
2865
|
+
name: string;
|
|
2866
|
+
/**
|
|
2867
|
+
* Whether to track execution duration
|
|
2868
|
+
* @default true
|
|
2869
|
+
*/
|
|
2870
|
+
trackDuration?: boolean;
|
|
2871
|
+
/**
|
|
2872
|
+
* Whether to track errors
|
|
2873
|
+
* @default true
|
|
2874
|
+
*/
|
|
2875
|
+
trackErrors?: boolean;
|
|
2876
|
+
/**
|
|
2877
|
+
* Whether to track invocation count
|
|
2878
|
+
* @default true
|
|
2879
|
+
*/
|
|
2880
|
+
trackInvocations?: boolean;
|
|
2881
|
+
/**
|
|
2882
|
+
* Metrics collector to use
|
|
2883
|
+
* If not provided, a new one will be created
|
|
2884
|
+
*/
|
|
2885
|
+
metrics?: Metrics;
|
|
2886
|
+
}
|
|
2887
|
+
/**
|
|
2888
|
+
* Wrap a node function with automatic metrics tracking.
|
|
2889
|
+
*
|
|
2890
|
+
* @example
|
|
2891
|
+
* ```typescript
|
|
2892
|
+
* import { withMetrics, createMetrics } from '@agentforge/core';
|
|
2893
|
+
*
|
|
2894
|
+
* const metrics = createMetrics('my-agent');
|
|
2895
|
+
*
|
|
2896
|
+
* const metricNode = withMetrics(myNode, {
|
|
2897
|
+
* name: 'research-node',
|
|
2898
|
+
* metrics,
|
|
2899
|
+
* });
|
|
2900
|
+
* ```
|
|
2901
|
+
*
|
|
2902
|
+
* @param node - The node function to wrap
|
|
2903
|
+
* @param options - Metrics tracking options
|
|
2904
|
+
* @returns A wrapped node function with metrics tracking
|
|
2905
|
+
*/
|
|
2906
|
+
declare function withMetrics<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, options: MetricsNodeOptions): (state: State) => Promise<State | Partial<State>>;
|
|
2907
|
+
|
|
2908
|
+
/**
|
|
2909
|
+
* Enhanced Error Handling Utilities
|
|
2910
|
+
*
|
|
2911
|
+
* Provides enhanced error classes and error reporting for better debugging.
|
|
2912
|
+
*/
|
|
2913
|
+
/**
|
|
2914
|
+
* Error context information
|
|
2915
|
+
*/
|
|
2916
|
+
interface ErrorContext {
|
|
2917
|
+
/**
|
|
2918
|
+
* Error code for categorization
|
|
2919
|
+
*/
|
|
2920
|
+
code?: string;
|
|
2921
|
+
/**
|
|
2922
|
+
* Node name where the error occurred
|
|
2923
|
+
*/
|
|
2924
|
+
node?: string;
|
|
2925
|
+
/**
|
|
2926
|
+
* Current state when the error occurred
|
|
2927
|
+
*/
|
|
2928
|
+
state?: any;
|
|
2929
|
+
/**
|
|
2930
|
+
* Additional metadata
|
|
2931
|
+
*/
|
|
2932
|
+
metadata?: Record<string, any>;
|
|
2933
|
+
/**
|
|
2934
|
+
* Original error that caused this error
|
|
2935
|
+
*/
|
|
2936
|
+
cause?: Error;
|
|
2937
|
+
}
|
|
2938
|
+
/**
|
|
2939
|
+
* Enhanced error class for agent errors
|
|
2940
|
+
*/
|
|
2941
|
+
declare class AgentError extends Error {
|
|
2942
|
+
readonly code?: string;
|
|
2943
|
+
readonly node?: string;
|
|
2944
|
+
readonly state?: any;
|
|
2945
|
+
readonly metadata?: Record<string, any>;
|
|
2946
|
+
readonly cause?: Error;
|
|
2947
|
+
readonly timestamp: number;
|
|
2948
|
+
constructor(message: string, context?: ErrorContext);
|
|
2949
|
+
/**
|
|
2950
|
+
* Convert error to JSON for logging/reporting
|
|
2951
|
+
*/
|
|
2952
|
+
toJSON(): Record<string, any>;
|
|
2953
|
+
/**
|
|
2954
|
+
* Get a human-readable string representation
|
|
2955
|
+
*/
|
|
2956
|
+
toString(): string;
|
|
2957
|
+
}
|
|
2958
|
+
/**
|
|
2959
|
+
* Error reporter configuration
|
|
2960
|
+
*/
|
|
2961
|
+
interface ErrorReporterOptions {
|
|
2962
|
+
/**
|
|
2963
|
+
* Callback function to handle errors
|
|
2964
|
+
*/
|
|
2965
|
+
onError: (error: AgentError) => void | Promise<void>;
|
|
2966
|
+
/**
|
|
2967
|
+
* Whether to include stack traces
|
|
2968
|
+
* @default true
|
|
2969
|
+
*/
|
|
2970
|
+
includeStackTrace?: boolean;
|
|
2971
|
+
/**
|
|
2972
|
+
* Whether to include state in error context
|
|
2973
|
+
* @default false (for security/privacy)
|
|
2974
|
+
*/
|
|
2975
|
+
includeState?: boolean;
|
|
2976
|
+
/**
|
|
2977
|
+
* Whether to rethrow errors after reporting
|
|
2978
|
+
* @default true
|
|
2979
|
+
*/
|
|
2980
|
+
rethrow?: boolean;
|
|
2981
|
+
}
|
|
2982
|
+
/**
|
|
2983
|
+
* Error reporter for tracking and reporting errors
|
|
2984
|
+
*/
|
|
2985
|
+
interface ErrorReporter {
|
|
2986
|
+
/**
|
|
2987
|
+
* Wrap a node function with error reporting
|
|
2988
|
+
*/
|
|
2989
|
+
wrap<State>(node: (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>, nodeName?: string): (state: State) => Promise<State | Partial<State>>;
|
|
2990
|
+
/**
|
|
2991
|
+
* Report an error manually
|
|
2992
|
+
*/
|
|
2993
|
+
report(error: Error, context?: ErrorContext): Promise<void>;
|
|
2994
|
+
}
|
|
2995
|
+
/**
|
|
2996
|
+
* Create an error reporter.
|
|
2997
|
+
*
|
|
2998
|
+
* @example
|
|
2999
|
+
* ```typescript
|
|
3000
|
+
* import { createErrorReporter } from '@agentforge/core';
|
|
3001
|
+
*
|
|
3002
|
+
* const reporter = createErrorReporter({
|
|
3003
|
+
* onError: (error) => {
|
|
3004
|
+
* console.error('Agent error:', error.toJSON());
|
|
3005
|
+
* // Send to error tracking service
|
|
3006
|
+
* },
|
|
3007
|
+
* includeStackTrace: true,
|
|
3008
|
+
* includeState: false,
|
|
3009
|
+
* });
|
|
3010
|
+
*
|
|
3011
|
+
* const safeNode = reporter.wrap(myNode, 'my-node');
|
|
3012
|
+
* ```
|
|
3013
|
+
*
|
|
3014
|
+
* @param options - Error reporter configuration
|
|
3015
|
+
* @returns An error reporter instance
|
|
3016
|
+
*/
|
|
3017
|
+
declare function createErrorReporter(options: ErrorReporterOptions): ErrorReporter;
|
|
3018
|
+
|
|
3019
|
+
/**
|
|
3020
|
+
* Middleware System - Type Definitions
|
|
3021
|
+
*
|
|
3022
|
+
* Core types and interfaces for the middleware system.
|
|
3023
|
+
* All middleware follows a consistent, composable pattern.
|
|
3024
|
+
*
|
|
3025
|
+
* @module langgraph/middleware/types
|
|
3026
|
+
*/
|
|
3027
|
+
/**
|
|
3028
|
+
* A LangGraph node function that processes state.
|
|
3029
|
+
*
|
|
3030
|
+
* Node functions can return:
|
|
3031
|
+
* - Full state (State)
|
|
3032
|
+
* - Partial state update (Partial<State>)
|
|
3033
|
+
* - Promise of either
|
|
3034
|
+
*
|
|
3035
|
+
* @template State - The state type for the node
|
|
3036
|
+
*/
|
|
3037
|
+
type NodeFunction<State> = (state: State) => State | Promise<State> | Partial<State> | Promise<Partial<State>>;
|
|
3038
|
+
/**
|
|
3039
|
+
* A middleware function that wraps a node function.
|
|
3040
|
+
*
|
|
3041
|
+
* Middleware takes a node function and options, and returns a new node function
|
|
3042
|
+
* with enhanced behavior (logging, metrics, retry, etc.).
|
|
3043
|
+
*
|
|
3044
|
+
* @template State - The state type for the node
|
|
3045
|
+
* @template Options - Configuration options for the middleware
|
|
3046
|
+
*
|
|
3047
|
+
* @example
|
|
3048
|
+
* ```typescript
|
|
3049
|
+
* const loggingMiddleware: Middleware<MyState, LoggingOptions> = (node, options) => {
|
|
3050
|
+
* return async (state) => {
|
|
3051
|
+
* console.log('Before:', state);
|
|
3052
|
+
* const result = await node(state);
|
|
3053
|
+
* console.log('After:', result);
|
|
3054
|
+
* return result;
|
|
3055
|
+
* };
|
|
3056
|
+
* };
|
|
3057
|
+
* ```
|
|
3058
|
+
*/
|
|
3059
|
+
type Middleware<State, Options = unknown> = (node: NodeFunction<State>, options: Options) => NodeFunction<State>;
|
|
3060
|
+
/**
|
|
3061
|
+
* A middleware factory that creates middleware with bound options.
|
|
3062
|
+
*
|
|
3063
|
+
* This is useful for creating reusable middleware configurations.
|
|
3064
|
+
*
|
|
3065
|
+
* @template State - The state type for the node
|
|
3066
|
+
* @template Options - Configuration options for the middleware
|
|
3067
|
+
*
|
|
3068
|
+
* @example
|
|
3069
|
+
* ```typescript
|
|
3070
|
+
* const createLogger: MiddlewareFactory<MyState, LoggingOptions> = (options) => {
|
|
3071
|
+
* return (node) => {
|
|
3072
|
+
* return async (state) => {
|
|
3073
|
+
* // Logging logic using options
|
|
3074
|
+
* return await node(state);
|
|
3075
|
+
* };
|
|
3076
|
+
* };
|
|
3077
|
+
* };
|
|
3078
|
+
* ```
|
|
3079
|
+
*/
|
|
3080
|
+
type MiddlewareFactory<State, Options = unknown> = (options: Options) => (node: NodeFunction<State>) => NodeFunction<State>;
|
|
3081
|
+
/**
|
|
3082
|
+
* A middleware that doesn't require options.
|
|
3083
|
+
*
|
|
3084
|
+
* @template State - The state type for the node
|
|
3085
|
+
*/
|
|
3086
|
+
type SimpleMiddleware<State> = (node: NodeFunction<State>) => NodeFunction<State>;
|
|
3087
|
+
/**
|
|
3088
|
+
* Configuration for middleware composition.
|
|
3089
|
+
*/
|
|
3090
|
+
interface ComposeOptions {
|
|
3091
|
+
/**
|
|
3092
|
+
* Whether to execute middleware in reverse order.
|
|
3093
|
+
* @default false
|
|
3094
|
+
*/
|
|
3095
|
+
reverse?: boolean;
|
|
3096
|
+
/**
|
|
3097
|
+
* Name for the composed middleware (for debugging).
|
|
3098
|
+
*/
|
|
3099
|
+
name?: string;
|
|
3100
|
+
/**
|
|
3101
|
+
* Whether to catch and handle errors in middleware.
|
|
3102
|
+
* @default true
|
|
3103
|
+
*/
|
|
3104
|
+
catchErrors?: boolean;
|
|
3105
|
+
}
|
|
3106
|
+
/**
|
|
3107
|
+
* Metadata about a middleware function.
|
|
3108
|
+
*/
|
|
3109
|
+
interface MiddlewareMetadata {
|
|
3110
|
+
/**
|
|
3111
|
+
* Name of the middleware
|
|
3112
|
+
*/
|
|
3113
|
+
name: string;
|
|
3114
|
+
/**
|
|
3115
|
+
* Description of what the middleware does
|
|
3116
|
+
*/
|
|
3117
|
+
description?: string;
|
|
3118
|
+
/**
|
|
3119
|
+
* Version of the middleware
|
|
3120
|
+
*/
|
|
3121
|
+
version?: string;
|
|
3122
|
+
/**
|
|
3123
|
+
* Tags for categorizing middleware
|
|
3124
|
+
*/
|
|
3125
|
+
tags?: string[];
|
|
3126
|
+
}
|
|
3127
|
+
/**
|
|
3128
|
+
* A middleware with attached metadata.
|
|
3129
|
+
*/
|
|
3130
|
+
interface MiddlewareWithMetadata<State, Options = unknown> {
|
|
3131
|
+
/**
|
|
3132
|
+
* The middleware function
|
|
3133
|
+
*/
|
|
3134
|
+
middleware: Middleware<State, Options>;
|
|
3135
|
+
/**
|
|
3136
|
+
* Metadata about the middleware
|
|
3137
|
+
*/
|
|
3138
|
+
metadata: MiddlewareMetadata;
|
|
3139
|
+
}
|
|
3140
|
+
/**
|
|
3141
|
+
* Context passed through middleware chain.
|
|
3142
|
+
*
|
|
3143
|
+
* This allows middleware to share information without modifying state.
|
|
3144
|
+
*/
|
|
3145
|
+
interface MiddlewareContext {
|
|
3146
|
+
/**
|
|
3147
|
+
* Unique ID for this execution
|
|
3148
|
+
*/
|
|
3149
|
+
executionId: string;
|
|
3150
|
+
/**
|
|
3151
|
+
* Timestamp when execution started
|
|
3152
|
+
*/
|
|
3153
|
+
startTime: number;
|
|
3154
|
+
/**
|
|
3155
|
+
* Custom data that middleware can read/write
|
|
3156
|
+
*/
|
|
3157
|
+
data: Record<string, unknown>;
|
|
3158
|
+
/**
|
|
3159
|
+
* Stack of middleware names that have been applied
|
|
3160
|
+
*/
|
|
3161
|
+
middlewareStack: string[];
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* Enhanced node function with middleware context.
|
|
3165
|
+
*/
|
|
3166
|
+
type NodeFunctionWithContext<State> = (state: State, context: MiddlewareContext) => State | Promise<State> | Partial<State> | Promise<Partial<State>>;
|
|
3167
|
+
|
|
3168
|
+
/**
|
|
3169
|
+
* Middleware Composition Utilities
|
|
3170
|
+
*
|
|
3171
|
+
* Functions for composing multiple middleware into a single middleware chain.
|
|
3172
|
+
*
|
|
3173
|
+
* @module langgraph/middleware/compose
|
|
3174
|
+
*/
|
|
3175
|
+
|
|
3176
|
+
/**
|
|
3177
|
+
* Compose multiple middleware functions into a single middleware.
|
|
3178
|
+
*
|
|
3179
|
+
* Middleware are applied from left to right (first middleware wraps the node,
|
|
3180
|
+
* second middleware wraps the first, etc.).
|
|
3181
|
+
*
|
|
3182
|
+
* @example
|
|
3183
|
+
* ```typescript
|
|
3184
|
+
* const enhanced = compose(
|
|
3185
|
+
* withLogging({ level: 'info' }),
|
|
3186
|
+
* withMetrics({ name: 'my-node' }),
|
|
3187
|
+
* withRetry({ maxAttempts: 3 })
|
|
3188
|
+
* )(myNode);
|
|
3189
|
+
* ```
|
|
3190
|
+
*
|
|
3191
|
+
* @param middleware - Middleware functions to compose
|
|
3192
|
+
* @returns A function that takes a node and returns the enhanced node
|
|
3193
|
+
*/
|
|
3194
|
+
declare function compose<State>(...middleware: SimpleMiddleware<State>[]): SimpleMiddleware<State>;
|
|
3195
|
+
/**
|
|
3196
|
+
* Compose middleware with options.
|
|
3197
|
+
*
|
|
3198
|
+
* @example
|
|
3199
|
+
* ```typescript
|
|
3200
|
+
* const enhanced = composeWithOptions(
|
|
3201
|
+
* { reverse: true, name: 'my-chain' },
|
|
3202
|
+
* withLogging({ level: 'info' }),
|
|
3203
|
+
* withMetrics({ name: 'my-node' })
|
|
3204
|
+
* )(myNode);
|
|
3205
|
+
* ```
|
|
3206
|
+
*
|
|
3207
|
+
* @param options - Composition options
|
|
3208
|
+
* @param middleware - Middleware functions to compose
|
|
3209
|
+
* @returns A function that takes a node and returns the enhanced node
|
|
3210
|
+
*/
|
|
3211
|
+
declare function composeWithOptions<State>(options: ComposeOptions, ...middleware: SimpleMiddleware<State>[]): SimpleMiddleware<State>;
|
|
3212
|
+
/**
|
|
3213
|
+
* Create a middleware chain builder for fluent API.
|
|
3214
|
+
*
|
|
3215
|
+
* @example
|
|
3216
|
+
* ```typescript
|
|
3217
|
+
* const enhanced = chain<MyState>()
|
|
3218
|
+
* .use(withLogging({ level: 'info' }))
|
|
3219
|
+
* .use(withMetrics({ name: 'my-node' }))
|
|
3220
|
+
* .use(withRetry({ maxAttempts: 3 }))
|
|
3221
|
+
* .build(myNode);
|
|
3222
|
+
* ```
|
|
3223
|
+
*/
|
|
3224
|
+
declare class MiddlewareChain<State> {
|
|
3225
|
+
private middleware;
|
|
3226
|
+
private options;
|
|
3227
|
+
/**
|
|
3228
|
+
* Add middleware to the chain.
|
|
3229
|
+
*/
|
|
3230
|
+
use(middleware: SimpleMiddleware<State>): this;
|
|
3231
|
+
/**
|
|
3232
|
+
* Set composition options.
|
|
3233
|
+
*/
|
|
3234
|
+
withOptions(options: ComposeOptions): this;
|
|
3235
|
+
/**
|
|
3236
|
+
* Build the middleware chain and apply it to a node.
|
|
3237
|
+
*/
|
|
3238
|
+
build(node: NodeFunction<State>): NodeFunction<State>;
|
|
3239
|
+
/**
|
|
3240
|
+
* Get the number of middleware in the chain.
|
|
3241
|
+
*/
|
|
3242
|
+
get length(): number;
|
|
3243
|
+
}
|
|
3244
|
+
/**
|
|
3245
|
+
* Create a new middleware chain builder.
|
|
3246
|
+
*
|
|
3247
|
+
* @example
|
|
3248
|
+
* ```typescript
|
|
3249
|
+
* const enhanced = chain<MyState>()
|
|
3250
|
+
* .use(withLogging({ level: 'info' }))
|
|
3251
|
+
* .build(myNode);
|
|
3252
|
+
* ```
|
|
3253
|
+
*/
|
|
3254
|
+
declare function chain<State>(): MiddlewareChain<State>;
|
|
3255
|
+
/**
|
|
3256
|
+
* Create a middleware context for tracking execution.
|
|
3257
|
+
*/
|
|
3258
|
+
declare function createMiddlewareContext(): MiddlewareContext;
|
|
3259
|
+
|
|
3260
|
+
/**
|
|
3261
|
+
* Middleware Presets
|
|
3262
|
+
*
|
|
3263
|
+
* Pre-configured middleware combinations for common use cases.
|
|
3264
|
+
*
|
|
3265
|
+
* @module langgraph/middleware/presets
|
|
3266
|
+
*/
|
|
3267
|
+
|
|
3268
|
+
/**
|
|
3269
|
+
* Options for the production preset.
|
|
3270
|
+
*/
|
|
3271
|
+
interface ProductionPresetOptions<State> {
|
|
3272
|
+
/**
|
|
3273
|
+
* Name of the node (for logging and metrics)
|
|
3274
|
+
*/
|
|
3275
|
+
nodeName: string;
|
|
3276
|
+
/**
|
|
3277
|
+
* Logger instance
|
|
3278
|
+
*/
|
|
3279
|
+
logger?: Logger;
|
|
3280
|
+
/**
|
|
3281
|
+
* Enable metrics tracking
|
|
3282
|
+
* @default true
|
|
3283
|
+
*/
|
|
3284
|
+
enableMetrics?: boolean;
|
|
3285
|
+
/**
|
|
3286
|
+
* Enable tracing
|
|
3287
|
+
* @default true
|
|
3288
|
+
*/
|
|
3289
|
+
enableTracing?: boolean;
|
|
3290
|
+
/**
|
|
3291
|
+
* Enable retry logic
|
|
3292
|
+
* @default true
|
|
3293
|
+
*/
|
|
3294
|
+
enableRetry?: boolean;
|
|
3295
|
+
/**
|
|
3296
|
+
* Timeout in milliseconds
|
|
3297
|
+
* @default 30000 (30 seconds)
|
|
3298
|
+
*/
|
|
3299
|
+
timeout?: number;
|
|
3300
|
+
/**
|
|
3301
|
+
* Custom retry options
|
|
3302
|
+
*/
|
|
3303
|
+
retryOptions?: Partial<RetryOptions>;
|
|
3304
|
+
/**
|
|
3305
|
+
* Custom error handler options
|
|
3306
|
+
*/
|
|
3307
|
+
errorOptions?: Partial<ErrorHandlerOptions<State>>;
|
|
3308
|
+
}
|
|
3309
|
+
/**
|
|
3310
|
+
* Production preset with comprehensive error handling, metrics, and tracing.
|
|
3311
|
+
*
|
|
3312
|
+
* Includes:
|
|
3313
|
+
* - Error handling with fallback
|
|
3314
|
+
* - Retry logic with exponential backoff
|
|
3315
|
+
* - Timeout protection
|
|
3316
|
+
* - Metrics tracking
|
|
3317
|
+
* - Distributed tracing
|
|
3318
|
+
*
|
|
3319
|
+
* @example
|
|
3320
|
+
* ```typescript
|
|
3321
|
+
* const productionNode = presets.production(myNode, {
|
|
3322
|
+
* nodeName: 'my-node',
|
|
3323
|
+
* logger: createLogger({ level: LogLevel.INFO }),
|
|
3324
|
+
* });
|
|
3325
|
+
* ```
|
|
3326
|
+
*/
|
|
3327
|
+
declare function production<State>(node: NodeFunction<State>, options: ProductionPresetOptions<State>): NodeFunction<State>;
|
|
3328
|
+
/**
|
|
3329
|
+
* Options for the development preset.
|
|
3330
|
+
*/
|
|
3331
|
+
interface DevelopmentPresetOptions {
|
|
3332
|
+
/**
|
|
3333
|
+
* Name of the node
|
|
3334
|
+
*/
|
|
3335
|
+
nodeName: string;
|
|
3336
|
+
/**
|
|
3337
|
+
* Enable verbose logging
|
|
3338
|
+
* @default true
|
|
3339
|
+
*/
|
|
3340
|
+
verbose?: boolean;
|
|
3341
|
+
/**
|
|
3342
|
+
* Logger instance
|
|
3343
|
+
*/
|
|
3344
|
+
logger?: Logger;
|
|
3345
|
+
}
|
|
3346
|
+
/**
|
|
3347
|
+
* Development preset with verbose logging and debugging.
|
|
3348
|
+
*
|
|
3349
|
+
* Includes:
|
|
3350
|
+
* - Verbose logging
|
|
3351
|
+
* - Error details
|
|
3352
|
+
* - No retry (fail fast)
|
|
3353
|
+
* - Extended timeout
|
|
3354
|
+
*
|
|
3355
|
+
* @example
|
|
3356
|
+
* ```typescript
|
|
3357
|
+
* const devNode = presets.development(myNode, {
|
|
3358
|
+
* nodeName: 'my-node',
|
|
3359
|
+
* verbose: true,
|
|
3360
|
+
* });
|
|
3361
|
+
* ```
|
|
3362
|
+
*/
|
|
3363
|
+
declare function development<State>(node: NodeFunction<State>, options: DevelopmentPresetOptions): NodeFunction<State>;
|
|
3364
|
+
/**
|
|
3365
|
+
* Options for the testing preset.
|
|
3366
|
+
*/
|
|
3367
|
+
interface TestingPresetOptions<State> {
|
|
3368
|
+
/**
|
|
3369
|
+
* Name of the node
|
|
3370
|
+
*/
|
|
3371
|
+
nodeName: string;
|
|
3372
|
+
/**
|
|
3373
|
+
* Mock responses for testing
|
|
3374
|
+
*/
|
|
3375
|
+
mockResponse?: Partial<State>;
|
|
3376
|
+
/**
|
|
3377
|
+
* Simulate errors for testing
|
|
3378
|
+
*/
|
|
3379
|
+
simulateError?: Error;
|
|
3380
|
+
/**
|
|
3381
|
+
* Delay in milliseconds for testing async behavior
|
|
3382
|
+
*/
|
|
3383
|
+
delay?: number;
|
|
3384
|
+
/**
|
|
3385
|
+
* Track invocations for assertions
|
|
3386
|
+
*/
|
|
3387
|
+
trackInvocations?: boolean;
|
|
3388
|
+
}
|
|
3389
|
+
/**
|
|
3390
|
+
* Testing preset for unit and integration tests.
|
|
3391
|
+
*
|
|
3392
|
+
* Includes:
|
|
3393
|
+
* - Mock responses
|
|
3394
|
+
* - Error simulation
|
|
3395
|
+
* - Invocation tracking
|
|
3396
|
+
* - Configurable delays
|
|
3397
|
+
*
|
|
3398
|
+
* @example
|
|
3399
|
+
* ```typescript
|
|
3400
|
+
* const testNode = presets.testing(myNode, {
|
|
3401
|
+
* nodeName: 'my-node',
|
|
3402
|
+
* mockResponse: { result: 'mocked' },
|
|
3403
|
+
* trackInvocations: true,
|
|
3404
|
+
* });
|
|
3405
|
+
* ```
|
|
3406
|
+
*/
|
|
3407
|
+
declare function testing<State>(node: NodeFunction<State>, options: TestingPresetOptions<State>): NodeFunction<State> & {
|
|
3408
|
+
invocations: State[];
|
|
3409
|
+
};
|
|
3410
|
+
/**
|
|
3411
|
+
* Preset collection for easy access.
|
|
3412
|
+
*/
|
|
3413
|
+
declare const presets: {
|
|
3414
|
+
production: typeof production;
|
|
3415
|
+
development: typeof development;
|
|
3416
|
+
testing: typeof testing;
|
|
3417
|
+
};
|
|
3418
|
+
|
|
3419
|
+
/**
|
|
3420
|
+
* Streaming utilities for LangGraph applications
|
|
3421
|
+
* @module streaming
|
|
3422
|
+
*/
|
|
3423
|
+
/**
|
|
3424
|
+
* Options for chunk transformer
|
|
3425
|
+
*/
|
|
3426
|
+
interface ChunkOptions {
|
|
3427
|
+
/** Number of items per chunk */
|
|
3428
|
+
size: number;
|
|
3429
|
+
}
|
|
3430
|
+
/**
|
|
3431
|
+
* Options for batch transformer
|
|
3432
|
+
*/
|
|
3433
|
+
interface BatchOptions {
|
|
3434
|
+
/** Maximum number of items per batch */
|
|
3435
|
+
maxSize: number;
|
|
3436
|
+
/** Maximum time to wait before emitting a batch (ms) */
|
|
3437
|
+
maxWait: number;
|
|
3438
|
+
}
|
|
3439
|
+
/**
|
|
3440
|
+
* Options for throttle transformer
|
|
3441
|
+
*/
|
|
3442
|
+
interface ThrottleOptions {
|
|
3443
|
+
/** Maximum number of items to emit */
|
|
3444
|
+
rate: number;
|
|
3445
|
+
/** Time period for rate limit (ms) */
|
|
3446
|
+
per: number;
|
|
3447
|
+
}
|
|
3448
|
+
/**
|
|
3449
|
+
* Reducer function for stream aggregation
|
|
3450
|
+
*/
|
|
3451
|
+
type ReducerFunction<T, R> = (accumulator: R, current: T) => R;
|
|
3452
|
+
/**
|
|
3453
|
+
* Progress information
|
|
3454
|
+
*/
|
|
3455
|
+
interface Progress {
|
|
3456
|
+
/** Current progress value */
|
|
3457
|
+
current: number;
|
|
3458
|
+
/** Total expected value */
|
|
3459
|
+
total: number;
|
|
3460
|
+
/** Percentage complete (0-100) */
|
|
3461
|
+
percentage: number;
|
|
3462
|
+
/** Estimated time to completion (seconds) */
|
|
3463
|
+
eta: number;
|
|
3464
|
+
/** Start time */
|
|
3465
|
+
startTime: number;
|
|
3466
|
+
/** Elapsed time (ms) */
|
|
3467
|
+
elapsed: number;
|
|
3468
|
+
}
|
|
3469
|
+
/**
|
|
3470
|
+
* Progress tracker options
|
|
3471
|
+
*/
|
|
3472
|
+
interface ProgressTrackerOptions {
|
|
3473
|
+
/** Total expected items/steps */
|
|
3474
|
+
total: number;
|
|
3475
|
+
/** Callback for progress updates */
|
|
3476
|
+
onProgress?: (progress: Progress) => void;
|
|
3477
|
+
/** Callback for completion */
|
|
3478
|
+
onComplete?: (progress: Progress) => void;
|
|
3479
|
+
/** Callback for cancellation */
|
|
3480
|
+
onCancel?: () => void;
|
|
3481
|
+
}
|
|
3482
|
+
/**
|
|
3483
|
+
* Progress tracker interface
|
|
3484
|
+
*/
|
|
3485
|
+
interface ProgressTracker {
|
|
3486
|
+
/** Start tracking */
|
|
3487
|
+
start(): void;
|
|
3488
|
+
/** Update progress */
|
|
3489
|
+
update(current: number): void;
|
|
3490
|
+
/** Mark as complete */
|
|
3491
|
+
complete(): void;
|
|
3492
|
+
/** Cancel tracking */
|
|
3493
|
+
cancel(): void;
|
|
3494
|
+
/** Get current progress */
|
|
3495
|
+
getProgress(): Progress;
|
|
3496
|
+
/** Check if cancelled */
|
|
3497
|
+
isCancelled(): boolean;
|
|
3498
|
+
}
|
|
3499
|
+
/**
|
|
3500
|
+
* SSE event
|
|
3501
|
+
*/
|
|
3502
|
+
interface SSEEvent {
|
|
3503
|
+
/** Event type */
|
|
3504
|
+
event?: string;
|
|
3505
|
+
/** Event data */
|
|
3506
|
+
data: string;
|
|
3507
|
+
/** Event ID */
|
|
3508
|
+
id?: string;
|
|
3509
|
+
/** Retry interval (ms) */
|
|
3510
|
+
retry?: number;
|
|
3511
|
+
}
|
|
3512
|
+
/**
|
|
3513
|
+
* SSE formatter options
|
|
3514
|
+
*/
|
|
3515
|
+
interface SSEFormatterOptions<T = any> {
|
|
3516
|
+
/** Event type mappers */
|
|
3517
|
+
eventTypes?: Record<string, (data: T) => SSEEvent>;
|
|
3518
|
+
/** Heartbeat interval (ms) */
|
|
3519
|
+
heartbeat?: number;
|
|
3520
|
+
/** Default retry interval (ms) */
|
|
3521
|
+
retry?: number;
|
|
3522
|
+
}
|
|
3523
|
+
/**
|
|
3524
|
+
* SSE formatter interface
|
|
3525
|
+
*/
|
|
3526
|
+
interface SSEFormatter<T = any> {
|
|
3527
|
+
/** Format stream as SSE events */
|
|
3528
|
+
format(stream: AsyncIterable<T>): AsyncIterable<string>;
|
|
3529
|
+
}
|
|
3530
|
+
/**
|
|
3531
|
+
* WebSocket message
|
|
3532
|
+
*/
|
|
3533
|
+
interface WebSocketMessage {
|
|
3534
|
+
/** Message type */
|
|
3535
|
+
type: string;
|
|
3536
|
+
/** Message data */
|
|
3537
|
+
data?: any;
|
|
3538
|
+
/** Error information */
|
|
3539
|
+
error?: string;
|
|
3540
|
+
}
|
|
3541
|
+
/**
|
|
3542
|
+
* WebSocket handler options
|
|
3543
|
+
*/
|
|
3544
|
+
interface WebSocketHandlerOptions {
|
|
3545
|
+
/** Connection handler */
|
|
3546
|
+
onConnect?: (ws: any, req?: any) => void;
|
|
3547
|
+
/** Message handler */
|
|
3548
|
+
onMessage?: (ws: any, message: any) => Promise<void>;
|
|
3549
|
+
/** Error handler */
|
|
3550
|
+
onError?: (ws: any, error: Error) => void;
|
|
3551
|
+
/** Close handler */
|
|
3552
|
+
onClose?: (ws: any, code?: number, reason?: string) => void;
|
|
3553
|
+
/** Heartbeat interval (ms) */
|
|
3554
|
+
heartbeat?: number;
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
/**
|
|
3558
|
+
* Stream transformers for LangGraph applications
|
|
3559
|
+
* @module streaming/transformers
|
|
3560
|
+
*/
|
|
3561
|
+
|
|
3562
|
+
/**
|
|
3563
|
+
* Transform a stream into chunks of a specified size
|
|
3564
|
+
*
|
|
3565
|
+
* @example
|
|
3566
|
+
* ```typescript
|
|
3567
|
+
* const chunked = chunk(stream, { size: 10 });
|
|
3568
|
+
* for await (const chunk of chunked) {
|
|
3569
|
+
* console.log(chunk); // Array of 10 items (or fewer for last chunk)
|
|
3570
|
+
* }
|
|
3571
|
+
* ```
|
|
3572
|
+
*/
|
|
3573
|
+
declare function chunk<T>(stream: AsyncIterable<T>, options: ChunkOptions): AsyncIterable<T[]>;
|
|
3574
|
+
/**
|
|
3575
|
+
* Batch stream items with size and time constraints
|
|
3576
|
+
*
|
|
3577
|
+
* @example
|
|
3578
|
+
* ```typescript
|
|
3579
|
+
* const batched = batch(stream, { maxSize: 5, maxWait: 100 });
|
|
3580
|
+
* for await (const batch of batched) {
|
|
3581
|
+
* console.log(batch); // Array of up to 5 items or items collected within 100ms
|
|
3582
|
+
* }
|
|
3583
|
+
* ```
|
|
3584
|
+
*/
|
|
3585
|
+
declare function batch<T>(stream: AsyncIterable<T>, options: BatchOptions): AsyncIterable<T[]>;
|
|
3586
|
+
/**
|
|
3587
|
+
* Throttle stream to limit rate of items
|
|
3588
|
+
*
|
|
3589
|
+
* @example
|
|
3590
|
+
* ```typescript
|
|
3591
|
+
* const throttled = throttle(stream, { rate: 10, per: 1000 });
|
|
3592
|
+
* for await (const item of throttled) {
|
|
3593
|
+
* console.log(item); // Max 10 items per second
|
|
3594
|
+
* }
|
|
3595
|
+
* ```
|
|
3596
|
+
*/
|
|
3597
|
+
declare function throttle<T>(stream: AsyncIterable<T>, options: ThrottleOptions): AsyncIterable<T>;
|
|
3598
|
+
|
|
3599
|
+
/**
|
|
3600
|
+
* Stream aggregators for LangGraph applications
|
|
3601
|
+
* @module streaming/aggregators
|
|
3602
|
+
*/
|
|
3603
|
+
|
|
3604
|
+
/**
|
|
3605
|
+
* Collect all items from a stream into an array
|
|
3606
|
+
*
|
|
3607
|
+
* @example
|
|
3608
|
+
* ```typescript
|
|
3609
|
+
* const items = await collect(stream);
|
|
3610
|
+
* console.log(items); // Array of all items
|
|
3611
|
+
* ```
|
|
3612
|
+
*/
|
|
3613
|
+
declare function collect<T>(stream: AsyncIterable<T>): Promise<T[]>;
|
|
3614
|
+
/**
|
|
3615
|
+
* Reduce a stream to a single value
|
|
3616
|
+
*
|
|
3617
|
+
* @example
|
|
3618
|
+
* ```typescript
|
|
3619
|
+
* const sum = await reduce(stream, (acc, val) => acc + val, 0);
|
|
3620
|
+
* console.log(sum); // Sum of all values
|
|
3621
|
+
* ```
|
|
3622
|
+
*/
|
|
3623
|
+
declare function reduce<T, R>(stream: AsyncIterable<T>, reducer: ReducerFunction<T, R>, initialValue: R): Promise<R>;
|
|
3624
|
+
/**
|
|
3625
|
+
* Merge multiple streams into a single stream
|
|
3626
|
+
*
|
|
3627
|
+
* Items are emitted as they arrive from any stream.
|
|
3628
|
+
*
|
|
3629
|
+
* @example
|
|
3630
|
+
* ```typescript
|
|
3631
|
+
* const merged = merge([stream1, stream2, stream3]);
|
|
3632
|
+
* for await (const item of merged) {
|
|
3633
|
+
* console.log(item); // Items from any stream
|
|
3634
|
+
* }
|
|
3635
|
+
* ```
|
|
3636
|
+
*/
|
|
3637
|
+
declare function merge<T>(streams: AsyncIterable<T>[]): AsyncIterable<T>;
|
|
3638
|
+
/**
|
|
3639
|
+
* Filter stream items based on a predicate
|
|
3640
|
+
*
|
|
3641
|
+
* @example
|
|
3642
|
+
* ```typescript
|
|
3643
|
+
* const filtered = filter(stream, (item) => item.value > 10);
|
|
3644
|
+
* for await (const item of filtered) {
|
|
3645
|
+
* console.log(item); // Only items with value > 10
|
|
3646
|
+
* }
|
|
3647
|
+
* ```
|
|
3648
|
+
*/
|
|
3649
|
+
declare function filter<T>(stream: AsyncIterable<T>, predicate: (item: T) => boolean | Promise<boolean>): AsyncIterable<T>;
|
|
3650
|
+
/**
|
|
3651
|
+
* Map stream items to new values
|
|
3652
|
+
*
|
|
3653
|
+
* @example
|
|
3654
|
+
* ```typescript
|
|
3655
|
+
* const mapped = map(stream, (item) => item.value * 2);
|
|
3656
|
+
* for await (const item of mapped) {
|
|
3657
|
+
* console.log(item); // Transformed items
|
|
3658
|
+
* }
|
|
3659
|
+
* ```
|
|
3660
|
+
*/
|
|
3661
|
+
declare function map<T, R>(stream: AsyncIterable<T>, mapper: (item: T) => R | Promise<R>): AsyncIterable<R>;
|
|
3662
|
+
/**
|
|
3663
|
+
* Take only the first N items from a stream
|
|
3664
|
+
*
|
|
3665
|
+
* @example
|
|
3666
|
+
* ```typescript
|
|
3667
|
+
* const first10 = take(stream, 10);
|
|
3668
|
+
* for await (const item of first10) {
|
|
3669
|
+
* console.log(item); // Only first 10 items
|
|
3670
|
+
* }
|
|
3671
|
+
* ```
|
|
3672
|
+
*/
|
|
3673
|
+
declare function take<T>(stream: AsyncIterable<T>, count: number): AsyncIterable<T>;
|
|
3674
|
+
|
|
3675
|
+
/**
|
|
3676
|
+
* Progress tracking for long-running operations
|
|
3677
|
+
* @module streaming/progress
|
|
3678
|
+
*/
|
|
3679
|
+
|
|
3680
|
+
/**
|
|
3681
|
+
* Create a progress tracker for long-running operations
|
|
3682
|
+
*
|
|
3683
|
+
* @example
|
|
3684
|
+
* ```typescript
|
|
3685
|
+
* const tracker = createProgressTracker({
|
|
3686
|
+
* total: 100,
|
|
3687
|
+
* onProgress: (progress) => {
|
|
3688
|
+
* console.log(`${progress.percentage}% complete (ETA: ${progress.eta}s)`);
|
|
3689
|
+
* },
|
|
3690
|
+
* });
|
|
3691
|
+
*
|
|
3692
|
+
* tracker.start();
|
|
3693
|
+
* for (let i = 0; i < 100; i++) {
|
|
3694
|
+
* await processItem(i);
|
|
3695
|
+
* tracker.update(i + 1);
|
|
3696
|
+
* }
|
|
3697
|
+
* tracker.complete();
|
|
3698
|
+
* ```
|
|
3699
|
+
*/
|
|
3700
|
+
declare function createProgressTracker(options: ProgressTrackerOptions): ProgressTracker;
|
|
3701
|
+
|
|
3702
|
+
/**
|
|
3703
|
+
* Server-Sent Events (SSE) support for streaming
|
|
3704
|
+
* @module streaming/sse
|
|
3705
|
+
*/
|
|
3706
|
+
|
|
3707
|
+
/**
|
|
3708
|
+
* Create an SSE formatter for streaming data
|
|
3709
|
+
*
|
|
3710
|
+
* @example
|
|
3711
|
+
* ```typescript
|
|
3712
|
+
* const formatter = createSSEFormatter({
|
|
3713
|
+
* eventTypes: {
|
|
3714
|
+
* token: (data) => ({ event: 'token', data: data.content }),
|
|
3715
|
+
* error: (data) => ({ event: 'error', data: data.message }),
|
|
3716
|
+
* },
|
|
3717
|
+
* heartbeat: 30000,
|
|
3718
|
+
* retry: 3000,
|
|
3719
|
+
* });
|
|
3720
|
+
*
|
|
3721
|
+
* // In Express/Fastify handler
|
|
3722
|
+
* res.setHeader('Content-Type', 'text/event-stream');
|
|
3723
|
+
* res.setHeader('Cache-Control', 'no-cache');
|
|
3724
|
+
* res.setHeader('Connection', 'keep-alive');
|
|
3725
|
+
*
|
|
3726
|
+
* for await (const event of formatter.format(stream)) {
|
|
3727
|
+
* res.write(event);
|
|
3728
|
+
* }
|
|
3729
|
+
* res.end();
|
|
3730
|
+
* ```
|
|
3731
|
+
*/
|
|
3732
|
+
declare function createSSEFormatter<T = any>(options?: SSEFormatterOptions<T>): SSEFormatter<T>;
|
|
3733
|
+
/**
|
|
3734
|
+
* Create a heartbeat comment for SSE
|
|
3735
|
+
*/
|
|
3736
|
+
declare function createHeartbeat(): string;
|
|
3737
|
+
/**
|
|
3738
|
+
* Parse SSE event from string
|
|
3739
|
+
*
|
|
3740
|
+
* Useful for testing or client-side parsing
|
|
3741
|
+
*/
|
|
3742
|
+
declare function parseSSEEvent(eventString: string): SSEEvent | null;
|
|
3743
|
+
|
|
3744
|
+
/**
|
|
3745
|
+
* WebSocket support for bidirectional streaming
|
|
3746
|
+
* @module streaming/websocket
|
|
3747
|
+
*/
|
|
3748
|
+
|
|
3749
|
+
/**
|
|
3750
|
+
* Create a WebSocket handler for bidirectional streaming
|
|
3751
|
+
*
|
|
3752
|
+
* @example
|
|
3753
|
+
* ```typescript
|
|
3754
|
+
* import WebSocket from 'ws';
|
|
3755
|
+
*
|
|
3756
|
+
* const handler = createWebSocketHandler({
|
|
3757
|
+
* onConnect: (ws) => {
|
|
3758
|
+
* console.log('Client connected');
|
|
3759
|
+
* },
|
|
3760
|
+
* onMessage: async (ws, message) => {
|
|
3761
|
+
* const stream = await agent.stream(message);
|
|
3762
|
+
* for await (const event of stream) {
|
|
3763
|
+
* ws.send(JSON.stringify(event));
|
|
3764
|
+
* }
|
|
3765
|
+
* },
|
|
3766
|
+
* onError: (ws, error) => {
|
|
3767
|
+
* ws.send(JSON.stringify({ type: 'error', error: error.message }));
|
|
3768
|
+
* },
|
|
3769
|
+
* heartbeat: 30000,
|
|
3770
|
+
* });
|
|
3771
|
+
*
|
|
3772
|
+
* wss.on('connection', handler);
|
|
3773
|
+
* ```
|
|
3774
|
+
*/
|
|
3775
|
+
declare function createWebSocketHandler(options: WebSocketHandlerOptions): (ws: any, req?: any) => void;
|
|
3776
|
+
/**
|
|
3777
|
+
* Send a message through WebSocket
|
|
3778
|
+
*
|
|
3779
|
+
* Automatically serializes objects to JSON
|
|
3780
|
+
*/
|
|
3781
|
+
declare function sendMessage(ws: any, message: WebSocketMessage): void;
|
|
3782
|
+
/**
|
|
3783
|
+
* Broadcast a message to multiple WebSocket clients
|
|
3784
|
+
*/
|
|
3785
|
+
declare function broadcast(clients: Set<any>, message: WebSocketMessage): void;
|
|
3786
|
+
/**
|
|
3787
|
+
* Create a WebSocket message
|
|
3788
|
+
*/
|
|
3789
|
+
declare function createMessage(type: string, data?: any, error?: string): WebSocketMessage;
|
|
3790
|
+
|
|
3791
|
+
/**
|
|
3792
|
+
* Connection pooling for database and HTTP clients
|
|
3793
|
+
*/
|
|
3794
|
+
interface PoolConfig {
|
|
3795
|
+
min?: number;
|
|
3796
|
+
max?: number;
|
|
3797
|
+
acquireTimeout?: number;
|
|
3798
|
+
idleTimeout?: number;
|
|
3799
|
+
evictionInterval?: number;
|
|
3800
|
+
}
|
|
3801
|
+
interface HealthCheckConfig {
|
|
3802
|
+
enabled?: boolean;
|
|
3803
|
+
interval?: number;
|
|
3804
|
+
timeout?: number;
|
|
3805
|
+
retries?: number;
|
|
3806
|
+
}
|
|
3807
|
+
interface ConnectionPoolOptions<T> {
|
|
3808
|
+
factory: () => Promise<T>;
|
|
3809
|
+
destroyer?: (connection: T) => Promise<void>;
|
|
3810
|
+
validator?: (connection: T) => Promise<boolean>;
|
|
3811
|
+
pool?: PoolConfig;
|
|
3812
|
+
healthCheck?: HealthCheckConfig;
|
|
3813
|
+
onAcquire?: (connection: T) => void;
|
|
3814
|
+
onRelease?: (connection: T) => void;
|
|
3815
|
+
onDestroy?: (connection: T) => void;
|
|
3816
|
+
onHealthCheckFail?: (error: Error) => void;
|
|
3817
|
+
}
|
|
3818
|
+
interface PoolStats {
|
|
3819
|
+
size: number;
|
|
3820
|
+
available: number;
|
|
3821
|
+
pending: number;
|
|
3822
|
+
acquired: number;
|
|
3823
|
+
created: number;
|
|
3824
|
+
destroyed: number;
|
|
3825
|
+
healthChecksPassed: number;
|
|
3826
|
+
healthChecksFailed: number;
|
|
3827
|
+
}
|
|
3828
|
+
declare class ConnectionPool<T> {
|
|
3829
|
+
private options;
|
|
3830
|
+
private connections;
|
|
3831
|
+
private pending;
|
|
3832
|
+
private stats;
|
|
3833
|
+
private evictionTimer?;
|
|
3834
|
+
private healthCheckTimer?;
|
|
3835
|
+
private draining;
|
|
3836
|
+
constructor(options: ConnectionPoolOptions<T>);
|
|
3837
|
+
private initialize;
|
|
3838
|
+
private createConnection;
|
|
3839
|
+
private destroyConnection;
|
|
3840
|
+
acquire(): Promise<T>;
|
|
3841
|
+
release(connection: T): Promise<void>;
|
|
3842
|
+
private evictIdleConnections;
|
|
3843
|
+
private performHealthChecks;
|
|
3844
|
+
drain(): Promise<void>;
|
|
3845
|
+
clear(): Promise<void>;
|
|
3846
|
+
getStats(): PoolStats;
|
|
3847
|
+
}
|
|
3848
|
+
declare function createConnectionPool<T>(options: ConnectionPoolOptions<T>): ConnectionPool<T>;
|
|
3849
|
+
|
|
3850
|
+
interface DatabaseConfig {
|
|
3851
|
+
host: string;
|
|
3852
|
+
port?: number;
|
|
3853
|
+
database: string;
|
|
3854
|
+
user: string;
|
|
3855
|
+
password: string;
|
|
3856
|
+
ssl?: boolean;
|
|
3857
|
+
connectionTimeout?: number;
|
|
3858
|
+
}
|
|
3859
|
+
interface DatabaseConnection {
|
|
3860
|
+
query<T = any>(sql: string, params?: any[]): Promise<T>;
|
|
3861
|
+
execute(sql: string, params?: any[]): Promise<void>;
|
|
3862
|
+
close(): Promise<void>;
|
|
3863
|
+
}
|
|
3864
|
+
interface DatabasePoolOptions {
|
|
3865
|
+
config: DatabaseConfig;
|
|
3866
|
+
pool?: PoolConfig;
|
|
3867
|
+
healthCheck?: HealthCheckConfig & {
|
|
3868
|
+
query?: string;
|
|
3869
|
+
};
|
|
3870
|
+
onConnect?: (connection: DatabaseConnection) => void;
|
|
3871
|
+
onDisconnect?: (connection: DatabaseConnection) => void;
|
|
3872
|
+
}
|
|
3873
|
+
declare class DatabasePool {
|
|
3874
|
+
private options;
|
|
3875
|
+
private pool;
|
|
3876
|
+
constructor(options: DatabasePoolOptions);
|
|
3877
|
+
acquire(): Promise<DatabaseConnection>;
|
|
3878
|
+
release(connection: DatabaseConnection): Promise<void>;
|
|
3879
|
+
query<T = any>(sql: string, params?: any[]): Promise<T>;
|
|
3880
|
+
execute(sql: string, params?: any[]): Promise<void>;
|
|
3881
|
+
drain(): Promise<void>;
|
|
3882
|
+
clear(): Promise<void>;
|
|
3883
|
+
getStats(): PoolStats;
|
|
3884
|
+
}
|
|
3885
|
+
declare function createDatabasePool(options: DatabasePoolOptions): DatabasePool;
|
|
3886
|
+
|
|
3887
|
+
interface HttpConfig {
|
|
3888
|
+
baseURL: string;
|
|
3889
|
+
timeout?: number;
|
|
3890
|
+
headers?: Record<string, string>;
|
|
3891
|
+
maxRedirects?: number;
|
|
3892
|
+
validateStatus?: (status: number) => boolean;
|
|
3893
|
+
}
|
|
3894
|
+
interface HttpPoolConfig extends PoolConfig {
|
|
3895
|
+
maxSockets?: number;
|
|
3896
|
+
keepAlive?: boolean;
|
|
3897
|
+
keepAliveMsecs?: number;
|
|
3898
|
+
}
|
|
3899
|
+
interface HttpClient {
|
|
3900
|
+
get<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
|
|
3901
|
+
post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
|
|
3902
|
+
put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
|
|
3903
|
+
delete<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
|
|
3904
|
+
request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
|
|
3905
|
+
close(): Promise<void>;
|
|
3906
|
+
}
|
|
3907
|
+
interface RequestConfig {
|
|
3908
|
+
url?: string;
|
|
3909
|
+
method?: string;
|
|
3910
|
+
headers?: Record<string, string>;
|
|
3911
|
+
params?: Record<string, any>;
|
|
3912
|
+
data?: any;
|
|
3913
|
+
timeout?: number;
|
|
3914
|
+
}
|
|
3915
|
+
interface HttpResponse<T = any> {
|
|
3916
|
+
data: T;
|
|
3917
|
+
status: number;
|
|
3918
|
+
statusText: string;
|
|
3919
|
+
headers: Record<string, string>;
|
|
3920
|
+
}
|
|
3921
|
+
interface HttpPoolOptions {
|
|
3922
|
+
config: HttpConfig;
|
|
3923
|
+
pool?: HttpPoolConfig;
|
|
3924
|
+
healthCheck?: HealthCheckConfig & {
|
|
3925
|
+
endpoint?: string;
|
|
3926
|
+
method?: string;
|
|
3927
|
+
};
|
|
3928
|
+
onConnect?: (client: HttpClient) => void;
|
|
3929
|
+
onDisconnect?: (client: HttpClient) => void;
|
|
3930
|
+
}
|
|
3931
|
+
declare class HttpPool {
|
|
3932
|
+
private options;
|
|
3933
|
+
private pool;
|
|
3934
|
+
constructor(options: HttpPoolOptions);
|
|
3935
|
+
acquire(): Promise<HttpClient>;
|
|
3936
|
+
release(client: HttpClient): Promise<void>;
|
|
3937
|
+
request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
|
|
3938
|
+
drain(): Promise<void>;
|
|
3939
|
+
clear(): Promise<void>;
|
|
3940
|
+
getStats(): PoolStats;
|
|
3941
|
+
}
|
|
3942
|
+
declare function createHttpPool(options: HttpPoolOptions): HttpPool;
|
|
3943
|
+
|
|
3944
|
+
/**
|
|
3945
|
+
* Memory management and tracking
|
|
3946
|
+
*/
|
|
3947
|
+
interface MemoryStats {
|
|
3948
|
+
used: number;
|
|
3949
|
+
total: number;
|
|
3950
|
+
percentage: number;
|
|
3951
|
+
heapUsed: number;
|
|
3952
|
+
heapTotal: number;
|
|
3953
|
+
external: number;
|
|
3954
|
+
arrayBuffers: number;
|
|
3955
|
+
}
|
|
3956
|
+
interface MemoryManagerOptions {
|
|
3957
|
+
maxMemory?: number;
|
|
3958
|
+
checkInterval?: number;
|
|
3959
|
+
thresholdPercentage?: number;
|
|
3960
|
+
onThreshold?: (stats: MemoryStats) => void;
|
|
3961
|
+
onLimit?: (stats: MemoryStats) => Promise<void>;
|
|
3962
|
+
onLeak?: (stats: MemoryStats) => void;
|
|
3963
|
+
leakDetection?: {
|
|
3964
|
+
enabled?: boolean;
|
|
3965
|
+
sampleInterval?: number;
|
|
3966
|
+
growthThreshold?: number;
|
|
3967
|
+
};
|
|
3968
|
+
}
|
|
3969
|
+
type CleanupHandler = () => Promise<void>;
|
|
3970
|
+
declare class MemoryManager {
|
|
3971
|
+
private options;
|
|
3972
|
+
private cleanupHandlers;
|
|
3973
|
+
private checkTimer?;
|
|
3974
|
+
private leakDetectionTimer?;
|
|
3975
|
+
private previousMemory?;
|
|
3976
|
+
private running;
|
|
3977
|
+
constructor(options: MemoryManagerOptions);
|
|
3978
|
+
start(): void;
|
|
3979
|
+
stop(): void;
|
|
3980
|
+
registerCleanup(name: string, handler: CleanupHandler): void;
|
|
3981
|
+
unregisterCleanup(name: string): void;
|
|
3982
|
+
cleanup(name?: string): Promise<void>;
|
|
3983
|
+
getStats(): MemoryStats;
|
|
3984
|
+
forceGC(): void;
|
|
3985
|
+
private checkMemory;
|
|
3986
|
+
private detectLeaks;
|
|
3987
|
+
}
|
|
3988
|
+
declare function createMemoryManager(options: MemoryManagerOptions): MemoryManager;
|
|
3989
|
+
|
|
3990
|
+
/**
|
|
3991
|
+
* Batch processing for efficient request handling
|
|
3992
|
+
*/
|
|
3993
|
+
interface BatchProcessorOptions<TInput, TOutput> {
|
|
3994
|
+
maxBatchSize: number;
|
|
3995
|
+
maxWaitTime: number;
|
|
3996
|
+
processor: (batch: TInput[]) => Promise<TOutput[]>;
|
|
3997
|
+
onBatchStart?: (batch: TInput[]) => void;
|
|
3998
|
+
onBatchComplete?: (batch: TInput[], results: TOutput[]) => void;
|
|
3999
|
+
onBatchError?: (batch: TInput[], error: Error) => void;
|
|
4000
|
+
onItemError?: (item: TInput, error: Error) => TOutput | undefined;
|
|
4001
|
+
}
|
|
4002
|
+
interface BatchStats {
|
|
4003
|
+
totalBatches: number;
|
|
4004
|
+
totalItems: number;
|
|
4005
|
+
averageBatchSize: number;
|
|
4006
|
+
averageWaitTime: number;
|
|
4007
|
+
successfulBatches: number;
|
|
4008
|
+
failedBatches: number;
|
|
4009
|
+
}
|
|
4010
|
+
declare class BatchProcessor<TInput, TOutput> {
|
|
4011
|
+
private options;
|
|
4012
|
+
private pending;
|
|
4013
|
+
private timer?;
|
|
4014
|
+
private processing;
|
|
4015
|
+
private stats;
|
|
4016
|
+
constructor(options: BatchProcessorOptions<TInput, TOutput>);
|
|
4017
|
+
add(input: TInput): Promise<TOutput>;
|
|
4018
|
+
flush(): Promise<void>;
|
|
4019
|
+
private processBatch;
|
|
4020
|
+
getStats(): BatchStats;
|
|
4021
|
+
getPendingCount(): number;
|
|
4022
|
+
}
|
|
4023
|
+
declare function createBatchProcessor<TInput, TOutput>(options: BatchProcessorOptions<TInput, TOutput>): BatchProcessor<TInput, TOutput>;
|
|
4024
|
+
|
|
4025
|
+
/**
|
|
4026
|
+
* Circuit breaker pattern for fault tolerance
|
|
4027
|
+
*/
|
|
4028
|
+
type CircuitState = 'closed' | 'open' | 'half-open';
|
|
4029
|
+
interface CircuitBreakerOptions {
|
|
4030
|
+
failureThreshold: number;
|
|
4031
|
+
resetTimeout: number;
|
|
4032
|
+
monitoringPeriod?: number;
|
|
4033
|
+
halfOpenRequests?: number;
|
|
4034
|
+
onStateChange?: (state: CircuitState, previousState: CircuitState) => void;
|
|
4035
|
+
onFailure?: (error: Error) => void;
|
|
4036
|
+
onSuccess?: () => void;
|
|
4037
|
+
shouldTrip?: (error: Error) => boolean;
|
|
4038
|
+
}
|
|
4039
|
+
interface CircuitBreakerStats {
|
|
4040
|
+
state: CircuitState;
|
|
4041
|
+
failures: number;
|
|
4042
|
+
successes: number;
|
|
4043
|
+
totalCalls: number;
|
|
4044
|
+
failureRate: number;
|
|
4045
|
+
lastFailureTime?: number;
|
|
4046
|
+
lastSuccessTime?: number;
|
|
4047
|
+
stateChanges: number;
|
|
4048
|
+
}
|
|
4049
|
+
declare class CircuitBreaker {
|
|
4050
|
+
private options;
|
|
4051
|
+
private state;
|
|
4052
|
+
private failures;
|
|
4053
|
+
private successes;
|
|
4054
|
+
private totalCalls;
|
|
4055
|
+
private stateChanges;
|
|
4056
|
+
private lastFailureTime?;
|
|
4057
|
+
private lastSuccessTime?;
|
|
4058
|
+
private resetTimer?;
|
|
4059
|
+
private callHistory;
|
|
4060
|
+
private halfOpenAttempts;
|
|
4061
|
+
constructor(options: CircuitBreakerOptions);
|
|
4062
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
4063
|
+
wrap<TArgs extends any[], TReturn>(fn: (...args: TArgs) => Promise<TReturn>): (...args: TArgs) => Promise<TReturn>;
|
|
4064
|
+
private onSuccess;
|
|
4065
|
+
private onFailure;
|
|
4066
|
+
private recordCall;
|
|
4067
|
+
private getRecentFailures;
|
|
4068
|
+
private scheduleReset;
|
|
4069
|
+
private transitionTo;
|
|
4070
|
+
getState(): CircuitState;
|
|
4071
|
+
getStats(): CircuitBreakerStats;
|
|
4072
|
+
reset(): void;
|
|
4073
|
+
}
|
|
4074
|
+
declare function createCircuitBreaker(options: CircuitBreakerOptions): CircuitBreaker;
|
|
4075
|
+
|
|
4076
|
+
export { AgentError, type AggregateNode, type BackoffStrategy, type BatchOptions, BatchProcessor, type BatchProcessorOptions, type BatchStats, type CheckpointHistoryOptions, type CheckpointerOptions, type ChunkOptions, CircuitBreaker, type CircuitBreakerOptions, type CircuitBreakerStats, type CircuitState, type ComposeGraphsOptions, type ComposeOptions, type ComposeToolConfig, type ComposedTool, type ConditionalConfig, type ConditionalRouter, type ConditionalRouterConfig, ConnectionPool, type ConnectionPoolOptions, type ConversationConfig, type DatabaseConfig, type DatabaseConnection, DatabasePool, type DatabasePoolOptions, type DevelopmentPresetOptions, type ErrorContext, type ErrorHandlerOptions, type ErrorReporter, type ErrorReporterOptions, type EventHandler, type ExecutionMetrics, type HealthCheckConfig, type HealthCheckResult, type HttpClient, type HttpConfig, HttpPool, type HttpPoolConfig, type HttpPoolOptions, type HttpResponse, type LangSmithConfig, type LogEntry, LogLevel, type Logger, type LoggerOptions, ManagedTool, type ManagedToolConfig, type ManagedToolStats, MemoryManager, type MemoryManagerOptions, type MemoryStats, type MetricEntry, MetricType, type Metrics, type MetricsNodeOptions, type Middleware, MiddlewareChain, type MiddlewareContext, type MiddlewareFactory, type MiddlewareMetadata, type MiddlewareWithMetadata, MissingDescriptionError, type MockToolConfig, type MockToolResponse, type NodeFunction, type NodeFunctionWithContext, type ParallelNode, type ParallelWorkflowConfig, type ParallelWorkflowOptions, type PoolConfig, type PoolStats, type Priority, type ProductionPresetOptions, type Progress, type ProgressTracker, type ProgressTrackerOptions, type PromptOptions, type ReducerFunction, RegistryEvent, type RequestConfig, type RetryOptions, type RetryPolicy, type RouteCondition, type RouteMap, type RouteName, type SSEEvent, type SSEFormatter, type SSEFormatterOptions, type SequentialNode, type SequentialWorkflowOptions, type SimpleMiddleware, type SqliteCheckpointerOptions, type StateChannelConfig, type SubgraphBuilder, type TestingPresetOptions, type ThreadConfig, type ThrottleOptions, TimeoutError, type TimeoutOptions, type Timer, type Tool, type BackoffStrategy$1 as ToolBackoffStrategy, ToolBuilder, ToolCategory, ToolCategorySchema, type ToolExample, ToolExampleSchema, type ToolExecution, type ToolExecutorConfig, type ToolInvocation, type ToolMetadata, ToolMetadataSchema, ToolNameSchema, ToolRegistry, type ToolSimulatorConfig, type TracingOptions, type WebSocketHandlerOptions, type WebSocketMessage, batch, broadcast, cache, chain, chunk, clearThread, collect, compose, composeGraphs, composeTool, composeWithOptions, conditional, configureLangSmith, createBatchProcessor, createBinaryRouter, createCircuitBreaker, createConditionalRouter, createConnectionPool, createConversationConfig, createDatabasePool, createErrorReporter, createHeartbeat, createHttpPool, createLogger, createManagedTool, createMemoryCheckpointer, createMemoryManager, createMessage, createMetrics, createMiddlewareContext, createMockTool, createMultiRouter, createParallelWorkflow, createProgressTracker, createSSEFormatter, createSequentialWorkflow, createSqliteCheckpointer, createStateAnnotation, createSubgraph, createThreadConfig, createTool, createToolExecutor, createToolSimulator, createToolUnsafe, createWebSocketHandler, development, filter, generateThreadId, getCheckpointHistory, getLangSmithConfig, getLatestCheckpoint, getMissingDescriptions, getToolDescription, getToolJsonSchema, isMemoryCheckpointer, isTracingEnabled, map, merge, mergeState, parallel, parseSSEEvent, presets, production, reduce, retry, safeValidateSchemaDescriptions, sendMessage, sequential, sequentialBuilder, take, testing, throttle, timeout, toLangChainTool, toLangChainTools, toolBuilder, validateSchemaDescriptions, validateState, validateTool, validateToolMetadata, validateToolName, withErrorHandler, withMetrics, withRetry, withTimeout, withTracing };
|