@mastra/pg 0.0.0-commonjs-20250227130920

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 ADDED
@@ -0,0 +1,161 @@
1
+ # @mastra/pg
2
+
3
+ PostgreSQL implementation for Mastra, providing both vector similarity search (using pgvector) and general storage capabilities with connection pooling and transaction support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @mastra/pg
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ - PostgreSQL server with pgvector extension installed (if using vector store)
14
+ - PostgreSQL 11 or higher
15
+
16
+ ## Usage
17
+
18
+ ### Vector Store
19
+
20
+ ```typescript
21
+ import { PgVector } from '@mastra/pg';
22
+
23
+ const vectorStore = new PgVector('postgresql://user:pass@localhost:5432/db');
24
+
25
+ // Create a new table with vector support
26
+ await vectorStore.createIndex('my_vectors', 1536, 'cosine');
27
+
28
+ // Add vectors
29
+ const ids = await vectorStore.upsert(
30
+ 'my_vectors',
31
+ [[0.1, 0.2, ...], [0.3, 0.4, ...]],
32
+ [{ text: 'doc1' }, { text: 'doc2' }]
33
+ );
34
+
35
+ // Query vectors
36
+ const results = await vectorStore.query(
37
+ 'my_vectors',
38
+ [0.1, 0.2, ...],
39
+ 10, // topK
40
+ { text: 'doc1' }, // filter
41
+ false, // includeVector
42
+ 0.5 // minScore
43
+ );
44
+
45
+ // Clean up
46
+ await vectorStore.disconnect();
47
+ ```
48
+
49
+ ### Storage
50
+
51
+ ```typescript
52
+ import { PostgresStore } from '@mastra/pg';
53
+
54
+ const store = new PostgresStore({
55
+ host: 'localhost',
56
+ port: 5432,
57
+ database: 'mastra',
58
+ user: 'postgres',
59
+ password: 'postgres',
60
+ });
61
+
62
+ // Create a thread
63
+ await store.saveThread({
64
+ id: 'thread-123',
65
+ resourceId: 'resource-456',
66
+ title: 'My Thread',
67
+ metadata: { key: 'value' },
68
+ });
69
+
70
+ // Add messages to thread
71
+ await store.saveMessages([
72
+ {
73
+ id: 'msg-789',
74
+ threadId: 'thread-123',
75
+ role: 'user',
76
+ type: 'text',
77
+ content: [{ type: 'text', text: 'Hello' }],
78
+ },
79
+ ]);
80
+
81
+ // Query threads and messages
82
+ const savedThread = await store.getThread('thread-123');
83
+ const messages = await store.getMessages('thread-123');
84
+ ```
85
+
86
+ ## Configuration
87
+
88
+ The PostgreSQL store can be initialized with either:
89
+
90
+ - `connectionString`: PostgreSQL connection string (for vector store)
91
+ - Configuration object with host, port, database, user, and password (for storage)
92
+
93
+ Connection pool settings:
94
+
95
+ - Maximum connections: 20
96
+ - Idle timeout: 30 seconds
97
+ - Connection timeout: 2 seconds
98
+
99
+ ## Features
100
+
101
+ ### Vector Store Features
102
+
103
+ - Vector similarity search with cosine, euclidean, and dot product metrics
104
+ - Advanced metadata filtering with MongoDB-like query syntax
105
+ - Minimum score threshold for queries
106
+ - Automatic UUID generation for vectors
107
+ - Table management (create, list, describe, delete, truncate)
108
+ - Uses pgvector's IVFFLAT indexing with 100 lists by default
109
+ - Supports HNSW indexing with configurable parameters
110
+ - Supports flat indexing
111
+
112
+ ### Storage Features
113
+
114
+ - Thread and message storage with JSON support
115
+ - Atomic transactions for data consistency
116
+ - Efficient batch operations
117
+ - Rich metadata support
118
+ - Timestamp tracking
119
+ - Cascading deletes
120
+
121
+ ## Supported Filter Operators
122
+
123
+ The following filter operators are supported for metadata queries:
124
+
125
+ - Comparison: `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`
126
+ - Logical: `$and`, `$or`
127
+ - Array: `$in`, `$nin`
128
+ - Text: `$regex`, `$like`
129
+
130
+ Example filter:
131
+
132
+ ```typescript
133
+ {
134
+ $and: [{ age: { $gt: 25 } }, { tags: { $in: ['tag1', 'tag2'] } }];
135
+ }
136
+ ```
137
+
138
+ ## Vector Store Methods
139
+
140
+ - `createIndex(indexName, dimension, metric?)`: Create a new table with vector support
141
+ - `upsert(indexName, vectors, metadata?, ids?)`: Add or update vectors
142
+ - `query(indexName, queryVector, topK?, filter?, includeVector?, minScore?)`: Search for similar vectors
143
+ - `listIndexes()`: List all vector-enabled tables
144
+ - `describeIndex(indexName)`: Get table statistics
145
+ - `deleteIndex(indexName)`: Delete a table
146
+ - `truncateIndex(indexName)`: Remove all data from a table
147
+ - `disconnect()`: Close all database connections
148
+
149
+ ## Storage Methods
150
+
151
+ - `saveThread(thread)`: Create or update a thread
152
+ - `getThread(threadId)`: Get a thread by ID
153
+ - `deleteThread(threadId)`: Delete a thread and its messages
154
+ - `saveMessages(messages)`: Save multiple messages in a transaction
155
+ - `getMessages(threadId)`: Get all messages for a thread
156
+ - `deleteMessages(messageIds)`: Delete specific messages
157
+
158
+ ## Related Links
159
+
160
+ - [pgvector Documentation](https://github.com/pgvector/pgvector)
161
+ - [PostgreSQL Documentation](https://www.postgresql.org/docs/)
@@ -0,0 +1,304 @@
1
+ import type { ArrayOperator } from '@mastra/core/filter';
2
+ import { BaseFilterTranslator } from '@mastra/core/filter';
3
+ import type { BasicOperator } from '@mastra/core/filter';
4
+ import type { ElementOperator } from '@mastra/core/filter';
5
+ import type { EvalRow } from '@mastra/core/storage';
6
+ import type { Filter } from '@mastra/core/filter';
7
+ import type { IndexStats } from '@mastra/core/vector';
8
+ import type { LogicalOperator } from '@mastra/core/filter';
9
+ import { MastraStorage } from '@mastra/core/storage';
10
+ import { MastraVector } from '@mastra/core/vector';
11
+ import type { MessageType } from '@mastra/core/memory';
12
+ import type { NumericOperator } from '@mastra/core/filter';
13
+ import type { OperatorSupport } from '@mastra/core/filter';
14
+ import type { QueryResult } from '@mastra/core/vector';
15
+ import type { RegexOperator } from '@mastra/core/filter';
16
+ import type { StorageColumn } from '@mastra/core/storage';
17
+ import type { StorageGetMessagesArg } from '@mastra/core/storage';
18
+ import type { StorageThreadType } from '@mastra/core/memory';
19
+ import type { TABLE_NAMES } from '@mastra/core/storage';
20
+ import type { WorkflowRunState } from '@mastra/core/workflows';
21
+
22
+ export declare const baseTestConfigs: {
23
+ smokeTests: {
24
+ dimension: number;
25
+ size: number;
26
+ k: number;
27
+ queryCount: number;
28
+ }[];
29
+ '64': {
30
+ dimension: number;
31
+ size: number;
32
+ k: number;
33
+ queryCount: number;
34
+ }[];
35
+ '384': {
36
+ dimension: number;
37
+ size: number;
38
+ k: number;
39
+ queryCount: number;
40
+ }[];
41
+ '1024': {
42
+ dimension: number;
43
+ size: number;
44
+ k: number;
45
+ queryCount: number;
46
+ }[];
47
+ stressTests: {
48
+ dimension: number;
49
+ size: number;
50
+ k: number;
51
+ queryCount: number;
52
+ }[];
53
+ };
54
+
55
+ export declare function buildFilterQuery(filter: Filter, minScore: number): FilterResult;
56
+
57
+ export declare const calculateRecall: (actual: number[], expected: number[], k: number) => number;
58
+
59
+ export declare const calculateTimeout: (dimension: number, size: number, k: number) => number;
60
+
61
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
62
+
63
+ export declare const FILTER_OPERATORS: Record<string, OperatorFn>;
64
+
65
+ declare type FilterOperator = {
66
+ sql: string;
67
+ needsValue: boolean;
68
+ transformValue?: (value: any) => any;
69
+ };
70
+
71
+ export declare interface FilterResult {
72
+ sql: string;
73
+ values: any[];
74
+ }
75
+
76
+ export declare const findNearestBruteForce: (query: number[], vectors: number[][], k: number) => number[];
77
+
78
+ export declare const formatTable: (data: any[], columns: string[]) => string;
79
+
80
+ export declare const generateClusteredVectors: (count: number, dim: number, numClusters?: number) => number[][];
81
+
82
+ export declare const generateRandomVectors: (count: number, dim: number) => number[][];
83
+
84
+ export declare const generateSkewedVectors: (count: number, dim: number) => number[][];
85
+
86
+ export declare const getHNSWConfig: (indexConfig: IndexConfig) => {
87
+ m: number;
88
+ efConstruction: number;
89
+ };
90
+
91
+ export declare function getIndexDescription({ type, hnsw, }: {
92
+ type: IndexType;
93
+ hnsw: {
94
+ m: number;
95
+ efConstruction: number;
96
+ };
97
+ }): string;
98
+
99
+ export declare const getListCount: (indexConfig: IndexConfig, size: number) => number | undefined;
100
+
101
+ export declare function getSearchEf(k: number, m: number): {
102
+ default: number;
103
+ lower: number;
104
+ higher: number;
105
+ };
106
+
107
+ export declare const groupBy: <T, K extends keyof T>(array: T[], key: K | ((item: T) => string), reducer?: (group: T[]) => any) => Record<string, any>;
108
+
109
+ export declare const handleKey: (key: string) => string;
110
+
111
+ declare interface HNSWConfig {
112
+ m?: number;
113
+ efConstruction?: number;
114
+ }
115
+
116
+ export declare interface IndexConfig {
117
+ type?: IndexType;
118
+ ivf?: IVFConfig;
119
+ hnsw?: HNSWConfig;
120
+ }
121
+
122
+ export declare type IndexType = 'ivfflat' | 'hnsw' | 'flat';
123
+
124
+ declare interface IVFConfig {
125
+ lists?: number;
126
+ }
127
+
128
+ export declare function measureLatency<T>(fn: () => Promise<T>): Promise<[number, T]>;
129
+
130
+ declare type OperatorFn = (key: string, paramIndex: number, value?: any) => FilterOperator;
131
+
132
+ export declare type OperatorType = BasicOperator | NumericOperator | ArrayOperator | ElementOperator | LogicalOperator | '$contains' | Exclude<RegexOperator, '$options'>;
133
+
134
+ /**
135
+ * Translates MongoDB-style filters to PG compatible filters.
136
+ *
137
+ * Key differences from MongoDB:
138
+ *
139
+ * Logical Operators ($and, $or, $nor):
140
+ * - Can be used at the top level or nested within fields
141
+ * - Can take either a single condition or an array of conditions
142
+ *
143
+ */
144
+ export declare class PGFilterTranslator extends BaseFilterTranslator {
145
+ protected getSupportedOperators(): OperatorSupport;
146
+ translate(filter: Filter): Filter;
147
+ private translateNode;
148
+ private translateRegexPattern;
149
+ }
150
+
151
+ declare interface PGIndexStats extends IndexStats {
152
+ type: IndexType;
153
+ config: {
154
+ m?: number;
155
+ efConstruction?: number;
156
+ lists?: number;
157
+ probes?: number;
158
+ };
159
+ }
160
+ export { PGIndexStats }
161
+ export { PGIndexStats as PGIndexStats_alias_1 }
162
+
163
+ declare class PgVector extends MastraVector {
164
+ private pool;
165
+ private indexCache;
166
+ constructor(connectionString: string);
167
+ transformFilter(filter?: Filter): Filter;
168
+ getIndexInfo(indexName: string): Promise<PGIndexStats>;
169
+ query(indexName: string, queryVector: number[], topK?: number, filter?: Filter, includeVector?: boolean, minScore?: number, // Optional minimum score threshold
170
+ options?: {
171
+ ef?: number;
172
+ probes?: number;
173
+ }): Promise<QueryResult[]>;
174
+ upsert(indexName: string, vectors: number[][], metadata?: Record<string, any>[], ids?: string[]): Promise<string[]>;
175
+ createIndex(indexName: string, dimension: number, metric?: 'cosine' | 'euclidean' | 'dotproduct', indexConfig?: IndexConfig, defineIndex?: boolean): Promise<void>;
176
+ /**
177
+ * @deprecated This function is deprecated. Use buildIndex instead
178
+ */
179
+ defineIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
180
+ buildIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
181
+ listIndexes(): Promise<string[]>;
182
+ describeIndex(indexName: string): Promise<PGIndexStats>;
183
+ deleteIndex(indexName: string): Promise<void>;
184
+ truncateIndex(indexName: string): Promise<void>;
185
+ disconnect(): Promise<void>;
186
+ }
187
+ export { PgVector }
188
+ export { PgVector as PgVector_alias_1 }
189
+
190
+ declare type PostgresConfig = {
191
+ host: string;
192
+ port: number;
193
+ database: string;
194
+ user: string;
195
+ password: string;
196
+ } | {
197
+ connectionString: string;
198
+ };
199
+ export { PostgresConfig }
200
+ export { PostgresConfig as PostgresConfig_alias_1 }
201
+
202
+ declare class PostgresStore extends MastraStorage {
203
+ private db;
204
+ private pgp;
205
+ constructor(config: PostgresConfig);
206
+ getEvalsByAgentName(_agentName: string, _type?: 'test' | 'live'): Promise<EvalRow[]>;
207
+ batchInsert({ tableName, records }: {
208
+ tableName: TABLE_NAMES;
209
+ records: Record<string, any>[];
210
+ }): Promise<void>;
211
+ getTraces({ name, scope, page, perPage, attributes, }: {
212
+ name?: string;
213
+ scope?: string;
214
+ page: number;
215
+ perPage: number;
216
+ attributes?: Record<string, string>;
217
+ }): Promise<any[]>;
218
+ createTable({ tableName, schema, }: {
219
+ tableName: TABLE_NAMES;
220
+ schema: Record<string, StorageColumn>;
221
+ }): Promise<void>;
222
+ clearTable({ tableName }: {
223
+ tableName: TABLE_NAMES;
224
+ }): Promise<void>;
225
+ insert({ tableName, record }: {
226
+ tableName: TABLE_NAMES;
227
+ record: Record<string, any>;
228
+ }): Promise<void>;
229
+ load<R>({ tableName, keys }: {
230
+ tableName: TABLE_NAMES;
231
+ keys: Record<string, string>;
232
+ }): Promise<R | null>;
233
+ getThreadById({ threadId }: {
234
+ threadId: string;
235
+ }): Promise<StorageThreadType | null>;
236
+ getThreadsByResourceId({ resourceId }: {
237
+ resourceId: string;
238
+ }): Promise<StorageThreadType[]>;
239
+ saveThread({ thread }: {
240
+ thread: StorageThreadType;
241
+ }): Promise<StorageThreadType>;
242
+ updateThread({ id, title, metadata, }: {
243
+ id: string;
244
+ title: string;
245
+ metadata: Record<string, unknown>;
246
+ }): Promise<StorageThreadType>;
247
+ deleteThread({ threadId }: {
248
+ threadId: string;
249
+ }): Promise<void>;
250
+ getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T>;
251
+ saveMessages({ messages }: {
252
+ messages: MessageType[];
253
+ }): Promise<MessageType[]>;
254
+ persistWorkflowSnapshot({ workflowName, runId, snapshot, }: {
255
+ workflowName: string;
256
+ runId: string;
257
+ snapshot: WorkflowRunState;
258
+ }): Promise<void>;
259
+ loadWorkflowSnapshot({ workflowName, runId, }: {
260
+ workflowName: string;
261
+ runId: string;
262
+ }): Promise<WorkflowRunState | null>;
263
+ close(): Promise<void>;
264
+ }
265
+ export { PostgresStore }
266
+ export { PostgresStore as PostgresStore_alias_1 }
267
+
268
+ export declare interface TestConfig {
269
+ dimension: number;
270
+ size: number;
271
+ k: number;
272
+ queryCount: number;
273
+ }
274
+
275
+ export declare interface TestResult {
276
+ distribution: string;
277
+ dimension: number;
278
+ type: IndexType;
279
+ size: number;
280
+ k?: number;
281
+ metrics: {
282
+ recall?: number;
283
+ minRecall?: number;
284
+ maxRecall?: number;
285
+ latency?: {
286
+ p50: number;
287
+ p95: number;
288
+ lists?: number;
289
+ vectorsPerList?: number;
290
+ m?: number;
291
+ ef?: number;
292
+ };
293
+ clustering?: {
294
+ numLists?: number;
295
+ avgVectorsPerList?: number;
296
+ recommendedLists?: number;
297
+ distribution?: string;
298
+ };
299
+ };
300
+ }
301
+
302
+ export declare function warmupQuery(vectorDB: PgVector, indexName: string, dimension: number, k: number): Promise<void>;
303
+
304
+ export { }