@falai/agent 0.1.0-alpha2 → 0.1.0-alpha3

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 (59) hide show
  1. package/README.md +106 -0
  2. package/dist/cjs/src/core/BatchExecutor.d.ts +353 -0
  3. package/dist/cjs/src/core/BatchExecutor.d.ts.map +1 -0
  4. package/dist/cjs/src/core/BatchExecutor.js +842 -0
  5. package/dist/cjs/src/core/BatchExecutor.js.map +1 -0
  6. package/dist/cjs/src/core/BatchPromptBuilder.d.ts +86 -0
  7. package/dist/cjs/src/core/BatchPromptBuilder.d.ts.map +1 -0
  8. package/dist/cjs/src/core/BatchPromptBuilder.js +201 -0
  9. package/dist/cjs/src/core/BatchPromptBuilder.js.map +1 -0
  10. package/dist/cjs/src/core/ResponseModal.d.ts +34 -0
  11. package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -1
  12. package/dist/cjs/src/core/ResponseModal.js +460 -34
  13. package/dist/cjs/src/core/ResponseModal.js.map +1 -1
  14. package/dist/cjs/src/index.d.ts +2 -0
  15. package/dist/cjs/src/index.d.ts.map +1 -1
  16. package/dist/cjs/src/index.js +7 -1
  17. package/dist/cjs/src/index.js.map +1 -1
  18. package/dist/cjs/src/types/agent.d.ts +9 -1
  19. package/dist/cjs/src/types/agent.d.ts.map +1 -1
  20. package/dist/cjs/src/types/route.d.ts +98 -0
  21. package/dist/cjs/src/types/route.d.ts.map +1 -1
  22. package/dist/src/core/BatchExecutor.d.ts +353 -0
  23. package/dist/src/core/BatchExecutor.d.ts.map +1 -0
  24. package/dist/src/core/BatchExecutor.js +837 -0
  25. package/dist/src/core/BatchExecutor.js.map +1 -0
  26. package/dist/src/core/BatchPromptBuilder.d.ts +86 -0
  27. package/dist/src/core/BatchPromptBuilder.d.ts.map +1 -0
  28. package/dist/src/core/BatchPromptBuilder.js +197 -0
  29. package/dist/src/core/BatchPromptBuilder.js.map +1 -0
  30. package/dist/src/core/ResponseModal.d.ts +34 -0
  31. package/dist/src/core/ResponseModal.d.ts.map +1 -1
  32. package/dist/src/core/ResponseModal.js +460 -34
  33. package/dist/src/core/ResponseModal.js.map +1 -1
  34. package/dist/src/index.d.ts +2 -0
  35. package/dist/src/index.d.ts.map +1 -1
  36. package/dist/src/index.js +2 -0
  37. package/dist/src/index.js.map +1 -1
  38. package/dist/src/types/agent.d.ts +9 -1
  39. package/dist/src/types/agent.d.ts.map +1 -1
  40. package/dist/src/types/route.d.ts +98 -0
  41. package/dist/src/types/route.d.ts.map +1 -1
  42. package/docs/api/overview.md +124 -0
  43. package/docs/architecture/multi-step-execution.md +243 -0
  44. package/docs/core/ai-integration/prompt-composition.md +135 -0
  45. package/docs/core/ai-integration/response-processing.md +146 -0
  46. package/docs/core/conversation-flows/data-collection.md +143 -0
  47. package/docs/core/conversation-flows/step-transitions.md +132 -0
  48. package/docs/core/conversation-flows/steps.md +112 -0
  49. package/docs/core/error-handling.md +193 -0
  50. package/docs/guides/getting-started/README.md +102 -0
  51. package/docs/guides/migration/README.md +23 -0
  52. package/docs/guides/migration/multi-step-execution.md +303 -0
  53. package/package.json +4 -2
  54. package/src/core/BatchExecutor.ts +1156 -0
  55. package/src/core/BatchPromptBuilder.ts +275 -0
  56. package/src/core/ResponseModal.ts +605 -35
  57. package/src/index.ts +2 -0
  58. package/src/types/agent.ts +9 -1
  59. package/src/types/route.ts +119 -0
