@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
|
@@ -31,31 +31,44 @@ const greetingRoute = agent
|
|
|
31
31
|
});
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
### Route with Schema
|
|
34
|
+
### Route with Agent-Level Schema
|
|
35
35
|
|
|
36
36
|
```typescript
|
|
37
37
|
interface UserInfo {
|
|
38
38
|
name: string;
|
|
39
39
|
email: string;
|
|
40
40
|
interests: string[];
|
|
41
|
+
preferences?: object;
|
|
42
|
+
profileComplete?: boolean;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
// Agent defines comprehensive schema
|
|
46
|
+
const agent = new Agent<{}, UserInfo>({
|
|
47
|
+
name: "Profile Assistant",
|
|
48
|
+
provider: openaiProvider,
|
|
49
|
+
schema: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
name: { type: "string" },
|
|
53
|
+
email: { type: "string", format: "email" },
|
|
54
|
+
interests: {
|
|
55
|
+
type: "array",
|
|
56
|
+
items: { type: "string" },
|
|
57
|
+
},
|
|
58
|
+
preferences: { type: "object" },
|
|
59
|
+
profileComplete: { type: "boolean" }
|
|
60
|
+
},
|
|
61
|
+
required: ["name", "email"],
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Route specifies required fields instead of schema
|
|
43
66
|
const userProfileRoute = agent
|
|
44
|
-
.createRoute
|
|
67
|
+
.createRoute({
|
|
45
68
|
title: "User Profile Collection",
|
|
46
69
|
description: "Collect basic user information",
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
properties: {
|
|
50
|
-
name: { type: "string" },
|
|
51
|
-
email: { type: "string", format: "email" },
|
|
52
|
-
interests: {
|
|
53
|
-
type: "array",
|
|
54
|
-
items: { type: "string" },
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
required: ["name", "email"],
|
|
58
|
-
},
|
|
70
|
+
requiredFields: ["name", "email", "interests"], // Required for completion
|
|
71
|
+
optionalFields: ["preferences"], // Nice to have
|
|
59
72
|
initialStep: {
|
|
60
73
|
prompt: "Let's create your profile. What's your name?",
|
|
61
74
|
collect: ["name"],
|
|
@@ -64,12 +77,12 @@ const userProfileRoute = agent
|
|
|
64
77
|
.nextStep({
|
|
65
78
|
prompt: "Great, {{name}}! What's your email address?",
|
|
66
79
|
collect: ["email"],
|
|
67
|
-
requires: ["name"],
|
|
80
|
+
requires: ["name"], // Prerequisites from agent data
|
|
68
81
|
})
|
|
69
82
|
.nextStep({
|
|
70
83
|
prompt: "What are your interests? (comma-separated)",
|
|
71
84
|
collect: ["interests"],
|
|
72
|
-
requires: ["name", "email"],
|
|
85
|
+
requires: ["name", "email"], // Prerequisites from agent data
|
|
73
86
|
});
|
|
74
87
|
```
|
|
75
88
|
|
|
@@ -99,9 +112,9 @@ interface StepOptions<TContext, TData> {
|
|
|
99
112
|
```typescript
|
|
100
113
|
const dataCollectionStep = {
|
|
101
114
|
prompt: "What's your preferred contact method?",
|
|
102
|
-
collect: ["contactMethod"], // Maps to schema field
|
|
103
|
-
requires: ["name", "email"], // Must have these fields
|
|
104
|
-
skipIf: (data) => data.contactMethod !== undefined, // Skip if already collected
|
|
115
|
+
collect: ["contactMethod"], // Maps to agent schema field
|
|
116
|
+
requires: ["name", "email"], // Must have these fields from agent data
|
|
117
|
+
skipIf: (data) => data.contactMethod !== undefined, // Skip if already collected by any route
|
|
105
118
|
};
|
|
106
119
|
```
|
|
107
120
|
|
|
@@ -296,6 +309,10 @@ const advancedRoute = agent.createRoute({
|
|
|
296
309
|
title: "Advanced Interaction",
|
|
297
310
|
description: "Complex multi-step conversation",
|
|
298
311
|
|
|
312
|
+
// Route completion requirements
|
|
313
|
+
requiredFields: ["customerName", "email", "issueType"],
|
|
314
|
+
optionalFields: ["phone", "priority"],
|
|
315
|
+
|
|
299
316
|
// Route-level identity overrides agent identity
|
|
300
317
|
identity: "You are an expert consultant specializing in {{domain}}",
|
|
301
318
|
|
|
@@ -316,19 +333,25 @@ const advancedRoute = agent.createRoute({
|
|
|
316
333
|
},
|
|
317
334
|
],
|
|
318
335
|
|
|
319
|
-
// Initial data to pre-populate
|
|
336
|
+
// Initial data to pre-populate (maps to agent schema)
|
|
320
337
|
initialData: {
|
|
321
338
|
sessionId: generateId(),
|
|
322
339
|
startTime: new Date().toISOString(),
|
|
323
340
|
},
|
|
324
341
|
|
|
325
|
-
//
|
|
342
|
+
// Route-level lifecycle hooks (work with agent data)
|
|
326
343
|
hooks: {
|
|
327
344
|
onDataUpdate: (newData, previousData) => {
|
|
328
|
-
// Validate or enrich collected data
|
|
345
|
+
// Validate or enrich agent-level collected data
|
|
329
346
|
if (newData.email && !isValidEmail(newData.email)) {
|
|
330
347
|
throw new Error("Invalid email format");
|
|
331
348
|
}
|
|
349
|
+
|
|
350
|
+
// Auto-set priority based on issue type
|
|
351
|
+
if (newData.issueType === 'billing' && !newData.priority) {
|
|
352
|
+
newData.priority = 'high';
|
|
353
|
+
}
|
|
354
|
+
|
|
332
355
|
return newData;
|
|
333
356
|
},
|
|
334
357
|
onContextUpdate: (newContext, previousContext) => {
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
# Routes
|
|
2
2
|
|
|
3
|
-
Routes define conversational journeys in @falai/agent. This document covers route definition, lifecycle management, and completion handling.
|
|
3
|
+
Routes define conversational journeys in @falai/agent with agent-level data collection. This document covers route definition with required fields, lifecycle management, and completion handling based on data availability.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
Routes represent complete conversational workflows that guide users through specific tasks or processes. Each route consists of steps
|
|
7
|
+
Routes represent complete conversational workflows that guide users through specific tasks or processes. Each route specifies required fields for completion, consists of steps that collect data into the agent-level schema, and can complete when their data requirements are satisfied regardless of which route collected the data.
|
|
8
8
|
|
|
9
|
-
## Route Definition
|
|
9
|
+
## Route Definition with Required Fields
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
// Agent defines comprehensive schema
|
|
13
|
+
interface HotelData {
|
|
14
|
+
destination: string;
|
|
15
|
+
checkIn: string;
|
|
16
|
+
checkOut: string;
|
|
17
|
+
guests: number;
|
|
18
|
+
roomType?: string;
|
|
19
|
+
customerName?: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
phone?: string;
|
|
22
|
+
specialRequests?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const agent = new Agent<{}, HotelData>({
|
|
26
|
+
name: "Hotel Booking Agent",
|
|
16
27
|
schema: {
|
|
17
28
|
type: "object",
|
|
18
29
|
properties: {
|
|
@@ -20,42 +31,87 @@ const bookingRoute = agent.createRoute<BookingData>({
|
|
|
20
31
|
checkIn: { type: "string", format: "date" },
|
|
21
32
|
checkOut: { type: "string", format: "date" },
|
|
22
33
|
guests: { type: "number", minimum: 1 },
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
roomType: { type: "string" },
|
|
35
|
+
customerName: { type: "string" },
|
|
36
|
+
email: { type: "string", format: "email" },
|
|
37
|
+
phone: { type: "string" },
|
|
38
|
+
specialRequests: { type: "string" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Routes specify required fields instead of schemas
|
|
44
|
+
const bookingRoute = agent.createRoute({
|
|
45
|
+
title: "Hotel Booking",
|
|
46
|
+
description: "Help users book hotel accommodations",
|
|
47
|
+
conditions: ["User wants to book a hotel"],
|
|
48
|
+
requiredFields: ["destination", "checkIn", "checkOut", "guests", "customerName", "email"],
|
|
49
|
+
optionalFields: ["roomType", "phone", "specialRequests"]
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const customerServiceRoute = agent.createRoute({
|
|
53
|
+
title: "Customer Service",
|
|
54
|
+
description: "Help with booking issues",
|
|
55
|
+
conditions: ["User needs help with existing booking"],
|
|
56
|
+
requiredFields: ["customerName", "email"], // Minimal requirements
|
|
57
|
+
optionalFields: ["phone", "destination"]
|
|
26
58
|
});
|
|
27
59
|
```
|
|
28
60
|
|
|
29
61
|
## Route Lifecycle
|
|
30
62
|
|
|
31
|
-
Routes have a complete lifecycle from creation through execution to completion.
|
|
63
|
+
Routes have a complete lifecycle from creation through execution to completion based on data availability.
|
|
32
64
|
|
|
33
65
|
### Route Creation
|
|
34
66
|
|
|
35
|
-
Routes are created using the agent's `createRoute()` method with
|
|
67
|
+
Routes are created using the agent's `createRoute()` method with required fields specifications that reference the agent-level schema.
|
|
36
68
|
|
|
37
69
|
### Route Execution
|
|
38
70
|
|
|
39
|
-
Routes are selected by the AI routing system based on user intent and conversation context.
|
|
71
|
+
Routes are selected by the AI routing system based on user intent and conversation context, with access to all agent-level data.
|
|
40
72
|
|
|
41
73
|
### Route Completion
|
|
42
74
|
|
|
43
|
-
Routes complete when
|
|
75
|
+
Routes complete when all their required fields are present in the agent's collected data, regardless of which route collected the data. This enables flexible cross-route completion scenarios.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// Route completion evaluation
|
|
79
|
+
const isComplete = bookingRoute.isComplete(agent.getCollectedData());
|
|
80
|
+
const missingFields = bookingRoute.getMissingRequiredFields(agent.getCollectedData());
|
|
81
|
+
const progress = bookingRoute.getCompletionProgress(agent.getCollectedData()); // 0-1
|
|
82
|
+
|
|
83
|
+
console.log(`Booking route is ${Math.round(progress * 100)}% complete`);
|
|
84
|
+
if (missingFields.length > 0) {
|
|
85
|
+
console.log(`Still need: ${missingFields.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
44
88
|
|
|
45
89
|
## Route Transitions
|
|
46
90
|
|
|
47
|
-
Routes can automatically transition to other routes upon completion using the `onComplete` configuration.
|
|
91
|
+
Routes can automatically transition to other routes upon completion using the `onComplete` configuration. With agent-level data, the target route may already have some of its required data.
|
|
48
92
|
|
|
49
93
|
```typescript
|
|
50
94
|
const bookingRoute = agent.createRoute({
|
|
51
95
|
title: "Hotel Booking",
|
|
96
|
+
requiredFields: ["destination", "checkIn", "checkOut", "guests", "customerName", "email"],
|
|
52
97
|
onComplete: "Feedback Collection", // Transition to feedback route
|
|
53
98
|
});
|
|
99
|
+
|
|
100
|
+
const feedbackRoute = agent.createRoute({
|
|
101
|
+
title: "Feedback Collection",
|
|
102
|
+
requiredFields: ["customerName", "email", "rating"], // Already has name and email from booking
|
|
103
|
+
optionalFields: ["comments"]
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// When booking completes, feedback route is already 2/3 complete
|
|
54
107
|
```
|
|
55
108
|
|
|
56
109
|
## Best Practices
|
|
57
110
|
|
|
58
111
|
- Use descriptive titles and conditions for better AI routing
|
|
59
|
-
- Define comprehensive schemas for type safety
|
|
60
|
-
-
|
|
61
|
-
-
|
|
112
|
+
- Define comprehensive agent-level schemas for type safety across all routes
|
|
113
|
+
- Specify minimal required fields for faster route completion
|
|
114
|
+
- Use optional fields to enhance user experience without blocking completion
|
|
115
|
+
- Implement appropriate completion handlers that leverage shared data
|
|
116
|
+
- Consider route transitions for multi-step workflows with data continuity
|
|
117
|
+
- Design routes that can benefit from cross-route data sharing
|
|
@@ -26,14 +26,14 @@ const smartRoute = agent
|
|
|
26
26
|
initialStep: {
|
|
27
27
|
prompt: "What's your name?",
|
|
28
28
|
collect: ["name"],
|
|
29
|
-
skipIf: (data) => data.name !== undefined, // Skip if name already
|
|
29
|
+
skipIf: (data) => data.name !== undefined, // Skip if name already collected by any route
|
|
30
30
|
},
|
|
31
31
|
})
|
|
32
32
|
.nextStep({
|
|
33
33
|
prompt: "What's your email, {{name}}?",
|
|
34
34
|
collect: ["email"],
|
|
35
|
-
requires: ["name"], // Must have name to proceed
|
|
36
|
-
skipIf: (data) => data.email !== undefined, // Skip if email already
|
|
35
|
+
requires: ["name"], // Must have name from agent data to proceed
|
|
36
|
+
skipIf: (data) => data.email !== undefined, // Skip if email already collected by any route
|
|
37
37
|
});
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# Steps
|
|
2
2
|
|
|
3
|
-
Steps are the building blocks of conversational routes in @falai/agent. This document covers step configuration, data collection, and transition logic.
|
|
3
|
+
Steps are the building blocks of conversational routes in @falai/agent with agent-level data collection. This document covers step configuration, data collection into the agent schema, and transition logic based on agent data.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
7
|
Steps represent individual moments in a conversation where the agent can:
|
|
8
8
|
|
|
9
9
|
- Prompt the user for information
|
|
10
|
-
- Collect structured data
|
|
11
|
-
- Execute tools
|
|
12
|
-
- Make decisions about conversation flow
|
|
10
|
+
- Collect structured data into the agent-level schema
|
|
11
|
+
- Execute tools that work with complete agent data
|
|
12
|
+
- Make decisions about conversation flow based on agent data
|
|
13
|
+
- Skip execution if required data is already available from other routes
|
|
13
14
|
|
|
14
15
|
## Step Configuration
|
|
15
16
|
|
|
16
17
|
```typescript
|
|
17
18
|
const nameStep = bookingRoute.initialStep.nextStep({
|
|
18
19
|
prompt: "What's your name?",
|
|
19
|
-
collect: ["
|
|
20
|
+
collect: ["customerName"], // Collects into agent-level schema
|
|
20
21
|
requires: [], // No prerequisites
|
|
21
|
-
skipIf: (data) => data.
|
|
22
|
+
skipIf: (data) => data.customerName, // Skip if already collected by any route
|
|
22
23
|
});
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -42,34 +43,57 @@ Steps that end the route using `END_ROUTE`.
|
|
|
42
43
|
|
|
43
44
|
## Data Collection
|
|
44
45
|
|
|
45
|
-
Steps collect data through the `collect` array, which maps to the
|
|
46
|
+
Steps collect data through the `collect` array, which maps to the agent's JSON schema and is validated against it.
|
|
46
47
|
|
|
47
48
|
```typescript
|
|
48
49
|
const contactStep = nameStep.nextStep({
|
|
49
50
|
prompt: "What's your email and phone number?",
|
|
50
|
-
collect: ["email", "phone"],
|
|
51
|
-
requires: ["
|
|
51
|
+
collect: ["email", "phone"], // Maps to agent schema fields
|
|
52
|
+
requires: ["customerName"], // Must have name first (from agent data)
|
|
52
53
|
});
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
## Conditional Logic
|
|
56
57
|
|
|
57
|
-
Steps support various conditional behaviors:
|
|
58
|
+
Steps support various conditional behaviors based on agent-level data:
|
|
58
59
|
|
|
59
|
-
- `skipIf`: Skip the step if a condition is met
|
|
60
|
-
- `requires`: Prerequisites that must be satisfied
|
|
60
|
+
- `skipIf`: Skip the step if a condition is met (evaluates against complete agent data)
|
|
61
|
+
- `requires`: Prerequisites that must be satisfied (checks agent data from any route)
|
|
61
62
|
- `when`: AI-evaluated conditions for branching
|
|
62
63
|
|
|
63
64
|
## Tool Integration
|
|
64
65
|
|
|
65
|
-
Steps can execute tools
|
|
66
|
+
Steps can execute tools that work with complete agent-level data:
|
|
66
67
|
|
|
67
68
|
```typescript
|
|
68
69
|
const weatherStep = planningStep.nextStep({
|
|
69
70
|
prompt: "I'll check the weather for your destination",
|
|
70
|
-
tool: weatherLookupTool,
|
|
71
|
-
requires: ["destination", "
|
|
71
|
+
tool: weatherLookupTool, // Tool receives complete agent data
|
|
72
|
+
requires: ["destination", "checkIn"], // Prerequisites from agent data
|
|
72
73
|
});
|
|
74
|
+
|
|
75
|
+
// Tool implementation with agent data access
|
|
76
|
+
const weatherLookupTool: Tool<Context, [], WeatherData, HotelData> = {
|
|
77
|
+
id: "weather_lookup",
|
|
78
|
+
description: "Look up weather for destination",
|
|
79
|
+
parameters: { type: "object", properties: {} },
|
|
80
|
+
handler: async (toolContext) => {
|
|
81
|
+
const { data } = toolContext; // Complete agent data
|
|
82
|
+
|
|
83
|
+
if (!data.destination || !data.checkIn) {
|
|
84
|
+
return { data: undefined };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const weather = await getWeather(data.destination, data.checkIn);
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
data: weather,
|
|
91
|
+
dataUpdate: {
|
|
92
|
+
weatherInfo: weather.summary // Update agent data
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
73
97
|
```
|
|
74
98
|
|
|
75
99
|
## Step Transitions
|
|
@@ -58,8 +58,9 @@ The system intelligently traverses step chains:
|
|
|
58
58
|
All routing decisions consider:
|
|
59
59
|
|
|
60
60
|
- **Conversation History**: Full dialogue context
|
|
61
|
-
- **
|
|
62
|
-
- **Session State**: Current route and step position
|
|
61
|
+
- **Agent-Level Data**: Centralized information gathered across all routes
|
|
62
|
+
- **Session State**: Current route and step position with cross-route data access
|
|
63
|
+
- **Route Completion**: Progress toward required fields for each route
|
|
63
64
|
- **Agent Knowledge**: Guidelines, terms, and domain knowledge
|
|
64
65
|
|
|
65
66
|
## Route Selection API
|
|
@@ -107,20 +108,27 @@ The `getCandidateSteps()` method implements sophisticated logic:
|
|
|
107
108
|
const candidates = routingEngine.getCandidateSteps(
|
|
108
109
|
route, // Current route
|
|
109
110
|
currentStep, // Current step (or null for route start)
|
|
110
|
-
|
|
111
|
+
agentData // Agent-level data collected across all routes
|
|
111
112
|
);
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
### SkipIf Processing
|
|
115
116
|
|
|
116
|
-
Steps are automatically filtered based on conditions:
|
|
117
|
+
Steps are automatically filtered based on agent-level data conditions:
|
|
117
118
|
|
|
118
119
|
```typescript
|
|
119
|
-
// Step definition with skipIf
|
|
120
|
+
// Step definition with skipIf using agent data
|
|
120
121
|
initialStep: {
|
|
121
122
|
prompt: "What's your name?",
|
|
122
123
|
collect: ["name"],
|
|
123
|
-
skipIf: (data) => data.name !== undefined // Skip if name already collected
|
|
124
|
+
skipIf: (data) => data.name !== undefined // Skip if name already collected by any route
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Cross-route skipping example
|
|
128
|
+
const emailStep = {
|
|
129
|
+
prompt: "What's your email?",
|
|
130
|
+
collect: ["email"],
|
|
131
|
+
skipIf: (data) => data.email !== undefined // Skip if collected in different route
|
|
124
132
|
}
|
|
125
133
|
```
|
|
126
134
|
|
|
@@ -155,8 +163,9 @@ const routingPrompt = await routingEngine.buildRoutingPrompt({
|
|
|
155
163
|
Prompts include:
|
|
156
164
|
|
|
157
165
|
- Agent identity and personality
|
|
158
|
-
- Available routes with descriptions and
|
|
159
|
-
- Session context and collected data
|
|
166
|
+
- Available routes with descriptions and required fields
|
|
167
|
+
- Session context and agent-level collected data
|
|
168
|
+
- Route completion progress (e.g., "2/3 required fields collected")
|
|
160
169
|
- Scoring guidelines (90-100 scale)
|
|
161
170
|
- Conversation history and directives
|
|
162
171
|
|
|
@@ -169,7 +178,7 @@ const stepPrompt = await routingEngine.buildStepSelectionPrompt({
|
|
|
169
178
|
route,
|
|
170
179
|
currentStep,
|
|
171
180
|
candidates,
|
|
172
|
-
data:
|
|
181
|
+
data: agent.getCollectedData(), // Agent-level data
|
|
173
182
|
history,
|
|
174
183
|
lastMessage,
|
|
175
184
|
agentOptions,
|
|
@@ -18,7 +18,7 @@ Tools are created as objects implementing the `Tool` interface:
|
|
|
18
18
|
```typescript
|
|
19
19
|
import { Tool } from "@falai/agent";
|
|
20
20
|
|
|
21
|
-
const weatherTool: Tool<unknown, [], string
|
|
21
|
+
const weatherTool: Tool<unknown, WeatherData, [], string> = {
|
|
22
22
|
id: "get_weather",
|
|
23
23
|
name: "Weather Forecast", // Human-readable name shown to AI models
|
|
24
24
|
description: "Get current weather and forecast for a location",
|
|
@@ -48,7 +48,7 @@ const weatherTool: Tool<unknown, [], string, WeatherData> = {
|
|
|
48
48
|
The optional `name` field provides a human-readable name for the tool that is displayed to AI models. When provided, this name takes precedence over the `id` field in AI provider interactions:
|
|
49
49
|
|
|
50
50
|
```typescript
|
|
51
|
-
const calculatorTool: Tool<unknown, [], string
|
|
51
|
+
const calculatorTool: Tool<unknown, CalcData, [], string> = {
|
|
52
52
|
id: "math_calculator", // Internal identifier
|
|
53
53
|
name: "Math Calculator", // Display name for AI models
|
|
54
54
|
description: "Perform mathematical calculations",
|
|
@@ -68,7 +68,7 @@ const calculatorTool: Tool<unknown, [], string, CalcData> = {
|
|
|
68
68
|
Tool parameters are defined using JSON Schema:
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
|
-
const searchTool: Tool<unknown, [], string
|
|
71
|
+
const searchTool: Tool<unknown, SearchData, [], string> = {
|
|
72
72
|
id: "web_search",
|
|
73
73
|
name: "Web Search Engine",
|
|
74
74
|
description: "Search the web for information",
|
|
@@ -110,7 +110,7 @@ Tools receive execution context including:
|
|
|
110
110
|
- **Route information** - Current route and step details
|
|
111
111
|
|
|
112
112
|
```typescript
|
|
113
|
-
const userProfileTool: Tool<unknown, [], string
|
|
113
|
+
const userProfileTool: Tool<unknown, UserData, [], string> = {
|
|
114
114
|
id: "get_user_profile",
|
|
115
115
|
description: "Retrieve user profile information",
|
|
116
116
|
parameters: {
|
|
@@ -159,7 +159,7 @@ interface ToolResult {
|
|
|
159
159
|
Tools can modify conversation context:
|
|
160
160
|
|
|
161
161
|
```typescript
|
|
162
|
-
const locationTool: Tool<unknown, [], string
|
|
162
|
+
const locationTool: Tool<unknown, LocationData, [], string> = {
|
|
163
163
|
id: "set_location",
|
|
164
164
|
description: "Update the user's location in context",
|
|
165
165
|
parameters: {
|
|
@@ -187,7 +187,7 @@ const locationTool: Tool<unknown, [], string, LocationData> = {
|
|
|
187
187
|
Tools can update session data collected during conversation:
|
|
188
188
|
|
|
189
189
|
```typescript
|
|
190
|
-
const validationTool: Tool<unknown, [], string
|
|
190
|
+
const validationTool: Tool<unknown, BookingData, [], string> = {
|
|
191
191
|
id: "validate_booking",
|
|
192
192
|
description: "Validate booking information and update session data",
|
|
193
193
|
parameters: {
|
|
@@ -223,7 +223,7 @@ const validationTool: Tool<unknown, [], string, BookingData> = {
|
|
|
223
223
|
Tools should handle errors gracefully:
|
|
224
224
|
|
|
225
225
|
```typescript
|
|
226
|
-
const apiTool: Tool<unknown, [], string
|
|
226
|
+
const apiTool: Tool<unknown, ApiData, [], string> = {
|
|
227
227
|
id: "call_external_api",
|
|
228
228
|
description: "Call an external API endpoint",
|
|
229
229
|
parameters: {
|
|
@@ -303,7 +303,7 @@ When multiple tools with the same name exist, priority is:
|
|
|
303
303
|
Tools support async operations and Promises:
|
|
304
304
|
|
|
305
305
|
```typescript
|
|
306
|
-
const asyncTool: Tool<unknown, [], string
|
|
306
|
+
const asyncTool: Tool<unknown, ProcessingData, [], string> = {
|
|
307
307
|
id: "process_data",
|
|
308
308
|
description: "Process data asynchronously with heavy computation",
|
|
309
309
|
parameters: {
|