@falai/agent 0.4.1 → 0.5.1

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 (285) hide show
  1. package/README.md +21 -74
  2. package/dist/cjs/core/Agent.d.ts +22 -29
  3. package/dist/cjs/core/Agent.d.ts.map +1 -1
  4. package/dist/cjs/core/Agent.js +464 -291
  5. package/dist/cjs/core/Agent.js.map +1 -1
  6. package/dist/cjs/core/Events.d.ts +10 -1
  7. package/dist/cjs/core/Events.d.ts.map +1 -1
  8. package/dist/cjs/core/Events.js +3 -2
  9. package/dist/cjs/core/Events.js.map +1 -1
  10. package/dist/cjs/core/PersistenceManager.d.ts +19 -0
  11. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
  12. package/dist/cjs/core/PersistenceManager.js +55 -0
  13. package/dist/cjs/core/PersistenceManager.js.map +1 -1
  14. package/dist/cjs/core/PromptComposer.d.ts +24 -0
  15. package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
  16. package/dist/cjs/core/PromptComposer.js +127 -0
  17. package/dist/cjs/core/PromptComposer.js.map +1 -0
  18. package/dist/cjs/core/ResponseEngine.d.ts +19 -0
  19. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
  20. package/dist/cjs/core/ResponseEngine.js +51 -0
  21. package/dist/cjs/core/ResponseEngine.js.map +1 -0
  22. package/dist/cjs/core/Route.d.ts +18 -12
  23. package/dist/cjs/core/Route.d.ts.map +1 -1
  24. package/dist/cjs/core/Route.js +15 -9
  25. package/dist/cjs/core/Route.js.map +1 -1
  26. package/dist/cjs/core/RoutingEngine.d.ts +38 -0
  27. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
  28. package/dist/cjs/core/RoutingEngine.js +110 -0
  29. package/dist/cjs/core/RoutingEngine.js.map +1 -0
  30. package/dist/cjs/core/State.d.ts +15 -4
  31. package/dist/cjs/core/State.d.ts.map +1 -1
  32. package/dist/cjs/core/State.js +21 -2
  33. package/dist/cjs/core/State.js.map +1 -1
  34. package/dist/cjs/core/ToolExecutor.d.ts +29 -0
  35. package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
  36. package/dist/cjs/core/ToolExecutor.js +73 -0
  37. package/dist/cjs/core/ToolExecutor.js.map +1 -0
  38. package/dist/cjs/core/Transition.d.ts +5 -5
  39. package/dist/cjs/core/Transition.d.ts.map +1 -1
  40. package/dist/cjs/core/Transition.js.map +1 -1
  41. package/dist/cjs/index.d.ts +6 -8
  42. package/dist/cjs/index.d.ts.map +1 -1
  43. package/dist/cjs/index.js +8 -10
  44. package/dist/cjs/index.js.map +1 -1
  45. package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
  46. package/dist/cjs/providers/AnthropicProvider.js +10 -13
  47. package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
  48. package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
  49. package/dist/cjs/providers/GeminiProvider.js +12 -8
  50. package/dist/cjs/providers/GeminiProvider.js.map +1 -1
  51. package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
  52. package/dist/cjs/providers/OpenAIProvider.js +10 -53
  53. package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
  54. package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
  55. package/dist/cjs/providers/OpenRouterProvider.js +10 -53
  56. package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
  57. package/dist/cjs/types/agent.d.ts +13 -12
  58. package/dist/cjs/types/agent.d.ts.map +1 -1
  59. package/dist/cjs/types/ai.d.ts +8 -2
  60. package/dist/cjs/types/ai.d.ts.map +1 -1
  61. package/dist/cjs/types/history.d.ts +8 -0
  62. package/dist/cjs/types/history.d.ts.map +1 -1
  63. package/dist/cjs/types/index.d.ts +0 -3
  64. package/dist/cjs/types/index.d.ts.map +1 -1
  65. package/dist/cjs/types/index.js +1 -3
  66. package/dist/cjs/types/index.js.map +1 -1
  67. package/dist/cjs/types/route.d.ts +39 -4
  68. package/dist/cjs/types/route.d.ts.map +1 -1
  69. package/dist/cjs/types/routing.d.ts +16 -0
  70. package/dist/cjs/types/routing.d.ts.map +1 -0
  71. package/dist/cjs/types/routing.js +3 -0
  72. package/dist/cjs/types/routing.js.map +1 -0
  73. package/dist/cjs/types/schema.d.ts +22 -0
  74. package/dist/cjs/types/schema.d.ts.map +1 -0
  75. package/dist/cjs/types/schema.js +3 -0
  76. package/dist/cjs/types/schema.js.map +1 -0
  77. package/dist/cjs/types/session.d.ts +77 -0
  78. package/dist/cjs/types/session.d.ts.map +1 -0
  79. package/dist/cjs/types/session.js +146 -0
  80. package/dist/cjs/types/session.js.map +1 -0
  81. package/dist/cjs/types/tool.d.ts +11 -5
  82. package/dist/cjs/types/tool.d.ts.map +1 -1
  83. package/dist/cjs/utils/id.d.ts +0 -5
  84. package/dist/cjs/utils/id.d.ts.map +1 -1
  85. package/dist/cjs/utils/id.js +0 -10
  86. package/dist/cjs/utils/id.js.map +1 -1
  87. package/dist/cjs/utils/schema.d.ts +17 -0
  88. package/dist/cjs/utils/schema.d.ts.map +1 -0
  89. package/dist/cjs/utils/schema.js +32 -0
  90. package/dist/cjs/utils/schema.js.map +1 -0
  91. package/dist/core/Agent.d.ts +22 -29
  92. package/dist/core/Agent.d.ts.map +1 -1
  93. package/dist/core/Agent.js +464 -291
  94. package/dist/core/Agent.js.map +1 -1
  95. package/dist/core/Events.d.ts +10 -1
  96. package/dist/core/Events.d.ts.map +1 -1
  97. package/dist/core/Events.js +3 -2
  98. package/dist/core/Events.js.map +1 -1
  99. package/dist/core/PersistenceManager.d.ts +19 -0
  100. package/dist/core/PersistenceManager.d.ts.map +1 -1
  101. package/dist/core/PersistenceManager.js +55 -0
  102. package/dist/core/PersistenceManager.js.map +1 -1
  103. package/dist/core/PromptComposer.d.ts +24 -0
  104. package/dist/core/PromptComposer.d.ts.map +1 -0
  105. package/dist/core/PromptComposer.js +123 -0
  106. package/dist/core/PromptComposer.js.map +1 -0
  107. package/dist/core/ResponseEngine.d.ts +19 -0
  108. package/dist/core/ResponseEngine.d.ts.map +1 -0
  109. package/dist/core/ResponseEngine.js +47 -0
  110. package/dist/core/ResponseEngine.js.map +1 -0
  111. package/dist/core/Route.d.ts +18 -12
  112. package/dist/core/Route.d.ts.map +1 -1
  113. package/dist/core/Route.js +15 -9
  114. package/dist/core/Route.js.map +1 -1
  115. package/dist/core/RoutingEngine.d.ts +38 -0
  116. package/dist/core/RoutingEngine.d.ts.map +1 -0
  117. package/dist/core/RoutingEngine.js +106 -0
  118. package/dist/core/RoutingEngine.js.map +1 -0
  119. package/dist/core/State.d.ts +15 -4
  120. package/dist/core/State.d.ts.map +1 -1
  121. package/dist/core/State.js +21 -2
  122. package/dist/core/State.js.map +1 -1
  123. package/dist/core/ToolExecutor.d.ts +29 -0
  124. package/dist/core/ToolExecutor.d.ts.map +1 -0
  125. package/dist/core/ToolExecutor.js +69 -0
  126. package/dist/core/ToolExecutor.js.map +1 -0
  127. package/dist/core/Transition.d.ts +5 -5
  128. package/dist/core/Transition.d.ts.map +1 -1
  129. package/dist/core/Transition.js.map +1 -1
  130. package/dist/index.d.ts +6 -8
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +3 -5
  133. package/dist/index.js.map +1 -1
  134. package/dist/providers/AnthropicProvider.d.ts.map +1 -1
  135. package/dist/providers/AnthropicProvider.js +10 -13
  136. package/dist/providers/AnthropicProvider.js.map +1 -1
  137. package/dist/providers/GeminiProvider.d.ts.map +1 -1
  138. package/dist/providers/GeminiProvider.js +12 -8
  139. package/dist/providers/GeminiProvider.js.map +1 -1
  140. package/dist/providers/OpenAIProvider.d.ts.map +1 -1
  141. package/dist/providers/OpenAIProvider.js +10 -53
  142. package/dist/providers/OpenAIProvider.js.map +1 -1
  143. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  144. package/dist/providers/OpenRouterProvider.js +10 -53
  145. package/dist/providers/OpenRouterProvider.js.map +1 -1
  146. package/dist/types/agent.d.ts +13 -12
  147. package/dist/types/agent.d.ts.map +1 -1
  148. package/dist/types/ai.d.ts +8 -2
  149. package/dist/types/ai.d.ts.map +1 -1
  150. package/dist/types/history.d.ts +8 -0
  151. package/dist/types/history.d.ts.map +1 -1
  152. package/dist/types/index.d.ts +0 -3
  153. package/dist/types/index.d.ts.map +1 -1
  154. package/dist/types/index.js +0 -1
  155. package/dist/types/index.js.map +1 -1
  156. package/dist/types/route.d.ts +39 -4
  157. package/dist/types/route.d.ts.map +1 -1
  158. package/dist/types/routing.d.ts +16 -0
  159. package/dist/types/routing.d.ts.map +1 -0
  160. package/dist/types/routing.js +2 -0
  161. package/dist/types/routing.js.map +1 -0
  162. package/dist/types/schema.d.ts +22 -0
  163. package/dist/types/schema.d.ts.map +1 -0
  164. package/dist/types/schema.js +2 -0
  165. package/dist/types/schema.js.map +1 -0
  166. package/dist/types/session.d.ts +77 -0
  167. package/dist/types/session.d.ts.map +1 -0
  168. package/dist/types/session.js +138 -0
  169. package/dist/types/session.js.map +1 -0
  170. package/dist/types/tool.d.ts +11 -5
  171. package/dist/types/tool.d.ts.map +1 -1
  172. package/dist/utils/id.d.ts +0 -5
  173. package/dist/utils/id.d.ts.map +1 -1
  174. package/dist/utils/id.js +0 -9
  175. package/dist/utils/id.js.map +1 -1
  176. package/dist/utils/schema.d.ts +17 -0
  177. package/dist/utils/schema.d.ts.map +1 -0
  178. package/dist/utils/schema.js +27 -0
  179. package/dist/utils/schema.js.map +1 -0
  180. package/docs/ADAPTERS.md +83 -3
  181. package/docs/API_REFERENCE.md +329 -104
  182. package/docs/ARCHITECTURE.md +284 -286
  183. package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
  184. package/docs/CONTEXT_MANAGEMENT.md +311 -28
  185. package/docs/CONTRIBUTING.md +1 -1
  186. package/docs/DOMAINS.md +61 -0
  187. package/docs/GETTING_STARTED.md +177 -88
  188. package/docs/PERSISTENCE.md +170 -23
  189. package/docs/README.md +7 -10
  190. package/examples/business-onboarding.ts +21 -9
  191. package/examples/company-qna-agent.ts +508 -0
  192. package/examples/declarative-agent.ts +143 -26
  193. package/examples/domain-scoping.ts +31 -10
  194. package/examples/extracted-data-modification.ts +415 -0
  195. package/examples/healthcare-agent.ts +194 -90
  196. package/examples/openai-agent.ts +67 -25
  197. package/examples/opensearch-persistence.ts +455 -151
  198. package/examples/persistent-onboarding.ts +162 -96
  199. package/examples/prisma-persistence.ts +371 -125
  200. package/examples/redis-persistence.ts +393 -23
  201. package/examples/rules-prohibitions.ts +32 -11
  202. package/examples/streaming-agent.ts +61 -13
  203. package/examples/travel-agent.ts +266 -133
  204. package/package.json +1 -1
  205. package/src/core/Agent.ts +668 -356
  206. package/src/core/Events.ts +12 -2
  207. package/src/core/PersistenceManager.ts +81 -0
  208. package/src/core/PromptComposer.ts +143 -0
  209. package/src/core/ResponseEngine.ts +82 -0
  210. package/src/core/Route.ts +32 -17
  211. package/src/core/RoutingEngine.ts +165 -0
  212. package/src/core/State.ts +55 -15
  213. package/src/core/ToolExecutor.ts +117 -0
  214. package/src/core/Transition.ts +5 -5
  215. package/src/index.ts +12 -21
  216. package/src/providers/AnthropicProvider.ts +10 -13
  217. package/src/providers/GeminiProvider.ts +12 -8
  218. package/src/providers/OpenAIProvider.ts +10 -56
  219. package/src/providers/OpenRouterProvider.ts +10 -56
  220. package/src/types/agent.ts +16 -13
  221. package/src/types/ai.ts +6 -2
  222. package/src/types/history.ts +8 -0
  223. package/src/types/index.ts +0 -11
  224. package/src/types/route.ts +41 -5
  225. package/src/types/routing.ts +18 -0
  226. package/src/types/schema.ts +23 -0
  227. package/src/types/session.ts +219 -0
  228. package/src/types/tool.ts +29 -7
  229. package/src/utils/id.ts +0 -10
  230. package/src/utils/schema.ts +32 -0
  231. package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
  232. package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
  233. package/dist/cjs/core/ConditionEvaluator.js +0 -272
  234. package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
  235. package/dist/cjs/core/Observation.d.ts +0 -24
  236. package/dist/cjs/core/Observation.d.ts.map +0 -1
  237. package/dist/cjs/core/Observation.js +0 -39
  238. package/dist/cjs/core/Observation.js.map +0 -1
  239. package/dist/cjs/core/PreparationEngine.d.ts +0 -116
  240. package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
  241. package/dist/cjs/core/PreparationEngine.js +0 -353
  242. package/dist/cjs/core/PreparationEngine.js.map +0 -1
  243. package/dist/cjs/core/PromptBuilder.d.ts +0 -136
  244. package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
  245. package/dist/cjs/core/PromptBuilder.js +0 -421
  246. package/dist/cjs/core/PromptBuilder.js.map +0 -1
  247. package/dist/cjs/types/observation.d.ts +0 -27
  248. package/dist/cjs/types/observation.d.ts.map +0 -1
  249. package/dist/cjs/types/observation.js +0 -6
  250. package/dist/cjs/types/observation.js.map +0 -1
  251. package/dist/cjs/types/prompt.d.ts +0 -46
  252. package/dist/cjs/types/prompt.d.ts.map +0 -1
  253. package/dist/cjs/types/prompt.js +0 -19
  254. package/dist/cjs/types/prompt.js.map +0 -1
  255. package/dist/core/ConditionEvaluator.d.ts +0 -72
  256. package/dist/core/ConditionEvaluator.d.ts.map +0 -1
  257. package/dist/core/ConditionEvaluator.js +0 -268
  258. package/dist/core/ConditionEvaluator.js.map +0 -1
  259. package/dist/core/Observation.d.ts +0 -24
  260. package/dist/core/Observation.d.ts.map +0 -1
  261. package/dist/core/Observation.js +0 -35
  262. package/dist/core/Observation.js.map +0 -1
  263. package/dist/core/PreparationEngine.d.ts +0 -116
  264. package/dist/core/PreparationEngine.d.ts.map +0 -1
  265. package/dist/core/PreparationEngine.js +0 -349
  266. package/dist/core/PreparationEngine.js.map +0 -1
  267. package/dist/core/PromptBuilder.d.ts +0 -136
  268. package/dist/core/PromptBuilder.d.ts.map +0 -1
  269. package/dist/core/PromptBuilder.js +0 -417
  270. package/dist/core/PromptBuilder.js.map +0 -1
  271. package/dist/types/observation.d.ts +0 -27
  272. package/dist/types/observation.d.ts.map +0 -1
  273. package/dist/types/observation.js +0 -5
  274. package/dist/types/observation.js.map +0 -1
  275. package/dist/types/prompt.d.ts +0 -46
  276. package/dist/types/prompt.d.ts.map +0 -1
  277. package/dist/types/prompt.js +0 -16
  278. package/dist/types/prompt.js.map +0 -1
  279. package/docs/STRUCTURE.md +0 -58
  280. package/src/core/ConditionEvaluator.ts +0 -381
  281. package/src/core/Observation.ts +0 -47
  282. package/src/core/PreparationEngine.ts +0 -561
  283. package/src/core/PromptBuilder.ts +0 -617
  284. package/src/types/observation.ts +0 -29
  285. package/src/types/prompt.ts +0 -49
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Example: Streaming Responses
3
+ * Updated for v2 architecture with session state management
3
4
  *