@@ -12,6 +12,138 @@ Step transitions handle:
12
12
  - **Route Completion**: Detect when routes reach their end
13
13
  - **Loop Prevention**: Avoid infinite traversal in complex flows
14
14
 
15
+ ## Stopping Conditions in Batch Execution
16
+
17
+ When executing multiple steps in a batch, the engine stops for specific reasons indicated by the `stoppedReason` field in the response.
18
+
19
+ ### StoppedReason Values
20
+
21
+ | Reason | Description | Behavior |
22
+ |--------|-------------|----------|
23
+ | `needs_input` | Step requires data not yet available | Batch stops, LLM generates response to collect data |
24
+ | `end_route` | Reached END_ROUTE marker | Route is complete, no more steps to execute |
25
+ | `route_complete` | All steps in route processed | Route finished successfully |
26
+ | `prepare_error` | Error in prepare hook | Batch stops, error returned with last successful state |
27
+ | `llm_error` | Error during LLM call | Batch stops, session state preserved |
28
+ | `validation_error` | Data validation failed | Batch continues, errors included in response |
29
+ | `finalize_error` | Error in finalize hook | Non-fatal, logged and execution continues |
30
+
31
+ ### Needs-Input Stopping
32
+
33
+ The most common stopping condition. A step needs input when:
34
+
35
+ ```typescript
36
+ // Step needs input if requires fields are missing
37
+ const step1 = {
38
+ prompt: "Confirm your booking",
39
+ requires: ["hotel", "date"], // Both must be present
40
+ };
41
+
42
+ // Step needs input if collecting and no collect fields have data
43
+ const step2 = {
44
+ prompt: "What's your preference?",
45
+ collect: ["preference", "notes"], // Needs input if BOTH are missing
46
+ };
47
+ ```
48
+
49
+ ### End-Route Stopping
50
+
51
+ Batch stops when reaching the END_ROUTE marker:
52
+
53
+ ```typescript
54
+ const finalStep = confirmStep.nextStep({
55
+ prompt: "Booking confirmed! Anything else?",
56
+ }).endRoute(); // Creates END_ROUTE transition
57
+
58
+ // Response will have:
59
+ // stoppedReason: "end_route"
60
+ // isRouteComplete: true
61
+ ```
62
+
63
+ ### Route-Complete Stopping
64
+
65
+ When all steps have been processed without hitting END_ROUTE:
66
+
67
+ ```typescript
68
+ // If the last step has no transitions and doesn't need input
69
+ const response = await agent.respond("Complete my booking");
70
+
71
+ // Response will have:
72
+ // stoppedReason: "route_complete"
73
+ // isRouteComplete: true
74
+ ```
75
+
76
+ ### Transitions Within Batched Execution
77
+
78
+ During batch execution, transitions work as follows:
79
+
80
+ 1. **Linear transitions** - Steps connected via `nextStep()` are evaluated sequentially
81
+ 2. **SkipIf evaluation** - Each step's `skipIf` is checked before inclusion
82
+ 3. **Needs-input check** - If a step needs input, batch stops there
83
+ 4. **END_ROUTE detection** - Batch stops when reaching route end
84
+
85
+ ```typescript
86
+ // Example: Steps A → B → C → END_ROUTE
87
+ // If user provides data for A and B but not C:
88
+
89
+ const response = await agent.respond("Data for A and B");
90
+
91
+ // Batch includes: [A, B]
92
+ // Stops at: C (needs_input)
93
+ // Next call will continue from C
94
+ ```
95
+
96
+ ### Error Stopping Conditions
97
+
98
+ Errors during batch execution have different behaviors:
99
+
100
+ ```typescript
101
+ // Prepare hook error - stops immediately
102
+ const stepWithPrepare = {
103
+ prompt: "Processing...",
104
+ prepare: async (context, data) => {
105
+ if (!data.valid) throw new Error("Invalid data");
106
+ },
107
+ };
108
+ // stoppedReason: "prepare_error"
109
+ // Session state: last successful state preserved
110
+
111
+ // LLM error - stops with preserved state
112
+ // stoppedReason: "llm_error"
113
+ // Session state: preserved from before LLM call
114
+
115
+ // Validation error - continues but reports error
116
+ // stoppedReason: "validation_error"
117
+ // Collected data: partial data preserved
118
+
119
+ // Finalize hook error - logged, continues
120
+ // stoppedReason: original reason (not changed)
121
+ // Error: included in response for logging
122
+ ```
123
+
124
+ ### Checking Stop Reason in Response
125
+
126
+ ```typescript
127
+ const response = await agent.respond("Book a hotel");
128
+
129
+ switch (response.stoppedReason) {
130
+ case 'needs_input':
131
+ console.log("Waiting for user input");
132
+ break;
133
+ case 'end_route':
134
+ case 'route_complete':
135
+ console.log("Route finished:", response.isRouteComplete);
136
+ break;
137
+ case 'prepare_error':
138
+ case 'llm_error':
139
+ console.error("Error occurred:", response.error);
140
+ break;
141
+ case 'validation_error':
142
+ console.warn("Validation issues:", response.error);
143
+ break;
144
+ }
145
+ ```
146
+
15
147
  ## Conditional Skipping
