@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
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Example: Modern Streaming API
3
+ *
4
+ * This example demonstrates the new agent.stream() method introduced in the
5
+ * ResponseModal refactor. The modern API provides automatic session management
6
+ * and a simpler interface compared to the legacy respondStream() method.
7
+ */
8
+
9
+ import {
10
+ Agent,
11
+ AnthropicProvider,
12
+ OpenAIProvider,
13
+ } from "../../src/index";
14
+
15
+ // Context type for our examples
16
+ interface UserContext {
17
+ userId: string;
18
+ preferences: {
19
+ language?: string;
20
+ verbosity: "concise" | "detailed";
21
+ };
22
+ }
23
+
24
+ async function basicModernStreaming() {
25
+ console.log("\nšŸš€ Example 1: Basic Modern Streaming API\n");
26
+
27
+ const provider = new AnthropicProvider({
28
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
29
+ model: "claude-sonnet-4-5",
30
+ });
31
+
32
+ const agent = new Agent<UserContext, unknown>({
33
+ name: "ModernStreamingAgent",
34
+ description: "Demonstrates the new stream() API",
35
+ context: {
36
+ userId: "user123",
37
+ preferences: {
38
+ language: "English",
39
+ verbosity: "concise",
40
+ },
41
+ },
42
+ provider,
43
+ });
44
+
45
+ try {
46
+ console.log("šŸ“¤ Using modern stream() API...\n");
47
+ console.log("Response: ");
48
+
49
+ // NEW: Simple streaming with automatic session management
50
+ for await (const chunk of agent.stream("What is machine learning?")) {
51
+ if (chunk.delta) {
52
+ process.stdout.write(chunk.delta);
53
+ }
54
+
55
+ if (chunk.done) {
56
+ console.log("\n\nāœ… Stream complete!");
57
+ console.log(`šŸ“Š Session has ${agent.session.getHistory().length} messages`);
58
+ console.log("šŸ’” Session history was automatically managed!");
59
+ }
60
+ }
61
+ } catch (error) {
62
+ console.error("āŒ Error:", error);
63
+ }
64
+ }
65
+
66
+ async function streamingWithOptions() {
67
+ console.log("\nšŸš€ Example 2: Streaming with Options\n");
68
+
69
+ const provider = new OpenAIProvider({
70
+ apiKey: process.env.OPENAI_API_KEY || "",
71
+ model: "gpt-4",
72
+ });
73
+
74
+ const agent = new Agent<UserContext, unknown>({
75
+ name: "OptionsStreamingAgent",
76
+ description: "Demonstrates streaming with options",
77
+ context: {
78
+ userId: "user456",
79
+ preferences: {
80
+ language: "English",
81
+ verbosity: "detailed",
82
+ },
83
+ },
84
+ provider,
85
+ });
86
+
87
+ try {
88
+ console.log("šŸ“¤ Streaming with context override and abort signal...\n");
89
+ console.log("Response: ");
90
+
91
+ // Create abort controller for cancellation
92
+ const abortController = new AbortController();
93
+
94
+ // Cancel after 10 seconds
95
+ setTimeout(() => {
96
+ console.log("\nāš ļø Aborting stream...");
97
+ abortController.abort();
98
+ }, 10000);
99
+
100
+ // Stream with options
101
+ for await (const chunk of agent.stream("Explain quantum computing in detail", {
102
+ contextOverride: {
103
+ preferences: { verbosity: "concise" } // Override to be more concise
104
+ },
105
+ signal: abortController.signal
106
+ })) {
107
+ if (chunk.delta) {
108
+ process.stdout.write(chunk.delta);
109
+ }
110
+
111
+ if (chunk.done) {
112
+ console.log("\n\nāœ… Stream complete!");
113
+ console.log("šŸ’” Context was overridden for this response only");
114
+ clearTimeout();
115
+ }
116
+ }
117
+ } catch (error) {
118
+ if (error instanceof Error && error.name === "AbortError") {
119
+ console.log("\nšŸ›‘ Stream was successfully aborted!");
120
+ } else {
121
+ console.error("āŒ Error:", error);
122
+ }
123
+ }
124
+ }
125
+
126
+ async function conversationFlow() {
127
+ console.log("\nšŸš€ Example 3: Multi-turn Conversation Flow\n");
128
+
129
+ const provider = new AnthropicProvider({
130
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
131
+ model: "claude-sonnet-4-5",
132
+ });
133
+
134
+ const agent = new Agent<UserContext, unknown>({
135
+ name: "ConversationAgent",
136
+ description: "Demonstrates multi-turn conversations",
137
+ context: {
138
+ userId: "user789",
139
+ preferences: {
140
+ language: "English",
141
+ verbosity: "detailed",
142
+ },
143
+ },
144
+ provider,
145
+ });
146
+
147
+ const messages = [
148
+ "What is TypeScript?",
149
+ "How is it different from JavaScript?",
150
+ "Can you give me a simple example?",
151
+ "Thank you for the explanation!"
152
+ ];
153
+
154
+ try {
155
+ console.log("šŸ“¤ Multi-turn conversation with automatic session management...\n");
156
+
157
+ for (let i = 0; i < messages.length; i++) {
158
+ console.log(`\n${"=".repeat(60)}`);
159
+ console.log(`šŸ’¬ Turn ${i + 1}: ${messages[i]}`);
160
+ console.log(`${"=".repeat(60)}`);
161
+ console.log("Response: ");
162
+
163
+ // Each stream() call automatically manages the session
164
+ for await (const chunk of agent.stream(messages[i])) {
165
+ if (chunk.delta) {
166
+ process.stdout.write(chunk.delta);
167
+ }
168
+
169
+ if (chunk.done) {
170
+ console.log(`\nšŸ“Š Session now has ${agent.session.getHistory().length} messages`);
171
+ }
172
+ }
173
+ }
174
+
175
+ console.log("\nāœ… Conversation complete!");
176
+ console.log("šŸ’” All session management was handled automatically");
177
+ console.log(`šŸ“Š Final session has ${agent.session.getHistory().length} messages`);
178
+
179
+ } catch (error) {
180
+ console.error("āŒ Error:", error);
181
+ }
182
+ }
183
+
184
+ async function migrationComparison() {
185
+ console.log("\nšŸš€ Example 4: Migration from respondStream() to stream()\n");
186
+
187
+ const provider = new AnthropicProvider({
188
+ apiKey: process.env.ANTHROPIC_API_KEY || "",
189
+ model: "claude-sonnet-4-5",
190
+ });
191
+
192
+ const agent = new Agent<UserContext, unknown>({
193
+ name: "MigrationAgent",
194
+ description: "Shows migration from old to new API",
195
+ context: {
196
+ userId: "migration-user",
197
+ preferences: {
198
+ language: "English",
199
+ verbosity: "concise",
200
+ },
201
+ },
202
+ provider,
203
+ });
204
+
205
+ const userMessage = "What are the benefits of TypeScript?";
206
+
207
+ try {
208
+ // ========================================================================
209
+ // OLD WAY: respondStream() - Manual session management
210
+ // ========================================================================
211
+ console.log("šŸ”ø OLD WAY: Using respondStream() with manual session management");
212
+ console.log("Code: agent.respondStream({ history: agent.session.getHistory() })");
213
+ console.log("Response: ");
214
+
215
+ // Manual session management required
216
+ await agent.session.addMessage("user", userMessage);
217
+
218
+ let oldResponse = "";
219
+ for await (const chunk of agent.respondStream({
220
+ history: agent.session.getHistory()
221
+ })) {
222
+ if (chunk.delta) {
223
+ process.stdout.write(chunk.delta);
224
+ oldResponse += chunk.delta;
225
+ }
226
+
227
+ if (chunk.done) {
228
+ // Manual history update required
229
+ await agent.session.addMessage("assistant", oldResponse);
230
+ console.log("\n āœ… Manual session update completed");
231
+ }
232
+ }
233
+
234
+ console.log("\n" + "=".repeat(60));
235
+
236
+ // ========================================================================
237
+ // NEW WAY: stream() - Automatic session management
238
+ // ========================================================================
239
+ console.log("šŸ”ø NEW WAY: Using stream() with automatic session management");
240
+ console.log("Code: agent.stream('message')");
241
+ console.log("Response: ");
242
+
243
+ // Automatic session management - just pass the message!
244
+ for await (const chunk of agent.stream("Can you elaborate on the type safety benefits?")) {
245
+ if (chunk.delta) {
246
+ process.stdout.write(chunk.delta);
247
+ }
248
+
249
+ if (chunk.done) {
250
+ console.log("\n āœ… Automatic session update - no manual work needed!");
251
+ }
252
+ }
253
+
254
+ console.log("\nšŸ“Š Migration Benefits:");
255
+ console.log(" āœ… Simpler API: agent.stream('message') vs complex parameters");
256
+ console.log(" āœ… Automatic session management - no manual addMessage() calls");
257
+ console.log(" āœ… Same performance and features as respondStream()");
258
+ console.log(" āœ… Backward compatibility - respondStream() still works");
259
+ console.log(" āœ… Consistent with chat() API patterns");
260
+
261
+ console.log(`\nšŸ“Š Final session has ${agent.session.getHistory().length} messages`);
262
+
263
+ } catch (error) {
264
+ console.error("āŒ Error:", error);
265
+ }
266
+ }
267
+
268
+ async function main() {
269
+ console.log("šŸš€ Modern Streaming API Examples");
270
+ console.log("=".repeat(60));
271
+
272
+ const examples = [
273
+ { name: "Basic Modern Streaming", fn: basicModernStreaming },
274
+ { name: "Streaming with Options", fn: streamingWithOptions },
275
+ { name: "Multi-turn Conversation", fn: conversationFlow },
276
+ { name: "Migration Comparison", fn: migrationComparison },
277
+ ];
278
+
279
+ console.log("\nAvailable Examples:");
280
+ examples.forEach((ex, i) => {
281
+ console.log(` ${i + 1}. ${ex.name}`);
282
+ });
283
+
284
+ console.log("\nšŸ’” Key Benefits of Modern stream() API:");
285
+ console.log(" - Simple interface: agent.stream('message')");
286
+ console.log(" - Automatic session management");
287
+ console.log(" - No manual history updates needed");
288
+ console.log(" - Same performance as respondStream()");
289
+ console.log(" - Full backward compatibility maintained");
290
+
291
+ console.log("\n" + "=".repeat(60));
292
+
293
+ // Run examples if API key is available
294
+ if (process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY) {
295
+ await basicModernStreaming();
296
+ await migrationComparison();
297
+ } else {
298
+ console.log(
299
+ "\nāš ļø Set ANTHROPIC_API_KEY or OPENAI_API_KEY to run examples."
300
+ );
301
+ }
302
+ }
303
+
304
+ // Run if executed directly
305
+ if (import.meta.url === `file://${process.argv[1]}`) {
306
+ main().catch(console.error);
307
+ }
308
+
309
+ export { main };
@@ -24,7 +24,7 @@ interface UserProfileData {
24
24
  }
