@falai/agent 0.9.0-alpha-1 ā 0.9.0-alpha-2
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 +52 -24
- package/dist/cjs/src/core/Agent.d.ts.map +1 -1
- package/dist/cjs/src/core/Agent.js +266 -39
- 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/ResponsePipeline.d.ts +66 -38
- package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/src/core/ResponsePipeline.js +71 -3
- 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/types/agent.d.ts +41 -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/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/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 +52 -24
- package/dist/src/core/Agent.d.ts.map +1 -1
- package/dist/src/core/Agent.js +266 -39
- 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/ResponsePipeline.d.ts +66 -38
- package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/src/core/ResponsePipeline.js +71 -3
- 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/types/agent.d.ts +41 -21
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/agent.js.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/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 +3 -3
- package/docs/api/README.md +35 -4
- package/docs/api/overview.md +166 -12
- 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/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 +28 -23
- 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/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 +418 -128
- package/src/core/PersistenceManager.ts +51 -27
- package/src/core/PromptComposer.ts +1 -1
- package/src/core/ResponseEngine.ts +21 -19
- package/src/core/ResponsePipeline.ts +174 -59
- 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/types/agent.ts +46 -23
- 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/session.ts +6 -31
|
@@ -15,21 +15,35 @@ import {
|
|
|
15
15
|
type SessionState,
|
|
16
16
|
} from "../../src/index";
|
|
17
17
|
|
|
18
|
-
// Type definitions for our
|
|
19
|
-
interface
|
|
18
|
+
// Type definitions for our unified data collection
|
|
19
|
+
interface UnifiedBookingData {
|
|
20
|
+
// Booking fields
|
|
20
21
|
hotelName: string;
|
|
21
22
|
date: string;
|
|
22
23
|
guests: number;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
interface FeedbackData {
|
|
24
|
+
// Feedback fields
|
|
26
25
|
rating: number;
|
|
27
26
|
comments?: string;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
async function main() {
|
|
31
|
-
//
|
|
32
|
-
const
|
|
30
|
+
// Define unified schema for both booking and feedback data
|
|
31
|
+
const unifiedSchema = {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
// Booking fields
|
|
35
|
+
hotelName: { type: "string" },
|
|
36
|
+
date: { type: "string" },
|
|
37
|
+
guests: { type: "number" },
|
|
38
|
+
// Feedback fields
|
|
39
|
+
rating: { type: "number", minimum: 1, maximum: 5 },
|
|
40
|
+
comments: { type: "string" },
|
|
41
|
+
},
|
|
42
|
+
required: ["hotelName", "date", "guests"], // Only booking fields are required initially
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Create agent with unified schema
|
|
46
|
+
const agent = new Agent<unknown, UnifiedBookingData>({
|
|
33
47
|
name: "HotelBot",
|
|
34
48
|
description: "A hotel booking assistant with feedback collection",
|
|
35
49
|
provider: new GeminiProvider({
|
|
@@ -37,22 +51,16 @@ async function main() {
|
|
|
37
51
|
model: "models/gemini-2.5-flash",
|
|
38
52
|
}),
|
|
39
53
|
debug: true,
|
|
54
|
+
schema: unifiedSchema,
|
|
40
55
|
});
|
|
41
56
|
|
|
42
57
|
// Route 1: Hotel Booking with automatic transition to feedback
|
|
43
|
-
agent.createRoute
|
|
58
|
+
agent.createRoute({
|
|
44
59
|
title: "Book Hotel",
|
|
45
60
|
description: "Collects hotel booking information",
|
|
46
61
|
conditions: ["User wants to book a hotel"],
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
properties: {
|
|
50
|
-
hotelName: { type: "string" },
|
|
51
|
-
date: { type: "string" },
|
|
52
|
-
guests: { type: "number" },
|
|
53
|
-
},
|
|
54
|
-
required: ["hotelName", "date", "guests"],
|
|
55
|
-
},
|
|
62
|
+
// NEW: Required fields for route completion
|
|
63
|
+
requiredFields: ["hotelName", "date", "guests"],
|
|
56
64
|
// Sequential steps for booking flow
|
|
57
65
|
steps: [
|
|
58
66
|
{
|
|
@@ -60,7 +68,7 @@ async function main() {
|
|
|
60
68
|
description: "Ask for hotel preference",
|
|
61
69
|
prompt: "Which hotel would you like to book?",
|
|
62
70
|
collect: ["hotelName"],
|
|
63
|
-
skipIf: (data: Partial<
|
|
71
|
+
skipIf: (data: Partial<UnifiedBookingData>) => !!data.hotelName,
|
|
64
72
|
},
|
|
65
73
|
{
|
|
66
74
|
id: "ask_date",
|
|
@@ -68,7 +76,7 @@ async function main() {
|
|
|
68
76
|
prompt: "What date would you like to book for?",
|
|
69
77
|
collect: ["date"],
|
|
70
78
|
requires: ["hotelName"],
|
|
71
|
-
skipIf: (data: Partial<
|
|
79
|
+
skipIf: (data: Partial<UnifiedBookingData>) => !!data.date,
|
|
72
80
|
},
|
|
73
81
|
{
|
|
74
82
|
id: "ask_guests",
|
|
@@ -76,7 +84,7 @@ async function main() {
|
|
|
76
84
|
prompt: "How many guests will be staying?",
|
|
77
85
|
collect: ["guests"],
|
|
78
86
|
requires: ["hotelName", "date"],
|
|
79
|
-
skipIf: (data: Partial<
|
|
87
|
+
skipIf: (data: Partial<UnifiedBookingData>) => data.guests !== undefined,
|
|
80
88
|
},
|
|
81
89
|
{
|
|
82
90
|
id: "confirm_booking",
|
|
@@ -91,18 +99,14 @@ async function main() {
|
|
|
91
99
|
});
|
|
92
100
|
|
|
93
101
|
// Route 2: Feedback Collection
|
|
94
|
-
agent.createRoute
|
|
102
|
+
agent.createRoute({
|
|
95
103
|
title: "Collect Feedback",
|
|
96
104
|
description: "Collects user feedback after booking",
|
|
97
105
|
conditions: ["User wants to provide feedback"],
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
comments: { type: "string" },
|
|
103
|
-
},
|
|
104
|
-
required: ["rating"],
|
|
105
|
-
},
|
|
106
|
+
// NEW: Required fields for route completion
|
|
107
|
+
requiredFields: ["rating"],
|
|
108
|
+
// NEW: Optional fields that enhance the experience
|
|
109
|
+
optionalFields: ["comments"],
|
|
106
110
|
// Sequential steps for feedback collection
|
|
107
111
|
steps: [
|
|
108
112
|
{
|
|
@@ -110,7 +114,7 @@ async function main() {
|
|
|
110
114
|
description: "Ask for rating",
|
|
111
115
|
prompt: "How would you rate your booking experience from 1 to 5?",
|
|
112
116
|
collect: ["rating"],
|
|
113
|
-
skipIf: (data: Partial<
|
|
117
|
+
skipIf: (data: Partial<UnifiedBookingData>) => data.rating !== undefined,
|
|
114
118
|
},
|
|
115
119
|
{
|
|
116
120
|
id: "ask_comments",
|
|
@@ -153,7 +157,7 @@ async function main() {
|
|
|
153
157
|
"Pending transition?",
|
|
154
158
|
response1.session?.pendingTransition?.targetRouteId
|
|
155
159
|
);
|
|
156
|
-
console.log("
|
|
160
|
+
console.log("Collected data:", response1.session?.data);
|
|
157
161
|
|
|
158
162
|
session = response1.session;
|
|
159
163
|
history = [
|
|
@@ -203,7 +207,7 @@ async function main() {
|
|
|
203
207
|
const response3 = await agent.respond({ history, session });
|
|
204
208
|
console.log("\nBot:", response3.message);
|
|
205
209
|
console.log("Current route:", response3.session?.currentRoute?.title);
|
|
206
|
-
console.log("
|
|
210
|
+
console.log("Collected data:", response3.session?.data);
|
|
207
211
|
console.log("Route complete?", response3.isRouteComplete);
|
|
208
212
|
|
|
209
213
|
console.log("\n=== Manual Transition Example ===\n");
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
type Guideline,
|
|
18
18
|
type Tool,
|
|
19
19
|
type RouteOptions,
|
|
20
|
-
History,
|
|
21
20
|
} from "../../src/index";
|
|
22
21
|
|
|
23
22
|
// Context type
|
|
@@ -42,7 +41,7 @@ interface LabData {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
// Define tools using the new Tool interface
|
|
45
|
-
const getInsuranceProviders: Tool<HealthcareContext, [], string[]> = {
|
|
44
|
+
const getInsuranceProviders: Tool<HealthcareContext, HealthcareData, [], string[]> = {
|
|
46
45
|
id: "healthcare_insurance_providers",
|
|
47
46
|
description: "Retrieves list of accepted insurance providers",
|
|
48
47
|
parameters: {
|
|
@@ -58,6 +57,7 @@ const getInsuranceProviders: Tool<HealthcareContext, [], string[]> = {
|
|
|
58
57
|
|
|
59
58
|
const getAvailableSlots: Tool<
|
|
60
59
|
HealthcareContext,
|
|
60
|
+
HealthcareData,
|
|
61
61
|
[],
|
|
62
62
|
{ date: string; time: string }[]
|
|
63
63
|
> = {
|
|
@@ -80,6 +80,7 @@ const getAvailableSlots: Tool<
|
|
|
80
80
|
|
|
81
81
|
const getLabResults: Tool<
|
|
82
82
|
HealthcareContext,
|
|
83
|
+
HealthcareData,
|
|
83
84
|
[],
|
|
84
85
|
{ report: string; status: string }
|
|
85
86
|
> = {
|
|
@@ -89,19 +90,12 @@ const getLabResults: Tool<
|
|
|
89
90
|
type: "object",
|
|
90
91
|
properties: {},
|
|
91
92
|
},
|
|
92
|
-
handler: ({
|
|
93
|
-
context,
|
|
94
|
-
data,
|
|
95
|
-
}: {
|
|
96
|
-
context: HealthcareContext;
|
|
97
|
-
data?: Partial<LabData>;
|
|
98
|
-
}) => {
|
|
93
|
+
handler: ({ context, data }) => {
|
|
99
94
|
// Tools can access collected data and context
|
|
100
|
-
|
|
101
|
-
if (labData?.testType) {
|
|
95
|
+
if (data?.testType) {
|
|
102
96
|
return {
|
|
103
97
|
data: {
|
|
104
|
-
report: `${
|
|
98
|
+
report: `${data.testType} results for ${context.patientName}`,
|
|
105
99
|
status: "All values within normal range",
|
|
106
100
|
},
|
|
107
101
|
};
|
|
@@ -118,6 +112,7 @@ const getLabResults: Tool<
|
|
|
118
112
|
|
|
119
113
|
const scheduleAppointment: Tool<
|
|
120
114
|
HealthcareContext,
|
|
115
|
+
HealthcareData,
|
|
121
116
|
[],
|
|
122
117
|
{ confirmation: string }
|
|
123
118
|
> = {
|
|
@@ -127,21 +122,15 @@ const scheduleAppointment: Tool<
|
|
|
127
122
|
type: "object",
|
|
128
123
|
properties: {},
|
|
129
124
|
},
|
|
130
|
-
handler: ({
|
|
131
|
-
data,
|
|
132
|
-
}: {
|
|
133
|
-
context: HealthcareContext;
|
|
134
|
-
data?: Partial<AppointmentData>;
|
|
135
|
-
}) => {
|
|
125
|
+
handler: ({ data }) => {
|
|
136
126
|
// Tools access collected appointment data
|
|
137
|
-
|
|
138
|
-
if (!appointment?.preferredDate || !appointment?.preferredTime) {
|
|
127
|
+
if (!data?.preferredDate || !data?.preferredTime) {
|
|
139
128
|
return { data: { confirmation: "Please provide appointment details" } };
|
|
140
129
|
}
|
|
141
130
|
|
|
142
131
|
return {
|
|
143
132
|
data: {
|
|
144
|
-
confirmation: `Appointment scheduled for ${
|
|
133
|
+
confirmation: `Appointment scheduled for ${data.preferredDate} at ${data.preferredTime}`,
|
|
145
134
|
},
|
|
146
135
|
};
|
|
147
136
|
},
|
|
@@ -186,40 +175,16 @@ const guidelines: Guideline<HealthcareContext>[] = [
|
|
|
186
175
|
},
|
|
187
176
|
];
|
|
188
177
|
|
|
189
|
-
const routes: RouteOptions<HealthcareContext>[] = [
|
|
178
|
+
const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
|
|
190
179
|
{
|
|
191
180
|
id: "route_schedule_appointment",
|
|
192
181
|
title: "Schedule Appointment",
|
|
193
182
|
description: "Helps the patient schedule an appointment",
|
|
194
183
|
conditions: ["The patient wants to schedule an appointment"],
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
type: "string",
|
|
200
|
-
enum: ["checkup", "consultation", "followup"],
|
|
201
|
-
description: "Type of appointment needed",
|
|
202
|
-
},
|
|
203
|
-
preferredDate: {
|
|
204
|
-
type: "string",
|
|
205
|
-
description: "Preferred appointment date",
|
|
206
|
-
},
|
|
207
|
-
preferredTime: {
|
|
208
|
-
type: "string",
|
|
209
|
-
description: "Preferred appointment time",
|
|
210
|
-
},
|
|
211
|
-
symptoms: {
|
|
212
|
-
type: "string",
|
|
213
|
-
description: "Description of symptoms (if applicable)",
|
|
214
|
-
},
|
|
215
|
-
urgency: {
|
|
216
|
-
type: "string",
|
|
217
|
-
enum: ["low", "medium", "high"],
|
|
218
|
-
default: "medium",
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
required: ["appointmentType", "preferredDate", "preferredTime"],
|
|
222
|
-
},
|
|
184
|
+
// NEW: Required fields for route completion (instead of schema)
|
|
185
|
+
requiredFields: ["appointmentType", "preferredDate", "preferredTime"],
|
|
186
|
+
// NEW: Optional fields that enhance the experience
|
|
187
|
+
optionalFields: ["symptoms", "urgency"],
|
|
223
188
|
guidelines: [
|
|
224
189
|
{
|
|
225
190
|
condition: "The patient says their visit is urgent",
|
|
@@ -249,7 +214,7 @@ const routes: RouteOptions<HealthcareContext>[] = [
|
|
|
249
214
|
description: "Ask about symptoms",
|
|
250
215
|
prompt: "Are you experiencing any symptoms?",
|
|
251
216
|
collect: ["symptoms"],
|
|
252
|
-
skipIf: (data: Partial<
|
|
217
|
+
skipIf: (data: Partial<HealthcareData>) =>
|
|
253
218
|
data.appointmentType === "checkup", // Skip for checkups
|
|
254
219
|
},
|
|
255
220
|
{
|
|
@@ -283,25 +248,10 @@ const routes: RouteOptions<HealthcareContext>[] = [
|
|
|
283
248
|
title: "Check Lab Results",
|
|
284
249
|
description: "Retrieves and explains patient lab results",
|
|
285
250
|
conditions: ["The patient wants to see their lab results"],
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
type: "string",
|
|
291
|
-
description: "Type of lab test",
|
|
292
|
-
},
|
|
293
|
-
testDate: {
|
|
294
|
-
type: "string",
|
|
295
|
-
description: "Date of the lab test",
|
|
296
|
-
},
|
|
297
|
-
resultsNeeded: {
|
|
298
|
-
type: "boolean",
|
|
299
|
-
default: true,
|
|
300
|
-
description: "Whether detailed results are needed",
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
required: ["testType"],
|
|
304
|
-
},
|
|
251
|
+
// NEW: Required fields for route completion
|
|
252
|
+
requiredFields: ["testType"],
|
|
253
|
+
// NEW: Optional fields
|
|
254
|
+
optionalFields: ["testDate", "resultsNeeded"],
|
|
305
255
|
guidelines: [
|
|
306
256
|
{
|
|
307
257
|
condition: "The patient presses for more conclusions about results",
|
|
@@ -316,12 +266,58 @@ const routes: RouteOptions<HealthcareContext>[] = [
|
|
|
316
266
|
title: "General Healthcare Questions",
|
|
317
267
|
description: "Answer general healthcare questions",
|
|
318
268
|
conditions: ["Patient asks general healthcare questions"],
|
|
319
|
-
// No
|
|
269
|
+
// No required fields - conversational Q&A
|
|
320
270
|
},
|
|
321
271
|
];
|
|
322
272
|
|
|
323
|
-
//
|
|
324
|
-
|
|
273
|
+
// Define a unified data schema for all healthcare interactions
|
|
274
|
+
interface HealthcareData extends AppointmentData, LabData {}
|
|
275
|
+
|
|
276
|
+
const healthcareSchema = {
|
|
277
|
+
type: "object",
|
|
278
|
+
properties: {
|
|
279
|
+
// Appointment fields
|
|
280
|
+
appointmentType: {
|
|
281
|
+
type: "string",
|
|
282
|
+
enum: ["checkup", "consultation", "followup"],
|
|
283
|
+
description: "Type of appointment needed",
|
|
284
|
+
},
|
|
285
|
+
preferredDate: {
|
|
286
|
+
type: "string",
|
|
287
|
+
description: "Preferred appointment date",
|
|
288
|
+
},
|
|
289
|
+
preferredTime: {
|
|
290
|
+
type: "string",
|
|
291
|
+
description: "Preferred appointment time",
|
|
292
|
+
},
|
|
293
|
+
symptoms: {
|
|
294
|
+
type: "string",
|
|
295
|
+
description: "Description of symptoms (if applicable)",
|
|
296
|
+
},
|
|
297
|
+
urgency: {
|
|
298
|
+
type: "string",
|
|
299
|
+
enum: ["low", "medium", "high"],
|
|
300
|
+
default: "medium",
|
|
301
|
+
},
|
|
302
|
+
// Lab fields
|
|
303
|
+
testType: {
|
|
304
|
+
type: "string",
|
|
305
|
+
description: "Type of lab test",
|
|
306
|
+
},
|
|
307
|
+
testDate: {
|
|
308
|
+
type: "string",
|
|
309
|
+
description: "Date of the lab test",
|
|
310
|
+
},
|
|
311
|
+
resultsNeeded: {
|
|
312
|
+
type: "boolean",
|
|
313
|
+
default: true,
|
|
314
|
+
description: "Whether detailed results are needed",
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Create the fully configured agent with agent-level schema
|
|
320
|
+
const agent = new Agent<HealthcareContext, HealthcareData>({
|
|
325
321
|
name: "HealthBot",
|
|
326
322
|
description: "A compassionate healthcare assistant",
|
|
327
323
|
goal: "Provide helpful information and assist with appointments",
|
|
@@ -333,6 +329,8 @@ const agent = new Agent<HealthcareContext>({
|
|
|
333
329
|
apiKey: process.env.GEMINI_API_KEY || "demo-key",
|
|
334
330
|
model: "models/gemini-2.5-flash",
|
|
335
331
|
}),
|
|
332
|
+
// NEW: Agent-level schema
|
|
333
|
+
schema: healthcareSchema,
|
|
336
334
|
// Declarative initialization
|
|
337
335
|
terms,
|
|
338
336
|
guidelines,
|
|
@@ -381,7 +379,7 @@ async function main() {
|
|
|
381
379
|
});
|
|
382
380
|
|
|
383
381
|
console.log("š¤ Agent:", response2.message);
|
|
384
|
-
console.log("š Collected data:", agent.session.getData
|
|
382
|
+
console.log("š Collected data:", agent.session.getData());
|
|
385
383
|
console.log("š Current step:", response2.session?.currentStep?.id);
|
|
386
384
|
|
|
387
385
|
await agent.session.addMessage("assistant", response2.message);
|
|
@@ -396,7 +394,7 @@ async function main() {
|
|
|
396
394
|
});
|
|
397
395
|
|
|
398
396
|
console.log("š¤ Agent:", response3.message);
|
|
399
|
-
console.log("š Updated data:", agent.session.getData
|
|
397
|
+
console.log("š Updated data:", agent.session.getData());
|
|
400
398
|
console.log("š Current step:", response3.session?.currentStep?.id);
|
|
401
399
|
|
|
402
400
|
await agent.session.addMessage("assistant", response3.message);
|
|
@@ -405,7 +403,7 @@ async function main() {
|
|
|
405
403
|
if (response3.isRouteComplete && response3.session) {
|
|
406
404
|
console.log("\nā
Appointment scheduling complete!");
|
|
407
405
|
await sendAppointmentConfirmation(
|
|
408
|
-
agent.
|
|
406
|
+
agent.getCollectedData() as HealthcareData
|
|
409
407
|
);
|
|
410
408
|
}
|
|
411
409
|
|
|
@@ -424,9 +422,9 @@ async function main() {
|
|
|
424
422
|
|
|
425
423
|
/**
|
|
426
424
|
* Mock function to send an appointment confirmation.
|
|
427
|
-
* @param data - The
|
|
425
|
+
* @param data - The healthcare data.
|
|
428
426
|
*/
|
|
429
|
-
async function sendAppointmentConfirmation(data:
|
|
427
|
+
async function sendAppointmentConfirmation(data: HealthcareData) {
|
|
430
428
|
console.log("\n" + "=".repeat(60));
|
|
431
429
|
console.log("š Sending Appointment Confirmation...");
|
|
432
430
|
console.log("=".repeat(60));
|
|
@@ -24,7 +24,7 @@ interface UserProfileData {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// Define a tool that uses the collected data
|
|
27
|
-
const saveUserProfile: Tool<unknown, [], string
|
|
27
|
+
const saveUserProfile: Tool<unknown, UserProfileData, [], string> = {
|
|
28
28
|
id: "save_user_profile",
|
|
29
29
|
description: "Save the collected user profile information",
|
|
30
30
|
parameters: {
|
|
@@ -37,24 +37,12 @@ const saveUserProfile: Tool<unknown, [], string, UserProfileData> = {
|
|
|
37
37
|
// Simulate saving to database
|
|
38
38
|
console.log("Profile data:", data);
|
|
39
39
|
|
|
40
|
-
const userData = data as Partial<UserProfileData>;
|
|
41
40
|
return {
|
|
42
|
-
data: `Profile saved successfully! Welcome ${
|
|
41
|
+
data: `Profile saved successfully! Welcome ${data?.name}!`,
|
|
43
42
|
};
|
|
44
43
|
},
|
|
45
44
|
};
|
|
46
45
|
|
|
47
|
-
// Create the agent
|
|
48
|
-
const agent = new Agent({
|
|
49
|
-
name: "ProfileBot",
|
|
50
|
-
description:
|
|
51
|
-
"A bot that collects user profile information using schema-driven extraction",
|
|
52
|
-
provider: new GeminiProvider({
|
|
53
|
-
apiKey: process.env.GEMINI_API_KEY!,
|
|
54
|
-
model: "models/gemini-2.5-flash",
|
|
55
|
-
}),
|
|
56
|
-
});
|
|
57
|
-
|
|
58
46
|
// Define the schema for data validation and extraction
|
|
59
47
|
const userProfileSchema = {
|
|
60
48
|
type: "object",
|
|
@@ -98,11 +86,27 @@ const userProfileSchema = {
|
|
|
98
86
|
required: ["name", "email"],
|
|
99
87
|
};
|
|
100
88
|
|
|
89
|
+
// Create the agent with agent-level schema
|
|
90
|
+
const agent = new Agent<unknown, UserProfileData>({
|
|
91
|
+
name: "ProfileBot",
|
|
92
|
+
description:
|
|
93
|
+
"A bot that collects user profile information using schema-driven extraction",
|
|
94
|
+
provider: new GeminiProvider({
|
|
95
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
96
|
+
model: "models/gemini-2.5-flash",
|
|
97
|
+
}),
|
|
98
|
+
// NEW: Agent-level schema definition
|
|
99
|
+
schema: userProfileSchema,
|
|
100
|
+
});
|
|
101
|
+
|
|
101
102
|
// Create a route that collects profile information step by step
|
|
102
|
-
agent.createRoute
|
|
103
|
+
agent.createRoute({
|
|
103
104
|
title: "User Profile Collection",
|
|
104
105
|
description: "Collect comprehensive user profile information",
|
|
105
|
-
|
|
106
|
+
// NEW: Required fields for route completion (instead of schema)
|
|
107
|
+
requiredFields: ["name", "email"],
|
|
108
|
+
// NEW: Optional fields that enhance the experience
|
|
109
|
+
optionalFields: ["age", "interests", "preferredContact", "newsletterOptIn"],
|
|
106
110
|
// Use sequential steps for a linear flow with smart skipIf conditions
|
|
107
111
|
steps: [
|
|
108
112
|
{
|