@mastra/pg 0.14.6-alpha.0 → 0.14.6-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,514 +0,0 @@
1
- import type { MastraMessageContentV2, MastraMessageV2 } from '@mastra/core/agent';
2
- import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
3
- import type { MastraMessageV1, StorageThreadType } from '@mastra/core/memory';
4
- import type { ScoreRowData, ScoringSource } from '@mastra/core/scores';
5
- import { MastraStorage } from '@mastra/core/storage';
6
- import type {
7
- EvalRow,
8
- PaginationInfo,
9
- StorageColumn,
10
- StorageGetMessagesArg,
11
- StorageGetTracesArg,
12
- StorageGetTracesPaginatedArg,
13
- StorageResourceType,
14
- TABLE_NAMES,
15
- WorkflowRun,
16
- WorkflowRuns,
17
- PaginationArgs,
18
- StoragePagination,
19
- StorageDomains,
20
- ThreadSortOptions,
21
- } from '@mastra/core/storage';
22
- import type { Trace } from '@mastra/core/telemetry';
23
- import type { StepResult, WorkflowRunState } from '@mastra/core/workflows';
24
- import pgPromise from 'pg-promise';
25
- import type { ISSLConfig } from 'pg-promise/typescript/pg-subset';
26
- import { LegacyEvalsPG } from './domains/legacy-evals';
27
- import { MemoryPG } from './domains/memory';
28
- import { StoreOperationsPG } from './domains/operations';
29
- import { ScoresPG } from './domains/scores';
30
- import { TracesPG } from './domains/traces';
31
- import { WorkflowsPG } from './domains/workflows';
32
-
33
- export type PostgresConfig = {
34
- schemaName?: string;
35
- max?: number;
36
- idleTimeoutMillis?: number;
37
- } & (
38
- | {
39
- host: string;
40
- port: number;
41
- database: string;
42
- user: string;
43
- password: string;
44
- ssl?: boolean | ISSLConfig;
45
- }
46
- | {
47
- connectionString: string;
48
- }
49
- );
50
-
51
- export class PostgresStore extends MastraStorage {
52
- #db?: pgPromise.IDatabase<{}>;
53
- #pgp?: pgPromise.IMain;
54
- #config: PostgresConfig;
55
- private schema: string;
56
- private isConnected: boolean = false;
57
-
58
- stores: StorageDomains;
59
-
60
- constructor(config: PostgresConfig) {
61
- // Validation: connectionString or host/database/user/password must not be empty
62
- try {
63
- if ('connectionString' in config) {
64
- if (
65
- !config.connectionString ||
66
- typeof config.connectionString !== 'string' ||
67
- config.connectionString.trim() === ''
68
- ) {
69
- throw new Error(
70
- 'PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.',
71
- );
72
- }
73
- } else {
74
- const required = ['host', 'database', 'user', 'password'];
75
- for (const key of required) {
76
- if (!(key in config) || typeof (config as any)[key] !== 'string' || (config as any)[key].trim() === '') {
77
- throw new Error(
78
- `PostgresStore: ${key} must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`,
79
- );
80
- }
81
- }
82
- }
83
- super({ name: 'PostgresStore' });
84
- this.schema = config.schemaName || 'public';
85
- this.#config = {
86
- max: config.max,
87
- idleTimeoutMillis: config.idleTimeoutMillis,
88
- ...(`connectionString` in config
89
- ? { connectionString: config.connectionString }
90
- : {
91
- host: config.host,
92
- port: config.port,
93
- database: config.database,
94
- user: config.user,
95
- password: config.password,
96
- ssl: config.ssl,
97
- }),
98
- };
99
- this.stores = {} as StorageDomains;
100
- } catch (e) {
101
- throw new MastraError(
102
- {
103
- id: 'MASTRA_STORAGE_PG_STORE_INITIALIZATION_FAILED',
104
- domain: ErrorDomain.STORAGE,
105
- category: ErrorCategory.USER,
106
- },
107
- e,
108
- );
109
- }
110
- }
111
-
112
- async init(): Promise<void> {
113
- if (this.isConnected) {
114
- return;
115
- }
116
-
117
- try {
118
- this.isConnected = true;
119
- this.#pgp = pgPromise();
120
- this.#db = this.#pgp(this.#config);
121
-
122
- const operations = new StoreOperationsPG({ client: this.#db, schemaName: this.schema });
123
- const scores = new ScoresPG({ client: this.#db, operations, schema: this.schema });
124
- const traces = new TracesPG({ client: this.#db, operations, schema: this.schema });
125
- const workflows = new WorkflowsPG({ client: this.#db, operations, schema: this.schema });
126
- const legacyEvals = new LegacyEvalsPG({ client: this.#db, schema: this.schema });
127
- const memory = new MemoryPG({ client: this.#db, schema: this.schema, operations });
128
-
129
- this.stores = {
130
- operations,
131
- scores,
132
- traces,
133
- workflows,
134
- legacyEvals,
135
- memory,
136
- };
137
-
138
- await super.init();
139
- } catch (error) {
140
- this.isConnected = false;
141
- throw new MastraError(
142
- {
143
- id: 'MASTRA_STORAGE_POSTGRES_STORE_INIT_FAILED',
144
- domain: ErrorDomain.STORAGE,
145
- category: ErrorCategory.THIRD_PARTY,
146
- },
147
- error,
148
- );
149
- }
150
- }
151
-
152
- public get db() {
153
- if (!this.#db) {
154
- throw new Error(`PostgresStore: Store is not initialized, please call "init()" first.`);
155
- }
156
- return this.#db;
157
- }
158
-
159
- public get pgp() {
160
- if (!this.#pgp) {
161
- throw new Error(`PostgresStore: Store is not initialized, please call "init()" first.`);
162
- }
163
- return this.#pgp;
164
- }
165
-
166
- public get supports() {
167
- return {
168
- selectByIncludeResourceScope: true,
169
- resourceWorkingMemory: true,
170
- hasColumn: true,
171
- createTable: true,
172
- deleteMessages: true,
173
- };
174
- }
175
-
176
- /** @deprecated use getEvals instead */
177
- async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {
178
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
179
- }
180
-
181
- async getEvals(
182
- options: {
183
- agentName?: string;
184
- type?: 'test' | 'live';
185
- } & PaginationArgs = {},
186
- ): Promise<PaginationInfo & { evals: EvalRow[] }> {
187
- return this.stores.legacyEvals.getEvals(options);
188
- }
189
-
190
- /**
191
- * @deprecated use getTracesPaginated instead
192
- */
193
- public async getTraces(args: StorageGetTracesArg): Promise<Trace[]> {
194
- return this.stores.traces.getTraces(args);
195
- }
196
-
197
- public async getTracesPaginated(args: StorageGetTracesPaginatedArg): Promise<PaginationInfo & { traces: Trace[] }> {
198
- return this.stores.traces.getTracesPaginated(args);
199
- }
200
-
201
- async batchTraceInsert({ records }: { records: Record<string, any>[] }): Promise<void> {
202
- return this.stores.traces.batchTraceInsert({ records });
203
- }
204
-
205
- async createTable({
206
- tableName,
207
- schema,
208
- }: {
209
- tableName: TABLE_NAMES;
210
- schema: Record<string, StorageColumn>;
211
- }): Promise<void> {
212
- return this.stores.operations.createTable({ tableName, schema });
213
- }
214
-
215
- async alterTable({
216
- tableName,
217
- schema,
218
- ifNotExists,
219
- }: {
220
- tableName: TABLE_NAMES;
221
- schema: Record<string, StorageColumn>;
222
- ifNotExists: string[];
223
- }): Promise<void> {
224
- return this.stores.operations.alterTable({ tableName, schema, ifNotExists });
225
- }
226
-
227
- async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
228
- return this.stores.operations.clearTable({ tableName });
229
- }
230
-
231
- async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
232
- return this.stores.operations.dropTable({ tableName });
233
- }
234
-
235
- async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {
236
- return this.stores.operations.insert({ tableName, record });
237
- }
238
-
239
- async batchInsert({ tableName, records }: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {
240
- return this.stores.operations.batchInsert({ tableName, records });
241
- }
242
-
243
- async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {
244
- return this.stores.operations.load({ tableName, keys });
245
- }
246
-
247
- /**
248
- * Memory
249
- */
250
-
251
- async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
252
- return this.stores.memory.getThreadById({ threadId });
253
- }
254
-
255
- /**
256
- * @deprecated use getThreadsByResourceIdPaginated instead
257
- */
258
- public async getThreadsByResourceId(args: { resourceId: string } & ThreadSortOptions): Promise<StorageThreadType[]> {
259
- return this.stores.memory.getThreadsByResourceId(args);
260
- }
261
-
262
- public async getThreadsByResourceIdPaginated(
263
- args: {
264
- resourceId: string;
265
- page: number;
266
- perPage: number;
267
- } & ThreadSortOptions,
268
- ): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
269
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
270
- }
271
-
272
- async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
273
- return this.stores.memory.saveThread({ thread });
274
- }
275
-
276
- async updateThread({
277
- id,
278
- title,
279
- metadata,
280
- }: {
281
- id: string;
282
- title: string;
283
- metadata: Record<string, unknown>;
284
- }): Promise<StorageThreadType> {
285
- return this.stores.memory.updateThread({ id, title, metadata });
286
- }
287
-
288
- async deleteThread({ threadId }: { threadId: string }): Promise<void> {
289
- return this.stores.memory.deleteThread({ threadId });
290
- }
291
-
292
- /**
293
- * @deprecated use getMessagesPaginated instead
294
- */
295
- public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
296
- public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;
297
- public async getMessages(
298
- args: StorageGetMessagesArg & {
299
- format?: 'v1' | 'v2';
300
- },
301
- ): Promise<MastraMessageV1[] | MastraMessageV2[]> {
302
- return this.stores.memory.getMessages(args);
303
- }
304
-
305
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format: 'v1' }): Promise<MastraMessageV1[]>;
306
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format?: 'v2' }): Promise<MastraMessageV2[]>;
307
- async getMessagesById({
308
- messageIds,
309
- format,
310
- }: {
311
- messageIds: string[];
312
- format?: 'v1' | 'v2';
313
- }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
314
- return this.stores.memory.getMessagesById({ messageIds, format });
315
- }
316
-
317
- public async getMessagesPaginated(
318
- args: StorageGetMessagesArg & {
319
- format?: 'v1' | 'v2';
320
- },
321
- ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
322
- return this.stores.memory.getMessagesPaginated(args);
323
- }
324
-
325
- async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;
326
- async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;
327
- async saveMessages(
328
- args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },
329
- ): Promise<MastraMessageV2[] | MastraMessageV1[]> {
330
- return this.stores.memory.saveMessages(args);
331
- }
332
-
333
- async updateMessages({
334
- messages,
335
- }: {
336
- messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {
337
- id: string;
338
- content?: {
339
- metadata?: MastraMessageContentV2['metadata'];
340
- content?: MastraMessageContentV2['content'];
341
- };
342
- })[];
343
- }): Promise<MastraMessageV2[]> {
344
- return this.stores.memory.updateMessages({ messages });
345
- }
346
-
347
- async deleteMessages(messageIds: string[]): Promise<void> {
348
- return this.stores.memory.deleteMessages(messageIds);
349
- }
350
-
351
- async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {
352
- return this.stores.memory.getResourceById({ resourceId });
353
- }
354
-
355
- async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {
356
- return this.stores.memory.saveResource({ resource });
357
- }
358
-
359
- async updateResource({
360
- resourceId,
361
- workingMemory,
362
- metadata,
363
- }: {
364
- resourceId: string;
365
- workingMemory?: string;
366
- metadata?: Record<string, unknown>;
367
- }): Promise<StorageResourceType> {
368
- return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
369
- }
370
-
371
- /**
372
- * Workflows
373
- */
374
- async updateWorkflowResults({
375
- workflowName,
376
- runId,
377
- stepId,
378
- result,
379
- runtimeContext,
380
- }: {
381
- workflowName: string;
382
- runId: string;
383
- stepId: string;
384
- result: StepResult<any, any, any, any>;
385
- runtimeContext: Record<string, any>;
386
- }): Promise<Record<string, StepResult<any, any, any, any>>> {
387
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
388
- }
389
-
390
- async updateWorkflowState({
391
- workflowName,
392
- runId,
393
- opts,
394
- }: {
395
- workflowName: string;
396
- runId: string;
397
- opts: {
398
- status: string;
399
- result?: StepResult<any, any, any, any>;
400
- error?: string;
401
- suspendedPaths?: Record<string, number[]>;
402
- waitingPaths?: Record<string, number[]>;
403
- };
404
- }): Promise<WorkflowRunState | undefined> {
405
- return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
406
- }
407
-
408
- async persistWorkflowSnapshot({
409
- workflowName,
410
- runId,
411
- snapshot,
412
- }: {
413
- workflowName: string;
414
- runId: string;
415
- snapshot: WorkflowRunState;
416
- }): Promise<void> {
417
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
418
- }
419
-
420
- async loadWorkflowSnapshot({
421
- workflowName,
422
- runId,
423
- }: {
424
- workflowName: string;
425
- runId: string;
426
- }): Promise<WorkflowRunState | null> {
427
- return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
428
- }
429
-
430
- async getWorkflowRuns({
431
- workflowName,
432
- fromDate,
433
- toDate,
434
- limit,
435
- offset,
436
- resourceId,
437
- }: {
438
- workflowName?: string;
439
- fromDate?: Date;
440
- toDate?: Date;
441
- limit?: number;
442
- offset?: number;
443
- resourceId?: string;
444
- } = {}): Promise<WorkflowRuns> {
445
- return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
446
- }
447
-
448
- async getWorkflowRunById({
449
- runId,
450
- workflowName,
451
- }: {
452
- runId: string;
453
- workflowName?: string;
454
- }): Promise<WorkflowRun | null> {
455
- return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
456
- }
457
-
458
- async close(): Promise<void> {
459
- this.pgp.end();
460
- }
461
-
462
- /**
463
- * Scorers
464
- */
465
- async getScoreById({ id: _id }: { id: string }): Promise<ScoreRowData | null> {
466
- return this.stores.scores.getScoreById({ id: _id });
467
- }
468
-
469
- async getScoresByScorerId({
470
- scorerId,
471
- pagination,
472
- entityId,
473
- entityType,
474
- source,
475
- }: {
476
- scorerId: string;
477
- pagination: StoragePagination;
478
- entityId?: string;
479
- entityType?: string;
480
- source?: ScoringSource;
481
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
482
- return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
483
- }
484
-
485
- async saveScore(_score: ScoreRowData): Promise<{ score: ScoreRowData }> {
486
- return this.stores.scores.saveScore(_score);
487
- }
488
-
489
- async getScoresByRunId({
490
- runId: _runId,
491
- pagination: _pagination,
492
- }: {
493
- runId: string;
494
- pagination: StoragePagination;
495
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
496
- return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
497
- }
498
-
499
- async getScoresByEntityId({
500
- entityId: _entityId,
501
- entityType: _entityType,
502
- pagination: _pagination,
503
- }: {
504
- pagination: StoragePagination;
505
- entityId: string;
506
- entityType: string;
507
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
508
- return this.stores.scores.getScoresByEntityId({
509
- entityId: _entityId,
510
- entityType: _entityType,
511
- pagination: _pagination,
512
- });
513
- }
514
- }