@falai/agent 0.9.0-alpha-2 → 0.9.2

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.
Files changed (179) hide show
  1. package/README.md +42 -34
  2. package/dist/cjs/src/core/Agent.d.ts +48 -44
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +151 -1110
  5. package/dist/cjs/src/core/Agent.js.map +1 -1
  6. package/dist/cjs/src/core/ResponseModal.d.ts +211 -0
  7. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
  8. package/dist/cjs/src/core/ResponseModal.js +1394 -0
  9. package/dist/cjs/src/core/ResponseModal.js.map +1 -0
  10. package/dist/cjs/src/core/ResponsePipeline.d.ts +8 -4
  11. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
  12. package/dist/cjs/src/core/ResponsePipeline.js +48 -20
  13. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
  14. package/dist/cjs/src/core/Route.d.ts +12 -5
  15. package/dist/cjs/src/core/Route.d.ts.map +1 -1
  16. package/dist/cjs/src/core/Route.js +26 -5
  17. package/dist/cjs/src/core/Route.js.map +1 -1
  18. package/dist/cjs/src/core/RoutingEngine.d.ts +5 -0
  19. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
  20. package/dist/cjs/src/core/RoutingEngine.js +37 -25
  21. package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
  22. package/dist/cjs/src/core/SessionManager.d.ts +9 -1
  23. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
  24. package/dist/cjs/src/core/SessionManager.js +27 -5
  25. package/dist/cjs/src/core/SessionManager.js.map +1 -1
  26. package/dist/cjs/src/core/Step.d.ts +60 -7
  27. package/dist/cjs/src/core/Step.d.ts.map +1 -1
  28. package/dist/cjs/src/core/Step.js +151 -4
  29. package/dist/cjs/src/core/Step.js.map +1 -1
  30. package/dist/cjs/src/core/ToolManager.d.ts +234 -0
  31. package/dist/cjs/src/core/ToolManager.d.ts.map +1 -0
  32. package/dist/cjs/src/core/ToolManager.js +1117 -0
  33. package/dist/cjs/src/core/ToolManager.js.map +1 -0
  34. package/dist/cjs/src/index.d.ts +5 -4
  35. package/dist/cjs/src/index.d.ts.map +1 -1
  36. package/dist/cjs/src/index.js +11 -3
  37. package/dist/cjs/src/index.js.map +1 -1
  38. package/dist/cjs/src/types/agent.d.ts +2 -1
  39. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  40. package/dist/cjs/src/types/ai.d.ts +1 -1
  41. package/dist/cjs/src/types/ai.d.ts.map +1 -1
  42. package/dist/cjs/src/types/index.d.ts +3 -2
  43. package/dist/cjs/src/types/index.d.ts.map +1 -1
  44. package/dist/cjs/src/types/index.js +3 -1
  45. package/dist/cjs/src/types/index.js.map +1 -1
  46. package/dist/cjs/src/types/route.d.ts +6 -4
  47. package/dist/cjs/src/types/route.d.ts.map +1 -1
  48. package/dist/cjs/src/types/tool.d.ts +84 -14
  49. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  50. package/dist/cjs/src/types/tool.js +13 -0
  51. package/dist/cjs/src/types/tool.js.map +1 -1
  52. package/dist/cjs/src/utils/clone.d.ts.map +1 -1
  53. package/dist/cjs/src/utils/clone.js +0 -4
  54. package/dist/cjs/src/utils/clone.js.map +1 -1
  55. package/dist/cjs/src/utils/history.d.ts +30 -1
  56. package/dist/cjs/src/utils/history.d.ts.map +1 -1
  57. package/dist/cjs/src/utils/history.js +169 -23
  58. package/dist/cjs/src/utils/history.js.map +1 -1
  59. package/dist/cjs/src/utils/index.d.ts +1 -1
  60. package/dist/cjs/src/utils/index.d.ts.map +1 -1
  61. package/dist/cjs/src/utils/index.js +5 -1
  62. package/dist/cjs/src/utils/index.js.map +1 -1
  63. package/dist/src/core/Agent.d.ts +48 -44
  64. package/dist/src/core/Agent.d.ts.map +1 -1
  65. package/dist/src/core/Agent.js +152 -1111
  66. package/dist/src/core/Agent.js.map +1 -1
  67. package/dist/src/core/ResponseModal.d.ts +211 -0
  68. package/dist/src/core/ResponseModal.d.ts.map +1 -0
  69. package/dist/src/core/ResponseModal.js +1389 -0
  70. package/dist/src/core/ResponseModal.js.map +1 -0
  71. package/dist/src/core/ResponsePipeline.d.ts +8 -4
  72. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  73. package/dist/src/core/ResponsePipeline.js +48 -20
  74. package/dist/src/core/ResponsePipeline.js.map +1 -1
  75. package/dist/src/core/Route.d.ts +12 -5
  76. package/dist/src/core/Route.d.ts.map +1 -1
  77. package/dist/src/core/Route.js +26 -5
  78. package/dist/src/core/Route.js.map +1 -1
  79. package/dist/src/core/RoutingEngine.d.ts +5 -0
  80. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  81. package/dist/src/core/RoutingEngine.js +37 -25
  82. package/dist/src/core/RoutingEngine.js.map +1 -1
  83. package/dist/src/core/SessionManager.d.ts +9 -1
  84. package/dist/src/core/SessionManager.d.ts.map +1 -1
  85. package/dist/src/core/SessionManager.js +27 -5
  86. package/dist/src/core/SessionManager.js.map +1 -1
  87. package/dist/src/core/Step.d.ts +60 -7
  88. package/dist/src/core/Step.d.ts.map +1 -1
  89. package/dist/src/core/Step.js +151 -4
  90. package/dist/src/core/Step.js.map +1 -1
  91. package/dist/src/core/ToolManager.d.ts +234 -0
  92. package/dist/src/core/ToolManager.d.ts.map +1 -0
  93. package/dist/src/core/ToolManager.js +1111 -0
  94. package/dist/src/core/ToolManager.js.map +1 -0
  95. package/dist/src/index.d.ts +5 -4
  96. package/dist/src/index.d.ts.map +1 -1
  97. package/dist/src/index.js +3 -2
  98. package/dist/src/index.js.map +1 -1
  99. package/dist/src/types/agent.d.ts +2 -1
  100. package/dist/src/types/agent.d.ts.map +1 -1
  101. package/dist/src/types/ai.d.ts +1 -1
  102. package/dist/src/types/ai.d.ts.map +1 -1
  103. package/dist/src/types/index.d.ts +3 -2
  104. package/dist/src/types/index.d.ts.map +1 -1
  105. package/dist/src/types/index.js +1 -0
  106. package/dist/src/types/index.js.map +1 -1
  107. package/dist/src/types/route.d.ts +6 -4
  108. package/dist/src/types/route.d.ts.map +1 -1
  109. package/dist/src/types/tool.d.ts +84 -14
  110. package/dist/src/types/tool.d.ts.map +1 -1
  111. package/dist/src/types/tool.js +12 -1
  112. package/dist/src/types/tool.js.map +1 -1
  113. package/dist/src/utils/clone.d.ts.map +1 -1
  114. package/dist/src/utils/clone.js +0 -4
  115. package/dist/src/utils/clone.js.map +1 -1
  116. package/dist/src/utils/history.d.ts +30 -1
  117. package/dist/src/utils/history.d.ts.map +1 -1
  118. package/dist/src/utils/history.js +165 -23
  119. package/dist/src/utils/history.js.map +1 -1
  120. package/dist/src/utils/index.d.ts +1 -1
  121. package/dist/src/utils/index.d.ts.map +1 -1
  122. package/dist/src/utils/index.js +1 -1
  123. package/dist/src/utils/index.js.map +1 -1
  124. package/docs/CONTRIBUTING.md +40 -0
  125. package/docs/README.md +14 -6
  126. package/docs/api/README.md +235 -45
  127. package/docs/api/overview.md +140 -33
  128. package/docs/core/agent/session-management.md +152 -5
  129. package/docs/core/ai-integration/response-processing.md +115 -4
  130. package/docs/core/conversation-flows/routes.md +130 -0
  131. package/docs/core/error-handling.md +638 -0
  132. package/docs/core/tools/tool-definition.md +684 -60
  133. package/docs/core/tools/tool-scoping.md +244 -53
  134. package/docs/guides/error-handling-patterns.md +578 -0
  135. package/docs/guides/getting-started/README.md +139 -28
  136. package/docs/guides/migration/README.md +72 -0
  137. package/docs/guides/migration/response-modal-refactor.md +518 -0
  138. package/examples/advanced-patterns/knowledge-based-agent.ts +6 -6
  139. package/examples/advanced-patterns/persistent-onboarding.ts +30 -43
  140. package/examples/advanced-patterns/streaming-responses.ts +169 -96
  141. package/examples/ai-providers/anthropic-integration.ts +9 -5
  142. package/examples/ai-providers/openai-integration.ts +11 -7
  143. package/examples/core-concepts/basic-agent.ts +106 -67
  144. package/examples/core-concepts/modern-streaming-api.ts +309 -0
  145. package/examples/core-concepts/schema-driven-extraction.ts +10 -7
  146. package/examples/core-concepts/session-management.ts +71 -18
  147. package/examples/integrations/healthcare-integration.ts +15 -29
  148. package/examples/integrations/server-session-management.ts +3 -3
  149. package/examples/persistence/memory-sessions.ts +3 -3
  150. package/examples/tools/basic-tools.ts +293 -89
  151. package/examples/tools/data-enrichment-tools.ts +185 -75
  152. package/package.json +1 -1
  153. package/src/core/Agent.ts +190 -1529
  154. package/src/core/ResponseModal.ts +1798 -0
  155. package/src/core/ResponsePipeline.ts +83 -57
  156. package/src/core/Route.ts +39 -12
  157. package/src/core/RoutingEngine.ts +46 -42
  158. package/src/core/SessionManager.ts +39 -7
  159. package/src/core/Step.ts +198 -20
  160. package/src/core/ToolManager.ts +1394 -0
  161. package/src/index.ts +19 -3
  162. package/src/types/agent.ts +2 -1
  163. package/src/types/ai.ts +1 -1
  164. package/src/types/index.ts +13 -2
  165. package/src/types/route.ts +6 -4
  166. package/src/types/tool.ts +116 -25
  167. package/src/utils/clone.ts +6 -8
  168. package/src/utils/history.ts +190 -27
  169. package/src/utils/index.ts +4 -0
  170. package/dist/cjs/src/core/ToolExecutor.d.ts +0 -45
  171. package/dist/cjs/src/core/ToolExecutor.d.ts.map +0 -1
  172. package/dist/cjs/src/core/ToolExecutor.js +0 -84
  173. package/dist/cjs/src/core/ToolExecutor.js.map +0 -1
  174. package/dist/src/core/ToolExecutor.d.ts +0 -45
  175. package/dist/src/core/ToolExecutor.d.ts.map +0 -1
  176. package/dist/src/core/ToolExecutor.js +0 -80
  177. package/dist/src/core/ToolExecutor.js.map +0 -1
  178. package/docs/core/tools/tool-execution.md +0 -815
  179. package/src/core/ToolExecutor.ts +0 -126
