@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.
Files changed (71) hide show
  1. package/README.md +92 -0
  2. package/dist/adapters/PrismaAdapter.d.ts +115 -0
  3. package/dist/adapters/PrismaAdapter.d.ts.map +1 -0
  4. package/dist/adapters/PrismaAdapter.js +331 -0
  5. package/dist/adapters/PrismaAdapter.js.map +1 -0
  6. package/dist/adapters/index.d.ts +6 -0
  7. package/dist/adapters/index.d.ts.map +1 -0
  8. package/dist/adapters/index.js +5 -0
  9. package/dist/adapters/index.js.map +1 -0
  10. package/dist/cjs/adapters/PrismaAdapter.d.ts +115 -0
  11. package/dist/cjs/adapters/PrismaAdapter.d.ts.map +1 -0
  12. package/dist/cjs/adapters/PrismaAdapter.js +335 -0
  13. package/dist/cjs/adapters/PrismaAdapter.js.map +1 -0
  14. package/dist/cjs/adapters/index.d.ts +6 -0
  15. package/dist/cjs/adapters/index.d.ts.map +1 -0
  16. package/dist/cjs/adapters/index.js +9 -0
  17. package/dist/cjs/adapters/index.js.map +1 -0
  18. package/dist/cjs/core/Agent.d.ts +10 -0
  19. package/dist/cjs/core/Agent.d.ts.map +1 -1
  20. package/dist/cjs/core/Agent.js +23 -0
  21. package/dist/cjs/core/Agent.js.map +1 -1
  22. package/dist/cjs/core/PersistenceManager.d.ts +77 -0
  23. package/dist/cjs/core/PersistenceManager.d.ts.map +1 -0
  24. package/dist/cjs/core/PersistenceManager.js +153 -0
  25. package/dist/cjs/core/PersistenceManager.js.map +1 -0
  26. package/dist/cjs/index.d.ts +4 -0
  27. package/dist/cjs/index.d.ts.map +1 -1
  28. package/dist/cjs/index.js +6 -1
  29. package/dist/cjs/index.js.map +1 -1
  30. package/dist/cjs/types/agent.d.ts +3 -0
  31. package/dist/cjs/types/agent.d.ts.map +1 -1
  32. package/dist/cjs/types/agent.js.map +1 -1
  33. package/dist/cjs/types/index.d.ts +1 -0
  34. package/dist/cjs/types/index.d.ts.map +1 -1
  35. package/dist/cjs/types/persistence.d.ts +194 -0
  36. package/dist/cjs/types/persistence.d.ts.map +1 -0
  37. package/dist/cjs/types/persistence.js +7 -0
  38. package/dist/cjs/types/persistence.js.map +1 -0
  39. package/dist/core/Agent.d.ts +10 -0
  40. package/dist/core/Agent.d.ts.map +1 -1
  41. package/dist/core/Agent.js +23 -0
  42. package/dist/core/Agent.js.map +1 -1
  43. package/dist/core/PersistenceManager.d.ts +77 -0
  44. package/dist/core/PersistenceManager.d.ts.map +1 -0
  45. package/dist/core/PersistenceManager.js +149 -0
  46. package/dist/core/PersistenceManager.js.map +1 -0
  47. package/dist/index.d.ts +4 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +3 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/types/agent.d.ts +3 -0
  52. package/dist/types/agent.d.ts.map +1 -1
  53. package/dist/types/agent.js.map +1 -1
  54. package/dist/types/index.d.ts +1 -0
  55. package/dist/types/index.d.ts.map +1 -1
  56. package/dist/types/persistence.d.ts +194 -0
  57. package/dist/types/persistence.d.ts.map +1 -0
  58. package/dist/types/persistence.js +6 -0
  59. package/dist/types/persistence.js.map +1 -0
  60. package/docs/PERSISTENCE.md +419 -0
  61. package/examples/prisma-persistence.ts +313 -0
  62. package/examples/prisma-schema.example.prisma +74 -0
  63. package/package.json +9 -1
  64. package/src/adapters/PrismaAdapter.ts +510 -0
  65. package/src/adapters/index.ts +10 -0
  66. package/src/core/Agent.ts +31 -0
  67. package/src/core/PersistenceManager.ts +222 -0
  68. package/src/index.ts +21 -0
  69. package/src/types/agent.ts +3 -0
  70. package/src/types/index.ts +14 -0
  71. package/src/types/persistence.ts +234 -0
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Persistence Manager
3
+ * Handles optional persistence of sessions and messages
4
+ */
5
+
6
+ import type {
7
+ PersistenceConfig,
8
+ SessionData,
9
+ MessageData,
10
+ CreateSessionOptions,
11
+ SaveMessageOptions,
12
+ SessionStatus,
13
+ SessionRepository,
14
+ MessageRepository,
15
+ } from "../types/persistence";
16
+ import type { Event } from "../types/history";
17
+
18
+ /**
19
+ * Manager for handling persistence operations
20
+ * Provides a clean interface for optional database persistence
21
+ */
22
+ export class PersistenceManager {
23
+ private config: PersistenceConfig;
24
+ private sessionRepository: SessionRepository;
25
+ private messageRepository: MessageRepository;
26
+
27
+ constructor(config: PersistenceConfig) {
28
+ this.config = {
29
+ autoSave: true,
30
+ ...config,
31
+ };
32
+ this.sessionRepository = config.adapter.sessionRepository;
33
+ this.messageRepository = config.adapter.messageRepository;
34
+ }
35
+
36
+ /**
37
+ * Create a new session
38
+ */
39
+ async createSession(options: CreateSessionOptions): Promise<SessionData> {
40
+ const userId = options.userId || this.config.userId;
41
+
42
+ return await this.sessionRepository.create({
43
+ userId,
44
+ agentName: options.agentName,
45
+ status: "active",
46
+ collectedData: options.initialData || {},
47
+ messageCount: 0,
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Get session by ID
53
+ */
54
+ async getSession(sessionId: string): Promise<SessionData | null> {
55
+ return await this.sessionRepository.findById(sessionId);
56
+ }
57
+
58
+ /**
59
+ * Find active session for a user
60
+ */
61
+ async findActiveSession(userId?: string): Promise<SessionData | null> {
62
+ const effectiveUserId = userId || this.config.userId;
63
+ if (!effectiveUserId) {
64
+ throw new Error(
65
+ "userId must be provided or configured in PersistenceConfig"
66
+ );
67
+ }
68
+ return await this.sessionRepository.findActiveByUserId(effectiveUserId);
69
+ }
70
+
71
+ /**
72
+ * Get all sessions for a user
73
+ */
74
+ async getUserSessions(
75
+ userId?: string,
76
+ limit?: number
77
+ ): Promise<SessionData[]> {
78
+ const effectiveUserId = userId || this.config.userId;
79
+ if (!effectiveUserId) {
80
+ throw new Error(
81
+ "userId must be provided or configured in PersistenceConfig"
82
+ );
83
+ }
84
+ return await this.sessionRepository.findByUserId(effectiveUserId, limit);
85
+ }
86
+
87
+ /**
88
+ * Update session status
89
+ */
90
+ async updateSessionStatus(
91
+ sessionId: string,
92
+ status: SessionStatus,
93
+ completedAt?: Date
94
+ ): Promise<SessionData | null> {
95
+ return await this.sessionRepository.updateStatus(
96
+ sessionId,
97
+ status,
98
+ completedAt
99
+ );
100
+ }
101
+
102
+ /**
103
+ * Update collected data in session
104
+ */
105
+ async updateCollectedData(
106
+ sessionId: string,
107
+ collectedData: Record<string, unknown>
108
+ ): Promise<SessionData | null> {
109
+ return await this.sessionRepository.updateCollectedData(
110
+ sessionId,
111
+ collectedData
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Update current route and state
117
+ */
118
+ async updateRouteState(
119
+ sessionId: string,
120
+ route?: string,
121
+ state?: string
122
+ ): Promise<SessionData | null> {
123
+ return await this.sessionRepository.updateRouteState(
124
+ sessionId,
125
+ route,
126
+ state
127
+ );
128
+ }
129
+
130
+ /**
131
+ * Save a message
132
+ */
133
+ async saveMessage(options: SaveMessageOptions): Promise<MessageData> {
134
+ const userId = options.userId || this.config.userId;
135
+
136
+ const message = await this.messageRepository.create({
137
+ sessionId: options.sessionId,
138
+ userId,
139
+ role: options.role,
140
+ content: options.content,
141
+ route: options.route,
142
+ state: options.state,
143
+ toolCalls: options.toolCalls,
144
+ event: options.event,
145
+ });
146
+
147
+ // Increment message count in session if autoSave is enabled
148
+ if (this.config.autoSave) {
149
+ await this.sessionRepository.incrementMessageCount(options.sessionId);
150
+ }
151
+
152
+ return message;
153
+ }
154
+
155
+ /**
156
+ * Get all messages for a session
157
+ */
158
+ async getSessionMessages(
159
+ sessionId: string,
160
+ limit?: number
161
+ ): Promise<MessageData[]> {
162
+ return await this.messageRepository.findBySessionId(sessionId, limit);
163
+ }
164
+
165
+ /**
166
+ * Get messages for a user
167
+ */
168
+ async getUserMessages(
169
+ userId?: string,
170
+ limit?: number
171
+ ): Promise<MessageData[]> {
172
+ const effectiveUserId = userId || this.config.userId;
173
+ if (!effectiveUserId) {
174
+ throw new Error(
175
+ "userId must be provided or configured in PersistenceConfig"
176
+ );
177
+ }
178
+ return await this.messageRepository.findByUserId(effectiveUserId, limit);
179
+ }
180
+
181
+ /**
182
+ * Delete a session and all its messages
183
+ */
184
+ async deleteSession(sessionId: string): Promise<boolean> {
185
+ // Delete all messages first
186
+ await this.messageRepository.deleteBySessionId(sessionId);
187
+
188
+ // Then delete the session
189
+ return await this.sessionRepository.delete(sessionId);
190
+ }
191
+
192
+ /**
193
+ * Complete a session
194
+ */
195
+ async completeSession(sessionId: string): Promise<SessionData | null> {
196
+ return await this.updateSessionStatus(sessionId, "completed", new Date());
197
+ }
198
+
199
+ /**
200
+ * Abandon a session
201
+ */
202
+ async abandonSession(sessionId: string): Promise<SessionData | null> {
203
+ return await this.updateSessionStatus(sessionId, "abandoned");
204
+ }
205
+
206
+ /**
207
+ * Helper: Convert message data to Event format
208
+ */
209
+ messageToEvent(message: MessageData): Event | undefined {
210
+ return message.event;
211
+ }
212
+
213
+ /**
214
+ * Helper: Load history from session messages
215
+ */
216
+ async loadSessionHistory(sessionId: string): Promise<Event[]> {
217
+ const messages = await this.getSessionMessages(sessionId);
218
+ return messages
219
+ .map((m) => this.messageToEvent(m))
220
+ .filter((e): e is Event => e !== undefined);
221
+ }
222
+ }
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export { adaptEvent, createMessageEvent, createToolEvent } from "./core/Events";
16
16
  export { PromptBuilder } from "./core/PromptBuilder";
17
17
  export type { Customer, AgentInfo } from "./core/PromptBuilder";
18
18
  export { BuiltInSection } from "./core/PromptBuilder";
19
+ export { PersistenceManager } from "./core/PersistenceManager";
19
20
 
20
21
  // Providers
21
22
  export { GeminiProvider } from "./providers/GeminiProvider";
@@ -27,6 +28,14 @@ export type { OpenRouterProviderOptions } from "./providers/OpenRouterProvider";
27
28
  export { AnthropicProvider } from "./providers/AnthropicProvider";
28
29
  export type { AnthropicProviderOptions } from "./providers/AnthropicProvider";
29
30
 
31
+ // Adapters
32
+ export { PrismaAdapter } from "./adapters/PrismaAdapter";
33
+ export type {
34
+ PrismaClient,
35
+ FieldMappings,
36
+ PrismaAdapterOptions,
37
+ } from "./adapters/PrismaAdapter";
38
+
30
39
  // Constants
31
40
  export { END_ROUTE } from "./constants";
32
41
 
@@ -94,3 +103,15 @@ export type {
94
103
  Observation as IObservation,
95
104
  ObservationOptions,
96
105
  } from "./types/observation";
106
+
107
+ export type {
108
+ SessionData,
109
+ MessageData,
110
+ SessionStatus,
111
+ MessageRole,
112
+ SessionRepository,
113
+ MessageRepository,
114
+ PersistenceConfig,
115
+ CreateSessionOptions,
116
+ SaveMessageOptions,
117
+ } from "./types/persistence";
@@ -5,6 +5,7 @@
5
5
  import type { AiProvider } from "./ai";
6
6
  import type { ToolRef } from "./tool";
7
7
  import type { RouteOptions } from "./route";
8
+ import type { PersistenceConfig } from "./persistence";
8
9
 
9
10
  /**
10
11
  * Composition mode determines how the agent processes and structures responses
@@ -85,6 +86,8 @@ export interface AgentOptions<TContext = unknown> {
85
86
  routes?: RouteOptions[];
86
87
  /** Initial observations for disambiguation */
87
88
  observations?: ObservationOptions[];
89
+ /** Optional persistence configuration for auto-saving sessions and messages */
90
+ persistence?: PersistenceConfig;
88
91
  }
89
92
 
90
93
  /**
@@ -54,3 +54,17 @@ export { SectionStatus } from "./prompt";
54
54
 
55
55
  // Observation types
56
56
  export type { Observation, ObservationOptions } from "./observation";
57
+
58
+ // Persistence types
59
+ export type {
60
+ SessionData,
61
+ MessageData,
62
+ SessionStatus,
63
+ MessageRole,
64
+ SessionRepository,
65
+ MessageRepository,
66
+ PersistenceAdapter,
67
+ PersistenceConfig,
68
+ CreateSessionOptions,
69
+ SaveMessageOptions,
70
+ } from "./persistence";
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Persistence-related type definitions
3
+ * Support for optional database persistence (Prisma, etc.)
4
+ */
5
+
6
+ import type { Event } from "./history";
7
+
8
+ /**
9
+ * Session status enum
10
+ */
11
+ export type SessionStatus = "active" | "completed" | "abandoned";
12
+
13
+ /**
14
+ * Message role enum
15
+ */
16
+ export type MessageRole = "user" | "agent" | "system";
17
+
18
+ /**
19
+ * Base session data structure
20
+ */
21
+ export interface SessionData {
22
+ id: string;
23
+ userId?: string;
24
+ agentName?: string;
25
+ status: SessionStatus;
26
+ currentRoute?: string;
27
+ currentState?: string;
28
+ collectedData?: Record<string, unknown>;
29
+ messageCount?: number;
30
+ lastMessageAt?: Date;
31
+ completedAt?: Date;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }
35
+
36
+ /**
37
+ * Base message data structure
38
+ */
39
+ export interface MessageData {
40
+ id: string;
41
+ sessionId: string;
42
+ userId?: string;
43
+ role: MessageRole;
44
+ content: string;
45
+ route?: string;
46
+ state?: string;
47
+ toolCalls?: Array<{ toolName: string; arguments: Record<string, unknown> }>;
48
+ event?: Event; // Optional: store full event data
49
+ createdAt: Date;
50
+ }
51
+
52
+ /**
53
+ * Repository interface for sessions
54
+ * Implement this interface with your database of choice
55
+ */
56
+ export interface SessionRepository {
57
+ /**
58
+ * Create a new session
59
+ */
60
+ create(
61
+ data: Omit<SessionData, "id" | "createdAt" | "updatedAt">
62
+ ): Promise<SessionData>;
63
+
64
+ /**
65
+ * Find session by ID
66
+ */
67
+ findById(id: string): Promise<SessionData | null>;
68
+
69
+ /**
70
+ * Find active session by user ID
71
+ */
72
+ findActiveByUserId(userId: string): Promise<SessionData | null>;
73
+
74
+ /**
75
+ * Find all sessions for a user
76
+ */
77
+ findByUserId(userId: string, limit?: number): Promise<SessionData[]>;
78
+
79
+ /**
80
+ * Update session
81
+ */
82
+ update(
83
+ id: string,
84
+ data: Partial<Omit<SessionData, "id" | "createdAt">>
85
+ ): Promise<SessionData | null>;
86
+
87
+ /**
88
+ * Update session status
89
+ */
90
+ updateStatus(
91
+ id: string,
92
+ status: SessionStatus,
93
+ completedAt?: Date
94
+ ): Promise<SessionData | null>;
95
+
96
+ /**
97
+ * Update collected data
98
+ */
99
+ updateCollectedData(
100
+ id: string,
101
+ collectedData: Record<string, unknown>
102
+ ): Promise<SessionData | null>;
103
+
104
+ /**
105
+ * Update current route and state
106
+ */
107
+ updateRouteState(
108
+ id: string,
109
+ route?: string,
110
+ state?: string
111
+ ): Promise<SessionData | null>;
112
+
113
+ /**
114
+ * Increment message count
115
+ */
116
+ incrementMessageCount(id: string): Promise<SessionData | null>;
117
+
118
+ /**
119
+ * Delete session
120
+ */
121
+ delete(id: string): Promise<boolean>;
122
+ }
123
+
124
+ /**
125
+ * Repository interface for messages
126
+ * Implement this interface with your database of choice
127
+ */
128
+ export interface MessageRepository {
129
+ /**
130
+ * Create a new message
131
+ */
132
+ create(data: Omit<MessageData, "id" | "createdAt">): Promise<MessageData>;
133
+
134
+ /**
135
+ * Find message by ID
136
+ */
137
+ findById(id: string): Promise<MessageData | null>;
138
+
139
+ /**
140
+ * Find all messages for a session
141
+ */
142
+ findBySessionId(sessionId: string, limit?: number): Promise<MessageData[]>;
143
+
144
+ /**
145
+ * Find messages for a user
146
+ */
147
+ findByUserId(userId: string, limit?: number): Promise<MessageData[]>;
148
+
149
+ /**
150
+ * Delete message by ID
151
+ */
152
+ delete(id: string): Promise<boolean>;
153
+
154
+ /**
155
+ * Delete all messages for a session
156
+ */
157
+ deleteBySessionId(sessionId: string): Promise<number>;
158
+
159
+ /**
160
+ * Delete all messages for a user
161
+ */
162
+ deleteByUserId(userId: string): Promise<number>;
163
+ }
164
+
165
+ /**
166
+ * Persistence adapter interface
167
+ * Implement this to create adapters for different databases
168
+ */
169
+ export interface PersistenceAdapter {
170
+ /**
171
+ * Session repository
172
+ */
173
+ readonly sessionRepository: SessionRepository;
174
+
175
+ /**
176
+ * Message repository
177
+ */
178
+ readonly messageRepository: MessageRepository;
179
+
180
+ /**
181
+ * Initialize the adapter (create tables, indexes, etc.)
182
+ * Called automatically when adapter is created
183
+ */
184
+ initialize?(): Promise<void>;
185
+
186
+ /**
187
+ * Disconnect/cleanup resources
188
+ */
189
+ disconnect?(): Promise<void>;
190
+ }
191
+
192
+ /**
193
+ * Configuration for persistence
194
+ */
195
+ export interface PersistenceConfig {
196
+ /**
197
+ * Persistence adapter instance (e.g., PrismaAdapter)
198
+ */
199
+ adapter: PersistenceAdapter;
200
+
201
+ /**
202
+ * Whether to auto-save messages (default: true)
203
+ */
204
+ autoSave?: boolean;
205
+
206
+ /**
207
+ * User ID to associate with sessions/messages
208
+ * Can also be provided per-call in methods
209
+ */
210
+ userId?: string;
211
+ }
212
+
213
+ /**
214
+ * Options for creating a session
215
+ */
216
+ export interface CreateSessionOptions {
217
+ userId?: string;
218
+ agentName?: string;
219
+ initialData?: Record<string, unknown>;
220
+ }
221
+
222
+ /**
223
+ * Options for saving a message
224
+ */
225
+ export interface SaveMessageOptions {
226
+ sessionId: string;
227
+ userId?: string;
228
+ role: MessageRole;
229
+ content: string;
230
+ route?: string;
231
+ state?: string;
232
+ toolCalls?: Array<{ toolName: string; arguments: Record<string, unknown> }>;
233
+ event?: Event;
234
+ }