@falai/agent 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +42 -34
  2. package/dist/cjs/src/core/Agent.d.ts +19 -5
  3. package/dist/cjs/src/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/src/core/Agent.js +79 -35
  5. package/dist/cjs/src/core/Agent.js.map +1 -1
  6. package/dist/cjs/src/core/ResponseModal.d.ts +9 -3
  7. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -1
  8. package/dist/cjs/src/core/ResponseModal.js +121 -55
  9. package/dist/cjs/src/core/ResponseModal.js.map +1 -1
  10. package/dist/cjs/src/core/ResponsePipeline.d.ts +8 -4
  11. package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
  12. package/dist/cjs/src/core/ResponsePipeline.js +47 -19
  13. package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
  14. package/dist/cjs/src/core/Route.d.ts +12 -5
  15. package/dist/cjs/src/core/Route.d.ts.map +1 -1
  16. package/dist/cjs/src/core/Route.js +26 -5
  17. package/dist/cjs/src/core/Route.js.map +1 -1
  18. package/dist/cjs/src/core/RoutingEngine.d.ts +5 -0
  19. package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
  20. package/dist/cjs/src/core/RoutingEngine.js +37 -25
  21. package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
  22. package/dist/cjs/src/core/SessionManager.d.ts +9 -1
  23. package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
  24. package/dist/cjs/src/core/SessionManager.js +27 -5
  25. package/dist/cjs/src/core/SessionManager.js.map +1 -1
  26. package/dist/cjs/src/core/Step.d.ts +60 -7
  27. package/dist/cjs/src/core/Step.d.ts.map +1 -1
  28. package/dist/cjs/src/core/Step.js +151 -4
  29. package/dist/cjs/src/core/Step.js.map +1 -1
  30. package/dist/cjs/src/core/ToolManager.d.ts +234 -0
  31. package/dist/cjs/src/core/ToolManager.d.ts.map +1 -0
  32. package/dist/cjs/src/core/ToolManager.js +1117 -0
  33. package/dist/cjs/src/core/ToolManager.js.map +1 -0
  34. package/dist/cjs/src/index.d.ts +2 -3
  35. package/dist/cjs/src/index.d.ts.map +1 -1
  36. package/dist/cjs/src/index.js +5 -3
  37. package/dist/cjs/src/index.js.map +1 -1
  38. package/dist/cjs/src/types/agent.d.ts +1 -1
  39. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  40. package/dist/cjs/src/types/index.d.ts +3 -2
  41. package/dist/cjs/src/types/index.d.ts.map +1 -1
  42. package/dist/cjs/src/types/index.js +3 -1
  43. package/dist/cjs/src/types/index.js.map +1 -1
  44. package/dist/cjs/src/types/route.d.ts +6 -4
  45. package/dist/cjs/src/types/route.d.ts.map +1 -1
  46. package/dist/cjs/src/types/tool.d.ts +84 -14
  47. package/dist/cjs/src/types/tool.d.ts.map +1 -1
  48. package/dist/cjs/src/types/tool.js +13 -0
  49. package/dist/cjs/src/types/tool.js.map +1 -1
  50. package/dist/src/core/Agent.d.ts +19 -5
  51. package/dist/src/core/Agent.d.ts.map +1 -1
  52. package/dist/src/core/Agent.js +79 -35
  53. package/dist/src/core/Agent.js.map +1 -1
  54. package/dist/src/core/ResponseModal.d.ts +9 -3
  55. package/dist/src/core/ResponseModal.d.ts.map +1 -1
  56. package/dist/src/core/ResponseModal.js +121 -55
  57. package/dist/src/core/ResponseModal.js.map +1 -1
  58. package/dist/src/core/ResponsePipeline.d.ts +8 -4
  59. package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
  60. package/dist/src/core/ResponsePipeline.js +47 -19
  61. package/dist/src/core/ResponsePipeline.js.map +1 -1
  62. package/dist/src/core/Route.d.ts +12 -5
  63. package/dist/src/core/Route.d.ts.map +1 -1
  64. package/dist/src/core/Route.js +26 -5
  65. package/dist/src/core/Route.js.map +1 -1
  66. package/dist/src/core/RoutingEngine.d.ts +5 -0
  67. package/dist/src/core/RoutingEngine.d.ts.map +1 -1
  68. package/dist/src/core/RoutingEngine.js +37 -25
  69. package/dist/src/core/RoutingEngine.js.map +1 -1
  70. package/dist/src/core/SessionManager.d.ts +9 -1
  71. package/dist/src/core/SessionManager.d.ts.map +1 -1
  72. package/dist/src/core/SessionManager.js +27 -5
  73. package/dist/src/core/SessionManager.js.map +1 -1
  74. package/dist/src/core/Step.d.ts +60 -7
  75. package/dist/src/core/Step.d.ts.map +1 -1
  76. package/dist/src/core/Step.js +151 -4
  77. package/dist/src/core/Step.js.map +1 -1
  78. package/dist/src/core/ToolManager.d.ts +234 -0
  79. package/dist/src/core/ToolManager.d.ts.map +1 -0
  80. package/dist/src/core/ToolManager.js +1111 -0
  81. package/dist/src/core/ToolManager.js.map +1 -0
  82. package/dist/src/index.d.ts +2 -3
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +1 -1
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/types/agent.d.ts +1 -1
  87. package/dist/src/types/agent.d.ts.map +1 -1
  88. package/dist/src/types/index.d.ts +3 -2
  89. package/dist/src/types/index.d.ts.map +1 -1
  90. package/dist/src/types/index.js +1 -0
  91. package/dist/src/types/index.js.map +1 -1
  92. package/dist/src/types/route.d.ts +6 -4
  93. package/dist/src/types/route.d.ts.map +1 -1
  94. package/dist/src/types/tool.d.ts +84 -14
  95. package/dist/src/types/tool.d.ts.map +1 -1
  96. package/dist/src/types/tool.js +12 -1
  97. package/dist/src/types/tool.js.map +1 -1
  98. package/docs/CONTRIBUTING.md +40 -0
  99. package/docs/README.md +12 -5
  100. package/docs/api/README.md +75 -45
  101. package/docs/api/overview.md +74 -32
  102. package/docs/core/agent/session-management.md +152 -5
  103. package/docs/core/ai-integration/response-processing.md +115 -4
  104. package/docs/core/conversation-flows/routes.md +130 -0
  105. package/docs/core/error-handling.md +638 -0
  106. package/docs/core/tools/tool-definition.md +684 -60
  107. package/docs/core/tools/tool-scoping.md +244 -53
  108. package/docs/guides/error-handling-patterns.md +578 -0
  109. package/docs/guides/getting-started/README.md +139 -28
  110. package/examples/advanced-patterns/knowledge-based-agent.ts +6 -6
  111. package/examples/advanced-patterns/persistent-onboarding.ts +30 -43
  112. package/examples/ai-providers/anthropic-integration.ts +9 -5
  113. package/examples/ai-providers/openai-integration.ts +11 -7
  114. package/examples/core-concepts/basic-agent.ts +106 -67
  115. package/examples/core-concepts/schema-driven-extraction.ts +10 -7
  116. package/examples/core-concepts/session-management.ts +71 -18
  117. package/examples/integrations/healthcare-integration.ts +15 -29
  118. package/examples/integrations/server-session-management.ts +3 -3
  119. package/examples/persistence/memory-sessions.ts +3 -3
  120. package/examples/tools/basic-tools.ts +293 -89
  121. package/examples/tools/data-enrichment-tools.ts +185 -75
  122. package/package.json +1 -1
  123. package/src/core/Agent.ts +98 -44
  124. package/src/core/ResponseModal.ts +148 -72
  125. package/src/core/ResponsePipeline.ts +82 -56
  126. package/src/core/Route.ts +39 -12
  127. package/src/core/RoutingEngine.ts +46 -42
  128. package/src/core/SessionManager.ts +39 -7
  129. package/src/core/Step.ts +198 -20
  130. package/src/core/ToolManager.ts +1394 -0
  131. package/src/index.ts +8 -3
  132. package/src/types/agent.ts +1 -1
  133. package/src/types/index.ts +13 -2
  134. package/src/types/route.ts +6 -4
  135. package/src/types/tool.ts +116 -25
  136. package/dist/cjs/src/core/ToolExecutor.d.ts +0 -45
  137. package/dist/cjs/src/core/ToolExecutor.d.ts.map +0 -1
  138. package/dist/cjs/src/core/ToolExecutor.js +0 -84
  139. package/dist/cjs/src/core/ToolExecutor.js.map +0 -1
  140. package/dist/src/core/ToolExecutor.d.ts +0 -45
  141. package/dist/src/core/ToolExecutor.d.ts.map +0 -1
  142. package/dist/src/core/ToolExecutor.js +0 -80
  143. package/dist/src/core/ToolExecutor.js.map +0 -1
  144. package/docs/core/tools/tool-execution.md +0 -815
  145. package/src/core/ToolExecutor.ts +0 -126
