@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Example: Custom Database Integration (Manual Session
|
|
2
|
+
* Example: Custom Database Integration (Manual Session Step Management)
|
|
3
3
|
*
|
|
4
|
-
* This example shows how to manually manage session
|
|
4
|
+
* This example shows how to manually manage session step when using your own
|
|
5
5
|
* database structure instead of the built-in persistence adapters.
|
|
6
6
|
*
|
|
7
7
|
* Use this approach if you:
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
createMessageEvent,
|
|
17
17
|
EventSource,
|
|
18
18
|
createSession,
|
|
19
|
-
|
|
19
|
+
SessionStep,
|
|
20
20
|
MessageEventData,
|
|
21
21
|
Event,
|
|
22
|
-
|
|
22
|
+
END_ROUTE,
|
|
23
23
|
} from "../src/index";
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -30,13 +30,13 @@ interface CustomDatabaseSession {
|
|
|
30
30
|
id: string;
|
|
31
31
|
userId: string;
|
|
32
32
|
currentRoute?: string;
|
|
33
|
-
|
|
33
|
+
currentStep?: string;
|
|
34
34
|
collectedData?: {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
data?: Record<string, unknown>;
|
|
36
|
+
dataByRoute?: Record<string, Partial<unknown>>;
|
|
37
37
|
routeHistory?: unknown[];
|
|
38
38
|
currentRouteTitle?: string;
|
|
39
|
-
|
|
39
|
+
currentStepDescription?: string;
|
|
40
40
|
metadata?: Record<string, unknown>;
|
|
41
41
|
};
|
|
42
42
|
createdAt: Date;
|
|
@@ -50,7 +50,7 @@ interface CustomDatabaseMessage {
|
|
|
50
50
|
role: "user" | "agent" | "system";
|
|
51
51
|
content: string;
|
|
52
52
|
route?: string;
|
|
53
|
-
|
|
53
|
+
step?: string;
|
|
54
54
|
createdAt: Date;
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -148,7 +148,7 @@ async function example() {
|
|
|
148
148
|
"User is a new customer",
|
|
149
149
|
"User needs to set up their account",
|
|
150
150
|
],
|
|
151
|
-
|
|
151
|
+
schema: {
|
|
152
152
|
type: "object",
|
|
153
153
|
properties: {
|
|
154
154
|
fullName: { type: "string" },
|
|
@@ -161,47 +161,47 @@ async function example() {
|
|
|
161
161
|
},
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
-
// Define
|
|
165
|
-
onboardingRoute.
|
|
166
|
-
.
|
|
164
|
+
// Define steps with custom IDs
|
|
165
|
+
onboardingRoute.initialStep
|
|
166
|
+
.nextStep({
|
|
167
167
|
id: "ask_name",
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
instructions: "Ask for full name",
|
|
169
|
+
collect: ["fullName"],
|
|
170
170
|
skipIf: (data) => !!data.fullName,
|
|
171
171
|
})
|
|
172
|
-
.
|
|
172
|
+
.nextStep({
|
|
173
173
|
id: "ask_email",
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
instructions: "Ask for email address",
|
|
175
|
+
collect: ["email"],
|
|
176
176
|
skipIf: (data) => !!data.email,
|
|
177
177
|
})
|
|
178
|
-
.
|
|
178
|
+
.nextStep({
|
|
179
179
|
id: "ask_company",
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
instructions: "Ask for company name",
|
|
181
|
+
collect: ["companyName"],
|
|
182
182
|
skipIf: (data) => !!data.companyName,
|
|
183
183
|
})
|
|
184
|
-
.
|
|
184
|
+
.nextStep({
|
|
185
185
|
id: "ask_phone",
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
instructions: "Ask for phone number (optional)",
|
|
187
|
+
collect: ["phoneNumber"],
|
|
188
188
|
})
|
|
189
|
-
.
|
|
189
|
+
.nextStep({
|
|
190
190
|
id: "ask_industry",
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
instructions: "Ask for industry",
|
|
192
|
+
collect: ["industry"],
|
|
193
193
|
})
|
|
194
|
-
.
|
|
194
|
+
.nextStep({
|
|
195
195
|
id: "confirm_details",
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
instructions: "Confirm all details",
|
|
197
|
+
requires: ["fullName", "email", "companyName"],
|
|
198
198
|
})
|
|
199
|
-
.
|
|
199
|
+
.nextStep({
|
|
200
200
|
id: "complete_onboarding",
|
|
201
|
-
|
|
201
|
+
instructions:
|
|
202
202
|
"Thank you! Your account is set up. You will receive a confirmation email shortly.",
|
|
203
203
|
})
|
|
204
|
-
.
|
|
204
|
+
.nextStep({ step: END_ROUTE });
|
|
205
205
|
|
|
206
206
|
/**
|
|
207
207
|
* Create or load session from your custom database
|
|
@@ -218,9 +218,9 @@ async function example() {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
/**
|
|
221
|
-
* Convert database session to agent
|
|
221
|
+
* Convert database session to agent SessionStep
|
|
222
222
|
*/
|
|
223
|
-
let agentSession:
|
|
223
|
+
let agentSession: SessionStep<OnboardingData>;
|
|
224
224
|
|
|
225
225
|
if (dbSession.currentRoute && dbSession.collectedData) {
|
|
226
226
|
// Restore existing session from database
|
|
@@ -233,23 +233,22 @@ async function example() {
|
|
|
233
233
|
dbSession.collectedData?.currentRouteTitle || dbSession.currentRoute,
|
|
234
234
|
enteredAt: new Date(),
|
|
235
235
|
},
|
|
236
|
-
|
|
236
|
+
currentStep: dbSession.currentStep
|
|
237
237
|
? {
|
|
238
|
-
id: dbSession.
|
|
239
|
-
description: dbSession.collectedData?.
|
|
238
|
+
id: dbSession.currentStep,
|
|
239
|
+
description: dbSession.collectedData?.currentStepDescription,
|
|
240
240
|
enteredAt: new Date(),
|
|
241
241
|
}
|
|
242
242
|
: undefined,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
(dbSession.collectedData?.extractedByRoute as Record<
|
|
243
|
+
data: (dbSession.collectedData?.data as Partial<OnboardingData>) || {},
|
|
244
|
+
dataByRoute:
|
|
245
|
+
(dbSession.collectedData?.dataByRoute as Record<
|
|
247
246
|
string,
|
|
248
247
|
Partial<OnboardingData>
|
|
249
248
|
>) || {},
|
|
250
249
|
routeHistory:
|
|
251
250
|
(dbSession.collectedData
|
|
252
|
-
?.routeHistory as
|
|
251
|
+
?.routeHistory as SessionStep<OnboardingData>["routeHistory"]) || [],
|
|
253
252
|
metadata: {
|
|
254
253
|
sessionId: dbSession.id,
|
|
255
254
|
userId,
|
|
@@ -262,12 +261,12 @@ async function example() {
|
|
|
262
261
|
console.log("✅ Session restored:", {
|
|
263
262
|
sessionId: agentSession.metadata?.sessionId,
|
|
264
263
|
currentRoute: agentSession.currentRoute?.title,
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
currentStep: agentSession.currentStep?.id,
|
|
265
|
+
data: agentSession.data,
|
|
267
266
|
});
|
|
268
267
|
} else {
|
|
269
|
-
// Create new session
|
|
270
|
-
console.log("🆕 Creating new session
|
|
268
|
+
// Create new session step
|
|
269
|
+
console.log("🆕 Creating new session step...");
|
|
271
270
|
|
|
272
271
|
agentSession = createSession<OnboardingData>(dbSession.id, {
|
|
273
272
|
sessionId: dbSession.id,
|
|
@@ -304,7 +303,7 @@ async function example() {
|
|
|
304
303
|
});
|
|
305
304
|
|
|
306
305
|
console.log("🤖 Agent:", response1.message);
|
|
307
|
-
console.log("📊
|
|
306
|
+
console.log("📊 Data so far:", response1.session?.data);
|
|
308
307
|
|
|
309
308
|
// Save agent message to database
|
|
310
309
|
await db.createMessage({
|
|
@@ -313,18 +312,18 @@ async function example() {
|
|
|
313
312
|
role: "agent",
|
|
314
313
|
content: response1.message,
|
|
315
314
|
route: response1.session?.currentRoute?.id,
|
|
316
|
-
|
|
315
|
+
step: response1.session?.currentStep?.id,
|
|
317
316
|
});
|
|
318
317
|
|
|
319
|
-
// Manually save session
|
|
318
|
+
// Manually save session step back to database
|
|
320
319
|
await db.updateSession(dbSession.id, {
|
|
321
320
|
currentRoute: response1.session?.currentRoute?.id,
|
|
322
|
-
|
|
321
|
+
currentStep: response1.session?.currentStep?.id,
|
|
323
322
|
collectedData: {
|
|
324
|
-
|
|
323
|
+
data: response1.session?.data,
|
|
325
324
|
routeHistory: response1.session?.routeHistory,
|
|
326
325
|
currentRouteTitle: response1.session?.currentRoute?.title,
|
|
327
|
-
|
|
326
|
+
currentStepDescription: response1.session?.currentStep?.description,
|
|
328
327
|
metadata: response1.session?.metadata,
|
|
329
328
|
},
|
|
330
329
|
});
|
|
@@ -360,7 +359,7 @@ async function example() {
|
|
|
360
359
|
});
|
|
361
360
|
|
|
362
361
|
console.log("🤖 Agent:", response2.message);
|
|
363
|
-
console.log("📊
|
|
362
|
+
console.log("📊 Data so far:", response2.session?.data);
|
|
364
363
|
|
|
365
364
|
await db.createMessage({
|
|
366
365
|
sessionId: dbSession.id,
|
|
@@ -368,18 +367,18 @@ async function example() {
|
|
|
368
367
|
role: "agent",
|
|
369
368
|
content: response2.message,
|
|
370
369
|
route: response2.session?.currentRoute?.id,
|
|
371
|
-
|
|
370
|
+
step: response2.session?.currentStep?.id,
|
|
372
371
|
});
|
|
373
372
|
|
|
374
|
-
// Save session
|
|
373
|
+
// Save session step
|
|
375
374
|
await db.updateSession(dbSession.id, {
|
|
376
375
|
currentRoute: response2.session?.currentRoute?.id,
|
|
377
|
-
|
|
376
|
+
currentStep: response2.session?.currentStep?.id,
|
|
378
377
|
collectedData: {
|
|
379
|
-
|
|
378
|
+
data: response2.session?.data,
|
|
380
379
|
routeHistory: response2.session?.routeHistory,
|
|
381
380
|
currentRouteTitle: response2.session?.currentRoute?.title,
|
|
382
|
-
|
|
381
|
+
currentStepDescription: response2.session?.currentStep?.description,
|
|
383
382
|
metadata: response2.session?.metadata,
|
|
384
383
|
},
|
|
385
384
|
});
|
|
@@ -391,7 +390,7 @@ async function example() {
|
|
|
391
390
|
console.log("\n✅ Onboarding Complete!");
|
|
392
391
|
// In a real app, you would now trigger the next steps,
|
|
393
392
|
// like sending a welcome email, creating an account, etc.
|
|
394
|
-
await processOnboarding(response2.session?.
|
|
393
|
+
await processOnboarding(response2.session?.data);
|
|
395
394
|
}
|
|
396
395
|
|
|
397
396
|
/**
|
|
@@ -404,8 +403,8 @@ async function example() {
|
|
|
404
403
|
const reloadedDbSession = await db.findSession(dbSession.id);
|
|
405
404
|
if (!reloadedDbSession) throw new Error("Session not found");
|
|
406
405
|
|
|
407
|
-
// Reconstruct session
|
|
408
|
-
const recoveredSession:
|
|
406
|
+
// Reconstruct session step
|
|
407
|
+
const recoveredSession: SessionStep<OnboardingData> = {
|
|
409
408
|
currentRoute: reloadedDbSession.currentRoute
|
|
410
409
|
? {
|
|
411
410
|
id: reloadedDbSession.currentRoute,
|
|
@@ -415,24 +414,23 @@ async function example() {
|
|
|
415
414
|
enteredAt: new Date(),
|
|
416
415
|
}
|
|
417
416
|
: undefined,
|
|
418
|
-
|
|
417
|
+
currentStep: reloadedDbSession.currentStep
|
|
419
418
|
? {
|
|
420
|
-
id: reloadedDbSession.
|
|
421
|
-
description: reloadedDbSession.collectedData?.
|
|
419
|
+
id: reloadedDbSession.currentStep,
|
|
420
|
+
description: reloadedDbSession.collectedData?.currentStepDescription,
|
|
422
421
|
enteredAt: new Date(),
|
|
423
422
|
}
|
|
424
423
|
: undefined,
|
|
425
|
-
|
|
426
|
-
(reloadedDbSession.collectedData?.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
(reloadedDbSession.collectedData?.extractedByRoute as Record<
|
|
424
|
+
data:
|
|
425
|
+
(reloadedDbSession.collectedData?.data as Partial<OnboardingData>) || {},
|
|
426
|
+
dataByRoute:
|
|
427
|
+
(reloadedDbSession.collectedData?.dataByRoute as Record<
|
|
430
428
|
string,
|
|
431
429
|
Partial<OnboardingData>
|
|
432
430
|
>) || {},
|
|
433
431
|
routeHistory:
|
|
434
432
|
(reloadedDbSession.collectedData
|
|
435
|
-
?.routeHistory as
|
|
433
|
+
?.routeHistory as SessionStep<OnboardingData>["routeHistory"]) || [],
|
|
436
434
|
metadata: {
|
|
437
435
|
sessionId: reloadedDbSession.id,
|
|
438
436
|
userId,
|
|
@@ -444,8 +442,8 @@ async function example() {
|
|
|
444
442
|
console.log("✅ Session recovered from database:", {
|
|
445
443
|
sessionId: recoveredSession.metadata?.sessionId,
|
|
446
444
|
currentRoute: recoveredSession.currentRoute?.title,
|
|
447
|
-
|
|
448
|
-
|
|
445
|
+
currentStep: recoveredSession.currentStep?.id,
|
|
446
|
+
data: recoveredSession.data,
|
|
449
447
|
});
|
|
450
448
|
|
|
451
449
|
// Load message history
|
|
@@ -486,28 +484,28 @@ async function advancedExample() {
|
|
|
486
484
|
model: "models/gemini-2.0-flash-exp",
|
|
487
485
|
}),
|
|
488
486
|
hooks: {
|
|
489
|
-
// Validate and enrich
|
|
490
|
-
|
|
491
|
-
console.log("🔄 Data
|
|
487
|
+
// Validate and enrich collected data
|
|
488
|
+
onDataUpdate: async (data, previous) => {
|
|
489
|
+
console.log("🔄 Data collected, validating...");
|
|
492
490
|
|
|
493
491
|
// Normalize email
|
|
494
|
-
if (
|
|
495
|
-
|
|
492
|
+
if (data.email) {
|
|
493
|
+
data.email = data.email.toLowerCase().trim();
|
|
496
494
|
}
|
|
497
495
|
|
|
498
496
|
// Normalize phone
|
|
499
|
-
if (
|
|
500
|
-
|
|
497
|
+
if (data.phoneNumber) {
|
|
498
|
+
data.phoneNumber = data.phoneNumber.replace(/\D/g, "");
|
|
501
499
|
}
|
|
502
500
|
|
|
503
|
-
return
|
|
501
|
+
return data;
|
|
504
502
|
},
|
|
505
503
|
},
|
|
506
504
|
});
|
|
507
505
|
|
|
508
506
|
const route = agent.createRoute<OnboardingData>({
|
|
509
507
|
title: "Onboarding",
|
|
510
|
-
|
|
508
|
+
schema: {
|
|
511
509
|
type: "object",
|
|
512
510
|
properties: {
|
|
513
511
|
fullName: { type: "string" },
|
|
@@ -519,10 +517,10 @@ async function advancedExample() {
|
|
|
519
517
|
},
|
|
520
518
|
});
|
|
521
519
|
|
|
522
|
-
route.
|
|
520
|
+
route.initialStep.nextStep({
|
|
523
521
|
id: "collect_all",
|
|
524
|
-
|
|
525
|
-
|
|
522
|
+
instructions: "Collect all information",
|
|
523
|
+
collect: ["fullName", "email", "companyName", "phoneNumber"],
|
|
526
524
|
});
|
|
527
525
|
|
|
528
526
|
// Create database session
|
|
@@ -549,18 +547,18 @@ async function advancedExample() {
|
|
|
549
547
|
});
|
|
550
548
|
|
|
551
549
|
console.log("🤖 Agent:", response.message);
|
|
552
|
-
console.log("📊 Normalized data:", response.session?.
|
|
550
|
+
console.log("📊 Normalized data:", response.session?.data);
|
|
553
551
|
// Shows: { email: "alice@example.com", phoneNumber: "5551234567", ... }
|
|
554
552
|
|
|
555
553
|
// Save to database
|
|
556
554
|
await db.updateSession(dbSession.id, {
|
|
557
555
|
currentRoute: response.session?.currentRoute?.id,
|
|
558
|
-
|
|
556
|
+
currentStep: response.session?.currentStep?.id,
|
|
559
557
|
collectedData: {
|
|
560
|
-
|
|
558
|
+
data: response.session?.data,
|
|
561
559
|
routeHistory: response.session?.routeHistory,
|
|
562
560
|
currentRouteTitle: response.session?.currentRoute?.title,
|
|
563
|
-
|
|
561
|
+
currentStepDescription: response.session?.currentStep?.description,
|
|
564
562
|
metadata: response.session?.metadata,
|
|
565
563
|
},
|
|
566
564
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Example: Declarative Agent Configuration with Session
|
|
2
|
+
* Example: Declarative Agent Configuration with Session Step
|
|
3
3
|
*
|
|
4
4
|
* This example demonstrates how to configure an entire agent
|
|
5
5
|
* using declarative syntax in the constructor, including:
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Guidelines (behavior rules)
|
|
8
8
|
* - Capabilities
|
|
9
9
|
* - Routes with data extraction schemas and custom IDs
|
|
10
|
-
* - Session
|
|
10
|
+
* - Session step management for multi-turn conversations
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
type Guideline,
|
|
22
22
|
type Capability,
|
|
23
23
|
type RouteOptions,
|
|
24
|
-
|
|
24
|
+
END_ROUTE,
|
|
25
25
|
} from "../src/index";
|
|
26
26
|
|
|
27
27
|
// Context type
|
|
@@ -80,9 +80,9 @@ const getLabResults = defineTool<
|
|
|
80
80
|
{ report: string; status: string }
|
|
81
81
|
>({
|
|
82
82
|
name: "get_lab_results",
|
|
83
|
-
handler: async ({ context,
|
|
84
|
-
// Tools can now access
|
|
85
|
-
const labData =
|
|
83
|
+
handler: async ({ context, data }) => {
|
|
84
|
+
// Tools can now access collected data
|
|
85
|
+
const labData = data as Partial<LabData>;
|
|
86
86
|
if (labData?.testType) {
|
|
87
87
|
return {
|
|
88
88
|
data: {
|
|
@@ -105,9 +105,9 @@ const getLabResults = defineTool<
|
|
|
105
105
|
|
|
106
106
|
const scheduleAppointment = defineTool<HealthcareContext>({
|
|
107
107
|
name: "schedule_appointment",
|
|
108
|
-
handler: async ({ context,
|
|
109
|
-
// Tools can access
|
|
110
|
-
const appointment =
|
|
108
|
+
handler: async ({ context, data }) => {
|
|
109
|
+
// Tools can access data appointment data
|
|
110
|
+
const appointment = data as Partial<AppointmentData>;
|
|
111
111
|
if (!appointment?.preferredDate || !appointment?.preferredTime) {
|
|
112
112
|
return { data: { confirmation: "Please provide appointment details" } };
|
|
113
113
|
}
|
|
@@ -179,7 +179,7 @@ const routes: RouteOptions[] = [
|
|
|
179
179
|
title: "Schedule Appointment",
|
|
180
180
|
description: "Helps the patient schedule an appointment",
|
|
181
181
|
conditions: ["The patient wants to schedule an appointment"],
|
|
182
|
-
|
|
182
|
+
schema: {
|
|
183
183
|
type: "object",
|
|
184
184
|
properties: {
|
|
185
185
|
appointmentType: {
|
|
@@ -219,29 +219,29 @@ const routes: RouteOptions[] = [
|
|
|
219
219
|
steps: [
|
|
220
220
|
{
|
|
221
221
|
id: "ask_appointment_type",
|
|
222
|
-
|
|
222
|
+
instructions:
|
|
223
223
|
"What type of appointment do you need? (checkup, consultation, or followup)",
|
|
224
|
-
|
|
224
|
+
collect: ["appointmentType"],
|
|
225
225
|
},
|
|
226
226
|
{
|
|
227
227
|
id: "ask_date_time",
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
instructions: "When would you like to come in?",
|
|
229
|
+
collect: ["preferredDate", "preferredTime"],
|
|
230
|
+
requires: ["appointmentType"],
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
233
|
id: "ask_symptoms",
|
|
234
|
-
|
|
235
|
-
|
|
234
|
+
instructions: "Are you experiencing any symptoms?",
|
|
235
|
+
collect: ["symptoms"],
|
|
236
236
|
},
|
|
237
237
|
{
|
|
238
238
|
id: "confirm_appointment",
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
tool: scheduleAppointment,
|
|
240
|
+
requires: ["preferredDate", "preferredTime"],
|
|
241
241
|
},
|
|
242
242
|
{
|
|
243
243
|
id: "final_confirmation",
|
|
244
|
-
|
|
244
|
+
instructions:
|
|
245
245
|
"Your appointment is confirmed. You will receive a notification shortly.",
|
|
246
246
|
},
|
|
247
247
|
],
|
|
@@ -251,7 +251,7 @@ const routes: RouteOptions[] = [
|
|
|
251
251
|
title: "Check Lab Results",
|
|
252
252
|
description: "Retrieves and explains patient lab results",
|
|
253
253
|
conditions: ["The patient wants to see their lab results"],
|
|
254
|
-
|
|
254
|
+
schema: {
|
|
255
255
|
type: "object",
|
|
256
256
|
properties: {
|
|
257
257
|
testType: {
|
|
@@ -283,7 +283,7 @@ const routes: RouteOptions[] = [
|
|
|
283
283
|
title: "General Healthcare Questions",
|
|
284
284
|
description: "Answer general healthcare questions",
|
|
285
285
|
conditions: ["Patient asks general healthcare questions"],
|
|
286
|
-
// No
|
|
286
|
+
// No schema - stepless Q&A
|
|
287
287
|
},
|
|
288
288
|
] as RouteOptions[];
|
|
289
289
|
|
|
@@ -320,9 +320,9 @@ agent
|
|
|
320
320
|
synonyms: ["virtual visit", "video appointment"],
|
|
321
321
|
});
|
|
322
322
|
|
|
323
|
-
// Example usage with session
|
|
323
|
+
// Example usage with session step
|
|
324
324
|
async function main() {
|
|
325
|
-
// Initialize session
|
|
325
|
+
// Initialize session step
|
|
326
326
|
let session = createSession<AppointmentData | LabData>();
|
|
327
327
|
|
|
328
328
|
// Create events with custom timestamps (useful for historical data)
|
|
@@ -338,12 +338,12 @@ async function main() {
|
|
|
338
338
|
const response = await agent.respond({ history, session });
|
|
339
339
|
console.log("Agent:", response.message);
|
|
340
340
|
console.log("Route chosen:", response.session?.currentRoute?.title);
|
|
341
|
-
console.log("
|
|
341
|
+
console.log("Collected data:", response.session?.data);
|
|
342
342
|
|
|
343
|
-
// Session
|
|
343
|
+
// Session step is updated with progress
|
|
344
344
|
session = response.session!;
|
|
345
345
|
|
|
346
|
-
// Turn 2 - Continue conversation with session
|
|
346
|
+
// Turn 2 - Continue conversation with session step
|
|
347
347
|
if (response.session?.currentRoute?.title === "Schedule Appointment") {
|
|
348
348
|
const history2 = [
|
|
349
349
|
...history,
|
|
@@ -357,26 +357,26 @@ async function main() {
|
|
|
357
357
|
|
|
358
358
|
const response2 = await agent.respond({ history: history2, session });
|
|
359
359
|
console.log("Agent:", response2.message);
|
|
360
|
-
console.log("Updated
|
|
360
|
+
console.log("Updated data:", response2.session?.data);
|
|
361
361
|
|
|
362
362
|
// Session tracks the appointment booking progress
|
|
363
|
-
console.log("Current
|
|
363
|
+
console.log("Current step:", response2.session?.currentStep?.id);
|
|
364
364
|
|
|
365
365
|
// Check for route completion
|
|
366
366
|
if (response2.isRouteComplete && response2.session) {
|
|
367
367
|
console.log("\n✅ Appointment scheduling complete!");
|
|
368
368
|
await sendAppointmentConfirmation(
|
|
369
|
-
agent.
|
|
369
|
+
agent.getData(response2.session.id) as AppointmentData
|
|
370
370
|
);
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
// Note: Custom IDs ensure consistency across server restarts
|
|
375
|
-
// Session
|
|
375
|
+
// Session step enables:
|
|
376
376
|
// - Tracking conversation progress across turns
|
|
377
377
|
// - Extracting structured data throughout conversation
|
|
378
378
|
// - Always-on routing that respects user intent changes
|
|
379
|
-
// -
|
|
379
|
+
// - Step recovery for resuming conversations
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Domain Scoping Example
|
|
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 domain scoping to restrict which tools
|
|
6
6
|
* can EXECUTE in different conversation routes for security and isolation.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* available everywhere. Use domains when you need security and organization.
|
|
10
10
|
*
|
|
11
11
|
* Key Concept: The AI never sees tools. Domains control which tools can
|
|
12
|
-
* execute automatically when triggered by the
|
|
12
|
+
* execute automatically when triggered by the step machine or guidelines.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import {
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
createMessageEvent,
|
|
18
18
|
EventSource,
|
|
19
19
|
createSession,
|
|
20
|
-
|
|
20
|
+
END_ROUTE,
|
|
21
21
|
defineTool,
|
|
22
22
|
} from "../src/index";
|
|
23
23
|
import { OpenRouterProvider } from "../src/providers";
|
|
@@ -108,8 +108,8 @@ const scheduleEventTool = defineTool({
|
|
|
108
108
|
id: "scheduleEvent",
|
|
109
109
|
name: "scheduleEvent",
|
|
110
110
|
description: "Schedules an event in the calendar",
|
|
111
|
-
handler: async ({
|
|
112
|
-
const { title, date, description } =
|
|
111
|
+
handler: async ({ data }) => {
|
|
112
|
+
const { title, date, description } = data as {
|
|
113
113
|
title: string;
|
|
114
114
|
date: string;
|
|
115
115
|
description: string;
|
|
@@ -124,7 +124,7 @@ agent.createRoute<{ title: string; date: string; description: string }>({
|
|
|
124
124
|
description: "Book and manage appointments",
|
|
125
125
|
conditions: ["User wants to schedule, view, or cancel events"],
|
|
126
126
|
domains: ["calendar"], // ✅ Only calendar tools available
|
|
127
|
-
|
|
127
|
+
schema: {
|
|
128
128
|
type: "object",
|
|
129
129
|
properties: {
|
|
130
130
|
title: { type: "string" },
|
|
@@ -135,22 +135,22 @@ agent.createRoute<{ title: string; date: string; description: string }>({
|
|
|
135
135
|
},
|
|
136
136
|
steps: [
|
|
137
137
|
{
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
instructions: "What is the title of the meeting?",
|
|
139
|
+
collect: ["title"],
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
instructions: "When would you like to schedule it?",
|
|
143
|
+
collect: ["date"],
|
|
144
144
|
},
|
|
145
145
|
{
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
instructions: "Any description for the meeting?",
|
|
147
|
+
collect: ["description"],
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
|
-
|
|
150
|
+
tool: scheduleEventTool,
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
|
-
|
|
153
|
+
instructions: "The meeting has been scheduled.",
|
|
154
154
|
},
|
|
155
155
|
],
|
|
156
156
|
});
|
|
@@ -190,7 +190,7 @@ async function demonstrateScoping() {
|
|
|
190
190
|
}),
|
|
191
191
|
];
|
|
192
192
|
|
|
193
|
-
// Initialize session
|
|
193
|
+
// Initialize session step for multi-turn conversation
|
|
194
194
|
let session = createSession();
|
|
195
195
|
|
|
196
196
|
const response1 = await agent.respond({ history: history1, session });
|
|
@@ -219,7 +219,7 @@ async function demonstrateScoping() {
|
|
|
219
219
|
if (response2.isRouteComplete) {
|
|
220
220
|
console.log("\n✅ Meeting scheduling complete!");
|
|
221
221
|
await sendMeetingInvite(
|
|
222
|
-
agent.
|
|
222
|
+
agent.getData(response2.session?.id) as {
|
|
223
223
|
title: string;
|
|
224
224
|
date: string;
|
|
225
225
|
}
|
|
@@ -270,7 +270,7 @@ console.log(`
|
|
|
270
270
|
- Data Collection route cannot execute calendar.scheduleEvent()
|
|
271
271
|
- Each route has minimum necessary tool permissions
|
|
272
272
|
- Prevents prompt injection attacks from calling sensitive tools
|
|
273
|
-
- Session
|
|
273
|
+
- Session step ensures domain scoping persists across turns
|
|
274
274
|
|
|
275
275
|
🎯 Isolation Benefits:
|
|
276
276
|
- Route execution is isolated - tools can't cross boundaries
|
|
@@ -283,7 +283,7 @@ console.log(`
|
|
|
283
283
|
- Easy to audit what each route can execute
|
|
284
284
|
- Better debugging when tools are called
|
|
285
285
|
- Self-documenting security model
|
|
286
|
-
- Session
|
|
286
|
+
- Session step tracks domain-scoped conversations
|
|
287
287
|
`);
|
|
288
288
|
|
|
289
289
|
// Inspect route configurations
|