@falai/agent 0.9.0 → 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 (145) hide show
  1. package/README.md +42 -34
  2. package/dist/cjs/src/core/Agent.d.ts +19 -5
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +79 -35
  5. package/dist/cjs/src/core/Agent.js.map +1 -1
  6. package/dist/cjs/src/core/ResponseModal.d.ts +9 -3
  7. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -1
  8. package/dist/cjs/src/core/ResponseModal.js +121 -55
  9. package/dist/cjs/src/core/ResponseModal.js.map +1 -1
  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 +47 -19
  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 +2 -3
  35. package/dist/cjs/src/index.d.ts.map +1 -1
  36. package/dist/cjs/src/index.js +5 -3
  37. package/dist/cjs/src/index.js.map +1 -1
  38. package/dist/cjs/src/types/agent.d.ts +1 -1
  39. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  40. package/dist/cjs/src/types/index.d.ts +3 -2
  41. package/dist/cjs/src/types/index.d.ts.map +1 -1
  42. package/dist/cjs/src/types/index.js +3 -1
  43. package/dist/cjs/src/types/index.js.map +1 -1
  44. package/dist/cjs/src/types/route.d.ts +6 -4
  45. package/dist/cjs/src/types/route.d.ts.map +1 -1
  46. package/dist/cjs/src/types/tool.d.ts +84 -14
  47. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  48. package/dist/cjs/src/types/tool.js +13 -0
  49. package/dist/cjs/src/types/tool.js.map +1 -1
  50. package/dist/src/core/Agent.d.ts +19 -5
  51. package/dist/src/core/Agent.d.ts.map +1 -1
  52. package/dist/src/core/Agent.js +79 -35
  53. package/dist/src/core/Agent.js.map +1 -1
  54. package/dist/src/core/ResponseModal.d.ts +9 -3
  55. package/dist/src/core/ResponseModal.d.ts.map +1 -1
  56. package/dist/src/core/ResponseModal.js +121 -55
  57. package/dist/src/core/ResponseModal.js.map +1 -1
  58. package/dist/src/core/ResponsePipeline.d.ts +8 -4
  59. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  60. package/dist/src/core/ResponsePipeline.js +47 -19
  61. package/dist/src/core/ResponsePipeline.js.map +1 -1
  62. package/dist/src/core/Route.d.ts +12 -5
  63. package/dist/src/core/Route.d.ts.map +1 -1
  64. package/dist/src/core/Route.js +26 -5
  65. package/dist/src/core/Route.js.map +1 -1
  66. package/dist/src/core/RoutingEngine.d.ts +5 -0
  67. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  68. package/dist/src/core/RoutingEngine.js +37 -25
  69. package/dist/src/core/RoutingEngine.js.map +1 -1
  70. package/dist/src/core/SessionManager.d.ts +9 -1
  71. package/dist/src/core/SessionManager.d.ts.map +1 -1
  72. package/dist/src/core/SessionManager.js +27 -5
  73. package/dist/src/core/SessionManager.js.map +1 -1
  74. package/dist/src/core/Step.d.ts +60 -7
  75. package/dist/src/core/Step.d.ts.map +1 -1
  76. package/dist/src/core/Step.js +151 -4
  77. package/dist/src/core/Step.js.map +1 -1
  78. package/dist/src/core/ToolManager.d.ts +234 -0
  79. package/dist/src/core/ToolManager.d.ts.map +1 -0
  80. package/dist/src/core/ToolManager.js +1111 -0
  81. package/dist/src/core/ToolManager.js.map +1 -0
  82. package/dist/src/index.d.ts +2 -3
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +1 -1
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/types/agent.d.ts +1 -1
  87. package/dist/src/types/agent.d.ts.map +1 -1
  88. package/dist/src/types/index.d.ts +3 -2
  89. package/dist/src/types/index.d.ts.map +1 -1
  90. package/dist/src/types/index.js +1 -0
  91. package/dist/src/types/index.js.map +1 -1
  92. package/dist/src/types/route.d.ts +6 -4
  93. package/dist/src/types/route.d.ts.map +1 -1
  94. package/dist/src/types/tool.d.ts +84 -14
  95. package/dist/src/types/tool.d.ts.map +1 -1
  96. package/dist/src/types/tool.js +12 -1
  97. package/dist/src/types/tool.js.map +1 -1
  98. package/docs/CONTRIBUTING.md +40 -0
  99. package/docs/README.md +12 -5
  100. package/docs/api/README.md +75 -45
  101. package/docs/api/overview.md +74 -32
  102. package/docs/core/agent/session-management.md +152 -5
  103. package/docs/core/ai-integration/response-processing.md +115 -4
  104. package/docs/core/conversation-flows/routes.md +130 -0
  105. package/docs/core/error-handling.md +638 -0
  106. package/docs/core/tools/tool-definition.md +684 -60
  107. package/docs/core/tools/tool-scoping.md +244 -53
  108. package/docs/guides/error-handling-patterns.md +578 -0
  109. package/docs/guides/getting-started/README.md +139 -28
  110. package/examples/advanced-patterns/knowledge-based-agent.ts +6 -6
  111. package/examples/advanced-patterns/persistent-onboarding.ts +30 -43
  112. package/examples/ai-providers/anthropic-integration.ts +9 -5
  113. package/examples/ai-providers/openai-integration.ts +11 -7
  114. package/examples/core-concepts/basic-agent.ts +106 -67
  115. package/examples/core-concepts/schema-driven-extraction.ts +10 -7
  116. package/examples/core-concepts/session-management.ts +71 -18
  117. package/examples/integrations/healthcare-integration.ts +15 -29
  118. package/examples/integrations/server-session-management.ts +3 -3
  119. package/examples/persistence/memory-sessions.ts +3 -3
  120. package/examples/tools/basic-tools.ts +293 -89
  121. package/examples/tools/data-enrichment-tools.ts +185 -75
  122. package/package.json +1 -1
  123. package/src/core/Agent.ts +98 -44
  124. package/src/core/ResponseModal.ts +148 -72
  125. package/src/core/ResponsePipeline.ts +82 -56
  126. package/src/core/Route.ts +39 -12
  127. package/src/core/RoutingEngine.ts +46 -42
  128. package/src/core/SessionManager.ts +39 -7
  129. package/src/core/Step.ts +198 -20
  130. package/src/core/ToolManager.ts +1394 -0
  131. package/src/index.ts +8 -3
  132. package/src/types/agent.ts +1 -1
  133. package/src/types/index.ts +13 -2
  134. package/src/types/route.ts +6 -4
  135. package/src/types/tool.ts +116 -25
  136. package/dist/cjs/src/core/ToolExecutor.d.ts +0 -45
  137. package/dist/cjs/src/core/ToolExecutor.d.ts.map +0 -1
  138. package/dist/cjs/src/core/ToolExecutor.js +0 -84
  139. package/dist/cjs/src/core/ToolExecutor.js.map +0 -1
  140. package/dist/src/core/ToolExecutor.d.ts +0 -45
  141. package/dist/src/core/ToolExecutor.d.ts.map +0 -1
  142. package/dist/src/core/ToolExecutor.js +0 -80
  143. package/dist/src/core/ToolExecutor.js.map +0 -1
  144. package/docs/core/tools/tool-execution.md +0 -815
  145. package/src/core/ToolExecutor.ts +0 -126
