@falai/agent 0.9.0-alpha-1 → 0.9.0-alpha-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 (166) hide show
  1. package/README.md +34 -22
  2. package/dist/cjs/src/core/Agent.d.ts +52 -24
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +266 -39
  5. package/dist/cjs/src/core/Agent.js.map +1 -1
  6. package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -1
  7. package/dist/cjs/src/core/PersistenceManager.js +48 -25
  8. package/dist/cjs/src/core/PersistenceManager.js.map +1 -1
  9. package/dist/cjs/src/core/PromptComposer.d.ts +1 -1
  10. package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -1
  11. package/dist/cjs/src/core/PromptComposer.js.map +1 -1
  12. package/dist/cjs/src/core/ResponseEngine.d.ts +13 -12
  13. package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -1
  14. package/dist/cjs/src/core/ResponseEngine.js +4 -4
  15. package/dist/cjs/src/core/ResponseEngine.js.map +1 -1
  16. package/dist/cjs/src/core/ResponsePipeline.d.ts +66 -38
  17. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
  18. package/dist/cjs/src/core/ResponsePipeline.js +71 -3
  19. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
  20. package/dist/cjs/src/core/Route.d.ts +24 -5
  21. package/dist/cjs/src/core/Route.d.ts.map +1 -1
  22. package/dist/cjs/src/core/Route.js +45 -1
  23. package/dist/cjs/src/core/Route.js.map +1 -1
  24. package/dist/cjs/src/core/RoutingEngine.d.ts +31 -6
  25. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
  26. package/dist/cjs/src/core/RoutingEngine.js +113 -9
  27. package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
  28. package/dist/cjs/src/core/SessionManager.d.ts +14 -4
  29. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
  30. package/dist/cjs/src/core/SessionManager.js +25 -5
  31. package/dist/cjs/src/core/SessionManager.js.map +1 -1
  32. package/dist/cjs/src/core/Step.d.ts +10 -10
  33. package/dist/cjs/src/core/Step.d.ts.map +1 -1
  34. package/dist/cjs/src/core/Step.js.map +1 -1
  35. package/dist/cjs/src/core/ToolExecutor.d.ts +4 -2
  36. package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -1
  37. package/dist/cjs/src/core/ToolExecutor.js +13 -3
  38. package/dist/cjs/src/core/ToolExecutor.js.map +1 -1
  39. package/dist/cjs/src/types/agent.d.ts +41 -21
  40. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  41. package/dist/cjs/src/types/agent.js.map +1 -1
  42. package/dist/cjs/src/types/index.d.ts +1 -1
  43. package/dist/cjs/src/types/index.d.ts.map +1 -1
  44. package/dist/cjs/src/types/index.js.map +1 -1
  45. package/dist/cjs/src/types/persistence.d.ts +0 -1
  46. package/dist/cjs/src/types/persistence.d.ts.map +1 -1
  47. package/dist/cjs/src/types/route.d.ts +22 -16
  48. package/dist/cjs/src/types/route.d.ts.map +1 -1
  49. package/dist/cjs/src/types/session.d.ts +6 -11
  50. package/dist/cjs/src/types/session.d.ts.map +1 -1
  51. package/dist/cjs/src/types/tool.d.ts +12 -6
  52. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  53. package/dist/cjs/src/utils/session.d.ts +2 -2
  54. package/dist/cjs/src/utils/session.d.ts.map +1 -1
  55. package/dist/cjs/src/utils/session.js +6 -26
  56. package/dist/cjs/src/utils/session.js.map +1 -1
  57. package/dist/src/core/Agent.d.ts +52 -24
  58. package/dist/src/core/Agent.d.ts.map +1 -1
  59. package/dist/src/core/Agent.js +266 -39
  60. package/dist/src/core/Agent.js.map +1 -1
  61. package/dist/src/core/PersistenceManager.d.ts.map +1 -1
  62. package/dist/src/core/PersistenceManager.js +48 -25
  63. package/dist/src/core/PersistenceManager.js.map +1 -1
  64. package/dist/src/core/PromptComposer.d.ts +1 -1
  65. package/dist/src/core/PromptComposer.d.ts.map +1 -1
  66. package/dist/src/core/PromptComposer.js.map +1 -1
  67. package/dist/src/core/ResponseEngine.d.ts +13 -12
  68. package/dist/src/core/ResponseEngine.d.ts.map +1 -1
  69. package/dist/src/core/ResponseEngine.js +4 -4
  70. package/dist/src/core/ResponseEngine.js.map +1 -1
  71. package/dist/src/core/ResponsePipeline.d.ts +66 -38
  72. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  73. package/dist/src/core/ResponsePipeline.js +71 -3
  74. package/dist/src/core/ResponsePipeline.js.map +1 -1
  75. package/dist/src/core/Route.d.ts +24 -5
  76. package/dist/src/core/Route.d.ts.map +1 -1
  77. package/dist/src/core/Route.js +45 -1
  78. package/dist/src/core/Route.js.map +1 -1
  79. package/dist/src/core/RoutingEngine.d.ts +31 -6
  80. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  81. package/dist/src/core/RoutingEngine.js +113 -9
  82. package/dist/src/core/RoutingEngine.js.map +1 -1
  83. package/dist/src/core/SessionManager.d.ts +14 -4
  84. package/dist/src/core/SessionManager.d.ts.map +1 -1
  85. package/dist/src/core/SessionManager.js +25 -5
  86. package/dist/src/core/SessionManager.js.map +1 -1
  87. package/dist/src/core/Step.d.ts +10 -10
  88. package/dist/src/core/Step.d.ts.map +1 -1
  89. package/dist/src/core/Step.js.map +1 -1
  90. package/dist/src/core/ToolExecutor.d.ts +4 -2
  91. package/dist/src/core/ToolExecutor.d.ts.map +1 -1
  92. package/dist/src/core/ToolExecutor.js +13 -3
  93. package/dist/src/core/ToolExecutor.js.map +1 -1
  94. package/dist/src/types/agent.d.ts +41 -21
  95. package/dist/src/types/agent.d.ts.map +1 -1
  96. package/dist/src/types/agent.js.map +1 -1
  97. package/dist/src/types/index.d.ts +1 -1
  98. package/dist/src/types/index.d.ts.map +1 -1
  99. package/dist/src/types/index.js.map +1 -1
  100. package/dist/src/types/persistence.d.ts +0 -1
  101. package/dist/src/types/persistence.d.ts.map +1 -1
  102. package/dist/src/types/route.d.ts +22 -16
  103. package/dist/src/types/route.d.ts.map +1 -1
  104. package/dist/src/types/session.d.ts +6 -11
  105. package/dist/src/types/session.d.ts.map +1 -1
  106. package/dist/src/types/tool.d.ts +12 -6
  107. package/dist/src/types/tool.d.ts.map +1 -1
  108. package/dist/src/utils/session.d.ts +2 -2
  109. package/dist/src/utils/session.d.ts.map +1 -1
  110. package/dist/src/utils/session.js +6 -26
  111. package/dist/src/utils/session.js.map +1 -1
  112. package/docs/README.md +3 -3
  113. package/docs/api/README.md +35 -4
  114. package/docs/api/overview.md +166 -12
  115. package/docs/core/agent/README.md +162 -17
  116. package/docs/core/agent/context-management.md +39 -15
  117. package/docs/core/agent/session-management.md +49 -16
  118. package/docs/core/ai-integration/prompt-composition.md +38 -14
  119. package/docs/core/ai-integration/response-processing.md +28 -17
  120. package/docs/core/conversation-flows/data-collection.md +103 -25
  121. package/docs/core/conversation-flows/route-dsl.md +45 -22
  122. package/docs/core/conversation-flows/routes.md +74 -18
  123. package/docs/core/conversation-flows/step-transitions.md +3 -3
  124. package/docs/core/conversation-flows/steps.md +39 -15
  125. package/docs/core/routing/intelligent-routing.md +18 -9
  126. package/docs/core/tools/tool-definition.md +8 -8
  127. package/docs/core/tools/tool-execution.md +26 -26
  128. package/docs/core/tools/tool-scoping.md +5 -5
  129. package/docs/guides/getting-started/README.md +54 -32
  130. package/examples/advanced-patterns/knowledge-based-agent.ts +37 -28
  131. package/examples/advanced-patterns/persistent-onboarding.ts +70 -41
  132. package/examples/advanced-patterns/route-lifecycle-hooks.ts +28 -2
  133. package/examples/advanced-patterns/streaming-responses.ts +28 -23
  134. package/examples/ai-providers/anthropic-integration.ts +40 -33
  135. package/examples/ai-providers/openai-integration.ts +25 -25
  136. package/examples/conversation-flows/completion-transitions.ts +36 -32
  137. package/examples/core-concepts/basic-agent.ts +76 -78
  138. package/examples/core-concepts/schema-driven-extraction.ts +20 -16
  139. package/examples/core-concepts/session-management.ts +65 -53
  140. package/examples/integrations/database-integration.ts +49 -34
  141. package/examples/integrations/healthcare-integration.ts +96 -91
  142. package/examples/integrations/search-integration.ts +79 -82
  143. package/examples/integrations/server-session-management.ts +25 -17
  144. package/examples/persistence/database-persistence.ts +61 -45
  145. package/examples/persistence/memory-sessions.ts +52 -63
  146. package/examples/persistence/redis-persistence.ts +81 -95
  147. package/examples/tools/basic-tools.ts +73 -62
  148. package/examples/tools/data-enrichment-tools.ts +52 -44
  149. package/package.json +1 -1
  150. package/src/core/Agent.ts +418 -128
  151. package/src/core/PersistenceManager.ts +51 -27
  152. package/src/core/PromptComposer.ts +1 -1
  153. package/src/core/ResponseEngine.ts +21 -19
  154. package/src/core/ResponsePipeline.ts +174 -59
  155. package/src/core/Route.ts +58 -6
  156. package/src/core/RoutingEngine.ts +174 -27
  157. package/src/core/SessionManager.ts +32 -8
  158. package/src/core/Step.ts +20 -12
  159. package/src/core/ToolExecutor.ts +19 -5
  160. package/src/types/agent.ts +46 -23
  161. package/src/types/index.ts +2 -0
  162. package/src/types/persistence.ts +0 -1
  163. package/src/types/route.ts +22 -16
  164. package/src/types/session.ts +6 -12
  165. package/src/types/tool.ts +15 -9
  166. package/src/utils/session.ts +6 -31
