@falai/agent 0.3.11 → 0.3.20
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 +164 -0
- package/dist/adapters/MongoAdapter.d.ts +97 -0
- package/dist/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/adapters/MongoAdapter.js +163 -0
- package/dist/adapters/MongoAdapter.js.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts +71 -0
- package/dist/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/adapters/PostgreSQLAdapter.js +256 -0
- package/dist/adapters/PostgreSQLAdapter.js.map +1 -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/RedisAdapter.d.ts +71 -0
- package/dist/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/adapters/RedisAdapter.js +226 -0
- package/dist/adapters/RedisAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +8 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/MongoAdapter.d.ts +97 -0
- package/dist/cjs/adapters/MongoAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/MongoAdapter.js +167 -0
- package/dist/cjs/adapters/MongoAdapter.js.map +1 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts +71 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.js +260 -0
- package/dist/cjs/adapters/PostgreSQLAdapter.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/RedisAdapter.d.ts +71 -0
- package/dist/cjs/adapters/RedisAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/RedisAdapter.js +230 -0
- package/dist/cjs/adapters/RedisAdapter.js.map +1 -0
- package/dist/cjs/adapters/index.d.ts +12 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -0
- package/dist/cjs/adapters/index.js +15 -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 +10 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +12 -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 +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -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/ADAPTERS.md +127 -0
- package/docs/API_REFERENCE.md +337 -0
- package/docs/PERSISTENCE.md +513 -0
- package/examples/prisma-persistence.ts +313 -0
- package/examples/prisma-schema.example.prisma +74 -0
- package/examples/redis-persistence.ts +89 -0
- package/package.json +29 -1
- package/src/adapters/MongoAdapter.ts +295 -0
- package/src/adapters/PostgreSQLAdapter.ts +417 -0
- package/src/adapters/PrismaAdapter.ts +510 -0
- package/src/adapters/RedisAdapter.ts +365 -0
- package/src/adapters/index.ts +28 -0
- package/src/core/Agent.ts +31 -0
- package/src/core/PersistenceManager.ts +222 -0
- package/src/index.ts +36 -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,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using Prisma ORM for Persistence
|
|
3
|
+
*
|
|
4
|
+
* This example shows how to use @falai/agent with Prisma for automatic
|
|
5
|
+
* session and message persistence - as easy as using an AI provider!
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
Agent,
|
|
10
|
+
GeminiProvider,
|
|
11
|
+
PrismaAdapter,
|
|
12
|
+
createMessageEvent,
|
|
13
|
+
EventSource,
|
|
14
|
+
} from "../src/index";
|
|
15
|
+
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import { PrismaClient } from "@prisma/client";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Setup Steps:
|
|
21
|
+
*
|
|
22
|
+
* 1. Install dependencies:
|
|
23
|
+
* npm install prisma @prisma/client
|
|
24
|
+
*
|
|
25
|
+
* 2. Initialize Prisma:
|
|
26
|
+
* npx prisma init
|
|
27
|
+
*
|
|
28
|
+
* 3. Copy schema from examples/prisma-schema.example.prisma
|
|
29
|
+
* to your prisma/schema.prisma file
|
|
30
|
+
*
|
|
31
|
+
* 4. Generate Prisma client:
|
|
32
|
+
* npx prisma generate
|
|
33
|
+
*
|
|
34
|
+
* 5. Run migrations:
|
|
35
|
+
* npx prisma migrate dev --name init
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
// Example context type
|
|
39
|
+
interface ConversationContext {
|
|
40
|
+
userId: string;
|
|
41
|
+
sessionId: string;
|
|
42
|
+
userName: string;
|
|
43
|
+
preferences: {
|
|
44
|
+
language: string;
|
|
45
|
+
theme: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function example() {
|
|
50
|
+
// Initialize Prisma client
|
|
51
|
+
const prisma = new PrismaClient();
|
|
52
|
+
|
|
53
|
+
const userId = "user_123";
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create Agent with Persistence - Simple Provider Pattern! ✨
|
|
57
|
+
*/
|
|
58
|
+
const agent = new Agent<ConversationContext>({
|
|
59
|
+
name: "Shopping Assistant",
|
|
60
|
+
description: "A helpful shopping assistant",
|
|
61
|
+
ai: new GeminiProvider({
|
|
62
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
63
|
+
model: "models/gemini-2.0-flash-exp",
|
|
64
|
+
}),
|
|
65
|
+
context: {
|
|
66
|
+
userId,
|
|
67
|
+
sessionId: "", // Will be set when we create/load a session
|
|
68
|
+
userName: "Alice",
|
|
69
|
+
preferences: {
|
|
70
|
+
language: "en",
|
|
71
|
+
theme: "light",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
// ✨ Just pass the adapter - that's it!
|
|
75
|
+
persistence: {
|
|
76
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
77
|
+
autoSave: true,
|
|
78
|
+
userId,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get persistence manager from agent
|
|
84
|
+
*/
|
|
85
|
+
const persistence = agent.getPersistenceManager();
|
|
86
|
+
|
|
87
|
+
if (!persistence) {
|
|
88
|
+
throw new Error("Persistence not configured");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Create or find a session
|
|
93
|
+
*/
|
|
94
|
+
let session = await persistence.findActiveSession(userId);
|
|
95
|
+
|
|
96
|
+
if (!session) {
|
|
97
|
+
session = await persistence.createSession({
|
|
98
|
+
userId,
|
|
99
|
+
agentName: "Shopping Assistant",
|
|
100
|
+
initialData: {
|
|
101
|
+
language: "en",
|
|
102
|
+
theme: "light",
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
console.log("✨ Created new session:", session.id);
|
|
106
|
+
} else {
|
|
107
|
+
console.log("📂 Found active session:", session.id);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Update context with session ID
|
|
111
|
+
await agent.updateContext({
|
|
112
|
+
sessionId: session.id,
|
|
113
|
+
} as Partial<ConversationContext>);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Load conversation history
|
|
117
|
+
*/
|
|
118
|
+
const history = await persistence.loadSessionHistory(session.id);
|
|
119
|
+
console.log(`📜 Loaded ${history.length} messages from history`);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Send a message
|
|
123
|
+
*/
|
|
124
|
+
const userMessage = createMessageEvent(
|
|
125
|
+
EventSource.CUSTOMER,
|
|
126
|
+
"Alice",
|
|
127
|
+
"I'm looking for a winter jacket"
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Save user message
|
|
131
|
+
await persistence.saveMessage({
|
|
132
|
+
sessionId: session.id,
|
|
133
|
+
userId,
|
|
134
|
+
role: "user",
|
|
135
|
+
content: "I'm looking for a winter jacket",
|
|
136
|
+
event: userMessage,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
history.push(userMessage);
|
|
140
|
+
|
|
141
|
+
// Generate agent response
|
|
142
|
+
const response = await agent.respond({ history });
|
|
143
|
+
console.log("🤖 Agent:", response.message);
|
|
144
|
+
|
|
145
|
+
// Save agent message
|
|
146
|
+
await persistence.saveMessage({
|
|
147
|
+
sessionId: session.id,
|
|
148
|
+
userId,
|
|
149
|
+
role: "agent",
|
|
150
|
+
content: response.message,
|
|
151
|
+
route: response.route?.id,
|
|
152
|
+
state: response.state?.id,
|
|
153
|
+
toolCalls: response.toolCalls,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Query sessions and messages
|
|
158
|
+
*/
|
|
159
|
+
const userSessions = await persistence.getUserSessions(userId);
|
|
160
|
+
console.log(`👤 User has ${userSessions.length} total sessions`);
|
|
161
|
+
|
|
162
|
+
const messages = await persistence.getSessionMessages(session.id);
|
|
163
|
+
console.log(`💬 Session has ${messages.length} messages`);
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Complete the session
|
|
167
|
+
*/
|
|
168
|
+
await persistence.completeSession(session.id);
|
|
169
|
+
console.log("✅ Session completed");
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Cleanup
|
|
173
|
+
*/
|
|
174
|
+
await prisma.$disconnect();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Advanced Example: Using with Lifecycle Hooks
|
|
179
|
+
*/
|
|
180
|
+
async function advancedExample() {
|
|
181
|
+
const prisma = new PrismaClient();
|
|
182
|
+
const userId = "user_123";
|
|
183
|
+
|
|
184
|
+
const agent = new Agent<ConversationContext>({
|
|
185
|
+
name: "Smart Assistant",
|
|
186
|
+
description: "An intelligent assistant with persistent state",
|
|
187
|
+
ai: new GeminiProvider({
|
|
188
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
189
|
+
model: "models/gemini-2.0-flash-exp",
|
|
190
|
+
}),
|
|
191
|
+
context: {
|
|
192
|
+
userId,
|
|
193
|
+
sessionId: "",
|
|
194
|
+
userName: "Alice",
|
|
195
|
+
preferences: {
|
|
196
|
+
language: "en",
|
|
197
|
+
theme: "light",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
// Lifecycle hooks for automatic context sync
|
|
201
|
+
hooks: {
|
|
202
|
+
// Load fresh context before each response
|
|
203
|
+
beforeRespond: async (currentContext) => {
|
|
204
|
+
const persistence = agent.getPersistenceManager();
|
|
205
|
+
if (!persistence) return currentContext;
|
|
206
|
+
|
|
207
|
+
const freshSession = await persistence.getSession(
|
|
208
|
+
currentContext.sessionId
|
|
209
|
+
);
|
|
210
|
+
return {
|
|
211
|
+
...currentContext,
|
|
212
|
+
preferences:
|
|
213
|
+
(
|
|
214
|
+
freshSession?.collectedData as {
|
|
215
|
+
preferences?: typeof currentContext.preferences;
|
|
216
|
+
}
|
|
217
|
+
)?.preferences || currentContext.preferences,
|
|
218
|
+
};
|
|
219
|
+
},
|
|
220
|
+
// Automatically persist context updates
|
|
221
|
+
onContextUpdate: async (newContext) => {
|
|
222
|
+
const persistence = agent.getPersistenceManager();
|
|
223
|
+
if (!persistence) return;
|
|
224
|
+
|
|
225
|
+
await persistence.updateCollectedData(newContext.sessionId, {
|
|
226
|
+
preferences: newContext.preferences,
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
// ✨ Same simple adapter pattern!
|
|
231
|
+
persistence: {
|
|
232
|
+
adapter: new PrismaAdapter({ prisma }),
|
|
233
|
+
autoSave: true,
|
|
234
|
+
userId,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Create a session
|
|
239
|
+
const persistence = agent.getPersistenceManager();
|
|
240
|
+
const session = await persistence!.createSession({
|
|
241
|
+
userId,
|
|
242
|
+
agentName: "Smart Assistant",
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
await agent.updateContext({
|
|
246
|
+
sessionId: session.id,
|
|
247
|
+
} as Partial<ConversationContext>);
|
|
248
|
+
|
|
249
|
+
// Now context updates are automatically persisted!
|
|
250
|
+
await agent.updateContext({
|
|
251
|
+
preferences: {
|
|
252
|
+
language: "es",
|
|
253
|
+
theme: "dark",
|
|
254
|
+
},
|
|
255
|
+
} as Partial<ConversationContext>);
|
|
256
|
+
|
|
257
|
+
console.log("🎉 Context updates automatically saved to database!");
|
|
258
|
+
|
|
259
|
+
await prisma.$disconnect();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Minimal Example - Quick Start
|
|
264
|
+
*/
|
|
265
|
+
async function quickStart() {
|
|
266
|
+
const prisma = new PrismaClient();
|
|
267
|
+
|
|
268
|
+
// That's it! Just create the adapter and pass it
|
|
269
|
+
const agent = new Agent({
|
|
270
|
+
name: "My Agent",
|
|
271
|
+
description: "A helpful assistant",
|
|
272
|
+
ai: new GeminiProvider({
|
|
273
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
274
|
+
model: "models/gemini-2.5-flash",
|
|
275
|
+
}),
|
|
276
|
+
persistence: {
|
|
277
|
+
adapter: new PrismaAdapter({ prisma }), // ✨ Simple!
|
|
278
|
+
userId: "user_123",
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Get persistence manager
|
|
283
|
+
const persistence = agent.getPersistenceManager();
|
|
284
|
+
if (!persistence) return;
|
|
285
|
+
|
|
286
|
+
// Create session
|
|
287
|
+
const session = await persistence.createSession({
|
|
288
|
+
userId: "user_123",
|
|
289
|
+
agentName: "My Agent",
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// Load history and respond
|
|
293
|
+
const history = await persistence.loadSessionHistory(session.id);
|
|
294
|
+
const response = await agent.respond({ history });
|
|
295
|
+
|
|
296
|
+
// Save message
|
|
297
|
+
await persistence.saveMessage({
|
|
298
|
+
sessionId: session.id,
|
|
299
|
+
role: "agent",
|
|
300
|
+
content: response.message,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
console.log("✅ Done! Messages automatically saved to Prisma.");
|
|
304
|
+
|
|
305
|
+
await prisma.$disconnect();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Run the example
|
|
309
|
+
if (require.main === module) {
|
|
310
|
+
example().catch(console.error);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export { example, advancedExample, quickStart };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// This is an example Prisma schema file for @falai/agent persistence
|
|
2
|
+
// Copy and adapt this to your needs
|
|
3
|
+
|
|
4
|
+
datasource db {
|
|
5
|
+
provider = "postgresql" // or "mysql", "sqlite", "sqlserver", "mongodb"
|
|
6
|
+
url = env("DATABASE_URL")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
generator client {
|
|
10
|
+
provider = "prisma-client-js"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Agent Session model
|
|
14
|
+
// Stores conversation session state
|
|
15
|
+
model AgentSession {
|
|
16
|
+
id String @id @default(cuid())
|
|
17
|
+
userId String? @map("user_id")
|
|
18
|
+
agentName String? @map("agent_name")
|
|
19
|
+
status String @default("active") // "active" | "completed" | "abandoned"
|
|
20
|
+
currentRoute String? @map("current_route")
|
|
21
|
+
currentState String? @map("current_state")
|
|
22
|
+
collectedData Json? @map("collected_data")
|
|
23
|
+
messageCount Int @default(0) @map("message_count")
|
|
24
|
+
lastMessageAt DateTime? @map("last_message_at")
|
|
25
|
+
completedAt DateTime? @map("completed_at")
|
|
26
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
27
|
+
updatedAt DateTime @updatedAt @map("updated_at")
|
|
28
|
+
|
|
29
|
+
// Relations
|
|
30
|
+
messages AgentMessage[]
|
|
31
|
+
|
|
32
|
+
@@index([userId])
|
|
33
|
+
@@index([status])
|
|
34
|
+
@@index([userId, status])
|
|
35
|
+
@@map("agent_sessions")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Agent Message model
|
|
39
|
+
// Stores individual messages in a conversation
|
|
40
|
+
model AgentMessage {
|
|
41
|
+
id String @id @default(cuid())
|
|
42
|
+
sessionId String @map("session_id")
|
|
43
|
+
userId String? @map("user_id")
|
|
44
|
+
role String // "user" | "agent" | "system"
|
|
45
|
+
content String @db.Text
|
|
46
|
+
route String?
|
|
47
|
+
state String?
|
|
48
|
+
toolCalls Json? @map("tool_calls")
|
|
49
|
+
event Json? // Optional: store full event data
|
|
50
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
51
|
+
|
|
52
|
+
// Relations
|
|
53
|
+
session AgentSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
54
|
+
|
|
55
|
+
@@index([sessionId])
|
|
56
|
+
@@index([userId])
|
|
57
|
+
@@index([sessionId, createdAt])
|
|
58
|
+
@@map("agent_messages")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Alternative: If you want different table names, you can customize:
|
|
62
|
+
//
|
|
63
|
+
// model ConversationSession {
|
|
64
|
+
// id String @id @default(cuid())
|
|
65
|
+
// ...
|
|
66
|
+
// @@map("conversations")
|
|
67
|
+
// }
|
|
68
|
+
//
|
|
69
|
+
// model ChatMessage {
|
|
70
|
+
// id String @id @default(cuid())
|
|
71
|
+
// ...
|
|
72
|
+
// @@map("chat_messages")
|
|
73
|
+
// }
|
|
74
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using Redis for Persistence
|
|
3
|
+
*
|
|
4
|
+
* Fast, in-memory persistence perfect for:
|
|
5
|
+
* - High-throughput applications
|
|
6
|
+
* - Session caching
|
|
7
|
+
* - Real-time chat applications
|
|
8
|
+
* - Temporary conversation storage
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Agent, GeminiProvider, RedisAdapter } from "../src/index";
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
import Redis from "ioredis";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Setup Steps:
|
|
17
|
+
*
|
|
18
|
+
* 1. Install Redis and client:
|
|
19
|
+
* brew install redis (macOS) or apt-get install redis (Linux)
|
|
20
|
+
* npm install ioredis
|
|
21
|
+
*
|
|
22
|
+
* 2. Start Redis:
|
|
23
|
+
* redis-server
|
|
24
|
+
*
|
|
25
|
+
* 3. Run this example
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
async function example() {
|
|
29
|
+
// Initialize Redis client
|
|
30
|
+
const redis = new Redis();
|
|
31
|
+
|
|
32
|
+
// Create agent with Redis persistence
|
|
33
|
+
const agent = new Agent({
|
|
34
|
+
name: "Chat Assistant",
|
|
35
|
+
description: "Fast, real-time chat assistant",
|
|
36
|
+
ai: new GeminiProvider({
|
|
37
|
+
apiKey: process.env.GEMINI_API_KEY!,
|
|
38
|
+
model: "models/gemini-2.0-flash-exp",
|
|
39
|
+
}),
|
|
40
|
+
// ✨ Redis adapter with custom options
|
|
41
|
+
persistence: {
|
|
42
|
+
adapter: new RedisAdapter({
|
|
43
|
+
redis,
|
|
44
|
+
keyPrefix: "chat:", // Custom prefix
|
|
45
|
+
sessionTTL: 24 * 60 * 60, // 24 hours
|
|
46
|
+
messageTTL: 7 * 24 * 60 * 60, // 7 days
|
|
47
|
+
}),
|
|
48
|
+
autoSave: true,
|
|
49
|
+
userId: "user_123",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const persistence = agent.getPersistenceManager();
|
|
54
|
+
if (!persistence) return;
|
|
55
|
+
|
|
56
|
+
// Create session
|
|
57
|
+
const session = await persistence.createSession({
|
|
58
|
+
userId: "user_123",
|
|
59
|
+
agentName: "Chat Assistant",
|
|
60
|
+
initialData: { chatType: "support" },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log("✨ Session created in Redis:", session.id);
|
|
64
|
+
|
|
65
|
+
// Save a message
|
|
66
|
+
await persistence.saveMessage({
|
|
67
|
+
sessionId: session.id,
|
|
68
|
+
role: "user",
|
|
69
|
+
content: "Hello! I need help",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Load messages
|
|
73
|
+
const messages = await persistence.getSessionMessages(session.id);
|
|
74
|
+
console.log(`💬 ${messages.length} messages in session`);
|
|
75
|
+
|
|
76
|
+
// Complete session
|
|
77
|
+
await persistence.completeSession(session.id);
|
|
78
|
+
console.log("✅ Session completed");
|
|
79
|
+
|
|
80
|
+
// Cleanup
|
|
81
|
+
await redis.quit();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Run the example
|
|
85
|
+
if (require.main === module) {
|
|
86
|
+
example().catch(console.error);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { example };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@falai/agent",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.20",
|
|
4
4
|
"description": "Standalone, strongly-typed AI Agent framework with route DSL and AI provider strategy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -80,5 +80,33 @@
|
|
|
80
80
|
"@anthropic-ai/sdk": "^0.65.0",
|
|
81
81
|
"@google/genai": "^0.3.0",
|
|
82
82
|
"openai": "^6.3.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependencies": {
|
|
85
|
+
"@prisma/client": "^6.0.0",
|
|
86
|
+
"ioredis": "^5.7.0",
|
|
87
|
+
"redis": "^4.6.0 || ^5.0.0",
|
|
88
|
+
"mongodb": "^6.0.0 || ^7.0.0",
|
|
89
|
+
"pg": "^8.11.0",
|
|
90
|
+
"mysql2": "^3.2.0"
|
|
91
|
+
},
|
|
92
|
+
"peerDependenciesMeta": {
|
|
93
|
+
"@prisma/client": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"ioredis": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
"redis": {
|
|
100
|
+
"optional": true
|
|
101
|
+
},
|
|
102
|
+
"mongodb": {
|
|
103
|
+
"optional": true
|
|
104
|
+
},
|
|
105
|
+
"pg": {
|
|
106
|
+
"optional": true
|
|
107
|
+
},
|
|
108
|
+
"mysql2": {
|
|
109
|
+
"optional": true
|
|
110
|
+
}
|
|
83
111
|
}
|
|
84
112
|
}
|