@@ -131,30 +131,19 @@ interface BookingData {
131
131
  ### Create an Agent with Centralized Data Schema
132
132
 
133
133
  ```typescript
134
- import { Agent, GeminiProvider, type Tool } from "@falai/agent";
135
-
136
- // Booking tool
137
- const checkAvailability: Tool<{}, [], string, BookingData> = {
138
- id: "check_availability",
139
- description: "Check availability and pricing",
140
- parameters: {
141
- type: "object",
142
- properties: {},
143
- },
144
- handler: async (toolContext) => {
145
- // Simulate availability check
146
- const available = Math.random() > 0.2;
147
- const price = Math.floor(Math.random() * 1000) + 500;
134
+ import { Agent, GeminiProvider } from "@falai/agent";
148
135
 
149
- return {
150
- data: available
151
- ? `✅ Available! Estimated cost: $${price}`
152
- : "❌ Not available for those dates",
153
- };
154
- },
155
- };
136
+ // Define data interface first
137
+ interface BookingData {
138
+ destination?: string;
139
+ travelDate?: string;
140
+ travelers?: number;
141
+ budget?: number;
142
+ estimatedPrice?: number;
143
+ availabilityChecked?: boolean;
144
+ }
156
145
 
157
- // Create agent with centralized data schema
146
+ // Create agent with centralized data schema first
158
147
  const agent = new Agent<{}, BookingData>({
159
148
  name: "TravelAgent",
160
149
  provider: new GeminiProvider({
@@ -173,9 +162,6 @@ const agent = new Agent<{}, BookingData>({
173
162
  required: ["destination", "travelers"],
174
163
  },
175
164
 
176
- // Agent-level tools available to all routes
177
- tools: [checkAvailability],
178
-
179
165
  // Agent-level data validation and enrichment
180
166
  hooks: {
181
167
  onDataUpdate: async (data, previousData) => {
@@ -188,6 +174,33 @@ const agent = new Agent<{}, BookingData>({
188
174
  }
189
175
  });
190
176
 
177
+ // Create booking tool using unified Tool interface - simple return value
178
+ agent.addTool({
179
+ id: "check_availability",
180
+ name: "Availability Checker",
181
+ description: "Check travel availability and pricing",
182
+ parameters: {
183
+ type: "object",
184
+ properties: {},
185
+ },
186
+ handler: async ({ context, data, updateData }) => {
187
+ // Simulate availability check using collected data
188
+ const available = Math.random() > 0.2;
189
+ const price = Math.floor(Math.random() * 1000) + 500;
190
+
191
+ // Update data with pricing information using helper method
192
+ await updateData({
193
+ estimatedPrice: price,
194
+ availabilityChecked: true
195
+ });
196
+
197
+ // Return simple string value - unified interface supports both simple and complex returns
198
+ return available
199
+ ? `✅ Available! Estimated cost: $${price} for ${data.travelers} travelers to ${data.destination}`
200
+ : "❌ Not available for those dates. Please try different dates.";
201
+ },
202
+ };
203
+
191
204
  // Routes specify required fields instead of schemas
192
205
  const bookingRoute = agent.createRoute({
193
206
  title: "Travel Booking",
@@ -226,7 +239,7 @@ const askBudget = askTravelers.nextStep({
226
239
 
227
240
  const checkAndBook = askBudget.nextStep({
228
241
  prompt: "Let me check availability for your trip.",
229
- tool: checkAvailability, // Tool accesses complete agent data
242
+ tools: ["check_availability"], // Reference tool by ID
230
243
  requires: ["destination", "travelers"], // Minimum data needed
231
244
  });
232
245
  ```
@@ -245,10 +258,26 @@ async function testBookingAgent() {
245
258
 
246
259
  // Same agent-level schema and configuration
247
260
  schema: agent.schema,
248
- tools: agent.tools,
249
261
  hooks: agent.hooks
250
262
  });
