@falai/agent 0.9.0-alpha-2 ā 0.9.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 +42 -34
- package/dist/cjs/src/core/Agent.d.ts +48 -44
- package/dist/cjs/src/core/Agent.d.ts.map +1 -1
- package/dist/cjs/src/core/Agent.js +151 -1110
- package/dist/cjs/src/core/Agent.js.map +1 -1
- package/dist/cjs/src/core/ResponseModal.d.ts +211 -0
- package/dist/cjs/src/core/ResponseModal.d.ts.map +1 -0
- package/dist/cjs/src/core/ResponseModal.js +1394 -0
- package/dist/cjs/src/core/ResponseModal.js.map +1 -0
- package/dist/cjs/src/core/ResponsePipeline.d.ts +8 -4
- package/dist/cjs/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/cjs/src/core/ResponsePipeline.js +48 -20
- package/dist/cjs/src/core/ResponsePipeline.js.map +1 -1
- package/dist/cjs/src/core/Route.d.ts +12 -5
- package/dist/cjs/src/core/Route.d.ts.map +1 -1
- package/dist/cjs/src/core/Route.js +26 -5
- package/dist/cjs/src/core/Route.js.map +1 -1
- package/dist/cjs/src/core/RoutingEngine.d.ts +5 -0
- package/dist/cjs/src/core/RoutingEngine.d.ts.map +1 -1
- package/dist/cjs/src/core/RoutingEngine.js +37 -25
- package/dist/cjs/src/core/RoutingEngine.js.map +1 -1
- package/dist/cjs/src/core/SessionManager.d.ts +9 -1
- package/dist/cjs/src/core/SessionManager.d.ts.map +1 -1
- package/dist/cjs/src/core/SessionManager.js +27 -5
- package/dist/cjs/src/core/SessionManager.js.map +1 -1
- package/dist/cjs/src/core/Step.d.ts +60 -7
- package/dist/cjs/src/core/Step.d.ts.map +1 -1
- package/dist/cjs/src/core/Step.js +151 -4
- package/dist/cjs/src/core/Step.js.map +1 -1
- package/dist/cjs/src/core/ToolManager.d.ts +234 -0
- package/dist/cjs/src/core/ToolManager.d.ts.map +1 -0
- package/dist/cjs/src/core/ToolManager.js +1117 -0
- package/dist/cjs/src/core/ToolManager.js.map +1 -0
- package/dist/cjs/src/index.d.ts +5 -4
- package/dist/cjs/src/index.d.ts.map +1 -1
- package/dist/cjs/src/index.js +11 -3
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/types/agent.d.ts +2 -1
- package/dist/cjs/src/types/agent.d.ts.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 +3 -2
- package/dist/cjs/src/types/index.d.ts.map +1 -1
- package/dist/cjs/src/types/index.js +3 -1
- package/dist/cjs/src/types/index.js.map +1 -1
- package/dist/cjs/src/types/route.d.ts +6 -4
- package/dist/cjs/src/types/route.d.ts.map +1 -1
- package/dist/cjs/src/types/tool.d.ts +84 -14
- package/dist/cjs/src/types/tool.d.ts.map +1 -1
- package/dist/cjs/src/types/tool.js +13 -0
- package/dist/cjs/src/types/tool.js.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/src/core/Agent.d.ts +48 -44
- package/dist/src/core/Agent.d.ts.map +1 -1
- package/dist/src/core/Agent.js +152 -1111
- package/dist/src/core/Agent.js.map +1 -1
- package/dist/src/core/ResponseModal.d.ts +211 -0
- package/dist/src/core/ResponseModal.d.ts.map +1 -0
- package/dist/src/core/ResponseModal.js +1389 -0
- package/dist/src/core/ResponseModal.js.map +1 -0
- package/dist/src/core/ResponsePipeline.d.ts +8 -4
- package/dist/src/core/ResponsePipeline.d.ts.map +1 -1
- package/dist/src/core/ResponsePipeline.js +48 -20
- package/dist/src/core/ResponsePipeline.js.map +1 -1
- package/dist/src/core/Route.d.ts +12 -5
- package/dist/src/core/Route.d.ts.map +1 -1
- package/dist/src/core/Route.js +26 -5
- package/dist/src/core/Route.js.map +1 -1
- package/dist/src/core/RoutingEngine.d.ts +5 -0
- package/dist/src/core/RoutingEngine.d.ts.map +1 -1
- package/dist/src/core/RoutingEngine.js +37 -25
- package/dist/src/core/RoutingEngine.js.map +1 -1
- package/dist/src/core/SessionManager.d.ts +9 -1
- package/dist/src/core/SessionManager.d.ts.map +1 -1
- package/dist/src/core/SessionManager.js +27 -5
- package/dist/src/core/SessionManager.js.map +1 -1
- package/dist/src/core/Step.d.ts +60 -7
- package/dist/src/core/Step.d.ts.map +1 -1
- package/dist/src/core/Step.js +151 -4
- package/dist/src/core/Step.js.map +1 -1
- package/dist/src/core/ToolManager.d.ts +234 -0
- package/dist/src/core/ToolManager.d.ts.map +1 -0
- package/dist/src/core/ToolManager.js +1111 -0
- package/dist/src/core/ToolManager.js.map +1 -0
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/types/agent.d.ts +2 -1
- package/dist/src/types/agent.d.ts.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 +3 -2
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -0
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/route.d.ts +6 -4
- package/dist/src/types/route.d.ts.map +1 -1
- package/dist/src/types/tool.d.ts +84 -14
- package/dist/src/types/tool.d.ts.map +1 -1
- package/dist/src/types/tool.js +12 -1
- package/dist/src/types/tool.js.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/docs/CONTRIBUTING.md +40 -0
- package/docs/README.md +14 -6
- package/docs/api/README.md +235 -45
- package/docs/api/overview.md +140 -33
- package/docs/core/agent/session-management.md +152 -5
- package/docs/core/ai-integration/response-processing.md +115 -4
- package/docs/core/conversation-flows/routes.md +130 -0
- package/docs/core/error-handling.md +638 -0
- package/docs/core/tools/tool-definition.md +684 -60
- package/docs/core/tools/tool-scoping.md +244 -53
- package/docs/guides/error-handling-patterns.md +578 -0
- package/docs/guides/getting-started/README.md +139 -28
- 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 +6 -6
- package/examples/advanced-patterns/persistent-onboarding.ts +30 -43
- package/examples/advanced-patterns/streaming-responses.ts +169 -96
- package/examples/ai-providers/anthropic-integration.ts +9 -5
- package/examples/ai-providers/openai-integration.ts +11 -7
- package/examples/core-concepts/basic-agent.ts +106 -67
- package/examples/core-concepts/modern-streaming-api.ts +309 -0
- package/examples/core-concepts/schema-driven-extraction.ts +10 -7
- package/examples/core-concepts/session-management.ts +71 -18
- package/examples/integrations/healthcare-integration.ts +15 -29
- package/examples/integrations/server-session-management.ts +3 -3
- package/examples/persistence/memory-sessions.ts +3 -3
- package/examples/tools/basic-tools.ts +293 -89
- package/examples/tools/data-enrichment-tools.ts +185 -75
- package/package.json +1 -1
- package/src/core/Agent.ts +190 -1529
- package/src/core/ResponseModal.ts +1798 -0
- package/src/core/ResponsePipeline.ts +83 -57
- package/src/core/Route.ts +39 -12
- package/src/core/RoutingEngine.ts +46 -42
- package/src/core/SessionManager.ts +39 -7
- package/src/core/Step.ts +198 -20
- package/src/core/ToolManager.ts +1394 -0
- package/src/index.ts +19 -3
- package/src/types/agent.ts +2 -1
- package/src/types/ai.ts +1 -1
- package/src/types/index.ts +13 -2
- package/src/types/route.ts +6 -4
- package/src/types/tool.ts +116 -25
- package/src/utils/clone.ts +6 -8
- package/src/utils/history.ts +190 -27
- package/src/utils/index.ts +4 -0
- package/dist/cjs/src/core/ToolExecutor.d.ts +0 -45
- package/dist/cjs/src/core/ToolExecutor.d.ts.map +0 -1
- package/dist/cjs/src/core/ToolExecutor.js +0 -84
- package/dist/cjs/src/core/ToolExecutor.js.map +0 -1
- package/dist/src/core/ToolExecutor.d.ts +0 -45
- package/dist/src/core/ToolExecutor.d.ts.map +0 -1
- package/dist/src/core/ToolExecutor.js +0 -80
- package/dist/src/core/ToolExecutor.js.map +0 -1
- package/docs/core/tools/tool-execution.md +0 -815
- package/src/core/ToolExecutor.ts +0 -126
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
import {
|
|
14
14
|
Agent,
|
|
15
15
|
GeminiProvider,
|
|
16
|
+
Tool,
|
|
17
|
+
ValidationError,
|
|
16
18
|
type Term,
|
|
17
19
|
type Guideline,
|
|
18
|
-
type Tool,
|
|
19
20
|
type RouteOptions,
|
|
20
21
|
} from "../../src/index";
|
|
21
22
|
|
|
@@ -40,98 +41,71 @@ interface LabData {
|
|
|
40
41
|
resultsNeeded: boolean;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
// Define tools using
|
|
44
|
-
const
|
|
44
|
+
// Define tools using unified Tool interface
|
|
45
|
+
const getInsuranceProvidersTool: Tool<HealthcareContext, HealthcareData> = {
|
|
45
46
|
id: "healthcare_insurance_providers",
|
|
46
47
|
description: "Retrieves list of accepted insurance providers",
|
|
47
48
|
parameters: {
|
|
48
49
|
type: "object",
|
|
49
50
|
properties: {},
|
|
50
51
|
},
|
|
51
|
-
handler: () => {
|
|
52
|
+
handler: async (context, args) => {
|
|
52
53
|
return {
|
|
53
|
-
data:
|
|
54
|
+
data: "Available insurance providers: MegaCare Insurance, HealthFirst, WellnessPlus",
|
|
54
55
|
};
|
|
55
56
|
},
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
const
|
|
59
|
-
HealthcareContext,
|
|
60
|
-
HealthcareData,
|
|
61
|
-
[],
|
|
62
|
-
{ date: string; time: string }[]
|
|
63
|
-
> = {
|
|
59
|
+
const getAvailableSlotsTool: Tool<HealthcareContext, HealthcareData> = {
|
|
64
60
|
id: "healthcare_available_slots",
|
|
65
61
|
description: "Gets available appointment slots",
|
|
66
62
|
parameters: {
|
|
67
63
|
type: "object",
|
|
68
64
|
properties: {},
|
|
69
65
|
},
|
|
70
|
-
handler: () => {
|
|
66
|
+
handler: async (context, args) => {
|
|
71
67
|
return {
|
|
72
|
-
data:
|
|
73
|
-
{ date: "2025-10-20", time: "10:00 AM" },
|
|
74
|
-
{ date: "2025-10-20", time: "2:00 PM" },
|
|
75
|
-
{ date: "2025-10-21", time: "1:00 PM" },
|
|
76
|
-
],
|
|
68
|
+
data: "Available slots: Oct 20 at 10:00 AM, Oct 20 at 2:00 PM, Oct 21 at 1:00 PM",
|
|
77
69
|
};
|
|
78
70
|
},
|
|
79
71
|
};
|
|
80
72
|
|
|
81
|
-
const
|
|
82
|
-
HealthcareContext,
|
|
83
|
-
HealthcareData,
|
|
84
|
-
[],
|
|
85
|
-
{ report: string; status: string }
|
|
86
|
-
> = {
|
|
73
|
+
const getLabResultsTool: Tool<HealthcareContext, HealthcareData> = {
|
|
87
74
|
id: "healthcare_lab_results",
|
|
88
75
|
description: "Retrieves patient lab results",
|
|
89
76
|
parameters: {
|
|
90
77
|
type: "object",
|
|
91
78
|
properties: {},
|
|
92
79
|
},
|
|
93
|
-
handler: (
|
|
80
|
+
handler: async (toolContext, args) => {
|
|
94
81
|
// Tools can access collected data and context
|
|
95
|
-
if (data?.testType) {
|
|
82
|
+
if (toolContext.data?.testType) {
|
|
96
83
|
return {
|
|
97
|
-
data: {
|
|
98
|
-
report: `${data.testType} results for ${context.patientName}`,
|
|
99
|
-
status: "All values within normal range",
|
|
100
|
-
},
|
|
84
|
+
data: `${toolContext.data.testType} results for ${toolContext.context.patientName}: All values within normal range`,
|
|
101
85
|
};
|
|
102
86
|
}
|
|
103
87
|
|
|
104
88
|
return {
|
|
105
|
-
data: {
|
|
106
|
-
report: `Lab results for ${context.patientName}`,
|
|
107
|
-
status: "All values within normal range",
|
|
108
|
-
},
|
|
89
|
+
data: `Lab results for ${toolContext.context.patientName}: All values within normal range`,
|
|
109
90
|
};
|
|
110
91
|
},
|
|
111
92
|
};
|
|
112
93
|
|
|
113
|
-
const
|
|
114
|
-
HealthcareContext,
|
|
115
|
-
HealthcareData,
|
|
116
|
-
[],
|
|
117
|
-
{ confirmation: string }
|
|
118
|
-
> = {
|
|
94
|
+
const scheduleAppointmentTool: Tool<HealthcareContext, HealthcareData> = {
|
|
119
95
|
id: "healthcare_schedule_appointment",
|
|
120
96
|
description: "Schedules patient appointments",
|
|
121
97
|
parameters: {
|
|
122
98
|
type: "object",
|
|
123
99
|
properties: {},
|
|
124
100
|
},
|
|
125
|
-
handler: (
|
|
101
|
+
handler: async (context, args) => {
|
|
126
102
|
// Tools access collected appointment data
|
|
127
|
-
if (!data?.preferredDate || !data?.preferredTime) {
|
|
128
|
-
return { data:
|
|
103
|
+
if (!context.data?.preferredDate || !context.data?.preferredTime) {
|
|
104
|
+
return { data: "Please provide appointment details" };
|
|
129
105
|
}
|
|
130
106
|
|
|
131
107
|
return {
|
|
132
|
-
data: {
|
|
133
|
-
confirmation: `Appointment scheduled for ${data.preferredDate} at ${data.preferredTime}`,
|
|
134
|
-
},
|
|
108
|
+
data: `Appointment scheduled for ${context.data.preferredDate} at ${context.data.preferredTime}`,
|
|
135
109
|
};
|
|
136
110
|
},
|
|
137
111
|
};
|
|
@@ -175,7 +149,7 @@ const guidelines: Guideline<HealthcareContext>[] = [
|
|
|
175
149
|
},
|
|
176
150
|
];
|
|
177
151
|
|
|
178
|
-
const routes
|
|
152
|
+
const routes = [
|
|
179
153
|
{
|
|
180
154
|
id: "route_schedule_appointment",
|
|
181
155
|
title: "Schedule Appointment",
|
|
@@ -221,27 +195,13 @@ const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
|
|
|
221
195
|
id: "schedule_appointment",
|
|
222
196
|
description: "Schedule the appointment",
|
|
223
197
|
prompt: "I'll schedule your appointment now.",
|
|
224
|
-
tools: [
|
|
198
|
+
tools: ["healthcare_schedule_appointment"], // Reference by ID
|
|
225
199
|
requires: ["preferredDate", "preferredTime"],
|
|
226
|
-
prepare:
|
|
227
|
-
finalize:
|
|
228
|
-
// Inline tool to handle appointment finalization
|
|
229
|
-
id: "finalize_appointment",
|
|
230
|
-
description: "Complete the appointment booking process",
|
|
231
|
-
parameters: { type: "object", properties: {} },
|
|
232
|
-
handler: ({ context, data }) => {
|
|
233
|
-
console.log(`ā
Appointment finalized for ${context.patientName}`);
|
|
234
|
-
console.log(`š
Details: ${JSON.stringify(data, null, 2)}`);
|
|
235
|
-
|
|
236
|
-
// Could send confirmation email, update calendar, etc.
|
|
237
|
-
return {
|
|
238
|
-
data: `Appointment confirmed for ${context.patientName}`,
|
|
239
|
-
};
|
|
240
|
-
},
|
|
241
|
-
},
|
|
200
|
+
prepare: "healthcare_insurance_providers", // Reference by ID
|
|
201
|
+
finalize: "finalize_appointment", // Reference by ID - will be registered later
|
|
242
202
|
},
|
|
243
203
|
],
|
|
244
|
-
tools: [
|
|
204
|
+
tools: ["healthcare_available_slots"], // Reference by ID
|
|
245
205
|
},
|
|
246
206
|
{
|
|
247
207
|
id: "route_check_lab_results",
|
|
@@ -260,7 +220,7 @@ const routes: RouteOptions<HealthcareContext, HealthcareData>[] = [
|
|
|
260
220
|
tags: ["escalation"],
|
|
261
221
|
},
|
|
262
222
|
],
|
|
263
|
-
tools: [
|
|
223
|
+
tools: ["healthcare_lab_results"], // Reference by ID
|
|
264
224
|
},
|
|
265
225
|
{
|
|
266
226
|
title: "General Healthcare Questions",
|
|
@@ -334,8 +294,87 @@ const agent = new Agent<HealthcareContext, HealthcareData>({
|
|
|
334
294
|
// Declarative initialization
|
|
335
295
|
terms,
|
|
336
296
|
guidelines,
|
|
337
|
-
|
|
338
|
-
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Demonstrate different tool registration approaches
|
|
300
|
+
|
|
301
|
+
// Method 1: Register tools for ID-based reference in routes
|
|
302
|
+
agent.tool.registerMany([
|
|
303
|
+
getInsuranceProvidersTool,
|
|
304
|
+
getAvailableSlotsTool,
|
|
305
|
+
getLabResultsTool,
|
|
306
|
+
scheduleAppointmentTool,
|
|
307
|
+
]);
|
|
308
|
+
|
|
309
|
+
// Method 2: Create and register specialized tools
|
|
310
|
+
const appointmentValidator = agent.tool.createValidation({
|
|
311
|
+
id: "validate_appointment",
|
|
312
|
+
fields: ["appointmentType", "preferredDate", "preferredTime"] as const,
|
|
313
|
+
validator: async (context, data) => {
|
|
314
|
+
const errors: ValidationError[] = [];
|
|
315
|
+
if (!data.appointmentType) errors.push({
|
|
316
|
+
field: "appointmentType",
|
|
317
|
+
value: data.appointmentType,
|
|
318
|
+
message: "Appointment type is required",
|
|
319
|
+
schemaPath: "appointmentType"
|
|
320
|
+
});
|
|
321
|
+
if (!data.preferredDate) errors.push({
|
|
322
|
+
field: "preferredDate",
|
|
323
|
+
value: data.preferredDate,
|
|
324
|
+
message: "Preferred date is required",
|
|
325
|
+
schemaPath: "preferredDate"
|
|
326
|
+
});
|
|
327
|
+
if (!data.preferredTime) errors.push({
|
|
328
|
+
field: "preferredTime",
|
|
329
|
+
value: data.preferredTime,
|
|
330
|
+
message: "Preferred time is required",
|
|
331
|
+
schemaPath: "preferredTime"
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
valid: errors.length === 0,
|
|
336
|
+
errors,
|
|
337
|
+
warnings: [],
|
|
338
|
+
};
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Method 3: Create data enrichment tool
|
|
343
|
+
const patientDataEnricher = agent.tool.createDataEnrichment({
|
|
344
|
+
id: "enrich_patient_data",
|
|
345
|
+
fields: ["appointmentType", "symptoms"] as const,
|
|
346
|
+
enricher: async (context, data) => {
|
|
347
|
+
// Add urgency classification based on symptoms - return fields that exist in HealthcareData
|
|
348
|
+
const urgentKeywords = ["chest pain", "difficulty breathing", "severe", "emergency"];
|
|
349
|
+
const hasUrgentSymptoms = data.symptoms && urgentKeywords.some(keyword =>
|
|
350
|
+
data.symptoms!.toLowerCase().includes(keyword)
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
urgency: hasUrgentSymptoms ? "high" : "medium", // This matches the urgency field in HealthcareData
|
|
355
|
+
};
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// Method 4: Create tool using tool.create()
|
|
360
|
+
const finalizeAppointmentTool = agent.tool.create({
|
|
361
|
+
id: "finalize_appointment",
|
|
362
|
+
description: "Complete the appointment booking process",
|
|
363
|
+
parameters: { type: "object", properties: {} },
|
|
364
|
+
handler: async (context, args) => {
|
|
365
|
+
console.log(`ā
Appointment finalized for ${context.context.patientName}`);
|
|
366
|
+
console.log(`š
Details: ${JSON.stringify(context.data, null, 2)}`);
|
|
367
|
+
|
|
368
|
+
// Could send confirmation email, update calendar, etc.
|
|
369
|
+
return {
|
|
370
|
+
data: `Appointment confirmed for ${context.context.patientName}`,
|
|
371
|
+
};
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// Add routes after tools are registered
|
|
376
|
+
routes.forEach((route: any) => {
|
|
377
|
+
agent.createRoute(route);
|
|
339
378
|
});
|
|
340
379
|
|
|
341
380
|
// You can still add more dynamically after construction
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Modern Streaming API
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates the new agent.stream() method introduced in the
|
|
5
|
+
* ResponseModal refactor. The modern API provides automatic session management
|
|
6
|
+
* and a simpler interface compared to the legacy respondStream() method.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
Agent,
|
|
11
|
+
AnthropicProvider,
|
|
12
|
+
OpenAIProvider,
|
|
13
|
+
} from "../../src/index";
|
|
14
|
+
|
|
15
|
+
// Context type for our examples
|
|
16
|
+
interface UserContext {
|
|
17
|
+
userId: string;
|
|
18
|
+
preferences: {
|
|
19
|
+
language?: string;
|
|
20
|
+
verbosity: "concise" | "detailed";
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function basicModernStreaming() {
|
|
25
|
+
console.log("\nš Example 1: Basic Modern Streaming API\n");
|
|
26
|
+
|
|
27
|
+
const provider = new AnthropicProvider({
|
|
28
|
+
apiKey: process.env.ANTHROPIC_API_KEY || "",
|
|
29
|
+
model: "claude-sonnet-4-5",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const agent = new Agent<UserContext, unknown>({
|
|
33
|
+
name: "ModernStreamingAgent",
|
|
34
|
+
description: "Demonstrates the new stream() API",
|
|
35
|
+
context: {
|
|
36
|
+
userId: "user123",
|
|
37
|
+
preferences: {
|
|
38
|
+
language: "English",
|
|
39
|
+
verbosity: "concise",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
provider,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
console.log("š¤ Using modern stream() API...\n");
|
|
47
|
+
console.log("Response: ");
|
|
48
|
+
|
|
49
|
+
// NEW: Simple streaming with automatic session management
|
|
50
|
+
for await (const chunk of agent.stream("What is machine learning?")) {
|
|
51
|
+
if (chunk.delta) {
|
|
52
|
+
process.stdout.write(chunk.delta);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (chunk.done) {
|
|
56
|
+
console.log("\n\nā
Stream complete!");
|
|
57
|
+
console.log(`š Session has ${agent.session.getHistory().length} messages`);
|
|
58
|
+
console.log("š” Session history was automatically managed!");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error("ā Error:", error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function streamingWithOptions() {
|
|
67
|
+
console.log("\nš Example 2: Streaming with Options\n");
|
|
68
|
+
|
|
69
|
+
const provider = new OpenAIProvider({
|
|
70
|
+
apiKey: process.env.OPENAI_API_KEY || "",
|
|
71
|
+
model: "gpt-4",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const agent = new Agent<UserContext, unknown>({
|
|
75
|
+
name: "OptionsStreamingAgent",
|
|
76
|
+
description: "Demonstrates streaming with options",
|
|
77
|
+
context: {
|
|
78
|
+
userId: "user456",
|
|
79
|
+
preferences: {
|
|
80
|
+
language: "English",
|
|
81
|
+
verbosity: "detailed",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
provider,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
console.log("š¤ Streaming with context override and abort signal...\n");
|
|
89
|
+
console.log("Response: ");
|
|
90
|
+
|
|
91
|
+
// Create abort controller for cancellation
|
|
92
|
+
const abortController = new AbortController();
|
|
93
|
+
|
|
94
|
+
// Cancel after 10 seconds
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
console.log("\nā ļø Aborting stream...");
|
|
97
|
+
abortController.abort();
|
|
98
|
+
}, 10000);
|
|
99
|
+
|
|
100
|
+
// Stream with options
|
|
101
|
+
for await (const chunk of agent.stream("Explain quantum computing in detail", {
|
|
102
|
+
contextOverride: {
|
|
103
|
+
preferences: { verbosity: "concise" } // Override to be more concise
|
|
104
|
+
},
|
|
105
|
+
signal: abortController.signal
|
|
106
|
+
})) {
|
|
107
|
+
if (chunk.delta) {
|
|
108
|
+
process.stdout.write(chunk.delta);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (chunk.done) {
|
|
112
|
+
console.log("\n\nā
Stream complete!");
|
|
113
|
+
console.log("š” Context was overridden for this response only");
|
|
114
|
+
clearTimeout();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
119
|
+
console.log("\nš Stream was successfully aborted!");
|
|
120
|
+
} else {
|
|
121
|
+
console.error("ā Error:", error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function conversationFlow() {
|
|
127
|
+
console.log("\nš Example 3: Multi-turn Conversation Flow\n");
|
|
128
|
+
|
|
129
|
+
const provider = new AnthropicProvider({
|
|
130
|
+
apiKey: process.env.ANTHROPIC_API_KEY || "",
|
|
131
|
+
model: "claude-sonnet-4-5",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const agent = new Agent<UserContext, unknown>({
|
|
135
|
+
name: "ConversationAgent",
|
|
136
|
+
description: "Demonstrates multi-turn conversations",
|
|
137
|
+
context: {
|
|
138
|
+
userId: "user789",
|
|
139
|
+
preferences: {
|
|
140
|
+
language: "English",
|
|
141
|
+
verbosity: "detailed",
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
provider,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const messages = [
|
|
148
|
+
"What is TypeScript?",
|
|
149
|
+
"How is it different from JavaScript?",
|
|
150
|
+
"Can you give me a simple example?",
|
|
151
|
+
"Thank you for the explanation!"
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
console.log("š¤ Multi-turn conversation with automatic session management...\n");
|
|
156
|
+
|
|
157
|
+
for (let i = 0; i < messages.length; i++) {
|
|
158
|
+
console.log(`\n${"=".repeat(60)}`);
|
|
159
|
+
console.log(`š¬ Turn ${i + 1}: ${messages[i]}`);
|
|
160
|
+
console.log(`${"=".repeat(60)}`);
|
|
161
|
+
console.log("Response: ");
|
|
162
|
+
|
|
163
|
+
// Each stream() call automatically manages the session
|
|
164
|
+
for await (const chunk of agent.stream(messages[i])) {
|
|
165
|
+
if (chunk.delta) {
|
|
166
|
+
process.stdout.write(chunk.delta);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (chunk.done) {
|
|
170
|
+
console.log(`\nš Session now has ${agent.session.getHistory().length} messages`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
console.log("\nā
Conversation complete!");
|
|
176
|
+
console.log("š” All session management was handled automatically");
|
|
177
|
+
console.log(`š Final session has ${agent.session.getHistory().length} messages`);
|
|
178
|
+
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error("ā Error:", error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function migrationComparison() {
|
|
185
|
+
console.log("\nš Example 4: Migration from respondStream() to stream()\n");
|
|
186
|
+
|
|
187
|
+
const provider = new AnthropicProvider({
|
|
188
|
+
apiKey: process.env.ANTHROPIC_API_KEY || "",
|
|
189
|
+
model: "claude-sonnet-4-5",
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const agent = new Agent<UserContext, unknown>({
|
|
193
|
+
name: "MigrationAgent",
|
|
194
|
+
description: "Shows migration from old to new API",
|
|
195
|
+
context: {
|
|
196
|
+
userId: "migration-user",
|
|
197
|
+
preferences: {
|
|
198
|
+
language: "English",
|
|
199
|
+
verbosity: "concise",
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
provider,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const userMessage = "What are the benefits of TypeScript?";
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
// ========================================================================
|
|
209
|
+
// OLD WAY: respondStream() - Manual session management
|
|
210
|
+
// ========================================================================
|
|
211
|
+
console.log("šø OLD WAY: Using respondStream() with manual session management");
|
|
212
|
+
console.log("Code: agent.respondStream({ history: agent.session.getHistory() })");
|
|
213
|
+
console.log("Response: ");
|
|
214
|
+
|
|
215
|
+
// Manual session management required
|
|
216
|
+
await agent.session.addMessage("user", userMessage);
|
|
217
|
+
|
|
218
|
+
let oldResponse = "";
|
|
219
|
+
for await (const chunk of agent.respondStream({
|
|
220
|
+
history: agent.session.getHistory()
|
|
221
|
+
})) {
|
|
222
|
+
if (chunk.delta) {
|
|
223
|
+
process.stdout.write(chunk.delta);
|
|
224
|
+
oldResponse += chunk.delta;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (chunk.done) {
|
|
228
|
+
// Manual history update required
|
|
229
|
+
await agent.session.addMessage("assistant", oldResponse);
|
|
230
|
+
console.log("\n ā
Manual session update completed");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
console.log("\n" + "=".repeat(60));
|
|
235
|
+
|
|
236
|
+
// ========================================================================
|
|
237
|
+
// NEW WAY: stream() - Automatic session management
|
|
238
|
+
// ========================================================================
|
|
239
|
+
console.log("šø NEW WAY: Using stream() with automatic session management");
|
|
240
|
+
console.log("Code: agent.stream('message')");
|
|
241
|
+
console.log("Response: ");
|
|
242
|
+
|
|
243
|
+
// Automatic session management - just pass the message!
|
|
244
|
+
for await (const chunk of agent.stream("Can you elaborate on the type safety benefits?")) {
|
|
245
|
+
if (chunk.delta) {
|
|
246
|
+
process.stdout.write(chunk.delta);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (chunk.done) {
|
|
250
|
+
console.log("\n ā
Automatic session update - no manual work needed!");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
console.log("\nš Migration Benefits:");
|
|
255
|
+
console.log(" ā
Simpler API: agent.stream('message') vs complex parameters");
|
|
256
|
+
console.log(" ā
Automatic session management - no manual addMessage() calls");
|
|
257
|
+
console.log(" ā
Same performance and features as respondStream()");
|
|
258
|
+
console.log(" ā
Backward compatibility - respondStream() still works");
|
|
259
|
+
console.log(" ā
Consistent with chat() API patterns");
|
|
260
|
+
|
|
261
|
+
console.log(`\nš Final session has ${agent.session.getHistory().length} messages`);
|
|
262
|
+
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error("ā Error:", error);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function main() {
|
|
269
|
+
console.log("š Modern Streaming API Examples");
|
|
270
|
+
console.log("=".repeat(60));
|
|
271
|
+
|
|
272
|
+
const examples = [
|
|
273
|
+
{ name: "Basic Modern Streaming", fn: basicModernStreaming },
|
|
274
|
+
{ name: "Streaming with Options", fn: streamingWithOptions },
|
|
275
|
+
{ name: "Multi-turn Conversation", fn: conversationFlow },
|
|
276
|
+
{ name: "Migration Comparison", fn: migrationComparison },
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
console.log("\nAvailable Examples:");
|
|
280
|
+
examples.forEach((ex, i) => {
|
|
281
|
+
console.log(` ${i + 1}. ${ex.name}`);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
console.log("\nš” Key Benefits of Modern stream() API:");
|
|
285
|
+
console.log(" - Simple interface: agent.stream('message')");
|
|
286
|
+
console.log(" - Automatic session management");
|
|
287
|
+
console.log(" - No manual history updates needed");
|
|
288
|
+
console.log(" - Same performance as respondStream()");
|
|
289
|
+
console.log(" - Full backward compatibility maintained");
|
|
290
|
+
|
|
291
|
+
console.log("\n" + "=".repeat(60));
|
|
292
|
+
|
|
293
|
+
// Run examples if API key is available
|
|
294
|
+
if (process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY) {
|
|
295
|
+
await basicModernStreaming();
|
|
296
|
+
await migrationComparison();
|
|
297
|
+
} else {
|
|
298
|
+
console.log(
|
|
299
|
+
"\nā ļø Set ANTHROPIC_API_KEY or OPENAI_API_KEY to run examples."
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Run if executed directly
|
|
305
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
306
|
+
main().catch(console.error);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export { main };
|
|
@@ -23,22 +23,22 @@ interface UserProfileData {
|
|
|
23
23
|
newsletterOptIn: boolean;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// Define a tool that uses the collected data
|
|
27
|
-
const
|
|
26
|
+
// Define a tool that uses the collected data - using unified Tool interface
|
|
27
|
+
const saveUserProfileTool: Tool<unknown, UserProfileData> = {
|
|
28
28
|
id: "save_user_profile",
|
|
29
29
|
description: "Save the collected user profile information",
|
|
30
30
|
parameters: {
|
|
31
31
|
type: "object",
|
|
32
32
|
properties: {},
|
|
33
33
|
},
|
|
34
|
-
handler: (
|
|
35
|
-
console.log("Saving user profile:", data);
|
|
34
|
+
handler: async (context, args) => {
|
|
35
|
+
console.log("Saving user profile:", context.data);
|
|
36
36
|
|
|
37
37
|
// Simulate saving to database
|
|
38
|
-
console.log("Profile data:", data);
|
|
38
|
+
console.log("Profile data:", context.data);
|
|
39
39
|
|
|
40
40
|
return {
|
|
41
|
-
data: `Profile saved successfully! Welcome ${data?.name}!`,
|
|
41
|
+
data: `Profile saved successfully! Welcome ${context.data?.name}!`,
|
|
42
42
|
};
|
|
43
43
|
},
|
|
44
44
|
};
|
|
@@ -99,6 +99,9 @@ const agent = new Agent<unknown, UserProfileData>({
|
|
|
99
99
|
schema: userProfileSchema,
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
// Add tool using unified interface
|
|
103
|
+
agent.addTool(saveUserProfileTool);
|
|
104
|
+
|
|
102
105
|
// Create a route that collects profile information step by step
|
|
103
106
|
agent.createRoute({
|
|
104
107
|
title: "User Profile Collection",
|
|
@@ -163,7 +166,7 @@ agent.createRoute({
|
|
|
163
166
|
description: "Save the collected profile",
|
|
164
167
|
prompt:
|
|
165
168
|
"Thanks for providing your information! Let me save your profile.",
|
|
166
|
-
tools: [
|
|
169
|
+
tools: ["save_user_profile"], // Reference by ID
|
|
167
170
|
requires: ["name", "email"],
|
|
168
171
|
},
|
|
169
172
|
],
|