@falai/agent 0.6.9 → 0.8.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 +78 -82
- package/dist/adapters/MemoryAdapter.d.ts +1 -1
- package/dist/adapters/MemoryAdapter.js +3 -3
- package/dist/adapters/MemoryAdapter.js.map +1 -1
- package/dist/adapters/MongoAdapter.d.ts +1 -1
- package/dist/adapters/MongoAdapter.js +3 -3
- 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.d.ts +1 -1
- package/dist/adapters/PostgreSQLAdapter.js +10 -10
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/adapters/PrismaAdapter.d.ts +1 -1
- package/dist/adapters/PrismaAdapter.js +4 -4
- package/dist/adapters/PrismaAdapter.js.map +1 -1
- package/dist/adapters/RedisAdapter.d.ts +1 -1
- package/dist/adapters/RedisAdapter.js +3 -3
- package/dist/adapters/RedisAdapter.js.map +1 -1
- package/dist/adapters/SQLiteAdapter.d.ts +4 -4
- package/dist/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/adapters/SQLiteAdapter.js +12 -12
- 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.d.ts +1 -1
- package/dist/cjs/adapters/MemoryAdapter.js +3 -3
- package/dist/cjs/adapters/MemoryAdapter.js.map +1 -1
- package/dist/cjs/adapters/MongoAdapter.d.ts +1 -1
- package/dist/cjs/adapters/MongoAdapter.js +3 -3
- 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.d.ts +1 -1
- package/dist/cjs/adapters/PostgreSQLAdapter.js +10 -10
- package/dist/cjs/adapters/PostgreSQLAdapter.js.map +1 -1
- package/dist/cjs/adapters/PrismaAdapter.d.ts +1 -1
- package/dist/cjs/adapters/PrismaAdapter.js +4 -4
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -1
- package/dist/cjs/adapters/RedisAdapter.d.ts +1 -1
- package/dist/cjs/adapters/RedisAdapter.js +3 -3
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.d.ts +4 -4
- package/dist/cjs/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/dist/cjs/adapters/SQLiteAdapter.js +12 -12
- 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 +168 -160
- 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 +31 -31
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/core/RoutingEngine.js +196 -196
- 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 +9 -9
- 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 +170 -162
- 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 +31 -31
- package/dist/core/RoutingEngine.d.ts.map +1 -1
- package/dist/core/RoutingEngine.js +197 -197
- 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 +9 -9
- 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 +63 -61
- package/docs/API_REFERENCE.md +218 -220
- package/docs/ARCHITECTURE.md +99 -104
- package/docs/CONTEXT_MANAGEMENT.md +84 -91
- package/docs/CONTRIBUTING.md +3 -3
- package/docs/DOCS.md +18 -18
- package/docs/DOMAINS.md +18 -18
- package/docs/EXAMPLES.md +44 -44
- package/docs/GETTING_STARTED.md +63 -66
- package/docs/PERSISTENCE.md +70 -74
- package/docs/PROVIDERS.md +6 -6
- package/docs/README.md +6 -6
- package/docs/ROUTES.md +218 -220
- package/docs/STEPS.md +883 -0
- package/examples/business-onboarding.ts +85 -82
- package/examples/company-qna-agent.ts +69 -68
- package/examples/custom-database-persistence.ts +89 -91
- package/examples/declarative-agent.ts +33 -33
- package/examples/domain-scoping.ts +20 -20
- package/examples/extracted-data-modification.ts +93 -98
- package/examples/healthcare-agent.ts +90 -92
- package/examples/openai-agent.ts +30 -33
- package/examples/opensearch-persistence.ts +46 -48
- package/examples/persistent-onboarding.ts +67 -68
- package/examples/prisma-persistence.ts +111 -115
- package/examples/prisma-schema.example.prisma +3 -3
- package/examples/redis-persistence.ts +70 -76
- package/examples/route-transitions.ts +72 -48
- package/examples/rules-prohibitions.ts +31 -31
- package/examples/streaming-agent.ts +29 -29
- package/examples/travel-agent.ts +95 -110
- package/package.json +1 -1
- package/src/adapters/MemoryAdapter.ts +4 -4
- package/src/adapters/MongoAdapter.ts +4 -4
- package/src/adapters/OpenSearchAdapter.ts +8 -8
- package/src/adapters/PostgreSQLAdapter.ts +11 -11
- package/src/adapters/PrismaAdapter.ts +5 -5
- package/src/adapters/RedisAdapter.ts +4 -4
- package/src/adapters/SQLiteAdapter.ts +16 -16
- package/src/adapters/index.ts +1 -1
- package/src/constants/index.ts +4 -4
- package/src/core/Agent.ts +218 -214
- 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 +252 -258
- 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 +9 -9
- 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/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
|
|
|
@@ -201,7 +189,7 @@ async function createTravelAgent() {
|
|
|
201
189
|
description:
|
|
202
190
|
"A knowledgeable travel agent who helps book flights, answer travel questions, and manage reservations.",
|
|
203
191
|
goal: "Help customers book travel and manage their reservations",
|
|
204
|
-
|
|
192
|
+
provider: provider,
|
|
205
193
|
context: {
|
|
206
194
|
customerId: "test-123",
|
|
207
195
|
customerName: "Test Customer",
|
|
@@ -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
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
*
|
|
28
28
|
* const agent = new Agent({
|
|
29
29
|
* name: "My Agent",
|
|
30
|
-
*
|
|
30
|
+
* provider: provider,
|
|
31
31
|
* persistence: {
|
|
32
32
|
* adapter: new MemoryAdapter(),
|
|
33
33
|
* userId: "user_123",
|
|
@@ -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
|
|
|
@@ -87,7 +87,7 @@ export interface MongoAdapterOptions {
|
|
|
87
87
|
*
|
|
88
88
|
* const agent = new Agent({
|
|
89
89
|
* name: "My Agent",
|
|
90
|
-
*
|
|
90
|
+
* provider: provider,
|
|
91
91
|
* persistence: {
|
|
92
92
|
* adapter: new MongoAdapter({
|
|
93
93
|
* client,
|
|
@@ -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
|
|
|
@@ -191,7 +191,7 @@ export class OpenSearchAdapter implements PersistenceAdapter {
|
|
|
191
191
|
agentName: { type: "keyword" },
|
|
192
192
|
status: { type: "keyword" },
|
|
193
193
|
currentRoute: { type: "keyword" },
|
|
194
|
-
|
|
194
|
+
currentStep: { type: "keyword" },
|
|
195
195
|
collectedData: { type: "object", enabled: false },
|
|
196
196
|
messageCount: { type: "integer" },
|
|
197
197
|
createdAt: { type: "date" },
|
|
@@ -221,7 +221,7 @@ export class OpenSearchAdapter implements PersistenceAdapter {
|
|
|
221
221
|
role: { type: "keyword" },
|
|
222
222
|
content: { type: "text" },
|
|
223
223
|
route: { type: "keyword" },
|
|
224
|
-
|
|
224
|
+
step: { type: "keyword" },
|
|
225
225
|
toolCalls: { type: "object", enabled: false },
|
|
226
226
|
event: { type: "object", enabled: false },
|
|
227
227
|
createdAt: { type: "date" },
|
|
@@ -396,10 +396,10 @@ class OpenSearchSessionRepository implements SessionRepository {
|
|
|
396
396
|
return await this.findById(id);
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
-
async
|
|
399
|
+
async updateRouteStep(
|
|
400
400
|
id: string,
|
|
401
401
|
route?: string,
|
|
402
|
-
|
|
402
|
+
step?: string
|
|
403
403
|
): Promise<SessionData | null> {
|
|
404
404
|
const doc: Record<string, unknown> = {
|
|
405
405
|
updatedAt: new Date().toISOString(),
|
|
@@ -408,8 +408,8 @@ class OpenSearchSessionRepository implements SessionRepository {
|
|
|
408
408
|
if (route !== undefined) {
|
|
409
409
|
doc.currentRoute = route;
|
|
410
410
|
}
|
|
411
|
-
if (
|
|
412
|
-
doc.
|
|
411
|
+
if (step !== undefined) {
|
|
412
|
+
doc.currentStep = step;
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
await this.client.update({
|
|
@@ -478,7 +478,7 @@ class OpenSearchSessionRepository implements SessionRepository {
|
|
|
478
478
|
agentName: doc.agentName as string | undefined,
|
|
479
479
|
status: doc.status as SessionData["status"],
|
|
480
480
|
currentRoute: doc.currentRoute as string | undefined,
|
|
481
|
-
|
|
481
|
+
currentStep: doc.currentStep as string | undefined,
|
|
482
482
|
collectedData: doc.collectedData as Record<string, unknown> | undefined,
|
|
483
483
|
messageCount: doc.messageCount as number | undefined,
|
|
484
484
|
createdAt: new Date(doc.createdAt as string),
|
|
@@ -646,7 +646,7 @@ class OpenSearchMessageRepository implements MessageRepository {
|
|
|
646
646
|
role: doc.role as MessageData["role"],
|
|
647
647
|
content: doc.content as string,
|
|
648
648
|
route: doc.route as string | undefined,
|
|
649
|
-
|
|
649
|
+
step: doc.step as string | undefined,
|
|
650
650
|
toolCalls: doc.toolCalls as
|
|
651
651
|
| Array<{ toolName: string; arguments: Record<string, unknown> }>
|
|
652
652
|
| undefined,
|
|
@@ -68,7 +68,7 @@ export interface PostgreSQLAdapterOptions {
|
|
|
68
68
|
*
|
|
69
69
|
* const agent = new Agent({
|
|
70
70
|
* name: "My Agent",
|
|
71
|
-
*
|
|
71
|
+
* provider: provider,
|
|
72
72
|
* persistence: {
|
|
73
73
|
* adapter: new PostgreSQLAdapter({ client }),
|
|
74
74
|
* userId: "user_123",
|
|
@@ -110,7 +110,7 @@ export class PostgreSQLAdapter implements PersistenceAdapter {
|
|
|
110
110
|
agent_name VARCHAR(255),
|
|
111
111
|
status VARCHAR(50) DEFAULT 'active',
|
|
112
112
|
current_route VARCHAR(255),
|
|
113
|
-
|
|
113
|
+
current_step VARCHAR(255),
|
|
114
114
|
collected_data JSONB,
|
|
115
115
|
message_count INTEGER DEFAULT 0,
|
|
116
116
|
last_message_at TIMESTAMP,
|
|
@@ -133,7 +133,7 @@ export class PostgreSQLAdapter implements PersistenceAdapter {
|
|
|
133
133
|
role VARCHAR(50) NOT NULL,
|
|
134
134
|
content TEXT NOT NULL,
|
|
135
135
|
route VARCHAR(255),
|
|
136
|
-
|
|
136
|
+
step VARCHAR(255),
|
|
137
137
|
tool_calls JSONB,
|
|
138
138
|
event JSONB,
|
|
139
139
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
@@ -237,9 +237,9 @@ class PostgreSQLSessionRepository implements SessionRepository {
|
|
|
237
237
|
fields.push(`current_route = $${paramIndex++}`);
|
|
238
238
|
values.push(data.currentRoute);
|
|
239
239
|
}
|
|
240
|
-
if (data.
|
|
241
|
-
fields.push(`
|
|
242
|
-
values.push(data.
|
|
240
|
+
if (data.currentStep !== undefined) {
|
|
241
|
+
fields.push(`current_step = $${paramIndex++}`);
|
|
242
|
+
values.push(data.currentStep);
|
|
243
243
|
}
|
|
244
244
|
if (data.messageCount !== undefined) {
|
|
245
245
|
fields.push(`message_count = $${paramIndex++}`);
|
|
@@ -285,14 +285,14 @@ class PostgreSQLSessionRepository implements SessionRepository {
|
|
|
285
285
|
return await this.update(id, { collectedData });
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
async
|
|
288
|
+
async updateRouteStep(
|
|
289
289
|
id: string,
|
|
290
290
|
route?: string,
|
|
291
|
-
|
|
291
|
+
step?: string
|
|
292
292
|
): Promise<SessionData | null> {
|
|
293
293
|
return await this.update(id, {
|
|
294
294
|
currentRoute: route,
|
|
295
|
-
|
|
295
|
+
currentStep: step,
|
|
296
296
|
});
|
|
297
297
|
}
|
|
298
298
|
|
|
@@ -333,7 +333,7 @@ class PostgreSQLMessageRepository implements MessageRepository {
|
|
|
333
333
|
|
|
334
334
|
const result = await this.client.query<MessageData>(
|
|
335
335
|
`INSERT INTO ${this.tableName}
|
|
336
|
-
(id, session_id, user_id, role, content, route,
|
|
336
|
+
(id, session_id, user_id, role, content, route, step, tool_calls, event, created_at)
|
|
337
337
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NOW())
|
|
338
338
|
RETURNING *`,
|
|
339
339
|
[
|
|
@@ -343,7 +343,7 @@ class PostgreSQLMessageRepository implements MessageRepository {
|
|
|
343
343
|
data.role,
|
|
344
344
|
data.content,
|
|
345
345
|
data.route || null,
|
|
346
|
-
data.
|
|
346
|
+
data.step || null,
|
|
347
347
|
JSON.stringify(data.toolCalls || null),
|
|
348
348
|
JSON.stringify(data.event || null),
|
|
349
349
|
]
|
|
@@ -107,7 +107,7 @@ export interface PrismaAdapterOptions {
|
|
|
107
107
|
*
|
|
108
108
|
* const agent = new Agent({
|
|
109
109
|
* name: "My Agent",
|
|
110
|
-
*
|
|
110
|
+
* provider: provider,
|
|
111
111
|
* persistence: {
|
|
112
112
|
* adapter: new PrismaAdapter({ prisma }),
|
|
113
113
|
* userId: "user_123",
|
|
@@ -333,10 +333,10 @@ class PrismaSessionRepository implements SessionRepository {
|
|
|
333
333
|
return this.unmapFields(result);
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
async
|
|
336
|
+
async updateRouteStep(
|
|
337
337
|
id: string,
|
|
338
338
|
route?: string,
|
|
339
|
-
|
|
339
|
+
step?: string
|
|
340
340
|
): Promise<SessionData | null> {
|
|
341
341
|
const data: Record<string, unknown> = {
|
|
342
342
|
[this.fieldMap.updatedAt || "updatedAt"]: new Date(),
|
|
@@ -344,8 +344,8 @@ class PrismaSessionRepository implements SessionRepository {
|
|
|
344
344
|
if (route !== undefined) {
|
|
345
345
|
data[this.fieldMap.currentRoute || "currentRoute"] = route;
|
|
346
346
|
}
|
|
347
|
-
if (
|
|
348
|
-
data[this.fieldMap.
|
|
347
|
+
if (step !== undefined) {
|
|
348
|
+
data[this.fieldMap.currentStep || "currentStep"] = step;
|
|
349
349
|
}
|
|
350
350
|
const result = await this.getModel().update({
|
|
351
351
|
where: { [this.fieldMap.id || "id"]: id },
|