@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
@@ -31,7 +31,7 @@ interface BookingData {
31
31
  }
32
32
 
33
33
  // Booking confirmation tool
34
- const confirmBooking: Tool<unknown, [], string, BookingData> = {
34
+ const confirmBooking: Tool<unknown, BookingData, [], string> = {
35
35
  id: "confirm_booking",
36
36
  description: "Confirm the hotel booking with all details",
37
37
  parameters: {
@@ -56,15 +56,33 @@ const confirmBooking: Tool<unknown, [], string, BookingData> = {
56
56
  },
57
57
  };
58
58
 
59
+ // Define booking schema
60
+ const bookingSchema = {
61
+ type: "object",
62
+ properties: {
63
+ customerName: { type: "string" },
64
+ hotelName: { type: "string" },
65
+ checkInDate: { type: "string" },
66
+ checkOutDate: { type: "string" },
67
+ guests: { type: "number", minimum: 1, maximum: 10 },
68
+ roomType: { type: "string", enum: ["standard", "deluxe", "suite"] },
69
+ specialRequests: { type: "string" },
70
+ bookingId: { type: "string" },
71
+ },
72
+ required: ["customerName", "hotelName", "checkInDate", "checkOutDate", "guests"],
73
+ };
74
+
59
75
  // Function to create agent for each request (server pattern)
60
76
  function createBookingAgent(sessionId?: string) {
61
- return new Agent({
77
+ return new Agent<unknown, BookingData>({
62
78
  name: "Hotel Booking Assistant",
63
79
  description: "Help customers book hotel rooms",
64
80
  provider: new OpenAIProvider({
65
81
  apiKey: process.env.OPENAI_API_KEY!,
66
82
  model: "gpt-4",
67
83
  }),
84
+ // NEW: Agent-level schema
85
+ schema: bookingSchema,
68
86
  persistence: {
69
87
  adapter: new MemoryAdapter(), // In production: RedisAdapter, PrismaAdapter, etc.
70
88
  autoSave: true,
@@ -75,20 +93,10 @@ function createBookingAgent(sessionId?: string) {
75
93
  title: "Hotel Booking",
76
94
  description: "Collect booking details and confirm reservation",
77
95
  conditions: ["User wants to book a hotel room"],
78
- schema: {
79
- type: "object",
80
- properties: {
81
- customerName: { type: "string" },
82
- hotelName: { type: "string" },
83
- checkInDate: { type: "string" },
84
- checkOutDate: { type: "string" },
85
- guests: { type: "number", minimum: 1, maximum: 10 },
86
- roomType: { type: "string", enum: ["standard", "deluxe", "suite"] },
87
- specialRequests: { type: "string" },
88
- bookingId: { type: "string" },
89
- },
90
- required: ["customerName", "hotelName", "checkInDate", "checkOutDate", "guests"],
91
- },
96
+ // NEW: Required fields for route completion
97
+ requiredFields: ["customerName", "hotelName", "checkInDate", "checkOutDate", "guests"],
98
+ // NEW: Optional fields that enhance the experience
99
+ optionalFields: ["roomType", "specialRequests", "bookingId"],
92
100
  steps: [
93
101
  {
94
102
  id: "ask_name",
@@ -179,7 +187,7 @@ async function handleChatRequest(request: ChatRequest): Promise<ChatResponse> {
179
187
  message: response.message,
180
188
  sessionId: agent.session.id!,
181
189
  isComplete: response.isRouteComplete!,
182
- data: agent.session.getData<BookingData>(),
190
+ data: agent.session.getData(),
183
191
  };
184
192
  }
185
193
 
@@ -84,7 +84,7 @@ async function example() {
84
84
  */
85
85
  const sessionId = "session_user123_booking"; // Could be from request params
86
86
 
87
- const agent = new Agent<ConversationContext>({
87
+ const agent = new Agent<ConversationContext, FlightBookingData>({
88
88
  name: "Travel Assistant",
89
89
  description: "A helpful travel booking assistant",
90
90
  goal: "Help users book flights with ease",
@@ -100,19 +100,6 @@ async function example() {
100
100
  adapter: new PrismaAdapter<ConversationContext>({ prisma }),
101
101
  autoSave: true, // Auto-saves session after each response
102
102
  },
103
- sessionId, // ✨ Agent will automatically load or create this session
104
- });
105
-
106
- /**
107
- * Create a route with data extraction schema
108
- */
109
- const flightRoute = agent.createRoute<FlightBookingData>({
110
- title: "Book a Flight",
111
- description: "Help user book a flight ticket",
112
- conditions: [
113
- "User wants to book a flight",
114
- "User mentions travel, flying, or booking tickets",
115
- ],
116
103
  schema: {
117
104
  type: "object",
118
105
  properties: {
@@ -143,6 +130,19 @@ async function example() {
143
130
  },
144
131
  required: ["destination", "departureDate", "passengers", "cabinClass"],
145
132
  },
133
+ sessionId, // ✨ Agent will automatically load or create this session
134
+ });
135
+
136
+ /**
137
+ * Create a route with data extraction schema
138
+ */
139
+ const flightRoute = agent.createRoute({
140
+ title: "Book a Flight",
141
+ description: "Help user book a flight ticket",
142
+ conditions: [
143
+ "User wants to book a flight",
144
+ "User mentions travel, flying, or booking tickets",
145
+ ],
146
146
  });
147
147
 
148
148
  // Step flow with smart data collecting and custom IDs
@@ -194,8 +194,8 @@ async function example() {
194
194
  console.log("📜 Conversation history:", agent.session.getHistory().length, "messages");
195
195
 
196
196
  // Set some initial data if this is a new session
197
- if (!agent.session.getData<FlightBookingData>()?.cabinClass) {
198
- await agent.session.setData<FlightBookingData>({ cabinClass: "economy" });
197
+ if (!agent.session.getData()?.cabinClass) {
198
+ await agent.session.setData({ cabinClass: "economy" });
199
199
  }
200
200
 
201
201
  /**
@@ -216,7 +216,7 @@ async function example() {
216
216
  sessionId: agent.session.id,
217
217
  currentRoute: response1.session?.currentRoute?.title,
218
218
  currentStepId: response1.session?.currentStep?.id,
219
- data: agent.session.getData<FlightBookingData>(),
219
+ data: agent.session.getData(),
220
220
  });
221
221
 
222
222
  // Add agent response to session history
@@ -237,14 +237,14 @@ async function example() {
237
237
  console.log("📊 Session after turn 2:", {
238
238
  currentRoute: response2.session?.currentRoute?.title,
239
239
  currentStep: response2.session?.currentStep?.id,
240
- data: agent.session.getData<FlightBookingData>(),
240
+ data: agent.session.getData(),
241
241
  });
242
242
 
243
243
  await agent.session.addMessage("assistant", response2.message);
244
244
 
245
245
  if (response2.isRouteComplete) {
246
246
  console.log("\n✅ Flight booking complete!");
247
- await sendFlightConfirmation(agent.session.getData<FlightBookingData>());
247
+ await sendFlightConfirmation(agent.session.getData());
248
248
  }
249
249
 
250
250
  /**
@@ -252,7 +252,7 @@ async function example() {
252
252
  */
253
253
  console.log("\n--- Session Recovery (New Agent Instance) ---");
254
254
 
255
- const newAgent = new Agent<ConversationContext>({
255
+ const newAgent = new Agent<ConversationContext, FlightBookingData>({
256
256
  name: "Travel Assistant",
257
257
  provider: new GeminiProvider({
258
258
  apiKey: process.env.GEMINI_API_KEY!,
@@ -262,6 +262,18 @@ async function example() {
262
262
  userId: "user_123",
263
263
  userName: "Alice",
264
264
  },
265
+ // NEW: Agent-level schema (same as original agent)
266
+ schema: {
267
+ type: "object",
268
+ properties: {
269
+ destination: { type: "string" },
270
+ departureDate: { type: "string" },
271
+ returnDate: { type: "string" },
272
+ passengers: { type: "number", minimum: 1, maximum: 9 },
273
+ cabinClass: { type: "string", enum: ["economy", "premium", "business", "first"] },
274
+ },
275
+ required: ["destination", "departureDate", "passengers", "cabinClass"],
276
+ },
265
277
  persistence: {
266
278
  adapter: new PrismaAdapter<ConversationContext>({ prisma }),
267
279
  },
@@ -271,7 +283,7 @@ async function example() {
271
283
  console.log("📥 Recovered session:", {
272
284
  sessionId: newAgent.session.id,
273
285
  historyLength: newAgent.session.getHistory().length,
274
- data: newAgent.session.getData<FlightBookingData>(),
286
+ data: newAgent.session.getData(),
275
287
  });
276
288
 
277
289
  /**
@@ -308,7 +320,7 @@ async function advancedExample() {
308
320
  };
309
321
  }
310
322
 
311
- const agent = new Agent<UserContext>({
323
+ const agent = new Agent<UserContext, OnboardingData>({
312
324
  name: "Onboarding Assistant",
313
325
  description: "Help new users get started",
314
326
  provider: new GeminiProvider({
@@ -357,12 +369,6 @@ async function advancedExample() {
357
369
  autoSave: true,
358
370
  },
359
371
  sessionId,
360
- });
361
-
362
- // Create onboarding route
363
- const onboardingRoute = agent.createRoute<OnboardingData>({
364
- title: "User Onboarding",
365
- description: "Collect user information for account setup",
366
372
  schema: {
367
373
  type: "object",
368
374
  properties: {
@@ -375,6 +381,12 @@ async function advancedExample() {
375
381
  },
376
382
  });
377
383
 
384
+ // Create onboarding route
385
+ const onboardingRoute = agent.createRoute({
386
+ title: "User Onboarding",
387
+ description: "Collect user information for account setup",
388
+ });
389
+
378
390
  onboardingRoute.initialStep
379
391
  .nextStep({
380
392
  prompt: "Welcome and ask for name",
@@ -413,7 +425,7 @@ async function advancedExample() {
413
425
  });
414
426
 
415
427
  console.log("🤖 Agent:", response.message);
416
- console.log("📊 Data collected:", agent.session.getData<OnboardingData>());
428
+ console.log("📊 Data collected:", agent.session.getData());
417
429
 
418
430
  // Add to session history for future responses
419
431
  await agent.session.addMessage("user", "I'd like to create an account");
@@ -427,12 +439,12 @@ async function advancedExample() {
427
439
  });
428
440
 
429
441
  console.log("🤖 Agent:", response2.message);
430
- console.log("📊 Normalized data:", agent.session.getData<OnboardingData>());
442
+ console.log("📊 Normalized data:", agent.session.getData());
431
443
  // Shows normalized phone and email
432
444
 
433
445
  if (response2.isRouteComplete) {
434
446
  console.log("\n✅ Onboarding complete!");
435
- await sendOnboardingEmail(agent.session.getData<OnboardingData>());
447
+ await sendOnboardingEmail(agent.session.getData());
436
448
  }
437
449
 
438
450
  await prisma.$disconnect();
@@ -450,32 +462,36 @@ async function serverEndpointExample() {
450
462
  message: "I need help, my name is John and my email is john@example.com",
451
463
  };
452
464
 
465
+ // Define contact form schema
466
+ const contactFormSchema = {
467
+ type: "object",
468
+ properties: {
469
+ name: { type: "string" },
470
+ email: { type: "string" },
471
+ message: { type: "string" },
472
+ },
473
+ required: ["name", "email", "message"],
474
+ };
475
+
453
476
  // Create agent with sessionId (loads existing or creates new)
454
- const agent = new Agent({
477
+ const agent = new Agent<unknown, ContactFormData>({
455
478
  name: "Support Agent",
456
479
  provider: new GeminiProvider({
457
480
  apiKey: process.env.GEMINI_API_KEY!,
458
481
  model: "models/gemini-2.5-flash",
459
482
  }),
483
+ // NEW: Agent-level schema
484
+ schema: contactFormSchema,
460
485
  persistence: {
461
- adapter: new PrismaAdapter<ContactFormData>({ prisma }),
486
+ adapter: new PrismaAdapter<unknown>({ prisma }),
462
487
  autoSave: true,
463
488
  },
464
489
  sessionId: requestData.sessionId, // ✨ Automatic session management
465
490
  });
466
491
 
467
492
  // Create a simple contact form route
468
- const contactRoute = agent.createRoute<ContactFormData>({
493
+ const contactRoute = agent.createRoute({
469
494
  title: "Contact Form",
470
- schema: {
471
- type: "object",
472
- properties: {
473
- name: { type: "string" },
474
- email: { type: "string" },
475
- message: { type: "string" },
476
- },
477
- required: ["name", "email", "message"],
478
- },
479
495
  });
480
496
 
481
497
  contactRoute.initialStep
@@ -502,14 +518,14 @@ async function serverEndpointExample() {
502
518
  message: response.message,
503
519
  sessionId: agent.session.id,
504
520
  isComplete: response.isRouteComplete,
505
- data: agent.session.getData<ContactFormData>(),
521
+ data: agent.session.getData(),
506
522
  };
507
523
 
508
524
  console.log("✅ API Response:", apiResponse);
509
525
 
510
526
  if (response.isRouteComplete) {
511
527
  console.log("\n✅ Contact form submitted!");
512
- await logContactForm(agent.session.getData<ContactFormData>());
528
+ await logContactForm(agent.session.getData());
513
529
  }
514
530
 
515
531
  await prisma.$disconnect();
@@ -38,7 +38,7 @@ interface SupportContext {
38
38
  }
39
39
 
40
40
  // Support tools
41
- const createTicket: Tool<unknown, [], string, SupportTicketData> = {
41
+ const createTicket: Tool<unknown, SupportTicketData, [], string> = {
42
42
  id: "create_support_ticket",
43
43
  description: "Create a new support ticket",
44
44
  parameters: {
@@ -62,38 +62,46 @@ const createTicket: Tool<unknown, [], string, SupportTicketData> = {
62
62
  },
63
63
  };
64
64
 
65
+ // Define support ticket schema
66
+ const supportTicketSchema = {
67
+ type: "object",
68
+ properties: {
69
+ issue: { type: "string" },
70
+ category: {
71
+ type: "string",
72
+ enum: ["technical", "billing", "account", "general"],
73
+ },
74
+ priority: { type: "string", enum: ["low", "medium", "high"] },
75
+ status: { type: "string", enum: ["open", "in_progress", "resolved"] },
76
+ ticketId: { type: "string" },
77
+ assignedAgent: { type: "string" },
78
+ },
79
+ required: ["issue"],
80
+ };
81
+
65
82
  // Create agent with memory persistence
66
- const agent = new Agent({
83
+ const agent = new Agent<unknown, SupportTicketData>({
67
84
  name: "SupportBot",
68
85
  description: "A support agent with memory-based session management",
69
86
  provider: new GeminiProvider({
70
87
  apiKey: process.env.GEMINI_API_KEY!,
71
88
  model: "models/gemini-2.5-flash",
72
89
  }),
90
+ // NEW: Agent-level schema
91
+ schema: supportTicketSchema,
73
92
  persistence: {
74
93
  adapter: new MemoryAdapter(),
75
94
  },
76
95
  });
77
96
 
78
97
  // Create support route with sequential steps
79
- const supportRoute = agent.createRoute<SupportTicketData>({
98
+ const supportRoute = agent.createRoute({
80
99
  title: "Customer Support",
81
100
  description: "Handle customer support requests with session persistence",
82
- schema: {
83
- type: "object",
84
- properties: {
85
- issue: { type: "string" },
86
- category: {
87
- type: "string",
88
- enum: ["technical", "billing", "account", "general"],
89
- },
90
- priority: { type: "string", enum: ["low", "medium", "high"] },
91
- status: { type: "string", enum: ["open", "in_progress", "resolved"] },
92
- ticketId: { type: "string" },
93
- assignedAgent: { type: "string" },
94
- },
95
- required: ["issue"],
96
- },
101
+ // NEW: Required fields for route completion
102
+ requiredFields: ["issue"],
103
+ // NEW: Optional fields that enhance the experience
104
+ optionalFields: ["category", "priority", "status", "ticketId", "assignedAgent"],
97
105
  // Sequential steps for support ticket creation
98
106
  steps: [
99
107
  {
@@ -138,7 +146,7 @@ async function demonstrateSessionBasics() {
138
146
 
139
147
  // Create agent with specific sessionId
140
148
  const sessionId = "session-user-123";
141
- const sessionAgent = new Agent<SupportContext>({
149
+ const sessionAgent = new Agent<SupportContext, SupportTicketData>({
142
150
  name: "Support Assistant",
143
151
  description: "Help users with technical issues",
144
152
  provider: new GeminiProvider({
@@ -150,6 +158,8 @@ async function demonstrateSessionBasics() {
150
158
  userName: "Alice",
151
159
  userTier: "premium",
152
160
  },
161
+ // NEW: Agent-level schema
162
+ schema: supportTicketSchema,
153
163
  persistence: {
154
164
  adapter: new MemoryAdapter(),
155
165
  autoSave: true,
@@ -158,33 +168,22 @@ async function demonstrateSessionBasics() {
158
168
  });
159
169
 
160
170
  // Create the same route on the new agent
161
- sessionAgent.createRoute<SupportTicketData>({
171
+ sessionAgent.createRoute({
162
172
  title: "Customer Support",
163
173
  description: "Handle customer support requests with session persistence",
164
- schema: {
165
- type: "object",
166
- properties: {
167
- issue: { type: "string" },
168
- category: {
169
- type: "string",
170
- enum: ["technical", "billing", "account", "general"],
171
- },
172
- priority: { type: "string", enum: ["low", "medium", "high"] },
173
- status: { type: "string", enum: ["open", "in_progress", "resolved"] },
174
- ticketId: { type: "string" },
175
- assignedAgent: { type: "string" },
176
- },
177
- required: ["issue"],
178
- },
174
+ // NEW: Required fields for route completion
175
+ requiredFields: ["issue"],
176
+ // NEW: Optional fields that enhance the experience
177
+ optionalFields: ["category", "priority", "status", "ticketId", "assignedAgent"],
179
178
  });
180
179
 
181
180
  console.log("Session ready:", sessionAgent.session.id);
182
181
 
183
182
  // Use the session in conversation
184
183
  console.log("\nUser: I can't access my account");
185
-
184
+
186
185
  await sessionAgent.session.addMessage("user", "I can't access my account", "Alice");
187
-
186
+
188
187
  const response1 = await sessionAgent.respond({
189
188
  history: sessionAgent.session.getHistory(),
190
189
  });
@@ -192,9 +191,9 @@ async function demonstrateSessionBasics() {
192
191
  console.log("Bot:", response1.message);
193
192
  console.log(
194
193
  "Session data:",
195
- JSON.stringify(sessionAgent.session.getData<SupportTicketData>(), null, 2)
194
+ JSON.stringify(sessionAgent.session.getData(), null, 2)
196
195
  );
197
-
196
+
198
197
  await sessionAgent.session.addMessage("assistant", response1.message);
199
198
 
200
199
  // Continue the conversation with the returned session
@@ -331,8 +330,7 @@ async function demonstrateMultiUserSessions() {
331
330
 
332
331
  console.log(` Session ID: ${response.session?.id}`);
333
332
  console.log(
334
- ` Issue recorded: ${
335
- (response.session?.data as Partial<SupportTicketData>)?.issue
333
+ ` Issue recorded: ${(response.session?.data as Partial<SupportTicketData>)?.issue
336
334
  }`
337
335
  );
338
336
  }
@@ -362,8 +360,8 @@ async function demonstrateSessionLifecycle() {
362
360
  // 1. Create agent with session
363
361
  console.log("1. 🆕 Creating new session");
364
362
  const sessionId = `lifecycle-demo-${Date.now()}`;
365
-
366
- const lifecycleAgent = new Agent<SupportContext>({
363
+
364
+ const lifecycleAgent = new Agent<SupportContext, SupportTicketData>({
367
365
  name: "Support Assistant",
368
366
  provider: new GeminiProvider({
369
367
  apiKey: process.env.GEMINI_API_KEY!,
@@ -374,6 +372,8 @@ async function demonstrateSessionLifecycle() {
374
372
  userName: "Demo",
375
373
  userTier: "standard",
376
374
  },
375
+ // NEW: Agent-level schema
376
+ schema: supportTicketSchema,
377
377
  persistence: {
378
378
  adapter: new MemoryAdapter(),
379
379
  autoSave: true,
@@ -382,39 +382,28 @@ async function demonstrateSessionLifecycle() {
382
382
  });
383
383
 
384
384
  // Create the same route on the lifecycle agent
385
- lifecycleAgent.createRoute<SupportTicketData>({
385
+ lifecycleAgent.createRoute({
386
386
  title: "Customer Support",
387
387
  description: "Handle customer support requests with session persistence",
388
- schema: {
389
- type: "object",
390
- properties: {
391
- issue: { type: "string" },
392
- category: {
393
- type: "string",
394
- enum: ["technical", "billing", "account", "general"],
395
- },
396
- priority: { type: "string", enum: ["low", "medium", "high"] },
397
- status: { type: "string", enum: ["open", "in_progress", "resolved"] },
398
- ticketId: { type: "string" },
399
- assignedAgent: { type: "string" },
400
- },
401
- required: ["issue"],
402
- },
388
+ // NEW: Required fields for route completion
389
+ requiredFields: ["issue"],
390
+ // NEW: Optional fields that enhance the experience
391
+ optionalFields: ["category", "priority", "status", "ticketId", "assignedAgent"],
403
392
  });
404
393
 
405
394
  console.log(` Created session: ${lifecycleAgent.session.id}`);
406
395
 
407
396
  // 2. Use session in conversation
408
397
  console.log("\n2. 💬 Using session in conversation");
409
-
398
+
410
399
  await lifecycleAgent.session.addMessage("user", "I need help with something", "Demo");
411
-
400
+
412
401
  const response1 = await lifecycleAgent.respond({
413
402
  history: lifecycleAgent.session.getHistory(),
414
403
  });
415
404
 
416
- console.log(` Session data: ${JSON.stringify(lifecycleAgent.session.getData<SupportTicketData>())}`);
417
-
405
+ console.log(` Session data: ${JSON.stringify(lifecycleAgent.session.getData())}`);
406
+
418
407
  await lifecycleAgent.session.addMessage("assistant", response1.message);
419
408
 
420
409
  // 3. Complete the session