@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
|
@@ -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
|
|
|
@@ -133,7 +133,7 @@ async function example() {
|
|
|
133
133
|
name: "Onboarding Assistant",
|
|
134
134
|
description: "Help new customers get started",
|
|
135
135
|
goal: "Collect customer information efficiently",
|
|
136
|
-
|
|
136
|
+
provider: new GeminiProvider({
|
|
137
137
|
apiKey: process.env.GEMINI_API_KEY!,
|
|
138
138
|
model: "models/gemini-2.0-flash-exp",
|
|
139
139
|
}),
|
|
@@ -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
|
|
@@ -481,33 +479,33 @@ async function advancedExample() {
|
|
|
481
479
|
|
|
482
480
|
const agent = new Agent({
|
|
483
481
|
name: "Smart Onboarding",
|
|
484
|
-
|
|
482
|
+
provider: new GeminiProvider({
|
|
485
483
|
apiKey: process.env.GEMINI_API_KEY!,
|
|
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
|
|
|
@@ -296,7 +296,7 @@ const agent = new Agent<HealthcareContext>({
|
|
|
296
296
|
patientId: "p_12345",
|
|
297
297
|
patientName: "Alice Johnson",
|
|
298
298
|
},
|
|
299
|
-
|
|
299
|
+
provider: new GeminiProvider({
|
|
300
300
|
apiKey: process.env.GEMINI_API_KEY || "demo-key",
|
|
301
301
|
model: "models/gemini-2.5-flash",
|
|
302
302
|
}),
|
|
@@ -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
|
/**
|