@falai/agent 0.3.11 → 0.3.12
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 +92 -0
- package/dist/adapters/PrismaAdapter.d.ts +115 -0
- package/dist/adapters/PrismaAdapter.d.ts.map +1 -0
- package/dist/adapters/PrismaAdapter.js +331 -0
- package/dist/adapters/PrismaAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/PrismaAdapter.d.ts +115 -0
- package/dist/cjs/adapters/PrismaAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/PrismaAdapter.js +335 -0
- package/dist/cjs/adapters/PrismaAdapter.js.map +1 -0
- package/dist/cjs/adapters/index.d.ts +6 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -0
- package/dist/cjs/adapters/index.js +9 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/core/Agent.d.ts +10 -0
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +23 -0
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/PersistenceManager.d.ts +77 -0
- package/dist/cjs/core/PersistenceManager.d.ts.map +1 -0
- package/dist/cjs/core/PersistenceManager.js +153 -0
- package/dist/cjs/core/PersistenceManager.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +3 -0
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/agent.js.map +1 -1
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/persistence.d.ts +194 -0
- package/dist/cjs/types/persistence.d.ts.map +1 -0
- package/dist/cjs/types/persistence.js +7 -0
- package/dist/cjs/types/persistence.js.map +1 -0
- package/dist/core/Agent.d.ts +10 -0
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +23 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/PersistenceManager.d.ts +77 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -0
- package/dist/core/PersistenceManager.js +149 -0
- package/dist/core/PersistenceManager.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/types/agent.d.ts +3 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/agent.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/persistence.d.ts +194 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/persistence.js +6 -0
- package/dist/types/persistence.js.map +1 -0
- package/docs/PERSISTENCE.md +419 -0
- package/examples/prisma-persistence.ts +313 -0
- package/examples/prisma-schema.example.prisma +74 -0
- package/package.json +9 -1
- package/src/adapters/PrismaAdapter.ts +510 -0
- package/src/adapters/index.ts +10 -0
- package/src/core/Agent.ts +31 -0
- package/src/core/PersistenceManager.ts +222 -0
- package/src/index.ts +21 -0
- package/src/types/agent.ts +3 -0
- package/src/types/index.ts +14 -0
- package/src/types/persistence.ts +234 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/types/persistence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/types/persistence.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# Persistence with @falai/agent
|
|
2
|
+
|
|
3
|
+
The `@falai/agent` framework provides optional, flexible persistence for automatically saving conversation sessions and messages to your database.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Optional** - Persistence is completely optional
|
|
8
|
+
- ✅ **Provider Pattern** - Simple API like AI providers (`new PrismaAdapter({ prisma })`)
|
|
9
|
+
- ✅ **Type-safe** - Full TypeScript support
|
|
10
|
+
- ✅ **Prisma Ready** - Built-in Prisma ORM adapter
|
|
11
|
+
- ✅ **Extensible** - Create adapters for any database
|
|
12
|
+
- ✅ **Auto-save** - Automatic message persistence
|
|
13
|
+
|
|
14
|
+
## Quick Start with Prisma
|
|
15
|
+
|
|
16
|
+
### 1. Install Dependencies
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @prisma/client prisma
|
|
20
|
+
npx prisma init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Set Up Schema
|
|
24
|
+
|
|
25
|
+
Copy this schema to `prisma/schema.prisma`:
|
|
26
|
+
|
|
27
|
+
```prisma
|
|
28
|
+
datasource db {
|
|
29
|
+
provider = "postgresql"
|
|
30
|
+
url = env("DATABASE_URL")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
generator client {
|
|
34
|
+
provider = "prisma-client-js"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
model AgentSession {
|
|
38
|
+
id String @id @default(cuid())
|
|
39
|
+
userId String? @map("user_id")
|
|
40
|
+
agentName String? @map("agent_name")
|
|
41
|
+
status String @default("active")
|
|
42
|
+
currentRoute String? @map("current_route")
|
|
43
|
+
currentState String? @map("current_state")
|
|
44
|
+
collectedData Json? @map("collected_data")
|
|
45
|
+
messageCount Int @default(0) @map("message_count")
|
|
46
|
+
lastMessageAt DateTime? @map("last_message_at")
|
|
47
|
+
completedAt DateTime? @map("completed_at")
|
|
48
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
49
|
+
updatedAt DateTime @updatedAt @map("updated_at")
|
|
50
|
+
|
|
51
|
+
messages AgentMessage[]
|
|
52
|
+
|
|
53
|
+
@@index([userId, status])
|
|
54
|
+
@@map("agent_sessions")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
model AgentMessage {
|
|
58
|
+
id String @id @default(cuid())
|
|
59
|
+
sessionId String @map("session_id")
|
|
60
|
+
userId String? @map("user_id")
|
|
61
|
+
role String
|
|
62
|
+
content String @db.Text
|
|
63
|
+
route String?
|
|
64
|
+
state String?
|
|
65
|
+
toolCalls Json? @map("tool_calls")
|
|
66
|
+
event Json?
|
|
67
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
68
|
+
|
|
69
|
+
session AgentSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
70
|
+
|
|
71
|
+
@@index([sessionId])
|
|
72
|
+
@@map("agent_messages")
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Generate and Migrate
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx prisma generate
|
|
80
|
+
npx prisma migrate dev --name init
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Use in Your Agent (That's it!)
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { Agent, PrismaAdapter, GeminiProvider } from "@falai/agent";
|
|
87
|
+
import { PrismaClient } from "@prisma/client";
|
|
88
|
+
|
|
89
|
+
const prisma = new PrismaClient();
|
|
90
|
+
|
|
91
|
+
const agent = new Agent({
|
|
92
|
+
name: "My Agent",
|
|
93
|
+
ai: new GeminiProvider({ apiKey: "..." }),
|
|
94
|
+
// ✨ Just add this!
|
|
95
|
+
persistence: {
|
|
96
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
97
|
+
userId: "user_123",
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Access persistence methods
|
|
102
|
+
const persistence = agent.getPersistenceManager();
|
|
103
|
+
|
|
104
|
+
// Create a session
|
|
105
|
+
const session = await persistence.createSession({
|
|
106
|
+
userId: "user_123",
|
|
107
|
+
agentName: "My Agent",
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Load history
|
|
111
|
+
const history = await persistence.loadSessionHistory(session.id);
|
|
112
|
+
|
|
113
|
+
// Generate response
|
|
114
|
+
const response = await agent.respond({ history });
|
|
115
|
+
|
|
116
|
+
// Save message (auto-saved if configured)
|
|
117
|
+
await persistence.saveMessage({
|
|
118
|
+
sessionId: session.id,
|
|
119
|
+
role: "agent",
|
|
120
|
+
content: response.message,
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Configuration Options
|
|
125
|
+
|
|
126
|
+
### Basic Configuration
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
new PrismaAdapter({
|
|
130
|
+
prisma: prismaClient, // Required: Your Prisma client
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Custom Table Names
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
new PrismaAdapter({
|
|
138
|
+
prisma,
|
|
139
|
+
tables: {
|
|
140
|
+
sessions: "myCustomSessions",
|
|
141
|
+
messages: "myCustomMessages",
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Custom Field Mappings
|
|
147
|
+
|
|
148
|
+
If your database uses different field names:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
new PrismaAdapter({
|
|
152
|
+
prisma,
|
|
153
|
+
fieldMappings: {
|
|
154
|
+
sessions: {
|
|
155
|
+
userId: "user_id",
|
|
156
|
+
createdAt: "created_at",
|
|
157
|
+
updatedAt: "updated_at",
|
|
158
|
+
},
|
|
159
|
+
messages: {
|
|
160
|
+
sessionId: "session_id",
|
|
161
|
+
createdAt: "created_at",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Auto-Save Messages
|
|
168
|
+
|
|
169
|
+
Enable automatic message persistence:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const agent = new Agent({
|
|
173
|
+
name: "My Agent",
|
|
174
|
+
ai: provider,
|
|
175
|
+
persistence: {
|
|
176
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
177
|
+
autoSave: true, // Default: true
|
|
178
|
+
userId: "user_123",
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Using with Lifecycle Hooks
|
|
184
|
+
|
|
185
|
+
The most powerful pattern - auto-sync context with database:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const agent = new Agent({
|
|
189
|
+
name: "Smart Assistant",
|
|
190
|
+
ai: provider,
|
|
191
|
+
context: {
|
|
192
|
+
userId: "user_123",
|
|
193
|
+
sessionId: session.id,
|
|
194
|
+
preferences: { theme: "light" },
|
|
195
|
+
},
|
|
196
|
+
hooks: {
|
|
197
|
+
// Load fresh context before each response
|
|
198
|
+
beforeRespond: async (ctx) => {
|
|
199
|
+
const persistence = agent.getPersistenceManager();
|
|
200
|
+
const session = await persistence?.getSession(ctx.sessionId);
|
|
201
|
+
return {
|
|
202
|
+
...ctx,
|
|
203
|
+
preferences: session?.collectedData?.preferences || ctx.preferences,
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
// Auto-save context updates
|
|
207
|
+
onContextUpdate: async (ctx) => {
|
|
208
|
+
const persistence = agent.getPersistenceManager();
|
|
209
|
+
await persistence?.updateCollectedData(ctx.sessionId, {
|
|
210
|
+
preferences: ctx.preferences,
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
persistence: {
|
|
215
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Now context updates are automatically persisted!
|
|
220
|
+
await agent.updateContext({ preferences: { theme: "dark" } });
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## PersistenceManager API
|
|
224
|
+
|
|
225
|
+
Access via `agent.getPersistenceManager()`:
|
|
226
|
+
|
|
227
|
+
### Session Methods
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// Create session
|
|
231
|
+
await persistence.createSession({
|
|
232
|
+
userId: "user_123",
|
|
233
|
+
agentName: "My Agent",
|
|
234
|
+
initialData: { key: "value" },
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Get session
|
|
238
|
+
await persistence.getSession(sessionId);
|
|
239
|
+
|
|
240
|
+
// Find active session for user
|
|
241
|
+
await persistence.findActiveSession(userId);
|
|
242
|
+
|
|
243
|
+
// Get all user sessions
|
|
244
|
+
await persistence.getUserSessions(userId);
|
|
245
|
+
|
|
246
|
+
// Update session
|
|
247
|
+
await persistence.updateSessionStatus(sessionId, "completed");
|
|
248
|
+
await persistence.updateCollectedData(sessionId, { key: "value" });
|
|
249
|
+
await persistence.updateRouteState(sessionId, routeId, stateId);
|
|
250
|
+
|
|
251
|
+
// Complete/abandon session
|
|
252
|
+
await persistence.completeSession(sessionId);
|
|
253
|
+
await persistence.abandonSession(sessionId);
|
|
254
|
+
|
|
255
|
+
// Delete session
|
|
256
|
+
await persistence.deleteSession(sessionId);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Message Methods
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Save message
|
|
263
|
+
await persistence.saveMessage({
|
|
264
|
+
sessionId: session.id,
|
|
265
|
+
userId: "user_123",
|
|
266
|
+
role: "user" | "agent" | "system",
|
|
267
|
+
content: "Hello!",
|
|
268
|
+
route: "route_id",
|
|
269
|
+
state: "state_id",
|
|
270
|
+
toolCalls: [...],
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Get messages
|
|
274
|
+
await persistence.getSessionMessages(sessionId);
|
|
275
|
+
await persistence.getUserMessages(userId);
|
|
276
|
+
|
|
277
|
+
// Load as Event history
|
|
278
|
+
await persistence.loadSessionHistory(sessionId);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Creating Custom Adapters
|
|
282
|
+
|
|
283
|
+
Create adapters for any database:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { PersistenceAdapter, SessionRepository, MessageRepository } from "@falai/agent";
|
|
287
|
+
|
|
288
|
+
class MyDatabaseAdapter implements PersistenceAdapter {
|
|
289
|
+
public readonly sessionRepository: SessionRepository;
|
|
290
|
+
public readonly messageRepository: MessageRepository;
|
|
291
|
+
|
|
292
|
+
constructor(config: MyConfig) {
|
|
293
|
+
this.sessionRepository = new MySessionRepository(config);
|
|
294
|
+
this.messageRepository = new MyMessageRepository(config);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async initialize?(): Promise<void> {
|
|
298
|
+
// Optional: Setup tables/indexes
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async disconnect?(): Promise<void> {
|
|
302
|
+
// Optional: Cleanup
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Use it
|
|
307
|
+
const agent = new Agent({
|
|
308
|
+
persistence: {
|
|
309
|
+
adapter: new MyDatabaseAdapter({ ... }),
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Examples
|
|
315
|
+
|
|
316
|
+
### Complete Example
|
|
317
|
+
|
|
318
|
+
See `examples/prisma-persistence.ts` for a full working example.
|
|
319
|
+
|
|
320
|
+
### Minimal Example
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { Agent, PrismaAdapter } from "@falai/agent";
|
|
324
|
+
import { PrismaClient } from "@prisma/client";
|
|
325
|
+
|
|
326
|
+
const prisma = new PrismaClient();
|
|
327
|
+
const agent = new Agent({
|
|
328
|
+
name: "Assistant",
|
|
329
|
+
ai: provider,
|
|
330
|
+
persistence: {
|
|
331
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const persistence = agent.getPersistenceManager();
|
|
336
|
+
const session = await persistence.createSession({ userId: "user_123" });
|
|
337
|
+
const history = await persistence.loadSessionHistory(session.id);
|
|
338
|
+
const response = await agent.respond({ history });
|
|
339
|
+
await persistence.saveMessage({
|
|
340
|
+
sessionId: session.id,
|
|
341
|
+
role: "agent",
|
|
342
|
+
content: response.message,
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Database Schema Details
|
|
347
|
+
|
|
348
|
+
### SessionData Fields
|
|
349
|
+
|
|
350
|
+
- `id`: Unique session identifier
|
|
351
|
+
- `userId`: Optional user identifier
|
|
352
|
+
- `agentName`: Name of the agent
|
|
353
|
+
- `status`: `"active" | "completed" | "abandoned"`
|
|
354
|
+
- `currentRoute`: Current route ID
|
|
355
|
+
- `currentState`: Current state ID
|
|
356
|
+
- `collectedData`: JSON object for custom data
|
|
357
|
+
- `messageCount`: Number of messages in session
|
|
358
|
+
- `lastMessageAt`: Timestamp of last message
|
|
359
|
+
- `completedAt`: When session was completed
|
|
360
|
+
- `createdAt`: Session creation time
|
|
361
|
+
- `updatedAt`: Last update time
|
|
362
|
+
|
|
363
|
+
### MessageData Fields
|
|
364
|
+
|
|
365
|
+
- `id`: Unique message identifier
|
|
366
|
+
- `sessionId`: Reference to session
|
|
367
|
+
- `userId`: Optional user identifier
|
|
368
|
+
- `role`: `"user" | "agent" | "system"`
|
|
369
|
+
- `content`: Message text
|
|
370
|
+
- `route`: Route ID when message was sent
|
|
371
|
+
- `state`: State ID when message was sent
|
|
372
|
+
- `toolCalls`: Array of tool calls (if any)
|
|
373
|
+
- `event`: Full event data (optional)
|
|
374
|
+
- `createdAt`: Message creation time
|
|
375
|
+
|
|
376
|
+
## Best Practices
|
|
377
|
+
|
|
378
|
+
1. ✅ Use lifecycle hooks for automatic context persistence
|
|
379
|
+
2. ✅ Enable `autoSave` to track message counts automatically
|
|
380
|
+
3. ✅ Store minimal data in `collectedData`
|
|
381
|
+
4. ✅ Index frequently queried fields
|
|
382
|
+
5. ✅ Use cascading deletes for cleanup
|
|
383
|
+
6. ✅ Handle errors gracefully
|
|
384
|
+
7. ✅ Complete or abandon sessions when done
|
|
385
|
+
|
|
386
|
+
## Troubleshooting
|
|
387
|
+
|
|
388
|
+
### "Cannot find module '@prisma/client'"
|
|
389
|
+
|
|
390
|
+
Install Prisma:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
npm install @prisma/client prisma
|
|
394
|
+
npx prisma generate
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### "Table not found"
|
|
398
|
+
|
|
399
|
+
Run migrations:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
npx prisma migrate dev
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Custom schema not working
|
|
406
|
+
|
|
407
|
+
Check your field mappings match your actual database schema.
|
|
408
|
+
|
|
409
|
+
## Other Databases
|
|
410
|
+
|
|
411
|
+
The adapter pattern works with any database. Examples:
|
|
412
|
+
|
|
413
|
+
- **MongoDB**: Create `MongoAdapter`
|
|
414
|
+
- **PostgreSQL (raw)**: Create `PostgresAdapter`
|
|
415
|
+
- **MySQL**: Create `MySQLAdapter`
|
|
416
|
+
- **Redis**: Create `RedisAdapter`
|
|
417
|
+
- **Elasticsearch**: Create `ElasticsearchAdapter`
|
|
418
|
+
|
|
419
|
+
Just implement the `PersistenceAdapter` interface!
|