@@ -74,6 +74,72 @@ Adds a domain glossary term. Returns `this` for chaining.
74
74
 
75
75
  Adds a behavioral guideline. Returns `this` for chaining.
76
76
 
77
+ ##### `addTool(definition: Tool<TContext, TData, TResult>): this`
78
+
79
+ Creates and adds a tool to agent scope using the unified Tool interface. Returns `this` for chaining.
80
+
81
+ ```typescript
82
+ // Simple return value approach
83
+ agent.addTool({
84
+ id: "weather_check",
85
+ description: "Get current weather",
86
+ parameters: {
87
+ type: "object",
88
+ properties: {
89
+ location: { type: "string", description: "City name" }
90
+ },
91
+ required: ["location"]
92
+ },
93
+ handler: async ({ context, data }, args) => {
94
+ const weather = await weatherAPI.get(args.location);
95
+ return `Weather in ${args.location}: ${weather.condition}`;
96
+ }
97
+ });
98
+
99
+ // Advanced ToolResult pattern
100
+ agent.addTool({
101
+ id: "user_lookup",
102
+ description: "Look up user information",
103
+ handler: async ({ context, data }, args) => {
104
+ const user = await userAPI.find(args.userId);
105
+ return {
106
+ data: `Found user: ${user.name}`,
107
+ success: true,
108
+ contextUpdate: { currentUser: user },
109
+ dataUpdate: { userName: user.name }
110
+ };
111
+ }
112
+ });
113
+ ```
114
+
115
+ ##### `tool: ToolManager<TContext, TData>`
116
+
117
+ Access to the ToolManager instance for advanced tool operations.
118
+
119
+ ```typescript
120
+ // Register tools for ID-based reference
121
+ agent.tool.register({
122
+ id: "reusable_search",
123
+ description: "Search across data sources",
124
+ handler: async ({ context, data }, args) => "Search results"
125
+ });
126
+
127
+ // Create tools without adding to scope
128
+ const customTool = agent.tool.create({
129
+ id: "standalone_tool",
130
+ handler: async () => "Custom result"
131
+ });
132
+
133
+ // Use pattern helpers
134
+ const enrichmentTool = agent.tool.createDataEnrichment({
135
+ id: "enrich_profile",
136
+ fields: ['name', 'email'],
137
+ enricher: async (context, data) => ({
138
+ displayName: `${data.name} <${data.email}>`
139
+ })
140
+ });
141
+ ```
142
+
77
143
  ##### `respond(input: RespondInput<TContext>): Promise<RespondOutput>`
