@falai/agent 0.9.0-alpha-1 → 0.9.0

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 (217) hide show
  1. package/README.md +34 -22
  2. package/dist/cjs/src/core/Agent.d.ts +77 -59
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +284 -1060
  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/ResponseModal.d.ts +205 -0
  17. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
  18. package/dist/cjs/src/core/ResponseModal.js +1328 -0
  19. package/dist/cjs/src/core/ResponseModal.js.map +1 -0
  20. package/dist/cjs/src/core/ResponsePipeline.d.ts +66 -38
  21. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
  22. package/dist/cjs/src/core/ResponsePipeline.js +72 -4
  23. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
  24. package/dist/cjs/src/core/Route.d.ts +24 -5
  25. package/dist/cjs/src/core/Route.d.ts.map +1 -1
  26. package/dist/cjs/src/core/Route.js +45 -1
  27. package/dist/cjs/src/core/Route.js.map +1 -1
  28. package/dist/cjs/src/core/RoutingEngine.d.ts +31 -6
  29. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
  30. package/dist/cjs/src/core/RoutingEngine.js +113 -9
  31. package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
  32. package/dist/cjs/src/core/SessionManager.d.ts +14 -4
  33. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
  34. package/dist/cjs/src/core/SessionManager.js +25 -5
  35. package/dist/cjs/src/core/SessionManager.js.map +1 -1
  36. package/dist/cjs/src/core/Step.d.ts +10 -10
  37. package/dist/cjs/src/core/Step.d.ts.map +1 -1
  38. package/dist/cjs/src/core/Step.js.map +1 -1
  39. package/dist/cjs/src/core/ToolExecutor.d.ts +4 -2
  40. package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -1
  41. package/dist/cjs/src/core/ToolExecutor.js +13 -3
  42. package/dist/cjs/src/core/ToolExecutor.js.map +1 -1
  43. package/dist/cjs/src/index.d.ts +3 -1
  44. package/dist/cjs/src/index.d.ts.map +1 -1
  45. package/dist/cjs/src/index.js +7 -1
  46. package/dist/cjs/src/index.js.map +1 -1
  47. package/dist/cjs/src/types/agent.d.ts +42 -21
  48. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  49. package/dist/cjs/src/types/agent.js.map +1 -1
  50. package/dist/cjs/src/types/ai.d.ts +1 -1
  51. package/dist/cjs/src/types/ai.d.ts.map +1 -1
  52. package/dist/cjs/src/types/index.d.ts +1 -1
  53. package/dist/cjs/src/types/index.d.ts.map +1 -1
  54. package/dist/cjs/src/types/index.js.map +1 -1
  55. package/dist/cjs/src/types/persistence.d.ts +0 -1
  56. package/dist/cjs/src/types/persistence.d.ts.map +1 -1
  57. package/dist/cjs/src/types/route.d.ts +22 -16
  58. package/dist/cjs/src/types/route.d.ts.map +1 -1
  59. package/dist/cjs/src/types/session.d.ts +6 -11
  60. package/dist/cjs/src/types/session.d.ts.map +1 -1
  61. package/dist/cjs/src/types/tool.d.ts +12 -6
  62. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  63. package/dist/cjs/src/utils/clone.d.ts.map +1 -1
  64. package/dist/cjs/src/utils/clone.js +0 -4
  65. package/dist/cjs/src/utils/clone.js.map +1 -1
  66. package/dist/cjs/src/utils/history.d.ts +30 -1
  67. package/dist/cjs/src/utils/history.d.ts.map +1 -1
  68. package/dist/cjs/src/utils/history.js +169 -23
  69. package/dist/cjs/src/utils/history.js.map +1 -1
  70. package/dist/cjs/src/utils/index.d.ts +1 -1
  71. package/dist/cjs/src/utils/index.d.ts.map +1 -1
  72. package/dist/cjs/src/utils/index.js +5 -1
  73. package/dist/cjs/src/utils/index.js.map +1 -1
  74. package/dist/cjs/src/utils/session.d.ts +2 -2
  75. package/dist/cjs/src/utils/session.d.ts.map +1 -1
  76. package/dist/cjs/src/utils/session.js +6 -26
  77. package/dist/cjs/src/utils/session.js.map +1 -1
  78. package/dist/src/core/Agent.d.ts +77 -59
  79. package/dist/src/core/Agent.d.ts.map +1 -1
  80. package/dist/src/core/Agent.js +285 -1061
  81. package/dist/src/core/Agent.js.map +1 -1
  82. package/dist/src/core/PersistenceManager.d.ts.map +1 -1
  83. package/dist/src/core/PersistenceManager.js +48 -25
  84. package/dist/src/core/PersistenceManager.js.map +1 -1
  85. package/dist/src/core/PromptComposer.d.ts +1 -1
  86. package/dist/src/core/PromptComposer.d.ts.map +1 -1
  87. package/dist/src/core/PromptComposer.js.map +1 -1
  88. package/dist/src/core/ResponseEngine.d.ts +13 -12
  89. package/dist/src/core/ResponseEngine.d.ts.map +1 -1
  90. package/dist/src/core/ResponseEngine.js +4 -4
  91. package/dist/src/core/ResponseEngine.js.map +1 -1
  92. package/dist/src/core/ResponseModal.d.ts +205 -0
  93. package/dist/src/core/ResponseModal.d.ts.map +1 -0
  94. package/dist/src/core/ResponseModal.js +1323 -0
  95. package/dist/src/core/ResponseModal.js.map +1 -0
  96. package/dist/src/core/ResponsePipeline.d.ts +66 -38
  97. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  98. package/dist/src/core/ResponsePipeline.js +72 -4
  99. package/dist/src/core/ResponsePipeline.js.map +1 -1
  100. package/dist/src/core/Route.d.ts +24 -5
  101. package/dist/src/core/Route.d.ts.map +1 -1
  102. package/dist/src/core/Route.js +45 -1
  103. package/dist/src/core/Route.js.map +1 -1
  104. package/dist/src/core/RoutingEngine.d.ts +31 -6
  105. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  106. package/dist/src/core/RoutingEngine.js +113 -9
  107. package/dist/src/core/RoutingEngine.js.map +1 -1
  108. package/dist/src/core/SessionManager.d.ts +14 -4
  109. package/dist/src/core/SessionManager.d.ts.map +1 -1
  110. package/dist/src/core/SessionManager.js +25 -5
  111. package/dist/src/core/SessionManager.js.map +1 -1
  112. package/dist/src/core/Step.d.ts +10 -10
  113. package/dist/src/core/Step.d.ts.map +1 -1
  114. package/dist/src/core/Step.js.map +1 -1
  115. package/dist/src/core/ToolExecutor.d.ts +4 -2
  116. package/dist/src/core/ToolExecutor.d.ts.map +1 -1
  117. package/dist/src/core/ToolExecutor.js +13 -3
  118. package/dist/src/core/ToolExecutor.js.map +1 -1
  119. package/dist/src/index.d.ts +3 -1
  120. package/dist/src/index.d.ts.map +1 -1
  121. package/dist/src/index.js +2 -1
  122. package/dist/src/index.js.map +1 -1
  123. package/dist/src/types/agent.d.ts +42 -21
  124. package/dist/src/types/agent.d.ts.map +1 -1
  125. package/dist/src/types/agent.js.map +1 -1
  126. package/dist/src/types/ai.d.ts +1 -1
  127. package/dist/src/types/ai.d.ts.map +1 -1
  128. package/dist/src/types/index.d.ts +1 -1
  129. package/dist/src/types/index.d.ts.map +1 -1
  130. package/dist/src/types/index.js.map +1 -1
  131. package/dist/src/types/persistence.d.ts +0 -1
  132. package/dist/src/types/persistence.d.ts.map +1 -1
  133. package/dist/src/types/route.d.ts +22 -16
  134. package/dist/src/types/route.d.ts.map +1 -1
  135. package/dist/src/types/session.d.ts +6 -11
  136. package/dist/src/types/session.d.ts.map +1 -1
  137. package/dist/src/types/tool.d.ts +12 -6
  138. package/dist/src/types/tool.d.ts.map +1 -1
  139. package/dist/src/utils/clone.d.ts.map +1 -1
  140. package/dist/src/utils/clone.js +0 -4
  141. package/dist/src/utils/clone.js.map +1 -1
  142. package/dist/src/utils/history.d.ts +30 -1
  143. package/dist/src/utils/history.d.ts.map +1 -1
  144. package/dist/src/utils/history.js +165 -23
  145. package/dist/src/utils/history.js.map +1 -1
  146. package/dist/src/utils/index.d.ts +1 -1
  147. package/dist/src/utils/index.d.ts.map +1 -1
  148. package/dist/src/utils/index.js +1 -1
  149. package/dist/src/utils/index.js.map +1 -1
  150. package/dist/src/utils/session.d.ts +2 -2
  151. package/dist/src/utils/session.d.ts.map +1 -1
  152. package/dist/src/utils/session.js +6 -26
  153. package/dist/src/utils/session.js.map +1 -1
  154. package/docs/README.md +5 -4
  155. package/docs/api/README.md +195 -4
  156. package/docs/api/overview.md +232 -13
  157. package/docs/core/agent/README.md +162 -17
  158. package/docs/core/agent/context-management.md +39 -15
  159. package/docs/core/agent/session-management.md +49 -16
  160. package/docs/core/ai-integration/prompt-composition.md +38 -14
  161. package/docs/core/ai-integration/response-processing.md +28 -17
  162. package/docs/core/conversation-flows/data-collection.md +103 -25
  163. package/docs/core/conversation-flows/route-dsl.md +45 -22
  164. package/docs/core/conversation-flows/routes.md +74 -18
  165. package/docs/core/conversation-flows/step-transitions.md +3 -3
  166. package/docs/core/conversation-flows/steps.md +39 -15
  167. package/docs/core/routing/intelligent-routing.md +18 -9
  168. package/docs/core/tools/tool-definition.md +8 -8
  169. package/docs/core/tools/tool-execution.md +26 -26
  170. package/docs/core/tools/tool-scoping.md +5 -5
  171. package/docs/guides/getting-started/README.md +54 -32
  172. package/docs/guides/migration/README.md +72 -0
  173. package/docs/guides/migration/response-modal-refactor.md +518 -0
  174. package/examples/advanced-patterns/knowledge-based-agent.ts +37 -28
  175. package/examples/advanced-patterns/persistent-onboarding.ts +70 -41
  176. package/examples/advanced-patterns/route-lifecycle-hooks.ts +28 -2
  177. package/examples/advanced-patterns/streaming-responses.ts +197 -119
  178. package/examples/ai-providers/anthropic-integration.ts +40 -33
  179. package/examples/ai-providers/openai-integration.ts +25 -25
  180. package/examples/conversation-flows/completion-transitions.ts +36 -32
  181. package/examples/core-concepts/basic-agent.ts +76 -78
  182. package/examples/core-concepts/modern-streaming-api.ts +309 -0
  183. package/examples/core-concepts/schema-driven-extraction.ts +20 -16
  184. package/examples/core-concepts/session-management.ts +65 -53
  185. package/examples/integrations/database-integration.ts +49 -34
  186. package/examples/integrations/healthcare-integration.ts +96 -91
  187. package/examples/integrations/search-integration.ts +79 -82
  188. package/examples/integrations/server-session-management.ts +25 -17
  189. package/examples/persistence/database-persistence.ts +61 -45
  190. package/examples/persistence/memory-sessions.ts +52 -63
  191. package/examples/persistence/redis-persistence.ts +81 -95
  192. package/examples/tools/basic-tools.ts +73 -62
  193. package/examples/tools/data-enrichment-tools.ts +52 -44
  194. package/package.json +1 -1
  195. package/src/core/Agent.ts +396 -1499
  196. package/src/core/PersistenceManager.ts +51 -27
  197. package/src/core/PromptComposer.ts +1 -1
  198. package/src/core/ResponseEngine.ts +21 -19
  199. package/src/core/ResponseModal.ts +1722 -0
  200. package/src/core/ResponsePipeline.ts +175 -60
  201. package/src/core/Route.ts +58 -6
  202. package/src/core/RoutingEngine.ts +174 -27
  203. package/src/core/SessionManager.ts +32 -8
  204. package/src/core/Step.ts +20 -12
  205. package/src/core/ToolExecutor.ts +19 -5
  206. package/src/index.ts +11 -0
  207. package/src/types/agent.ts +47 -23
  208. package/src/types/ai.ts +1 -1
  209. package/src/types/index.ts +2 -0
  210. package/src/types/persistence.ts +0 -1
  211. package/src/types/route.ts +22 -16
  212. package/src/types/session.ts +6 -12
  213. package/src/types/tool.ts +15 -9
  214. package/src/utils/clone.ts +6 -8
  215. package/src/utils/history.ts +190 -27
  216. package/src/utils/index.ts +4 -0
  217. package/src/utils/session.ts +6 -31
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- The `Agent<TContext>` class is the central orchestrator of @falai/agent, providing a strongly-typed, context-aware AI agent framework with intelligent routing and schema-driven data collection.
5
+ The `Agent<TContext, TData>` class is the central orchestrator of @falai/agent, providing a strongly-typed, context-aware AI agent framework with intelligent routing and agent-level schema-driven data collection.
6
6
 
