@falai/agent 0.6.3 → 0.6.4

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 (128) hide show
  1. package/README.md +89 -29
  2. package/dist/cjs/constants/index.d.ts +6 -1
  3. package/dist/cjs/constants/index.d.ts.map +1 -1
  4. package/dist/cjs/constants/index.js +8 -3
  5. package/dist/cjs/constants/index.js.map +1 -1
  6. package/dist/cjs/core/Agent.d.ts +22 -0
  7. package/dist/cjs/core/Agent.d.ts.map +1 -1
  8. package/dist/cjs/core/Agent.js +108 -21
  9. package/dist/cjs/core/Agent.js.map +1 -1
  10. package/dist/cjs/core/Events.d.ts +13 -0
  11. package/dist/cjs/core/Events.d.ts.map +1 -1
  12. package/dist/cjs/core/Events.js +28 -14
  13. package/dist/cjs/core/Events.js.map +1 -1
  14. package/dist/cjs/core/Route.d.ts.map +1 -1
  15. package/dist/cjs/core/Route.js +4 -4
  16. package/dist/cjs/core/Route.js.map +1 -1
  17. package/dist/cjs/core/RoutingEngine.d.ts +6 -1
  18. package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
  19. package/dist/cjs/core/RoutingEngine.js +112 -37
  20. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  21. package/dist/cjs/core/State.d.ts +15 -5
  22. package/dist/cjs/core/State.d.ts.map +1 -1
  23. package/dist/cjs/core/State.js +24 -5
  24. package/dist/cjs/core/State.js.map +1 -1
  25. package/dist/cjs/core/Tool.d.ts +8 -1
  26. package/dist/cjs/core/Tool.d.ts.map +1 -1
  27. package/dist/cjs/core/Tool.js +25 -28
  28. package/dist/cjs/core/Tool.js.map +1 -1
  29. package/dist/cjs/core/Transition.js +1 -1
  30. package/dist/cjs/index.d.ts +1 -1
  31. package/dist/cjs/index.d.ts.map +1 -1
  32. package/dist/cjs/index.js +3 -2
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/types/agent.d.ts +5 -0
  35. package/dist/cjs/types/agent.d.ts.map +1 -1
  36. package/dist/cjs/types/agent.js.map +1 -1
  37. package/dist/cjs/types/route.d.ts +7 -1
  38. package/dist/cjs/types/route.d.ts.map +1 -1
  39. package/dist/cjs/types/session.d.ts +12 -1
  40. package/dist/cjs/types/session.d.ts.map +1 -1
  41. package/dist/cjs/types/session.js +26 -5
  42. package/dist/cjs/types/session.js.map +1 -1
  43. package/dist/cjs/utils/logger.d.ts +10 -0
  44. package/dist/cjs/utils/logger.d.ts.map +1 -0
  45. package/dist/cjs/utils/logger.js +23 -0
  46. package/dist/cjs/utils/logger.js.map +1 -0
  47. package/dist/constants/index.d.ts +6 -1
  48. package/dist/constants/index.d.ts.map +1 -1
  49. package/dist/constants/index.js +6 -1
  50. package/dist/constants/index.js.map +1 -1
  51. package/dist/core/Agent.d.ts +22 -0
  52. package/dist/core/Agent.d.ts.map +1 -1
  53. package/dist/core/Agent.js +108 -21
  54. package/dist/core/Agent.js.map +1 -1
  55. package/dist/core/Events.d.ts +13 -0
  56. package/dist/core/Events.d.ts.map +1 -1
  57. package/dist/core/Events.js +28 -14
  58. package/dist/core/Events.js.map +1 -1
  59. package/dist/core/Route.d.ts.map +1 -1
  60. package/dist/core/Route.js +4 -4
  61. package/dist/core/Route.js.map +1 -1
  62. package/dist/core/RoutingEngine.d.ts +6 -1
  63. package/dist/core/RoutingEngine.d.ts.map +1 -1
  64. package/dist/core/RoutingEngine.js +112 -37
  65. package/dist/core/RoutingEngine.js.map +1 -1
  66. package/dist/core/State.d.ts +15 -5
  67. package/dist/core/State.d.ts.map +1 -1
  68. package/dist/core/State.js +25 -6
  69. package/dist/core/State.js.map +1 -1
  70. package/dist/core/Tool.d.ts +8 -1
  71. package/dist/core/Tool.d.ts.map +1 -1
  72. package/dist/core/Tool.js +25 -28
  73. package/dist/core/Tool.js.map +1 -1
  74. package/dist/core/Transition.js +1 -1
  75. package/dist/index.d.ts +1 -1
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +1 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/types/agent.d.ts +5 -0
  80. package/dist/types/agent.d.ts.map +1 -1
  81. package/dist/types/agent.js.map +1 -1
  82. package/dist/types/route.d.ts +7 -1
  83. package/dist/types/route.d.ts.map +1 -1
  84. package/dist/types/session.d.ts +12 -1
  85. package/dist/types/session.d.ts.map +1 -1
  86. package/dist/types/session.js +26 -5
  87. package/dist/types/session.js.map +1 -1
  88. package/dist/utils/logger.d.ts +10 -0
  89. package/dist/utils/logger.d.ts.map +1 -0
  90. package/dist/utils/logger.js +17 -0
  91. package/dist/utils/logger.js.map +1 -0
  92. package/docs/{CONSTRUCTOR_OPTIONS.md → AGENT.md} +79 -7
  93. package/docs/API_REFERENCE.md +309 -18
  94. package/docs/ARCHITECTURE.md +1 -1
  95. package/docs/DOCS.md +46 -22
  96. package/docs/GETTING_STARTED.md +1 -1
  97. package/docs/README.md +13 -5
  98. package/docs/ROUTES.md +743 -0
  99. package/docs/STATES.md +798 -0
  100. package/examples/business-onboarding.ts +46 -5
  101. package/examples/company-qna-agent.ts +107 -1
  102. package/examples/custom-database-persistence.ts +44 -1
  103. package/examples/declarative-agent.ts +80 -37
  104. package/examples/domain-scoping.ts +91 -21
  105. package/examples/extracted-data-modification.ts +64 -2
  106. package/examples/healthcare-agent.ts +61 -4
  107. package/examples/openai-agent.ts +24 -2
  108. package/examples/opensearch-persistence.ts +26 -1
  109. package/examples/persistent-onboarding.ts +84 -18
  110. package/examples/prisma-persistence.ts +90 -16
  111. package/examples/redis-persistence.ts +89 -17
  112. package/examples/rules-prohibitions.ts +300 -139
  113. package/examples/streaming-agent.ts +60 -0
  114. package/examples/travel-agent.ts +66 -24
  115. package/package.json +3 -2
  116. package/src/constants/index.ts +6 -1
  117. package/src/core/Agent.ts +135 -21
  118. package/src/core/Events.ts +73 -10
  119. package/src/core/Route.ts +8 -4
  120. package/src/core/RoutingEngine.ts +150 -39
  121. package/src/core/State.ts +35 -10
  122. package/src/core/Tool.ts +67 -10
  123. package/src/core/Transition.ts +1 -1
  124. package/src/index.ts +1 -1
  125. package/src/types/agent.ts +5 -0
  126. package/src/types/route.ts +10 -1
  127. package/src/types/session.ts +42 -6
  128. package/src/utils/logger.ts +19 -0
