@falai/agent 0.9.0-alpha-1 ā 0.9.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 +34 -22
- package/dist/cjs/src/core/Agent.d.ts +77 -59
- package/dist/cjs/src/core/Agent.d.ts.map +1 -1
- package/dist/cjs/src/core/Agent.js +284 -1060
- package/dist/cjs/src/core/Agent.js.map +1 -1
- package/dist/cjs/src/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/src/core/PersistenceManager.js +48 -25
- package/dist/cjs/src/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/src/core/PromptComposer.d.ts +1 -1
- package/dist/cjs/src/core/PromptComposer.d.ts.map +1 -1
- package/dist/cjs/src/core/PromptComposer.js.map +1 -1
- package/dist/cjs/src/core/ResponseEngine.d.ts +13 -12
- package/dist/cjs/src/core/ResponseEngine.d.ts.map +1 -1
- package/dist/cjs/src/core/ResponseEngine.js +4 -4
- package/dist/cjs/src/core/ResponseEngine.js.map +1 -1
- package/dist/cjs/src/core/ResponseModal.d.ts +205 -0
- package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
- package/dist/cjs/src/core/ResponseModal.js +1328 -0
- package/dist/cjs/src/core/ResponseModal.js.map +1 -0
- package/dist/cjs/src/core/ResponsePipeline.d.ts +66 -38
- package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/src/core/ResponsePipeline.js +72 -4
- package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/src/core/Route.d.ts +24 -5
- package/dist/cjs/src/core/Route.d.ts.map +1 -1
- package/dist/cjs/src/core/Route.js +45 -1
- package/dist/cjs/src/core/Route.js.map +1 -1
- package/dist/cjs/src/core/RoutingEngine.d.ts +31 -6
- package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/src/core/RoutingEngine.js +113 -9
- package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
- package/dist/cjs/src/core/SessionManager.d.ts +14 -4
- package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
- package/dist/cjs/src/core/SessionManager.js +25 -5
- package/dist/cjs/src/core/SessionManager.js.map +1 -1
- package/dist/cjs/src/core/Step.d.ts +10 -10
- package/dist/cjs/src/core/Step.d.ts.map +1 -1
- package/dist/cjs/src/core/Step.js.map +1 -1
- package/dist/cjs/src/core/ToolExecutor.d.ts +4 -2
- package/dist/cjs/src/core/ToolExecutor.d.ts.map +1 -1
- package/dist/cjs/src/core/ToolExecutor.js +13 -3
- package/dist/cjs/src/core/ToolExecutor.js.map +1 -1
- package/dist/cjs/src/index.d.ts +3 -1
- package/dist/cjs/src/index.d.ts.map +1 -1
- package/dist/cjs/src/index.js +7 -1
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/types/agent.d.ts +42 -21
- package/dist/cjs/src/types/agent.d.ts.map +1 -1
- package/dist/cjs/src/types/agent.js.map +1 -1
- package/dist/cjs/src/types/ai.d.ts +1 -1
- package/dist/cjs/src/types/ai.d.ts.map +1 -1
- package/dist/cjs/src/types/index.d.ts +1 -1
- package/dist/cjs/src/types/index.d.ts.map +1 -1
- package/dist/cjs/src/types/index.js.map +1 -1
- package/dist/cjs/src/types/persistence.d.ts +0 -1
- package/dist/cjs/src/types/persistence.d.ts.map +1 -1
- package/dist/cjs/src/types/route.d.ts +22 -16
- package/dist/cjs/src/types/route.d.ts.map +1 -1
- package/dist/cjs/src/types/session.d.ts +6 -11
- package/dist/cjs/src/types/session.d.ts.map +1 -1
- package/dist/cjs/src/types/tool.d.ts +12 -6
- package/dist/cjs/src/types/tool.d.ts.map +1 -1
- package/dist/cjs/src/utils/clone.d.ts.map +1 -1
- package/dist/cjs/src/utils/clone.js +0 -4
- package/dist/cjs/src/utils/clone.js.map +1 -1
- package/dist/cjs/src/utils/history.d.ts +30 -1
- package/dist/cjs/src/utils/history.d.ts.map +1 -1
- package/dist/cjs/src/utils/history.js +169 -23
- package/dist/cjs/src/utils/history.js.map +1 -1
- package/dist/cjs/src/utils/index.d.ts +1 -1
- package/dist/cjs/src/utils/index.d.ts.map +1 -1
- package/dist/cjs/src/utils/index.js +5 -1
- package/dist/cjs/src/utils/index.js.map +1 -1
- package/dist/cjs/src/utils/session.d.ts +2 -2
- package/dist/cjs/src/utils/session.d.ts.map +1 -1
- package/dist/cjs/src/utils/session.js +6 -26
- package/dist/cjs/src/utils/session.js.map +1 -1
- package/dist/src/core/Agent.d.ts +77 -59
- package/dist/src/core/Agent.d.ts.map +1 -1
- package/dist/src/core/Agent.js +285 -1061
- package/dist/src/core/Agent.js.map +1 -1
- package/dist/src/core/PersistenceManager.d.ts.map +1 -1
- package/dist/src/core/PersistenceManager.js +48 -25
- package/dist/src/core/PersistenceManager.js.map +1 -1
- package/dist/src/core/PromptComposer.d.ts +1 -1
- package/dist/src/core/PromptComposer.d.ts.map +1 -1
- package/dist/src/core/PromptComposer.js.map +1 -1
- package/dist/src/core/ResponseEngine.d.ts +13 -12
- package/dist/src/core/ResponseEngine.d.ts.map +1 -1
- package/dist/src/core/ResponseEngine.js +4 -4
- package/dist/src/core/ResponseEngine.js.map +1 -1
- package/dist/src/core/ResponseModal.d.ts +205 -0
- package/dist/src/core/ResponseModal.d.ts.map +1 -0
- package/dist/src/core/ResponseModal.js +1323 -0
- package/dist/src/core/ResponseModal.js.map +1 -0
- package/dist/src/core/ResponsePipeline.d.ts +66 -38
- package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/src/core/ResponsePipeline.js +72 -4
- package/dist/src/core/ResponsePipeline.js.map +1 -1
- package/dist/src/core/Route.d.ts +24 -5
- package/dist/src/core/Route.d.ts.map +1 -1
- package/dist/src/core/Route.js +45 -1
- package/dist/src/core/Route.js.map +1 -1
- package/dist/src/core/RoutingEngine.d.ts +31 -6
- package/dist/src/core/RoutingEngine.d.ts.map +1 -1
- package/dist/src/core/RoutingEngine.js +113 -9
- package/dist/src/core/RoutingEngine.js.map +1 -1
- package/dist/src/core/SessionManager.d.ts +14 -4
- package/dist/src/core/SessionManager.d.ts.map +1 -1
- package/dist/src/core/SessionManager.js +25 -5
- package/dist/src/core/SessionManager.js.map +1 -1
- package/dist/src/core/Step.d.ts +10 -10
- package/dist/src/core/Step.d.ts.map +1 -1
- package/dist/src/core/Step.js.map +1 -1
- package/dist/src/core/ToolExecutor.d.ts +4 -2
- package/dist/src/core/ToolExecutor.d.ts.map +1 -1
- package/dist/src/core/ToolExecutor.js +13 -3
- package/dist/src/core/ToolExecutor.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/types/agent.d.ts +42 -21
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/agent.js.map +1 -1
- package/dist/src/types/ai.d.ts +1 -1
- package/dist/src/types/ai.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/persistence.d.ts +0 -1
- package/dist/src/types/persistence.d.ts.map +1 -1
- package/dist/src/types/route.d.ts +22 -16
- package/dist/src/types/route.d.ts.map +1 -1
- package/dist/src/types/session.d.ts +6 -11
- package/dist/src/types/session.d.ts.map +1 -1
- package/dist/src/types/tool.d.ts +12 -6
- package/dist/src/types/tool.d.ts.map +1 -1
- package/dist/src/utils/clone.d.ts.map +1 -1
- package/dist/src/utils/clone.js +0 -4
- package/dist/src/utils/clone.js.map +1 -1
- package/dist/src/utils/history.d.ts +30 -1
- package/dist/src/utils/history.d.ts.map +1 -1
- package/dist/src/utils/history.js +165 -23
- package/dist/src/utils/history.js.map +1 -1
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/session.d.ts +2 -2
- package/dist/src/utils/session.d.ts.map +1 -1
- package/dist/src/utils/session.js +6 -26
- package/dist/src/utils/session.js.map +1 -1
- package/docs/README.md +5 -4
- package/docs/api/README.md +195 -4
- package/docs/api/overview.md +232 -13
- package/docs/core/agent/README.md +162 -17
- package/docs/core/agent/context-management.md +39 -15
- package/docs/core/agent/session-management.md +49 -16
- package/docs/core/ai-integration/prompt-composition.md +38 -14
- package/docs/core/ai-integration/response-processing.md +28 -17
- package/docs/core/conversation-flows/data-collection.md +103 -25
- package/docs/core/conversation-flows/route-dsl.md +45 -22
- package/docs/core/conversation-flows/routes.md +74 -18
- package/docs/core/conversation-flows/step-transitions.md +3 -3
- package/docs/core/conversation-flows/steps.md +39 -15
- package/docs/core/routing/intelligent-routing.md +18 -9
- package/docs/core/tools/tool-definition.md +8 -8
- package/docs/core/tools/tool-execution.md +26 -26
- package/docs/core/tools/tool-scoping.md +5 -5
- package/docs/guides/getting-started/README.md +54 -32
- package/docs/guides/migration/README.md +72 -0
- package/docs/guides/migration/response-modal-refactor.md +518 -0
- package/examples/advanced-patterns/knowledge-based-agent.ts +37 -28
- package/examples/advanced-patterns/persistent-onboarding.ts +70 -41
- package/examples/advanced-patterns/route-lifecycle-hooks.ts +28 -2
- package/examples/advanced-patterns/streaming-responses.ts +197 -119
- package/examples/ai-providers/anthropic-integration.ts +40 -33
- package/examples/ai-providers/openai-integration.ts +25 -25
- package/examples/conversation-flows/completion-transitions.ts +36 -32
- package/examples/core-concepts/basic-agent.ts +76 -78
- package/examples/core-concepts/modern-streaming-api.ts +309 -0
- package/examples/core-concepts/schema-driven-extraction.ts +20 -16
- package/examples/core-concepts/session-management.ts +65 -53
- package/examples/integrations/database-integration.ts +49 -34
- package/examples/integrations/healthcare-integration.ts +96 -91
- package/examples/integrations/search-integration.ts +79 -82
- package/examples/integrations/server-session-management.ts +25 -17
- package/examples/persistence/database-persistence.ts +61 -45
- package/examples/persistence/memory-sessions.ts +52 -63
- package/examples/persistence/redis-persistence.ts +81 -95
- package/examples/tools/basic-tools.ts +73 -62
- package/examples/tools/data-enrichment-tools.ts +52 -44
- package/package.json +1 -1
- package/src/core/Agent.ts +396 -1499
- package/src/core/PersistenceManager.ts +51 -27
- package/src/core/PromptComposer.ts +1 -1
- package/src/core/ResponseEngine.ts +21 -19
- package/src/core/ResponseModal.ts +1722 -0
- package/src/core/ResponsePipeline.ts +175 -60
- package/src/core/Route.ts +58 -6
- package/src/core/RoutingEngine.ts +174 -27
- package/src/core/SessionManager.ts +32 -8
- package/src/core/Step.ts +20 -12
- package/src/core/ToolExecutor.ts +19 -5
- package/src/index.ts +11 -0
- package/src/types/agent.ts +47 -23
- package/src/types/ai.ts +1 -1
- package/src/types/index.ts +2 -0
- package/src/types/persistence.ts +0 -1
- package/src/types/route.ts +22 -16
- package/src/types/session.ts +6 -12
- package/src/types/tool.ts +15 -9
- package/src/utils/clone.ts +6 -8
- package/src/utils/history.ts +190 -27
- package/src/utils/index.ts +4 -0
- package/src/utils/session.ts +6 -31
|
@@ -124,8 +124,21 @@ async function example() {
|
|
|
124
124
|
const userId = "user_123";
|
|
125
125
|
const sessionId = "session_user123_onboarding";
|
|
126
126
|
|
|
127
|
+
// Define onboarding schema
|
|
128
|
+
const onboardingSchema = {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
fullName: { type: "string" },
|
|
132
|
+
email: { type: "string" },
|
|
133
|
+
companyName: { type: "string" },
|
|
134
|
+
phoneNumber: { type: "string" },
|
|
135
|
+
industry: { type: "string" },
|
|
136
|
+
},
|
|
137
|
+
required: ["fullName", "email", "companyName"],
|
|
138
|
+
};
|
|
139
|
+
|
|
127
140
|
// Create agent with SessionManager (no persistence adapter)
|
|
128
|
-
const agent = new Agent({
|
|
141
|
+
const agent = new Agent<unknown, OnboardingData>({
|
|
129
142
|
name: "Onboarding Assistant",
|
|
130
143
|
description: "Help new customers get started",
|
|
131
144
|
goal: "Collect customer information efficiently",
|
|
@@ -133,28 +146,23 @@ async function example() {
|
|
|
133
146
|
apiKey: process.env.GEMINI_API_KEY!,
|
|
134
147
|
model: "models/gemini-2.5-flash",
|
|
135
148
|
}),
|
|
149
|
+
// NEW: Agent-level schema
|
|
150
|
+
schema: onboardingSchema,
|
|
136
151
|
// No persistence - we'll sync manually with our database
|
|
137
152
|
});
|
|
138
153
|
|
|
139
154
|
// Create onboarding route
|
|
140
|
-
const onboardingRoute = agent.createRoute
|
|
155
|
+
const onboardingRoute = agent.createRoute({
|
|
141
156
|
title: "Customer Onboarding",
|
|
142
157
|
description: "Collect customer information",
|
|
143
158
|
conditions: [
|
|
144
159
|
"User is a new customer",
|
|
145
160
|
"User needs to set up their account",
|
|
146
161
|
],
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
email: { type: "string" },
|
|
152
|
-
companyName: { type: "string" },
|
|
153
|
-
phoneNumber: { type: "string" },
|
|
154
|
-
industry: { type: "string" },
|
|
155
|
-
},
|
|
156
|
-
required: ["fullName", "email", "companyName"],
|
|
157
|
-
},
|
|
162
|
+
// NEW: Required fields for route completion
|
|
163
|
+
requiredFields: ["fullName", "email", "companyName"],
|
|
164
|
+
// NEW: Optional fields that enhance the experience
|
|
165
|
+
optionalFields: ["phoneNumber", "industry"],
|
|
158
166
|
});
|
|
159
167
|
|
|
160
168
|
// Define steps with custom IDs
|
|
@@ -251,7 +259,7 @@ async function example() {
|
|
|
251
259
|
console.log("ā
Session synchronized:", {
|
|
252
260
|
sessionId: agent.session.id,
|
|
253
261
|
historyLength: agent.session.getHistory().length,
|
|
254
|
-
data: agent.session.getData
|
|
262
|
+
data: agent.session.getData(),
|
|
255
263
|
});
|
|
256
264
|
|
|
257
265
|
/**
|
|
@@ -267,7 +275,7 @@ async function example() {
|
|
|
267
275
|
});
|
|
268
276
|
|
|
269
277
|
console.log("š¤ Agent:", response1.message);
|
|
270
|
-
console.log("š Data collected:", agent.session.getData
|
|
278
|
+
console.log("š Data collected:", agent.session.getData());
|
|
271
279
|
|
|
272
280
|
// Add agent response to SessionManager
|
|
273
281
|
await agent.session.addMessage("assistant", response1.message);
|
|
@@ -286,7 +294,7 @@ async function example() {
|
|
|
286
294
|
});
|
|
287
295
|
|
|
288
296
|
console.log("š¤ Agent:", response2.message);
|
|
289
|
-
console.log("š Data collected:", agent.session.getData
|
|
297
|
+
console.log("š Data collected:", agent.session.getData());
|
|
290
298
|
|
|
291
299
|
await agent.session.addMessage("assistant", response2.message);
|
|
292
300
|
|
|
@@ -297,7 +305,7 @@ async function example() {
|
|
|
297
305
|
// Check for route completion
|
|
298
306
|
if (response2.isRouteComplete) {
|
|
299
307
|
console.log("\nā
Onboarding Complete!");
|
|
300
|
-
await processOnboarding(agent.session.getData
|
|
308
|
+
await processOnboarding(agent.session.getData());
|
|
301
309
|
}
|
|
302
310
|
|
|
303
311
|
/**
|
|
@@ -347,7 +355,7 @@ async function example() {
|
|
|
347
355
|
console.log("ā
Session recovered in new agent:", {
|
|
348
356
|
sessionId: newAgent.session.id,
|
|
349
357
|
historyLength: newAgent.session.getHistory().length,
|
|
350
|
-
data: newAgent.session.getData
|
|
358
|
+
data: newAgent.session.getData(),
|
|
351
359
|
});
|
|
352
360
|
|
|
353
361
|
// Continue conversation with recovered session
|
|
@@ -367,7 +375,7 @@ async function example() {
|
|
|
367
375
|
* Helper function to sync SessionManager state to custom database
|
|
368
376
|
*/
|
|
369
377
|
async function syncSessionToDatabase(
|
|
370
|
-
agent: Agent,
|
|
378
|
+
agent: Agent<unknown, OnboardingData>,
|
|
371
379
|
db: CustomDatabase,
|
|
372
380
|
sessionId: string,
|
|
373
381
|
userId: string
|
|
@@ -424,15 +432,28 @@ async function advancedExample() {
|
|
|
424
432
|
const db = new CustomDatabase();
|
|
425
433
|
const sessionId = "session_user456_smart_onboarding";
|
|
426
434
|
|
|
427
|
-
const
|
|
435
|
+
const smartOnboardingSchema = {
|
|
436
|
+
type: "object",
|
|
437
|
+
properties: {
|
|
438
|
+
fullName: { type: "string" },
|
|
439
|
+
email: { type: "string" },
|
|
440
|
+
companyName: { type: "string" },
|
|
441
|
+
phoneNumber: { type: "string" },
|
|
442
|
+
},
|
|
443
|
+
required: ["fullName", "email", "companyName"],
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
const agent = new Agent<unknown, OnboardingData>({
|
|
428
447
|
name: "Smart Onboarding",
|
|
429
448
|
provider: new GeminiProvider({
|
|
430
449
|
apiKey: process.env.GEMINI_API_KEY!,
|
|
431
450
|
model: "models/gemini-2.5-flash",
|
|
432
451
|
}),
|
|
452
|
+
// NEW: Agent-level schema
|
|
453
|
+
schema: smartOnboardingSchema,
|
|
433
454
|
hooks: {
|
|
434
455
|
// Validate and enrich collected data
|
|
435
|
-
onDataUpdate: (data: OnboardingData
|
|
456
|
+
onDataUpdate: (data: Partial<OnboardingData>, _previous: Partial<OnboardingData>) => {
|
|
436
457
|
console.log("š Data collected, validating...");
|
|
437
458
|
|
|
438
459
|
// Normalize email
|
|
@@ -450,18 +471,12 @@ async function advancedExample() {
|
|
|
450
471
|
},
|
|
451
472
|
});
|
|
452
473
|
|
|
453
|
-
const route = agent.createRoute
|
|
474
|
+
const route = agent.createRoute({
|
|
454
475
|
title: "Smart Onboarding",
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
email: { type: "string" },
|
|
460
|
-
companyName: { type: "string" },
|
|
461
|
-
phoneNumber: { type: "string" },
|
|
462
|
-
},
|
|
463
|
-
required: ["fullName", "email", "companyName"],
|
|
464
|
-
},
|
|
476
|
+
// NEW: Required fields for route completion
|
|
477
|
+
requiredFields: ["fullName", "email", "companyName"],
|
|
478
|
+
// NEW: Optional fields
|
|
479
|
+
optionalFields: ["phoneNumber"],
|
|
465
480
|
});
|
|
466
481
|
|
|
467
482
|
route.initialStep.nextStep({
|
|
@@ -492,7 +507,7 @@ async function advancedExample() {
|
|
|
492
507
|
});
|
|
493
508
|
|
|
494
509
|
console.log("š¤ Agent:", response.message);
|
|
495
|
-
console.log("š Normalized data:", agent.session.getData
|
|
510
|
+
console.log("š Normalized data:", agent.session.getData());
|
|
496
511
|
// Shows: { email: "alice@example.com", phoneNumber: "5551234567", ... }
|
|
497
512
|
|
|
498
513
|
await agent.session.addMessage("assistant", response.message);
|
|
@@ -518,7 +533,7 @@ async function serverEndpointExample() {
|
|
|
518
533
|
const { sessionId, userId, message } = req;
|
|
519
534
|
|
|
520
535
|
// Create agent with sessionId (loads existing or creates new)
|
|
521
|
-
const agent = new Agent({
|
|
536
|
+
const agent = new Agent<unknown, OnboardingData>({
|
|
522
537
|
name: "Customer Support",
|
|
523
538
|
provider: new GeminiProvider({
|
|
524
539
|
apiKey: process.env.GEMINI_API_KEY!,
|
|
@@ -39,7 +39,7 @@ interface SatisfactionData {
|
|
|
39
39
|
|
|
40
40
|
// Tools
|
|
41
41
|
|
|
42
|
-
const getUpcomingSlots: Tool<HealthcareContext, unknown[], unknown
|
|
42
|
+
const getUpcomingSlots: Tool<HealthcareContext, HealthcareData, unknown[], unknown> = {
|
|
43
43
|
id: "get_upcoming_slots",
|
|
44
44
|
name: "Available Appointment Slots",
|
|
45
45
|
description: "Get upcoming appointment slots",
|
|
@@ -52,7 +52,7 @@ const getUpcomingSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
|
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
const getLaterSlots: Tool<HealthcareContext, unknown[], unknown
|
|
55
|
+
const getLaterSlots: Tool<HealthcareContext, HealthcareData, unknown[], unknown> = {
|
|
56
56
|
id: "get_later_slots",
|
|
57
57
|
name: "Extended Appointment Slots",
|
|
58
58
|
description: "Get later appointment slots",
|
|
@@ -67,9 +67,9 @@ const getLaterSlots: Tool<HealthcareContext, unknown[], unknown, unknown> = {
|
|
|
67
67
|
|
|
68
68
|
const scheduleAppointment: Tool<
|
|
69
69
|
HealthcareContext,
|
|
70
|
+
HealthcareData,
|
|
70
71
|
unknown[],
|
|
71
|
-
unknown
|
|
72
|
-
AppointmentData
|
|
72
|
+
unknown
|
|
73
73
|
> = {
|
|
74
74
|
id: "schedule_appointment",
|
|
75
75
|
name: "Appointment Scheduler",
|
|
@@ -82,25 +82,24 @@ const scheduleAppointment: Tool<
|
|
|
82
82
|
required: ["datetime"],
|
|
83
83
|
},
|
|
84
84
|
handler: ({ data }) => {
|
|
85
|
-
|
|
86
|
-
if (!appointment?.preferredDate || !appointment?.preferredTime) {
|
|
85
|
+
if (!data?.preferredDate || !data?.preferredTime) {
|
|
87
86
|
return {
|
|
88
87
|
data: "Please specify preferred date and time for the appointment",
|
|
89
88
|
};
|
|
90
89
|
}
|
|
91
90
|
return {
|
|
92
|
-
data: `Appointment scheduled for ${
|
|
93
|
-
|
|
94
|
-
} for ${
|
|
91
|
+
data: `Appointment scheduled for ${data.preferredDate} at ${
|
|
92
|
+
data.preferredTime
|
|
93
|
+
} for ${data.appointmentReason || "consultation"}`,
|
|
95
94
|
};
|
|
96
95
|
},
|
|
97
96
|
};
|
|
98
97
|
|
|
99
98
|
const getLabResults: Tool<
|
|
100
99
|
HealthcareContext,
|
|
100
|
+
HealthcareData,
|
|
101
101
|
unknown[],
|
|
102
|
-
unknown
|
|
103
|
-
LabResultsData
|
|
102
|
+
unknown
|
|
104
103
|
> = {
|
|
105
104
|
id: "get_lab_results",
|
|
106
105
|
name: "Lab Results Retriever",
|
|
@@ -110,10 +109,9 @@ const getLabResults: Tool<
|
|
|
110
109
|
properties: {},
|
|
111
110
|
},
|
|
112
111
|
handler: ({ context, data }) => {
|
|
113
|
-
const labData = data as Partial<LabResultsData>;
|
|
114
112
|
return {
|
|
115
113
|
data: {
|
|
116
|
-
report: `Lab results for ${
|
|
114
|
+
report: `Lab results for ${data?.testType || "general"} tests`,
|
|
117
115
|
prognosis: "All tests are within the valid range",
|
|
118
116
|
patientName: context.patientName,
|
|
119
117
|
},
|
|
@@ -121,18 +119,79 @@ const getLabResults: Tool<
|
|
|
121
119
|
},
|
|
122
120
|
};
|
|
123
121
|
|
|
122
|
+
// Define unified healthcare data schema
|
|
123
|
+
interface HealthcareData extends AppointmentData, LabResultsData, SatisfactionData {}
|
|
124
|
+
|
|
125
|
+
const healthcareSchema = {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
// Appointment fields
|
|
129
|
+
appointmentReason: {
|
|
130
|
+
type: "string",
|
|
131
|
+
description: "Reason for the appointment",
|
|
132
|
+
},
|
|
133
|
+
urgency: {
|
|
134
|
+
type: "string",
|
|
135
|
+
enum: ["low", "medium", "high"],
|
|
136
|
+
default: "medium",
|
|
137
|
+
},
|
|
138
|
+
preferredTime: {
|
|
139
|
+
type: "string",
|
|
140
|
+
description: "Preferred time slot",
|
|
141
|
+
},
|
|
142
|
+
preferredDate: {
|
|
143
|
+
type: "string",
|
|
144
|
+
description: "Preferred date",
|
|
145
|
+
},
|
|
146
|
+
appointmentType: {
|
|
147
|
+
type: "string",
|
|
148
|
+
enum: ["checkup", "consultation", "followup"],
|
|
149
|
+
default: "consultation",
|
|
150
|
+
},
|
|
151
|
+
// Lab results fields
|
|
152
|
+
testType: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "Type of lab test",
|
|
155
|
+
},
|
|
156
|
+
testDate: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Date of the lab test",
|
|
159
|
+
},
|
|
160
|
+
resultsNeeded: {
|
|
161
|
+
type: "boolean",
|
|
162
|
+
default: true,
|
|
163
|
+
description: "Whether detailed results are needed",
|
|
164
|
+
},
|
|
165
|
+
// Satisfaction fields
|
|
166
|
+
rating: {
|
|
167
|
+
type: "number",
|
|
168
|
+
description: "Overall satisfaction rating 1-5",
|
|
169
|
+
},
|
|
170
|
+
easeOfScheduling: {
|
|
171
|
+
type: "number",
|
|
172
|
+
description: "Ease of scheduling process 1-5",
|
|
173
|
+
},
|
|
174
|
+
comments: {
|
|
175
|
+
type: "string",
|
|
176
|
+
description: "Optional feedback comments",
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
124
181
|
function createHealthcareAgent() {
|
|
125
182
|
const provider = new AnthropicProvider({
|
|
126
183
|
apiKey: process.env.ANTHROPIC_API_KEY || "test-key",
|
|
127
184
|
model: "claude-sonnet-4-5",
|
|
128
185
|
});
|
|
129
186
|
|
|
130
|
-
const agent = new Agent<HealthcareContext>({
|
|
187
|
+
const agent = new Agent<HealthcareContext, HealthcareData>({
|
|
131
188
|
name: "Healthcare Agent",
|
|
132
189
|
description: "Is empathetic and calming to the patient.",
|
|
133
190
|
identity:
|
|
134
191
|
"I am the Healthcare Agent, a compassionate AI assistant dedicated to providing excellent patient care. With deep knowledge of medical procedures and a focus on patient comfort, I'm here to help you navigate your healthcare journey with empathy and expertise.",
|
|
135
192
|
provider: provider,
|
|
193
|
+
// NEW: Agent-level schema
|
|
194
|
+
schema: healthcareSchema,
|
|
136
195
|
|
|
137
196
|
// Knowledge base with healthcare-specific information
|
|
138
197
|
knowledgeBase: {
|
|
@@ -200,7 +259,7 @@ function createHealthcareAgent() {
|
|
|
200
259
|
|
|
201
260
|
// Create scheduling route with data extraction schema
|
|
202
261
|
// NEW: Added onComplete to automatically transition to satisfaction survey after booking
|
|
203
|
-
const schedulingRoute = agent.createRoute
|
|
262
|
+
const schedulingRoute = agent.createRoute({
|
|
204
263
|
title: "Schedule an Appointment",
|
|
205
264
|
description: "Helps the patient find a time for their appointment.",
|
|
206
265
|
conditions: ["The patient wants to schedule an appointment"],
|
|
@@ -224,34 +283,10 @@ function createHealthcareAgent() {
|
|
|
224
283
|
description: "Remote healthcare consultation via video call or phone",
|
|
225
284
|
},
|
|
226
285
|
],
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
type: "string",
|
|
232
|
-
description: "Reason for the appointment",
|
|
233
|
-
},
|
|
234
|
-
urgency: {
|
|
235
|
-
type: "string",
|
|
236
|
-
enum: ["low", "medium", "high"],
|
|
237
|
-
default: "medium",
|
|
238
|
-
},
|
|
239
|
-
preferredTime: {
|
|
240
|
-
type: "string",
|
|
241
|
-
description: "Preferred time slot",
|
|
242
|
-
},
|
|
243
|
-
preferredDate: {
|
|
244
|
-
type: "string",
|
|
245
|
-
description: "Preferred date",
|
|
246
|
-
},
|
|
247
|
-
appointmentType: {
|
|
248
|
-
type: "string",
|
|
249
|
-
enum: ["checkup", "consultation", "followup"],
|
|
250
|
-
default: "consultation",
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
required: ["appointmentReason"],
|
|
254
|
-
},
|
|
286
|
+
// NEW: Required fields for route completion
|
|
287
|
+
requiredFields: ["appointmentReason"],
|
|
288
|
+
// NEW: Optional fields that enhance the experience
|
|
289
|
+
optionalFields: ["urgency", "preferredTime", "preferredDate", "appointmentType"],
|
|
255
290
|
// NEW: Automatically collect feedback after successful scheduling
|
|
256
291
|
onComplete: "Satisfaction Survey",
|
|
257
292
|
});
|
|
@@ -334,29 +369,14 @@ function createHealthcareAgent() {
|
|
|
334
369
|
});
|
|
335
370
|
|
|
336
371
|
// Create lab results route with data extraction schema
|
|
337
|
-
const labResultsRoute = agent.createRoute
|
|
372
|
+
const labResultsRoute = agent.createRoute({
|
|
338
373
|
title: "Lab Results",
|
|
339
374
|
description: "Retrieves the patient's lab results and explains them.",
|
|
340
375
|
conditions: ["The patient wants to see their lab results"],
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
type: "string",
|
|
346
|
-
description: "Type of lab test",
|
|
347
|
-
},
|
|
348
|
-
testDate: {
|
|
349
|
-
type: "string",
|
|
350
|
-
description: "Date of the lab test",
|
|
351
|
-
},
|
|
352
|
-
resultsNeeded: {
|
|
353
|
-
type: "boolean",
|
|
354
|
-
default: true,
|
|
355
|
-
description: "Whether detailed results are needed",
|
|
356
|
-
},
|
|
357
|
-
},
|
|
358
|
-
required: ["testType"],
|
|
359
|
-
},
|
|
376
|
+
// NEW: Required fields for route completion
|
|
377
|
+
requiredFields: ["testType"],
|
|
378
|
+
// NEW: Optional fields
|
|
379
|
+
optionalFields: ["testDate", "resultsNeeded"],
|
|
360
380
|
});
|
|
361
381
|
|
|
362
382
|
// Step 1: Collect test information
|
|
@@ -395,7 +415,7 @@ function createHealthcareAgent() {
|
|
|
395
415
|
});
|
|
396
416
|
|
|
397
417
|
// NEW: Satisfaction Survey route - collects feedback after appointment scheduling
|
|
398
|
-
const satisfactionRoute = agent.createRoute
|
|
418
|
+
const satisfactionRoute = agent.createRoute({
|
|
399
419
|
title: "Satisfaction Survey",
|
|
400
420
|
description: "Quick satisfaction survey after scheduling",
|
|
401
421
|
conditions: ["Collect patient satisfaction feedback"],
|
|
@@ -426,24 +446,10 @@ function createHealthcareAgent() {
|
|
|
426
446
|
positive: "Share with staff as recognition",
|
|
427
447
|
},
|
|
428
448
|
},
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
type: "number",
|
|
434
|
-
description: "Overall satisfaction rating 1-5",
|
|
435
|
-
},
|
|
436
|
-
easeOfScheduling: {
|
|
437
|
-
type: "number",
|
|
438
|
-
description: "Ease of scheduling process 1-5",
|
|
439
|
-
},
|
|
440
|
-
comments: {
|
|
441
|
-
type: "string",
|
|
442
|
-
description: "Optional feedback comments",
|
|
443
|
-
},
|
|
444
|
-
},
|
|
445
|
-
required: ["rating"],
|
|
446
|
-
},
|
|
449
|
+
// NEW: Required fields for route completion
|
|
450
|
+
requiredFields: ["rating"],
|
|
451
|
+
// NEW: Optional fields
|
|
452
|
+
optionalFields: ["easeOfScheduling", "comments"],
|
|
447
453
|
});
|
|
448
454
|
|
|
449
455
|
const askRating = satisfactionRoute.initialStep.nextStep({
|
|
@@ -512,14 +518,15 @@ async function main() {
|
|
|
512
518
|
// Turn 1: Patient wants to follow up
|
|
513
519
|
await agent.session.addMessage("user", "Hi, I need to follow up on my visit", "Patient");
|
|
514
520
|
|
|
521
|
+
const history = agent.session.getHistory()
|
|
515
522
|
const response1 = await agent.respond({
|
|
516
|
-
history
|
|
523
|
+
history,
|
|
517
524
|
});
|
|
518
525
|
|
|
519
526
|
console.log("Patient: Hi, I need to follow up on my visit");
|
|
520
527
|
console.log("Agent:", response1.message);
|
|
521
528
|
console.log("Route:", response1.session?.currentRoute?.title);
|
|
522
|
-
console.log("Data:", agent.session.getData
|
|
529
|
+
console.log("Data:", agent.session.getData());
|
|
523
530
|
|
|
524
531
|
await agent.session.addMessage("assistant", response1.message);
|
|
525
532
|
|
|
@@ -534,14 +541,12 @@ async function main() {
|
|
|
534
541
|
},
|
|
535
542
|
];
|
|
536
543
|
|
|
537
|
-
const response2 = await agent.respond({ history: history2
|
|
544
|
+
const response2 = await agent.respond({ history: history2 });
|
|
538
545
|
console.log("\nPatient: I need to schedule a checkup for next week");
|
|
539
546
|
console.log("Agent:", response2.message);
|
|
540
547
|
console.log("Updated data:", response2.session?.data);
|
|
541
548
|
console.log("Current step:", response2.session?.currentStep?.id);
|
|
542
549
|
|
|
543
|
-
// Update session again
|
|
544
|
-
session = response2.session!;
|
|
545
550
|
|
|
546
551
|
// NEW: Check if route is complete - will auto-transition to satisfaction survey
|
|
547
552
|
if (response2.isRouteComplete) {
|
|
@@ -563,7 +568,7 @@ async function main() {
|
|
|
563
568
|
},
|
|
564
569
|
];
|
|
565
570
|
|
|
566
|
-
const response3 = await agent.respond({ history: history3
|
|
571
|
+
const response3 = await agent.respond({ history: history3 });
|
|
567
572
|
console.log("\nPatient: Tuesday at 2 PM works for me.");
|
|
568
573
|
console.log("Agent:", response3.message);
|
|
569
574
|
console.log("Updated data:", response3.session?.data);
|
|
@@ -573,7 +578,7 @@ async function main() {
|
|
|
573
578
|
if (response3.isRouteComplete) {
|
|
574
579
|
console.log("\nā
Appointment scheduling complete!");
|
|
575
580
|
await sendAppointmentReminder(
|
|
576
|
-
agent.
|
|
581
|
+
agent.getCollectedData() as HealthcareData
|
|
577
582
|
);
|
|
578
583
|
}
|
|
579
584
|
}
|
|
@@ -581,9 +586,9 @@ async function main() {
|
|
|
581
586
|
|
|
582
587
|
/**
|
|
583
588
|
* Mock function to send an appointment reminder.
|
|
584
|
-
* @param data - The
|
|
589
|
+
* @param data - The healthcare data.
|
|
585
590
|
*/
|
|
586
|
-
async function sendAppointmentReminder(data:
|
|
591
|
+
async function sendAppointmentReminder(data: HealthcareData) {
|
|
587
592
|
console.log("\n" + "=".repeat(60));
|
|
588
593
|
console.log("š Sending Appointment Reminder...");
|
|
589
594
|
console.log("=".repeat(60));
|