@falai/agent 0.6.9 → 0.7.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.
- package/README.md +62 -59
- package/dist/adapters/MemoryAdapter.js +2 -2
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.js +2 -2
- package/dist/adapters/MongoAdapter.js.map +1 -1
- package/dist/adapters/OpenSearchAdapter.js +7 -7
- package/dist/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +9 -9
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.js +3 -3
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.js +2 -2
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts +3 -3
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +11 -11
- package/dist/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +2 -2
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +2 -2
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -1
- package/dist/cjs/adapters/OpenSearchAdapter.js +7 -7
- package/dist/cjs/adapters/OpenSearchAdapter.js.map +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +9 -9
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +3 -3
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +2 -2
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +3 -3
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +11 -11
- package/dist/cjs/adapters/SQLiteAdapter.js.map +1 -1
- package/dist/cjs/adapters/index.d.ts +1 -1
- package/dist/cjs/adapters/index.d.ts.map +1 -1
- package/dist/cjs/constants/index.d.ts +4 -4
- package/dist/cjs/constants/index.js +5 -5
- package/dist/cjs/core/Agent.d.ts +22 -22
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +160 -152
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +6 -6
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +13 -13
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +24 -24
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/ResponseEngine.d.ts +3 -8
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/core/ResponseEngine.js +8 -8
- package/dist/cjs/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/core/Route.d.ts +17 -17
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +33 -33
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +30 -30
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +192 -192
- package/dist/cjs/core/RoutingEngine.js.map +1 -1
- package/dist/cjs/core/Step.d.ts +72 -0
- package/dist/cjs/core/Step.d.ts.map +1 -0
- package/dist/cjs/core/Step.js +150 -0
- package/dist/cjs/core/Step.js.map +1 -0
- package/dist/cjs/core/ToolExecutor.d.ts +5 -5
- package/dist/cjs/core/ToolExecutor.d.ts.map +1 -1
- package/dist/cjs/core/ToolExecutor.js +8 -8
- package/dist/cjs/core/ToolExecutor.js.map +1 -1
- package/dist/cjs/core/Transition.d.ts +14 -14
- package/dist/cjs/core/Transition.d.ts.map +1 -1
- package/dist/cjs/core/Transition.js +48 -19
- package/dist/cjs/core/Transition.js.map +1 -1
- package/dist/cjs/index.d.ts +7 -7
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +8 -8
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +2 -2
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +3 -3
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +1 -1
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/persistence.d.ts +5 -5
- package/dist/cjs/types/persistence.d.ts.map +1 -1
- package/dist/cjs/types/route.d.ts +57 -52
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +27 -27
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/types/session.js +48 -50
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/cjs/types/tool.d.ts +13 -13
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/utils/id.d.ts +8 -3
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +16 -7
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/constants/index.d.ts +4 -4
- package/dist/constants/index.js +4 -4
- package/dist/core/Agent.d.ts +22 -22
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +162 -154
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/Events.d.ts +6 -6
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/PersistenceManager.d.ts +13 -13
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +25 -25
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/ResponseEngine.d.ts +3 -8
- package/dist/core/ResponseEngine.d.ts.map +1 -1
- package/dist/core/ResponseEngine.js +8 -8
- package/dist/core/ResponseEngine.js.map +1 -1
- package/dist/core/Route.d.ts +17 -17
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +33 -33
- package/dist/core/Route.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +30 -30
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +193 -193
- package/dist/core/RoutingEngine.js.map +1 -1
- package/dist/core/Step.d.ts +72 -0
- package/dist/core/Step.d.ts.map +1 -0
- package/dist/core/Step.js +146 -0
- package/dist/core/Step.js.map +1 -0
- package/dist/core/ToolExecutor.d.ts +5 -5
- package/dist/core/ToolExecutor.d.ts.map +1 -1
- package/dist/core/ToolExecutor.js +8 -8
- package/dist/core/ToolExecutor.js.map +1 -1
- package/dist/core/Transition.d.ts +14 -14
- package/dist/core/Transition.d.ts.map +1 -1
- package/dist/core/Transition.js +48 -19
- package/dist/core/Transition.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/types/agent.d.ts +8 -8
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +2 -2
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/history.d.ts +3 -3
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/persistence.d.ts +5 -5
- package/dist/types/persistence.d.ts.map +1 -1
- package/dist/types/route.d.ts +57 -52
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/session.d.ts +27 -27
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +44 -46
- package/dist/types/session.js.map +1 -1
- package/dist/types/tool.d.ts +13 -13
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/id.d.ts +8 -3
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +14 -6
- package/dist/utils/id.js.map +1 -1
- package/docs/ADAPTERS.md +21 -21
- package/docs/AGENT.md +57 -55
- package/docs/API_REFERENCE.md +218 -220
- package/docs/ARCHITECTURE.md +99 -104
- package/docs/CONTEXT_MANAGEMENT.md +81 -88
- package/docs/DOCS.md +18 -18
- package/docs/DOMAINS.md +16 -16
- package/docs/EXAMPLES.md +43 -43
- package/docs/GETTING_STARTED.md +60 -63
- package/docs/PERSISTENCE.md +66 -70
- package/docs/PROVIDERS.md +2 -2
- package/docs/README.md +6 -6
- package/docs/ROUTES.md +218 -220
- package/docs/STEPS.md +883 -0
- package/examples/business-onboarding.ts +84 -81
- package/examples/company-qna-agent.ts +68 -67
- package/examples/custom-database-persistence.ts +87 -89
- package/examples/declarative-agent.ts +32 -32
- package/examples/domain-scoping.ts +18 -18
- package/examples/extracted-data-modification.ts +92 -97
- package/examples/healthcare-agent.ts +89 -91
- package/examples/openai-agent.ts +29 -32
- package/examples/opensearch-persistence.ts +43 -45
- package/examples/persistent-onboarding.ts +65 -66
- package/examples/prisma-persistence.ts +108 -112
- package/examples/prisma-schema.example.prisma +3 -3
- package/examples/redis-persistence.ts +67 -73
- package/examples/route-transitions.ts +71 -47
- package/examples/rules-prohibitions.ts +28 -28
- package/examples/streaming-agent.ts +24 -24
- package/examples/travel-agent.ts +94 -109
- package/package.json +1 -1
- package/src/adapters/MemoryAdapter.ts +3 -3
- package/src/adapters/MongoAdapter.ts +3 -3
- package/src/adapters/OpenSearchAdapter.ts +8 -8
- package/src/adapters/PostgreSQLAdapter.ts +10 -10
- package/src/adapters/PrismaAdapter.ts +4 -4
- package/src/adapters/RedisAdapter.ts +3 -3
- package/src/adapters/SQLiteAdapter.ts +15 -15
- package/src/adapters/index.ts +1 -1
- package/src/constants/index.ts +4 -4
- package/src/core/Agent.ts +210 -206
- package/src/core/Events.ts +12 -12
- package/src/core/PersistenceManager.ts +32 -36
- package/src/core/ResponseEngine.ts +11 -17
- package/src/core/Route.ts +55 -49
- package/src/core/RoutingEngine.ts +244 -252
- package/src/core/Step.ts +197 -0
- package/src/core/ToolExecutor.ts +11 -11
- package/src/core/Transition.ts +72 -26
- package/src/index.ts +8 -8
- package/src/types/agent.ts +8 -8
- package/src/types/ai.ts +2 -2
- package/src/types/history.ts +3 -3
- package/src/types/index.ts +1 -1
- package/src/types/persistence.ts +6 -6
- package/src/types/route.ts +77 -61
- package/src/types/session.ts +75 -78
- package/src/types/tool.ts +17 -17
- package/src/utils/id.ts +15 -6
- package/dist/cjs/core/State.d.ts +0 -72
- package/dist/cjs/core/State.d.ts.map +0 -1
- package/dist/cjs/core/State.js +0 -148
- package/dist/cjs/core/State.js.map +0 -1
- package/dist/core/State.d.ts +0 -72
- package/dist/core/State.d.ts.map +0 -1
- package/dist/core/State.js +0 -144
- package/dist/core/State.js.map +0 -1
- package/docs/STATES.md +0 -888
- package/src/core/State.ts +0 -212
package/dist/cjs/core/Agent.js
CHANGED
|
@@ -8,7 +8,7 @@ const session_1 = require("../types/session");
|
|
|
8
8
|
const PromptComposer_1 = require("./PromptComposer");
|
|
9
9
|
const logger_1 = require("../utils/logger");
|
|
10
10
|
const Route_1 = require("./Route");
|
|
11
|
-
const
|
|
11
|
+
const Step_1 = require("./Step");
|
|
12
12
|
const DomainRegistry_1 = require("./DomainRegistry");
|
|
13
13
|
const PersistenceManager_1 = require("./PersistenceManager");
|
|
14
14
|
const RoutingEngine_1 = require("./RoutingEngine");
|
|
@@ -101,7 +101,7 @@ class Agent {
|
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
103
|
* Create a new route (journey)
|
|
104
|
-
* @template
|
|
104
|
+
* @template TData - Type of data collected throughout the route
|
|
105
105
|
*/
|
|
106
106
|
createRoute(options) {
|
|
107
107
|
const route = new Route_1.Route(options);
|
|
@@ -178,23 +178,23 @@ class Agent {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
/**
|
|
181
|
-
* Update
|
|
182
|
-
* Triggers the
|
|
181
|
+
* Update collected data in session with lifecycle hook support
|
|
182
|
+
* Triggers the onDataUpdate lifecycle hook if configured
|
|
183
183
|
* @internal
|
|
184
184
|
*/
|
|
185
|
-
async
|
|
186
|
-
const
|
|
187
|
-
// Merge new
|
|
188
|
-
let
|
|
189
|
-
...session.
|
|
190
|
-
...
|
|
185
|
+
async updateData(session, collectedUpdate) {
|
|
186
|
+
const previousCollected = { ...session.data };
|
|
187
|
+
// Merge new collected data
|
|
188
|
+
let newCollected = {
|
|
189
|
+
...session.data,
|
|
190
|
+
...collectedUpdate,
|
|
191
191
|
};
|
|
192
192
|
// Trigger lifecycle hook if configured
|
|
193
|
-
if (this.options.hooks?.
|
|
194
|
-
|
|
193
|
+
if (this.options.hooks?.onDataUpdate) {
|
|
194
|
+
newCollected = (await this.options.hooks.onDataUpdate(newCollected, previousCollected));
|
|
195
195
|
}
|
|
196
196
|
// Return updated session
|
|
197
|
-
return (0, session_1.
|
|
197
|
+
return (0, session_1.mergeCollected)(session, newCollected);
|
|
198
198
|
}
|
|
199
199
|
/**
|
|
200
200
|
* Get current context (fetches from provider if configured)
|
|
@@ -228,37 +228,37 @@ class Agent {
|
|
|
228
228
|
};
|
|
229
229
|
// Initialize or get session (use current session if available)
|
|
230
230
|
let session = params.session || this.currentSession || (0, session_1.createSession)();
|
|
231
|
-
// PHASE 1: TOOL EXECUTION - Execute tools if current
|
|
232
|
-
if (session.currentRoute && session.
|
|
231
|
+
// PHASE 1: TOOL EXECUTION - Execute tools if current step has tool
|
|
232
|
+
if (session.currentRoute && session.currentStep) {
|
|
233
233
|
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
234
234
|
if (currentRoute) {
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
237
|
-
const transitions =
|
|
238
|
-
const toolTransition = transitions.find((t) => t.spec.
|
|
239
|
-
if (toolTransition?.spec.
|
|
235
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
236
|
+
if (currentStep) {
|
|
237
|
+
const transitions = currentStep.getTransitions();
|
|
238
|
+
const toolTransition = transitions.find((t) => t.spec.tool);
|
|
239
|
+
if (toolTransition?.spec.tool) {
|
|
240
240
|
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
241
241
|
// Get allowed domains from current route for security enforcement
|
|
242
242
|
const allowedDomains = currentRoute.getDomains();
|
|
243
|
-
const result = await toolExecutor.executeTool(toolTransition.spec.
|
|
243
|
+
const result = await toolExecutor.executeTool(toolTransition.spec.tool, effectiveContext, this.updateContext.bind(this), history, session.data, allowedDomains);
|
|
244
244
|
// Update context with tool results
|
|
245
245
|
if (result.contextUpdate) {
|
|
246
246
|
await this.updateContext(result.contextUpdate);
|
|
247
247
|
}
|
|
248
|
-
// Update
|
|
249
|
-
if (result.
|
|
250
|
-
session = await this.
|
|
251
|
-
logger_1.logger.debug(`[Agent] Tool updated
|
|
248
|
+
// Update collected data with tool results
|
|
249
|
+
if (result.collectedUpdate) {
|
|
250
|
+
session = await this.updateData(session, result.collectedUpdate);
|
|
251
|
+
logger_1.logger.debug(`[Agent] Tool updated collected data:`, result.collectedUpdate);
|
|
252
252
|
}
|
|
253
253
|
logger_1.logger.debug(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
// PHASE 2: ROUTING +
|
|
258
|
+
// PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
|
|
259
259
|
let selectedRoute;
|
|
260
260
|
let responseDirectives;
|
|
261
|
-
let
|
|
261
|
+
let selectedStep;
|
|
262
262
|
let isRouteComplete = false;
|
|
263
263
|
// Check for pending transition from previous route completion
|
|
264
264
|
if (session.pendingTransition) {
|
|
@@ -273,7 +273,7 @@ class Agent {
|
|
|
273
273
|
session = (0, session_1.enterRoute)(session, targetRoute.id, targetRoute.title);
|
|
274
274
|
// Merge initial data if available
|
|
275
275
|
if (targetRoute.initialData) {
|
|
276
|
-
session = (0, session_1.
|
|
276
|
+
session = (0, session_1.mergeCollected)(session, targetRoute.initialData);
|
|
277
277
|
}
|
|
278
278
|
selectedRoute = targetRoute;
|
|
279
279
|
}
|
|
@@ -288,7 +288,7 @@ class Agent {
|
|
|
288
288
|
}
|
|
289
289
|
// If no pending transition or transition handled, do normal routing
|
|
290
290
|
if (this.routes.length > 0 && !selectedRoute) {
|
|
291
|
-
const orchestration = await this.routingEngine.
|
|
291
|
+
const orchestration = await this.routingEngine.decideRouteAndStep({
|
|
292
292
|
routes: this.routes,
|
|
293
293
|
session,
|
|
294
294
|
history,
|
|
@@ -303,45 +303,45 @@ class Agent {
|
|
|
303
303
|
signal,
|
|
304
304
|
});
|
|
305
305
|
selectedRoute = orchestration.selectedRoute;
|
|
306
|
-
|
|
306
|
+
selectedStep = orchestration.selectedStep;
|
|
307
307
|
responseDirectives = orchestration.responseDirectives;
|
|
308
308
|
session = orchestration.session;
|
|
309
309
|
isRouteComplete = orchestration.isRouteComplete || false;
|
|
310
310
|
// Log if route is complete
|
|
311
311
|
if (isRouteComplete) {
|
|
312
|
-
logger_1.logger.debug(`[Agent] Route complete: all required data collected,
|
|
312
|
+
logger_1.logger.debug(`[Agent] Route complete: all required data collected, END_ROUTE reached`);
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
// PHASE 3: DETERMINE NEXT
|
|
315
|
+
// PHASE 3: DETERMINE NEXT STEP - Use step from combined decision or get initial step
|
|
316
316
|
if (selectedRoute && !isRouteComplete) {
|
|
317
|
-
let
|
|
318
|
-
// If we have a selected
|
|
319
|
-
if (
|
|
320
|
-
|
|
317
|
+
let nextStep;
|
|
318
|
+
// If we have a selected step from the combined routing decision, use it
|
|
319
|
+
if (selectedStep) {
|
|
320
|
+
nextStep = selectedStep;
|
|
321
321
|
}
|
|
322
322
|
else {
|
|
323
|
-
// New route or no
|
|
324
|
-
const candidates = this.routingEngine.
|
|
323
|
+
// New route or no step selected - get initial step or first valid step
|
|
324
|
+
const candidates = this.routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
|
|
325
325
|
if (candidates.length > 0) {
|
|
326
|
-
|
|
327
|
-
logger_1.logger.debug(`[Agent] Using first valid
|
|
326
|
+
nextStep = candidates[0].step;
|
|
327
|
+
logger_1.logger.debug(`[Agent] Using first valid step: ${nextStep.id} for new route`);
|
|
328
328
|
}
|
|
329
329
|
else {
|
|
330
|
-
// Fallback to initial
|
|
331
|
-
|
|
332
|
-
logger_1.logger.warn(`[Agent] No valid
|
|
330
|
+
// Fallback to initial step even if it should be skipped
|
|
331
|
+
nextStep = selectedRoute.initialStep;
|
|
332
|
+
logger_1.logger.warn(`[Agent] No valid steps found, using initial step: ${nextStep.id}`);
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
|
-
// Update session with next
|
|
336
|
-
session = (0, session_1.
|
|
337
|
-
logger_1.logger.debug(`[Agent] Entered
|
|
338
|
-
// PHASE 4: RESPONSE GENERATION - Stream message using selected route and
|
|
335
|
+
// Update session with next step
|
|
336
|
+
session = (0, session_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
337
|
+
logger_1.logger.debug(`[Agent] Entered step: ${nextStep.id}`);
|
|
338
|
+
// PHASE 4: RESPONSE GENERATION - Stream message using selected route and step
|
|
339
339
|
// Get last user message
|
|
340
340
|
const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
|
|
341
|
-
// Build response schema for this route (with
|
|
342
|
-
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute,
|
|
341
|
+
// Build response schema for this route (with collect fields from step)
|
|
342
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
|
|
343
343
|
// Build response prompt
|
|
344
|
-
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute,
|
|
344
|
+
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
|
|
345
345
|
name: this.options.name,
|
|
346
346
|
goal: this.options.goal,
|
|
347
347
|
description: this.options.description,
|
|
@@ -361,20 +361,20 @@ class Agent {
|
|
|
361
361
|
// Stream chunks to caller
|
|
362
362
|
for await (const chunk of stream) {
|
|
363
363
|
const toolCalls = undefined;
|
|
364
|
-
// Extract
|
|
365
|
-
if (chunk.done && chunk.structured &&
|
|
366
|
-
const
|
|
367
|
-
// The structured response includes both base fields and
|
|
364
|
+
// Extract collected data on final chunk
|
|
365
|
+
if (chunk.done && chunk.structured && nextStep.collectFields) {
|
|
366
|
+
const collectedData = {};
|
|
367
|
+
// The structured response includes both base fields and collected extraction fields
|
|
368
368
|
const structuredData = chunk.structured;
|
|
369
|
-
for (const field of
|
|
369
|
+
for (const field of nextStep.collectFields) {
|
|
370
370
|
if (field in structuredData) {
|
|
371
|
-
|
|
371
|
+
collectedData[field] = structuredData[field];
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
|
-
// Merge
|
|
375
|
-
if (Object.keys(
|
|
376
|
-
session = await this.
|
|
377
|
-
logger_1.logger.debug(`[Agent]
|
|
374
|
+
// Merge collected data into session
|
|
375
|
+
if (Object.keys(collectedData).length > 0) {
|
|
376
|
+
session = await this.updateData(session, collectedData);
|
|
377
|
+
logger_1.logger.debug(`[Agent] Collected data:`, collectedData);
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
380
|
// Extract any additional data from structured response on final chunk
|
|
@@ -385,13 +385,13 @@ class Agent {
|
|
|
385
385
|
await this.updateContext(chunk.structured
|
|
386
386
|
.contextUpdate);
|
|
387
387
|
}
|
|
388
|
-
// Auto-save session
|
|
388
|
+
// Auto-save session step on final chunk
|
|
389
389
|
if (chunk.done &&
|
|
390
390
|
this.persistenceManager &&
|
|
391
391
|
session.id &&
|
|
392
392
|
this.options.persistence?.autoSave !== false) {
|
|
393
|
-
await this.persistenceManager.
|
|
394
|
-
logger_1.logger.debug(`[Agent] Auto-saved session
|
|
393
|
+
await this.persistenceManager.saveSessionStep(session.id, session);
|
|
394
|
+
logger_1.logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
|
|
395
395
|
}
|
|
396
396
|
// Update current session if we have one
|
|
397
397
|
if (chunk.done && this.currentSession) {
|
|
@@ -410,14 +410,16 @@ class Agent {
|
|
|
410
410
|
else if (isRouteComplete && selectedRoute) {
|
|
411
411
|
// Route is complete - generate completion message then check for onComplete transition
|
|
412
412
|
const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
|
|
413
|
-
// Get
|
|
414
|
-
const
|
|
415
|
-
// Create a temporary
|
|
416
|
-
const
|
|
413
|
+
// Get endStep spec from route
|
|
414
|
+
const endStepSpec = selectedRoute.endStepSpec;
|
|
415
|
+
// Create a temporary step for completion message generation using endStep configuration
|
|
416
|
+
const completionStep = new Step_1.Step(selectedRoute.id, endStepSpec.instructions ||
|
|
417
|
+
"Summarize what was accomplished and confirm completion", endStepSpec.id || constants_1.END_ROUTE_ID, endStepSpec.collect, undefined, endStepSpec.requires, endStepSpec.instructions ||
|
|
418
|
+
"Summarize what was accomplished and confirm completion based on the conversation history and collected data");
|
|
417
419
|
// Build response schema for completion
|
|
418
|
-
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute,
|
|
420
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
|
|
419
421
|
// Build completion response prompt
|
|
420
|
-
const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute,
|
|
422
|
+
const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
|
|
421
423
|
history, lastUserMessage, {
|
|
422
424
|
name: this.options.name,
|
|
423
425
|
goal: this.options.goal,
|
|
@@ -437,11 +439,11 @@ class Agent {
|
|
|
437
439
|
});
|
|
438
440
|
logger_1.logger.debug(`[Agent] Streaming completion message for route: ${selectedRoute.title}`);
|
|
439
441
|
// Check for onComplete transition
|
|
440
|
-
const transitionConfig = await selectedRoute.evaluateOnComplete({
|
|
442
|
+
const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
|
|
441
443
|
if (transitionConfig) {
|
|
442
444
|
// Find target route by ID or title
|
|
443
|
-
const targetRoute = this.routes.find((r) => r.id === transitionConfig.
|
|
444
|
-
r.title === transitionConfig.
|
|
445
|
+
const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
|
|
446
|
+
r.title === transitionConfig.nextStep);
|
|
445
447
|
if (targetRoute) {
|
|
446
448
|
// Set pending transition in session
|
|
447
449
|
session = {
|
|
@@ -455,12 +457,12 @@ class Agent {
|
|
|
455
457
|
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
|
|
456
458
|
}
|
|
457
459
|
else {
|
|
458
|
-
logger_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.
|
|
460
|
+
logger_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
|
|
459
461
|
}
|
|
460
462
|
}
|
|
461
|
-
// Set
|
|
462
|
-
session = (0, session_1.
|
|
463
|
-
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered
|
|
463
|
+
// Set step to END_ROUTE marker
|
|
464
|
+
session = (0, session_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
465
|
+
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
464
466
|
// Stream completion chunks
|
|
465
467
|
for await (const chunk of stream) {
|
|
466
468
|
// Update current session if we have one
|
|
@@ -544,37 +546,37 @@ class Agent {
|
|
|
544
546
|
};
|
|
545
547
|
// Initialize or get session (use current session if available)
|
|
546
548
|
let session = params.session || this.currentSession || (0, session_1.createSession)();
|
|
547
|
-
// PHASE 1: TOOL EXECUTION - Execute tools if current
|
|
548
|
-
if (session.currentRoute && session.
|
|
549
|
+
// PHASE 1: TOOL EXECUTION - Execute tools if current step has tool
|
|
550
|
+
if (session.currentRoute && session.currentStep) {
|
|
549
551
|
const currentRoute = this.routes.find((r) => r.id === session.currentRoute?.id);
|
|
550
552
|
if (currentRoute) {
|
|
551
|
-
const
|
|
552
|
-
if (
|
|
553
|
-
const transitions =
|
|
554
|
-
const toolTransition = transitions.find((t) => t.spec.
|
|
555
|
-
if (toolTransition?.spec.
|
|
553
|
+
const currentStep = currentRoute.getStep(session.currentStep.id);
|
|
554
|
+
if (currentStep) {
|
|
555
|
+
const transitions = currentStep.getTransitions();
|
|
556
|
+
const toolTransition = transitions.find((t) => t.spec.tool);
|
|
557
|
+
if (toolTransition?.spec.tool) {
|
|
556
558
|
const toolExecutor = new ToolExecutor_1.ToolExecutor();
|
|
557
559
|
// Get allowed domains from current route for security enforcement
|
|
558
560
|
const allowedDomains = currentRoute.getDomains();
|
|
559
|
-
const result = await toolExecutor.executeTool(toolTransition.spec.
|
|
561
|
+
const result = await toolExecutor.executeTool(toolTransition.spec.tool, effectiveContext, this.updateContext.bind(this), history, session.data, allowedDomains);
|
|
560
562
|
// Update context with tool results
|
|
561
563
|
if (result.contextUpdate) {
|
|
562
564
|
await this.updateContext(result.contextUpdate);
|
|
563
565
|
}
|
|
564
|
-
// Update
|
|
565
|
-
if (result.
|
|
566
|
-
session = await this.
|
|
567
|
-
logger_1.logger.debug(`[Agent] Tool updated
|
|
566
|
+
// Update collected data with tool results
|
|
567
|
+
if (result.collectedUpdate) {
|
|
568
|
+
session = await this.updateData(session, result.collectedUpdate);
|
|
569
|
+
logger_1.logger.debug(`[Agent] Tool updated collected data:`, result.collectedUpdate);
|
|
568
570
|
}
|
|
569
571
|
logger_1.logger.debug(`[Agent] Executed tool: ${result.toolName} (success: ${result.success})`);
|
|
570
572
|
}
|
|
571
573
|
}
|
|
572
574
|
}
|
|
573
575
|
}
|
|
574
|
-
// PHASE 2: ROUTING +
|
|
576
|
+
// PHASE 2: ROUTING + STEP SELECTION - Determine which route and step to use (combined)
|
|
575
577
|
let selectedRoute;
|
|
576
578
|
let responseDirectives;
|
|
577
|
-
let
|
|
579
|
+
let selectedStep;
|
|
578
580
|
let isRouteComplete = false;
|
|
579
581
|
// Check for pending transition from previous route completion
|
|
580
582
|
if (session.pendingTransition) {
|
|
@@ -589,7 +591,7 @@ class Agent {
|
|
|
589
591
|
session = (0, session_1.enterRoute)(session, targetRoute.id, targetRoute.title);
|
|
590
592
|
// Merge initial data if available
|
|
591
593
|
if (targetRoute.initialData) {
|
|
592
|
-
session = (0, session_1.
|
|
594
|
+
session = (0, session_1.mergeCollected)(session, targetRoute.initialData);
|
|
593
595
|
}
|
|
594
596
|
selectedRoute = targetRoute;
|
|
595
597
|
}
|
|
@@ -604,7 +606,7 @@ class Agent {
|
|
|
604
606
|
}
|
|
605
607
|
// If no pending transition or transition handled, do normal routing
|
|
606
608
|
if (this.routes.length > 0 && !selectedRoute) {
|
|
607
|
-
const orchestration = await this.routingEngine.
|
|
609
|
+
const orchestration = await this.routingEngine.decideRouteAndStep({
|
|
608
610
|
routes: this.routes,
|
|
609
611
|
session,
|
|
610
612
|
history,
|
|
@@ -619,47 +621,47 @@ class Agent {
|
|
|
619
621
|
signal,
|
|
620
622
|
});
|
|
621
623
|
selectedRoute = orchestration.selectedRoute;
|
|
622
|
-
|
|
624
|
+
selectedStep = orchestration.selectedStep;
|
|
623
625
|
responseDirectives = orchestration.responseDirectives;
|
|
624
626
|
session = orchestration.session;
|
|
625
627
|
isRouteComplete = orchestration.isRouteComplete || false;
|
|
626
628
|
// Log if route is complete
|
|
627
629
|
if (isRouteComplete) {
|
|
628
|
-
logger_1.logger.debug(`[Agent] Route complete: all required data collected,
|
|
630
|
+
logger_1.logger.debug(`[Agent] Route complete: all required data collected, END_ROUTE reached`);
|
|
629
631
|
}
|
|
630
632
|
}
|
|
631
|
-
// PHASE 3: DETERMINE NEXT
|
|
633
|
+
// PHASE 3: DETERMINE NEXT STEP - Use step from combined decision or get initial step
|
|
632
634
|
let message;
|
|
633
635
|
const toolCalls = undefined;
|
|
634
636
|
if (selectedRoute && !isRouteComplete) {
|
|
635
|
-
let
|
|
636
|
-
// If we have a selected
|
|
637
|
-
if (
|
|
638
|
-
|
|
637
|
+
let nextStep;
|
|
638
|
+
// If we have a selected step from the combined routing decision, use it
|
|
639
|
+
if (selectedStep) {
|
|
640
|
+
nextStep = selectedStep;
|
|
639
641
|
}
|
|
640
642
|
else {
|
|
641
|
-
// New route or no
|
|
642
|
-
const candidates = this.routingEngine.
|
|
643
|
+
// New route or no step selected - get initial step or first valid step
|
|
644
|
+
const candidates = this.routingEngine.getCandidateSteps(selectedRoute, undefined, session.data || {});
|
|
643
645
|
if (candidates.length > 0) {
|
|
644
|
-
|
|
645
|
-
logger_1.logger.debug(`[Agent] Using first valid
|
|
646
|
+
nextStep = candidates[0].step;
|
|
647
|
+
logger_1.logger.debug(`[Agent] Using first valid step: ${nextStep.id} for new route`);
|
|
646
648
|
}
|
|
647
649
|
else {
|
|
648
|
-
// Fallback to initial
|
|
649
|
-
|
|
650
|
-
logger_1.logger.warn(`[Agent] No valid
|
|
650
|
+
// Fallback to initial step even if it should be skipped
|
|
651
|
+
nextStep = selectedRoute.initialStep;
|
|
652
|
+
logger_1.logger.warn(`[Agent] No valid steps found, using initial step: ${nextStep.id}`);
|
|
651
653
|
}
|
|
652
654
|
}
|
|
653
|
-
// Update session with next
|
|
654
|
-
session = (0, session_1.
|
|
655
|
-
logger_1.logger.debug(`[Agent] Entered
|
|
656
|
-
// PHASE 4: RESPONSE GENERATION - Generate message using selected route and
|
|
655
|
+
// Update session with next step
|
|
656
|
+
session = (0, session_1.enterStep)(session, nextStep.id, nextStep.description);
|
|
657
|
+
logger_1.logger.debug(`[Agent] Entered step: ${nextStep.id}`);
|
|
658
|
+
// PHASE 4: RESPONSE GENERATION - Generate message using selected route and step
|
|
657
659
|
// Get last user message
|
|
658
660
|
const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
|
|
659
|
-
// Build response schema for this route (with
|
|
660
|
-
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute,
|
|
661
|
+
// Build response schema for this route (with collect fields from step)
|
|
662
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, nextStep);
|
|
661
663
|
// Build response prompt
|
|
662
|
-
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute,
|
|
664
|
+
const responsePrompt = this.responseEngine.buildResponsePrompt(selectedRoute, nextStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), responseDirectives, history, lastUserMessage, {
|
|
663
665
|
name: this.options.name,
|
|
664
666
|
goal: this.options.goal,
|
|
665
667
|
description: this.options.description,
|
|
@@ -677,20 +679,20 @@ class Agent {
|
|
|
677
679
|
},
|
|
678
680
|
});
|
|
679
681
|
message = result.structured?.message || result.message;
|
|
680
|
-
// Extract
|
|
681
|
-
if (result.structured &&
|
|
682
|
-
const
|
|
683
|
-
// The structured response includes both base fields and
|
|
682
|
+
// Extract collected data from response
|
|
683
|
+
if (result.structured && nextStep.collectFields) {
|
|
684
|
+
const collectedData = {};
|
|
685
|
+
// The structured response includes both base fields and collected extraction fields
|
|
684
686
|
const structuredData = result.structured;
|
|
685
|
-
for (const field of
|
|
687
|
+
for (const field of nextStep.collectFields) {
|
|
686
688
|
if (field in structuredData) {
|
|
687
|
-
|
|
689
|
+
collectedData[field] = structuredData[field];
|
|
688
690
|
}
|
|
689
691
|
}
|
|
690
|
-
// Merge
|
|
691
|
-
if (Object.keys(
|
|
692
|
-
session = await this.
|
|
693
|
-
logger_1.logger.debug(`[Agent]
|
|
692
|
+
// Merge collected data into session
|
|
693
|
+
if (Object.keys(collectedData).length > 0) {
|
|
694
|
+
session = await this.updateData(session, collectedData);
|
|
695
|
+
logger_1.logger.debug(`[Agent] Collected data:`, collectedData);
|
|
694
696
|
}
|
|
695
697
|
}
|
|
696
698
|
// Extract any additional data from structured response
|
|
@@ -704,14 +706,16 @@ class Agent {
|
|
|
704
706
|
else if (isRouteComplete && selectedRoute) {
|
|
705
707
|
// Route is complete - generate completion message then check for onComplete transition
|
|
706
708
|
const lastUserMessage = (0, event_1.getLastMessageFromHistory)(history);
|
|
707
|
-
// Get
|
|
708
|
-
const
|
|
709
|
-
// Create a temporary
|
|
710
|
-
const
|
|
709
|
+
// Get endStep spec from route
|
|
710
|
+
const endStepSpec = selectedRoute.endStepSpec;
|
|
711
|
+
// Create a temporary step for completion message generation using endStep configuration
|
|
712
|
+
const completionStep = new Step_1.Step(selectedRoute.id, endStepSpec.instructions ||
|
|
713
|
+
"Summarize what was accomplished and confirm completion", endStepSpec.id || constants_1.END_ROUTE_ID, endStepSpec.collect, undefined, endStepSpec.requires, endStepSpec.instructions ||
|
|
714
|
+
"Summarize what was accomplished and confirm completion based on the conversation history and collected data");
|
|
711
715
|
// Build response schema for completion
|
|
712
|
-
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute,
|
|
716
|
+
const responseSchema = this.responseEngine.responseSchemaForRoute(selectedRoute, completionStep);
|
|
713
717
|
// Build completion response prompt
|
|
714
|
-
const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute,
|
|
718
|
+
const completionPrompt = this.responseEngine.buildResponsePrompt(selectedRoute, completionStep, selectedRoute.getRules(), selectedRoute.getProhibitions(), undefined, // No directives for completion
|
|
715
719
|
history, lastUserMessage, {
|
|
716
720
|
name: this.options.name,
|
|
717
721
|
goal: this.options.goal,
|
|
@@ -729,14 +733,15 @@ class Agent {
|
|
|
729
733
|
schemaName: "completion_message",
|
|
730
734
|
},
|
|
731
735
|
});
|
|
732
|
-
message =
|
|
736
|
+
message =
|
|
737
|
+
completionResult.structured?.message || completionResult.message;
|
|
733
738
|
logger_1.logger.debug(`[Agent] Generated completion message for route: ${selectedRoute.title}`);
|
|
734
739
|
// Check for onComplete transition
|
|
735
|
-
const transitionConfig = await selectedRoute.evaluateOnComplete({
|
|
740
|
+
const transitionConfig = await selectedRoute.evaluateOnComplete({ data: session.data }, effectiveContext);
|
|
736
741
|
if (transitionConfig) {
|
|
737
742
|
// Find target route by ID or title
|
|
738
|
-
const targetRoute = this.routes.find((r) => r.id === transitionConfig.
|
|
739
|
-
r.title === transitionConfig.
|
|
743
|
+
const targetRoute = this.routes.find((r) => r.id === transitionConfig.nextStep ||
|
|
744
|
+
r.title === transitionConfig.nextStep);
|
|
740
745
|
if (targetRoute) {
|
|
741
746
|
// Set pending transition in session
|
|
742
747
|
session = {
|
|
@@ -750,12 +755,12 @@ class Agent {
|
|
|
750
755
|
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed with pending transition to: ${targetRoute.title}`);
|
|
751
756
|
}
|
|
752
757
|
else {
|
|
753
|
-
logger_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.
|
|
758
|
+
logger_1.logger.warn(`[Agent] Route ${selectedRoute.title} completed but target route not found: ${transitionConfig.nextStep}`);
|
|
754
759
|
}
|
|
755
760
|
}
|
|
756
|
-
// Set
|
|
757
|
-
session = (0, session_1.
|
|
758
|
-
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered
|
|
761
|
+
// Set step to END_ROUTE marker
|
|
762
|
+
session = (0, session_1.enterStep)(session, constants_1.END_ROUTE_ID, "Route completed");
|
|
763
|
+
logger_1.logger.debug(`[Agent] Route ${selectedRoute.title} completed. Entered END_ROUTE step.`);
|
|
759
764
|
}
|
|
760
765
|
else {
|
|
761
766
|
// Fallback: No routes defined, generate a simple response
|
|
@@ -790,12 +795,12 @@ class Agent {
|
|
|
790
795
|
});
|
|
791
796
|
message = result.structured?.message || result.message;
|
|
792
797
|
}
|
|
793
|
-
// Auto-save session
|
|
798
|
+
// Auto-save session step to persistence if configured
|
|
794
799
|
if (this.persistenceManager &&
|
|
795
800
|
session.id &&
|
|
796
801
|
this.options.persistence?.autoSave !== false) {
|
|
797
|
-
await this.persistenceManager.
|
|
798
|
-
logger_1.logger.debug(`[Agent] Auto-saved session
|
|
802
|
+
await this.persistenceManager.saveSessionStep(session.id, session);
|
|
803
|
+
logger_1.logger.debug(`[Agent] Auto-saved session step to persistence: ${session.id}`);
|
|
799
804
|
}
|
|
800
805
|
// Update current session if we have one
|
|
801
806
|
if (this.currentSession) {
|
|
@@ -803,9 +808,9 @@ class Agent {
|
|
|
803
808
|
}
|
|
804
809
|
return {
|
|
805
810
|
message,
|
|
806
|
-
session, // Return updated session with route/
|
|
811
|
+
session, // Return updated session with route/step info
|
|
807
812
|
toolCalls,
|
|
808
|
-
isRouteComplete, // Indicates if the route has reached
|
|
813
|
+
isRouteComplete, // Indicates if the route has reached END_ROUTE with all data collected
|
|
809
814
|
};
|
|
810
815
|
}
|
|
811
816
|
/**
|
|
@@ -880,7 +885,7 @@ class Agent {
|
|
|
880
885
|
}
|
|
881
886
|
/**
|
|
882
887
|
* Set the current session for convenience methods
|
|
883
|
-
* @param session - Session
|
|
888
|
+
* @param session - Session step to use for subsequent calls
|
|
884
889
|
*/
|
|
885
890
|
setCurrentSession(session) {
|
|
886
891
|
this.currentSession = session;
|
|
@@ -898,37 +903,38 @@ class Agent {
|
|
|
898
903
|
this.currentSession = undefined;
|
|
899
904
|
}
|
|
900
905
|
/**
|
|
901
|
-
* Get
|
|
906
|
+
* Get collected data from current session
|
|
902
907
|
* @param routeId - Optional route ID to get data for (uses current route if not provided)
|
|
903
|
-
* @returns The
|
|
908
|
+
* @returns The collected data from the current session
|
|
904
909
|
*/
|
|
905
|
-
|
|
910
|
+
getData(routeId) {
|
|
906
911
|
if (!this.currentSession) {
|
|
907
912
|
return {};
|
|
908
913
|
}
|
|
909
914
|
if (routeId) {
|
|
910
|
-
return (this.currentSession.
|
|
915
|
+
return (this.currentSession.dataByRoute?.[routeId] ||
|
|
916
|
+
{});
|
|
911
917
|
}
|
|
912
|
-
return this.currentSession.
|
|
918
|
+
return this.currentSession.data || {};
|
|
913
919
|
}
|
|
914
920
|
/**
|
|
915
921
|
* Manually transition to a different route
|
|
916
922
|
* Sets a pending transition that will be executed on the next respond() call
|
|
917
923
|
*
|
|
918
924
|
* @param routeIdOrTitle - Route ID or title to transition to
|
|
919
|
-
* @param session - Session
|
|
925
|
+
* @param session - Session step to update (uses current session if not provided)
|
|
920
926
|
* @param condition - Optional AI-evaluated condition for the transition
|
|
921
927
|
* @returns Updated session with pending transition
|
|
922
928
|
*
|
|
923
929
|
* @example
|
|
924
930
|
* // After route completes
|
|
925
931
|
* if (response.isRouteComplete && response.session) {
|
|
926
|
-
* const updatedSession = agent.
|
|
932
|
+
* const updatedSession = agent.nextStepRoute("feedback-collection", response.session);
|
|
927
933
|
* // Next respond() call will automatically transition to feedback route
|
|
928
934
|
* const nextResponse = await agent.respond({ history, session: updatedSession });
|
|
929
935
|
* }
|
|
930
936
|
*/
|
|
931
|
-
|
|
937
|
+
nextStepRoute(routeIdOrTitle, session, condition) {
|
|
932
938
|
const targetSession = session || this.currentSession;
|
|
933
939
|
if (!targetSession) {
|
|
934
940
|
throw new Error("No session provided and no current session available. Please provide a session to transition.");
|
|
@@ -936,7 +942,9 @@ class Agent {
|
|
|
936
942
|
// Find target route by ID or title
|
|
937
943
|
const targetRoute = this.routes.find((r) => r.id === routeIdOrTitle || r.title === routeIdOrTitle);
|
|
938
944
|
if (!targetRoute) {
|
|
939
|
-
throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.routes
|
|
945
|
+
throw new Error(`Route not found: ${routeIdOrTitle}. Available routes: ${this.routes
|
|
946
|
+
.map((r) => r.title)
|
|
947
|
+
.join(", ")}`);
|
|
940
948
|
}
|
|
941
949
|
const updatedSession = {
|
|
942
950
|
...targetSession,
|