25
25
 
26
26
  // Define a tool that uses the collected data
27
- const saveUserProfile: Tool<unknown, [], string, UserProfileData> = {
27
+ const saveUserProfile: Tool<unknown, UserProfileData, [], string> = {
28
28
  id: "save_user_profile",
29
29
  description: "Save the collected user profile information",
30
30
  parameters: {
@@ -37,24 +37,12 @@ const saveUserProfile: Tool<unknown, [], string, UserProfileData> = {
37
37
  // Simulate saving to database
38
38
  console.log("Profile data:", data);
39
39
 
40
- const userData = data as Partial<UserProfileData>;
41
40
  return {
42
- data: `Profile saved successfully! Welcome ${userData?.name}!`,
41
+ data: `Profile saved successfully! Welcome ${data?.name}!`,
43
42
  };
44
43
  },
45
44
  };
46
45
 
47
- // Create the agent
48
- const agent = new Agent({
49
- name: "ProfileBot",
50
- description:
51
- "A bot that collects user profile information using schema-driven extraction",
52
- provider: new GeminiProvider({
53
- apiKey: process.env.GEMINI_API_KEY!,
54
- model: "models/gemini-2.5-flash",
55
- }),
56
- });
57
-
58
46
  // Define the schema for data validation and extraction
59
47
  const userProfileSchema = {
60
48
  type: "object",
@@ -98,11 +86,27 @@ const userProfileSchema = {
98
86
  required: ["name", "email"],
99
87
  };
100
88
 
89
+ // Create the agent with agent-level schema
90
+ const agent = new Agent<unknown, UserProfileData>({
91
+ name: "ProfileBot",
92
+ description:
93
+ "A bot that collects user profile information using schema-driven extraction",
94
+ provider: new GeminiProvider({
95
+ apiKey: process.env.GEMINI_API_KEY!,
96
+ model: "models/gemini-2.5-flash",
97
+ }),
98
+ // NEW: Agent-level schema definition
99
+ schema: userProfileSchema,
100
+ });
101
+
101
102
  // Create a route that collects profile information step by step
102
- agent.createRoute<UserProfileData>({
103
+ agent.createRoute({
103
104
  title: "User Profile Collection",
104
105
  description: "Collect comprehensive user profile information",
105
- schema: userProfileSchema,
106
+ // NEW: Required fields for route completion (instead of schema)
107
+ requiredFields: ["name", "email"],
108
+ // NEW: Optional fields that enhance the experience
109
+ optionalFields: ["age", "interests", "preferredContact", "newsletterOptIn"],
106
110
  // Use sequential steps for a linear flow with smart skipIf conditions
107
111
  steps: [
108
112
  {
@@ -43,7 +43,7 @@ interface PaymentData {
43
43
  }
44
44
 
45
45
  // Tools for order processing
46
- const createOrder: Tool<unknown, [], string, OrderData> = {
46
+ const createOrder: Tool<unknown, UnifiedOrderData, [], string> = {
47
47
  id: "create_order",
48
48
  description: "Create a new order from the collected order data",
49
49
  parameters: {
@@ -52,8 +52,7 @@ const createOrder: Tool<unknown, [], string, OrderData> = {
52
52
  },
53
53
  handler: ({ data }) => {
54
54
  const orderId = `ORD-${Date.now()}`;
55
- const orderData = data as Partial<OrderData>;
56
- console.log(`Creating order ${orderId} for ${orderData?.customerName}`);
55
+ console.log(`Creating order ${orderId} for ${data?.customerName}`);
57
56
 
58
57
  return {
59
58
  data: `Order ${orderId} created successfully!`,
@@ -64,7 +63,7 @@ const createOrder: Tool<unknown, [], string, OrderData> = {
64
63
  },
65
64
  };
66
65
 
67
- const processPayment: Tool<unknown, [], string, PaymentData> = {
66
+ const processPayment: Tool<unknown, UnifiedOrderData, [], string> = {
68
67
  id: "process_payment",
69
68
  description: "Process payment for an order",
70
69
  parameters: {
@@ -72,15 +71,14 @@ const processPayment: Tool<unknown, [], string, PaymentData> = {
72
71
  properties: {},
73
72
  },
74
73
  handler: ({ data }) => {
75
- const paymentData = data as Partial<PaymentData>;
76
- console.log(`Processing payment for order ${paymentData?.orderId}`);
74
+ console.log(`Processing payment for order ${data?.orderId}`);
77
75
 
78
76
  // Simulate payment processing
79
77
  const success = Math.random() > 0.1; // 90% success rate
80
78
 
81
79
  if (success) {
82
80
  return {
83
- data: `Payment processed successfully! Order ${paymentData?.orderId} is now confirmed.`,
81
+ data: `Payment processed successfully! Order ${data?.orderId} is now confirmed.`,
84
82
  dataUpdate: {
85
83
  confirmed: true,
86
84
  },
@@ -96,8 +94,31 @@ const processPayment: Tool<unknown, [], string, PaymentData> = {
96
94
  },
97
95
  };
98
96
 
99
- // Create agent with persistence
100
- const agent = new Agent({
97
+ // Define unified data schema for all order-related interactions
98
+ interface UnifiedOrderData extends OrderData, PaymentData {}
99
+
100
+ const orderSchema = {
101
+ type: "object",
102
+ properties: {
103
+ // Order fields
104
+ customerName: { type: "string" },
105
+ productType: { type: "string", enum: ["laptop", "phone", "tablet"] },
106
+ budget: { type: "number", minimum: 100 },
107
+ preferredColor: { type: "string" },
108
+ urgentDelivery: { type: "boolean" },
109
+ orderId: { type: "string" },
110
+ // Payment fields
111
+ paymentMethod: {
112
+ type: "string",
113
+ enum: ["credit_card", "paypal", "bank_transfer"],
114
+ },
115
+ amount: { type: "number" },
116
+ confirmed: { type: "boolean" },
117
+ },
118
+ };
119
+
120
+ // Create agent with persistence and agent-level schema
121
+ const agent = new Agent<unknown, UnifiedOrderData>({
101
122
  name: "OrderBot",
102
123
  description:
103
124
  "A bot that handles multi-step order processing with session management",
@@ -105,27 +126,21 @@ const agent = new Agent({
105
126
  apiKey: process.env.GEMINI_API_KEY!,
106
127
  model: "models/gemini-2.5-flash",
107
128
  }),
129
+ // NEW: Agent-level schema
130
+ schema: orderSchema,
108
131
  persistence: {
109
132
  adapter: new MemoryAdapter(), // In production, use RedisAdapter, PrismaAdapter, etc.
110
133
  },
111
134
  });
112
135
 
113
136
  // Order collection route with sequential steps
114
- agent.createRoute<OrderData>({
137
+ agent.createRoute({
115
138
  title: "Product Order",
116
139
  description: "Collect order details and create an order",
117
- schema: {
118
- type: "object",
119
- properties: {
120
- customerName: { type: "string" },
121
- productType: { type: "string", enum: ["laptop", "phone", "tablet"] },
122
- budget: { type: "number", minimum: 100 },
123
- preferredColor: { type: "string" },
124
- urgentDelivery: { type: "boolean" },
125
- orderId: { type: "string" },
126
- },
127
- required: ["customerName", "productType", "budget"],
128
- },
140
+ // NEW: Required fields for route completion
141
+ requiredFields: ["customerName", "productType", "budget"],
142
+ // NEW: Optional fields that enhance the experience
143
+ optionalFields: ["preferredColor", "urgentDelivery", "orderId"],
129
144
  // Sequential steps for order collection
130
145
  steps: [
131
146
  {
@@ -133,7 +148,7 @@ agent.createRoute<OrderData>({
133
148
  description: "Ask for customer name",
134
149
  prompt: "Hi! I'd like to help you place an order. What's your name?",
135
150
  collect: ["customerName"],
136
- skipIf: (data: Partial<OrderData>) => !!data.customerName,
151
+ skipIf: (data: Partial<UnifiedOrderData>) => !!data.customerName,
137
152
  },
138
153
  {
139
154
  id: "ask_product",
@@ -141,7 +156,7 @@ agent.createRoute<OrderData>({
141
156
  prompt: "What would you like to order? (laptop, phone, or tablet)",
142
157
  collect: ["productType"],
143
158
  requires: ["customerName"],
144
- skipIf: (data: Partial<OrderData>) => !!data.productType,
159
+ skipIf: (data: Partial<UnifiedOrderData>) => !!data.productType,
145
160
  },
146
161
  {
147
162
  id: "ask_budget",
@@ -149,7 +164,7 @@ agent.createRoute<OrderData>({
149
164
  prompt: "What's your budget for this purchase?",
150
165
  collect: ["budget"],
151
166
  requires: ["customerName", "productType"],
152
- skipIf: (data: Partial<OrderData>) => data.budget !== undefined,
167
+ skipIf: (data: Partial<UnifiedOrderData>) => data.budget !== undefined,
153
168
  },
154
169
  {
155
170
  id: "ask_color",
@@ -157,7 +172,7 @@ agent.createRoute<OrderData>({
157
172
  prompt: "Do you have a preferred color?",
158
173
  collect: ["preferredColor"],
159
174
  requires: ["customerName", "productType", "budget"],
160
- skipIf: (data: Partial<OrderData>) => !!data.preferredColor,
175
+ skipIf: (data: Partial<UnifiedOrderData>) => !!data.preferredColor,
161
176
  },
162
177
  {
163
178
  id: "ask_urgent",
@@ -165,7 +180,7 @@ agent.createRoute<OrderData>({
165
180
  prompt: "Do you need urgent delivery?",
166
181
  collect: ["urgentDelivery"],
167
182
  requires: ["customerName", "productType", "budget"],
168
- skipIf: (data: Partial<OrderData>) => data.urgentDelivery !== undefined,
183
+ skipIf: (data: Partial<UnifiedOrderData>) => data.urgentDelivery !== undefined,
169
184
  },
170
185
  {
171
186
  id: "create_order",
@@ -182,22 +197,13 @@ agent.createRoute<OrderData>({
182
197
  });
183
198
 
184
199
  // Payment route with sequential steps
185
- agent.createRoute<PaymentData>({
200
+ agent.createRoute({
186
201
  title: "Payment Processing",
187
202
  description: "Process payment for an order",
188
- schema: {
189
- type: "object",
190
- properties: {
191
- orderId: { type: "string" },
192
- paymentMethod: {
193
- type: "string",
194
- enum: ["credit_card", "paypal", "bank_transfer"],
195
- },
196
- amount: { type: "number" },
197
- confirmed: { type: "boolean" },
198
- },
199
- required: ["orderId", "paymentMethod", "amount"],
200
- },
203
+ // NEW: Required fields for route completion
204
+ requiredFields: ["orderId", "paymentMethod", "amount"],
205
+ // NEW: Optional fields
206
+ optionalFields: ["confirmed"],
201
207
  // Sequential steps for payment processing
202
208
  steps: [
203
209
  {
@@ -206,7 +212,7 @@ agent.createRoute<PaymentData>({
206
212
  prompt:
207
213
  "Now let's process payment for your order. What payment method would you prefer?",
208
214
  collect: ["paymentMethod"],
209
- skipIf: (data: Partial<PaymentData>) => !!data.paymentMethod,
215
+ skipIf: (data: Partial<UnifiedOrderData>) => !!data.paymentMethod,
210
216
  },
211
217
  {
212
218
  id: "ask_amount",
@@ -214,7 +220,7 @@ agent.createRoute<PaymentData>({
214
220
  prompt: "What's the payment amount?",
215
221
  collect: ["amount"],
216
222
  requires: ["paymentMethod"],
217
- skipIf: (data: Partial<PaymentData>) => data.amount !== undefined,
223
+ skipIf: (data: Partial<UnifiedOrderData>) => data.amount !== undefined,
218
224
  },
219
225
  {
220
226
  id: "process_payment",
@@ -232,13 +238,15 @@ async function demonstrateSessionManagement() {
232
238
  console.log("=== Automatic Session Management Demo ===\n");
233
239
 
234
240
  // Create agent with automatic session management
235
- const sessionAgent = new Agent({
241
+ const sessionAgent = new Agent<unknown, UnifiedOrderData>({
236
242
  name: "OrderBot",
237
243
  description: "A bot that handles multi-step order processing",
238
244
  provider: new GeminiProvider({
239
245
  apiKey: process.env.GEMINI_API_KEY!,
240
246
  model: "models/gemini-2.5-flash",
241
247
  }),
248
+ // NEW: Agent-level schema
249
+ schema: orderSchema,
242
250
  persistence: {
243
251
  adapter: new MemoryAdapter(),
244
252
  },
@@ -258,7 +266,7 @@ async function demonstrateSessionManagement() {
258
266
 
259
267
  console.log("Bot:", response1.message);
260
268
  console.log("Session ID:", sessionAgent.session.id);
261
- console.log("Session data:", JSON.stringify(sessionAgent.session.getData<OrderData>(), null, 2));
269
+ console.log("Session data:", JSON.stringify(sessionAgent.session.getData<UnifiedOrderData>(), null, 2));
262
270
  console.log("History length:", sessionAgent.session.getHistory().length);
263
271
  console.log();
264
272
 
@@ -269,7 +277,7 @@ async function demonstrateSessionManagement() {
269
277
  const response2 = await sessionAgent.chat("My budget is $1500");
270
278
 
271
279
  console.log("Bot:", response2.message);
272
- console.log("Session data:", JSON.stringify(sessionAgent.session.getData<OrderData>(), null, 2));
280
+ console.log("Session data:", JSON.stringify(sessionAgent.session.getData<UnifiedOrderData>(), null, 2));
273
281
  console.log("History length:", sessionAgent.session.getHistory().length);
274
282
  console.log();
275
283
 
@@ -280,7 +288,7 @@ async function demonstrateSessionManagement() {
280
288
  const response3 = await sessionAgent.chat("I want black color and urgent delivery please");
281
289
 
282
290
  console.log("Bot:", response3.message);
283
- console.log("Session data:", JSON.stringify(sessionAgent.session.getData<OrderData>(), null, 2));
291
+ console.log("Session data:", JSON.stringify(sessionAgent.session.getData<UnifiedOrderData>(), null, 2));
284
292
  console.log("Route complete:", response3.isRouteComplete);
285
293
  console.log("History length:", sessionAgent.session.getHistory().length);
286
294
  console.log();
@@ -292,7 +300,7 @@ async function demonstrateSessionManagement() {
292
300
  const response4 = await sessionAgent.chat("I'll pay with credit card, amount is $1599");
293
301
 
294
302
  console.log("Bot:", response4.message);
295
- console.log("Session data:", JSON.stringify(sessionAgent.session.getData<PaymentData>(), null, 2));
303
+ console.log("Session data:", JSON.stringify(sessionAgent.session.getData<UnifiedOrderData>(), null, 2));
296
304
  console.log("Route complete:", response4.isRouteComplete);
297
305
  console.log("Final history length:", sessionAgent.session.getHistory().length);
298
306
  }
@@ -303,7 +311,7 @@ async function demonstrateSessionPersistence() {
303
311
 
304
312
  // Create agent with specific sessionId for demonstration
305
313
  const sessionId = "demo-session-456";
306
- const persistentAgent = new Agent<OrderContext>({
314
+ const persistentAgent = new Agent<OrderContext, UnifiedOrderData>({
307
315
  name: "Order Assistant",
308
316
  description: "Help customers place orders with automatic persistence",
309
317
  provider: new GeminiProvider({
@@ -315,6 +323,8 @@ async function demonstrateSessionPersistence() {
315
323
  userName: "Alice",
316
324
  isVip: false,
317
325
  },
326
+ // NEW: Agent-level schema
327
+ schema: orderSchema,
318
328
  persistence: {
319
329
  adapter: new MemoryAdapter(),
320
330
  autoSave: true, // Automatic persistence
@@ -334,14 +344,14 @@ async function demonstrateSessionPersistence() {
334
344
 
335
345
  console.log("After first interaction:");
336
346
  console.log("šŸ¤– Agent:", response1.message);
337
- console.log("Session data:", JSON.stringify(persistentAgent.session.getData<OrderData>(), null, 2));
347
+ console.log("Session data:", JSON.stringify(persistentAgent.session.getData<UnifiedOrderData>(), null, 2));
338
348
  console.log("History length:", persistentAgent.session.getHistory().length);
339
349
  console.log("Session automatically saved to persistence āœ“");
340
350
 
341
351
  // Simulate server restart - create new agent instance with same sessionId
342
352
  console.log("\nšŸ”„ Simulating server restart - creating new agent instance...");
343
353
 
344
- const restoredAgent = new Agent<OrderContext>({
354
+ const restoredAgent = new Agent<OrderContext, UnifiedOrderData>({
345
355
  name: "Order Assistant",
346
356
  provider: new GeminiProvider({
347
357
  apiKey: process.env.GEMINI_API_KEY!,
@@ -352,6 +362,8 @@ async function demonstrateSessionPersistence() {
352
362
  userName: "Alice",
353
363
  isVip: false,
354
364
  },
365
+ // NEW: Agent-level schema
366
+ schema: orderSchema,
355
367
  persistence: {
356
368
  adapter: new MemoryAdapter(), // Same adapter instance for demo
357
369
  autoSave: true,
@@ -367,14 +379,14 @@ async function demonstrateSessionPersistence() {
367
379
  console.log("Session automatically restored:");
368
380
  console.log("- Session ID:", restoredAgent.session.id);
369
381
  console.log("- History length:", restoredAgent.session.getHistory().length);
370
- console.log("- Restored data:", JSON.stringify(restoredAgent.session.getData<OrderData>(), null, 2));
382
+ console.log("- Restored data:", JSON.stringify(restoredAgent.session.getData<UnifiedOrderData>(), null, 2));
371
383
 
372
384
  // Continue conversation seamlessly
373
385
  const response2 = await restoredAgent.chat("Actually, make it urgent delivery");
374
386
 
375
387
  console.log("\nAfter continuing with restored session:");
376
388
  console.log("šŸ¤– Agent:", response2.message);
377
- console.log("Session data:", JSON.stringify(restoredAgent.session.getData<OrderData>(), null, 2));
389
+ console.log("Session data:", JSON.stringify(restoredAgent.session.getData<UnifiedOrderData>(), null, 2));
378
390
  console.log("History length:", restoredAgent.session.getHistory().length);
379
391
  console.log("Session automatically saved again āœ“");
380
392
  }