@falai/agent 0.4.0 → 0.5.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 (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 +465 -275
  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 +57 -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 -9
  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 +72 -0
  78. package/dist/cjs/types/session.d.ts.map +1 -0
  79. package/dist/cjs/types/session.js +140 -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 +465 -275
  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 +57 -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 -9
  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 +72 -0
  167. package/dist/types/session.d.ts.map +1 -0
  168. package/dist/types/session.js +132 -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 +95 -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 +679 -332
  206. package/src/core/Events.ts +12 -2
  207. package/src/core/PersistenceManager.ts +83 -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 -10
  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 +207 -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 -105
  240. package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
  241. package/dist/cjs/core/PreparationEngine.js +0 -320
  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 -105
  264. package/dist/core/PreparationEngine.d.ts.map +0 -1
  265. package/dist/core/PreparationEngine.js +0 -316
  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 -500
  283. package/src/core/PromptBuilder.ts +0 -617
  284. package/src/types/observation.ts +0 -29
  285. package/src/types/prompt.ts +0 -49
@@ -47,8 +47,17 @@ import {
47
47
  GeminiProvider,
48
48
  createMessageEvent,
49
49
  EventSource,
50
+ createSession,
50
51
  } from "@falai/agent";
51
52
 
53
+ // Define your data extraction type
54
+ interface FlightData {
55
+ destination: string;
56
+ departureDate: string;
57
+ passengers: number;
58
+ cabinClass: "economy" | "business" | "first";
59
+ }
60
+
52
61
  // Define your context type
53
62
  interface MyContext {
54
63
  userId: string;
@@ -63,8 +72,8 @@ const ai = new GeminiProvider({
63
72
 
64
73
  // Create your agent
65
74
  const agent = new Agent<MyContext>({
66
- name: "MyBot",
67
- description: "A helpful assistant",
75
+ name: "FlightBot",
76
+ description: "A helpful flight booking assistant",
68
77
  ai,
69
78
  context: {
70
79
  userId: "user_123",
@@ -72,20 +81,44 @@ const agent = new Agent<MyContext>({
72
81
  },
73
82
  });
74
83
 
75
- // Add a guideline
76
- agent.createGuideline({
77
- condition: "User asks for help",
78
- action: "Be friendly and offer specific assistance",
84
+ // Create a data-driven route
85
+ const bookingRoute = agent.createRoute<FlightData>({
86
+ title: "Book Flight",
87
+ description: "Help user book a flight",
88
+ conditions: ["User wants to book a flight"],
89
+ gatherSchema: {
90
+ type: "object",
91
+ properties: {
92
+ destination: { type: "string" },
93
+ departureDate: { type: "string" },
94
+ passengers: { type: "number", minimum: 1, maximum: 9 },
95
+ cabinClass: {
96
+ type: "string",
97
+ enum: ["economy", "business", "first"],
98
+ default: "economy",
99
+ },
100
+ },
101
+ required: ["destination", "departureDate", "passengers"],
102
+ },
79
103
  });
80
104
 
81
- // Generate a response
105
+ // Initialize session state
106
+ let session = createSession<FlightData>();
107
+
108
+ // Generate a response with session state
82
109
  const response = await agent.respond({
83
110
  history: [
84
- createMessageEvent(EventSource.CUSTOMER, "Alice", "Hi, I need help!"),
111
+ createMessageEvent(
112
+ EventSource.CUSTOMER,
113
+ "Alice",
114
+ "I want to fly to Paris tomorrow with 2 people"
115
+ ),
85
116
  ],
117
+ session,
86
118
  });
87
119
 
88
120
  console.log("Agent:", response.message);
121
+ console.log("Extracted:", response.session?.extracted);
89
122
  ```
90
123
 
91
124
  ### 3. Run It!
@@ -100,83 +133,102 @@ bun run index.ts
100
133
 
101
134
  ## Next Steps
102
135
 
103
- ### Add a Domain Glossary
136
+ ### Add Session State Management
104
137
 
105
- Help your agent understand your business:
138
+ Continue the conversation with extracted data:
106
139
 
107
140
  ```typescript
108
- agent
109
- .createTerm({
110
- name: "Premium Plan",
111
- description: "Our top-tier subscription at $99/month",
112
- synonyms: ["pro plan", "premium subscription"],
113
- })
114
- .createTerm({
115
- name: "SLA",
116
- description: "Service Level Agreement - our response time guarantee",
117
- });
141
+ // Turn 2 - User provides more details
142
+ const response2 = await agent.respond({
143
+ history: [
144
+ createMessageEvent(EventSource.AI_AGENT, "Bot", response.message),
145
+ createMessageEvent(EventSource.CUSTOMER, "Alice", "Make it business class"),
146
+ ],
147
+ session: response.session, // Pass previous session state
148
+ });
149
+
150
+ console.log("Agent:", response2.message);
151
+ console.log("Updated extracted:", response2.session?.extracted);
152
+ // Agent remembers destination and passengers, updates cabin class
118
153
  ```
119
154
 
120
- ### Create Tools
155
+ ### Create Tools with Data Access
121
156
 
122
- Give your agent superpowers:
157
+ Tools can access and modify extracted data:
123
158
 
124
159
  ```typescript
125
160
  import { defineTool } from "@falai/agent";
126
161
 
127
- const checkBalance = defineTool<MyContext, [accountId: string], number>(
128
- "check_balance",
129
- async ({ context }, accountId) => {
130
- // Your logic here
131
- const balance = await fetchBalance(accountId);
132
- return { data: balance };
162
+ const searchFlights = defineTool<MyContext, [], void, FlightData>(
163
+ "search_flights",
164
+ async ({ context, extracted }) => {
165
+ // Access extracted data directly
166
+ if (!extracted.destination || !extracted.departureDate) {
167
+ return { data: undefined };
168
+ }
169
+
170
+ // Search for flights and enrich extracted data
171
+ const flights = await searchFlightAPI(
172
+ extracted.destination,
173
+ extracted.departureDate
174
+ );
175
+
176
+ return {
177
+ data: undefined,
178
+ contextUpdate: { availableFlights: flights },
179
+ extractedUpdate: {
180
+ destinationCode: await lookupAirportCode(extracted.destination),
181
+ },
182
+ };
133
183
  },
134
- { description: "Checks account balance" }
184
+ { description: "Search for available flights based on extracted data" }
135
185
  );
136
186
 
137
- agent.createGuideline({
138
- condition: "User asks about their balance",
139
- action: "Use the check_balance tool to retrieve current balance",
140
- tools: [checkBalance],
141
- });
187
+ // Add tool to state machine
188
+ const searchState = bookingRoute.initialState
189
+ .transitionTo({
190
+ chatState: "Extract travel details",
191
+ gather: ["destination", "departureDate", "passengers"],
192
+ })
193
+ .transitionTo({
194
+ toolState: searchFlights,
195
+ requiredData: ["destination", "departureDate", "passengers"],
196
+ });
142
197
  ```
143
198
 
144
- ### Build Conversation Routes
199
+ ### Build Smart State Machines
145
200
 
146
- Create structured flows:
201
+ Create intelligent flows with code-based logic:
147
202
 
148
203
  ```typescript
149
- import { END_ROUTE } from "@falai/agent";
150
-
151
- const onboardingRoute = agent.createRoute({
152
- title: "User Onboarding",
153
- description: "Guide new users through setup",
154
- conditions: ["User is new and needs onboarding"],
204
+ // State machine with smart bypassing and data validation
205
+ const askDestination = bookingRoute.initialState.transitionTo({
206
+ chatState: "Ask where they want to fly",
207
+ gather: ["destination"],
208
+ skipIf: (extracted) => !!extracted.destination, // Skip if already have destination
155
209
  });
156
210
 
157
- // Build the flow - two approaches:
158
-
159
- // Approach 1: Step-by-step (great for complex flows with branching)
160
- const step1 = onboardingRoute.initialState.transitionTo({
161
- chatState: "Ask for user's name",
211
+ const enrichDestination = askDestination.transitionTo({
212
+ toolState: searchFlights, // Tool executes automatically
213
+ requiredData: ["destination"], // Prerequisites
162
214
  });
163
215
 
164
- const step2 = step1.transitionTo({
165
- chatState: "Ask for user's email",
216
+ const askDates = enrichDestination.transitionTo({
217
+ chatState: "Ask about travel dates",
218
+ gather: ["departureDate"],
219
+ skipIf: (extracted) => !!extracted.departureDate,
220
+ requiredData: ["destination"], // Must have destination first
166
221
  });
167
222
 
168
- const step3 = step2.transitionTo({
169
- chatState: "Confirm details and welcome user",
223
+ const askPassengers = askDates.transitionTo({
224
+ chatState: "How many passengers?",
225
+ gather: ["passengers"],
226
+ skipIf: (extracted) => !!extracted.passengers,
170
227
  });
171
228
 
172
- step3.transitionTo({ state: END_ROUTE });
173
-
174
- // Approach 2: Fluent chaining (concise for linear flows)
175
- onboardingRoute.initialState
176
- .transitionTo({ chatState: "Ask for user's name" })
177
- .transitionTo({ chatState: "Ask for user's email" })
178
- .transitionTo({ chatState: "Confirm details and welcome user" })
179
- .transitionTo({ state: END_ROUTE });
229
+ const presentFlights = askPassengers.transitionTo({
230
+ chatState: "Present available flights from search results",
231
+ });
180
232
  ```
181
233
 
182
234
  ### Handle Context Dynamically
@@ -232,26 +284,59 @@ if (user.isPremium) {
232
284
  }
233
285
  ```
234
286
 
235
- ### Multi-Turn Conversations
287
+ ### Multi-Turn Conversations with Session State
236
288
 
237
- Build up conversation history:
289
+ Track conversation progress and extracted data:
238
290
 
239
291
  ```typescript
240
- const history: Event[] = [];
241
-
242
- // Turn 1
243
- history.push(createMessageEvent(EventSource.CUSTOMER, "User", "Hello"));
244
- const response1 = await agent.respond({ history });
245
- history.push(
246
- createMessageEvent(EventSource.AI_AGENT, "Bot", response1.message)
247
- );
248
-
249
- // Turn 2
250
- history.push(createMessageEvent(EventSource.CUSTOMER, "User", "Tell me more"));
251
- const response2 = await agent.respond({ history });
252
- history.push(
253
- createMessageEvent(EventSource.AI_AGENT, "Bot", response2.message)
254
- );
292
+ import { createSession, enterRoute, mergeExtracted } from "@falai/agent";
293
+
294
+ // Initialize session
295
+ let session = createSession<FlightData>();
296
+
297
+ // Turn 1 - User starts booking
298
+ const history1 = [
299
+ createMessageEvent(
300
+ EventSource.CUSTOMER,
301
+ "User",
302
+ "I want to fly to Paris tomorrow with 2 people"
303
+ ),
304
+ ];
305
+
306
+ const response1 = await agent.respond({ history: history1, session });
307
+ console.log("Turn 1 - Extracted:", response1.session?.extracted);
308
+ // { destination: "Paris", departureDate: "tomorrow", passengers: 2 }
309
+
310
+ session = response1.session!; // Update session with extracted data
311
+
312
+ // Turn 2 - User changes their mind
313
+ const history2 = [
314
+ ...history1,
315
+ createMessageEvent(EventSource.AI_AGENT, "Bot", response1.message),
316
+ createMessageEvent(
317
+ EventSource.CUSTOMER,
318
+ "User",
319
+ "Actually, make that Tokyo instead"
320
+ ),
321
+ ];
322
+
323
+ const response2 = await agent.respond({ history: history2, session });
324
+ console.log("Turn 2 - Updated:", response2.session?.extracted);
325
+ // { destination: "Tokyo", departureDate: "tomorrow", passengers: 2 }
326
+
327
+ session = response2.session!; // Router handled the route change
328
+
329
+ // Turn 3 - Continue with updated data
330
+ const response3 = await agent.respond({
331
+ history: [
332
+ ...history2,
333
+ createMessageEvent(EventSource.AI_AGENT, "Bot", response2.message),
334
+ createMessageEvent(EventSource.CUSTOMER, "User", "Business class please"),
335
+ ],
336
+ session,
337
+ });
338
+ console.log("Turn 3 - Final:", response3.session?.extracted);
339
+ // { destination: "Tokyo", departureDate: "tomorrow", passengers: 2, cabinClass: "business" }
255
340
  ```
256
341
 
257
342
  ---
@@ -260,20 +345,24 @@ history.push(
260
345
 
261
346
  ### ✅ Do's
262
347
 
263
- - **Use TypeScript** - Full type safety and IntelliSense
264
- - **Define custom context** - Strongly typed context for your domain
265
- - **Add glossary terms** - Help the agent understand your terminology
266
- - **Use specific guidelines** - Clear conditions and actions
267
- - **Enable/disable guidelines** - Use the `enabled` flag for A/B testing
268
- - **Tag your guidelines** - Organize with tags for filtering
348
+ - **Use TypeScript** - Full type safety and IntelliSense throughout
349
+ - **Define extraction schemas** - Use JSON Schema for reliable data collection
350
+ - **Leverage session state** - Track conversation progress across turns
351
+ - **Use code-based logic** - `skipIf` and `requiredData` for deterministic flow
352
+ - **Create type-safe routes** - Generic types for both context and extracted data
353
+ - **Handle user changes** - Always-on routing respects "I changed my mind"
354
+ - **Add lifecycle hooks** - Validate and enrich extracted data
355
+ - **Mix stateful & stateless** - Use appropriate patterns for each use case
269
356
 
270
357
  ### ❌ Don'ts
271
358
 
272
- - **Don't use `any` for context** - Define proper types
273
- - **Don't skip error handling** - Wrap agent calls in try/catch
274
- - **Don't forget to set API key** - Use environment variables
275
- - **Don't create overly complex routes** - Keep flows simple and clear
276
- - **Don't ignore linter warnings** - Fix TypeScript errors
359
+ - **Don't use `any` types** - Define proper interfaces for context and extracted data
360
+ - **Don't rely on LLM conditions** - Use code (`skipIf`) for state logic
361
+ - **Don't skip session management** - Pass session state between turns
362
+ - **Don't forget error handling** - Wrap agent calls in try/catch
363
+ - **Don't ignore type errors** - Fix TypeScript issues for reliability
364
+ - **Don't create fuzzy logic** - Use explicit schemas over prompt-based parsing
365
+ - **Don't forget API keys** - Set environment variables properly
277
366
 
278
367
  ---
279
368
 
@@ -330,7 +419,7 @@ new GeminiProvider({
330
419
 
331
420
  - 📚 Read the [Constructor Options Guide](./CONSTRUCTOR_OPTIONS.md)
332
421
  - 🔍 Check the [API Reference](./API_REFERENCE.md)
333
- - 🏗️ Understand the [Architecture](./STRUCTURE.md)
422
+ - 🏗️ Understand the [Architecture](./ARCHITECTURE.md)
334
423
  - 🎯 Explore [Examples](../examples/)
335
424
 
336
425
  ---
@@ -1,15 +1,16 @@
1
1
  # Persistence with @falai/agent
2
2
 
3
- The `@falai/agent` framework provides optional, flexible persistence for automatically saving conversation sessions and messages to your database.
3
+ The `@falai/agent` framework provides optional, flexible persistence for automatically saving conversation sessions, extracted data, and messages to your database.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - ✅ **Optional** - Persistence is completely optional
8
8
  - ✅ **Provider Pattern** - Simple API like AI providers (`new PrismaAdapter({ prisma })`)
9
- - ✅ **Type-safe** - Full TypeScript support
10
- - ✅ **Prisma Ready** - Built-in Prisma ORM adapter
9
+ - ✅ **Type-safe** - Full TypeScript support with generics
10
+ - ✅ **Session State Integration** - Automatic saving of extracted data and conversation progress
11
+ - ✅ **Multiple Adapters** - Prisma, Redis, MongoDB, PostgreSQL, SQLite, OpenSearch, Memory
11
12
  - ✅ **Extensible** - Create adapters for any database
12
- - ✅ **Auto-save** - Automatic message persistence
13
+ - ✅ **Auto-save** - Automatic session state and message persistence
13
14
 
14
15
  ## Quick Start with Prisma
15
16
 
@@ -80,7 +81,7 @@ npx prisma generate
80
81
  npx prisma migrate dev --name init
81
82
  ```
82
83
 
83
- ### 4. Use in Your Agent (That's it!)
84
+ ### 4. Use in Your Agent with Session State (That's it!)
84
85
 
85
86
  ```typescript
86
87
  import { Agent, PrismaAdapter, GeminiProvider } from "@falai/agent";
@@ -88,6 +89,13 @@ import { PrismaClient } from "@prisma/client";
88
89
 
89
90
  const prisma = new PrismaClient();
90
91
 
92
+ // Define your extracted data type
93
+ interface BookingData {
94
+ destination: string;
95
+ date: string;
96
+ passengers: number;
97
+ }
98
+
91
99
  const agent = new Agent({
92
100
  name: "My Agent",
93
101
  ai: new GeminiProvider({ apiKey: "..." }),
@@ -95,27 +103,55 @@ const agent = new Agent({
95
103
  persistence: {
96
104
  adapter: new PrismaAdapter({ prisma }),
97
105
  userId: "user_123",
106
+ autoSave: true, // Auto-saves session state!
107
+ },
108
+ });
109
+
110
+ // Create a route with data extraction
111
+ const bookingRoute = agent.createRoute<BookingData>({
112
+ title: "Book Flight",
113
+ gatherSchema: {
114
+ type: "object",
115
+ properties: {
116
+ destination: { type: "string" },
117
+ date: { type: "string" },
118
+ passengers: { type: "number" },
119
+ },
120
+ required: ["destination", "date", "passengers"],
98
121
  },
99
122
  });
100
123
 
124
+ // Define states with smart data gathering
125
+ bookingRoute.initialState.transitionTo({
126
+ chatState: "Collect booking details",
127
+ gather: ["destination", "date", "passengers"],
128
+ });
129
+
101
130
  // Access persistence methods
102
131
  const persistence = agent.getPersistenceManager();
103
132
 
104
- // Create a session
105
- const session = await persistence.createSession({
106
- userId: "user_123",
107
- agentName: "My Agent",
108
- });
133
+ // Create a session with state support
134
+ const { sessionData, sessionState } =
135
+ await persistence.createSessionWithState<BookingData>({
136
+ userId: "user_123",
137
+ agentName: "My Agent",
138
+ });
109
139
 
110
140
  // Load history
111
- const history = await persistence.loadSessionHistory(session.id);
141
+ const history = await persistence.loadSessionHistory(sessionData.id);
112
142
 
113
- // Generate response
114
- const response = await agent.respond({ history });
143
+ // Generate response with session state
144
+ const response = await agent.respond({
145
+ history,
146
+ session: sessionState, // Pass session state
147
+ });
148
+
149
+ // Session state is auto-saved! ✨
150
+ console.log("Extracted data:", response.session?.extracted);
115
151
 
116
- // Save message (auto-saved if configured)
152
+ // Save message
117
153
  await persistence.saveMessage({
118
- sessionId: session.id,
154
+ sessionId: sessionData.id,
119
155
  role: "agent",
120
156
  content: response.message,
121
157
  });
@@ -220,6 +256,96 @@ const agent = new Agent({
220
256
  await agent.updateContext({ preferences: { theme: "dark" } });
221
257
  ```
222
258
 
259
+ ## Session State Integration
260
+
261
+ The new architecture automatically saves and loads `SessionState<TExtracted>` which includes:
262
+
263
+ - **Current route and state** - Track conversation progress
264
+ - **Extracted data** - All data gathered via `gatherSchema` and `gather` fields
265
+ - **Route history** - History of route transitions
266
+ - **Metadata** - Session timestamps and custom data
267
+
268
+ ### How It Works
269
+
270
+ 1. **Auto-Save**: When `autoSave: true`, session state is automatically persisted after each `respond()` call
271
+ 2. **Conversion**: `SessionState` is automatically converted to `SessionData` for storage
272
+ 3. **Recovery**: Load session state from database to resume conversations
273
+
274
+ ### Create Session with State
275
+
276
+ ```typescript
277
+ const { sessionData, sessionState } =
278
+ await persistence.createSessionWithState<YourDataType>({
279
+ userId: "user_123",
280
+ agentName: "My Agent",
281
+ initialData: {
282
+ /* optional pre-filled data */
283
+ },
284
+ });
285
+
286
+ // sessionData: Database record
287
+ // sessionState: In-memory session state ready to use
288
+ ```
289
+
290
+ ### Save Session State
291
+
292
+ ```typescript
293
+ // Manual save (not needed if autoSave: true)
294
+ await persistence.saveSessionState(sessionId, sessionState);
295
+ ```
296
+
297
+ ### Load Session State
298
+
299
+ ```typescript
300
+ // Load session state from database
301
+ const sessionState = await persistence.loadSessionState<YourDataType>(
302
+ sessionId
303
+ );
304
+
305
+ // Load message history
306
+ const history = await persistence.loadSessionHistory(sessionId);
307
+
308
+ // Resume conversation
309
+ const response = await agent.respond({
310
+ history,
311
+ session: sessionState,
312
+ });
313
+ ```
314
+
315
+ ### What Gets Persisted
316
+
317
+ The session state stores:
318
+
319
+ ```typescript
320
+ {
321
+ currentRoute: {
322
+ id: "book_flight",
323
+ title: "Book a Flight",
324
+ enteredAt: Date
325
+ },
326
+ currentState: {
327
+ id: "ask_dates",
328
+ description: "Ask about travel dates",
329
+ enteredAt: Date
330
+ },
331
+ extracted: {
332
+ destination: "Paris",
333
+ departureDate: "2025-06-15",
334
+ passengers: 2
335
+ },
336
+ routeHistory: [
337
+ { routeId: "book_flight", enteredAt: Date, completed: false }
338
+ ],
339
+ metadata: {
340
+ sessionId: "session_123",
341
+ createdAt: Date,
342
+ lastUpdatedAt: Date
343
+ }
344
+ }
345
+ ```
346
+
347
+ This data is stored in `collectedData` field as JSON in the database.
348
+
223
349
  ## PersistenceManager API
224
350
 
225
351
  Access via `agent.getPersistenceManager()`:
@@ -227,7 +353,25 @@ Access via `agent.getPersistenceManager()`:
227
353
  ### Session Methods
228
354
 
229
355
  ```typescript
230
- // Create session
356
+ // Create session with state support (NEW!)
357
+ const { sessionData, sessionState } =
358
+ await persistence.createSessionWithState<YourDataType>({
359
+ userId: "user_123",
360
+ agentName: "My Agent",
361
+ initialData: {
362
+ /* optional */
363
+ },
364
+ });
365
+
366
+ // Save session state (NEW!)
367
+ await persistence.saveSessionState(sessionId, sessionState);
368
+
369
+ // Load session state (NEW!)
370
+ const sessionState = await persistence.loadSessionState<YourDataType>(
371
+ sessionId
372
+ );
373
+
374
+ // Create session (legacy)
231
375
  await persistence.createSession({
232
376
  userId: "user_123",
233
377
  agentName: "My Agent",
@@ -375,13 +519,16 @@ await persistence.saveMessage({
375
519
 
376
520
  ## Best Practices
377
521
 
378
- 1. ✅ Use lifecycle hooks for automatic context persistence
379
- 2. ✅ Enable `autoSave` to track message counts automatically
380
- 3. ✅ Store minimal data in `collectedData`
381
- 4. ✅ Index frequently queried fields
382
- 5. ✅ Use cascading deletes for cleanup
383
- 6. ✅ Handle errors gracefully
384
- 7. ✅ Complete or abandon sessions when done
522
+ 1. ✅ **Use `createSessionWithState()`** - Get both database record and session state in one call
523
+ 2. ✅ **Enable `autoSave: true`** - Automatically persist session state after each response
524
+ 3. ✅ **Define extraction schemas** - Use `gatherSchema` in routes for structured data collection
525
+ 4. ✅ **Pass session state** - Always pass `session` parameter to `agent.respond()`
526
+ 5. ✅ **Load session state** - Use `loadSessionState()` to resume conversations
527
+ 6. ✅ **Store extracted data** - Leverage `collectedData.extracted` for user input tracking
528
+ 7. ✅ **Index frequently queried fields** - Add database indexes on `userId`, `status`, etc.
529
+ 8. ✅ **Use cascading deletes** - Clean up messages automatically when deleting sessions
530
+ 9. ✅ **Complete sessions** - Mark sessions as completed when conversation ends
531
+ 10. ✅ **Handle errors gracefully** - Wrap persistence calls in try-catch blocks
385
532
 
386
533
  ## Troubleshooting
387
534
 
package/docs/README.md CHANGED
@@ -10,10 +10,9 @@ Welcome to the `@falai/agent` documentation!
10
10
 
11
11
  ### Core Concepts
12
12
 
13
- - **[Architecture](./ARCHITECTURE.md)** - Design principles & philosophy ⭐ **NEW**
14
- - **[Constructor Options](./CONSTRUCTOR_OPTIONS.md)** - Comprehensive guide to declarative vs fluent configuration
15
- - **[Context Management](./CONTEXT_MANAGEMENT.md)** - Dynamic context variables & lifecycle hooks
16
- - **[Package Structure](./STRUCTURE.md)** - Package organization and module design
13
+ - **[Architecture](./ARCHITECTURE.md)** - Design principles & philosophy (Data-driven sessions) ⭐ **UPDATED**
14
+ - **[Constructor Options](./CONSTRUCTOR_OPTIONS.md)** - Comprehensive guide to declarative vs fluent configuration ⭐ **UPDATED**
15
+ - **[Context Management](./CONTEXT_MANAGEMENT.md)** - Session state & data extraction patterns ⭐ **UPDATED**
17
16
 
18
17
  ### Reference
19
18
 
@@ -47,19 +46,15 @@ Welcome to the `@falai/agent` documentation!
47
46
  **Need specific API details?**
48
47
  → Browse the [API Reference](./API_REFERENCE.md)
49
48
 
50
- **Understanding the codebase?**
51
- → Read [Package Structure](./STRUCTURE.md)
52
-
53
49
  **Need persistence?**
54
50
  → See [Persistence Guide](./PERSISTENCE.md)
55
51
 
56
52
  ### By Topic
57
53
 
58
- - **Architecture & Design**: [Architecture Guide](./ARCHITECTURE.md) | [Package Structure](./STRUCTURE.md)
54
+ - **Architecture & Design**: [Architecture Guide](./ARCHITECTURE.md)
59
55
  - **Agent Configuration**: [Constructor Options](./CONSTRUCTOR_OPTIONS.md) | [Context Management](./CONTEXT_MANAGEMENT.md)
60
56
  - **Conversation Flows**: [API Reference - Routes](./API_REFERENCE.md#route)
61
57
  - **Tools & Domains**: [Domain Organization](./DOMAINS.md) | [API Reference - Tools](./API_REFERENCE.md#definetool)
62
- - **Disambiguation**: [API Reference - Observations](./API_REFERENCE.md#observation)
63
58
  - **AI Providers**: [Providers Guide](./PROVIDERS.md) | [API Reference](./API_REFERENCE.md#geminiprovider)
64
59
  - **Database Persistence**: [Persistence Guide](./PERSISTENCE.md) | [Adapters](./ADAPTERS.md)
65
60
  - **Contributing**: [Contributing Guide](./CONTRIBUTING.md) | [Publishing Guide](./PUBLISHING.md)
@@ -72,8 +67,9 @@ Check out the [`examples/`](../examples/) directory for complete, runnable examp
72
67
 
73
68
  - **[Declarative Agent](../examples/declarative-agent.ts)** - Full constructor-based configuration
74
69
  - **[Travel Agent](../examples/travel-agent.ts)** - Complex multi-route travel booking system
75
- - **[Healthcare Agent](../examples/healthcare-agent.ts)** - Disambiguation with observations
70
+ - **[Healthcare Agent](../examples/healthcare-agent.ts)** - Full example
76
71
  - **[Streaming Agent](../examples/streaming-agent.ts)** - Real-time streaming responses
72
+ - **[Company Q&A Agent](../examples/company-qna-agent.ts)** - Stateless question-answering with knowledge base
77
73
 
78
74
  ### Persistence Examples
79
75
 
@@ -90,6 +86,7 @@ Check out the [`examples/`](../examples/) directory for complete, runnable examp
90
86
 
91
87
  - **[Domain Scoping](../examples/domain-scoping.ts)** - Control tool access per route
92
88
  - **[Rules & Prohibitions](../examples/rules-prohibitions.ts)** - Fine-grained behavior control
89
+ - **[Extracted Data Modification](../examples/extracted-data-modification.ts)** - Tools that validate and enrich extracted data
93
90
 
94
91
  ## 🤝 Contributing
95
92