@@ -16,7 +16,7 @@ Main agent class for managing conversational AI.
16
16
  new Agent<TContext>(options: AgentOptions<TContext>)
17
17
  ```
18
18
 
19
- See [Constructor Options](./CONSTRUCTOR_OPTIONS.md) for full details.
19
+ See [Agent](./AGENT.md) for full details.
20
20
 
21
21
  #### Methods
22
22
 
@@ -48,6 +48,70 @@ Gets allowed domains for a specific route by ID. Returns filtered domains based
48
48
 
49
49
  Gets allowed domains for a specific route by title. Returns filtered domains based on route's `domains` property, or all domains if route has no restrictions.
50
50
 
51
+ ##### `getExtractedData<TExtracted>(routeId?): Partial<TExtracted>`
52
+
53
+ Gets the extracted data from current session, optionally for a specific route.
54
+
55
+ ```typescript
56
+ // Option 1: Using current session (set with setCurrentSession)
57
+ agent.setCurrentSession(session);
58
+ const extracted = agent.getExtractedData(); // Uses current session
59
+
60
+ // Option 2: Get data for specific route
61
+ const routeData = agent.getExtractedData("onboarding"); // Route-specific data
62
+
63
+ // Option 3: From response (with current session set)
64
+ const response = await agent.respond({ history });
65
+ const extracted = agent.getExtractedData(); // Uses current session
66
+ ```
67
+
68
+ **Parameters:**
69
+
70
+ - `routeId` (optional): Route ID to get data for. If not provided, returns current route data.
71
+
72
+ **Returns:** The extracted data from the current session
73
+
74
+ **Note:** Returns empty object if no current session is set.
75
+
76
+ ##### `setCurrentSession(session): void`
77
+
78
+ Sets the current session for convenience methods. Once set, methods like `getExtractedData()` don't need the session parameter.
79
+
80
+ ```typescript
81
+ // Set current session
82
+ agent.setCurrentSession(session);
83
+
84
+ // Now methods use the current session automatically
85
+ const extracted = agent.getExtractedData();
86
+ // Get extracted data for route
87
+ const routeData = agent.getExtractedData("onboarding");
88
+ ```
89
+
90
+ **Parameters:**
91
+
92
+ - `session`: Session state to use as current session
93
+
94
+ ##### `getCurrentSession(): SessionState | undefined`
95
+
96
+ Gets the currently set session.
97
+
98
+ ```typescript
99
+ const current = agent.getCurrentSession();
100
+ if (current) {
101
+ console.log("Current session:", current.id);
102
+ }
103
+ ```
104
+
105
+ **Returns:** Current session or undefined if none set
106
+
107
+ ##### `clearCurrentSession(): void`
108
+
109
+ Clears the current session.
110
+
111
+ ```typescript
112
+ agent.clearCurrentSession();
113
+ ```
114
+
51
115
  ##### `respond(input: RespondInput<TContext>): Promise<RespondOutput>`
52
116
 
53
117
  Generates an AI response with session state management, data extraction, and intelligent routing.
@@ -70,6 +134,13 @@ interface RespondOutput {
70
134
  toolName: string;
71
135
  arguments: Record<string, unknown>;
72
136
  }>;
137
+ /**
138
+ * NEW: Indicates if the current route has reached END_STATE
139
+ * When true, all required data has been collected and the route is complete.
140
+ * Your application should handle this appropriately (e.g., process collected data,
141
+ * show completion UI, start a new route, etc.)
142
+ */
143
+ isRouteComplete?: boolean;
73
144
  }
74
145
  ```
