@falai/agent 0.4.1 → 0.5.1
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 +21 -74
- package/dist/cjs/core/Agent.d.ts +22 -29
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +464 -291
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/Events.d.ts +10 -1
- package/dist/cjs/core/Events.d.ts.map +1 -1
- package/dist/cjs/core/Events.js +3 -2
- package/dist/cjs/core/Events.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +19 -0
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -1
- package/dist/cjs/core/PersistenceManager.js +55 -0
- package/dist/cjs/core/PersistenceManager.js.map +1 -1
- package/dist/cjs/core/PromptComposer.d.ts +24 -0
- package/dist/cjs/core/PromptComposer.d.ts.map +1 -0
- package/dist/cjs/core/PromptComposer.js +127 -0
- package/dist/cjs/core/PromptComposer.js.map +1 -0
- package/dist/cjs/core/ResponseEngine.d.ts +19 -0
- package/dist/cjs/core/ResponseEngine.d.ts.map +1 -0
- package/dist/cjs/core/ResponseEngine.js +51 -0
- package/dist/cjs/core/ResponseEngine.js.map +1 -0
- package/dist/cjs/core/Route.d.ts +18 -12
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +15 -9
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/core/RoutingEngine.d.ts +38 -0
- package/dist/cjs/core/RoutingEngine.d.ts.map +1 -0
- package/dist/cjs/core/RoutingEngine.js +110 -0
- package/dist/cjs/core/RoutingEngine.js.map +1 -0
- package/dist/cjs/core/State.d.ts +15 -4
- package/dist/cjs/core/State.d.ts.map +1 -1
- package/dist/cjs/core/State.js +21 -2
- package/dist/cjs/core/State.js.map +1 -1
- package/dist/cjs/core/ToolExecutor.d.ts +29 -0
- package/dist/cjs/core/ToolExecutor.d.ts.map +1 -0
- package/dist/cjs/core/ToolExecutor.js +73 -0
- package/dist/cjs/core/ToolExecutor.js.map +1 -0
- package/dist/cjs/core/Transition.d.ts +5 -5
- package/dist/cjs/core/Transition.d.ts.map +1 -1
- package/dist/cjs/core/Transition.js.map +1 -1
- package/dist/cjs/index.d.ts +6 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +10 -13
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +12 -8
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +10 -53
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +10 -53
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +13 -12
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +8 -2
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +8 -0
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +0 -3
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +1 -3
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/route.d.ts +39 -4
- package/dist/cjs/types/route.d.ts.map +1 -1
- package/dist/cjs/types/routing.d.ts +16 -0
- package/dist/cjs/types/routing.d.ts.map +1 -0
- package/dist/cjs/types/routing.js +3 -0
- package/dist/cjs/types/routing.js.map +1 -0
- package/dist/cjs/types/schema.d.ts +22 -0
- package/dist/cjs/types/schema.d.ts.map +1 -0
- package/dist/cjs/types/schema.js +3 -0
- package/dist/cjs/types/schema.js.map +1 -0
- package/dist/cjs/types/session.d.ts +77 -0
- package/dist/cjs/types/session.d.ts.map +1 -0
- package/dist/cjs/types/session.js +146 -0
- package/dist/cjs/types/session.js.map +1 -0
- package/dist/cjs/types/tool.d.ts +11 -5
- package/dist/cjs/types/tool.d.ts.map +1 -1
- package/dist/cjs/utils/id.d.ts +0 -5
- package/dist/cjs/utils/id.d.ts.map +1 -1
- package/dist/cjs/utils/id.js +0 -10
- package/dist/cjs/utils/id.js.map +1 -1
- package/dist/cjs/utils/schema.d.ts +17 -0
- package/dist/cjs/utils/schema.d.ts.map +1 -0
- package/dist/cjs/utils/schema.js +32 -0
- package/dist/cjs/utils/schema.js.map +1 -0
- package/dist/core/Agent.d.ts +22 -29
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +464 -291
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/Events.d.ts +10 -1
- package/dist/core/Events.d.ts.map +1 -1
- package/dist/core/Events.js +3 -2
- package/dist/core/Events.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +19 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -1
- package/dist/core/PersistenceManager.js +55 -0
- package/dist/core/PersistenceManager.js.map +1 -1
- package/dist/core/PromptComposer.d.ts +24 -0
- package/dist/core/PromptComposer.d.ts.map +1 -0
- package/dist/core/PromptComposer.js +123 -0
- package/dist/core/PromptComposer.js.map +1 -0
- package/dist/core/ResponseEngine.d.ts +19 -0
- package/dist/core/ResponseEngine.d.ts.map +1 -0
- package/dist/core/ResponseEngine.js +47 -0
- package/dist/core/ResponseEngine.js.map +1 -0
- package/dist/core/Route.d.ts +18 -12
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +15 -9
- package/dist/core/Route.js.map +1 -1
- package/dist/core/RoutingEngine.d.ts +38 -0
- package/dist/core/RoutingEngine.d.ts.map +1 -0
- package/dist/core/RoutingEngine.js +106 -0
- package/dist/core/RoutingEngine.js.map +1 -0
- package/dist/core/State.d.ts +15 -4
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +21 -2
- package/dist/core/State.js.map +1 -1
- package/dist/core/ToolExecutor.d.ts +29 -0
- package/dist/core/ToolExecutor.d.ts.map +1 -0
- package/dist/core/ToolExecutor.js +69 -0
- package/dist/core/ToolExecutor.js.map +1 -0
- package/dist/core/Transition.d.ts +5 -5
- package/dist/core/Transition.d.ts.map +1 -1
- package/dist/core/Transition.js.map +1 -1
- package/dist/index.d.ts +6 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +10 -13
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +12 -8
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +10 -53
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +10 -53
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/types/agent.d.ts +13 -12
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +8 -2
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/history.d.ts +8 -0
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/route.d.ts +39 -4
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/routing.d.ts +16 -0
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/types/routing.js +2 -0
- package/dist/types/routing.js.map +1 -0
- package/dist/types/schema.d.ts +22 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +2 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/session.d.ts +77 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +138 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/tool.d.ts +11 -5
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/id.d.ts +0 -5
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +0 -9
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/schema.d.ts +17 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +27 -0
- package/dist/utils/schema.js.map +1 -0
- package/docs/ADAPTERS.md +83 -3
- package/docs/API_REFERENCE.md +329 -104
- package/docs/ARCHITECTURE.md +284 -286
- package/docs/CONSTRUCTOR_OPTIONS.md +192 -135
- package/docs/CONTEXT_MANAGEMENT.md +311 -28
- package/docs/CONTRIBUTING.md +1 -1
- package/docs/DOMAINS.md +61 -0
- package/docs/GETTING_STARTED.md +177 -88
- package/docs/PERSISTENCE.md +170 -23
- package/docs/README.md +7 -10
- package/examples/business-onboarding.ts +21 -9
- package/examples/company-qna-agent.ts +508 -0
- package/examples/declarative-agent.ts +143 -26
- package/examples/domain-scoping.ts +31 -10
- package/examples/extracted-data-modification.ts +415 -0
- package/examples/healthcare-agent.ts +194 -90
- package/examples/openai-agent.ts +67 -25
- package/examples/opensearch-persistence.ts +455 -151
- package/examples/persistent-onboarding.ts +162 -96
- package/examples/prisma-persistence.ts +371 -125
- package/examples/redis-persistence.ts +393 -23
- package/examples/rules-prohibitions.ts +32 -11
- package/examples/streaming-agent.ts +61 -13
- package/examples/travel-agent.ts +266 -133
- package/package.json +1 -1
- package/src/core/Agent.ts +668 -356
- package/src/core/Events.ts +12 -2
- package/src/core/PersistenceManager.ts +81 -0
- package/src/core/PromptComposer.ts +143 -0
- package/src/core/ResponseEngine.ts +82 -0
- package/src/core/Route.ts +32 -17
- package/src/core/RoutingEngine.ts +165 -0
- package/src/core/State.ts +55 -15
- package/src/core/ToolExecutor.ts +117 -0
- package/src/core/Transition.ts +5 -5
- package/src/index.ts +12 -21
- package/src/providers/AnthropicProvider.ts +10 -13
- package/src/providers/GeminiProvider.ts +12 -8
- package/src/providers/OpenAIProvider.ts +10 -56
- package/src/providers/OpenRouterProvider.ts +10 -56
- package/src/types/agent.ts +16 -13
- package/src/types/ai.ts +6 -2
- package/src/types/history.ts +8 -0
- package/src/types/index.ts +0 -11
- package/src/types/route.ts +41 -5
- package/src/types/routing.ts +18 -0
- package/src/types/schema.ts +23 -0
- package/src/types/session.ts +219 -0
- package/src/types/tool.ts +29 -7
- package/src/utils/id.ts +0 -10
- package/src/utils/schema.ts +32 -0
- package/dist/cjs/core/ConditionEvaluator.d.ts +0 -72
- package/dist/cjs/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/cjs/core/ConditionEvaluator.js +0 -272
- package/dist/cjs/core/ConditionEvaluator.js.map +0 -1
- package/dist/cjs/core/Observation.d.ts +0 -24
- package/dist/cjs/core/Observation.d.ts.map +0 -1
- package/dist/cjs/core/Observation.js +0 -39
- package/dist/cjs/core/Observation.js.map +0 -1
- package/dist/cjs/core/PreparationEngine.d.ts +0 -116
- package/dist/cjs/core/PreparationEngine.d.ts.map +0 -1
- package/dist/cjs/core/PreparationEngine.js +0 -353
- package/dist/cjs/core/PreparationEngine.js.map +0 -1
- package/dist/cjs/core/PromptBuilder.d.ts +0 -136
- package/dist/cjs/core/PromptBuilder.d.ts.map +0 -1
- package/dist/cjs/core/PromptBuilder.js +0 -421
- package/dist/cjs/core/PromptBuilder.js.map +0 -1
- package/dist/cjs/types/observation.d.ts +0 -27
- package/dist/cjs/types/observation.d.ts.map +0 -1
- package/dist/cjs/types/observation.js +0 -6
- package/dist/cjs/types/observation.js.map +0 -1
- package/dist/cjs/types/prompt.d.ts +0 -46
- package/dist/cjs/types/prompt.d.ts.map +0 -1
- package/dist/cjs/types/prompt.js +0 -19
- package/dist/cjs/types/prompt.js.map +0 -1
- package/dist/core/ConditionEvaluator.d.ts +0 -72
- package/dist/core/ConditionEvaluator.d.ts.map +0 -1
- package/dist/core/ConditionEvaluator.js +0 -268
- package/dist/core/ConditionEvaluator.js.map +0 -1
- package/dist/core/Observation.d.ts +0 -24
- package/dist/core/Observation.d.ts.map +0 -1
- package/dist/core/Observation.js +0 -35
- package/dist/core/Observation.js.map +0 -1
- package/dist/core/PreparationEngine.d.ts +0 -116
- package/dist/core/PreparationEngine.d.ts.map +0 -1
- package/dist/core/PreparationEngine.js +0 -349
- package/dist/core/PreparationEngine.js.map +0 -1
- package/dist/core/PromptBuilder.d.ts +0 -136
- package/dist/core/PromptBuilder.d.ts.map +0 -1
- package/dist/core/PromptBuilder.js +0 -417
- package/dist/core/PromptBuilder.js.map +0 -1
- package/dist/types/observation.d.ts +0 -27
- package/dist/types/observation.d.ts.map +0 -1
- package/dist/types/observation.js +0 -5
- package/dist/types/observation.js.map +0 -1
- package/dist/types/prompt.d.ts +0 -46
- package/dist/types/prompt.d.ts.map +0 -1
- package/dist/types/prompt.js +0 -16
- package/dist/types/prompt.js.map +0 -1
- package/docs/STRUCTURE.md +0 -58
- package/src/core/ConditionEvaluator.ts +0 -381
- package/src/core/Observation.ts +0 -47
- package/src/core/PreparationEngine.ts +0 -561
- package/src/core/PromptBuilder.ts +0 -617
- package/src/types/observation.ts +0 -29
- package/src/types/prompt.ts +0 -49
package/docs/ADAPTERS.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
All adapters follow the **provider pattern** - no dependencies required in the package, users install only what they need.
|
|
4
4
|
|
|
5
|
+
**NEW**: All adapters now support the new **Session State** pattern with automatic persistence of extracted data, current route/state, and conversation progress!
|
|
6
|
+
|
|
5
7
|
## ✅ Implemented Adapters
|
|
6
8
|
|
|
7
9
|
### 1. **PrismaAdapter**
|
|
@@ -73,11 +75,17 @@ All adapters follow the **provider pattern** - no dependencies required in the p
|
|
|
73
75
|
|
|
74
76
|
## 🎯 Usage Pattern
|
|
75
77
|
|
|
76
|
-
All adapters follow the same simple pattern:
|
|
78
|
+
All adapters follow the same simple pattern with full session state support:
|
|
77
79
|
|
|
78
80
|
```typescript
|
|
79
81
|
import { Agent, [Adapter]Adapter } from "@falai/agent";
|
|
80
82
|
|
|
83
|
+
// Define your data extraction type
|
|
84
|
+
interface YourDataType {
|
|
85
|
+
field1: string;
|
|
86
|
+
field2: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
81
89
|
const adapter = new [Adapter]Adapter({
|
|
82
90
|
client: yourClientInstance,
|
|
83
91
|
// ... adapter-specific options
|
|
@@ -87,9 +95,45 @@ const agent = new Agent({
|
|
|
87
95
|
persistence: {
|
|
88
96
|
adapter,
|
|
89
97
|
userId: "user_123",
|
|
90
|
-
autoSave: true,
|
|
98
|
+
autoSave: true, // ✨ Auto-saves session state!
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Create a route with data extraction
|
|
103
|
+
const route = agent.createRoute<YourDataType>({
|
|
104
|
+
title: "My Route",
|
|
105
|
+
gatherSchema: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
field1: { type: "string" },
|
|
109
|
+
field2: { type: "number" },
|
|
110
|
+
},
|
|
111
|
+
required: ["field1", "field2"],
|
|
91
112
|
},
|
|
92
113
|
});
|
|
114
|
+
|
|
115
|
+
// Define states
|
|
116
|
+
route.initialState.transitionTo({
|
|
117
|
+
chatState: "Collect data",
|
|
118
|
+
gather: ["field1", "field2"],
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Use with session state
|
|
122
|
+
const persistence = agent.getPersistenceManager();
|
|
123
|
+
const { sessionData, sessionState } =
|
|
124
|
+
await persistence.createSessionWithState<YourDataType>({
|
|
125
|
+
userId: "user_123",
|
|
126
|
+
agentName: "My Agent",
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Chat with automatic session state persistence
|
|
130
|
+
const response = await agent.respond({
|
|
131
|
+
history: [...],
|
|
132
|
+
session: sessionState, // Pass session state
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Session state auto-saved! Includes extracted data
|
|
136
|
+
console.log("Extracted:", response.session?.extracted);
|
|
93
137
|
```
|
|
94
138
|
|
|
95
139
|
## 🔌 Optional Dependencies
|
|
@@ -150,9 +194,45 @@ export class MyCustomAdapter implements PersistenceAdapter {
|
|
|
150
194
|
|
|
151
195
|
All adapters are fully typed with **zero `any` types** (except for Prisma's dynamic model access):
|
|
152
196
|
|
|
153
|
-
- Generic client interfaces
|
|
197
|
+
- Generic client interfaces with `SessionState<TExtracted>` support
|
|
154
198
|
- Typed repository methods
|
|
155
199
|
- Full IDE autocomplete
|
|
200
|
+
- Type-safe data extraction throughout
|
|
201
|
+
|
|
202
|
+
## 💾 What Gets Stored
|
|
203
|
+
|
|
204
|
+
All adapters store session state in the `collectedData` JSON field:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"extracted": {
|
|
209
|
+
"destination": "Paris",
|
|
210
|
+
"departureDate": "2025-06-15",
|
|
211
|
+
"passengers": 2
|
|
212
|
+
},
|
|
213
|
+
"routeHistory": [
|
|
214
|
+
{
|
|
215
|
+
"routeId": "book_flight",
|
|
216
|
+
"enteredAt": "2025-10-15T10:00:00Z",
|
|
217
|
+
"completed": false
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"currentRouteTitle": "Book a Flight",
|
|
221
|
+
"currentStateDescription": "Ask about travel dates",
|
|
222
|
+
"metadata": {
|
|
223
|
+
"sessionId": "session_123",
|
|
224
|
+
"createdAt": "2025-10-15T10:00:00Z",
|
|
225
|
+
"lastUpdatedAt": "2025-10-15T10:05:00Z"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This allows:
|
|
231
|
+
|
|
232
|
+
- ✅ Full session state recovery
|
|
233
|
+
- ✅ Analytics on extracted data
|
|
234
|
+
- ✅ Conversation progress tracking
|
|
235
|
+
- ✅ Multi-turn conversation support
|
|
156
236
|
|
|
157
237
|
## 🚀 Coming Soon
|
|
158
238
|
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -36,10 +36,6 @@ Adds a behavioral guideline. Returns `this` for chaining.
|
|
|
36
36
|
|
|
37
37
|
Adds an agent capability. Returns `this` for chaining.
|
|
38
38
|
|
|
39
|
-
##### `createObservation(description: string): Observation`
|
|
40
|
-
|
|
41
|
-
Creates an observation for disambiguation.
|
|
42
|
-
|
|
43
39
|
##### `addDomain<TName, TDomain>(name: TName, domainObject: TDomain): void`
|
|
44
40
|
|
|
45
41
|
Registers a domain with tools/methods.
|
|
@@ -54,12 +50,12 @@ Gets allowed domains for a specific route by title. Returns filtered domains bas
|
|
|
54
50
|
|
|
55
51
|
##### `respond(input: RespondInput<TContext>): Promise<RespondOutput>`
|
|
56
52
|
|
|
57
|
-
Generates an AI response
|
|
53
|
+
Generates an AI response with session state management, data extraction, and intelligent routing.
|
|
58
54
|
|
|
59
55
|
```typescript
|
|
60
56
|
interface RespondInput<TContext> {
|
|
61
57
|
history: Event[];
|
|
62
|
-
|
|
58
|
+
session?: SessionState; // NEW: Session state for conversation tracking
|
|
63
59
|
contextOverride?: Partial<TContext>;
|
|
64
60
|
signal?: AbortSignal;
|
|
65
61
|
}
|
|
@@ -67,11 +63,9 @@ interface RespondInput<TContext> {
|
|
|
67
63
|
interface RespondOutput {
|
|
68
64
|
/** The message to send to the user */
|
|
69
65
|
message: string;
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
state?: { id: string; description?: string };
|
|
74
|
-
/** Tool calls requested by the agent */
|
|
66
|
+
/** Updated session state (includes extracted data, current route/state) */
|
|
67
|
+
session?: SessionState;
|
|
68
|
+
/** Tool calls executed during response (for debugging) */
|
|
75
69
|
toolCalls?: Array<{
|
|
76
70
|
toolName: string;
|
|
77
71
|
arguments: Record<string, unknown>;
|
|
@@ -79,12 +73,19 @@ interface RespondOutput {
|
|
|
79
73
|
}
|
|
80
74
|
```
|
|
81
75
|
|
|
82
|
-
**Enhanced Response
|
|
76
|
+
**Enhanced Response Pipeline:**
|
|
77
|
+
|
|
78
|
+
1. **Tool Execution** - Execute tools if current state has `toolState`
|
|
79
|
+
2. **Always-On Routing** - Score all routes, respect user intent to change direction
|
|
80
|
+
3. **State Traversal** - Use `skipIf` and `requiredData` to determine next state
|
|
81
|
+
4. **Response Generation** - Build schema with `gather` fields, extract data
|
|
82
|
+
5. **Session Update** - Merge extracted data into session state
|
|
83
|
+
|
|
84
|
+
**Session State Management:**
|
|
83
85
|
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
- Returns tool calls for execution in your application
|
|
86
|
+
- Tracks current route, state, and extracted data across turns
|
|
87
|
+
- Enables "I changed my mind" scenarios with context-aware routing
|
|
88
|
+
- Automatically merges new extracted data with existing session data
|
|
88
89
|
|
|
89
90
|
**Example:**
|
|
90
91
|
|
|
@@ -239,7 +240,7 @@ Represents a conversation flow with states and transitions.
|
|
|
239
240
|
```typescript
|
|
240
241
|
new Route(options: RouteOptions)
|
|
241
242
|
|
|
242
|
-
interface RouteOptions {
|
|
243
|
+
interface RouteOptions<TExtracted = unknown> {
|
|
243
244
|
id?: string; // Optional custom ID (deterministic ID generated from title if not provided)
|
|
244
245
|
title: string; // Route title
|
|
245
246
|
description?: string; // Route description
|
|
@@ -248,6 +249,17 @@ interface RouteOptions {
|
|
|
248
249
|
domains?: string[]; // Domain names allowed in this route (undefined = all domains)
|
|
249
250
|
rules?: string[]; // Absolute rules the agent MUST follow in this route
|
|
250
251
|
prohibitions?: string[]; // Absolute prohibitions the agent MUST NEVER do in this route
|
|
252
|
+
|
|
253
|
+
// NEW: Schema-first data extraction
|
|
254
|
+
gatherSchema?: {
|
|
255
|
+
type: "object";
|
|
256
|
+
properties: Record<string, any>;
|
|
257
|
+
required?: string[];
|
|
258
|
+
additionalProperties?: boolean;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// NEW: Pre-populate extracted data when entering route
|
|
262
|
+
initialData?: Partial<TExtracted>;
|
|
251
263
|
}
|
|
252
264
|
```
|
|
253
265
|
|
|
@@ -279,10 +291,6 @@ Returns the prohibitions that must never be done in this route.
|
|
|
279
291
|
|
|
280
292
|
Returns a reference to this route.
|
|
281
293
|
|
|
282
|
-
##### `toRef(): RouteRef`
|
|
283
|
-
|
|
284
|
-
Returns a reference including the route instance (for disambiguation).
|
|
285
|
-
|
|
286
294
|
##### `describe(): string`
|
|
287
295
|
|
|
288
296
|
Generates a description of this route's structure.
|
|
@@ -322,16 +330,28 @@ Represents a state within a conversation route.
|
|
|
322
330
|
Creates a transition from this state and returns a chainable result.
|
|
323
331
|
|
|
324
332
|
```typescript
|
|
325
|
-
interface TransitionSpec {
|
|
333
|
+
interface TransitionSpec<TExtracted = unknown> {
|
|
326
334
|
chatState?: string; // Transition to a chat interaction
|
|
327
335
|
toolState?: ToolRef; // Transition to execute a tool
|
|
328
336
|
state?: StateRef | symbol; // Transition to specific state or END_ROUTE
|
|
337
|
+
|
|
338
|
+
// NEW: Data extraction fields for this state
|
|
339
|
+
gather?: string[];
|
|
340
|
+
|
|
341
|
+
// NEW: Code-based condition to skip this state
|
|
342
|
+
skipIf?: (extracted: Partial<TExtracted>) => boolean;
|
|
343
|
+
|
|
344
|
+
// NEW: Prerequisites that must be met to enter this state
|
|
345
|
+
requiredData?: string[];
|
|
329
346
|
}
|
|
330
347
|
|
|
331
|
-
interface TransitionResult {
|
|
348
|
+
interface TransitionResult<TExtracted = unknown> {
|
|
332
349
|
id: string; // State identifier
|
|
333
350
|
routeId: string; // Route identifier
|
|
334
|
-
transitionTo: (
|
|
351
|
+
transitionTo: (
|
|
352
|
+
spec: TransitionSpec<TExtracted>,
|
|
353
|
+
condition?: string
|
|
354
|
+
) => TransitionResult<TExtracted>;
|
|
335
355
|
}
|
|
336
356
|
```
|
|
337
357
|
|
|
@@ -340,39 +360,66 @@ interface TransitionResult {
|
|
|
340
360
|
**Example:**
|
|
341
361
|
|
|
342
362
|
```typescript
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
363
|
+
// Define your data extraction type
|
|
364
|
+
interface FlightData {
|
|
365
|
+
destination: string;
|
|
366
|
+
departureDate: string;
|
|
367
|
+
passengers: number;
|
|
368
|
+
}
|
|
347
369
|
|
|
348
|
-
|
|
349
|
-
|
|
370
|
+
// Create a data-driven route
|
|
371
|
+
const flightRoute = agent.createRoute<FlightData>({
|
|
372
|
+
title: "Book Flight",
|
|
373
|
+
gatherSchema: {
|
|
374
|
+
type: "object",
|
|
375
|
+
properties: {
|
|
376
|
+
destination: { type: "string" },
|
|
377
|
+
departureDate: { type: "string" },
|
|
378
|
+
passengers: { type: "number", minimum: 1, maximum: 9 },
|
|
379
|
+
},
|
|
380
|
+
required: ["destination", "departureDate", "passengers"],
|
|
381
|
+
},
|
|
350
382
|
});
|
|
351
383
|
|
|
352
|
-
|
|
353
|
-
|
|
384
|
+
// Approach 1: Step-by-step with data extraction
|
|
385
|
+
const askDestination = flightRoute.initialState.transitionTo({
|
|
386
|
+
chatState: "Ask where they want to fly",
|
|
387
|
+
gather: ["destination"],
|
|
388
|
+
skipIf: (extracted) => !!extracted.destination, // Skip if already have destination
|
|
354
389
|
});
|
|
355
390
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
391
|
+
const askDates = askDestination.transitionTo({
|
|
392
|
+
chatState: "Ask about travel dates",
|
|
393
|
+
gather: ["departureDate"],
|
|
394
|
+
skipIf: (extracted) => !!extracted.departureDate,
|
|
395
|
+
requiredData: ["destination"], // Must have destination first
|
|
396
|
+
});
|
|
359
397
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
);
|
|
398
|
+
const askPassengers = askDates.transitionTo({
|
|
399
|
+
chatState: "How many passengers?",
|
|
400
|
+
gather: ["passengers"],
|
|
401
|
+
skipIf: (extracted) => !!extracted.passengers,
|
|
402
|
+
});
|
|
365
403
|
|
|
366
|
-
//
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
404
|
+
// Access state properties
|
|
405
|
+
console.log(askDestination.id); // State ID
|
|
406
|
+
console.log(askDestination.routeId); // Route ID
|
|
407
|
+
|
|
408
|
+
// Approach 2: Fluent chaining for linear flows
|
|
409
|
+
flightRoute.initialState
|
|
410
|
+
.transitionTo({
|
|
411
|
+
chatState: "Extract travel details",
|
|
412
|
+
gather: ["destination", "departureDate", "passengers"],
|
|
413
|
+
})
|
|
414
|
+
.transitionTo({
|
|
415
|
+
chatState: "Present available flights",
|
|
416
|
+
})
|
|
371
417
|
.transitionTo({ state: END_ROUTE });
|
|
372
418
|
|
|
373
|
-
//
|
|
374
|
-
|
|
375
|
-
|
|
419
|
+
// Use with session state
|
|
420
|
+
let session = createSession<FlightData>();
|
|
421
|
+
const response = await agent.respond({ history, session });
|
|
422
|
+
console.log(response.session?.extracted); // { destination: "Paris", ... }
|
|
376
423
|
```
|
|
377
424
|
|
|
378
425
|
##### `addGuideline(guideline: Guideline): void`
|
|
@@ -395,46 +442,6 @@ State description (readonly).
|
|
|
395
442
|
|
|
396
443
|
---
|
|
397
444
|
|
|
398
|
-
### `Observation`
|
|
399
|
-
|
|
400
|
-
Handles disambiguation between multiple routes.
|
|
401
|
-
|
|
402
|
-
#### Constructor
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
new Observation(options: ObservationOptions)
|
|
406
|
-
|
|
407
|
-
interface ObservationOptions {
|
|
408
|
-
id?: string; // Optional custom ID (deterministic ID generated from description if not provided)
|
|
409
|
-
description: string; // The observation description
|
|
410
|
-
routeRefs?: string[]; // Route IDs or titles to disambiguate between
|
|
411
|
-
}
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
**Note on IDs:** Observation IDs are deterministic by default, generated from the description using a hash function. This ensures consistency across server restarts.
|
|
415
|
-
|
|
416
|
-
#### Methods
|
|
417
|
-
|
|
418
|
-
##### `disambiguate(routes: (Route | RouteRef)[]): this`
|
|
419
|
-
|
|
420
|
-
Sets routes this observation can disambiguate between. Returns `this` for chaining.
|
|
421
|
-
|
|
422
|
-
##### `getRoutes(): RouteRef[]`
|
|
423
|
-
|
|
424
|
-
Returns routes associated with this observation.
|
|
425
|
-
|
|
426
|
-
#### Properties
|
|
427
|
-
|
|
428
|
-
##### `id: string`
|
|
429
|
-
|
|
430
|
-
Unique identifier (readonly).
|
|
431
|
-
|
|
432
|
-
##### `description: string`
|
|
433
|
-
|
|
434
|
-
Observation description (readonly).
|
|
435
|
-
|
|
436
|
-
---
|
|
437
|
-
|
|
438
445
|
### `DomainRegistry`
|
|
439
446
|
|
|
440
447
|
Registry for organizing agent tools and methods by domain.
|
|
@@ -1214,10 +1221,6 @@ Adds guidelines section.
|
|
|
1214
1221
|
|
|
1215
1222
|
Adds capabilities section.
|
|
1216
1223
|
|
|
1217
|
-
##### `addObservations(observations): this`
|
|
1218
|
-
|
|
1219
|
-
Adds observations for disambiguation.
|
|
1220
|
-
|
|
1221
1224
|
##### `addActiveRoutes(routes): this`
|
|
1222
1225
|
|
|
1223
1226
|
Adds active routes to the prompt.
|
|
@@ -1427,6 +1430,240 @@ interface ToolResult<TReturn> {
|
|
|
1427
1430
|
|
|
1428
1431
|
## Types
|
|
1429
1432
|
|
|
1433
|
+
### `SessionState<TExtracted>`
|
|
1434
|
+
|
|
1435
|
+
Tracks the current position in the conversation flow and data extracted during route progression.
|
|
1436
|
+
|
|
1437
|
+
```typescript
|
|
1438
|
+
interface SessionState<TExtracted = Record<string, unknown>> {
|
|
1439
|
+
/** Unique session identifier (useful for persistence) */
|
|
1440
|
+
id?: string;
|
|
1441
|
+
|
|
1442
|
+
/** Current route the conversation is in */
|
|
1443
|
+
currentRoute?: {
|
|
1444
|
+
id: string;
|
|
1445
|
+
title: string;
|
|
1446
|
+
enteredAt: Date;
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
/** Current state within the route */
|
|
1450
|
+
currentState?: {
|
|
1451
|
+
id: string;
|
|
1452
|
+
description?: string;
|
|
1453
|
+
enteredAt: Date;
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1456
|
+
/** Data extracted during the current route */
|
|
1457
|
+
extracted: Partial<TExtracted>;
|
|
1458
|
+
|
|
1459
|
+
/** History of routes visited in this session */
|
|
1460
|
+
routeHistory: Array<{
|
|
1461
|
+
routeId: string;
|
|
1462
|
+
enteredAt: Date;
|
|
1463
|
+
exitedAt?: Date;
|
|
1464
|
+
completed: boolean;
|
|
1465
|
+
}>;
|
|
1466
|
+
|
|
1467
|
+
/** Session metadata */
|
|
1468
|
+
metadata?: {
|
|
1469
|
+
createdAt?: Date;
|
|
1470
|
+
lastUpdatedAt?: Date;
|
|
1471
|
+
[key: string]: unknown;
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
**Key Features:**
|
|
1477
|
+
|
|
1478
|
+
- **`id`** - Optional session identifier that persists across database operations
|
|
1479
|
+
- **`extracted`** - Type-safe data collected via `gatherSchema`
|
|
1480
|
+
- **`currentRoute`** / **`currentState`** - Track conversation position
|
|
1481
|
+
- **`routeHistory`** - Full audit trail of route transitions
|
|
1482
|
+
- **`metadata`** - Custom data (timestamps, user info, etc.)
|
|
1483
|
+
|
|
1484
|
+
**Usage:**
|
|
1485
|
+
|
|
1486
|
+
```typescript
|
|
1487
|
+
interface FlightData {
|
|
1488
|
+
destination: string;
|
|
1489
|
+
departureDate: string;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
// Create session with database ID
|
|
1493
|
+
const session = createSession<FlightData>("session_abc123");
|
|
1494
|
+
|
|
1495
|
+
// Use in conversation
|
|
1496
|
+
const response = await agent.respond({ history, session });
|
|
1497
|
+
|
|
1498
|
+
// Access extracted data
|
|
1499
|
+
console.log(response.session?.extracted.destination); // Type-safe!
|
|
1500
|
+
```
|
|
1501
|
+
|
|
1502
|
+
---
|
|
1503
|
+
|
|
1504
|
+
### Session Helper Functions
|
|
1505
|
+
|
|
1506
|
+
#### `createSession<TExtracted>(sessionId?, metadata?): SessionState<TExtracted>`
|
|
1507
|
+
|
|
1508
|
+
Creates a new session state object.
|
|
1509
|
+
|
|
1510
|
+
**Parameters:**
|
|
1511
|
+
|
|
1512
|
+
- `sessionId` (optional): Unique session identifier from database
|
|
1513
|
+
- `metadata` (optional): Additional metadata to attach
|
|
1514
|
+
|
|
1515
|
+
**Example:**
|
|
1516
|
+
|
|
1517
|
+
```typescript
|
|
1518
|
+
// Simple usage
|
|
1519
|
+
const session = createSession<OnboardingData>();
|
|
1520
|
+
|
|
1521
|
+
// With database ID (when loading from persistence)
|
|
1522
|
+
const session = createSession<OnboardingData>("session_123");
|
|
1523
|
+
|
|
1524
|
+
// With metadata
|
|
1525
|
+
const session = createSession<OnboardingData>("session_123", {
|
|
1526
|
+
userId: "user_456",
|
|
1527
|
+
channel: "whatsapp",
|
|
1528
|
+
});
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
#### `enterRoute<TExtracted>(session, routeId, routeTitle): SessionState<TExtracted>`
|
|
1532
|
+
|
|
1533
|
+
Updates session when entering a new route. Automatically:
|
|
1534
|
+
|
|
1535
|
+
- Exits previous route (if exists)
|
|
1536
|
+
- Resets extracted data
|
|
1537
|
+
- Adds route to history
|
|
1538
|
+
- Updates timestamps
|
|
1539
|
+
|
|
1540
|
+
**Example:**
|
|
1541
|
+
|
|
1542
|
+
```typescript
|
|
1543
|
+
let session = createSession<FlightData>();
|
|
1544
|
+
|
|
1545
|
+
// Enter booking route
|
|
1546
|
+
session = enterRoute(session, "book_flight", "Book a Flight");
|
|
1547
|
+
|
|
1548
|
+
console.log(session.currentRoute?.title); // "Book a Flight"
|
|
1549
|
+
console.log(session.extracted); // {} (reset for new route)
|
|
1550
|
+
```
|
|
1551
|
+
|
|
1552
|
+
#### `enterState<TExtracted>(session, stateId, description?): SessionState<TExtracted>`
|
|
1553
|
+
|
|
1554
|
+
Updates session when entering a new state within a route.
|
|
1555
|
+
|
|
1556
|
+
**Example:**
|
|
1557
|
+
|
|
1558
|
+
```typescript
|
|
1559
|
+
session = enterState(session, "ask_destination", "Ask where to fly");
|
|
1560
|
+
|
|
1561
|
+
console.log(session.currentState?.id); // "ask_destination"
|
|
1562
|
+
console.log(session.currentState?.description); // "Ask where to fly"
|
|
1563
|
+
```
|
|
1564
|
+
|
|
1565
|
+
#### `mergeExtracted<TExtracted>(session, data): SessionState<TExtracted>`
|
|
1566
|
+
|
|
1567
|
+
Merges new extracted data into session. Updates timestamps automatically.
|
|
1568
|
+
|
|
1569
|
+
**Example:**
|
|
1570
|
+
|
|
1571
|
+
```typescript
|
|
1572
|
+
session = mergeExtracted(session, {
|
|
1573
|
+
destination: "Paris",
|
|
1574
|
+
departureDate: "2025-06-15",
|
|
1575
|
+
});
|
|
1576
|
+
|
|
1577
|
+
console.log(session.extracted); // { destination: "Paris", departureDate: "2025-06-15" }
|
|
1578
|
+
```
|
|
1579
|
+
|
|
1580
|
+
#### `sessionStateToData<TExtracted>(session): object`
|
|
1581
|
+
|
|
1582
|
+
Converts SessionState to persistence-friendly format for database storage.
|
|
1583
|
+
|
|
1584
|
+
**Returns:**
|
|
1585
|
+
|
|
1586
|
+
```typescript
|
|
1587
|
+
{
|
|
1588
|
+
currentRoute?: string; // Route ID
|
|
1589
|
+
currentState?: string; // State ID
|
|
1590
|
+
collectedData: { // All session data
|
|
1591
|
+
extracted: Partial<TExtracted>;
|
|
1592
|
+
routeHistory: Array<...>;
|
|
1593
|
+
currentRouteTitle?: string;
|
|
1594
|
+
currentStateDescription?: string;
|
|
1595
|
+
metadata?: object;
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
**Example:**
|
|
1601
|
+
|
|
1602
|
+
```typescript
|
|
1603
|
+
const session = createSession<FlightData>("session_123");
|
|
1604
|
+
// ... conversation happens ...
|
|
1605
|
+
|
|
1606
|
+
// Save to database
|
|
1607
|
+
const dbData = sessionStateToData(session);
|
|
1608
|
+
await db.sessions.update(session.id!, {
|
|
1609
|
+
currentRoute: dbData.currentRoute,
|
|
1610
|
+
currentState: dbData.currentState,
|
|
1611
|
+
collectedData: dbData.collectedData,
|
|
1612
|
+
});
|
|
1613
|
+
```
|
|
1614
|
+
|
|
1615
|
+
#### `sessionDataToState<TExtracted>(sessionId, data): SessionState<TExtracted>`
|
|
1616
|
+
|
|
1617
|
+
Converts database data back to SessionState for resuming conversations.
|
|
1618
|
+
|
|
1619
|
+
**Parameters:**
|
|
1620
|
+
|
|
1621
|
+
- `sessionId`: The database session ID
|
|
1622
|
+
- `data`: Database session data (currentRoute, currentState, collectedData)
|
|
1623
|
+
|
|
1624
|
+
**Example:**
|
|
1625
|
+
|
|
1626
|
+
```typescript
|
|
1627
|
+
// Load from database
|
|
1628
|
+
const dbSession = await db.sessions.findById("session_123");
|
|
1629
|
+
|
|
1630
|
+
// Restore session state
|
|
1631
|
+
const session = sessionDataToState<FlightData>(dbSession.id, {
|
|
1632
|
+
currentRoute: dbSession.currentRoute,
|
|
1633
|
+
currentState: dbSession.currentState,
|
|
1634
|
+
collectedData: dbSession.collectedData,
|
|
1635
|
+
});
|
|
1636
|
+
|
|
1637
|
+
// Resume conversation
|
|
1638
|
+
const response = await agent.respond({ history, session });
|
|
1639
|
+
```
|
|
1640
|
+
|
|
1641
|
+
**Complete Persistence Example:**
|
|
1642
|
+
|
|
1643
|
+
```typescript
|
|
1644
|
+
// CREATE: New session
|
|
1645
|
+
let session = createSession<FlightData>(dbSession.id);
|
|
1646
|
+
|
|
1647
|
+
// CONVERSATION: Extract data
|
|
1648
|
+
const response1 = await agent.respond({ history: history1, session });
|
|
1649
|
+
session = response1.session!; // { extracted: { destination: "Paris" } }
|
|
1650
|
+
|
|
1651
|
+
// SAVE: To database
|
|
1652
|
+
const saveData = sessionStateToData(session);
|
|
1653
|
+
await db.sessions.update(session.id!, saveData);
|
|
1654
|
+
|
|
1655
|
+
// --- Later (new request) ---
|
|
1656
|
+
|
|
1657
|
+
// LOAD: From database
|
|
1658
|
+
const loaded = await db.sessions.findById("session_123");
|
|
1659
|
+
const restored = sessionDataToState<FlightData>(loaded.id, loaded);
|
|
1660
|
+
|
|
1661
|
+
// CONTINUE: Conversation
|
|
1662
|
+
const response2 = await agent.respond({ history: history2, session: restored });
|
|
1663
|
+
```
|
|
1664
|
+
|
|
1665
|
+
---
|
|
1666
|
+
|
|
1430
1667
|
### `AgentStructuredResponse`
|
|
1431
1668
|
|
|
1432
1669
|
The structured response format returned by AI providers when JSON mode is enabled.
|
|
@@ -1479,17 +1716,6 @@ const stateId = generateStateId("route_123", "Ask for name");
|
|
|
1479
1716
|
// Returns: "state_ask_for_name_{hash}"
|
|
1480
1717
|
```
|
|
1481
1718
|
|
|
1482
|
-
#### `generateObservationId(description: string): string`
|
|
1483
|
-
|
|
1484
|
-
Generates a deterministic observation ID from a description.
|
|
1485
|
-
|
|
1486
|
-
```typescript
|
|
1487
|
-
import { generateObservationId } from "@falai/agent";
|
|
1488
|
-
|
|
1489
|
-
const obsId = generateObservationId("User intent is unclear");
|
|
1490
|
-
// Returns: "observation_user_intent_is_unclear_{hash}"
|
|
1491
|
-
```
|
|
1492
|
-
|
|
1493
1719
|
#### `generateToolId(name: string): string`
|
|
1494
1720
|
|
|
1495
1721
|
Generates a deterministic tool ID from a name.
|
|
@@ -1552,7 +1778,6 @@ enum BuiltInSection {
|
|
|
1552
1778
|
CONTEXT = "context",
|
|
1553
1779
|
GUIDELINES = "guidelines",
|
|
1554
1780
|
CAPABILITIES = "capabilities",
|
|
1555
|
-
OBSERVATIONS = "observations",
|
|
1556
1781
|
ACTIVE_ROUTES = "active_routes",
|
|
1557
1782
|
}
|
|
1558
1783
|
```
|