@falai/agent 0.6.8 → 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Example: Streaming Responses
|
|
3
|
-
* Updated for v2 architecture with session
|
|
3
|
+
* Updated for v2 architecture with session step management
|
|
4
4
|
*
|
|
5
5
|
* This example demonstrates how to use the respondStream method
|
|
6
6
|
* to stream AI responses in real-time for better user experience
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
OpenAIProvider,
|
|
15
15
|
GeminiProvider,
|
|
16
16
|
createSession,
|
|
17
|
-
|
|
17
|
+
END_ROUTE,
|
|
18
18
|
} from "../src/index";
|
|
19
19
|
|
|
20
20
|
// Custom context type
|
|
@@ -73,10 +73,10 @@ async function streamingWithAnthropic() {
|
|
|
73
73
|
console.log("📤 Streaming response from Claude...\n");
|
|
74
74
|
console.log("Response: ");
|
|
75
75
|
|
|
76
|
-
// Initialize session
|
|
76
|
+
// Initialize session step for streaming conversation
|
|
77
77
|
let session = createSession();
|
|
78
78
|
|
|
79
|
-
// Use respondStream for real-time streaming with session
|
|
79
|
+
// Use respondStream for real-time streaming with session step
|
|
80
80
|
let fullMessage = "";
|
|
81
81
|
for await (const chunk of agent.respondStream({ history, session })) {
|
|
82
82
|
// chunk.delta contains the new text
|
|
@@ -94,7 +94,7 @@ async function streamingWithAnthropic() {
|
|
|
94
94
|
console.log(
|
|
95
95
|
` - Route: ${chunk.session?.currentRoute?.title || "None"}`
|
|
96
96
|
);
|
|
97
|
-
console.log(` -
|
|
97
|
+
console.log(` - Data:`, chunk.session?.data || "None");
|
|
98
98
|
console.log(` - Tool Calls: ${chunk.toolCalls?.length || 0}`);
|
|
99
99
|
|
|
100
100
|
// Update session with progress
|
|
@@ -142,7 +142,7 @@ async function streamingWithOpenAI() {
|
|
|
142
142
|
console.log("📤 Streaming response from OpenAI...\n");
|
|
143
143
|
console.log("Response: ");
|
|
144
144
|
|
|
145
|
-
// Initialize session
|
|
145
|
+
// Initialize session step for streaming conversation
|
|
146
146
|
let session = createSession();
|
|
147
147
|
|
|
148
148
|
for await (const chunk of agent.respondStream({ history, session })) {
|
|
@@ -155,7 +155,7 @@ async function streamingWithOpenAI() {
|
|
|
155
155
|
console.log(
|
|
156
156
|
` - Route: ${chunk.session?.currentRoute?.title || "None"}`
|
|
157
157
|
);
|
|
158
|
-
console.log(` -
|
|
158
|
+
console.log(` - Data:`, chunk.session?.data || "None");
|
|
159
159
|
|
|
160
160
|
// Update session with progress
|
|
161
161
|
session = chunk.session!;
|
|
@@ -202,7 +202,7 @@ async function streamingWithGemini() {
|
|
|
202
202
|
console.log("📤 Streaming response from Gemini...\n");
|
|
203
203
|
console.log("Response: ");
|
|
204
204
|
|
|
205
|
-
// Initialize session
|
|
205
|
+
// Initialize session step for streaming conversation
|
|
206
206
|
let session = createSession();
|
|
207
207
|
|
|
208
208
|
for await (const chunk of agent.respondStream({ history, session })) {
|
|
@@ -215,7 +215,7 @@ async function streamingWithGemini() {
|
|
|
215
215
|
console.log(
|
|
216
216
|
` - Route: ${chunk.session?.currentRoute?.title || "None"}`
|
|
217
217
|
);
|
|
218
|
-
console.log(` -
|
|
218
|
+
console.log(` - Data:`, chunk.session?.data || "None");
|
|
219
219
|
|
|
220
220
|
// Update session with progress
|
|
221
221
|
session = chunk.session!;
|
|
@@ -227,7 +227,7 @@ async function streamingWithGemini() {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
async function streamingWithRoutes() {
|
|
230
|
-
console.log("\n🤖 Example 4: Streaming with Routes and
|
|
230
|
+
console.log("\n🤖 Example 4: Streaming with Routes and Steps\n");
|
|
231
231
|
|
|
232
232
|
const provider = new AnthropicProvider({
|
|
233
233
|
apiKey: process.env.ANTHROPIC_API_KEY || "",
|
|
@@ -254,8 +254,8 @@ async function streamingWithRoutes() {
|
|
|
254
254
|
conditions: ["User asks about product features or issues"],
|
|
255
255
|
});
|
|
256
256
|
|
|
257
|
-
supportRoute.
|
|
258
|
-
|
|
257
|
+
supportRoute.initialStep.nextStep({
|
|
258
|
+
instructions: "Understand the user's product question",
|
|
259
259
|
});
|
|
260
260
|
|
|
261
261
|
// Create a feedback route
|
|
@@ -266,7 +266,7 @@ async function streamingWithRoutes() {
|
|
|
266
266
|
title: "Collect Feedback",
|
|
267
267
|
description: "Collect user feedback on their support experience",
|
|
268
268
|
conditions: ["User wants to provide feedback"],
|
|
269
|
-
|
|
269
|
+
schema: {
|
|
270
270
|
type: "object",
|
|
271
271
|
properties: {
|
|
272
272
|
rating: { type: "number", minimum: 1, maximum: 5 },
|
|
@@ -276,15 +276,15 @@ async function streamingWithRoutes() {
|
|
|
276
276
|
},
|
|
277
277
|
steps: [
|
|
278
278
|
{
|
|
279
|
-
|
|
280
|
-
|
|
279
|
+
instructions: "How would you rate your support experience from 1 to 5?",
|
|
280
|
+
collect: ["rating"],
|
|
281
281
|
},
|
|
282
282
|
{
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
instructions: "Thanks for the rating! Any other comments?",
|
|
284
|
+
collect: ["comments"],
|
|
285
285
|
},
|
|
286
286
|
{
|
|
287
|
-
|
|
287
|
+
instructions: "We appreciate your feedback!",
|
|
288
288
|
},
|
|
289
289
|
],
|
|
290
290
|
});
|
|
@@ -301,7 +301,7 @@ async function streamingWithRoutes() {
|
|
|
301
301
|
console.log("📤 Streaming response with route detection...\n");
|
|
302
302
|
console.log("Response: ");
|
|
303
303
|
|
|
304
|
-
// Initialize session
|
|
304
|
+
// Initialize session step for streaming conversation
|
|
305
305
|
let session = createSession();
|
|
306
306
|
|
|
307
307
|
for await (const chunk of agent.respondStream({ history, session })) {
|
|
@@ -315,14 +315,14 @@ async function streamingWithRoutes() {
|
|
|
315
315
|
console.log(
|
|
316
316
|
` - Route: ${chunk.session?.currentRoute?.title || "None"}`
|
|
317
317
|
);
|
|
318
|
-
console.log(` -
|
|
318
|
+
console.log(` - Data:`, chunk.session?.data || "None");
|
|
319
319
|
|
|
320
320
|
// Check for route completion
|
|
321
321
|
if (chunk.isRouteComplete) {
|
|
322
322
|
console.log("\n✅ Route complete!");
|
|
323
323
|
if (chunk.session?.currentRoute?.title === "Collect Feedback") {
|
|
324
324
|
await logFeedback(
|
|
325
|
-
agent.
|
|
325
|
+
agent.getData(chunk.session?.id) as {
|
|
326
326
|
rating: number;
|
|
327
327
|
comments: string;
|
|
328
328
|
}
|
|
@@ -381,7 +381,7 @@ async function streamingWithAbortSignal() {
|
|
|
381
381
|
console.log("📤 Streaming response (will abort after 3s)...\n");
|
|
382
382
|
console.log("Response: ");
|
|
383
383
|
|
|
384
|
-
// Initialize session
|
|
384
|
+
// Initialize session step for streaming conversation
|
|
385
385
|
let session = createSession();
|
|
386
386
|
|
|
387
387
|
for await (const chunk of agent.respondStream({
|
|
@@ -399,7 +399,7 @@ async function streamingWithAbortSignal() {
|
|
|
399
399
|
console.log(
|
|
400
400
|
` - Route: ${chunk.session?.currentRoute?.title || "None"}`
|
|
401
401
|
);
|
|
402
|
-
console.log(` -
|
|
402
|
+
console.log(` - Data:`, chunk.session?.data || "None");
|
|
403
403
|
|
|
404
404
|
// Update session with progress
|
|
405
405
|
session = chunk.session!;
|
|
@@ -453,7 +453,7 @@ async function main() {
|
|
|
453
453
|
console.log(" - Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY");
|
|
454
454
|
console.log(" - Streaming provides real-time responses for better UX");
|
|
455
455
|
console.log(" - Use AbortSignal to cancel long-running streams");
|
|
456
|
-
console.log(" - Access chunk.route and chunk.
|
|
456
|
+
console.log(" - Access chunk.route and chunk.step for flow information");
|
|
457
457
|
|
|
458
458
|
console.log("\n" + "=".repeat(60));
|
|
459
459
|
|
package/examples/travel-agent.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Travel agent example with session
|
|
3
|
-
* Demonstrates data-driven conversations with schema extraction and
|
|
2
|
+
* Travel agent example with session step management
|
|
3
|
+
* Demonstrates data-driven conversations with schema extraction and step progression
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
Agent,
|
|
8
8
|
defineTool,
|
|
9
9
|
OpenRouterProvider,
|
|
10
|
-
|
|
10
|
+
END_ROUTE,
|
|
11
11
|
EventSource,
|
|
12
12
|
createMessageEvent,
|
|
13
13
|
createSession,
|
|
@@ -63,11 +63,8 @@ const getAvailableDestinations = defineTool(
|
|
|
63
63
|
|
|
64
64
|
const lookupDestinationCode = defineTool(
|
|
65
65
|
"lookup_destination_code",
|
|
66
|
-
async ({
|
|
67
|
-
|
|
68
|
-
extracted,
|
|
69
|
-
}: ToolContext<TravelContext, FlightBookingData>) => {
|
|
70
|
-
if (!extracted?.destination) {
|
|
66
|
+
async ({ context, data }: ToolContext<TravelContext, FlightBookingData>) => {
|
|
67
|
+
if (!data?.destination) {
|
|
71
68
|
return { data: undefined };
|
|
72
69
|
}
|
|
73
70
|
|
|
@@ -81,8 +78,8 @@ const lookupDestinationCode = defineTool(
|
|
|
81
78
|
|
|
82
79
|
return {
|
|
83
80
|
data: undefined,
|
|
84
|
-
|
|
85
|
-
destinationCode: codes[
|
|
81
|
+
dataUpdate: {
|
|
82
|
+
destinationCode: codes[data.destination],
|
|
86
83
|
},
|
|
87
84
|
};
|
|
88
85
|
},
|
|
@@ -93,46 +90,40 @@ const lookupDestinationCode = defineTool(
|
|
|
93
90
|
|
|
94
91
|
const searchFlights = defineTool(
|
|
95
92
|
"search_flights",
|
|
96
|
-
async ({
|
|
97
|
-
|
|
98
|
-
extracted,
|
|
99
|
-
}: ToolContext<TravelContext, FlightBookingData>) => {
|
|
100
|
-
if (!extracted?.destination || !extracted?.departureDate) {
|
|
93
|
+
async ({ context, data }: ToolContext<TravelContext, FlightBookingData>) => {
|
|
94
|
+
if (!data?.destination || !data?.departureDate) {
|
|
101
95
|
return { data: [] };
|
|
102
96
|
}
|
|
103
97
|
|
|
104
|
-
// Simulate flight search based on
|
|
98
|
+
// Simulate flight search based on collected data
|
|
105
99
|
const flights = [
|
|
106
|
-
`Flight 123 - ${
|
|
100
|
+
`Flight 123 - ${data.departureDate}, 9:00 AM, $${
|
|
107
101
|
800 + Math.floor(Math.random() * 200)
|
|
108
102
|
}`,
|
|
109
|
-
`Flight 321 - ${
|
|
103
|
+
`Flight 321 - ${data.departureDate}, 2:30 PM, $${
|
|
110
104
|
700 + Math.floor(Math.random() * 200)
|
|
111
105
|
}`,
|
|
112
|
-
`Flight 987 - ${
|
|
106
|
+
`Flight 987 - ${data.departureDate}, 6:45 PM, $${
|
|
113
107
|
600 + Math.floor(Math.random() * 200)
|
|
114
108
|
}`,
|
|
115
109
|
];
|
|
116
110
|
|
|
117
111
|
return {
|
|
118
112
|
data: flights,
|
|
119
|
-
|
|
113
|
+
dataUpdate: {
|
|
120
114
|
shouldSearchFlights: false, // Clear the flag
|
|
121
115
|
},
|
|
122
116
|
};
|
|
123
117
|
},
|
|
124
118
|
{
|
|
125
|
-
description: "Search for flights based on
|
|
119
|
+
description: "Search for flights based on data travel data",
|
|
126
120
|
}
|
|
127
121
|
);
|
|
128
122
|
|
|
129
123
|
const bookFlight = defineTool(
|
|
130
124
|
"book_flight",
|
|
131
|
-
async ({
|
|
132
|
-
|
|
133
|
-
extracted,
|
|
134
|
-
}: ToolContext<TravelContext, FlightBookingData>) => {
|
|
135
|
-
if (!extracted) {
|
|
125
|
+
async ({ context, data }: ToolContext<TravelContext, FlightBookingData>) => {
|
|
126
|
+
if (!data) {
|
|
136
127
|
return { data: "Please provide flight details" };
|
|
137
128
|
}
|
|
138
129
|
|
|
@@ -142,11 +133,11 @@ const bookFlight = defineTool(
|
|
|
142
133
|
.replace(/-/g, "")}-001`;
|
|
143
134
|
|
|
144
135
|
return {
|
|
145
|
-
data: `Flight booked for ${context.customerName} to ${
|
|
136
|
+
data: `Flight booked for ${context.customerName} to ${data.destination}. Confirmation: ${confirmationNumber}`,
|
|
146
137
|
};
|
|
147
138
|
},
|
|
148
139
|
{
|
|
149
|
-
description: "Book a flight using
|
|
140
|
+
description: "Book a flight using data travel data",
|
|
150
141
|
}
|
|
151
142
|
);
|
|
152
143
|
|
|
@@ -156,11 +147,8 @@ const getBookingStatus = defineTool<
|
|
|
156
147
|
{ status: string; details: string; notes?: string }
|
|
157
148
|
>(
|
|
158
149
|
"get_booking_status",
|
|
159
|
-
async ({
|
|
160
|
-
|
|
161
|
-
extracted,
|
|
162
|
-
}: ToolContext<TravelContext, BookingStatusData>) => {
|
|
163
|
-
if (!extracted?.confirmationNumber) {
|
|
150
|
+
async ({ context, data }: ToolContext<TravelContext, BookingStatusData>) => {
|
|
151
|
+
if (!data?.confirmationNumber) {
|
|
164
152
|
return {
|
|
165
153
|
data: {
|
|
166
154
|
status: "Error",
|
|
@@ -172,13 +160,13 @@ const getBookingStatus = defineTool<
|
|
|
172
160
|
return {
|
|
173
161
|
data: {
|
|
174
162
|
status: "Confirmed",
|
|
175
|
-
details: `Flight booking ${
|
|
163
|
+
details: `Flight booking ${data.confirmationNumber} is confirmed.`,
|
|
176
164
|
notes: "Check-in opens 24 hours before departure.",
|
|
177
165
|
},
|
|
178
166
|
};
|
|
179
167
|
},
|
|
180
168
|
{
|
|
181
|
-
description: "Get booking status using
|
|
169
|
+
description: "Get booking status using data confirmation number",
|
|
182
170
|
}
|
|
183
171
|
);
|
|
184
172
|
|
|
@@ -234,12 +222,12 @@ async function createTravelAgent() {
|
|
|
234
222
|
// NEW: Transition to feedback collection after successful booking
|
|
235
223
|
onComplete: (session) => {
|
|
236
224
|
// Dynamic logic: only collect feedback if destination is known
|
|
237
|
-
if (session.
|
|
225
|
+
if (session.data?.destination) {
|
|
238
226
|
return "Travel Feedback";
|
|
239
227
|
}
|
|
240
228
|
return undefined; // No transition
|
|
241
229
|
},
|
|
242
|
-
|
|
230
|
+
schema: {
|
|
243
231
|
type: "object",
|
|
244
232
|
properties: {
|
|
245
233
|
destination: {
|
|
@@ -285,66 +273,66 @@ async function createTravelAgent() {
|
|
|
285
273
|
},
|
|
286
274
|
});
|
|
287
275
|
|
|
288
|
-
// Build the route flow with data extraction and smart
|
|
289
|
-
const askDestination = flightBookingRoute.
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
skipIf: (
|
|
276
|
+
// Build the route flow with data extraction and smart step progression
|
|
277
|
+
const askDestination = flightBookingRoute.initialStep.nextStep({
|
|
278
|
+
instructions: "Ask about the destination",
|
|
279
|
+
collect: ["destination"],
|
|
280
|
+
skipIf: (data) => !!data.destination,
|
|
293
281
|
condition: "Customer needs to specify their travel destination",
|
|
294
282
|
});
|
|
295
283
|
|
|
296
|
-
const enrichDestination = askDestination.
|
|
297
|
-
|
|
298
|
-
|
|
284
|
+
const enrichDestination = askDestination.nextStep({
|
|
285
|
+
tool: lookupDestinationCode,
|
|
286
|
+
requires: ["destination"],
|
|
299
287
|
condition: "Destination provided, lookup airport code",
|
|
300
288
|
});
|
|
301
289
|
|
|
302
|
-
const askDates = enrichDestination.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
skipIf: (
|
|
306
|
-
|
|
290
|
+
const askDates = enrichDestination.nextStep({
|
|
291
|
+
instructions: "Ask about preferred travel dates",
|
|
292
|
+
collect: ["departureDate"],
|
|
293
|
+
skipIf: (data) => !!data.departureDate,
|
|
294
|
+
requires: ["destination"],
|
|
307
295
|
condition: "Destination confirmed, need travel dates",
|
|
308
296
|
});
|
|
309
297
|
|
|
310
|
-
const askPassengers = askDates.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
skipIf: (
|
|
314
|
-
|
|
298
|
+
const askPassengers = askDates.nextStep({
|
|
299
|
+
instructions: "Ask for number of passengers",
|
|
300
|
+
collect: ["passengers"],
|
|
301
|
+
skipIf: (data) => !!data.passengers,
|
|
302
|
+
requires: ["destination", "departureDate"],
|
|
315
303
|
condition: "Dates confirmed, need passenger count",
|
|
316
304
|
});
|
|
317
305
|
|
|
318
|
-
const
|
|
319
|
-
|
|
306
|
+
const searchFlightsStep = askPassengers.nextStep({
|
|
307
|
+
tool: searchFlights,
|
|
320
308
|
// Triggered when shouldSearchFlights flag is set by hook
|
|
321
|
-
condition: "All basic info
|
|
309
|
+
condition: "All basic info collected, search for available flights",
|
|
322
310
|
});
|
|
323
311
|
|
|
324
|
-
const presentFlights =
|
|
325
|
-
|
|
312
|
+
const presentFlights = searchFlightsStep.nextStep({
|
|
313
|
+
instructions: "Present available flights and ask which one works for them",
|
|
326
314
|
condition: "Flight search complete, present options to customer",
|
|
327
315
|
});
|
|
328
316
|
|
|
329
317
|
// Happy path: customer selects a flight
|
|
330
|
-
const confirmBooking = presentFlights.
|
|
331
|
-
|
|
332
|
-
|
|
318
|
+
const confirmBooking = presentFlights.nextStep({
|
|
319
|
+
instructions: "Confirm booking details before proceeding",
|
|
320
|
+
collect: ["cabinClass", "urgency"], // Additional optional data
|
|
333
321
|
condition: "Customer interested in a flight, confirm booking details",
|
|
334
322
|
});
|
|
335
323
|
|
|
336
|
-
const
|
|
337
|
-
|
|
324
|
+
const bookFlightStep = confirmBooking.nextStep({
|
|
325
|
+
tool: bookFlight,
|
|
338
326
|
condition: "Customer confirmed, proceed with booking",
|
|
339
327
|
});
|
|
340
328
|
|
|
341
|
-
const provideConfirmation =
|
|
342
|
-
|
|
329
|
+
const provideConfirmation = bookFlightStep.nextStep({
|
|
330
|
+
instructions: "Provide confirmation number and booking summary",
|
|
343
331
|
condition: "Booking completed successfully",
|
|
344
332
|
});
|
|
345
333
|
|
|
346
|
-
provideConfirmation.
|
|
347
|
-
|
|
334
|
+
provideConfirmation.nextStep({
|
|
335
|
+
step: END_ROUTE,
|
|
348
336
|
condition: "Customer has confirmation, booking flow complete",
|
|
349
337
|
});
|
|
350
338
|
|
|
@@ -368,7 +356,7 @@ async function createTravelAgent() {
|
|
|
368
356
|
description:
|
|
369
357
|
"Retrieves the customer's booking status and provides relevant information.",
|
|
370
358
|
conditions: ["The customer wants to check their booking status"],
|
|
371
|
-
|
|
359
|
+
schema: {
|
|
372
360
|
type: "object",
|
|
373
361
|
properties: {
|
|
374
362
|
confirmationNumber: {
|
|
@@ -384,27 +372,27 @@ async function createTravelAgent() {
|
|
|
384
372
|
},
|
|
385
373
|
});
|
|
386
374
|
|
|
387
|
-
const askConfirmation = bookingStatusRoute.
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
skipIf: (
|
|
375
|
+
const askConfirmation = bookingStatusRoute.initialStep.nextStep({
|
|
376
|
+
instructions: "Ask for the confirmation number or booking reference",
|
|
377
|
+
collect: ["confirmationNumber"],
|
|
378
|
+
skipIf: (data) => !!data.confirmationNumber,
|
|
391
379
|
condition:
|
|
392
380
|
"Customer wants to check booking status but hasn't provided confirmation number",
|
|
393
381
|
});
|
|
394
382
|
|
|
395
|
-
const checkStatus = askConfirmation.
|
|
396
|
-
|
|
397
|
-
|
|
383
|
+
const checkStatus = askConfirmation.nextStep({
|
|
384
|
+
tool: getBookingStatus,
|
|
385
|
+
requires: ["confirmationNumber"],
|
|
398
386
|
condition: "Confirmation number provided, look up booking details",
|
|
399
387
|
});
|
|
400
388
|
|
|
401
|
-
const provideStatus = checkStatus.
|
|
402
|
-
|
|
389
|
+
const provideStatus = checkStatus.nextStep({
|
|
390
|
+
instructions: "Provide booking status and relevant information",
|
|
403
391
|
condition: "Booking status retrieved successfully",
|
|
404
392
|
});
|
|
405
393
|
|
|
406
|
-
provideStatus.
|
|
407
|
-
|
|
394
|
+
provideStatus.nextStep({
|
|
395
|
+
step: END_ROUTE,
|
|
408
396
|
condition: "Booking information provided to customer",
|
|
409
397
|
});
|
|
410
398
|
|
|
@@ -413,7 +401,7 @@ async function createTravelAgent() {
|
|
|
413
401
|
title: "Travel Feedback",
|
|
414
402
|
description: "Collects customer feedback after flight booking",
|
|
415
403
|
conditions: ["Collect travel booking feedback"],
|
|
416
|
-
|
|
404
|
+
schema: {
|
|
417
405
|
type: "object",
|
|
418
406
|
properties: {
|
|
419
407
|
rating: {
|
|
@@ -433,25 +421,24 @@ async function createTravelAgent() {
|
|
|
433
421
|
},
|
|
434
422
|
});
|
|
435
423
|
|
|
436
|
-
const askFeedbackRating = feedbackRoute.
|
|
437
|
-
|
|
424
|
+
const askFeedbackRating = feedbackRoute.initialStep.nextStep({
|
|
425
|
+
instructions:
|
|
438
426
|
"Ask for overall rating from 1 to 5 for the booking experience",
|
|
439
|
-
|
|
440
|
-
skipIf: (
|
|
427
|
+
collect: ["rating"],
|
|
428
|
+
skipIf: (data) => !!data.rating,
|
|
441
429
|
});
|
|
442
430
|
|
|
443
|
-
const askRecommendation = askFeedbackRating.
|
|
444
|
-
|
|
431
|
+
const askRecommendation = askFeedbackRating.nextStep({
|
|
432
|
+
instructions:
|
|
445
433
|
"Ask if they would recommend our service to a friend (yes/no)",
|
|
446
|
-
|
|
434
|
+
collect: ["recommendToFriend"],
|
|
447
435
|
});
|
|
448
436
|
|
|
449
|
-
const thankForFeedback = askRecommendation.
|
|
450
|
-
|
|
451
|
-
"Thank them for their feedback and wish them a great trip!",
|
|
437
|
+
const thankForFeedback = askRecommendation.nextStep({
|
|
438
|
+
instructions: "Thank them for their feedback and wish them a great trip!",
|
|
452
439
|
});
|
|
453
440
|
|
|
454
|
-
thankForFeedback.
|
|
441
|
+
thankForFeedback.nextStep({ step: END_ROUTE });
|
|
455
442
|
|
|
456
443
|
// Global guidelines
|
|
457
444
|
agent.createGuideline({
|
|
@@ -476,11 +463,11 @@ async function createTravelAgent() {
|
|
|
476
463
|
return agent;
|
|
477
464
|
}
|
|
478
465
|
|
|
479
|
-
// Example usage with session
|
|
466
|
+
// Example usage with session step
|
|
480
467
|
async function main() {
|
|
481
468
|
const agent = await createTravelAgent();
|
|
482
469
|
|
|
483
|
-
// Initialize session
|
|
470
|
+
// Initialize session step
|
|
484
471
|
let session = createSession<FlightBookingData | BookingStatusData>();
|
|
485
472
|
|
|
486
473
|
// Simulate a conversation
|
|
@@ -500,13 +487,13 @@ async function main() {
|
|
|
500
487
|
console.info("\n=== TURN 1 ===");
|
|
501
488
|
console.info("Agent:", response1.message);
|
|
502
489
|
console.info("Route:", response1.session?.currentRoute?.title);
|
|
503
|
-
console.info("
|
|
504
|
-
console.info("
|
|
490
|
+
console.info("Step:", response1.session?.currentStep?.id);
|
|
491
|
+
console.info("Data:", response1.session?.data);
|
|
505
492
|
|
|
506
|
-
// Session
|
|
493
|
+
// Session step updated with progress
|
|
507
494
|
session = response1.session!;
|
|
508
495
|
|
|
509
|
-
// Turn 2 - Continue with session
|
|
496
|
+
// Turn 2 - Continue with session step
|
|
510
497
|
if (response1.session?.currentRoute?.title === "Book a Flight") {
|
|
511
498
|
const history2 = [
|
|
512
499
|
...history,
|
|
@@ -517,8 +504,8 @@ async function main() {
|
|
|
517
504
|
const response2 = await agent.respond({ history: history2, session });
|
|
518
505
|
console.info("\n=== TURN 2 ===");
|
|
519
506
|
console.info("Agent:", response2.message);
|
|
520
|
-
console.info("Updated
|
|
521
|
-
console.info("Current
|
|
507
|
+
console.info("Updated data:", response2.session?.data);
|
|
508
|
+
console.info("Current step:", response2.session?.currentStep?.id);
|
|
522
509
|
}
|
|
523
510
|
|
|
524
511
|
// Demonstrate booking status check
|
|
@@ -538,23 +525,21 @@ async function main() {
|
|
|
538
525
|
console.info("\n=== BOOKING STATUS CHECK ===");
|
|
539
526
|
console.info("Agent:", statusResponse.message);
|
|
540
527
|
console.info("Route:", statusResponse.session?.currentRoute?.title);
|
|
541
|
-
console.info("
|
|
528
|
+
console.info("Data:", statusResponse.session?.data);
|
|
542
529
|
|
|
543
|
-
// Show session
|
|
544
|
-
console.info("\n=== SESSION
|
|
530
|
+
// Show session step management benefits
|
|
531
|
+
console.info("\n=== SESSION STEP BENEFITS ===");
|
|
545
532
|
console.info("✅ Always-on routing - respects user intent changes");
|
|
546
|
-
console.info("✅ Data persistence -
|
|
533
|
+
console.info("✅ Data persistence - collected data survives across turns");
|
|
547
534
|
console.info(
|
|
548
|
-
"✅
|
|
535
|
+
"✅ Step progression - intelligent flow based on collected data"
|
|
549
536
|
);
|
|
550
537
|
console.info("✅ Context awareness - router sees current progress");
|
|
551
538
|
|
|
552
539
|
if (statusResponse.isRouteComplete) {
|
|
553
540
|
console.info("\n✅ Booking status check complete!");
|
|
554
541
|
await logBookingStatusCheck(
|
|
555
|
-
agent.
|
|
556
|
-
statusResponse.session?.id
|
|
557
|
-
) as unknown as BookingStatusData
|
|
542
|
+
agent.getData(statusResponse.session?.id) as unknown as BookingStatusData
|
|
558
543
|
);
|
|
559
544
|
}
|
|
560
545
|
}
|
package/package.json
CHANGED
|
@@ -149,14 +149,14 @@ class MemorySessionRepository implements SessionRepository {
|
|
|
149
149
|
return await this.update(id, { collectedData });
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async
|
|
152
|
+
async updateRouteStep(
|
|
153
153
|
id: string,
|
|
154
154
|
route?: string,
|
|
155
|
-
|
|
155
|
+
step?: string
|
|
156
156
|
): Promise<SessionData | null> {
|
|
157
157
|
return await this.update(id, {
|
|
158
158
|
currentRoute: route,
|
|
159
|
-
|
|
159
|
+
currentStep: step,
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -206,14 +206,14 @@ class MongoSessionRepository implements SessionRepository {
|
|
|
206
206
|
return await this.update(id, { collectedData });
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
async
|
|
209
|
+
async updateRouteStep(
|
|
210
210
|
id: string,
|
|
211
211
|
route?: string,
|
|
212
|
-
|
|
212
|
+
step?: string
|
|
213
213
|
): Promise<SessionData | null> {
|
|
214
214
|
return await this.update(id, {
|
|
215
215
|
currentRoute: route,
|
|
216
|
-
|
|
216
|
+
currentStep: step,
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
|