251
263
 
264
+ // Add the same tool to the session agent
265
+ sessionAgent.addTool({
266
+ id: "check_availability",
267
+ name: "Availability Checker",
268
+ description: "Check travel availability and pricing",
269
+ handler: async ({ context, data, updateData }) => {
270
+ const available = Math.random() > 0.2;
271
+ const price = Math.floor(Math.random() * 1000) + 500;
272
+ await updateData({ estimatedPrice: price, availabilityChecked: true });
273
+ return {
274
+ data: available
275
+ ? `✅ Available! Estimated cost: $${price} for ${data.travelers} travelers to ${data.destination}`
276
+ : "❌ Not available for those dates. Please try different dates.",
277
+ };
278
+ },
279
+ });
280
+
252
281
  // Copy the route to the session agent
253
282
  sessionAgent.createRoute(bookingRoute.options);
254
283
 
@@ -270,6 +299,88 @@ async function testBookingAgent() {
270
299
  }
271
300
 
272
301
  testBookingAgent();
302
+
303
+ // Advanced: Show different tool creation approaches
304
+ function demonstrateToolCreationMethods() {
305
+ // Method 1: Direct addition (simplest)
306
+ agent.addTool({
307
+ id: "simple_search",
308
+ description: "Basic search functionality",
309
+ handler: async ({ context, data }, args) => `Found results for: ${args.query}`
310
+ });
311
+
312
+ // Method 2: Registry for reuse
313
+ agent.tool.register({
314
+ id: "reusable_validator",
315
+ description: "Reusable validation tool",
316
+ handler: async ({ context, data }, args) => ({
317
+ data: "Validation complete",
318
+ success: true,
319
+ contextUpdate: { lastValidated: new Date() }
320
+ })
321
+ });
322
+
323
+ // Method 3: Pattern helpers
324
+ const enrichmentTool = agent.tool.createDataEnrichment({
325
+ id: "enrich_booking",
326
+ fields: ['destination', 'travelers'],
327
+ enricher: async (context, data) => ({
328
+ bookingCode: `${data.destination?.slice(0,3).toUpperCase()}-${data.travelers}`,
329
+ estimatedDuration: data.destination === 'Paris' ? '8 hours' : '12 hours'
330
+ })
331
+ });
332
+
333
+ agent.tool.register(enrichmentTool);
334
+ }
335
+
336
+ demonstrateToolCreationMethods();
337
+
338
+ // Advanced: Tools as Step Lifecycle Hooks
339
+ function demonstrateLifecycleHooks() {
340
+ // Create tools for step lifecycle
341
+ agent.addTool({
342
+ id: "prepare_booking",
343
+ description: "Prepare booking context",
344
+ handler: async ({ context, data, updateContext }) => {
345
+ // Enrich context before AI response
346
+ await updateContext({
347
+ bookingStartTime: new Date().toISOString(),
348
+ userTier: 'premium'
349
+ });
350
+ return "Booking preparation complete"; // Simple return
351
+ }
352
+ });
353
+
354
+ agent.addTool({
355
+ id: "finalize_booking",
356
+ description: "Finalize booking process",
357
+ handler: async ({ context, data }) => {
358
+ // Process after AI response
359
+ const confirmationId = await bookingService.reserve(data);
360
+ return {
361
+ data: `Booking reserved with ID: ${confirmationId}`,
362
+ success: true,
363
+ contextUpdate: { lastBookingId: confirmationId }
364
+ }; // Complex ToolResult
365
+ }
366
+ });
367
+
368
+ // Use tools in step lifecycle
369
+ const bookingStep = agent.createRoute({
370
+ title: "Hotel Booking with Lifecycle",
371
+ steps: [{
372
+ id: "process_booking",
373
+ prompt: "Let me process your booking...",
374
+ prepare: "prepare_booking", // Tool executes before AI response
375
+ finalize: "finalize_booking", // Tool executes after AI response
376
+ collect: ["hotelName", "checkInDate"]
377
+ }]
378
+ });
379
+
380
+ console.log("Lifecycle hooks configured with tools");
381
+ }
382
+
383
+ demonstrateLifecycleHooks();
273
384
  ```
274
385
 
275
386
  **Notice how the agent:**
@@ -277,7 +388,7 @@ testBookingAgent();
277
388
  - ✅ Automatically extracted destination from "Paris"
278
389
  - ✅ Understood "Next Friday, 2 people, $2000 budget" as structured data
279
390
  - ✅ Skipped asking for already-known information
280
- - ✅ Used the check_availability tool to provide real assistance
391
+ - ✅ Used the ToolManager API to create and execute tools with simplified context
281
392
 
282
393
  ---
283
394
 
@@ -65,11 +65,11 @@ interface FeedbackData {
65
65
  // ==============================================================================
66
66
 
67
67
  // Tool: Fetch latest company news (context enrichment)
68
- const fetchNewsTool: Tool<CompanyContext, UnifiedData, [], void> = {
68
+ const fetchNewsTool: Tool<CompanyContext, UnifiedData> = {
69
69
  id: "fetch_news",
70
70
  name: "Company News Fetcher",
71
71
  description: "Retrieve latest company news and updates",
72
- handler: () => {
72
+ handler: (context, args) => {
73
73
  // Simulate API call to news service
74
74
  const news = [
75
75
  {
@@ -87,7 +87,7 @@ const fetchNewsTool: Tool<CompanyContext, UnifiedData, [], void> = {
87
87
  console.log(`[Tool] Fetched ${news.length} news articles`);
88
88
 
89
89
  return {
90
- data: undefined,
90
+ data: `Fetched ${news.length} latest news articles`,
91
91
  contextUpdate: {
92
92
  recentNews: news,
93
93
  },
@@ -96,12 +96,12 @@ const fetchNewsTool: Tool<CompanyContext, UnifiedData, [], void> = {
96
96
  };
97
97
 
98
98
  // Tool: Search knowledge base (context enrichment)
99
- const searchKnowledgeTool: Tool<CompanyContext,UnifiedData, [], string> = {
99
+ const searchKnowledgeTool: Tool<CompanyContext, UnifiedData> = {
100
100
  id: "search_knowledge",
101
101
  name: "Knowledge Base Search",
102
102
  description: "Search FAQs and documentation",
103
- handler: (context) => {
104
- const { history } = context;
103
+ handler: (toolContext, args) => {
104
+ const { history } = toolContext;
105
105
 
106
106
  // Get last user message
107
107
  const lastMessage = history
@@ -228,12 +228,7 @@ function createPersistentOnboardingAgent(sessionId: string) {
228
228
  // ============================================================================
229
229
 
230
230
  // OPTION 1: Using contextUpdate in return value
231
- const saveBusinessInfo: Tool<
232
- OnboardingContext,
233
- OnboardingData,
234
- unknown[],
235
- unknown
236
- > = {
231
+ const saveBusinessInfo: Tool<OnboardingContext, OnboardingData> = {
237
232
  id: "save_business_info",
238
233
  name: "Business Info Saver",
239
234
  description: "Save business name and description",
@@ -245,12 +240,13 @@ function createPersistentOnboardingAgent(sessionId: string) {
245
240
  },
246
241
  required: ["name", "description"],
247
242
  },
248
- handler: (toolContext, ...args) => {
249
- const [name, description] = args as [string, string];
243
+ handler: (toolContext, args) => {
244
+ const name = args?.name as string;
245
+ const description = args?.description as string;
250
246
  console.log(`📝 Saving business info: ${name}`);
251
247
 
252
248
  return {
253
- data: true,
249
+ data: "Business information saved successfully",
254
250
  // Context update is automatically persisted via onContextUpdate hook
255
251
  contextUpdate: {
256
252
  collectedData: {
@@ -267,13 +263,8 @@ function createPersistentOnboardingAgent(sessionId: string) {
267
263
  },
268
264
  };
269
265
 
270
- // OPTION 2: Using updateContext method directly
271
- const saveIndustry: Tool<
272
- OnboardingContext,
273
- OnboardingData,
274
- unknown[],
275
- unknown
276
- > = {
266
+ // OPTION 2: Using contextUpdate in return value
267
+ const saveIndustry: Tool<OnboardingContext, OnboardingData> = {
277
268
  id: "save_industry",
278
269
  name: "Industry Classifier",
279
270
  description: "Save business industry",
@@ -284,29 +275,24 @@ function createPersistentOnboardingAgent(sessionId: string) {
284
275
  },
285
276
  required: ["industry"],
286
277
  },
287
- handler: async (toolContext, ...args) => {
288
- const [industry] = args as [string];
278
+ handler: async (toolContext, args) => {
279
+ const industry = args?.industry as string;
289
280
  console.log(`🏭 Saving industry: ${industry}`);
290
281
 
291
- // Direct context update (triggers onContextUpdate hook)
292
- await toolContext.updateContext({
293
- collectedData: {
294
- ...toolContext.context.collectedData,
295
- industry,
282
+ return {
283
+ data: "Industry information saved successfully",
284
+ contextUpdate: {
285
+ collectedData: {
286
+ ...toolContext.context.collectedData,
287
+ industry,
288
+ },
289
+ completedSteps: [...toolContext.context.completedSteps, "industry"],
296
290
  },
297
- completedSteps: [...toolContext.context.completedSteps, "industry"],
298
- });
299
-
300
- return { data: true };
291
+ };
301
292
  },
302
293
  };
303
294
 
304
- const saveContactEmail: Tool<
305
- OnboardingContext,
306
- OnboardingData,
307
- unknown[],
308
- unknown
309
- > = {
295
+ const saveContactEmail: Tool<OnboardingContext, OnboardingData> = {
310
296
  id: "save_contact_email",
311
297
  name: "Contact Email Saver",
312
298
  description: "Save contact email",
@@ -317,19 +303,20 @@ function createPersistentOnboardingAgent(sessionId: string) {
317
303
  },
318
304
  required: ["email"],
319
305
  },
320
- handler: async (toolContext, ...args) => {
321
- const [email] = args as [string];
306
+ handler: async (toolContext, args) => {
307
+ const email = args?.email as string;
322
308
  console.log(`📧 Saving contact email: ${email}`);
323
309
 
324
- await toolContext.updateContext({
325
- collectedData: {
326
- ...toolContext.context.collectedData,
327
- contactEmail: email,
310
+ return {
311
+ data: "Contact email saved successfully",
312
+ contextUpdate: {
313
+ collectedData: {
314
+ ...toolContext.context.collectedData,
315
+ contactEmail: email,
316
+ },
317
+ completedSteps: [...toolContext.context.completedSteps, "contact"],
328
318
  },
329
- completedSteps: [...toolContext.context.completedSteps, "contact"],
330
- });
331
-
332
- return { data: true };
319
+ };
333
320
  },
334
321
  };
335
322
 
@@ -25,14 +25,15 @@ interface ResearchData {
25
25
  }
26
26
 
27
27
  // Research tool that Claude can use
28
- const conductResearch: Tool<unknown, ResearchData, unknown[], unknown> = {
28
+ const conductResearch: Tool<unknown, ResearchData> = {
29
29
  id: "conduct_research",
30
30
  description: "Conduct comprehensive research on a given topic",
31
31
  parameters: {
32
32
  type: "object",
33
33
  properties: {},
34
34
  },
35
- handler: async ({ data }) => {
35
+ handler: async (context, args) => {
36
+ const data = context.data;
36
37
  console.log(
37
38
  `Conducting ${data?.depth} research on: ${data?.topic}`
38
39
  );
@@ -52,12 +53,12 @@ const conductResearch: Tool<unknown, ResearchData, unknown[], unknown> = {
52
53
  sources: ["academic papers", "industry reports", "expert interviews"],
53
54
  };
54
55
 
55
- return Promise.resolve({
56
+ return {
56
57
  data: `Research completed (ID: ${researchId}). ${findings.overview}`,
57
58
  dataUpdate: {
58
59
  researchId,
59
60
  },
60
- });
61
+ };
61
62
  },
62
63
  };
63
64
 
@@ -167,10 +168,13 @@ askFormat.nextStep({
167
168
  data?.topic
168
169
  }" using ${data?.sources || 5} sources. This may take a moment...`;