78
144
 
79
145
  Generates an AI response with session step management, tool execution, data extraction, and intelligent routing.
@@ -957,7 +1023,7 @@ Represents a step within a conversation route.
957
1023
 
958
1024
  #### Methods
959
1025
 
960
- ##### `nextStep(spec: StepOptions): StepResult`
1026
+ ##### `nextStep(spec: StepOptions): Step`
961
1027
 
962
1028
  Creates a transition from this step and returns a chainable result.
963
1029
 
@@ -982,10 +1048,14 @@ interface StepOptions<TData = unknown> {
982
1048
  condition?: string;
983
1049
  }
984
1050
 
985
- interface StepResult<TData = unknown> {
1051
+ interface Step<TContext = unknown, TData = unknown> {
986
1052
  id: string; // Step identifier
987
1053
  routeId: string; // Route identifier
988
- nextStep: (spec: StepOptions<TData>) => StepResult<TData>;
1054
+ nextStep: (spec: StepOptions<TContext, TData>) => Step<TContext, TData>;
1055
+ description?: string; // Step description
1056
+ collect?: (keyof TData)[]; // Fields to collect in this step
1057
+ skipIf?: (data: Partial<TData>) => boolean; // Skip condition function
1058
+ requires?: (keyof TData)[]; // Required data prerequisites
989
1059
  }
990
1060
  ```
991
1061
 
@@ -993,7 +1063,7 @@ interface StepResult<TData = unknown> {
993
1063
 
994
1064
  - `spec`: The transition specification (see `StepOptions` above). Can include an optional `condition` property for AI-evaluated step selection guidance.
995
1065
 
996
- **Returns:** A `StepResult` that includes the target step's reference (`id`, `routeId`) and a `nextStep` method for chaining additional transitions.
1066
+ **Returns:** A `Step` that includes the target step's reference (`id`, `routeId`) and a `nextStep` method for chaining additional transitions.
997
1067
 
998
1068
  **Example:**
999
1069
 
@@ -1110,14 +1180,7 @@ if (step.hasRequires(session.data)) {
1110
1180
  }
1111
1181
  ```
1112
1182
 
1113
- ##### `asStepResult(): StepResult<TContext, TData>`
1114
1183
 
1115
- Creates a transition result for this step that supports chaining.
1116
-
1117
- ```typescript
1118
- const result = step.asStepResult();
1119
- // Returns StepResult with nextStep method for chaining
1120
- ```
1121
1184
 
1122
1185
  ##### `configure(config): this`
1123
1186
 
@@ -1566,39 +1629,6 @@ Builds a fallback prompt when no routes are configured.
1566
1629
 
1567
1630
  ---
1568
1631
 
1569
- ### `ToolExecutor<TContext, TData>`
1570
-
1571
- Executes tools with context and security enforcement.
1572
-
1573
- #### Constructor
1574
-
1575
- ```typescript
1576
- new ToolExecutor<TContext, TData>();
1577
- ```
1578
-
1579
- #### Methods
1580
-
1581
- ##### `executeTool(params): Promise<ToolExecutionResult>`
1582
-
1583
- Executes a single tool with domain security enforcement.
1584
-
1585
- **Parameters:**
1586
-
1587
- - `tool`: Tool reference to execute
1588
- - `context`: Agent context
1589
- - `updateContext`: Function to update context
1590
- - `history`: Conversation history
1591
- - `data`: Collected session data
1592
- - `allowedDomains`: Array of allowed domain names
1593
-
1594
- **Returns:** Tool execution result with success status and data
1595
-
1596
- ##### `executeTools(params): Promise<ToolExecutionResult[]>`
1597
-
1598
- Executes multiple tools in sequence, stopping on first failure.
1599
-
1600
- ---
1601
-
1602
1632
  ### `Events`
1603
1633
 
1604
1634
  Utility functions for creating and adapting conversation events.
@@ -3016,4 +3046,4 @@ agent.createGuideline({
3016
3046
 
3017
3047
  ---
3018
3048
 
3019
- **Made with ❤️ for the community**
3049
+ **Made with ❤️ for the community**
@@ -12,7 +12,7 @@ Complete API documentation for `@falai/agent`. This framework provides a strongl
12
12
  - [RoutingEngine](#routingengine)
13
13
  - [ResponseEngine](#responseengine)
14
14
  - [PromptComposer](#promptcomposer)
15
- - [ToolExecutor](#toolexecutor)
15
+
16
16
  - [AI Providers](#ai-providers)
17
17
  - [Persistence Adapters](#persistence-adapters)
18
18
  - [Types & Interfaces](#types--interfaces)
@@ -136,9 +136,58 @@ for await (const chunk of agent.stream("Hello")) {
136
136
  ##### Tool Management
137
137
 
138
138
  ```typescript
139
- createTool(tool: Tool<TContext, unknown[], unknown, unknown>): this
140
- registerTools(tools: Tool<TContext, unknown[], unknown, unknown>[]): this
141
- getTools(): Tool<TContext, unknown[], unknown, unknown>[]
139
+ addTool(definition: Tool<TContext, TData, TResult>): this
140
+ tool: ToolManager<TContext, TData> // Access to ToolManager instance
141
+ ```
142
+
143
+ **Comprehensive Tool Examples:**
144
+
145
+ ```typescript
146
+ // 1. Simple return value (most common)
147
+ agent.addTool({
148
+ id: "calculate_tip",
149
+ description: "Calculate tip amount",
150
+ handler: async ({ context, data }, args) => {
151
+ const tip = args.amount * args.percentage;
152
+ return `Tip: $${tip.toFixed(2)}`; // Simple string return
153
+ }
154
+ });
155
+
156
+ // 2. Complex ToolResult pattern
157
+ agent.addTool({
158
+ id: "process_order",
159
+ description: "Process customer order",
160
+ handler: async ({ context, data }, args) => {
161
+ const order = await orderService.process(args.items);
162
+ return {
163
+ data: `Order ${order.id} processed successfully`,
164
+ success: true,
165
+ contextUpdate: { lastOrderId: order.id },
166
+ dataUpdate: { orderStatus: 'processed' }
167
+ }; // Detailed ToolResult object
168
+ }
169
+ });
170
+
171
+ // 3. Registry for reuse
172
+ agent.tool.register({
173
+ id: "send_notification",
174
+ description: "Send notification to user",
175
+ handler: async ({ context }, args) => {
176
+ await notificationService.send(context.userId, args.message);
177
+ return "Notification sent"; // Simple return
178
+ }
179
+ });
180
+
181
+ // 4. Pattern helper
182
+ const validationTool = agent.tool.createValidation({
183
+ id: "validate_email",
184
+ fields: ['email'],
185
+ validator: async (context, data) => ({
186
+ valid: /\S+@\S+\.\S+/.test(data.email),
187
+ errors: []
188
+ })
189
+ });
190
+ agent.tool.register(validationTool);
142
191
  ```
143
192
 
144
193
  ##### Domain Knowledge
@@ -301,9 +350,7 @@ getRoutingExtrasSchema(): StructuredSchema | undefined
301
350
  ##### Tool Management
302
351
 
303
352
  ```typescript
304
- createTool(tool: Tool<TContext, unknown[], unknown, TData>): this
305
- registerTools(tools: Tool<TContext, unknown[], unknown, TData>[]): this
306
- getTools(): Tool<TContext, unknown[], unknown, TData>[]
353
+ addTool(definition: Tool<TContext, TData, TResult>): this
307
354
  ```
308
355
 
309
356
  ##### Lifecycle Hooks
@@ -347,9 +394,9 @@ configure(config: Partial<StepOptions<TContext, TData>>): this
347
394
  ##### Transitions
348
395
 
349
396
  ```typescript
350
- nextStep(spec: StepOptions<TContext, TData>): StepResult<TContext, TData>
397
+ nextStep(spec: StepOptions<TContext, TData>): Step<TContext, TData>
351
398
  branch(branches: BranchSpec<TContext, TData>[]): BranchResult<TContext, TData>
352
- endRoute(options?: Omit<StepOptions<TContext, TData>, 'step'>): StepResult<TContext, TData>
399
+ endRoute(options?: Omit<StepOptions<TContext, TData>, 'step'>): Step<TContext, TData>
353
400
  ```
354
401
 
355
402
  ##### Validation
@@ -371,7 +418,6 @@ getTransitions(): Step<TContext, TData>[]
371
418
 
372
419
  ```typescript
373
420
  getRef(): StepRef
374
- asStepResult(): StepResult<TContext, TData>
375
421
  ```
376
422
 
377
423
  ---
@@ -505,23 +551,7 @@ addDirectives(directives?: string[]): Promise<this>
505
551
  build(): Promise<string>
506
552
  ```
507
553
 
508
- ---
509
-
510
- ### ToolExecutor
511
-
512
- Handles tool execution with context updates and data collection.
513
554
 
514
- #### Methods
515
-
516
- ```typescript
517
- executeTool(params: {
518
- tool: Tool;
519
- context: unknown;
520
- updateContext: (updates: Partial<unknown>) => Promise<void>;
521
- history: Event[];
522
- data: unknown;
523
- }): Promise<ToolExecutionResult>
524
- ```
525
555
 
526
556
  ---
527
557
 
@@ -756,21 +786,33 @@ interface StepOptions<TContext = unknown, TData = unknown> {
756
786
  }
757
787
  }
758
788
 
759
- // Example: Using existing tools (new approach)
789
+ // Example: Using existing tools (unified Tool interface)
760
790
  {
761
- prepare: "validate_user_data", // Tool ID string
762
- finalize: myCustomTool, // Tool object
791
+ prepare: "validate_user_data", // Tool ID string - simple return value
792
+ finalize: "send_notification", // Tool ID string - ToolResult pattern
763
793
  }
764
794
 
765
- // Example: Inline tool definition
795
+ // Example: Inline tool definition with flexible returns
766
796
  {
767
797
  prepare: {
768
798
  id: "setup_step_context",
769
799
  description: "Prepare context for this step",
770
800
  parameters: { type: "object", properties: {} },
771
801
  handler: ({ context, data }) => {
772
- // Custom logic here
773
- return { data: "Setup complete" };
802
+ // Simple return value
803
+ return "Setup complete";
804
+ }
805
+ },
806
+ finalize: {
807
+ id: "cleanup_step_context",
808
+ description: "Clean up after step completion",
809
+ handler: ({ context, data }) => {
810
+ // Complex ToolResult pattern
811
+ return {
812
+ data: "Cleanup complete",
813
+ success: true,
814
+ contextUpdate: { lastCleanup: new Date() }
815
+ };
774
816
  }
775
817
  }
776
818
  }
@@ -104,7 +104,7 @@ const response3 = await agent.respond("Also book me a hotel in Tokyo");
104
104
 
105
105
  **SessionManager API:**
106
106
 
107
- The `SessionManager` provides a clean API for session operations:
107
+ The `SessionManager` provides a clean API for session operations with comprehensive error handling:
108
108
 
109
109
  ```typescript
110
110
  // Access the session manager
@@ -114,13 +114,19 @@ const sessionManager = agent.session;
114
114
  await sessionManager.getOrCreate("user-123");
115
115
  await sessionManager.getOrCreate(); // Auto-generates ID
116
116
 
117
- // History management
118
- await sessionManager.addMessage("user", "Hello");
119
- await sessionManager.addMessage("assistant", "Hi there!");
117
+ // History management with error handling
118
+ try {
119
+ await sessionManager.addMessage("user", "Hello");
120
+ await sessionManager.addMessage("assistant", "Hi there!");
121
+ } catch (error) {
122
+ console.error("Failed to add message to history:", error);
123
+ // Message will be rolled back automatically
124
+ }
125
+
120
126
  const history = sessionManager.getHistory();
121
127
  sessionManager.clearHistory();
122
128
 
123
- // Data access
129
+ // Data access with synchronization
124
130
  const data = sessionManager.getData<FlightData>();
125
131
  await sessionManager.setData({ destination: "Paris" });
126
132
 
@@ -130,6 +136,147 @@ await sessionManager.delete();
130
136
  const newSession = await sessionManager.reset(true); // Preserve history
131
137
  ```
132
138
 
139
+ ### Agent-Session Data Synchronization
140
+
141
+ The framework ensures bidirectional synchronization between agent collected data and session data:
142
+
143
+ ```typescript
144
+ // Agent data updates automatically sync with session
145
+ const agent = new Agent<{}, BookingData>({
146
+ sessionId: "user-123",
147
+ // ... other config
148
+ });
149
+
150
+ try {
151
+ // Update agent data - automatically syncs with session
152
+ await agent.updateCollectedData({
153
+ destination: "Tokyo",
154
+ passengers: 2
155
+ });
156
+
157
+ // Session data is automatically updated
158
+ const sessionData = agent.session.getData<BookingData>();
159
+ console.log(sessionData.destination); // "Tokyo"
160
+
161
+ // Update session data - automatically syncs with agent
162
+ await agent.session.setData({
163
+ checkInDate: "2025-03-15"
164
+ });
165
+
166
+ // Agent data is automatically updated
167
+ const agentData = agent.getCollectedData();
168
+ console.log(agentData.checkInDate); // "2025-03-15"
169
+
170
+ } catch (error) {
171
+ console.error("Data synchronization failed:", error);
172
+ // Both agent and session data remain in consistent state
173
+ }
174
+ ```
175
+
176
+ ### Error Handling in Data Synchronization
177
+
178
+ ```typescript
179
+ class SessionManager<TData> {
180
+ async setData(data: Partial<TData>): Promise<void> {
181
+ const previousData = { ...this.session.data };
182
+
183
+ try {
184
+ // Validate data if schema is available
185
+ if (this.schema) {
186
+ this.validateData(data);
187
+ }
188
+
189
+ // Update session data
190
+ this.session.data = { ...this.session.data, ...data };
191
+
192
+ // Sync with agent collected data
193
+ if (this.agent) {
194
+ await this.agent.updateCollectedData(data);
195
+ }
196
+
197
+ // Persist changes
198
+ await this.save();
199
+
200
+ } catch (error) {
201
+ // Rollback session data on any failure
202
+ this.session.data = previousData;
203
+
204
+ console.error("Session data update failed, rolled back:", error);
205
+ throw new Error(`Data synchronization failed: ${error.message}`);
206
+ }
207
+ }
208
+
209
+ async addMessage(role: "user" | "assistant", content: string): Promise<void> {
210
+ const message: HistoryItem = {
211
+ role,
212
+ content,
213
+ timestamp: new Date().toISOString()
214
+ };
215
+
216
+ try {
217
+ // Add to session history
218
+ this.session.history.push(message);
219
+
220
+ // Persist immediately for reliability
221
+ await this.save();
222
+
223
+ } catch (error) {
224
+ // Remove message from history on persistence failure
225
+ this.session.history.pop();
226
+
227
+ console.error("Failed to persist message:", error);
228
+ throw new Error(`Message persistence failed: ${error.message}`);
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ ### Chat Method with Proper Error Handling
235
+
236
+ ```typescript
237
+ class Agent<TContext, TData> {
238
+ async chat(message: string, sessionId?: string): Promise<AgentResponse<TData>> {
239
+ try {
240
+ // Ensure session is loaded
241
+ if (!this.session || this.session.id !== sessionId) {
242
+ await this.loadSession(sessionId);
243
+ }
244
+
245
+ // Add user message to history BEFORE processing
246
+ await this.session.addMessage("user", message);
247
+
248
+ // Process the message
249
+ const response = await this.respond({
250
+ message,
251
+ sessionId: this.session.id
252
+ });
253
+
254
+ // Add assistant response to history
255
+ if (response.message) {
256
+ await this.session.addMessage("assistant", response.message);
257
+ }
258
+
259
+ return response;
260
+
261
+ } catch (error) {
262
+ console.error("Chat method failed:", error);
263
+
264
+ // Try to remove the user message if response failed
265
+ try {
266
+ const history = this.session.getHistory();
267
+ if (history.length > 0 && history[history.length - 1].role === "user") {
268
+ await this.session.removeLastMessage();
269
+ }
270
+ } catch (rollbackError) {
271
+ console.error("Failed to rollback user message:", rollbackError);
272
+ }
273
+
274
+ throw new Error(`Chat failed: ${error.message}`);
275
+ }
276
+ }
277
+ }
278
+ ```
279
+
133
280
  **Why?** Automatic session management provides:
134
281
 
135
282
  - **Zero Boilerplate** - No manual session creation or persistence code
@@ -118,10 +118,121 @@ agentContext.lastResponseTime = Date.now();
118
118
 
119
119
  Robust error handling for various failure scenarios:
120
120
 
121
- - **Schema validation failures** - Graceful fallback to manual extraction
122
- - **Tool execution errors** - Error recovery and user notification
123
- - **Context update failures** - Rollback and logging
124
- - **Routing errors** - Safe fallback to default behavior
121
+ ### Schema Validation Failures
122
+
123
+ When AI responses don't match expected schemas, the system gracefully falls back:
124
+
125
+ ```typescript
126
+ const processResponse = async (response: string, schema: JSONSchema) => {
127
+ try {
128
+ // Try schema-based extraction first
129
+ const extracted = await extractWithSchema(response, schema);
130
+ return { success: true, data: extracted };
131
+ } catch (schemaError) {
132
+ console.warn("Schema extraction failed, falling back to manual parsing:", schemaError.message);
133
+
134
+ // Fallback to manual extraction
135
+ try {
136
+ const manualData = await manualExtraction(response);
137
+ return { success: true, data: manualData, fallback: true };
138
+ } catch (fallbackError) {
139
+ return {
140
+ success: false,
141
+ error: `Both schema and manual extraction failed: ${fallbackError.message}`
142
+ };
143
+ }
144
+ }
145
+ };
146
+ ```
147
+
148
+ ### Tool Execution Errors
149
+
150
+ Tool failures are handled gracefully with proper error propagation:
151
+
152
+ ```typescript
153
+ const executeTool = async (tool: Tool, params: any) => {
154
+ try {
155
+ const result = await tool.handler(params);
156
+ return { success: true, result };
157
+ } catch (error) {
158
+ console.error(`Tool ${tool.id} execution failed:`, error);
159
+
160
+ return {
161
+ success: false,
162
+ error: error.message,
163
+ fallbackMessage: "I encountered an issue while processing your request. Please try again."
164
+ };
165
+ }
166
+ };
167
+ ```
168
+
169
+ ### Context Update Failures
170
+
171
+ Context updates include rollback mechanisms:
172
+
173
+ ```typescript
174
+ const updateContext = async (newContext: any, previousContext: any) => {
175
+ try {
176
+ await persistContext(newContext);
177
+ return { success: true };
178
+ } catch (error) {
179
+ console.error("Context update failed, rolling back:", error);
180
+
181
+ try {
182
+ await persistContext(previousContext);
183
+ return { success: false, rolledBack: true, error: error.message };
184
+ } catch (rollbackError) {
185
+ return {
186
+ success: false,
187
+ rolledBack: false,
188
+ error: `Update and rollback both failed: ${rollbackError.message}`
189
+ };
190
+ }
191
+ }
192
+ };
193
+ ```
194
+
195
+ ### Streaming Error Propagation
196
+
197
+ Streaming responses properly propagate provider errors:
198
+
199
+ ```typescript
200
+ async function* processStreamingResponse(provider: AIProvider, prompt: string) {
201
+ try {
202
+ for await (const chunk of provider.generateMessageStream(prompt)) {
203
+ yield { success: true, chunk };
204
+ }
205
+ } catch (error) {
206
+ // Ensure streaming errors are properly propagated
207
+ yield { success: false, error: error.message };
208
+ throw error; // Re-throw to stop the stream
209
+ }
210
+ }
211
+ ```
212
+
213
+ ### Routing Errors
214
+
215
+ Safe fallback to default behavior when routing fails:
216
+
217
+ ```typescript
218
+ const selectRoute = async (routes: Route[], context: any) => {
219
+ try {
220
+ const selectedRoute = await aiRouting.selectBestRoute(routes, context);
221
+ return { success: true, route: selectedRoute };
222
+ } catch (routingError) {
223
+ console.warn("AI routing failed, using default route:", routingError.message);
224
+
225
+ // Fallback to first available route or default
226
+ const fallbackRoute = routes.find(r => r.isDefault) || routes[0];
227
+ return {
228
+ success: true,
229
+ route: fallbackRoute,
230
+ fallback: true,
231
+ error: routingError.message
232
+ };
233
+ }
234
+ };
235
+ ```
125
236
 
126
237
  ## Streaming Response Processing
127
238