16
148
 
17
149
  ### SkipIf Logic
@@ -145,6 +145,115 @@ const dataStep = previousStep.nextStep({
145
145
  });
146
146
  ```
147
147
 
148
+ ## Multi-Step Batch Execution
149
+
150
+ Steps can execute together in a single LLM call when their data requirements are already satisfied. This reduces unnecessary back-and-forth and minimizes LLM costs.
151
+
152
+ ### How Steps Are Batched
153
+
154
+ The execution engine walks through Steps sequentially and includes them in a batch until encountering a Step that needs user input:
155
+
156
+ ```typescript
157
+ // Route with 3 steps
158
+ const route = agent.createRoute({
159
+ title: "Booking",
160
+ requiredFields: ["hotel", "date", "guests"],
161
+ initialStep: {
162
+ prompt: "Which hotel?",
163
+ collect: ["hotel"],
164
+ skipIf: (data) => !!data.hotel,
165
+ },
166
+ });
167
+
168
+ const askDate = route.initialStep.nextStep({
169
+ prompt: "What date?",
170
+ collect: ["date"],
171
+ skipIf: (data) => !!data.date,
172
+ });
173
+
174
+ const askGuests = askDate.nextStep({
175
+ prompt: "How many guests?",
176
+ collect: ["guests"],
177
+ skipIf: (data) => data.guests !== undefined,
178
+ });
179
+ ```
180
+
181
+ When a user says "Book Grand Hotel for 2 people on Friday":
182
+ 1. Pre-extraction captures: `{ hotel: "Grand Hotel", date: "Friday", guests: 2 }`
183
+ 2. All steps have their data satisfied (skipIf evaluates to true)
184
+ 3. Route completes in a single LLM call
185
+
186
+ ### The `requires` Field in Batch Context
187
+
188
+ The `requires` field specifies data prerequisites that must be present before a Step can execute:
189
+
190
+ ```typescript
191
+ const confirmStep = askGuests.nextStep({
192
+ prompt: "Confirm booking for {{guests}} guests at {{hotel}} on {{date}}?",
193
+ requires: ["hotel", "date", "guests"], // All must be present
194
+ collect: ["confirmed"],
195
+ });
196
+ ```
197
+
198
+ **Batch behavior:**
199
+ - If any `requires` field is missing from session data (after pre-extraction), the Step **needs input**
200
+ - The batch stops at this Step, and the LLM generates a response to collect the missing data
201
+
202
+ ### The `collect` Field in Batch Context
203
+
204
+ The `collect` field specifies which data fields the Step should extract from the conversation:
205
+
206
+ ```typescript
207
+ const contactStep = {
208
+ prompt: "What's your email and phone?",
209
+ collect: ["email", "phone"], // Extract both from response
210
+ };
211
+ ```
212
+
213
+ **Batch behavior:**
214
+ - If a Step has `collect` fields and **none** of those fields have data in the session, the Step **needs input**
215
+ - If **any** collect field already has data, the Step doesn't need input and can be included in the batch
216
+
217
+ ### SkipIf Evaluation During Batch Determination
218
+
219
+ The `skipIf` condition is evaluated for each Step during batch determination:
220
+
221
+ ```typescript
222
+ const premiumStep = {
223
+ prompt: "Would you like premium features?",
224
+ collect: ["wantsPremium"],
225
+ skipIf: (data) => data.userTier === "free", // Skip for free users
226
+ };
227
+ ```
228
+
229
+ **Evaluation rules:**
230
+ 1. If `skipIf` evaluates to `true` → Step is skipped, continue to next Step
231
+ 2. If `skipIf` evaluates to `false` → Step is evaluated for needs-input
232
+ 3. If `skipIf` throws an error → Step is treated as non-skippable (safer to execute than skip)
233
+
234
+ ### Batch Execution Example
235
+
236
+ ```typescript
237
+ // User provides partial info
238
+ const response1 = await agent.respond("I want to book the Grand Hotel");
239
+
240
+ // Response shows which steps executed
241
+ console.log(response1.executedSteps);
242
+ // [{ id: "ask-hotel", routeId: "booking" }]
243
+
244
+ console.log(response1.stoppedReason);
245
+ // "needs_input" - stopped at ask-date step
246
+
247
+ // User provides remaining info
248
+ const response2 = await agent.respond("2 people on Friday");
249
+
250
+ console.log(response2.executedSteps);
251
+ // [{ id: "ask-date", routeId: "booking" }, { id: "ask-guests", routeId: "booking" }]
252
+
253
+ console.log(response2.stoppedReason);
254
+ // "route_complete"
255
+ ```
256
+
148
257
  ## Best Practices
149
258
 
150
259
  - Keep step prompts clear and focused
@@ -152,3 +261,6 @@ const dataStep = previousStep.nextStep({
152
261
  - Leverage schema validation for data integrity
153
262
  - Implement error handling in lifecycle hooks
154
263
  - Consider user experience in step sequencing
264
+ - Design steps to maximize batching by using `skipIf` conditions
265
+ - Use `requires` to enforce data dependencies between steps
266
+ - Keep `collect` fields focused on what each step actually needs
@@ -11,6 +11,199 @@ The framework handles errors across multiple layers:
11
11
  - **Session Data Synchronization** - Consistent error handling for agent-session data operations
12
12
  - **Tool Execution Errors** - Graceful handling of tool failures
13
13
  - **Validation Errors** - Schema and data validation error recovery
14
+ - **Batch Execution Errors** - Error handling during multi-step batch execution
15
+
16
+ ## Batch Execution Error Handling
17
+
18
+ When executing multiple steps in a batch, errors are handled according to their category and severity.
19
+
20
+ ### Error Categories
21
+
22
+ | Error Type | Severity | Behavior |
23
+ |------------|----------|----------|
24
+ | `pre_extraction` | Warning | Log warning, continue with empty extraction |
25
+ | `skipif_evaluation` | Warning | Treat step as non-skippable, include in batch |
26
+ | `prepare_hook` | Fatal | Stop batch execution, return error response |
27
+ | `llm_call` | Fatal | Stop batch, preserve last successful session state |
28
+ | `data_validation` | Non-fatal | Include errors in response, preserve partial data |
29
+ | `finalize_hook` | Non-fatal | Log error, continue with remaining hooks |
30
+
31
+ ### Pre-Extraction Errors
32
+
33
+ Failures during data extraction from user message:
34
+
35
+ ```typescript
36
+ // Pre-extraction is an optimization; failure shouldn't block execution
37
+ try {
38
+ const preExtracted = await preExtractData(message, route);
39
+ session = mergeCollected(session, preExtracted);
40
+ } catch (error) {
41
+ // Log warning but continue
42
+ console.warn("Pre-extraction failed:", error.message);
43
+ // Continue with empty extraction result
44
+ }
45
+ ```
46
+
47
+ ### SkipIf Evaluation Errors
48
+
49
+ Exceptions thrown by skipIf conditions:
50
+
51
+ ```typescript
52
+ // Safer to execute than skip when condition is indeterminate
53
+ let shouldSkip = false;
54
+ try {
55
+ shouldSkip = await step.evaluateSkipIf(context);
56
+ } catch (error) {
57
+ console.warn(`skipIf error for step ${step.id}, treating as non-skippable`);
58
+ shouldSkip = false; // Include step in batch
59
+ }
60
+ ```
61
+
62
+ ### Prepare Hook Errors
63
+
64
+ Failures in step prepare hooks stop batch execution:
65
+
66
+ ```typescript
67
+ const response = await agent.respond("Process my request");
68
+
69
+ if (response.stoppedReason === 'prepare_error') {
70
+ console.error("Prepare hook failed:", response.error);
71
+ // {
72
+ // type: 'prepare_hook',
73
+ // message: 'Validation failed in prepare hook',
74
+ // stepId: 'validate-step',
75
+ // details: { ... }
76
+ // }
77
+
78
+ // Session state is preserved from before the failed hook
79
+ console.log(response.session); // Last successful state
80
+ }
81
+ ```
82
+
83
+ ### LLM Call Errors
84
+
85
+ Provider failures, timeouts, and rate limits:
86
+
87
+ ```typescript
88
+ const response = await agent.respond("Generate response");
89
+
90
+ if (response.stoppedReason === 'llm_error') {
91
+ console.error("LLM call failed:", response.error);
92
+ // {
93
+ // type: 'llm_call',
94
+ // message: 'Rate limit exceeded',
95
+ // details: { ... }
96
+ // }
97
+
98
+ // Session preserved from before LLM call
99
+ // Can retry with same session
100
+ }
101
+ ```
102
+
103
+ ### Data Validation Errors
104
+
105
+ Schema validation failures for collected data:
106
+
107
+ ```typescript
108
+ const response = await agent.respond("Book for 100 guests");
109
+
110
+ if (response.stoppedReason === 'validation_error') {
111
+ console.warn("Validation failed:", response.error);
112
+ // {
113
+ // type: 'data_validation',
114
+ // message: 'Validation failed for 1 field(s): guests',
115
+ // details: [
116
+ // { field: 'guests', value: 100, message: 'Exceeds maximum of 10' }
117
+ // ]
118
+ // }
119
+
120
+ // Valid partial data is still preserved
121
+ console.log(response.session.data); // Contains valid fields
122
+ }
123
+ ```
124
+
125
+ ### Finalize Hook Errors
126
+
127
+ Failures in finalize hooks are logged but don't stop execution:
128
+
129
+ ```typescript
130
+ // Finalize hooks are for cleanup; one failure shouldn't block others
131
+ const response = await agent.respond("Complete booking");
132
+
133
+ // Even if finalize hooks fail, response is returned
134
+ // Errors are logged and included in response.error if present
135
+ if (response.error?.type === 'finalize_hook') {
136
+ console.warn("Some finalize hooks failed:", response.error.details);
137
+ }
138
+ ```
139
+
140
+ ### Partial Progress Preservation
141
+
142
+ Errors preserve partial progress:
143
+
144
+ ```typescript
145
+ // Batch: [step1, step2, step3]
146
+ // step2's prepare hook fails
147
+
148
+ const response = await agent.respond("Process all steps");
149
+
150
+ // step1 completed successfully
151
+ // step2 failed during prepare
152
+ // step3 never executed
153
+
154
+ console.log(response.executedSteps);
155
+ // [{ id: "step1", routeId: "route" }]
156
+
157
+ console.log(response.stoppedReason);
158
+ // "prepare_error"
159
+
160
+ // Session contains data from step1
161
+ console.log(response.session.data);
162
+ ```
163
+
164
+ ### Error Response Structure
165
+
166
+ ```typescript
167
+ interface BatchExecutionError {
168
+ /** Type of error that occurred */
169
+ type: 'pre_extraction' | 'skipif_evaluation' | 'prepare_hook' |
170
+ 'llm_call' | 'data_validation' | 'finalize_hook';
171
+ /** Error message */
172
+ message: string;
173
+ /** Step where error occurred (if applicable) */
174
+ stepId?: string;
175
+ /** Additional error details */
176
+ details?: unknown;
177
+ }
178
+ ```
179
+
180
+ ### Handling Batch Errors
181
+
182
+ ```typescript
183
+ const response = await agent.respond(message);
184
+
185
+ // Check for errors
186
+ if (response.error) {
187
+ switch (response.error.type) {
188
+ case 'prepare_hook':
189
+ // Fatal - batch stopped
190
+ await handlePrepareError(response.error);
191
+ break;
192
+ case 'llm_call':
193
+ // Fatal - can retry
194
+ await retryWithBackoff(() => agent.respond(message));
195
+ break;
196
+ case 'data_validation':
197
+ // Non-fatal - ask user to correct
198
+ await promptForCorrection(response.error.details);
199
+ break;
200
+ case 'finalize_hook':
201
+ // Non-fatal - log and continue
202
+ console.warn("Finalize error:", response.error);
203
+ break;
204
+ }
205
+ }
206
+ ```
14
207
 
15
208
  ## Streaming Error Propagation
16
209
 
@@ -13,6 +13,7 @@ By the end of this guide, you'll have a working AI agent that can:
13
13
  - ✅ Maintain context across multiple turns
14
14
  - ✅ Use tools to perform actions
15
15
  - ✅ Handle complex conversation flows
16
+ - ✅ Execute multiple steps in a single LLM call (multi-step execution)
16
17
 
17
18
  **Time estimate:** 15-30 minutes
18
19
 
@@ -389,6 +390,107 @@ demonstrateLifecycleHooks();
389
390
  - ✅ Understood "Next Friday, 2 people, $2000 budget" as structured data
390
391
  - ✅ Skipped asking for already-known information
391
392
  - ✅ Used the ToolManager API to create and execute tools with simplified context
393
+ - ✅ Batched multiple steps together when data was available
394
+
395
+ ---
396
+
397
+ ## ⚡ Multi-Step Execution Benefits
398
+
399
+ @falai/agent automatically batches multiple steps together when their data requirements are satisfied, reducing LLM calls and improving conversation flow.
400
+
401
+ ### How It Works
402
+
403
+ When a user provides information that satisfies multiple steps, they execute together:
404
+
405
+ ```typescript
406
+ // Traditional approach: 3 separate turns
407
+ // Turn 1: "Which hotel?" → "Grand Hotel"
408
+ // Turn 2: "What date?" → "Friday"
409
+ // Turn 3: "How many guests?" → "2"
410
+
411
+ // With multi-step execution: 1 turn
412
+ const response = await agent.respond("Book Grand Hotel for 2 on Friday");
413
+
414
+ // All 3 steps execute in a single LLM call!
415
+ console.log(response.executedSteps);
416
+ // [
417
+ // { id: "ask-hotel", routeId: "booking" },
418
+ // { id: "ask-date", routeId: "booking" },
419
+ // { id: "ask-guests", routeId: "booking" }
420
+ // ]
421
+
422
+ console.log(response.stoppedReason);
423
+ // "route_complete"
424
+ ```
425
+
426
+ ### Benefits
427
+
428
+ 1. **Fewer LLM Calls** - Multiple steps in one call reduces costs
429
+ 2. **Better UX** - Users don't repeat information they've already provided
430
+ 3. **Faster Responses** - Less back-and-forth means quicker completion
431
+ 4. **Automatic** - No code changes needed, works with existing routes
432
+
433
+ ### Seeing It In Action
434
+
435
+ ```typescript
436
+ // Create a booking route with multiple steps
437
+ const bookingRoute = agent.createRoute({
438
+ title: "Hotel Booking",
439
+ requiredFields: ["hotel", "date", "guests"],
440
+ initialStep: {
441
+ prompt: "Which hotel?",
442
+ collect: ["hotel"],
443
+ skipIf: (data) => !!data.hotel,
444
+ },
445
+ });
446
+
447
+ const askDate = bookingRoute.initialStep.nextStep({
448
+ prompt: "What date?",
449
+ collect: ["date"],
450
+ skipIf: (data) => !!data.date,
451
+ });
452
+
453
+ const askGuests = askDate.nextStep({
454
+ prompt: "How many guests?",
455
+ collect: ["guests"],
456
+ skipIf: (data) => data.guests !== undefined,
457
+ });
458
+
459
+ // User provides all info at once
460
+ const response = await agent.respond(
461
+ "I want to book the Grand Hotel for 2 people next Friday"
462
+ );
463
+
464
+ // Pre-extraction captures all data
465
+ // All steps execute in one batch
466
+ // Route completes immediately!
467
+
468
+ console.log(response.message);
469
+ // "Perfect! I've booked the Grand Hotel for 2 guests on Friday."
470
+
471
+ console.log(response.isRouteComplete);
472
+ // true
473
+ ```
474
+
475
+ ### Understanding the Response
476
+
477
+ The response includes information about what executed:
478
+
479
+ ```typescript
480
+ const response = await agent.respond("Book for 2 guests");
481
+
482
+ // Which steps ran
483
+ console.log(response.executedSteps);
484
+ // [{ id: "ask-guests", routeId: "booking" }]
485
+
486
+ // Why execution stopped
487
+ console.log(response.stoppedReason);
488
+ // "needs_input" - waiting for hotel and date
489
+
490
+ // Or if complete:
491
+ // "route_complete" - all steps finished
492
+ // "end_route" - reached END_ROUTE marker
493
+ ```
392
494
 
393
495
  ---
394
496
 
@@ -4,6 +4,29 @@ This directory contains migration guides for major changes and updates to the `@
4
4
 