@@ -39,7 +39,7 @@ interface SatisfactionData {
39
39
 
40
40
  // Tools
41
41
 
42
- const getUpcomingSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
42
+ const getUpcomingSlots: Tool<HealthcareContext, HealthcareData, unknown[], unknown> = {
43
43
  id: "get_upcoming_slots",
44
44
  name: "Available Appointment Slots",
45
45
  description: "Get upcoming appointment slots",
@@ -52,7 +52,7 @@ const getUpcomingSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
52
52
  },
53
53
  };
54
54
 
55
- const getLaterSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
55
+ const getLaterSlots: Tool<HealthcareContext, HealthcareData, unknown[], unknown> = {
56
56
  id: "get_later_slots",
57
57
  name: "Extended Appointment Slots",
58
58
  description: "Get later appointment slots",
@@ -67,9 +67,9 @@ const getLaterSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
67
67
 
68
68
  const scheduleAppointment: Tool<
69
69
  HealthcareContext,
70
+ HealthcareData,
70
71
  unknown[],
71
- unknown,
72
- AppointmentData
72
+ unknown
73
73
  > = {
74
74
  id: "schedule_appointment",
75
75
  name: "Appointment Scheduler",
@@ -82,25 +82,24 @@ const scheduleAppointment: Tool<
82
82
  required: ["datetime"],
83
83
  },
84
84
  handler: ({ data }) => {
85
- const appointment = data as Partial<AppointmentData>;
86
- if (!appointment?.preferredDate || !appointment?.preferredTime) {
85
+ if (!data?.preferredDate || !data?.preferredTime) {
87
86
  return {
88
87
  data: "Please specify preferred date and time for the appointment",
89
88
  };
90
89
  }
91
90
  return {
92
- data: `Appointment scheduled for ${appointment.preferredDate} at ${
93
- appointment.preferredTime
94
- } for ${appointment.appointmentReason || "consultation"}`,
91
+ data: `Appointment scheduled for ${data.preferredDate} at ${
92
+ data.preferredTime
93
+ } for ${data.appointmentReason || "consultation"}`,
95
94
  };
96
95
  },
97
96
  };
98
97
 
99
98
  const getLabResults: Tool<
100
99
  HealthcareContext,
100
+ HealthcareData,
101
101
  unknown[],
102
- unknown,
103
- LabResultsData
102
+ unknown
104
103
  > = {
105
104
  id: "get_lab_results",
106
105
  name: "Lab Results Retriever",
@@ -110,10 +109,9 @@ const getLabResults: Tool<
110
109
  properties: {},
111
110
  },
112
111
  handler: ({ context, data }) => {
113
- const labData = data as Partial<LabResultsData>;
114
112
  return {
115
113
  data: {
116
- report: `Lab results for ${labData?.testType || "general"} tests`,
114
+ report: `Lab results for ${data?.testType || "general"} tests`,
117
115
  prognosis: "All tests are within the valid range",
118
116
  patientName: context.patientName,
119
117
  },
@@ -121,18 +119,79 @@ const getLabResults: Tool<
121
119
  },
122
120
  };
123
121
 
122
+ // Define unified healthcare data schema
123
+ interface HealthcareData extends AppointmentData, LabResultsData, SatisfactionData {}
124
+
125
+ const healthcareSchema = {
126
+ type: "object",
127
+ properties: {
128
+ // Appointment fields
129
+ appointmentReason: {
130
+ type: "string",
131
+ description: "Reason for the appointment",
132
+ },
133
+ urgency: {
134
+ type: "string",
135
+ enum: ["low", "medium", "high"],
136
+ default: "medium",
137
+ },
138
+ preferredTime: {
139
+ type: "string",
140
+ description: "Preferred time slot",
141
+ },
142
+ preferredDate: {
143
+ type: "string",
144
+ description: "Preferred date",
145
+ },
146
+ appointmentType: {
147
+ type: "string",
148
+ enum: ["checkup", "consultation", "followup"],
149
+ default: "consultation",
150
+ },
151
+ // Lab results fields
152
+ testType: {
153
+ type: "string",
154
+ description: "Type of lab test",
155
+ },
156
+ testDate: {
157
+ type: "string",
158
+ description: "Date of the lab test",
159
+ },
160
+ resultsNeeded: {
161
+ type: "boolean",
162
+ default: true,
163
+ description: "Whether detailed results are needed",
164
+ },
165
+ // Satisfaction fields
166
+ rating: {
167
+ type: "number",
168
+ description: "Overall satisfaction rating 1-5",
169
+ },
170
+ easeOfScheduling: {
171
+ type: "number",
172
+ description: "Ease of scheduling process 1-5",
173
+ },
174
+ comments: {
175
+ type: "string",
176
+ description: "Optional feedback comments",
177
+ },
178
+ },
179
+ };
180
+
124
181
  function createHealthcareAgent() {
125
182
  const provider = new AnthropicProvider({
126
183
  apiKey: process.env.ANTHROPIC_API_KEY || "test-key",
127
184
  model: "claude-sonnet-4-5",
128
185
  });
129
186
 
130
- const agent = new Agent<HealthcareContext>({
187
+ const agent = new Agent<HealthcareContext, HealthcareData>({
131
188
  name: "Healthcare Agent",
132
189
  description: "Is empathetic and calming to the patient.",
133
190
  identity:
134
191
  "I am the Healthcare Agent, a compassionate AI assistant dedicated to providing excellent patient care. With deep knowledge of medical procedures and a focus on patient comfort, I'm here to help you navigate your healthcare journey with empathy and expertise.",
135
192
  provider: provider,
193
+ // NEW: Agent-level schema
194
+ schema: healthcareSchema,
136
195
 
137
196
  // Knowledge base with healthcare-specific information
138
197
  knowledgeBase: {
@@ -200,7 +259,7 @@ function createHealthcareAgent() {
200
259
 
201
260
  // Create scheduling route with data extraction schema
202
261
  // NEW: Added onComplete to automatically transition to satisfaction survey after booking
203
- const schedulingRoute = agent.createRoute<AppointmentData>({
262
+ const schedulingRoute = agent.createRoute({
204
263
  title: "Schedule an Appointment",
205
264
  description: "Helps the patient find a time for their appointment.",
206
265
  conditions: ["The patient wants to schedule an appointment"],
@@ -224,34 +283,10 @@ function createHealthcareAgent() {
224
283
  description: "Remote healthcare consultation via video call or phone",
225
284
  },
226
285
  ],
227
- schema: {
228
- type: "object",
229
- properties: {
230
- appointmentReason: {
231
- type: "string",
232
- description: "Reason for the appointment",
233
- },
234
- urgency: {
235
- type: "string",
236
- enum: ["low", "medium", "high"],
237
- default: "medium",
238
- },
239
- preferredTime: {
240
- type: "string",
241
- description: "Preferred time slot",
242
- },
243
- preferredDate: {
244
- type: "string",
245
- description: "Preferred date",
246
- },
247
- appointmentType: {
248
- type: "string",
249
- enum: ["checkup", "consultation", "followup"],
250
- default: "consultation",
251
- },
252
- },
253
- required: ["appointmentReason"],
254
- },
286
+ // NEW: Required fields for route completion
287
+ requiredFields: ["appointmentReason"],
288
+ // NEW: Optional fields that enhance the experience
289
+ optionalFields: ["urgency", "preferredTime", "preferredDate", "appointmentType"],
255
290
  // NEW: Automatically collect feedback after successful scheduling
256
291
  onComplete: "Satisfaction Survey",
257
292
  });
@@ -334,29 +369,14 @@ function createHealthcareAgent() {
334
369
  });
335
370
 
336
371
  // Create lab results route with data extraction schema
337
- const labResultsRoute = agent.createRoute<LabResultsData>({
372
+ const labResultsRoute = agent.createRoute({
338
373
  title: "Lab Results",
339
374
  description: "Retrieves the patient's lab results and explains them.",
340
375
  conditions: ["The patient wants to see their lab results"],
341
- schema: {
342
- type: "object",
343
- properties: {
344
- testType: {
345
- type: "string",
346
- description: "Type of lab test",
347
- },
348
- testDate: {
349
- type: "string",
350
- description: "Date of the lab test",
351
- },
352
- resultsNeeded: {
353
- type: "boolean",
354
- default: true,
355
- description: "Whether detailed results are needed",
356
- },
357
- },
358
- required: ["testType"],
359
- },
376
+ // NEW: Required fields for route completion
377
+ requiredFields: ["testType"],
378
+ // NEW: Optional fields
379
+ optionalFields: ["testDate", "resultsNeeded"],
360
380
  });
361
381
 
362
382
  // Step 1: Collect test information
@@ -395,7 +415,7 @@ function createHealthcareAgent() {
395
415
  });
396
416
 
397
417
  // NEW: Satisfaction Survey route - collects feedback after appointment scheduling
398
- const satisfactionRoute = agent.createRoute<SatisfactionData>({
418
+ const satisfactionRoute = agent.createRoute({
399
419
  title: "Satisfaction Survey",
400
420
  description: "Quick satisfaction survey after scheduling",
401
421
  conditions: ["Collect patient satisfaction feedback"],
@@ -426,24 +446,10 @@ function createHealthcareAgent() {
426
446
  positive: "Share with staff as recognition",
427
447
  },
428
448
  },
429
- schema: {
430
- type: "object",
431
- properties: {
432
- rating: {
433
- type: "number",
434
- description: "Overall satisfaction rating 1-5",
435
- },
436
- easeOfScheduling: {
437
- type: "number",
438
- description: "Ease of scheduling process 1-5",
439
- },
440
- comments: {
441
- type: "string",
442
- description: "Optional feedback comments",
443
- },
444
- },
445
- required: ["rating"],
446
- },
449
+ // NEW: Required fields for route completion
450
+ requiredFields: ["rating"],
451
+ // NEW: Optional fields
452
+ optionalFields: ["easeOfScheduling", "comments"],
447
453
  });
448
454
 
449
455
  const askRating = satisfactionRoute.initialStep.nextStep({
@@ -512,14 +518,15 @@ async function main() {
512
518
  // Turn 1: Patient wants to follow up
513
519
  await agent.session.addMessage("user", "Hi, I need to follow up on my visit", "Patient");
514
520
 
521
+ const history = agent.session.getHistory()
515
522
  const response1 = await agent.respond({
516
- history: agent.session.getHistory()
523
+ history,
517
524
  });
518
525
 
519
526
  console.log("Patient: Hi, I need to follow up on my visit");
520
527
  console.log("Agent:", response1.message);
521
528
  console.log("Route:", response1.session?.currentRoute?.title);
522
- console.log("Data:", agent.session.getData<AppointmentData | LabResultsData>());
529
+ console.log("Data:", agent.session.getData());
523
530
 
524
531
  await agent.session.addMessage("assistant", response1.message);
525
532
 
@@ -534,14 +541,12 @@ async function main() {
534
541
  },
535
542
  ];
536
543
 
537
- const response2 = await agent.respond({ history: history2, session });
544
+ const response2 = await agent.respond({ history: history2 });
538
545
  console.log("\nPatient: I need to schedule a checkup for next week");
539
546
  console.log("Agent:", response2.message);
540
547
  console.log("Updated data:", response2.session?.data);
541
548
  console.log("Current step:", response2.session?.currentStep?.id);
542
549
 
543
- // Update session again
544
- session = response2.session!;
545
550
 
546
551
  // NEW: Check if route is complete - will auto-transition to satisfaction survey
547
552
  if (response2.isRouteComplete) {
@@ -563,7 +568,7 @@ async function main() {
563
568
  },
564
569
  ];
565
570
 
566
- const response3 = await agent.respond({ history: history3, session });
571
+ const response3 = await agent.respond({ history: history3 });
567
572
  console.log("\nPatient: Tuesday at 2 PM works for me.");
568
573
  console.log("Agent:", response3.message);
569
574
  console.log("Updated data:", response3.session?.data);
@@ -573,7 +578,7 @@ async function main() {
573
578
  if (response3.isRouteComplete) {
574
579
  console.log("\n✅ Appointment scheduling complete!");
575
580
  await sendAppointmentReminder(
576
- agent.getData(response3.session?.id) as unknown as AppointmentData
581
+ agent.getCollectedData() as HealthcareData
577
582
  );
578
583
  }
579
584
  }
@@ -581,9 +586,9 @@ async function main() {
581
586
 
582
587
  /**
583
588
  * Mock function to send an appointment reminder.
584
- * @param data - The appointment data.
589
+ * @param data - The healthcare data.
585
590
  */
586
- async function sendAppointmentReminder(data: AppointmentData) {
591
+ async function sendAppointmentReminder(data: HealthcareData) {
587
592
  console.log("\n" + "=".repeat(60));
588
593
  console.log("🚀 Sending Appointment Reminder...");
589
594
  console.log("=".repeat(60));
@@ -88,8 +88,38 @@ async function example() {
88
88
  // Initialize indices
89
89
  await adapter.initialize();
90
90
 
91
+ // Define complaint schema
92
+ const complaintSchema = {
93
+ type: "object",
94
+ properties: {
95
+ category: {
96
+ type: "string",
97
+ description: "Complaint category",
98
+ },
99
+ severity: {
100
+ type: "string",
101
+ enum: ["low", "medium", "high", "critical"],
102
+ default: "medium",
103
+ description: "Severity level",
104
+ },
105
+ description: {
106
+ type: "string",
107
+ description: "Detailed complaint description",
108
+ },
109
+ affectedService: {
110
+ type: "string",
111
+ description: "Which service is affected",
112
+ },
113
+ requestedResolution: {
114
+ type: "string",
115
+ description: "What resolution the customer wants",
116
+ },
117
+ },
118
+ required: ["category", "severity", "description"],
119
+ };
120
+
91
121
  // Create agent with OpenSearch persistence
92
- const agent = new Agent<ConversationContext>({
122
+ const agent = new Agent<ConversationContext, ComplaintData>({
93
123
  name: "Customer Service Agent",
94
124
  description: "Handle customer complaints with full-text search",
95
125
  goal: "Resolve customer issues efficiently",
@@ -102,6 +132,8 @@ async function example() {
102
132
  userName: "Alice",
103
133
  department: "customer_service",
104
134
  },
135
+ // NEW: Agent-level schema
136
+ schema: complaintSchema,
105
137
  persistence: {
106
138
  adapter,
107
139
  autoSave: true, // Auto-save session step with collected data
@@ -110,7 +142,7 @@ async function example() {
110
142
  });
111
143
 
112
144
  // Create complaint handling route
113
- const complaintRoute = agent.createRoute<ComplaintData>({
145
+ const complaintRoute = agent.createRoute({
114
146
  title: "Handle Customer Complaint",
115
147
  description: "Process and resolve customer complaints",
116
148
  conditions: [
@@ -118,34 +150,10 @@ async function example() {
118
150
  "User reports an issue or problem",
119
151
  "User is dissatisfied",
120
152
  ],
121
- schema: {
122
- type: "object",
123
- properties: {
124
- category: {
125
- type: "string",
126
- description: "Complaint category",
127
- },
128
- severity: {
129
- type: "string",
130
- enum: ["low", "medium", "high", "critical"],
131
- default: "medium",
132
- description: "Severity level",
133
- },
134
- description: {
135
- type: "string",
136
- description: "Detailed complaint description",
137
- },
138
- affectedService: {
139
- type: "string",
140
- description: "Which service is affected",
141
- },
142
- requestedResolution: {
143
- type: "string",
144
- description: "What resolution the customer wants",
145
- },
146
- },
147
- required: ["category", "severity", "description"],
148
- },
153
+ // NEW: Required fields for route completion
154
+ requiredFields: ["category", "severity", "description"],
155
+ // NEW: Optional fields that enhance the experience
156
+ optionalFields: ["affectedService", "requestedResolution"],
149
157
  });
150
158
 
151
159
  // Step flow
@@ -177,7 +185,7 @@ async function example() {
177
185
  console.log("✨ Session ready:", agent.session.id);
178
186
 
179
187
  // Set initial data
180
- await agent.session.setData<ComplaintData>({ severity: "medium" });
188
+ await agent.session.setData({ severity: "medium" });
181
189
 
182
190
  // Turn 1
183
191
  console.log("\n--- Turn 1 ---");
@@ -193,7 +201,7 @@ async function example() {
193
201
  });
194
202
 
195
203
  console.log("🤖 Agent:", response1.message);
196
- console.log("📊 Data:", agent.session.getData<ComplaintData>());
204
+ console.log("📊 Data:", agent.session.getData());
197
205
 
198
206
  await agent.session.addMessage("assistant", response1.message);
199
207
 
@@ -211,20 +219,20 @@ async function example() {
211
219
  });
212
220
 
213
221
  console.log("🤖 Agent:", response2.message);
214
- console.log("📊 Data:", agent.session.getData<ComplaintData>());
222
+ console.log("📊 Data:", agent.session.getData());
215
223
 
216
224
  await agent.session.addMessage("assistant", response2.message);
217
225
 
218
226
  if (response2.isRouteComplete) {
219
227
  console.log("\n✅ Complaint route complete!");
220
- await createSupportTicket(agent.session.getData<ComplaintData>() as ComplaintData);
228
+ await createSupportTicket(agent.session.getData() as ComplaintData);
221
229
  }
222
230
 
223
231
  // Demonstrate session recovery with new agent instance
224
232
  console.log("\n--- Session Recovery Example ---");
225
233
  const sessionId = agent.session.id;
226
234
 
227
- const recoveredAgent = new Agent<ConversationContext>({
235
+ const recoveredAgent = new Agent<ConversationContext, ComplaintData>({
228
236
  name: "Customer Service Agent",
229
237
  provider: new GeminiProvider({
230
238
  apiKey: process.env.GEMINI_API_KEY!,
@@ -243,7 +251,7 @@ async function example() {
243
251
  });
244
252
 
245
253
  // Recreate the same route on recovered agent
246
- recoveredAgent.createRoute<ComplaintData>({
254
+ recoveredAgent.createRoute({
247
255
  title: "Handle Customer Complaint",
248
256
  description: "Process and resolve customer complaints",
249
257
  conditions: [
@@ -251,28 +259,16 @@ async function example() {
251
259
  "User reports an issue or problem",
252
260
  "User is dissatisfied",
253
261
  ],
254
- schema: {
255
- type: "object",
256
- properties: {
257
- category: { type: "string", description: "Complaint category" },
258
- severity: {
259
- type: "string",
260
- enum: ["low", "medium", "high", "critical"],
261
- default: "medium",
262
- description: "Severity level",
263
- },
264
- description: { type: "string", description: "Detailed complaint description" },
265
- affectedService: { type: "string", description: "Which service is affected" },
266
- requestedResolution: { type: "string", description: "What resolution the customer wants" },
267
- },
268
- required: ["category", "severity", "description"],
269
- },
262
+ // NEW: Required fields for route completion
263
+ requiredFields: ["category", "severity", "description"],
264
+ // NEW: Optional fields
265
+ optionalFields: ["affectedService", "requestedResolution"],
270
266
  });
271
267
 
272
268
  console.log("📥 Recovered session:", {
273
269
  sessionId: recoveredAgent.session.id,
274
270
  historyLength: recoveredAgent.session.getHistory().length,
275
- data: recoveredAgent.session.getData<ComplaintData>(),
271
+ data: recoveredAgent.session.getData(),
276
272
  });
277
273
 
278
274
  // Demonstrate full-text search
@@ -344,12 +340,27 @@ async function analyticsExample() {
344
340
  tags: string[];
345
341
  }
346
342
 
347
- const agent = new Agent<ConversationContext>({
343
+ const ticketSchema = {
344
+ type: "object",
345
+ properties: {
346
+ ticketType: { type: "string" },
347
+ priority: { type: "string" },
348
+ tags: {
349
+ type: "array",
350
+ items: { type: "string" },
351
+ },
352
+ },
353
+ required: ["ticketType", "priority"],
354
+ };
355
+
356
+ const agent = new Agent<ConversationContext, TicketData>({
348
357
  name: "Support Analyzer",
349
358
  provider: new GeminiProvider({
350
359
  apiKey: process.env.GEMINI_API_KEY!,
351
360
  model: "models/gemini-2.5-flash",
352
361
  }),
362
+ // NEW: Agent-level schema
363
+ schema: ticketSchema,
353
364
  persistence: {
354
365
  adapter,
355
366
  autoSave: true,
@@ -357,20 +368,12 @@ async function analyticsExample() {
357
368
  },
358
369
  });
359
370
 
360
- const ticketRoute = agent.createRoute<TicketData>({
371
+ const ticketRoute = agent.createRoute({
361
372
  title: "Analyze Support Ticket",
362
- schema: {
363
- type: "object",
364
- properties: {
365
- ticketType: { type: "string" },
366
- priority: { type: "string" },
367
- tags: {
368
- type: "array",
369
- items: { type: "string" },
370
- },
371
- },
372
- required: ["ticketType", "priority"],
373
- },
373
+ // NEW: Required fields for route completion
374
+ requiredFields: ["ticketType", "priority"],
375
+ // NEW: Optional fields
376
+ optionalFields: ["tags"],
374
377
  });
375
378
 
376
379
  ticketRoute.initialStep.nextStep({
@@ -380,7 +383,7 @@ async function analyticsExample() {
380
383
 
381
384
  // Create multiple sessions with different agents
382
385
  for (let i = 0; i < 3; i++) {
383
- const sessionAgent = new Agent<AnalyticsContext>({
386
+ const sessionAgent = new Agent<AnalyticsContext, TicketData>({
384
387
  name: "Support Analyzer",
385
388
  provider: new GeminiProvider({
386
389
  apiKey: process.env.GEMINI_API_KEY!,
@@ -390,6 +393,8 @@ async function analyticsExample() {
390
393
  userId: "analyst_001",
391
394
  department: "support",
392
395
  },
396
+ // NEW: Agent-level schema
397
+ schema: ticketSchema,
393
398
  persistence: {
394
399
  adapter: new OpenSearchAdapter<AnalyticsContext>(client),
395
400
  autoSave: true,
@@ -397,20 +402,12 @@ async function analyticsExample() {
397
402
  });
398
403
 
399
404
  // Create the ticket route on each agent
400
- sessionAgent.createRoute<TicketData>({
405
+ sessionAgent.createRoute({
401
406
  title: "Analyze Support Ticket",
402
- schema: {
403
- type: "object",
404
- properties: {
405
- ticketType: { type: "string" },
406
- priority: { type: "string" },
407
- tags: {
408
- type: "array",
409
- items: { type: "string" },
410
- },
411
- },
412
- required: ["ticketType", "priority"],
413
- },
407
+ // NEW: Required fields for route completion
408
+ requiredFields: ["ticketType", "priority"],
409
+ // NEW: Optional fields
410
+ optionalFields: ["tags"],
414
411
  });
415
412
 
416
413
  const ticketContent = `Support ticket ${i + 1}: ${
@@ -474,7 +471,7 @@ async function timeSeriesExample() {
474
471
  const adapter = new OpenSearchAdapter<ConversationContext>(client);
475
472
  await adapter.initialize();
476
473
 
477
- new Agent<ConversationContext>({
474
+ new Agent<ConversationContext, unknown>({
478
475
  name: "Metrics Agent",
479
476
  provider: new GeminiProvider({
480
477
  apiKey: process.env.GEMINI_API_KEY!,