169
170
  },
170
- tools: [conductResearch],
171
+ tools: ["conduct_research"],
171
172
  requires: ["topic"],
172
173
  });
173
174
 
175
+ // Add the research tool to the agent
176
+ agent.addTool(conductResearch);
177
+
174
178
  // Demonstrate Claude's research capabilities
175
179
  async function demonstrateClaudeResearch() {
176
180
  console.log("=== Claude Research Assistant Demo ===\n");
@@ -25,8 +25,8 @@ interface WeatherData {
25
25
  condition?: string;
26
26
  }
27
27
 
28
- // Define a tool that can access collected data
29
- const getWeather: Tool<CustomerContext, WeatherData, unknown[], unknown> = {
28
+ // Define a tool that can access collected data - using unified Tool interface
29
+ const getWeatherTool: Tool<CustomerContext, WeatherData> = {
30
30
  id: "get_weather",
31
31
  description: "Get current weather for a location",
32
32
  parameters: {
@@ -36,14 +36,15 @@ const getWeather: Tool<CustomerContext, WeatherData, unknown[], unknown> = {
36
36
  },
37
37
  required: ["location"],
38
38
  },
39
- handler: ({ data }, location) => {
39
+ handler: async (context, args) => {
40
40
  // Use data location if available, otherwise use args
41
- const finalLocation = data?.location || location;
41
+ const finalLocation = context.data?.location || args?.location;
42
42
 
43
43
  // Simulate API call
44
44
  return {
45
- data: {
46
- location: finalLocation,
45
+ data: `Weather in ${finalLocation}: 72°F and Sunny`,
46
+ dataUpdate: {
47
+ location: finalLocation as string,
47
48
  temperature: 72,
48
49
  condition: "Sunny",
49
50
  },
@@ -104,6 +105,9 @@ async function main() {
104
105
  },
105
106
  });
106
107
 
108
+ // Add tool using unified interface
109
+ agent.addTool(getWeatherTool);
110
+
107
111
  // Add domain knowledge
108
112
  agent
109
113
  .createTerm({
@@ -139,7 +143,7 @@ async function main() {
139
143
 
140
144
  // Step 2: Get weather data
141
145
  const fetchWeather = askLocation.nextStep({
142
- tools: [getWeather],
146
+ tools: ["get_weather"], // Reference by ID
143
147
  requires: ["location"],
144
148
  });
145
149