75
146
 
@@ -86,6 +157,7 @@ interface RespondOutput {
86
157
  - Tracks current route, state, and extracted data across turns
87
158
  - Enables "I changed my mind" scenarios with context-aware routing
88
159
  - Automatically merges new extracted data with existing session data
160
+ - **Per-route data preservation** - Extracted data is organized by route ID, allowing users to switch routes without losing progress
89
161
 
90
162
  **Example with Persistence Adapters:**
91
163
 
@@ -99,9 +171,21 @@ const { sessionData, sessionState } =
99
171
  agentName: "Travel Agent",
100
172
  });
101
173
 
174
+ // Option 1: Set current session for convenience
175
+ agent.setCurrentSession(sessionState);
176
+
102
177
  const response = await agent.respond({
103
178
  history,
104
- session: sessionState, // Auto-saves if autoSave: true
179
+ // session: sessionState, // No longer required!
180
+ });
181
+
182
+ // Use convenience methods without passing session
183
+ const extracted = agent.getExtractedData();
184
+
185
+ // Option 2: Still pass session explicitly if preferred
186
+ const response2 = await agent.respond({
187
+ history,
188
+ session: sessionState,
105
189
  });
106
190
  ```
107
191
 
@@ -178,6 +262,101 @@ await yourDb.messages.create({
178
262
  });
179
263
  ```
180
264
 
265
+ **Handling Route Completion:**
266
+
267
+ When a route reaches its END_STATE transition (all required data collected), the response includes `isRouteComplete: true`:
268
+
269
+ ```typescript
270
+ const response = await agent.respond({
271
+ history,
272
+ session,
273
+ });
274
+
275
+ if (response.isRouteComplete) {
276
+ // Route is complete! All data has been collected
277
+ console.log("✅ Route completed!");
278
+
279
+ // Get all the collected data
280
+ const collectedData = agent.getExtractedData(response.session!);
281
+ console.log("Collected data:", collectedData);
282
+
283
+ // Handle completion in your application:
284
+ // - Save the collected data to your database
285
+ // - Trigger business logic (e.g., create booking, send email)
286
+ // - Show completion UI to user
287
+ // - Start a new route or conversation
288
+
289
+ await processCompletedData(collectedData);
290
+
291
+ // Optional: Show a custom completion message
292
+ return "Thank you! Your information has been saved.";
293
+ } else {
294
+ // Normal flow - route still in progress
295
+ return response.message;
296
+ }
297
+ ```
298
+
299
+ **Example: Onboarding Flow**
300
+
301
+ ```typescript
302
+ // Onboarding route with skipIf logic for pre-filled data
303
+ const onboardingRoute = agent.createRoute<OnboardingData>({
304
+ id: "onboarding",
305
+ title: "User Onboarding",
306
+ extractionSchema: ONBOARDING_SCHEMA,
307
+ initialData: existingUserData, // Pre-fill with existing data
308
+ });
309
+
310
+ // Build states with skipIf conditions
311
+ const welcome = onboardingRoute.initialState.transitionTo({
312
+ id: "ask_name",
313
+ chatState: "What's your name?",
314
+ gather: ["name"],
315
+ skipIf: (data) => !!data.name, // Skip if name already collected
316
+ });
317
+
318
+ const askEmail = welcome.transitionTo({
319
+ id: "ask_email",
320
+ chatState: "What's your email?",
321
+ gather: ["email"],
322
+ skipIf: (data) => !!data.email, // Skip if email already collected
323
+ });
324
+
325
+ const complete = askEmail.transitionTo({
326
+ id: "complete",
327
+ chatState: "All done! Thank you.",
328
+ });
329
+
330
+ complete.transitionTo({ state: END_STATE });
331
+
332
+ // Option 1: Set current session for convenience
333
+ agent.setCurrentSession(session);
334
+
335
+ const response = await agent.respond({ history });
336
+
337
+ if (response.isRouteComplete) {
338
+ // If all data was pre-filled, the route completes immediately!
339
+ // The routing engine recursively skips all states and reaches END_STATE
340
+ const data = agent.getExtractedData(); // No need to pass session!
341
+ await saveUserProfile(data);
342
+ return "Profile updated successfully!";
343
+ }
344
+
345
+ // Get route-specific data if needed
346
+ const onboardingData = agent.getExtractedDataForRoute("onboarding");
347
+ const bookingData = agent.getExtractedDataForRoute("booking");
348
+
349
+ return response.message;
350
+ ```
351
+
352
+ **Important Notes:**
353
+
354
+ - `isRouteComplete` is `true` when the route reaches an `END_STATE` transition
355
+ - The `message` will be empty (`""`) when `isRouteComplete` is `true`
356
+ - You should check `isRouteComplete` and handle completion appropriately
357
+ - If all states are skipped (due to `skipIf` conditions), the route can complete immediately on entry
358
+ - Use `agent.getExtractedData(session)` to retrieve all collected data
359
+
181
360
  See also: [Custom Database Integration Example](../examples/custom-database-persistence.ts)