5
5
  ## Available Migration Guides
6
6
 
7
+ ### [Multi-Step Execution Migration Guide](./multi-step-execution.md)
8
+
9
+ **Latest Update** - Guide for understanding and migrating to multi-step batch execution.
10
+
11
+ **What's New:**
12
+ - 🚀 **Multi-Step Batching**: Multiple steps execute in a single LLM call
13
+ - ⚡ **Reduced LLM Costs**: Fewer calls for the same outcome
14
+ - 🎯 **Better UX**: Less back-and-forth in conversations
15
+ - 📊 **New Response Fields**: `executedSteps`, `stoppedReason`, `error`
16
+
17
+ **Key Changes:**
18
+ - Steps batch together when data requirements are satisfied
19
+ - Pre-extraction happens before batch determination
20
+ - Hook execution order: all prepare → LLM → all finalize
21
+ - SkipIf conditions affect batch determination
22
+
23
+ **Migration Status:**
24
+ - ✅ **API Compatible**: Public API shape unchanged
25
+ - ⚠️ **Behavioral Change**: Execution semantics differ
26
+ - ✅ **Gradual Migration**: Review hooks and tests
27
+
28
+ ---
29
+
7
30
  ### [ResponseModal Refactor Migration Guide](./response-modal-refactor.md)
8
31
 
9
32
  **Latest Update** - Comprehensive guide for migrating to the new ResponseModal architecture.