7
7
  ## Core Responsibilities
8
8
 
@@ -11,7 +11,7 @@ The `Agent<TContext>` class is the central orchestrator of @falai/agent, providi
11
11
  - **Context Lifecycle**: Dynamic context management with provider functions and lifecycle hooks
12
12
  - **Session Management**: Conversation state persistence and multi-turn dialogue support
13
13
  - **Tool Orchestration**: Hierarchical tool execution (agent → route → step level)
14
- - **Data Collection**: Schema-driven information extraction from natural conversations
14
+ - **Agent-Level Data Collection**: Centralized schema-driven information extraction shared across all routes
15
15
 
16
16
  ## Agent Configuration
17
17
 
@@ -43,7 +43,18 @@ interface CustomerContext {
43
43
  };
44
44
  }
45
45
 
46
- const agent = new Agent<CustomerContext>({
46
+ interface CustomerData {
47
+ customerName?: string;
48
+ email?: string;
49
+ phone?: string;
50
+ issueType?: 'booking' | 'billing' | 'technical' | 'other';
51
+ issueDescription?: string;
52
+ priority?: 'low' | 'medium' | 'high';
53
+ rating?: number;
54
+ comments?: string;
55
+ }
56
+
57
+ const agent = new Agent<CustomerContext, CustomerData>({
47
58
  // Identity
48
59
  name: "Premium Support Assistant",
49
60
  description: "24/7 AI support for premium customers",
@@ -56,6 +67,21 @@ const agent = new Agent<CustomerContext>({
56
67
  backupModels: ["gpt-4"],
57
68
  }),
58
69
 
70
+ // Agent-level data schema (NEW)
71
+ schema: {
72
+ type: "object",
73
+ properties: {
74
+ customerName: { type: "string" },
75
+ email: { type: "string", format: "email" },
76
+ phone: { type: "string" },
77
+ issueType: { type: "string", enum: ["booking", "billing", "technical", "other"] },
78
+ issueDescription: { type: "string" },
79
+ priority: { type: "string", enum: ["low", "medium", "high"] },
80
+ rating: { type: "number", minimum: 1, maximum: 5 },
81
+ comments: { type: "string" }
82
+ }
83
+ },
84
+
59
85
  // Static context (can be overridden by contextProvider)
60
86
  context: {
61
87
  userId: "anonymous",
@@ -102,16 +128,21 @@ const agent = new Agent<CustomerContext>({
102
128
  }
103
129
  },
104
130
 
105
- // Validate and enrich collected data
131
+ // Validate and enrich collected data (NEW: Agent-level data hooks)
106
132
  onDataUpdate: async (data, previousData) => {
107
- // Data validation
133
+ // Data validation against agent schema
108
134
  if (data.email && !isValidEmail(data.email)) {
109
135
  throw new Error("Invalid email format");
110
136
  }
111
137
 
112
- // Data enrichment
113
- if (data.userId && !data.userProfile) {
114
- data.userProfile = await db.getUserProfile(data.userId);
138
+ // Data enrichment using agent-level data
139
+ if (data.customerName && !data.customerId) {
140
+ data.customerId = await lookupCustomerId(data.customerName);
141
+ }
142
+
143
+ // Auto-set priority based on issue type
144
+ if (data.issueType === 'billing' && !data.priority) {
145
+ data.priority = 'high';
115
146
  }
116
147
 
117
148
  return data;
@@ -327,26 +358,33 @@ agent.session.clearHistory();
327
358
  ### Declarative Route Creation
328
359
 
329
360
  ```typescript
330
- const agent = new Agent({
361
+ const agent = new Agent<CustomerContext, CustomerData>({
362
+ // Agent-level schema defines all possible data fields
363
+ schema: { /* comprehensive schema */ },
364
+
331
365
  routes: [
332
366
  {
333
367
  title: "Technical Support",
334
368
  description: "Help with technical issues",
335
369
  conditions: ["user reports technical problem"],
370
+ // NEW: Routes specify required fields instead of schemas
371
+ requiredFields: ["customerName", "email", "issueType", "issueDescription"],
372
+ optionalFields: ["phone", "priority"],
336
373
  initialStep: {
337
374
  prompt:
338
375
  "I understand you're having a technical issue. Can you describe what's happening?",
339
- collect: ["problem", "severity"],
376
+ collect: ["issueType", "issueDescription"], // Collects into agent-level data
340
377
  },
341
378
  },
342
379
  {
343
- title: "Billing Inquiry",
380
+ title: "Billing Inquiry",
344
381
  description: "Handle billing and payment questions",
345
382
  conditions: ["user asks about billing or payment"],
383
+ requiredFields: ["customerName", "email", "issueType"],
346
384
  initialStep: {
347
385
  prompt:
348
386
  "I'd be happy to help with your billing question. What can I assist with?",
349
- collect: ["billingIssue"],
387
+ collect: ["issueType"], // Maps to agent schema field
350
388
  },
351
389
  },
352
390
  ],
@@ -356,18 +394,21 @@ const agent = new Agent({
356
394
  ### Programmatic Route Creation
357
395
 
358
396
  ```typescript
359
- // Create routes dynamically
397
+ // Create routes dynamically with required fields
360
398
  const supportRoute = agent
361
399
  .createRoute({
362
400
  title: "Customer Support",
401
+ requiredFields: ["customerName", "email", "issueType"], // NEW: Required fields
402
+ optionalFields: ["phone"], // NEW: Optional fields
363
403
  initialStep: {
364
404
  prompt: "How can I help you today?",
365
- collect: ["intent"],
405
+ collect: ["customerName", "email"], // Collects into agent-level data
366
406
  },
367
407
  })
368
408
  .nextStep({
369
- prompt: "I understand you need help with {{intent}}",
370
- requires: ["intent"],
409
+ prompt: "I understand you need help, {{customerName}}. What type of issue are you experiencing?",
410
+ collect: ["issueType"],
411
+ requires: ["customerName", "email"], // Prerequisites from agent data
371
412
  });
372
413
 
373
414
  // Access created routes
@@ -404,6 +445,110 @@ const route = agent.createRoute({
404
445
  2. **Route-level tools**
405
446
  3. **Agent-level tools** (lowest priority)
406
447
 
448
+ ## Agent-Level Data Collection
449
+
450
+ ### Centralized Data Schema
451
+
452
+ The new architecture centralizes data collection at the agent level, allowing all routes to work with the same data structure:
453
+
454
+ ```typescript
455
+ interface ComprehensiveData {
456
+ // Customer identification
457
+ customerId?: string;
458
+ customerName?: string;
459
+ email?: string;
460
+ phone?: string;
461
+
462
+ // Issue tracking
463
+ issueType?: 'booking' | 'billing' | 'technical' | 'other';
464
+ issueDescription?: string;
465
+ priority?: 'low' | 'medium' | 'high';
466
+
467
+ // Feedback
468
+ rating?: number;
469
+ comments?: string;
470
+ recommendToFriend?: boolean;
471
+ }
472
+
473
+ const agent = new Agent<Context, ComprehensiveData>({
474
+ name: "Customer Service Agent",
475
+ schema: {
476
+ type: "object",
477
+ properties: {
478
+ customerId: { type: "string" },
479
+ customerName: { type: "string" },
480
+ email: { type: "string", format: "email" },
481
+ phone: { type: "string" },
482
+ issueType: { type: "string", enum: ["booking", "billing", "technical", "other"] },
483
+ issueDescription: { type: "string" },
484
+ priority: { type: "string", enum: ["low", "medium", "high"] },
485
+ rating: { type: "number", minimum: 1, maximum: 5 },
486
+ comments: { type: "string" },
487
+ recommendToFriend: { type: "boolean" }
488
+ }
489
+ }
490
+ });
491
+ ```
492
+
493
+ ### Route Completion Based on Required Fields
494
+
495
+ Routes now specify which fields they need to complete, enabling cross-route data sharing:
496
+
497
+ ```typescript
498
+ // Support route needs basic info + issue details
499
+ const supportRoute = agent.createRoute({
500
+ title: "Customer Support",
501
+ requiredFields: ["customerName", "email", "issueType", "issueDescription"],
502
+ optionalFields: ["phone", "priority"]
503
+ });
504
+
505
+ // Feedback route needs basic info + rating
506
+ const feedbackRoute = agent.createRoute({
507
+ title: "Feedback Collection",
508
+ requiredFields: ["customerName", "email", "rating"],
509
+ optionalFields: ["comments", "recommendToFriend"]
510
+ });
511
+
512
+ // Routes can complete when their required data is available,
513
+ // regardless of which route collected it
514
+ ```
515
+
516
+ ### Cross-Route Data Sharing
517
+
518
+ Data collected by any route is available to all other routes:
519
+
520
+ ```typescript
521
+ // User starts with support, provides name and email
522
+ const response1 = await agent.respond("I need help, my name is John Doe, email john@example.com");
523
+ // Agent data now contains: { customerName: "John Doe", email: "john@example.com" }
524
+
525
+ // User switches to feedback - already has 2/3 required fields
526
+ const response2 = await agent.respond("Actually, I want to leave feedback. I'd rate you 5 stars.");
527
+ // Feedback route completes immediately with: { customerName: "John Doe", email: "john@example.com", rating: 5 }
528
+ ```
529
+
530
+ ### Agent Data Management Methods
531
+
532
+ Access and update agent-level data programmatically:
533
+
534
+ ```typescript
535
+ // Get current collected data
536
+ const currentData = agent.getCollectedData();
537
+ console.log(currentData); // { customerName: "John", email: "john@example.com" }
538
+
539
+ // Update data programmatically
540
+ await agent.updateCollectedData({
541
+ customerId: "CUST-12345",
542
+ priority: "high"
543
+ });
544
+
545
+ // Validate data against schema
546
+ const validation = agent.validateData({ email: "invalid-email" });
547
+ if (!validation.valid) {
548
+ console.log(validation.errors); // Detailed validation errors
549
+ }
550
+ ```
551
+
407
552
  ## Response Generation
408
553
 
409
554
  ### Simple Response API
@@ -412,7 +557,7 @@ const route = agent.createRoute({
412
557
  // Simple message-based API (recommended)
413
558
  const response = await agent.respond("How do I reset my password?");
414
559
  console.log(response.message);
415
- console.log(agent.session.getData()); // Any collected data
560
+ console.log(agent.session.getData<CustomerData>()); // Agent-level collected data
416
561
  console.log(response.toolCalls); // Any tool calls made
417
562
  console.log(response.isRouteComplete); // Whether route finished
418
563
 
@@ -8,28 +8,45 @@ The `@falai/agent` framework provides **automatic session management** through t
8
8
 
9
9
  ## 🎯 Automatic Session Management
10
10
 
11
- The `SessionManager` automatically tracks three key aspects of a conversation:
11
+ The `SessionManager` automatically tracks four key aspects of a conversation:
12
12
 
13
13
  1. **Current Route** - Which conversation flow the user is in
14
14
  2. **Current Step** - Where in the flow they currently are
15
- 3. **Collected data** - Structured data collected so far
15
+ 3. **Agent-Level Data** - Centralized structured data collected across all routes
16
16
  4. **Conversation History** - Complete message history within the session
17
17
 
18
18
  ```typescript
19
- // Define your data extraction type
20
- interface FlightData {
19
+ // Define your agent-level data extraction type
20
+ interface TravelData {
21
21
  destination: string;
22
22
  departureDate: string;
23
23
  passengers: number;
24
24
  cabinClass: "economy" | "business" | "first";
25
+ hotelPreference?: string;
26
+ budgetRange?: string;
27
+ specialRequests?: string;
25
28
  }
26
29
 
27
- // Agent with automatic session management
28
- const agent = new Agent({
30
+ // Agent with automatic session management and agent-level schema
31
+ const agent = new Agent<{}, TravelData>({
29
32
  name: "Travel Agent",
30
33
  provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
31
34
  persistence: { adapter: new PrismaAdapter({ prisma }) },
32
- sessionId: "user-123" // Automatically loads or creates session
35
+ sessionId: "user-123", // Automatically loads or creates session
36
+
37
+ // Agent-level schema for all data collection
38
+ schema: {
39
+ type: "object",
40
+ properties: {
41
+ destination: { type: "string" },
42
+ departureDate: { type: "string", format: "date" },
43
+ passengers: { type: "number", minimum: 1, maximum: 9 },
44
+ cabinClass: { type: "string", enum: ["economy", "business", "first"] },
45
+ hotelPreference: { type: "string" },
46
+ budgetRange: { type: "string" },
47
+ specialRequests: { type: "string" }
48
+ }
49
+ }
33
50
  });
34
51
 
35
52
  // Simple conversation - session managed automatically
@@ -37,7 +54,7 @@ const response = await agent.respond("I want to book a flight to Paris");
37
54
 
38
55
  // Access session information
39
56
  console.log(agent.session.id); // "user-123"
40
- console.log(agent.session.getData<FlightData>()); // { destination: "Paris", ... }
57
+ console.log(agent.session.getData<TravelData>()); // { destination: "Paris", ... }
41
58
  console.log(agent.session.getHistory()); // Conversation history
42
59
  ```
43
60
 
@@ -64,12 +81,13 @@ const sessionManager = agent.session;
64
81
  await sessionManager.getOrCreate("user-123");
65
82
  await sessionManager.getOrCreate(); // Auto-generates ID
66
83
 
67
- // Data management
68
- const data = sessionManager.getData<FlightData>();
84
+ // Agent-level data management
85
+ const data = sessionManager.getData<TravelData>();
69
86
  await sessionManager.setData({
70
87
  destination: "Paris",
71
88
  departureDate: "2025-10-15",
72
89
  passengers: 2,
90
+ cabinClass: "economy"
73
91
  });
74
92
 
75
93
  // History management
@@ -128,19 +146,25 @@ const agent = new Agent({
128
146
  await saveUserData(newContext.userId, newContext);
129
147
  },
130
148
 
131
- // NEW: Validate and enrich collected data
149
+ // Agent-level data validation and enrichment
132
150
  onDataUpdate: async (data, previousData) => {
133
151
  // Normalize passenger count
134
152
  if (data.passengers < 1) data.passengers = 1;
135
153
  if (data.passengers > 9) data.passengers = 9;
136
154
 
137
- // Enrich with computed fields
138
- if (data.destination) {
155
+ // Enrich with computed fields using agent-level data
156
+ if (data.destination && !data.destinationCode) {
139
157
  data.destinationCode = await lookupAirportCode(data.destination);
140
158
  }
141
159
 
142
- // Auto-trigger actions
143
- if (hasAllRequires(data)) {
160
+ // Auto-set budget range based on cabin class
161
+ if (data.cabinClass && !data.budgetRange) {
162
+ data.budgetRange = data.cabinClass === 'first' ? 'premium' :
163
+ data.cabinClass === 'business' ? 'high' : 'standard';
164
+ }
165
+
166
+ // Auto-trigger actions when we have complete booking data
167
+ if (data.destination && data.departureDate && data.passengers) {
144
168
  data.shouldSearchFlights = true;
145
169
  }
146
170
 
@@ -6,22 +6,28 @@ The `@falai/agent` framework provides **automatic session management** through t
6
6
 
7
7
  ## Core Design Principles
8
8
 
9
- ### 1. 🎯 Schema-First Data Extraction
9
+ ### 1. 🎯 Agent-Level Schema-First Data Extraction
10
10
 
11
- Define what data to collect upfront using JSON Schema, then extract it reliably:
11
+ Define what data to collect upfront using JSON Schema at the agent level, then extract it reliably across all routes:
12
12
 
13
13
  ```typescript
14
- // Define your data contract
15
- interface FlightData {
14
+ // Define your agent-level data contract
15
+ interface TravelData {
16
16
  destination: string;
17
17
  departureDate: string;
18
18
  passengers: number;
19
19
  cabinClass: "economy" | "business" | "first";
20
+ hotelPreference?: string;
21
+ budgetRange?: string;
22
+ specialRequests?: string;
20
23
  }
21
24
 
22
- const route = agent.createRoute<FlightData>({
23
- title: "Book Flight",
24
- description: "Help user book a flight",
25
+ // Agent with centralized schema
26
+ const agent = new Agent<{}, TravelData>({
27
+ name: "Travel Agent",
28
+ provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
29
+
30
+ // Agent-level schema defines all possible data fields
25
31
  schema: {
26
32
  type: "object",
27
33
  properties: {
@@ -33,40 +39,67 @@ const route = agent.createRoute<FlightData>({
33
39
  enum: ["economy", "business", "first"],
34
40
  default: "economy",
35
41
  },
42
+ hotelPreference: { type: "string" },
43
+ budgetRange: { type: "string" },
44
+ specialRequests: { type: "string" }
36
45
  },
37
46
  required: ["destination", "departureDate", "passengers"],
38
- },
47
+ }
48
+ });
49
+
50
+ // Routes specify required fields instead of schemas
51
+ const flightRoute = agent.createRoute({
52
+ title: "Book Flight",
53
+ description: "Help user book a flight",
54
+ requiredFields: ["destination", "departureDate", "passengers", "cabinClass"],
55
+ optionalFields: ["specialRequests"]
56
+ });
57
+
58
+ const hotelRoute = agent.createRoute({
59
+ title: "Book Hotel",
60
+ description: "Help user book accommodation",
61
+ requiredFields: ["destination", "departureDate", "hotelPreference"],
62
+ optionalFields: ["budgetRange", "specialRequests"]
39
63
  });
40
64
  ```
41
65
 
42
- **Why?** Schema-first extraction provides:
66
+ **Why?** Agent-level schema-first extraction provides:
43
67
 
44
- - **Type Safety** - Full TypeScript types from definition to extraction
68
+ - **Type Safety** - Full TypeScript types from definition to extraction across all routes
45
69
  - **Reliability** - Provider-enforced schemas, not prompt-based parsing
46
- - **Predictability** - Same data structure every time
70
+ - **Predictability** - Same data structure every time, shared across routes
47
71
  - **Efficiency** - Extract multiple fields in one LLM call
72
+ - **Cross-Route Data Sharing** - Data collected by any route is available to all routes
73
+ - **Route Completion** - Routes complete when their required fields are satisfied
48
74
 
49
75
  ### 2. 🤖 Automatic Session Management
50
76
 
51
77
  Sessions are automatically managed through the `SessionManager` class integrated into every `Agent`:
52
78
 
53
79
  ```typescript
54
- // Server-side: Agent with automatic session management
55
- const agent = new Agent({
80
+ // Server-side: Agent with automatic session management and agent-level data
81
+ const agent = new Agent<{}, TravelData>({
56
82
  name: "Travel Agent",
57
83
  provider: new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }),
58
84
  persistence: { adapter: new PrismaAdapter({ prisma }) },
59
- sessionId: "user-123" // Automatically loads or creates this session
85
+ sessionId: "user-123", // Automatically loads or creates this session
86
+
87
+ // Agent-level schema
88
+ schema: { /* comprehensive travel data schema */ }
60
89
  });
61
90
 
62
91
  // Simple conversation - no manual session management
63
92
  const response1 = await agent.respond("I want to book a flight to Paris");
64
93
  console.log(agent.session.id); // Session ID
65
- console.log(agent.session.getData()); // Collected data
94
+ console.log(agent.session.getData<TravelData>()); // Agent-level collected data
66
95
 
67
96
  // Continue conversation - session automatically maintained
68
97
  const response2 = await agent.respond("Make that Tokyo instead");
69
- // Session automatically updated with new data
98
+ // Session automatically updated with new data in agent-level structure
99
+
100
+ // Switch to hotel booking - data is shared
101
+ const response3 = await agent.respond("Also book me a hotel in Tokyo");
102
+ // Hotel route can access destination data collected by flight route
70
103
  ```
71
104
 
72
105
  **SessionManager API:**
@@ -103,35 +103,59 @@ Assistant: Great! Let me check flights for next week. Could you tell me which ai
103
103
  Current session information including:
104
104
 
105
105
  - Active route and step
106
- - Collected data (with privacy filtering)
106
+ - Agent-level collected data (with privacy filtering)
107
107
  - Route progress and completion status
108
+ - Cross-route data availability
109
+
110
+ ```
111
+ Current Session:
112
+ - Route: Flight Booking (2/3 required fields collected)
113
+ - Step: ask_passengers
114
+ - Agent Data: { destination: "Paris", departureDate: "2025-01-15" }
115
+ - Missing Required: passengers
116
+ - Available from other routes: { hotelPreference: "luxury" }
117
+ ```
108
118
 
109
119
  ## Dynamic Schema Generation
110
120
 
111
- For data collection steps, the prompt includes JSON schemas:
121
+ For data collection steps, the prompt includes agent-level JSON schemas:
112
122
 
113
123
  ```typescript
114
- // Route schema
115
- schema: {
116
- type: "object",
117
- properties: {
118
- destination: { type: "string" },
119
- departureDate: { type: "string", format: "date" },
120
- passengers: { type: "number", minimum: 1 }
121
- },
122
- required: ["destination", "departureDate"]
123
- }
124
+ // Agent-level schema
125
+ const agent = new Agent<{}, TravelData>({
126
+ schema: {
127
+ type: "object",
128
+ properties: {
129
+ destination: { type: "string" },
130
+ departureDate: { type: "string", format: "date" },
131
+ passengers: { type: "number", minimum: 1 },
132
+ hotelPreference: { type: "string" },
133
+ budgetRange: { type: "string" }
134
+ },
135
+ required: ["destination", "departureDate"]
136
+ }
137
+ });
138
+
139
+ // Route specifies which fields to collect
140
+ const flightRoute = agent.createRoute({
141
+ title: "Flight Booking",
142
+ requiredFields: ["destination", "departureDate", "passengers"],
143
+ optionalFields: ["budgetRange"]
144
+ });
124
145
  ```
125
146
 
126
147
  Generates:
127
148
 
128
149
  ```
129
- Extract the following information from the user's response:
150
+ Extract the following information from the user's response based on the agent schema:
130
151
  - destination: string - Where the user wants to fly
131
152
  - departureDate: string (date format) - When they want to depart
132
153
  - passengers: number (minimum 1) - How many people are traveling
154
+ - budgetRange: string (optional) - Budget preference for the trip
133
155
 
134
- Return extracted data as valid JSON matching this schema.
156
+ Return extracted data as valid JSON matching the agent schema.
157
+ Current route requires: destination, departureDate, passengers
158
+ Route completion: 2/3 required fields collected
135
159
  ```
136
160
 
137
161
  ## Tool Integration
@@ -20,26 +20,33 @@ AI responses are parsed to extract:
20
20
  3. **Tool Calls** - Instructions to execute tools
21
21
  4. **Routing Decisions** - Route or step transitions
22
22
 
23
- ## Schema-Driven Extraction
23
+ ## Agent-Level Schema-Driven Extraction
24
24
 
25
- When steps specify `collect` fields, the AI response is validated against JSON schemas:
25
+ When steps specify `collect` fields, the AI response is validated against the agent-level JSON schema:
26
26
 
27
27
  ```typescript
28
- const step = route.initialStep.nextStep({
29
- prompt: "What's your name and email?",
30
- collect: ["name", "email"],
28
+ // Agent defines comprehensive schema
29
+ const agent = new Agent<{}, UserData>({
31
30
  schema: {
32
31
  type: "object",
33
32
  properties: {
34
33
  name: { type: "string" },
35
34
  email: { type: "string", format: "email" },
35
+ phone: { type: "string" },
36
+ preferences: { type: "object" }
36
37
  },
37
- required: ["name", "email"],
38
- },
38
+ required: ["name", "email"]
39
+ }
40
+ });
41
+
42
+ // Steps collect into agent schema
43
+ const step = route.initialStep.nextStep({
44
+ prompt: "What's your name and email?",
45
+ collect: ["name", "email"], // Maps to agent schema fields
39
46
  });
40
47
  ```
41
48
 
42
- The AI receives instructions to return structured data alongside natural language responses.
49
+ The AI receives instructions to return structured data that matches the agent-level schema, enabling cross-route data sharing.
43
50
 
44
51
  ## Tool Execution Pipeline
45
52
 
@@ -65,26 +72,30 @@ When tools are called, the response engine:
65
72
 
66
73
  ## Data Validation
67
74
 
68
- Extracted data is validated against route schemas:
75
+ Extracted data is validated against the agent-level schema:
69
76
 
70
- - **Type checking** - Ensures correct data types
71
- - **Required fields** - Validates mandatory data presence
72
- - **Format validation** - Email, dates, custom formats
73
- - **Business rules** - Custom validation logic
77
+ - **Type checking** - Ensures correct data types against agent schema
78
+ - **Required fields** - Validates mandatory data presence for route completion
79
+ - **Format validation** - Email, dates, custom formats from agent schema
80
+ - **Business rules** - Custom validation logic in agent-level hooks
81
+ - **Cross-route consistency** - Ensures data consistency across all routes
74
82
 
75
83
  ## Context Updates
76
84
 
77
85
  Response processing updates multiple context layers:
78
86
 
79
- ### Session Data
87
+ ### Agent-Level Data
80
88
 
81
89
  ```typescript
82
- // Collected data merged into session
83
- session.data = {
84
- ...session.data,
90
+ // Collected data merged into agent-level data structure
91
+ agent.collectedData = {
92
+ ...agent.collectedData,
85
93
  ...extractedData,
86
94
  ...toolResults,
87
95
  };
96
+
97
+ // Session references agent data
98
+ session.data = agent.collectedData;
88
99
  ```
89
100
 
90
101
  ### Route Context