182
361
 
183
362
  ##### `respondStream(input: RespondInput<TContext>): AsyncGenerator<StreamChunk>`
@@ -192,15 +371,18 @@ interface StreamChunk {
192
371
  accumulated: string;
193
372
  /** Whether this is the final chunk */
194
373
  done: boolean;
195
- /** Route chosen by the agent (only in final chunk) */
196
- route?: { id: string; title: string };
197
- /** Current state within the route (only in final chunk) */
198
- state?: { id: string; description?: string };
374
+ /** Updated session state (includes extracted data, current route/state) */
375
+ session?: SessionState;
199
376
  /** Tool calls requested by the agent (only in final chunk) */
200
377
  toolCalls?: Array<{
201
378
  toolName: string;
202
379
  arguments: Record<string, unknown>;
203
380
  }>;
381
+ /**
382
+ * Indicates if the current route has reached END_STATE (only in final chunk)
383
+ * When true, all required data has been collected and the route is complete.
384
+ */
385
+ isRouteComplete?: boolean;
204
386
  }
205
387
  ```
206
388
 
@@ -215,7 +397,7 @@ interface StreamChunk {
215
397
 
216
398
  ```typescript
217
399
  // Basic streaming
218
- for await (const chunk of agent.respondStream({ history })) {
400
+ for await (const chunk of agent.respondStream({ history, session })) {
219
401
  if (chunk.delta) {
220
402
  // Display incremental text to user
221
403
  process.stdout.write(chunk.delta);
@@ -223,9 +405,17 @@ for await (const chunk of agent.respondStream({ history })) {
223
405
 
224
406
  if (chunk.done) {
225
407
  console.log("\n✅ Complete!");
226
- // Access final metadata
227
- if (chunk.route) {
228
- console.log("Route:", chunk.route.title);
408
+
409
+ // Check if route is complete
410
+ if (chunk.isRouteComplete) {
411
+ console.log("🎉 Route completed!");
412
+ const data = agent.getExtractedData(chunk.session!);
413
+ await handleCompletion(data);
414
+ }
415
+
416
+ // Access session state
417
+ if (chunk.session?.currentRoute) {
418
+ console.log("Route:", chunk.session.currentRoute.title);
229
419
  }
230
420
  if (chunk.toolCalls) {
231
421
  console.log("Tool calls:", chunk.toolCalls.length);
@@ -330,11 +520,28 @@ interface RouteOptions<TExtracted = unknown> {
330
520
 
331
521
  // NEW: Pre-populate extracted data when entering route
332
522
  initialData?: Partial<TExtracted>;
523
+
524
+ // NEW: Configure the initial state
525
+ initialState?: {
526
+ id?: string; // Custom ID for the initial state
527
+ chatState?: string; // Description for the initial state
528
+ gather?: string[]; // Fields to gather in the initial state
529
+ skipIf?: (extracted: Partial<TExtracted>) => boolean; // Skip condition
530
+ requiredData?: string[]; // Required data prerequisites
531
+ };
532
+
533
+ // NEW: Sequential steps for simple linear flows
534
+ steps?: TransitionSpec<unknown, TExtracted>[];
333
535
  }
334
536
  ```
335
537
 
336
538
  **Note on IDs:** Route IDs are deterministic by default, generated from the title using a hash function. This ensures consistency across server restarts. You can provide a custom ID if you need specific control over the identifier.
337
539
 
540
+ **Initial State Configuration:** You can configure the initial state in two ways:
541
+
542
+ 1. Using `initialState` option when creating the route
543
+ 2. Using `route.initialState.configure()` method after route creation
544
+
338
545
  #### Methods
339
546
 
340
547
  ##### `createGuideline(guideline: Guideline): this`
@@ -361,6 +568,8 @@ Returns the prohibitions that must never be done in this route.
361
568
 
362
569
  Returns a reference to this route.
363
570
 
571
+ **Note:** Routes no longer have a `getExtractedData()` method. Use `agent.getExtractedData()` or `agent.getExtractedDataForRoute(routeId)` instead.
572
+
364
573
  ##### `describe(): string`
365
574
 
366
575
  Generates a description of this route's structure.
@@ -403,7 +612,7 @@ Creates a transition from this state and returns a chainable result.
403
612
  interface TransitionSpec<TExtracted = unknown> {
404
613
  chatState?: string; // Transition to a chat interaction
405
614
  toolState?: ToolRef; // Transition to execute a tool
406
- state?: StateRef | symbol; // Transition to specific state or END_ROUTE
615
+ state?: StateRef | symbol; // Transition to specific state or END_STATE
407
616
 
408
617
  // NEW: Data extraction fields for this state
409
618
  gather?: string[];
@@ -492,7 +701,7 @@ flightRoute.initialState
492
701
  .transitionTo({
493
702
  chatState: "Present available flights",
494
703
  })
495
- .transitionTo({ state: END_ROUTE });
704
+ .transitionTo({ state: END_STATE });
496
705
 
497
706
  // Use with session state
498
707
  let session = createSession<FlightData>();
@@ -504,6 +713,36 @@ console.log(response.session?.extracted); // { destination: "Paris", ... }
504
713
 
505
714
  Adds a guideline specific to this state.
506
715
 
716
+ ##### `configure(config): this`
717
+
718
+ Configure the state properties after creation. Useful for overriding initial state configuration. Returns `this` for chaining.
719
+
720
+ ```typescript
721
+ // Configure initial state after route creation
722
+ route.initialState.configure({
723
+ description: "Welcome! Let's get started",
724
+ gatherFields: ["name", "email"],
725
+ skipIf: (extracted) => !!extracted.name && !!extracted.email,
726
+ requiredData: [],
727
+ });
728
+
729
+ // Or configure any state
730
+ const askName = route.initialState.transitionTo({ chatState: "Ask for name" });
731
+ askName.configure({
732
+ gatherFields: ["firstName", "lastName"],
733
+ });
734
+ ```
735
+
736
+ **Parameters:**
737
+
738
+ - `config`: Configuration object with optional properties:
739
+ - `description?: string` - State description
740
+ - `gatherFields?: string[]` - Fields to gather in this state
741
+ - `skipIf?: (extracted: Partial<TExtracted>) => boolean` - Skip condition function
742
+ - `requiredData?: string[]` - Required data prerequisites
743
+
744
+ **Returns:** `this` for method chaining
745
+
507
746
  #### Properties
508
747
 
509
748
  ##### `id: string`
@@ -1531,9 +1770,19 @@ interface SessionState<TExtracted = Record<string, unknown>> {
1531
1770
  enteredAt: Date;
1532
1771
  };
1533
1772
 
1534
- /** Data extracted during the current route */
1773
+ /**
1774
+ * Data extracted during the current route
1775
+ * Convenience reference to extractedByRoute[currentRoute.id]
1776
+ */
1535
1777
  extracted: Partial<TExtracted>;
1536
1778
 
1779
+ /**
1780
+ * Extracted data organized by route ID
1781
+ * Preserves data when switching between routes
1782
+ * Format: { "routeId": { ...extractedData } }
1783
+ */
1784
+ extractedByRoute: Record<string, Partial<unknown>>;
1785
+
1537
1786
  /** History of routes visited in this session */
1538
1787
  routeHistory: Array<{
1539
1788
  routeId: string;
@@ -1554,11 +1803,26 @@ interface SessionState<TExtracted = Record<string, unknown>> {
1554
1803
  **Key Features:**
1555
1804
 
1556
1805
  - **`id`** - Optional session identifier that persists across database operations
1557
- - **`extracted`** - Type-safe data collected via `extractionSchema`
1806
+ - **`extracted`** - Type-safe data collected via `extractionSchema` for the **current route**
1807
+ - **`extractedByRoute`** - **NEW:** Per-route data map that preserves extracted data when switching routes
1558
1808
  - **`currentRoute`** / **`currentState`** - Track conversation position
1559
1809
  - **`routeHistory`** - Full audit trail of route transitions
1560
1810
  - **`metadata`** - Custom data (timestamps, user info, etc.)
1561
1811
 
1812
+ **Per-Route Data Preservation:**
1813
+
1814
+ When users switch routes (e.g., "Actually, I want to book a hotel instead"), the framework automatically:
1815
+
1816
+ - Saves current route's `extracted` data to `extractedByRoute[routeId]`
1817
+ - Loads the new route's data from `extractedByRoute[newRouteId]` (if resuming)
1818
+ - Keeps `extracted` as a convenient reference to the current route's data
1819
+
1820
+ This allows users to:
1821
+
1822
+ - Switch routes without losing progress
1823
+ - Resume incomplete routes where they left off
1824
+ - Access historical data from previous routes via `session.extractedByRoute["route_id"]`
1825
+
1562
1826
  **Usage:**
1563
1827
 
1564
1828
  ```typescript
@@ -1818,16 +2082,43 @@ All IDs are generated deterministically using a hash function of their content (
1818
2082
 
1819
2083
  ## Constants
1820
2084
 
1821
- ### `END_ROUTE`
2085
+ ### `END_STATE`
1822
2086
 
1823
- Symbol marking the end of a conversation route.
2087
+ Symbol marking the end of a conversation route. Use this when building routes to mark where they should end.
1824
2088
 
1825
2089
  ```typescript
1826
- import { END_ROUTE } from "@falai/agent";
2090
+ import { END_STATE } from "@falai/agent";
1827
2091
 
1828
- state.transitionTo({ state: END_ROUTE });
2092
+ const thankYou = askEmail.transitionTo({
2093
+ chatState: "Thank you for your information!",
2094
+ });
2095
+
2096
+ // Mark the end of the route
2097
+ thankYou.transitionTo({ state: END_STATE });
2098
+ ```
2099
+
2100
+ ### `END_STATE_ID`
2101
+
2102
+ String constant representing END_STATE for runtime comparisons. When a route completes, `currentState.id` is set to this value.
2103
+
2104
+ ```typescript
2105
+ import { END_STATE_ID } from "@falai/agent";
2106
+
2107
+ const response = await agent.respond({ history, session });
2108
+
2109
+ // Method 1: Using isRouteComplete (recommended)
2110
+ if (response.isRouteComplete) {
2111
+ console.log("Route completed!");
2112
+ }
2113
+
2114
+ // Method 2: Using END_STATE_ID constant
2115
+ if (response.session?.currentState?.id === END_STATE_ID) {
2116
+ console.log("Route completed!");
2117
+ }
1829
2118
  ```
1830
2119
 
2120
+ **Note:** Both methods are equivalent. Use `isRouteComplete` for simplicity, or `END_STATE_ID` for consistency with how you build routes.
2121
+
1831
2122
  ---
1832
2123
 
1833
2124
  ## Enums
@@ -158,7 +158,7 @@ If you don't provide an ID, one is automatically generated from the route ID and
158
158
  1. **Code filters first**: `skipIf` and `requiredData` filter out invalid states deterministically
159
159
  2. **AI selects best state**: From valid candidates, AI evaluates text conditions to choose optimal state
160
160
  3. **Combined decision**: Single AI call handles both route selection AND state selection (no extra calls!)
161
- 4. **Completion detection**: When all states are skipped and `END_ROUTE` is reached, route is marked complete
161
+ 4. **Completion detection**: When all states are skipped and `END_STATE` is reached, route is marked complete
162
162
 
163
163
  ```typescript
164
164
  // The AI sees:
package/docs/DOCS.md CHANGED
@@ -9,6 +9,7 @@ Complete index of all `@falai/agent` documentation.
9
9
  Start here if you're new to the framework:
10
10
 
11
11
  ### [Getting Started Guide](./GETTING_STARTED.md)
12
+
12
13
  Build your first AI agent in 5 minutes with step-by-step instructions.
13
14
 
14
15
  **Topics:** Installation, first agent, basic routes, data extraction, session state
@@ -20,16 +21,19 @@ Build your first AI agent in 5 minutes with step-by-step instructions.
20
21
  Essential guides for understanding how the framework works:
21
22
 
22
23
  ### [Architecture](./ARCHITECTURE.md)
24
+
23
25
  Design principles, philosophy, and how the framework works under the hood.
24
26
 
25
27
  **Topics:** Schema-first extraction, session state, code-based logic, state machines, deterministic IDs
26
28
 
27
- ### [Constructor Options](./CONSTRUCTOR_OPTIONS.md)
29
+ ### [Agent](./AGENT.md)
30
+
28
31
  Comprehensive guide to agent configuration patterns.
29
32
 
30
33
  **Topics:** Declarative vs fluent API, terms, guidelines, capabilities, routes, initialization patterns
31
34
 
32
35
  ### [Context Management](./CONTEXT_MANAGEMENT.md)
36
+
33
37
  Session state, lifecycle hooks, and persistent conversations.
34
38
 
35
39
  **Topics:** Session state, lifecycle hooks, context updates, multi-turn conversations, persistence patterns
@@ -40,27 +44,44 @@ Session state, lifecycle hooks, and persistent conversations.
40
44
 
41
45
  Deep dives into specific features:
42
46
 
47
+ ### [Routes Guide](./ROUTES.md)
48
+
49
+ Complete guide to creating and managing conversational routes.
50
+
51
+ **Topics:** Route creation, initial state configuration, data extraction, sequential steps, security, branching logic
52
+
53
+ ### [States Guide](./STATES.md)
54
+
55
+ Complete guide to creating and managing states in conversational flows.
56
+
57
+ **Topics:** State types, transitions, data gathering, state logic, skip conditions, configuration, advanced patterns
58
+
43
59
  ### [API Reference](./API_REFERENCE.md)
60
+
44
61
  Complete API documentation for all classes, methods, and types.
45
62
 
46
63
  **Topics:** Agent class, Route class, State class, defineTool, providers, all APIs
47
64
 
48
65
  ### [AI Providers](./PROVIDERS.md)
66
+
49
67
  Guide to AI provider configuration and usage.
50
68
 
51
69
  **Topics:** Anthropic (Claude), OpenAI (GPT), Google (Gemini), OpenRouter, custom providers, backup models, retry logic
52
70
 
53
71
  ### [Domain Organization](./DOMAINS.md)
72
+
54
73
  Optional tool security and organization.
55
74
 
56
75
  **Topics:** Domain-based security, tool scoping, route isolation, preventing unauthorized access
57
76
 
58
77
  ### [Persistence Guide](./PERSISTENCE.md)
78
+
59
79
  Database integration and session persistence.
60
80
 
61
81
  **Topics:** Persistence adapters, auto-save, session management, lifecycle integration, custom adapters
62
82
 
63
83
  ### [Database Adapters](./ADAPTERS.md)
84
+
64
85
  Detailed comparison and configuration for all database adapters.
65
86
 
66
87
  **Topics:** Prisma, Redis, MongoDB, PostgreSQL, SQLite, OpenSearch, Memory adapter, custom adapters
@@ -72,12 +93,15 @@ Detailed comparison and configuration for all database adapters.
72
93
  Real-world code examples:
73
94
 
74
95
  ### [Examples Guide](./EXAMPLES.md)
96
+
75
97
  Comprehensive guide to all 15+ production-ready examples.
76
98
 
77
99
  **Topics:** Learning path, use case guide, code examples, quick reference
78
100
 
79
101
  ### [Example Files](../examples/)
102
+
80
103
  Browse the `/examples` directory for runnable code:
104
+
81
105
  - [Business Onboarding](../examples/business-onboarding.ts) - Complex multi-step workflows
82
106
  - [Travel Agent](../examples/travel-agent.ts) - Session state & data extraction
83
107
  - [Healthcare Agent](../examples/healthcare-agent.ts) - Security & validation
@@ -93,11 +117,13 @@ Browse the `/examples` directory for runnable code:
93
117
  Help improve the framework:
94
118
 
95
119
  ### [Contributing Guide](./CONTRIBUTING.md)
120
+
96
121
  How to contribute code, documentation, and report issues.
97
122
 
98
123
  **Topics:** Development setup, code style, pull requests, bug reports
99
124
 
100
125
  ### [Publishing Guide](./PUBLISHING.md)
126
+
101
127
  Internal guide for maintainers on publishing releases.
102
128
 
103
129
  **Topics:** Release process, versioning, npm publishing, changelog
@@ -112,7 +138,9 @@ Internal guide for maintainers on publishing releases.
112
138
 
113
139
  - **Build my first agent** → [Getting Started](./GETTING_STARTED.md)
114
140
  - **Understand the design** → [Architecture](./ARCHITECTURE.md)
115
- - **Configure my agent** → [Constructor Options](./CONSTRUCTOR_OPTIONS.md)
141
+ - **Configure my agent** → [Agent](./AGENT.md)
142
+ - **Create conversational flows** → [Routes Guide](./ROUTES.md)
143
+ - **Manage states** → [States Guide](./STATES.md)
116
144
  - **Persist conversations** → [Persistence Guide](./PERSISTENCE.md)
117
145
  - **Add tool security** → [Domain Organization](./DOMAINS.md)
118
146
  - **See real examples** → [Examples Guide](./EXAMPLES.md)
@@ -124,45 +152,57 @@ Internal guide for maintainers on publishing releases.
124
152
  ### By Topic
125
153
 
126
154
  **Architecture & Design:**
155
+
127
156
  - [Architecture Guide](./ARCHITECTURE.md)
128
157
  - [How It Works](../README.md#-how-it-works)
129
158
 
130
159
  **Agent Configuration:**
131
- - [Constructor Options](./CONSTRUCTOR_OPTIONS.md)
160
+
161
+ - [Agent](./AGENT.md)
132
162
  - [Context Management](./CONTEXT_MANAGEMENT.md)
133
163
  - [Getting Started](./GETTING_STARTED.md)
134
164
 
135
165
  **Routes & State Machines:**
166
+
167
+ - [Routes Guide](./ROUTES.md) - Complete guide to routes
168
+ - [States Guide](./STATES.md) - Complete guide to states
136
169
  - [API Reference - Routes](./API_REFERENCE.md#route)
170
+ - [API Reference - States](./API_REFERENCE.md#state)
137
171
  - [Architecture - State Machines](./ARCHITECTURE.md#state-machines)
138
172
  - [Examples - Complex Flows](./EXAMPLES.md#-real-world-applications)
139
173
 
140
174
  **Tools & Domains:**
175
+
141
176
  - [Domain Organization](./DOMAINS.md)
142
177
  - [API Reference - defineTool](./API_REFERENCE.md#definetool)
143
178
  - [Examples - Domain Scoping](./EXAMPLES.md#-domain-scoping)
144
179
 
145
180
  **Data Extraction:**
181
+
146
182
  - [Architecture - Schema-First](./ARCHITECTURE.md#schema-first-data-extraction)
147
183
  - [API Reference - extractionSchema](./API_REFERENCE.md#extractionschema)
148
184
  - [Examples - Travel Agent](./EXAMPLES.md#-travel-agent)
149
185
 
150
186
  **Session State:**
187
+
151
188
  - [Context Management](./CONTEXT_MANAGEMENT.md)
152
189
  - [Architecture - Session State](./ARCHITECTURE.md#session-state-management)
153
190
  - [API Reference - createSession](./API_REFERENCE.md#createsession)
154
191
 
155
192
  **Persistence:**
193
+
156
194
  - [Persistence Guide](./PERSISTENCE.md)
157
195
  - [Database Adapters](./ADAPTERS.md)
158
196
  - [Examples - Prisma](./EXAMPLES.md#-prisma-persistence)
159
197
 
160
198
  **AI Providers:**
199
+
161
200
  - [AI Providers Guide](./PROVIDERS.md)
162
201
  - [API Reference - Providers](./API_REFERENCE.md#providers)
163
202
  - [Examples - Multiple Providers](./EXAMPLES.md#-provider-examples)
164
203
 
165
204
  **Streaming:**
205
+
166
206
  - [API Reference - respondStream](./API_REFERENCE.md#respondstream)
167
207
  - [Examples - Streaming](./EXAMPLES.md#-streaming-responses)
168
208
 
@@ -173,32 +213,15 @@ Internal guide for maintainers on publishing releases.
173
213
  All documentation follows these conventions:
174
214
 
175
215
  ### Code Examples
216
+
176
217
  All code examples are TypeScript and can be copy-pasted directly.
177
218
 
178
219
  ### Links
220
+
179
221
  - Internal docs use relative links: `[Text](./FILE.md)`
180
222
  - Examples use relative links: `[Text](../examples/file.ts)`
181
223
  - External links use full URLs
182
224
 
183
- ### File Structure
184
- ```
185
- docs/
186
- ├── INDEX.md # This file - documentation index
187
- ├── README.md # Docs overview and quick links
188
- ├── GETTING_STARTED.md # Beginner tutorial
189
- ├── ARCHITECTURE.md # Design principles
190
- ├── API_REFERENCE.md # Complete API docs
191
- ├── CONSTRUCTOR_OPTIONS.md # Configuration patterns
192
- ├── CONTEXT_MANAGEMENT.md # Session state & hooks
193
- ├── PERSISTENCE.md # Database integration
194
- ├── ADAPTERS.md # Database adapter guide
195
- ├── DOMAINS.md # Tool security
196
- ├── PROVIDERS.md # AI provider guide
197
- ├── EXAMPLES.md # Examples guide
198
- ├── CONTRIBUTING.md # How to contribute
199
- └── PUBLISHING.md # Release guide (maintainers)
200
- ```
201
-
202
225
  ---
203
226
 
204
227
  ## 🔍 Search Tips
@@ -211,6 +234,7 @@ docs/
211
234
  4. **Search the [API Reference](./API_REFERENCE.md)** for specific APIs
212
235
 
213
236
  **Common searches:**
237
+
214
238
  - "How do I..." → [Getting Started](./GETTING_STARTED.md)
215
239
  - "What is..." → [Architecture](./ARCHITECTURE.md)
216
240
  - "Example of..." → [Examples Guide](./EXAMPLES.md)
@@ -417,7 +417,7 @@ new GeminiProvider({
417
417
 
418
418
  ## What's Next?
419
419
 
420
- - 📚 Read the [Constructor Options Guide](./CONSTRUCTOR_OPTIONS.md)
420
+ - 📚 Read the [Agent Guide](./AGENT.md)
421
421
  - 🔍 Check the [API Reference](./API_REFERENCE.md)
422
422
  - 🏗️ Understand the [Architecture](./ARCHITECTURE.md)
423
423
  - 🎯 Explore [Examples](../examples/)