@@ -2,18 +2,18 @@
2
2
  * Basic Tools Example
3
3
  *
4
4
  * This example demonstrates the fundamentals of creating and using tools
5
- * in conversational agents. Shows tool definition, execution, error handling,
6
- * and integration with conversation flows.
5
+ * with the unified Tool interface. Shows different patterns for tool creation,
6
+ * execution, error handling, and integration with conversation flows.
7
7
  *
8
8
  * Key concepts:
9
- * - Tool definition with Tool<TContext, TData, TArgs, TResult> interface
10
- * - Tool context and parameters
11
- * - Tool execution in conversation flows
9
+ * - Multiple ways to create and use tools with unified interface
10
+ * - Different tool handler patterns and return types
11
+ * - Tool registration and scoping approaches
12
12
  * - Error handling in tools
13
13
  * - Tool results and data flow
14
14
  */
15
15
 
16
- import { Agent, GeminiProvider, type Tool } from "../../src/index";
16
+ import { Agent, GeminiProvider, Tool, ToolContext } from "../../src/index";
17
17
 
18
18
  // Define data types for our examples
19
19
  interface CalculatorData {
@@ -35,8 +35,9 @@ interface SearchData {
35
35
  source?: string;
36
36
  }
37
37
 
38
- // Example 1: Simple Calculator Tool
39
- const calculatorTool: Tool<unknown, UnifiedToolData, [], string> = {
38
+ // Example 1: Inline Tool Definition (most common pattern)
39
+ // This shows creating a tool object directly without explicit typing
40
+ const calculatorTool = {
40
41
  id: "calculator",
41
42
  name: "Math Calculator",
42
43
  description: "Evaluate mathematical expressions and return results",
@@ -50,40 +51,40 @@ const calculatorTool: Tool<unknown, UnifiedToolData, [], string> = {
50
51
  },
51
52
  required: ["expression"],
52
53
  },
53
- handler: ({ data }) => {
54
- if (!data?.expression) {
54
+ handler: async (context: ToolContext<{ preferences?: { theme: string; language: string } }, UnifiedToolData>, args?: Record<string, unknown>) => {
55
+ const expression = args?.expression as string;
56
+ if (!expression) {
55
57
  throw new Error("No expression provided");
56
58
  }
57
59
 
58
60
  try {
59
61
  // Simple expression evaluation (in production, use a safe math library)
60
62
  // WARNING: eval is unsafe - use a proper math evaluation library in production
61
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
62
- const result = eval(data.expression);
63
+ const result = eval(expression);
63
64
 
64
65
  if (typeof result !== "number" || isNaN(result)) {
65
66
  throw new Error("Invalid calculation result");
66
67
  }
67
68
 
68
69
  return {
69
- data: `The result of ${data.expression} is ${result}`,
70
+ data: `The result of ${expression} is ${result}`,
70
71
  dataUpdate: {
72
+ expression,
71
73
  result,
72
- operation: data.expression,
74
+ operation: expression,
73
75
  },
74
76
  };
75
77
  } catch (error) {
76
78
  throw new Error(
77
- `Error calculating ${data.expression}: ${
78
- error instanceof Error ? error.message : "Unknown error"
79
+ `Error calculating ${expression}: ${error instanceof Error ? error.message : "Unknown error"
79
80
  }`
80
81
  );
81
82
  }
82
83
  },
83
84
  };
84
85
 
85
- // Example 2: Weather Tool with External API Simulation
86
- const weatherTool: Tool<unknown, UnifiedToolData, [], string> = {
86
+ // Example 2: Explicitly Typed Tool (for better IDE support and type safety)
87
+ const weatherTool: Tool<{ preferences?: { theme: string; language: string } }, UnifiedToolData> = {
87
88
  id: "get_weather",
88
89
  name: "Weather Lookup",
89
90
  description: "Get current weather and forecast for a location",
@@ -94,8 +95,9 @@ const weatherTool: Tool<unknown, UnifiedToolData, [], string> = {
94
95
  },
95
96
  required: ["location"],
96
97
  },
97
- handler: async ({ data }) => {
98
- if (!data?.location) {
98
+ handler: async (context, args) => {
99
+ const location = args?.location as string;
100
+ if (!location) {
99
101
  throw new Error("No location provided");
100
102
  }
101
103
 
@@ -125,15 +127,16 @@ const weatherTool: Tool<unknown, UnifiedToolData, [], string> = {
125
127
  },
126
128
  };
127
129
 
128
- const weather = mockWeather[data.location] || {
130
+ const weather = mockWeather[location] || {
129
131
  temp: 70,
130
132
  condition: "Unknown",
131
133
  forecast: "Weather data unavailable",
132
134
  };
133
135
 
134
136
  return {
135
- data: `Weather in ${data.location}: ${weather.temp}°F and ${weather.condition}. ${weather.forecast}`,
137
+ data: `Weather in ${location}: ${weather.temp}°F and ${weather.condition}. ${weather.forecast}`,
136
138
  dataUpdate: {
139
+ location,
137
140
  temperature: weather.temp,
138
141
  condition: weather.condition,
139
142
  forecast: weather.forecast,
@@ -142,8 +145,8 @@ const weatherTool: Tool<unknown, UnifiedToolData, [], string> = {
142
145
  },
143
146
  };
144
147
 
145
- // Example 3: Search Tool with Multiple Results
146
- const searchTool: Tool<unknown, UnifiedToolData, [], string> = {
148
+ // Example 3: Simple Return Value (just return a string for simple tools)
149
+ const searchTool = {
147
150
  id: "web_search",
148
151
  name: "Web Search",
149
152
  description: "Search the web for information on a given query",
@@ -154,8 +157,9 @@ const searchTool: Tool<unknown, UnifiedToolData, [], string> = {
154
157
  },
155
158
  required: ["query"],
156
159
  },
157
- handler: async ({ data }) => {
158
- if (!data?.query) {
160
+ handler: async (context: ToolContext<any, any>, args?: Record<string, unknown>) => {
161
+ const query = args?.query as string;
162
+ if (!query) {
159
163
  throw new Error("No search query provided");
160
164
  }
161
165
 
@@ -184,32 +188,22 @@ const searchTool: Tool<unknown, UnifiedToolData, [], string> = {
184
188
  ],
185
189
  };
186
190
 
187
- const results = mockResults[data.query.toLowerCase()] || [
188
- `Search results for "${data.query}"`,
191
+ const results = mockResults[query.toLowerCase()] || [
192
+ `Search results for "${query}"`,
189
193
  "This is a simulated search result",
190
194
  "In a real implementation, this would connect to a search API",
191
195
  "Such as Google Custom Search, Bing Web Search, or Elasticsearch",
192
196
  ];
193
197
 
194
- return {
195
- data: `Search results for "${data.query}":\n${results
196
- .map((r, i) => `${i + 1}. ${r}`)
197
- .join("\n")}`,
198
- dataUpdate: {
199
- results,
200
- source: "Mock Search API",
201
- },
202
- };
198
+ // Simple return - just the message (no dataUpdate needed for this example)
199
+ return `Search results for "${query}":\n${results
200
+ .map((r, i) => `${i + 1}. ${r}`)
201
+ .join("\n")}`;
203
202
  },
204
203
  };
205
204
 
206
- // Example 4: Tool that Modifies Context (Advanced)
207
- const updatePreferencesTool: Tool<
208
- { preferences?: { theme: string; language: string } },
209
- UnifiedToolData,
210
- [],
211
- string
212
- > = {
205
+ // Example 4: ToolResult Return Type (for complex tools that need context/data updates)
206
+ const updatePreferencesTool = {
213
207
  id: "update_preferences",
214
208
  name: "Update Preferences",
215
209
  description: "Update user preferences and settings",
@@ -220,25 +214,91 @@ const updatePreferencesTool: Tool<
220
214
  language: { type: "string", enum: ["en", "es", "fr"] },
221
215
  },
222
216
  },
223
- handler: ({ context, data }) => {
224
- if (!context) {
217
+ handler: async (toolContext: ToolContext<{ preferences?: { theme: string; language: string } }, UnifiedToolData>, args?: Record<string, unknown>) => {
218
+ if (!toolContext.context) {
225
219
  throw new Error("No context available");
226
220
  }
227
221
 
228
222
  const newPreferences = {
229
- theme: data?.theme || context.preferences?.theme || "light",
230
- language: data?.language || context.preferences?.language || "en",
223
+ theme: (args?.theme as string) || toolContext.context.preferences?.theme || "light",
224
+ language: (args?.language as string) || toolContext.context.preferences?.language || "en",
231
225
  };
232
226
 
227
+ // Return ToolResult for complex updates
233
228
  return {
234
229
  data: `Preferences updated: Theme is now ${newPreferences.theme}, Language is ${newPreferences.language}`,
235
230
  contextUpdate: {
236
231
  preferences: newPreferences,
237
232
  },
233
+ dataUpdate: {
234
+ theme: newPreferences.theme,
235
+ language: newPreferences.language,
236
+ },
238
237
  };
239
238
  },
240
239
  };
241
240
 
241
+ // Example 5: Function-style Tool Creation (for dynamic tools)
242
+ function createValidationTool(fieldName: string) {
243
+ return {
244
+ id: `validate_${fieldName}`,
245
+ name: `${fieldName} Validator`,
246
+ description: `Validate the ${fieldName} field`,
247
+ parameters: {
248
+ type: "object",
249
+ properties: {
250
+ value: { type: "string", description: `Value to validate for ${fieldName}` },
251
+ },
252
+ required: ["value"],
253
+ },
254
+ handler: (context: ToolContext<any, any>, args?: Record<string, unknown>) => {
255
+ const value = args?.value as string;
256
+ const isValid = value && value.length > 0;
257
+
258
+ if (isValid) {
259
+ return `${fieldName} validation passed: ${value}`;
260
+ } else {
261
+ throw new Error(`${fieldName} validation failed: empty or invalid value`);
262
+ }
263
+ },
264
+ };
265
+ }
266
+
267
+ // Example 6: Class-based Tool (for complex stateful tools)
268
+ class ApiCallTool {
269
+ constructor(private baseUrl: string, private apiKey: string) { }
270
+
271
+ createTool() {
272
+ return {
273
+ id: "api_call",
274
+ name: "API Call Tool",
275
+ description: "Make API calls to external services",
276
+ parameters: {
277
+ type: "object",
278
+ properties: {
279
+ endpoint: { type: "string", description: "API endpoint to call" },
280
+ method: { type: "string", enum: ["GET", "POST", "PUT", "DELETE"], default: "GET" },
281
+ },
282
+ required: ["endpoint"],
283
+ },
284
+ handler: async (_context: ToolContext<any, any>, args?: Record<string, unknown>) => {
285
+ const endpoint = args?.endpoint as string;
286
+ const method = (args?.method as string) || "GET";
287
+
288
+ // Simulate API call
289
+ console.log(`Making ${method} request to ${this.baseUrl}${endpoint}`);
290
+
291
+ return {
292
+ data: `API call successful: ${method} ${this.baseUrl}${endpoint}`,
293
+ dataUpdate: {
294
+ source: `API: ${this.baseUrl}${endpoint}`,
295
+ },
296
+ };
297
+ },
298
+ };
299
+ }
300
+ }
301
+
242
302
  // Define unified data schema for all tool interactions
243
303
  interface UnifiedToolData extends CalculatorData, WeatherData, SearchData {
244
304
  theme?: string;
@@ -267,7 +327,7 @@ const unifiedToolSchema = {
267
327
  },
268
328
  };
269
329
 
270
- // Create agent with tools
330
+ // Create agent with tools using new ToolManager API
271
331
  const agent = new Agent<{ preferences?: { theme: string; language: string } }, UnifiedToolData>({
272
332
  name: "ToolBot",
273
333
  description: "An agent demonstrating various tool capabilities",
@@ -279,7 +339,74 @@ const agent = new Agent<{ preferences?: { theme: string; language: string } }, U
279
339
  schema: unifiedToolSchema,
280
340
  });
281
341
 
282
- // Create routes that use different tools
342
+ // Demonstrate ALL the different ways to add tools with the unified interface
343
+
344
+ // Method 1: Direct addTool() - most common for individual tools
345
+ agent.addTool(calculatorTool);
346
+ agent.addTool(weatherTool);
347
+
348
+ // Method 2: tool.register() - register for later reference by ID
349
+ agent.tool.register(searchTool);
350
+ agent.tool.register(updatePreferencesTool);
351
+
352
+ // Method 3: tool.registerMany() - register multiple tools at once
353
+ agent.tool.registerMany([
354
+ createValidationTool("email"),
355
+ createValidationTool("phone"),
356
+ ]);
357
+
358
+ // Method 4: tool.create() - create and register in one step
359
+ const greetingTool = agent.tool.create({
360
+ id: "greeting_tool",
361
+ description: "Generate personalized greetings",
362
+ handler: (context) => {
363
+ const name = context.context?.preferences?.language === "es" ? "Hola" : "Hello";
364
+ return `${name}! How can I help you today?`;
365
+ },
366
+ });
367
+
368
+ // Method 5: tool.createDataEnrichment() - specialized for data enrichment
369
+ const dataEnrichmentTool = agent.tool.createDataEnrichment({
370
+ id: "enrich_user_data",
371
+ fields: ["expression", "location"] as const,
372
+ enricher: async (context, data) => {
373
+ // Enrich the data with additional information that matches UnifiedToolData
374
+ return {
375
+ source: "basic-tools-example", // This matches the 'source' field in UnifiedToolData
376
+ };
377
+ },
378
+ });
379
+
380
+ // Method 6: tool.createValidation() - specialized for validation
381
+ const validationTool = agent.tool.createValidation({
382
+ id: "validate_input",
383
+ fields: ["expression"] as const,
384
+ validator: async (context, data) => {
385
+ if (!data.expression || data.expression.length < 1) {
386
+ return {
387
+ valid: false,
388
+ errors: [{
389
+ field: "expression",
390
+ value: data.expression,
391
+ message: "Expression cannot be empty",
392
+ schemaPath: "expression"
393
+ }],
394
+ warnings: [],
395
+ };
396
+ }
397
+ return {
398
+ valid: true,
399
+ errors: [],
400
+ warnings: [],
401
+ };
402
+ },
403
+ });
404
+
405
+ // Method 7: Class-based tools with addTool
406
+ const apiTool = new ApiCallTool("https://api.example.com", "your-api-key");
407
+ agent.addTool(apiTool.createTool());
408
+
409
+ // Create routes that use different tools (now referencing registered tools by ID)
283
410
  agent.createRoute({
284
411
  title: "Calculator",
285
412
  description: "Mathematical calculations",
@@ -299,7 +426,7 @@ agent.createRoute({
299
426
  id: "calculate",
300
427
  description: "Perform the calculation",
301
428
  prompt: "Let me calculate that for you.",
302
- tools: [calculatorTool],
429
+ tools: ["calculator"], // Reference registered tool by ID
303
430
  requires: ["expression"],
304
431
  },
305
432
  ],
@@ -324,7 +451,7 @@ agent.createRoute({
324
451
  id: "get_weather",
325
452
  description: "Fetch weather data",
326
453
  prompt: "Let me check the weather for you.",
327
- tools: [weatherTool],
454
+ tools: ["get_weather"], // Reference registered tool by ID
328
455
  requires: ["location"],
329
456
  },
330
457
  ],
@@ -349,7 +476,7 @@ agent.createRoute({
349
476
  id: "perform_search",
350
477
  description: "Execute the search",
351
478
  prompt: "Let me search for that information.",
352
- tools: [searchTool],
479
+ tools: ["web_search"], // Reference registered tool by ID
353
480
  requires: ["query"],
354
481
  },
355
482
  ],
@@ -364,7 +491,7 @@ agent.createRoute({
364
491
  id: "update_prefs",
365
492
  description: "Update user preferences",
366
493
  prompt: "I can help you update your preferences.",
367
- tools: [updatePreferencesTool],
494
+ tools: ["update_preferences"], // Reference registered tool by ID
368
495
  },
369
496
  ],
370
497
  });
@@ -495,53 +622,130 @@ async function demonstrateToolDataFlow() {
495
622
  function demonstrateToolPatterns() {
496
623
  console.log("\n=== Tool Definition Patterns ===\n");
497
624
 
498
- console.log("1. Basic Tool Pattern:");
625
+ console.log("1. Multiple Tool Creation Patterns:");
499
626
  console.log(`
500
- const myTool: Tool<ContextType, DataType, [], ResultType> = {
501
- id: "tool_name", // Unique identifier
502
- description: "What this tool does", // AI uses this to decide when to call
503
- parameters: { // JSON Schema for tool parameters
504
- type: "object",
505
- properties: { /* parameter definitions */ }
506
- },
507
- handler: ({ data, context, updateContext }) => {
508
- // Tool logic here - throw errors for failures
627
+ // Pattern A: Inline tool definition (most common)
628
+ const myTool = {
629
+ id: "tool_name",
630
+ description: "What this tool does",
631
+ handler: (context, args) => "Simple result"
632
+ };
633
+
634
+ // Pattern B: Explicitly typed tool (better IDE support)
635
+ const typedTool: Tool<MyContext, MyData> = {
636
+ id: "typed_tool",
637
+ description: "Typed tool with full IntelliSense",
638
+ handler: (context, args) => ({
639
+ data: "Result with updates",
640
+ dataUpdate: { field: "value" },
641
+ contextUpdate: { setting: "new" }
642
+ })
643
+ };
644
+
645
+ // Pattern C: Function factory for dynamic tools
646
+ function createTool(name: string) {
647
+ return {
648
+ id: name,
649
+ handler: () => \`Tool \${name} executed\`
650
+ };
651
+ }
652
+
653
+ // Pattern D: Class-based tools for complex logic
654
+ class MyToolClass {
655
+ createTool() {
509
656
  return {
510
- data: "Result message", // User-facing result
511
- dataUpdate: { /* session data updates */ },
512
- contextUpdate: { /* context updates */ },
657
+ id: "class_tool",
658
+ handler: (context, args) => this.processData(args)
513
659
  };
514
- },
515
- };
660
+ }
661
+
662
+ private processData(args: any) {
663
+ return "Processed data from class method";
664
+ }
665
+ }
516
666
  `);
517
667
 
518
- console.log("2. Tool Context Parameters:");
668
+ console.log("2. Multiple Return Types Supported:");
519
669
  console.log(`
520
- interface ToolContext<TContext, TData> {
521
- context: TContext; // Agent context
522
- updateContext: Function; // Update context function
523
- history; // Conversation history
524
- data: Partial<TData>; // Currently collected data
670
+ // Return Type A: Simple string (for basic tools)
671
+ handler: () => "Simple result message"
672
+
673
+ // Return Type B: ToolResult object (for complex tools)
674
+ handler: (context, args) => ({
675
+ data: "User message",
676
+ dataUpdate: { field: "value" },
677
+ contextUpdate: { setting: "new" }
678
+ })
679
+
680
+ // Return Type C: Promise for async operations
681
+ handler: async (context, args) => {
682
+ const result = await apiCall();
683
+ return \`Got: \${result}\`;
684
+ }
685
+
686
+ // Return Type D: Mixed - can return string OR ToolResult
687
+ handler: (context, args) => {
688
+ if (simple) return "Quick result";
689
+ return { data: "Complex result", dataUpdate: {...} };
525
690
  }
526
691
  `);
527
692
 
528
- console.log("3. Tool Result Structure:");
693
+ console.log("3. All Available Tool Registration Methods:");
529
694
  console.log(`
530
- interface ToolResult {
531
- data: unknown; // Primary result (string for AI)
532
- dataUpdate?: Record<string, unknown>; // Update collected data
533
- contextUpdate?: Record<string, unknown>; // Update agent context
534
- success: boolean; // Whether tool succeeded
535
- error?: string; // Error message if failed
536
- }
695
+ // Method 1: Direct addition (most common)
696
+ agent.addTool(myTool);
697
+
698
+ // Method 2: Register for ID-based reference
699
+ agent.tool.register(myTool);
700
+
701
+ // Method 3: Register multiple tools at once
702
+ agent.tool.registerMany([tool1, tool2, tool3]);
703
+
704
+ // Method 4: Create and register in one step
705
+ const tool = agent.tool.create({
706
+ id: "my_tool",
707
+ handler: () => "result"
708
+ });
709
+
710
+ // Method 5: Specialized data enrichment tools
711
+ const enricher = agent.tool.createDataEnrichment({
712
+ id: "enrich_data",
713
+ fields: ["field1", "field2"],
714
+ enricher: async (context, data) => ({ enriched: true })
715
+ });
716
+
717
+ // Method 6: Specialized validation tools
718
+ const validator = agent.tool.createValidation({
719
+ id: "validate_data",
720
+ fields: ["field1"],
721
+ validator: async (context, data) => data.field1 !== undefined
722
+ });
723
+
724
+ // Method 7: Route-scoped tools
725
+ route.addTool(routeSpecificTool);
726
+
727
+ // Method 8: Step-level tools
728
+ step.addTool(stepSpecificTool);
729
+
730
+ // Usage in steps - multiple patterns
731
+ route.step({
732
+ tools: ["tool_id"], // By ID (from register)
733
+ tools: [toolObject], // Direct object
734
+ tools: ["id1", obj2, "id3"] // Mixed approaches
735
+ });
537
736
  `);
538
737
 
539
- console.log("4. Common Tool Patterns:");
540
- console.log(" • Data Fetching: API calls to external services");
541
- console.log(" • Calculations: Mathematical or logical operations");
542
- console.log(" Data Processing: Transform or analyze collected data");
543
- console.log(" State Updates: Modify conversation state");
544
- console.log(" External Actions: Send emails, create records, etc.");
738
+ console.log("4. Unified Interface Benefits & Flexibility:");
739
+ console.log(" • Single Tool interface supports ALL patterns");
740
+ console.log(" • Choose the right pattern for your use case:");
741
+ console.log(" - Inline objects for simple tools");
742
+ console.log(" - Typed interfaces for complex tools");
743
+ console.log(" - Functions for dynamic tool generation");
744
+ console.log(" - Classes for stateful/complex logic");
745
+ console.log(" • Flexible return types (string OR ToolResult)");
746
+ console.log(" • Optional typing - use as much or as little as needed");
747
+ console.log(" • Consistent handler signature across all patterns");
748
+ console.log(" • Tool resolution across scopes (step → route → agent)");
545
749
  }
546
750
 
547
751
  // Run demonstrations