societyai 0.0.1
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/CHANGELOG.md +111 -0
- package/LICENSE +21 -0
- package/README.md +879 -0
- package/dist/builder.d.ts +181 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +667 -0
- package/dist/builder.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +107 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +319 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +219 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +395 -0
- package/dist/events.js.map +1 -0
- package/dist/graph.d.ts +104 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +366 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +78 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory.d.ts +146 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +353 -0
- package/dist/memory.js.map +1 -0
- package/dist/metrics.d.ts +143 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +271 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware.d.ts +147 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +484 -0
- package/dist/middleware.js.map +1 -0
- package/dist/models.d.ts +32 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +211 -0
- package/dist/models.js.map +1 -0
- package/dist/patterns.d.ts +6 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +68 -0
- package/dist/patterns.js.map +1 -0
- package/dist/pipeline.d.ts +84 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +569 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/retry.d.ts +5 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +70 -0
- package/dist/retry.js.map +1 -0
- package/dist/society.d.ts +94 -0
- package/dist/society.d.ts.map +1 -0
- package/dist/society.js +721 -0
- package/dist/society.js.map +1 -0
- package/dist/strategies.d.ts +55 -0
- package/dist/strategies.d.ts.map +1 -0
- package/dist/strategies.js +678 -0
- package/dist/strategies.js.map +1 -0
- package/dist/tools.d.ts +88 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +366 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +64 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +334 -0
- package/dist/validation.js.map +1 -0
- package/dist/worker-pool.d.ts +17 -0
- package/dist/worker-pool.d.ts.map +1 -0
- package/dist/worker-pool.js +80 -0
- package/dist/worker-pool.js.map +1 -0
- package/docs/README.md +468 -0
- package/docs/advanced.md +616 -0
- package/docs/aggregation-strategies.md +926 -0
- package/docs/api-reference.md +771 -0
- package/docs/architecture.md +648 -0
- package/docs/context-system.md +642 -0
- package/docs/event-system.md +1047 -0
- package/docs/examples.md +576 -0
- package/docs/getting-started.md +564 -0
- package/docs/graph-execution.md +389 -0
- package/docs/memory-system.md +497 -0
- package/docs/metrics-observability.md +560 -0
- package/docs/middleware-system.md +1038 -0
- package/docs/migration.md +296 -0
- package/docs/pipeline-patterns.md +761 -0
- package/docs/structured-output.md +612 -0
- package/docs/tool-calling.md +491 -0
- package/docs/workflows.md +740 -0
- package/examples/README.md +234 -0
- package/examples/advanced-patterns.ts +115 -0
- package/examples/complete-integration.ts +327 -0
- package/examples/graph-workflow.ts +161 -0
- package/examples/memory-system.ts +155 -0
- package/examples/metrics-tracking.ts +243 -0
- package/examples/structured-output.ts +231 -0
- package/examples/tool-calling.ts +163 -0
- package/package.json +94 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
# Tool Calling System
|
|
2
|
+
|
|
3
|
+
The Tool Calling System enables AI agents to interact with external functions, APIs, and services. Agents can discover available tools, call them with validated parameters, and integrate the results into their responses.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Tool Calling System provides:
|
|
8
|
+
|
|
9
|
+
- **Tool Registry**: Centralized management of available tools
|
|
10
|
+
- **JSON Schema Validation**: Automatic parameter validation
|
|
11
|
+
- **Automatic Retry**: Built-in retry logic for failed tool calls
|
|
12
|
+
- **Built-in Tools**: Pre-configured common utilities
|
|
13
|
+
- **Parallel Execution**: Execute multiple tools simultaneously
|
|
14
|
+
- **Tool Extraction**: Parse tool calls from agent output
|
|
15
|
+
|
|
16
|
+
## Core Components
|
|
17
|
+
|
|
18
|
+
### Tool
|
|
19
|
+
|
|
20
|
+
A tool represents a callable function with metadata:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
interface Tool {
|
|
24
|
+
name: string; // Unique tool identifier
|
|
25
|
+
description: string; // What the tool does
|
|
26
|
+
parameters: JSONSchema; // Parameter schema
|
|
27
|
+
executor: (params: Record<string, unknown>) => Promise<unknown>;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### ToolBuilder
|
|
32
|
+
|
|
33
|
+
Create tools with fluent API:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { ToolBuilder } from 'societyai';
|
|
37
|
+
|
|
38
|
+
const calculator = ToolBuilder.create()
|
|
39
|
+
.withName('calculator')
|
|
40
|
+
.withDescription('Performs basic arithmetic operations')
|
|
41
|
+
.withParameters({
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
operation: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: ['add', 'subtract', 'multiply', 'divide'],
|
|
47
|
+
},
|
|
48
|
+
a: { type: 'number' },
|
|
49
|
+
b: { type: 'number' },
|
|
50
|
+
},
|
|
51
|
+
required: ['operation', 'a', 'b'],
|
|
52
|
+
})
|
|
53
|
+
.withExecutor(async (params) => {
|
|
54
|
+
const { operation, a, b } = params as {
|
|
55
|
+
operation: string;
|
|
56
|
+
a: number;
|
|
57
|
+
b: number;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
switch (operation) {
|
|
61
|
+
case 'add':
|
|
62
|
+
return a + b;
|
|
63
|
+
case 'subtract':
|
|
64
|
+
return a - b;
|
|
65
|
+
case 'multiply':
|
|
66
|
+
return a * b;
|
|
67
|
+
case 'divide':
|
|
68
|
+
return b !== 0 ? a / b : 'Error: Division by zero';
|
|
69
|
+
default:
|
|
70
|
+
throw new Error(`Unknown operation: ${operation}`);
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.build();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### ToolRegistry
|
|
77
|
+
|
|
78
|
+
Manage and execute tools:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { ToolRegistry } from 'societyai';
|
|
82
|
+
|
|
83
|
+
const registry = new ToolRegistry();
|
|
84
|
+
|
|
85
|
+
// Register tools
|
|
86
|
+
registry.register(calculator);
|
|
87
|
+
registry.register(weatherTool);
|
|
88
|
+
registry.register(databaseTool);
|
|
89
|
+
|
|
90
|
+
// Get all tools
|
|
91
|
+
const tools = registry.getAll();
|
|
92
|
+
|
|
93
|
+
// Get specific tool
|
|
94
|
+
const calc = registry.get('calculator');
|
|
95
|
+
|
|
96
|
+
// Unregister
|
|
97
|
+
registry.unregister('calculator');
|
|
98
|
+
|
|
99
|
+
// Execute tool
|
|
100
|
+
const result = await registry.execute('calculator', {
|
|
101
|
+
operation: 'add',
|
|
102
|
+
a: 5,
|
|
103
|
+
b: 3,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
console.log(result); // { success: true, result: 8, duration: 2 }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### ToolExecutor
|
|
110
|
+
|
|
111
|
+
Handle tool calling workflows:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { ToolExecutor } from 'societyai';
|
|
115
|
+
|
|
116
|
+
const executor = new ToolExecutor(registry);
|
|
117
|
+
|
|
118
|
+
// Extract tool calls from agent output
|
|
119
|
+
const agentOutput = `
|
|
120
|
+
I'll calculate that for you.
|
|
121
|
+
{"tool": "calculator", "parameters": {"operation": "add", "a": 10, "b": 5}}
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
const { results, hasToolCalls } = await executor.executeFromAgentOutput(agentOutput);
|
|
125
|
+
|
|
126
|
+
if (hasToolCalls) {
|
|
127
|
+
console.log('Tools executed:', results);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Format results for feedback
|
|
131
|
+
const feedback = executor.formatResults(results);
|
|
132
|
+
console.log(feedback);
|
|
133
|
+
// Output:
|
|
134
|
+
// Tool Results:
|
|
135
|
+
// ✓ calculator: 15
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Built-in Tools
|
|
139
|
+
|
|
140
|
+
### Calculator
|
|
141
|
+
|
|
142
|
+
Performs basic arithmetic:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { BuiltInTools } from 'societyai';
|
|
146
|
+
|
|
147
|
+
const calculator = BuiltInTools.calculator();
|
|
148
|
+
registry.register(calculator);
|
|
149
|
+
|
|
150
|
+
// Usage
|
|
151
|
+
const result = await registry.execute('calculator', {
|
|
152
|
+
operation: 'multiply',
|
|
153
|
+
a: 7,
|
|
154
|
+
b: 6,
|
|
155
|
+
});
|
|
156
|
+
// { success: true, result: 42 }
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### String Manipulation
|
|
160
|
+
|
|
161
|
+
Common string operations:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const stringTool = BuiltInTools.stringManipulation();
|
|
165
|
+
registry.register(stringTool);
|
|
166
|
+
|
|
167
|
+
// Operations: uppercase, lowercase, reverse, length, trim, replace
|
|
168
|
+
const result = await registry.execute('string_manipulation', {
|
|
169
|
+
operation: 'uppercase',
|
|
170
|
+
text: 'hello world',
|
|
171
|
+
});
|
|
172
|
+
// { success: true, result: 'HELLO WORLD' }
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Storage
|
|
176
|
+
|
|
177
|
+
Simple key-value storage:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const storage = BuiltInTools.storage();
|
|
181
|
+
registry.register(storage);
|
|
182
|
+
|
|
183
|
+
// Set value
|
|
184
|
+
await registry.execute('storage', {
|
|
185
|
+
operation: 'set',
|
|
186
|
+
key: 'user_name',
|
|
187
|
+
value: 'Alice',
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Get value
|
|
191
|
+
const result = await registry.execute('storage', {
|
|
192
|
+
operation: 'get',
|
|
193
|
+
key: 'user_name',
|
|
194
|
+
});
|
|
195
|
+
// { success: true, result: 'Alice' }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Complete Example
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import {
|
|
202
|
+
ToolBuilder,
|
|
203
|
+
ToolRegistry,
|
|
204
|
+
ToolExecutor,
|
|
205
|
+
BuiltInTools,
|
|
206
|
+
StandardModelBase,
|
|
207
|
+
} from 'societyai';
|
|
208
|
+
|
|
209
|
+
// 1. Create custom tool
|
|
210
|
+
const weatherTool = ToolBuilder.create()
|
|
211
|
+
.withName('get_weather')
|
|
212
|
+
.withDescription('Get current weather for a city')
|
|
213
|
+
.withParameters({
|
|
214
|
+
type: 'object',
|
|
215
|
+
properties: {
|
|
216
|
+
city: { type: 'string' },
|
|
217
|
+
units: { type: 'string', enum: ['celsius', 'fahrenheit'] },
|
|
218
|
+
},
|
|
219
|
+
required: ['city'],
|
|
220
|
+
})
|
|
221
|
+
.withExecutor(async (params) => {
|
|
222
|
+
const { city, units = 'celsius' } = params as {
|
|
223
|
+
city: string;
|
|
224
|
+
units?: string;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Simulate API call
|
|
228
|
+
const temp = units === 'celsius' ? '22' : '72';
|
|
229
|
+
return `Temperature in ${city}: ${temp}°${units === 'celsius' ? 'C' : 'F'}`;
|
|
230
|
+
})
|
|
231
|
+
.build();
|
|
232
|
+
|
|
233
|
+
// 2. Setup registry
|
|
234
|
+
const registry = new ToolRegistry();
|
|
235
|
+
registry.register(weatherTool);
|
|
236
|
+
registry.register(BuiltInTools.calculator());
|
|
237
|
+
registry.register(BuiltInTools.stringManipulation());
|
|
238
|
+
|
|
239
|
+
// 3. Create executor
|
|
240
|
+
const executor = new ToolExecutor(registry);
|
|
241
|
+
|
|
242
|
+
// 4. Use with agent
|
|
243
|
+
class ToolAwareModel extends StandardModelBase {
|
|
244
|
+
constructor(private toolExecutor: ToolExecutor) {
|
|
245
|
+
super({ name: 'tool-aware' }, async (prompt: unknown) => {
|
|
246
|
+
const promptStr = typeof prompt === 'string' ? prompt : JSON.stringify(prompt);
|
|
247
|
+
|
|
248
|
+
// Agent decides to call tools
|
|
249
|
+
if (promptStr.includes('weather')) {
|
|
250
|
+
return JSON.stringify({
|
|
251
|
+
tool: 'get_weather',
|
|
252
|
+
parameters: { city: 'Paris', units: 'celsius' },
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return 'No tools needed for this task.';
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async process(prompt: unknown): Promise<string> {
|
|
261
|
+
const response = await super.process(prompt);
|
|
262
|
+
|
|
263
|
+
// Execute any tool calls
|
|
264
|
+
const { results, hasToolCalls } = await this.toolExecutor.executeFromAgentOutput(response);
|
|
265
|
+
|
|
266
|
+
if (hasToolCalls) {
|
|
267
|
+
// Return tool results
|
|
268
|
+
return this.toolExecutor.formatResults(results);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return response;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const model = new ToolAwareModel(executor);
|
|
276
|
+
const result = await model.process('What is the weather in Paris?');
|
|
277
|
+
console.log(result);
|
|
278
|
+
// Tool Results:
|
|
279
|
+
// ✓ get_weather: Temperature in Paris: 22°C
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Agent-Tool Loop
|
|
283
|
+
|
|
284
|
+
Implement a full agent-tool calling loop:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
async function executeWithTools(
|
|
288
|
+
agent: AIModel,
|
|
289
|
+
input: string,
|
|
290
|
+
toolExecutor: ToolExecutor,
|
|
291
|
+
maxIterations: number = 5
|
|
292
|
+
): Promise<string> {
|
|
293
|
+
let currentInput = input;
|
|
294
|
+
let iteration = 0;
|
|
295
|
+
|
|
296
|
+
while (iteration < maxIterations) {
|
|
297
|
+
// Get agent response
|
|
298
|
+
const response = await agent.process(currentInput);
|
|
299
|
+
|
|
300
|
+
// Check for tool calls
|
|
301
|
+
const { results, hasToolCalls } = await toolExecutor.executeFromAgentOutput(response);
|
|
302
|
+
|
|
303
|
+
if (!hasToolCalls) {
|
|
304
|
+
// No more tools, return final response
|
|
305
|
+
return response;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Format tool results as feedback
|
|
309
|
+
const feedback = toolExecutor.formatResults(results);
|
|
310
|
+
|
|
311
|
+
// Continue with tool results
|
|
312
|
+
currentInput = `Previous response: ${response}\n\n${feedback}\n\nContinue your response:`;
|
|
313
|
+
iteration++;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
throw new Error('Max tool calling iterations reached');
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Parallel Tool Execution
|
|
321
|
+
|
|
322
|
+
Execute multiple tools simultaneously:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
const registry = new ToolRegistry();
|
|
326
|
+
// ... register tools ...
|
|
327
|
+
|
|
328
|
+
const tools = [
|
|
329
|
+
{ name: 'get_weather', parameters: { city: 'Paris' } },
|
|
330
|
+
{ name: 'get_weather', parameters: { city: 'London' } },
|
|
331
|
+
{ name: 'get_weather', parameters: { city: 'Tokyo' } },
|
|
332
|
+
];
|
|
333
|
+
|
|
334
|
+
const results = await Promise.all(
|
|
335
|
+
tools.map(({ name, parameters }) => registry.execute(name, parameters))
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
results.forEach((result, i) => {
|
|
339
|
+
console.log(`${tools[i].parameters.city}: ${result.result}`);
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Parameter Validation
|
|
344
|
+
|
|
345
|
+
Tools automatically validate parameters against the JSON Schema:
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
const tool = ToolBuilder.create()
|
|
349
|
+
.withName('send_email')
|
|
350
|
+
.withDescription('Send an email')
|
|
351
|
+
.withParameters({
|
|
352
|
+
type: 'object',
|
|
353
|
+
properties: {
|
|
354
|
+
to: {
|
|
355
|
+
type: 'string',
|
|
356
|
+
format: 'email',
|
|
357
|
+
},
|
|
358
|
+
subject: {
|
|
359
|
+
type: 'string',
|
|
360
|
+
minLength: 1,
|
|
361
|
+
},
|
|
362
|
+
body: {
|
|
363
|
+
type: 'string',
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
required: ['to', 'subject', 'body'],
|
|
367
|
+
})
|
|
368
|
+
.withExecutor(async (params) => {
|
|
369
|
+
// params are validated before reaching here
|
|
370
|
+
return 'Email sent successfully';
|
|
371
|
+
})
|
|
372
|
+
.build();
|
|
373
|
+
|
|
374
|
+
registry.register(tool);
|
|
375
|
+
|
|
376
|
+
// This will fail validation
|
|
377
|
+
try {
|
|
378
|
+
await registry.execute('send_email', {
|
|
379
|
+
to: 'invalid-email', // Not a valid email
|
|
380
|
+
subject: '', // Too short
|
|
381
|
+
});
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.error('Validation failed:', error.message);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Tool Definitions for AI
|
|
388
|
+
|
|
389
|
+
Get tool definitions in a format suitable for AI models:
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const definitions = registry.getToolDefinitions();
|
|
393
|
+
|
|
394
|
+
// Pass to AI model
|
|
395
|
+
const systemPrompt = `
|
|
396
|
+
You are an assistant with access to these tools:
|
|
397
|
+
|
|
398
|
+
${JSON.stringify(definitions, null, 2)}
|
|
399
|
+
|
|
400
|
+
When you need to use a tool, respond with:
|
|
401
|
+
{"tool": "tool_name", "parameters": {...}}
|
|
402
|
+
`;
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Error Handling
|
|
406
|
+
|
|
407
|
+
Tools can throw errors or return error results:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
const riskyTool = ToolBuilder.create()
|
|
411
|
+
.withName('risky_operation')
|
|
412
|
+
.withDescription('May fail')
|
|
413
|
+
.withParameters({ type: 'object' })
|
|
414
|
+
.withExecutor(async (params) => {
|
|
415
|
+
if (Math.random() < 0.5) {
|
|
416
|
+
throw new Error('Operation failed');
|
|
417
|
+
}
|
|
418
|
+
return 'Success';
|
|
419
|
+
})
|
|
420
|
+
.build();
|
|
421
|
+
|
|
422
|
+
const result = await registry.execute('risky_operation', {});
|
|
423
|
+
|
|
424
|
+
if (!result.success) {
|
|
425
|
+
console.error('Tool failed:', result.error?.message);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Context Injection
|
|
430
|
+
|
|
431
|
+
Pass context to tools:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
const contextualTool = ToolBuilder.create()
|
|
435
|
+
.withName('get_user_data')
|
|
436
|
+
.withDescription('Get current user data')
|
|
437
|
+
.withParameters({ type: 'object' })
|
|
438
|
+
.withExecutor(async (params, context) => {
|
|
439
|
+
// Access injected context
|
|
440
|
+
const userId = context?.userId;
|
|
441
|
+
return `Data for user ${userId}`;
|
|
442
|
+
})
|
|
443
|
+
.build();
|
|
444
|
+
|
|
445
|
+
// Execute with context
|
|
446
|
+
const result = await registry.execute(
|
|
447
|
+
'get_user_data',
|
|
448
|
+
{},
|
|
449
|
+
{ userId: '12345' } // Context
|
|
450
|
+
);
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
## Best Practices
|
|
454
|
+
|
|
455
|
+
1. **Clear Descriptions**: Write detailed tool descriptions for the AI
|
|
456
|
+
2. **Strict Schemas**: Use JSON Schema to validate all parameters
|
|
457
|
+
3. **Handle Errors**: Tools should gracefully handle failures
|
|
458
|
+
4. **Timeout Protection**: Set timeouts for long-running operations
|
|
459
|
+
5. **Idempotency**: Make tools idempotent when possible
|
|
460
|
+
6. **Logging**: Log tool executions for debugging
|
|
461
|
+
7. **Security**: Validate and sanitize tool inputs
|
|
462
|
+
8. **Rate Limiting**: Implement rate limits for API tools
|
|
463
|
+
|
|
464
|
+
## Integration with Graph
|
|
465
|
+
|
|
466
|
+
Use tools in graph-based workflows:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
const graph = GraphBuilder.create()
|
|
470
|
+
.addNode('start', NodeType.START)
|
|
471
|
+
.addNode('agent_with_tools', NodeType.AGENT, {
|
|
472
|
+
agentId: 'tool-user',
|
|
473
|
+
})
|
|
474
|
+
.addNode('end', NodeType.END)
|
|
475
|
+
.addEdge('start', 'agent_with_tools')
|
|
476
|
+
.addEdge('agent_with_tools', 'end')
|
|
477
|
+
.build();
|
|
478
|
+
|
|
479
|
+
// Agent has access to tools
|
|
480
|
+
const toolAwareAgent = AgentBuilder.create()
|
|
481
|
+
.withId('tool-user')
|
|
482
|
+
.withRole(role)
|
|
483
|
+
.withModel(new ToolAwareModel(executor))
|
|
484
|
+
.build();
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## Next Steps
|
|
488
|
+
|
|
489
|
+
- See [Memory System](./memory-system.md) for context management
|
|
490
|
+
- See [Graph Execution](./graph-execution.md) for complex workflows
|
|
491
|
+
- See [Examples](./examples.md) for complete implementations
|