@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
@@ -13,9 +13,10 @@
13
13
  import {
14
14
  Agent,
15
15
  GeminiProvider,
16
+ Tool,
17
+ ValidationError,
16
18
  type Term,
17
19
  type Guideline,
18
- type Tool,
19
20
  type RouteOptions,
20
21
  } from "../../src/index";
21
22
 
@@ -40,98 +41,71 @@ interface LabData {
40
41
  resultsNeeded: boolean;
41
42
  }
42
43
 
43
- // Define tools using the new Tool interface
44
- const getInsuranceProviders: Tool<HealthcareContext, HealthcareData, [], string[]> = {
44
+ // Define tools using unified Tool interface
45
+ const getInsuranceProvidersTool: Tool<HealthcareContext, HealthcareData> = {
45
46
  id: "healthcare_insurance_providers",
46
47
  description: "Retrieves list of accepted insurance providers",
47
48
  parameters: {
48
49
  type: "object",
49
50
  properties: {},
50
51
  },
51
- handler: () => {
52
+ handler: async (context, args) => {
52
53
  return {
53
- data: ["MegaCare Insurance", "HealthFirst", "WellnessPlus"],
54
+ data: "Available insurance providers: MegaCare Insurance, HealthFirst, WellnessPlus",
54
55
  };
55
56
  },
56
57
  };
57
58
 
58
- const getAvailableSlots: Tool<
59
- HealthcareContext,
60
- HealthcareData,
61
- [],
62
- { date: string; time: string }[]
63
- > = {
59
+ const getAvailableSlotsTool: Tool<HealthcareContext, HealthcareData> = {
64
60
  id: "healthcare_available_slots",
65
61
  description: "Gets available appointment slots",
66
62
  parameters: {
67
63
  type: "object",
68
64
  properties: {},
69
65
  },
70
- handler: () => {
66
+ handler: async (context, args) => {
71
67
  return {
72
- data: [
73
- { date: "2025-10-20", time: "10:00 AM" },
74
- { date: "2025-10-20", time: "2:00 PM" },
75
- { date: "2025-10-21", time: "1:00 PM" },
76
- ],
68
+ data: "Available slots: Oct 20 at 10:00 AM, Oct 20 at 2:00 PM, Oct 21 at 1:00 PM",
77
69
  };
78
70
  },
79
71
  };
80
72
 
81
- const getLabResults: Tool<
82
- HealthcareContext,
83
- HealthcareData,
84
- [],
85
- { report: string; status: string }
86
- > = {
73
+ const getLabResultsTool: Tool<HealthcareContext, HealthcareData> = {
87
74
  id: "healthcare_lab_results",
88
75
  description: "Retrieves patient lab results",
89
76
  parameters: {
90
77
  type: "object",
91
78
  properties: {},
92
79
  },
93
- handler: ({ context, data }) => {
80
+ handler: async (toolContext, args) => {
94
81
  // Tools can access collected data and context
95
- if (data?.testType) {
82
+ if (toolContext.data?.testType) {
96
83
  return {
97
- data: {
98
- report: `${data.testType} results for ${context.patientName}`,
99
- status: "All values within normal range",
100
- },
84
+ data: `${toolContext.data.testType} results for ${toolContext.context.patientName}: All values within normal range`,
101
85
  };
102
86
  }
103
87
 
104
88
  return {
105
- data: {
106
- report: `Lab results for ${context.patientName}`,
107
- status: "All values within normal range",
108
- },
89
+ data: `Lab results for ${toolContext.context.patientName}: All values within normal range`,
109
90
  };
110
91
  },
111
92
  };
112
93
 
113
- const scheduleAppointment: Tool<
114
- HealthcareContext,
115
- HealthcareData,
116
- [],
117
- { confirmation: string }
118
- > = {
94
+ const scheduleAppointmentTool: Tool<HealthcareContext, HealthcareData> = {
119
95
  id: "healthcare_schedule_appointment",
120
96
  description: "Schedules patient appointments",
121
97
  parameters: {
122
98
  type: "object",
123
99
  properties: {},
124
100
  },
125
- handler: ({ data }) => {
101
+ handler: async (context, args) => {
126
102
  // Tools access collected appointment data
127
- if (!data?.preferredDate || !data?.preferredTime) {
128
- return { data: { confirmation: "Please provide appointment details" } };
103
+ if (!context.data?.preferredDate || !context.data?.preferredTime) {
104
+ return { data: "Please provide appointment details" };
129
105
  }
130
106
 
131
107
  return {
132
- data: {
133
- confirmation: `Appointment scheduled for ${data.preferredDate} at ${data.preferredTime}`,
134
- },
108
+ data: `Appointment scheduled for ${context.data.preferredDate} at ${context.data.preferredTime}`,
135
109
  };
136
110
  },
137
111
  };
@@ -175,7 +149,7 @@ const guidelines: Guideline<HealthcareContext>[] = [
175
149
  },
176
150
  ];
177
151
 
178
- const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
152
+ const routes = [
179
153
  {
180
154
  id: "route_schedule_appointment",
181
155
  title: "Schedule Appointment",
@@ -221,27 +195,13 @@ const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
221
195
  id: "schedule_appointment",
222
196
  description: "Schedule the appointment",
223
197
  prompt: "I'll schedule your appointment now.",
224
- tools: [scheduleAppointment], // Use the scheduling tool
198
+ tools: ["healthcare_schedule_appointment"], // Reference by ID
225
199
  requires: ["preferredDate", "preferredTime"],
226
- prepare: getInsuranceProviders, // Use existing tool to prepare insurance info
227
- finalize: {
228
- // Inline tool to handle appointment finalization
229
- id: "finalize_appointment",
230
- description: "Complete the appointment booking process",
231
- parameters: { type: "object", properties: {} },
232
- handler: ({ context, data }) => {
233
- console.log(`āœ… Appointment finalized for ${context.patientName}`);
234
- console.log(`šŸ“… Details: ${JSON.stringify(data, null, 2)}`);
235
-
236
- // Could send confirmation email, update calendar, etc.
237
- return {
238
- data: `Appointment confirmed for ${context.patientName}`,
239
- };
240
- },
241
- },
200
+ prepare: "healthcare_insurance_providers", // Reference by ID
201
+ finalize: "finalize_appointment", // Reference by ID - will be registered later
242
202
  },
243
203
  ],
244
- tools: [getAvailableSlots], // Route-level tools available to all steps
204
+ tools: ["healthcare_available_slots"], // Reference by ID
245
205
  },
246
206
  {
247
207
  id: "route_check_lab_results",
@@ -260,7 +220,7 @@ const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
260
220
  tags: ["escalation"],
261
221
  },
262
222
  ],
263
- tools: [getLabResults], // Route-level tools
223
+ tools: ["healthcare_lab_results"], // Reference by ID
264
224
  },
265
225
  {
266
226
  title: "General Healthcare Questions",
@@ -334,8 +294,87 @@ const agent = new Agent<HealthcareContext, HealthcareData>({
334
294
  // Declarative initialization
335
295
  terms,
336
296
  guidelines,
337
- tools: [getInsuranceProviders], // Agent-level tools
338
- routes,
297
+ });
298
+
299
+ // Demonstrate different tool registration approaches
300
+
301
+ // Method 1: Register tools for ID-based reference in routes
302
+ agent.tool.registerMany([
303
+ getInsuranceProvidersTool,
304
+ getAvailableSlotsTool,
305
+ getLabResultsTool,
306
+ scheduleAppointmentTool,
307
+ ]);
308
+
309
+ // Method 2: Create and register specialized tools
310
+ const appointmentValidator = agent.tool.createValidation({
311
+ id: "validate_appointment",
312
+ fields: ["appointmentType", "preferredDate", "preferredTime"] as const,
313
+ validator: async (context, data) => {
314
+ const errors: ValidationError[] = [];
315
+ if (!data.appointmentType) errors.push({
316
+ field: "appointmentType",
317
+ value: data.appointmentType,
318
+ message: "Appointment type is required",
319
+ schemaPath: "appointmentType"
320
+ });
321
+ if (!data.preferredDate) errors.push({
322
+ field: "preferredDate",
323
+ value: data.preferredDate,
324
+ message: "Preferred date is required",
325
+ schemaPath: "preferredDate"
326
+ });
327
+ if (!data.preferredTime) errors.push({
328
+ field: "preferredTime",
329
+ value: data.preferredTime,
330
+ message: "Preferred time is required",
331
+ schemaPath: "preferredTime"
332
+ });
333
+
334
+ return {
335
+ valid: errors.length === 0,
336
+ errors,
337
+ warnings: [],
338
+ };
339
+ },
340
+ });
341
+
342
+ // Method 3: Create data enrichment tool
343
+ const patientDataEnricher = agent.tool.createDataEnrichment({
344
+ id: "enrich_patient_data",
345
+ fields: ["appointmentType", "symptoms"] as const,
346
+ enricher: async (context, data) => {
347
+ // Add urgency classification based on symptoms - return fields that exist in HealthcareData
348
+ const urgentKeywords = ["chest pain", "difficulty breathing", "severe", "emergency"];
349
+ const hasUrgentSymptoms = data.symptoms && urgentKeywords.some(keyword =>
350
+ data.symptoms!.toLowerCase().includes(keyword)
351
+ );
352
+
353
+ return {
354
+ urgency: hasUrgentSymptoms ? "high" : "medium", // This matches the urgency field in HealthcareData
355
+ };
356
+ },
357
+ });
358
+
359
+ // Method 4: Create tool using tool.create()
360
+ const finalizeAppointmentTool = agent.tool.create({
361
+ id: "finalize_appointment",
362
+ description: "Complete the appointment booking process",
363
+ parameters: { type: "object", properties: {} },
364
+ handler: async (context, args) => {
365
+ console.log(`āœ… Appointment finalized for ${context.context.patientName}`);
366
+ console.log(`šŸ“… Details: ${JSON.stringify(context.data, null, 2)}`);
367
+
368
+ // Could send confirmation email, update calendar, etc.
369
+ return {
370
+ data: `Appointment confirmed for ${context.context.patientName}`,
371
+ };
372
+ },
373
+ });
374
+
375
+ // Add routes after tools are registered
376
+ routes.forEach((route: any) => {
377
+ agent.createRoute(route);
339
378
  });
340
379
 
341
380
  // You can still add more dynamically after construction
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Example: Modern Streaming API
3
+ *
4
+ * This example demonstrates the new agent.stream() method introduced in the
5
+ * ResponseModal refactor. The modern API provides automatic session management
6
+ * and a simpler interface compared to the legacy respondStream() method.
7
+ */
8
+
9
+ import {
10
+ Agent,
11
+ AnthropicProvider,
12
+ OpenAIProvider,
13
+ } from "../../src/index";
14
+
15
+ // Context type for our examples
16
+ interface UserContext {
17
+ userId: string;
18
+ preferences: {
19
+ language?: string;
20
+ verbosity: "concise" | "detailed";
21
+ };
22
+ }
23
+
24
+ async function basicModernStreaming() {
25
+ console.log("\nšŸš€ Example 1: Basic Modern Streaming API\n");
26
+
27
+ const provider = new AnthropicProvider({
28
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
29
+ model: "claude-sonnet-4-5",
30
+ });
31
+
32
+ const agent = new Agent<UserContext, unknown>({
33
+ name: "ModernStreamingAgent",
34
+ description: "Demonstrates the new stream() API",
35
+ context: {
36
+ userId: "user123",
37
+ preferences: {
38
+ language: "English",
39
+ verbosity: "concise",
40
+ },
41
+ },
42
+ provider,
43
+ });
44
+
45
+ try {
46
+ console.log("šŸ“¤ Using modern stream() API...\n");
47
+ console.log("Response: ");
48
+
49
+ // NEW: Simple streaming with automatic session management
50
+ for await (const chunk of agent.stream("What is machine learning?")) {
51
+ if (chunk.delta) {
52
+ process.stdout.write(chunk.delta);
53
+ }
54
+
55
+ if (chunk.done) {
56
+ console.log("\n\nāœ… Stream complete!");
57
+ console.log(`šŸ“Š Session has ${agent.session.getHistory().length} messages`);
58
+ console.log("šŸ’” Session history was automatically managed!");
59
+ }
60
+ }
61
+ } catch (error) {
62
+ console.error("āŒ Error:", error);
63
+ }
64
+ }
65
+
66
+ async function streamingWithOptions() {
67
+ console.log("\nšŸš€ Example 2: Streaming with Options\n");
68
+
69
+ const provider = new OpenAIProvider({
70
+ apiKey: process.env.OPENAI_API_KEY || "",
71
+ model: "gpt-4",
72
+ });
73
+
74
+ const agent = new Agent<UserContext, unknown>({
75
+ name: "OptionsStreamingAgent",
76
+ description: "Demonstrates streaming with options",
77
+ context: {
78
+ userId: "user456",
79
+ preferences: {
80
+ language: "English",
81
+ verbosity: "detailed",
82
+ },
83
+ },
84
+ provider,
85
+ });
86
+
87
+ try {
88
+ console.log("šŸ“¤ Streaming with context override and abort signal...\n");
89
+ console.log("Response: ");
90
+
91
+ // Create abort controller for cancellation
92
+ const abortController = new AbortController();
93
+
94
+ // Cancel after 10 seconds
95
+ setTimeout(() => {
96
+ console.log("\nāš ļø Aborting stream...");
97
+ abortController.abort();
98
+ }, 10000);
99
+
100
+ // Stream with options
101
+ for await (const chunk of agent.stream("Explain quantum computing in detail", {
102
+ contextOverride: {
103
+ preferences: { verbosity: "concise" } // Override to be more concise
104
+ },
105
+ signal: abortController.signal
106
+ })) {
107
+ if (chunk.delta) {
108
+ process.stdout.write(chunk.delta);
109
+ }
110
+
111
+ if (chunk.done) {
112
+ console.log("\n\nāœ… Stream complete!");
113
+ console.log("šŸ’” Context was overridden for this response only");
114
+ clearTimeout();
115
+ }
116
+ }
117
+ } catch (error) {
118
+ if (error instanceof Error && error.name === "AbortError") {
119
+ console.log("\nšŸ›‘ Stream was successfully aborted!");
120
+ } else {
121
+ console.error("āŒ Error:", error);
122
+ }
123
+ }
124
+ }
125
+
126
+ async function conversationFlow() {
127
+ console.log("\nšŸš€ Example 3: Multi-turn Conversation Flow\n");
128
+
129
+ const provider = new AnthropicProvider({
130
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
131
+ model: "claude-sonnet-4-5",
132
+ });
133
+
134
+ const agent = new Agent<UserContext, unknown>({
135
+ name: "ConversationAgent",
136
+ description: "Demonstrates multi-turn conversations",
137
+ context: {
138
+ userId: "user789",
139
+ preferences: {
140
+ language: "English",
141
+ verbosity: "detailed",
142
+ },
143
+ },
144
+ provider,
145
+ });
146
+
147
+ const messages = [
148
+ "What is TypeScript?",
149
+ "How is it different from JavaScript?",
150
+ "Can you give me a simple example?",
151
+ "Thank you for the explanation!"
152
+ ];
153
+
154
+ try {
155
+ console.log("šŸ“¤ Multi-turn conversation with automatic session management...\n");
156
+
157
+ for (let i = 0; i < messages.length; i++) {
158
+ console.log(`\n${"=".repeat(60)}`);
159
+ console.log(`šŸ’¬ Turn ${i + 1}: ${messages[i]}`);
160
+ console.log(`${"=".repeat(60)}`);
161
+ console.log("Response: ");
162
+
163
+ // Each stream() call automatically manages the session
164
+ for await (const chunk of agent.stream(messages[i])) {
165
+ if (chunk.delta) {
166
+ process.stdout.write(chunk.delta);
167
+ }
168
+
169
+ if (chunk.done) {
170
+ console.log(`\nšŸ“Š Session now has ${agent.session.getHistory().length} messages`);
171
+ }
172
+ }
173
+ }
174
+
175
+ console.log("\nāœ… Conversation complete!");
176
+ console.log("šŸ’” All session management was handled automatically");
177
+ console.log(`šŸ“Š Final session has ${agent.session.getHistory().length} messages`);
178
+
179
+ } catch (error) {
180
+ console.error("āŒ Error:", error);
181
+ }
182
+ }
183
+
184
+ async function migrationComparison() {
185
+ console.log("\nšŸš€ Example 4: Migration from respondStream() to stream()\n");
186
+
187
+ const provider = new AnthropicProvider({
188
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
189
+ model: "claude-sonnet-4-5",
190
+ });
191
+
192
+ const agent = new Agent<UserContext, unknown>({
193
+ name: "MigrationAgent",
194
+ description: "Shows migration from old to new API",
195
+ context: {
196
+ userId: "migration-user",
197
+ preferences: {
198
+ language: "English",
199
+ verbosity: "concise",
200
+ },
201
+ },
202
+ provider,
203
+ });
204
+
205
+ const userMessage = "What are the benefits of TypeScript?";
206
+
207
+ try {
208
+ // ========================================================================
209
+ // OLD WAY: respondStream() - Manual session management
210
+ // ========================================================================
211
+ console.log("šŸ”ø OLD WAY: Using respondStream() with manual session management");
212
+ console.log("Code: agent.respondStream({ history: agent.session.getHistory() })");
213
+ console.log("Response: ");
214
+
215
+ // Manual session management required
216
+ await agent.session.addMessage("user", userMessage);
217
+
218
+ let oldResponse = "";
219
+ for await (const chunk of agent.respondStream({
220
+ history: agent.session.getHistory()
221
+ })) {
222
+ if (chunk.delta) {
223
+ process.stdout.write(chunk.delta);
224
+ oldResponse += chunk.delta;
225
+ }
226
+
227
+ if (chunk.done) {
228
+ // Manual history update required
229
+ await agent.session.addMessage("assistant", oldResponse);
230
+ console.log("\n āœ… Manual session update completed");
231
+ }
232
+ }
233
+
234
+ console.log("\n" + "=".repeat(60));
235
+
236
+ // ========================================================================
237
+ // NEW WAY: stream() - Automatic session management
238
+ // ========================================================================
239
+ console.log("šŸ”ø NEW WAY: Using stream() with automatic session management");
240
+ console.log("Code: agent.stream('message')");
241
+ console.log("Response: ");
242
+
243
+ // Automatic session management - just pass the message!
244
+ for await (const chunk of agent.stream("Can you elaborate on the type safety benefits?")) {
245
+ if (chunk.delta) {
246
+ process.stdout.write(chunk.delta);
247
+ }
248
+
249
+ if (chunk.done) {
250
+ console.log("\n āœ… Automatic session update - no manual work needed!");
251
+ }
252
+ }
253
+
254
+ console.log("\nšŸ“Š Migration Benefits:");
255
+ console.log(" āœ… Simpler API: agent.stream('message') vs complex parameters");
256
+ console.log(" āœ… Automatic session management - no manual addMessage() calls");
257
+ console.log(" āœ… Same performance and features as respondStream()");
258
+ console.log(" āœ… Backward compatibility - respondStream() still works");
259
+ console.log(" āœ… Consistent with chat() API patterns");
260
+
261
+ console.log(`\nšŸ“Š Final session has ${agent.session.getHistory().length} messages`);
262
+
263
+ } catch (error) {
264
+ console.error("āŒ Error:", error);
265
+ }
266
+ }
267
+
268
+ async function main() {
269
+ console.log("šŸš€ Modern Streaming API Examples");
270
+ console.log("=".repeat(60));
271
+
272
+ const examples = [
273
+ { name: "Basic Modern Streaming", fn: basicModernStreaming },
274
+ { name: "Streaming with Options", fn: streamingWithOptions },
275
+ { name: "Multi-turn Conversation", fn: conversationFlow },
276
+ { name: "Migration Comparison", fn: migrationComparison },
277
+ ];
278
+
279
+ console.log("\nAvailable Examples:");
280
+ examples.forEach((ex, i) => {
281
+ console.log(` ${i + 1}. ${ex.name}`);
282
+ });
283
+
284
+ console.log("\nšŸ’” Key Benefits of Modern stream() API:");
285
+ console.log(" - Simple interface: agent.stream('message')");
286
+ console.log(" - Automatic session management");
287
+ console.log(" - No manual history updates needed");
288
+ console.log(" - Same performance as respondStream()");
289
+ console.log(" - Full backward compatibility maintained");
290
+
291
+ console.log("\n" + "=".repeat(60));
292
+
293
+ // Run examples if API key is available
294
+ if (process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY) {
295
+ await basicModernStreaming();
296
+ await migrationComparison();
297
+ } else {
298
+ console.log(
299
+ "\nāš ļø Set ANTHROPIC_API_KEY or OPENAI_API_KEY to run examples."
300
+ );
301
+ }
302
+ }
303
+
304
+ // Run if executed directly
305
+ if (import.meta.url === `file://${process.argv[1]}`) {
306
+ main().catch(console.error);
307
+ }
308
+
309
+ export { main };
@@ -23,22 +23,22 @@ interface UserProfileData {
23
23
  newsletterOptIn: boolean;
24
24
  }
25
25
 
26
- // Define a tool that uses the collected data
27
- const saveUserProfile: Tool<unknown, UserProfileData, [], string> = {
26
+ // Define a tool that uses the collected data - using unified Tool interface
27
+ const saveUserProfileTool: Tool<unknown, UserProfileData> = {
28
28
  id: "save_user_profile",
29
29
  description: "Save the collected user profile information",
30
30
  parameters: {
31
31
  type: "object",
32
32
  properties: {},
33
33
  },
34
- handler: ({ data }) => {
35
- console.log("Saving user profile:", data);
34
+ handler: async (context, args) => {
35
+ console.log("Saving user profile:", context.data);
36
36
 
37
37
  // Simulate saving to database
38
- console.log("Profile data:", data);
38
+ console.log("Profile data:", context.data);
39
39
 
40
40
  return {
41
- data: `Profile saved successfully! Welcome ${data?.name}!`,
41
+ data: `Profile saved successfully! Welcome ${context.data?.name}!`,
42
42
  };
43
43
  },
44
44
  };
@@ -99,6 +99,9 @@ const agent = new Agent<unknown, UserProfileData>({
99
99
  schema: userProfileSchema,
100
100
  });
101
101
 
102
+ // Add tool using unified interface
103
+ agent.addTool(saveUserProfileTool);
104
+
102
105
  // Create a route that collects profile information step by step
103
106
  agent.createRoute({
104
107
  title: "User Profile Collection",
@@ -163,7 +166,7 @@ agent.createRoute({
163
166
  description: "Save the collected profile",
164
167
  prompt:
165
168
  "Thanks for providing your information! Let me save your profile.",
166
- tools: [saveUserProfile],
169
+ tools: ["save_user_profile"], // Reference by ID
167
170
  requires: ["name", "email"],
168
171
  },
169
172
  ],