4
5
  * This example demonstrates how to use the respondStream method
5
6
  * to stream AI responses in real-time for better user experience
@@ -12,6 +13,7 @@ import {
12
13
  AnthropicProvider,
13
14
  OpenAIProvider,
14
15
  GeminiProvider,
16
+ createSession,
15
17
  } from "../src/index";
16
18
 
17
19
  // Custom context type
@@ -70,9 +72,12 @@ async function streamingWithAnthropic() {
70
72
  console.log("📤 Streaming response from Claude...\n");
71
73
  console.log("Response: ");
72
74
 
73
- // Use respondStream for real-time streaming
75
+ // Initialize session state for streaming conversation
76
+ let session = createSession();
77
+
78
+ // Use respondStream for real-time streaming with session state
74
79
  let fullMessage = "";
75
- for await (const chunk of agent.respondStream({ history })) {
80
+ for await (const chunk of agent.respondStream({ history, session })) {
76
81
  // chunk.delta contains the new text
77
82
  // chunk.accumulated contains the full text so far
78
83
  // chunk.done indicates if this is the final chunk
@@ -85,9 +90,14 @@ async function streamingWithAnthropic() {
85
90
  if (chunk.done) {
86
91
  console.log("\n\n✅ Stream complete!");
87
92
  console.log(`\n📊 Metadata:`);
88
- console.log(` - Route: ${chunk.route?.title || "None"}`);
89
- console.log(` - State: ${chunk.state?.description || "None"}`);
93
+ console.log(
94
+ ` - Route: ${chunk.session?.currentRoute?.title || "None"}`
95
+ );
96
+ console.log(` - Extracted:`, chunk.session?.extracted || "None");
90
97
  console.log(` - Tool Calls: ${chunk.toolCalls?.length || 0}`);
98
+
99
+ // Update session with progress
100
+ session = chunk.session!;
91
101
  }
92
102
  }
93
103
  } catch (error) {
@@ -131,13 +141,23 @@ async function streamingWithOpenAI() {
131
141
  console.log("📤 Streaming response from OpenAI...\n");
132
142
  console.log("Response: ");
133
143
 
134
- for await (const chunk of agent.respondStream({ history })) {
144
+ // Initialize session state for streaming conversation
145
+ let session = createSession();
146
+
147
+ for await (const chunk of agent.respondStream({ history, session })) {
135
148
  if (chunk.delta) {
136
149
  process.stdout.write(chunk.delta);
137
150
  }
138
151
 
139
152
  if (chunk.done) {
140
153
  console.log("\n\n✅ Stream complete!");
154
+ console.log(
155
+ ` - Route: ${chunk.session?.currentRoute?.title || "None"}`
156
+ );
157
+ console.log(` - Extracted:`, chunk.session?.extracted || "None");
158
+
159
+ // Update session with progress
160
+ session = chunk.session!;
141
161
  }
142
162
  }
143
163
  } catch (error) {
@@ -181,13 +201,23 @@ async function streamingWithGemini() {
181
201
  console.log("📤 Streaming response from Gemini...\n");
182
202
  console.log("Response: ");
183
203
 
184
- for await (const chunk of agent.respondStream({ history })) {
204
+ // Initialize session state for streaming conversation
205
+ let session = createSession();
206
+
207
+ for await (const chunk of agent.respondStream({ history, session })) {
185
208
  if (chunk.delta) {
186
209
  process.stdout.write(chunk.delta);
187
210
  }
188
211
 
189
212
  if (chunk.done) {
190
213
  console.log("\n\n✅ Stream complete!");
214
+ console.log(
215
+ ` - Route: ${chunk.session?.currentRoute?.title || "None"}`
216
+ );
217
+ console.log(` - Extracted:`, chunk.session?.extracted || "None");
218
+
219
+ // Update session with progress
220
+ session = chunk.session!;
191
221
  }
192
222
  }
193
223
  } catch (error) {
@@ -239,19 +269,24 @@ async function streamingWithRoutes() {
239
269
  console.log("📤 Streaming response with route detection...\n");
240
270
  console.log("Response: ");
241
271
 
242
- for await (const chunk of agent.respondStream({ history })) {
272
+ // Initialize session state for streaming conversation
273
+ let session = createSession();
274
+
275
+ for await (const chunk of agent.respondStream({ history, session })) {
243
276
  if (chunk.delta) {
244
277
  process.stdout.write(chunk.delta);
245
278
  }
246
279
 
247
280
  if (chunk.done) {
248
281
  console.log("\n\n✅ Stream complete!");
249
- if (chunk.route) {
250
- console.log(`\n🗺️ Route detected: ${chunk.route.title}`);
251
- }
252
- if (chunk.state) {
253
- console.log(`📍 State: ${chunk.state.description}`);
254
- }
282
+ console.log(`\n📊 Metadata:`);
283
+ console.log(
284
+ ` - Route: ${chunk.session?.currentRoute?.title || "None"}`
285
+ );
286
+ console.log(` - Extracted:`, chunk.session?.extracted || "None");
287
+
288
+ // Update session with progress
289
+ session = chunk.session!;
255
290
  }
256
291
  }
257
292
  } catch (error) {
@@ -301,8 +336,12 @@ async function streamingWithAbortSignal() {
301
336
  console.log("📤 Streaming response (will abort after 3s)...\n");
302
337
  console.log("Response: ");
303
338
 
339
+ // Initialize session state for streaming conversation
340
+ let session = createSession();
341
+
304
342
  for await (const chunk of agent.respondStream({
305
343
  history,
344
+ session,
306
345
  signal: abortController.signal,
307
346
  })) {
308
347
  if (chunk.delta) {
@@ -311,6 +350,15 @@ async function streamingWithAbortSignal() {
311
350
 
312
351
  if (chunk.done) {
313
352
  console.log("\n\n✅ Stream complete!");
353
+ console.log(`\n📊 Metadata:`);
354
+ console.log(
355
+ ` - Route: ${chunk.session?.currentRoute?.title || "None"}`
356
+ );
357
+ console.log(` - Extracted:`, chunk.session?.extracted || "None");
358
+
359
+ // Update session with progress
360
+ session = chunk.session!;
361
+
314
362
  clearTimeout(timeout);
315
363
  }
316
364
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Travel agent example (abridged from Python version)
3
- * Demonstrates route DSL, tools, and guidelines
2
+ * Travel agent example with session state management
3
+ * Demonstrates data-driven conversations with schema extraction and state progression
4
4
  */
5
5
 
6
6
  import {
@@ -10,6 +10,8 @@ import {
10
10
  END_ROUTE,
11
11
  EventSource,
12
12
  createMessageEvent,
13
+ createSession,
14
+ type ToolContext,
13
15
  } from "../src/index";
14
16
 
15
17
  // Context type for travel agent
@@ -18,10 +20,27 @@ interface TravelContext {
18
20
  customerName: string;
19
21
  }
20
22
 
21
- // Tools
22
- const getAvailableDestinations = defineTool<TravelContext, [], string[]>(
23
+ // Data extraction types for travel booking
24
+ interface FlightBookingData {
25
+ destination: string;
26
+ destinationCode?: string; // Enriched by tools
27
+ departureDate: string;
28
+ returnDate?: string;
29
+ passengers: number;
30
+ cabinClass: "economy" | "business" | "first";
31
+ urgency: "low" | "medium" | "high";
32
+ shouldSearchFlights?: boolean; // Action flag
33
+ }
34
+
35
+ interface BookingStatusData {
36
+ confirmationNumber: string;
37
+ email?: string;
38
+ }
39
+
40
+ // Tools with data access
41
+ const getAvailableDestinations = defineTool(
23
42
  "get_available_destinations",
24
- async () => {
43
+ async ({ context }: ToolContext<TravelContext>) => {
25
44
  return {
26
45
  data: [
27
46
  "Paris, France",
@@ -36,78 +55,124 @@ const getAvailableDestinations = defineTool<TravelContext, [], string[]>(
36
55
  }
37
56
  );
38
57
 
39
- const getAvailableFlights = defineTool<
40
- TravelContext,
41
- [destination: string],
42
- string[]
43
- >(
44
- "get_available_flights",
45
- async (_context, destination) => {
58
+ const lookupDestinationCode = defineTool(
59
+ "lookup_destination_code",
60
+ async ({
61
+ context,
62
+ extracted,
63
+ }: ToolContext<TravelContext, FlightBookingData>) => {
64
+ if (!extracted?.destination) {
65
+ return { data: undefined };
66
+ }
67
+
68
+ // Simulate airport code lookup
69
+ const codes: Record<string, string> = {
70
+ "Paris, France": "CDG",
71
+ "Tokyo, Japan": "NRT",
72
+ "Bali, Indonesia": "DPS",
73
+ "New York, USA": "JFK",
74
+ };
75
+
46
76
  return {
47
- data: [
48
- "Flight 123 - June 15, 9:00 AM, $850",
49
- "Flight 321 - June 16, 2:30 PM, $720",
50
- "Flight 987 - June 17, 6:45 PM, $680",
51
- ],
77
+ data: undefined,
78
+ extractedUpdate: {
79
+ destinationCode: codes[extracted.destination],
80
+ },
52
81
  };
53
82
  },
54
83
  {
55
- description: "Get available flights for a destination",
84
+ description: "Convert destination name to airport code",
56
85
  }
57
86
  );
58
87
 
59
- const getAlternativeFlights = defineTool<
60
- TravelContext,
61
- [destination: string],
62
- string[]
63
- >(
64
- "get_alternative_flights",
65
- async (_context, destination) => {
88
+ const searchFlights = defineTool(
89
+ "search_flights",
90
+ async ({
91
+ context,
92
+ extracted,
93
+ }: ToolContext<TravelContext, FlightBookingData>) => {
94
+ if (!extracted?.destination || !extracted?.departureDate) {
95
+ return { data: [] };
96
+ }
97
+
98
+ // Simulate flight search based on extracted data
99
+ const flights = [
100
+ `Flight 123 - ${extracted.departureDate}, 9:00 AM, $${
101
+ 800 + Math.floor(Math.random() * 200)
102
+ }`,
103
+ `Flight 321 - ${extracted.departureDate}, 2:30 PM, $${
104
+ 700 + Math.floor(Math.random() * 200)
105
+ }`,
106
+ `Flight 987 - ${extracted.departureDate}, 6:45 PM, $${
107
+ 600 + Math.floor(Math.random() * 200)
108
+ }`,
109
+ ];
110
+
66
111
  return {
67
- data: [
68
- "Flight 485 - June 25, 11:00 AM, $920",
69
- "Flight 516 - July 2, 4:15 PM, $780",
70
- ],
112
+ data: flights,
113
+ extractedUpdate: {
114
+ shouldSearchFlights: false, // Clear the flag
115
+ },
71
116
  };
72
117
  },
73
118
  {
74
- description: "Get alternative flight options with different dates",
119
+ description: "Search for flights based on extracted travel data",
75
120
  }
76
121
  );
77
122
 
78
- const bookFlight = defineTool<TravelContext, [flightDetails: string], string>(
123
+ const bookFlight = defineTool(
79
124
  "book_flight",
80
- async ({ context }, flightDetails) => {
125
+ async ({
126
+ context,
127
+ extracted,
128
+ }: ToolContext<TravelContext, FlightBookingData>) => {
129
+ if (!extracted) {
130
+ return { data: "Please provide flight details" };
131
+ }
132
+
81
133
  const confirmationNumber = `TRV-${new Date()
82
134
  .toISOString()
83
135
  .slice(0, 10)
84
136
  .replace(/-/g, "")}-001`;
137
+
85
138
  return {
86
- data: `Flight booked: ${flightDetails} for ${context.customerName}. Confirmation number: ${confirmationNumber}`,
139
+ data: `Flight booked for ${context.customerName} to ${extracted.destination}. Confirmation: ${confirmationNumber}`,
87
140
  };
88
141
  },
89
142
  {
90
- description: "Book a flight with the provided details",
143
+ description: "Book a flight using extracted travel data",
91
144
  }
92
145
  );
93
146
 
94
147
  const getBookingStatus = defineTool<
95
148
  TravelContext,
96
- [confirmationNumber: string],
97
- object
149
+ [],
150
+ { status: string; details: string; notes?: string }
98
151
  >(
99
152
  "get_booking_status",
100
- async (_context, confirmationNumber) => {
153
+ async ({
154
+ context,
155
+ extracted,
156
+ }: ToolContext<TravelContext, BookingStatusData>) => {
157
+ if (!extracted?.confirmationNumber) {
158
+ return {
159
+ data: {
160
+ status: "Error",
161
+ details: "Please provide a confirmation number",
162
+ },
163
+ };
164
+ }
165
+
101
166
  return {
102
167
  data: {
103
168
  status: "Confirmed",
104
- details: "Flight to Paris on June 15, 9:00 AM. Seat 12A assigned.",
169
+ details: `Flight booking ${extracted.confirmationNumber} is confirmed.`,
105
170
  notes: "Check-in opens 24 hours before departure.",
106
171
  },
107
172
  };
108
173
  },
109
174
  {
110
- description: "Get booking status by confirmation number",
175
+ description: "Get booking status using extracted confirmation number",
111
176
  }
112
177
  );
113
178
 
@@ -152,83 +217,108 @@ async function createTravelAgent() {
152
217
  synonyms: ["insurance", "trip protection", "travel protection"],
153
218
  });
154
219
 
155
- // Create flight booking route
156
- const flightBookingRoute = agent.createRoute({
220
+ // Create flight booking route with data extraction
221
+ const flightBookingRoute = agent.createRoute<FlightBookingData>({
157
222
  title: "Book a Flight",
158
223
  description:
159
224
  "Helps the customer find and book a flight to their desired destination.",
160
225
  conditions: ["The customer wants to book a flight"],
226
+ gatherSchema: {
227
+ type: "object",
228
+ properties: {
229
+ destination: {
230
+ type: "string",
231
+ description: "Travel destination",
232
+ },
233
+ destinationCode: {
234
+ type: "string",
235
+ description: "Airport code (enriched by tool)",
236
+ },
237
+ departureDate: {
238
+ type: "string",
239
+ description: "Departure date",
240
+ },
241
+ returnDate: {
242
+ type: "string",
243
+ description: "Return date (optional)",
244
+ },
245
+ passengers: {
246
+ type: "number",
247
+ minimum: 1,
248
+ maximum: 9,
249
+ description: "Number of passengers",
250
+ },
251
+ cabinClass: {
252
+ type: "string",
253
+ enum: ["economy", "business", "first"],
254
+ default: "economy",
255
+ description: "Cabin class preference",
256
+ },
257
+ urgency: {
258
+ type: "string",
259
+ enum: ["low", "medium", "high"],
260
+ default: "medium",
261
+ description: "Travel urgency level",
262
+ },
263
+ shouldSearchFlights: {
264
+ type: "boolean",
265
+ description: "Flag to trigger flight search",
266
+ },
267
+ },
268
+ required: ["destination", "departureDate", "passengers"],
269
+ },
161
270
  });
162
271
 
163
- // Build the route flow
164
- const t0 = flightBookingRoute.initialState.transitionTo({
272
+ // Build the route flow with data extraction and smart state progression
273
+ const askDestination = flightBookingRoute.initialState.transitionTo({
165
274
  chatState: "Ask about the destination",
275
+ gather: ["destination"],
276
+ skipIf: (extracted) => !!extracted.destination,
277
+ });
278
+
279
+ const enrichDestination = askDestination.transitionTo({
280
+ toolState: lookupDestinationCode,
281
+ requiredData: ["destination"],
166
282
  });
167
283
 
168
- const t1 = t0.transitionTo({
284
+ const askDates = enrichDestination.transitionTo({
169
285
  chatState: "Ask about preferred travel dates",
286
+ gather: ["departureDate"],
287
+ skipIf: (extracted) => !!extracted.departureDate,
288
+ requiredData: ["destination"],
170
289
  });
171
290
 
172
- const t2 = t1.transitionTo({
173
- toolState: getAvailableFlights,
291
+ const askPassengers = askDates.transitionTo({
292
+ chatState: "Ask for number of passengers",
293
+ gather: ["passengers"],
294
+ skipIf: (extracted) => !!extracted.passengers,
295
+ requiredData: ["destination", "departureDate"],
174
296
  });
175
297
 
176
- const t3 = t2.transitionTo({
298
+ const searchFlightsState = askPassengers.transitionTo({
299
+ toolState: searchFlights,
300
+ // Triggered when shouldSearchFlights flag is set by hook
301
+ });
302
+
303
+ const presentFlights = searchFlightsState.transitionTo({
177
304
  chatState: "Present available flights and ask which one works for them",
178
305
  });
179
306
 
180
307
  // Happy path: customer selects a flight
181
- const t4 = t3.transitionTo(
182
- {
183
- chatState:
184
- "Collect passenger information and confirm booking details before proceeding",
185
- },
186
- "The customer selects a flight"
187
- );
188
-
189
- const t5 = t4.transitionTo(
190
- {
191
- toolState: bookFlight,
192
- },
193
- "The customer confirms the booking details"
194
- );
195
-
196
- const t6 = t5.transitionTo({
197
- chatState: "Provide confirmation number and booking summary",
308
+ const confirmBooking = presentFlights.transitionTo({
309
+ chatState: "Confirm booking details before proceeding",
310
+ gather: ["cabinClass", "urgency"], // Additional optional data
198
311
  });
199
312
 
200
- t6.transitionTo({ state: END_ROUTE });
201
-
202
- // Alternative path: no flights work
203
- const t7 = t3.transitionTo(
204
- {
205
- toolState: getAlternativeFlights,
206
- },
207
- "None of the flights work for the customer"
208
- );
209
-
210
- const t8 = t7.transitionTo({
211
- chatState: "Present alternative flights and ask if any work",
313
+ const bookFlightState = confirmBooking.transitionTo({
314
+ toolState: bookFlight,
212
315
  });
213
316
 
214
- // Link back to happy path
215
- t8.transitionTo(
216
- {
217
- state: t4,
218
- },
219
- "The customer selects a flight"
220
- );
221
-
222
- // No alternative flights work either
223
- const t9 = t8.transitionTo(
224
- {
225
- chatState:
226
- "Suggest calling our office or visiting our website for more options",
227
- },
228
- "None of the alternative flights work either"
229
- );
317
+ const provideConfirmation = bookFlightState.transitionTo({
318
+ chatState: "Provide confirmation number and booking summary",
319
+ });
230
320
 
231
- t9.transitionTo({ state: END_ROUTE });
321
+ provideConfirmation.transitionTo({ state: END_ROUTE });
232
322
 
233
323
  // Add route-specific guidelines
234
324
  flightBookingRoute.createGuideline({
@@ -244,45 +334,44 @@ async function createTravelAgent() {
244
334
  "Inform them that visa requirements vary by destination and nationality, and suggest they check with the embassy or consulate",
245
335
  });
246
336
 
247
- // Create booking status route
248
- const bookingStatusRoute = agent.createRoute({
337
+ // Create booking status route with data extraction
338
+ const bookingStatusRoute = agent.createRoute<BookingStatusData>({
249
339
  title: "Check Booking Status",
250
340
  description:
251
341
  "Retrieves the customer's booking status and provides relevant information.",
252
342
  conditions: ["The customer wants to check their booking status"],
343
+ gatherSchema: {
344
+ type: "object",
345
+ properties: {
346
+ confirmationNumber: {
347
+ type: "string",
348
+ description: "Booking confirmation number",
349
+ },
350
+ email: {
351
+ type: "string",
352
+ description: "Email address associated with booking (optional)",
353
+ },
354
+ },
355
+ required: ["confirmationNumber"],
356
+ },
253
357
  });
254
358
 
255
- const s0 = bookingStatusRoute.initialState.transitionTo({
359
+ const askConfirmation = bookingStatusRoute.initialState.transitionTo({
256
360
  chatState: "Ask for the confirmation number or booking reference",
361
+ gather: ["confirmationNumber"],
362
+ skipIf: (extracted) => !!extracted.confirmationNumber,
257
363
  });
258
364
 
259
- const s1 = s0.transitionTo({
365
+ const checkStatus = askConfirmation.transitionTo({
260
366
  toolState: getBookingStatus,
367
+ requiredData: ["confirmationNumber"],
261
368
  });
262
369
 
263
- s1.transitionTo(
264
- {
265
- chatState:
266
- "Tell the customer that the booking could not be found and ask them to verify the confirmation number or call the office",
267
- },
268
- "The booking could not be found"
269
- );
270
-
271
- s1.transitionTo(
272
- {
273
- chatState:
274
- "Provide the booking details and confirm everything is in order",
275
- },
276
- "The booking is confirmed and all details are correct"
277
- );
370
+ const provideStatus = checkStatus.transitionTo({
371
+ chatState: "Provide booking status and relevant information",
372
+ });
278
373
 
279
- s1.transitionTo(
280
- {
281
- chatState:
282
- "Present the booking information and mention any issues or pending actions required",
283
- },
284
- "The booking has issues or requires customer action"
285
- );
374
+ provideStatus.transitionTo({ state: END_ROUTE });
286
375
 
287
376
  // Global guidelines
288
377
  agent.createGuideline({
@@ -307,34 +396,78 @@ async function createTravelAgent() {
307
396
  return agent;
308
397
  }
309
398
 
310
- // Example usage
399
+ // Example usage with session state
311
400
  async function main() {
312
401
  const agent = await createTravelAgent();
313
402
 
403
+ // Initialize session state
404
+ let session = createSession<FlightBookingData | BookingStatusData>();
405
+
314
406
  // Simulate a conversation
315
407
  const history = [
316
408
  createMessageEvent(
317
409
  EventSource.CUSTOMER,
318
- "Customer",
319
- "Hi, I want to book a flight to Paris"
410
+ "Alice",
411
+ "Hi, I want to book a flight to Paris next week with 2 passengers"
320
412
  ),
321
413
  ];
322
414
 
323
415
  console.log("Agent:", agent.name);
324
416
  console.log("Description:", agent.description);
325
- console.log("\nRoutes:", agent.getRoutes().length);
326
- console.log("Terms:", agent.getTerms().length);
327
- console.log("Guidelines:", agent.getGuidelines().length);
328
-
329
- // Print route structure
330
- const routes = agent.getRoutes();
331
- for (const route of routes) {
332
- console.log("\n" + route.describe());
417
+
418
+ // Turn 1 - Agent extracts data and starts booking flow
419
+ const response1 = await agent.respond({ history, session });
420
+ console.log("\n=== TURN 1 ===");
421
+ console.log("Agent:", response1.message);
422
+ console.log("Route:", response1.session?.currentRoute?.title);
423
+ console.log("State:", response1.session?.currentState?.id);
424
+ console.log("Extracted:", response1.session?.extracted);
425
+
426
+ // Session state updated with progress
427
+ session = response1.session!;
428
+
429
+ // Turn 2 - Continue with session state
430
+ if (response1.session?.currentRoute?.title === "Book a Flight") {
431
+ const history2 = [
432
+ ...history,
433
+ createMessageEvent(EventSource.AI_AGENT, "Agent", response1.message),
434
+ createMessageEvent(EventSource.CUSTOMER, "Alice", "Economy class please"),
435
+ ];
436
+
437
+ const response2 = await agent.respond({ history: history2, session });
438
+ console.log("\n=== TURN 2 ===");
439
+ console.log("Agent:", response2.message);
440
+ console.log("Updated extracted:", response2.session?.extracted);
441
+ console.log("Current state:", response2.session?.currentState?.id);
333
442
  }
334
443
 
335
- // Generate response (would need valid API key)
336
- // const response = await agent.respond({ history });
337
- // console.log('\nAgent response:', response.message);
444
+ // Demonstrate booking status check
445
+ const statusHistory = [
446
+ createMessageEvent(
447
+ EventSource.CUSTOMER,
448
+ "Bob",
449
+ "Can you check my booking status? Confirmation number TRV-20251015-001"
450
+ ),
451
+ ];
452
+
453
+ let statusSession = createSession<BookingStatusData>();
454
+ const statusResponse = await agent.respond({
455
+ history: statusHistory,
456
+ session: statusSession,
457
+ });
458
+ console.log("\n=== BOOKING STATUS CHECK ===");
459
+ console.log("Agent:", statusResponse.message);
460
+ console.log("Route:", statusResponse.session?.currentRoute?.title);
461
+ console.log("Extracted:", statusResponse.session?.extracted);
462
+
463
+ // Show session state management benefits
464
+ console.log("\n=== SESSION STATE BENEFITS ===");
465
+ console.log("✅ Always-on routing - respects user intent changes");
466
+ console.log("✅ Data persistence - extracted data survives across turns");
467
+ console.log(
468
+ "✅ State progression - intelligent flow based on collected data"
469
+ );
470
+ console.log("✅ Context awareness - router sees current progress");
338
471
  }
339
472
 
340
473
  // Run if executed directly