@mastra/upstash 0.12.3 → 0.12.4-alpha.1
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +46 -0
- package/README.md +98 -0
- package/dist/_tsup-dts-rollup.d.cts +30 -4
- package/dist/_tsup-dts-rollup.d.ts +30 -4
- package/dist/index.cjs +97 -36
- package/dist/index.js +97 -36
- package/package.json +5 -5
- package/src/storage/domains/memory/index.ts +70 -0
- package/src/storage/index.ts +5 -0
- package/src/vector/hybrid.test.ts +1455 -0
- package/src/vector/index.test.ts +2 -2
- package/src/vector/index.ts +40 -41
- package/src/vector/types.ts +26 -0
package/src/vector/index.test.ts
CHANGED
|
@@ -37,7 +37,7 @@ function waitUntilVectorsIndexed(vector: UpstashVector, indexName: string, expec
|
|
|
37
37
|
*/
|
|
38
38
|
describe.skipIf(!process.env.UPSTASH_VECTOR_URL || !process.env.UPSTASH_VECTOR_TOKEN)('UpstashVector', () => {
|
|
39
39
|
let vectorStore: UpstashVector;
|
|
40
|
-
const VECTOR_DIMENSION =
|
|
40
|
+
const VECTOR_DIMENSION = 1024;
|
|
41
41
|
const testIndexName = 'default';
|
|
42
42
|
const filterIndexName = 'filter-index';
|
|
43
43
|
|
|
@@ -250,7 +250,7 @@ describe.skipIf(!process.env.UPSTASH_VECTOR_URL || !process.env.UPSTASH_VECTOR_T
|
|
|
250
250
|
it('should describe an index correctly', async () => {
|
|
251
251
|
const stats = await vectorStore.describeIndex({ indexName: 'mastra_default' });
|
|
252
252
|
expect(stats).toEqual({
|
|
253
|
-
dimension:
|
|
253
|
+
dimension: 1024,
|
|
254
254
|
metric: 'cosine',
|
|
255
255
|
count: 0,
|
|
256
256
|
});
|
package/src/vector/index.ts
CHANGED
|
@@ -7,16 +7,12 @@ import type {
|
|
|
7
7
|
DescribeIndexParams,
|
|
8
8
|
IndexStats,
|
|
9
9
|
QueryResult,
|
|
10
|
-
QueryVectorParams,
|
|
11
|
-
UpdateVectorParams,
|
|
12
|
-
UpsertVectorParams,
|
|
13
10
|
} from '@mastra/core/vector';
|
|
14
11
|
import { Index } from '@upstash/vector';
|
|
15
12
|
|
|
16
13
|
import { UpstashFilterTranslator } from './filter';
|
|
17
14
|
import type { UpstashVectorFilter } from './filter';
|
|
18
|
-
|
|
19
|
-
type UpstashQueryVectorParams = QueryVectorParams<UpstashVectorFilter>;
|
|
15
|
+
import type { UpstashUpsertVectorParams, UpstashQueryVectorParams, UpstashUpdateVectorParams } from './types';
|
|
20
16
|
|
|
21
17
|
export class UpstashVector extends MastraVector<UpstashVectorFilter> {
|
|
22
18
|
private client: Index;
|
|
@@ -40,12 +36,19 @@ export class UpstashVector extends MastraVector<UpstashVectorFilter> {
|
|
|
40
36
|
* @param {UpsertVectorParams} params - The parameters for the upsert operation.
|
|
41
37
|
* @returns {Promise<string[]>} A promise that resolves to the IDs of the upserted vectors.
|
|
42
38
|
*/
|
|
43
|
-
async upsert({
|
|
39
|
+
async upsert({
|
|
40
|
+
indexName: namespace,
|
|
41
|
+
vectors,
|
|
42
|
+
metadata,
|
|
43
|
+
ids,
|
|
44
|
+
sparseVectors,
|
|
45
|
+
}: UpstashUpsertVectorParams): Promise<string[]> {
|
|
44
46
|
const generatedIds = ids || vectors.map(() => crypto.randomUUID());
|
|
45
47
|
|
|
46
48
|
const points = vectors.map((vector, index) => ({
|
|
47
49
|
id: generatedIds[index]!,
|
|
48
50
|
vector,
|
|
51
|
+
...(sparseVectors?.[index] && { sparseVector: sparseVectors[index] }),
|
|
49
52
|
metadata: metadata?.[index],
|
|
50
53
|
}));
|
|
51
54
|
|
|
@@ -97,6 +100,9 @@ export class UpstashVector extends MastraVector<UpstashVectorFilter> {
|
|
|
97
100
|
topK = 10,
|
|
98
101
|
filter,
|
|
99
102
|
includeVector = false,
|
|
103
|
+
sparseVector,
|
|
104
|
+
fusionAlgorithm,
|
|
105
|
+
queryMode,
|
|
100
106
|
}: UpstashQueryVectorParams): Promise<QueryResult[]> {
|
|
101
107
|
try {
|
|
102
108
|
const ns = this.client.namespace(namespace);
|
|
@@ -105,9 +111,12 @@ export class UpstashVector extends MastraVector<UpstashVectorFilter> {
|
|
|
105
111
|
const results = await ns.query({
|
|
106
112
|
topK,
|
|
107
113
|
vector: queryVector,
|
|
114
|
+
...(sparseVector && { sparseVector }),
|
|
108
115
|
includeVectors: includeVector,
|
|
109
116
|
includeMetadata: true,
|
|
110
117
|
...(filterString ? { filter: filterString } : {}),
|
|
118
|
+
...(fusionAlgorithm && { fusionAlgorithm }),
|
|
119
|
+
...(queryMode && { queryMode }),
|
|
111
120
|
});
|
|
112
121
|
|
|
113
122
|
// Map the results to our expected format
|
|
@@ -209,47 +218,37 @@ export class UpstashVector extends MastraVector<UpstashVectorFilter> {
|
|
|
209
218
|
* @returns A promise that resolves when the update is complete.
|
|
210
219
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
211
220
|
*/
|
|
212
|
-
async updateVector({ indexName: namespace, id, update }:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
async updateVector({ indexName: namespace, id, update }: UpstashUpdateVectorParams): Promise<void> {
|
|
222
|
+
if (!update.vector && !update.metadata && !update.sparseVector) {
|
|
223
|
+
throw new MastraError({
|
|
224
|
+
id: 'STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
225
|
+
domain: ErrorDomain.STORAGE,
|
|
226
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
227
|
+
details: { namespace, id },
|
|
228
|
+
text: 'No update data provided',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
217
231
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
229
|
-
details: { namespace, id },
|
|
230
|
-
},
|
|
231
|
-
error,
|
|
232
|
-
);
|
|
232
|
+
// The upstash client throws an exception as: 'This index requires dense/sparse vectors' when
|
|
233
|
+
// only metadata is present in the update object.
|
|
234
|
+
if (!update.vector && !update.sparseVector && update.metadata) {
|
|
235
|
+
throw new MastraError({
|
|
236
|
+
id: 'STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
237
|
+
domain: ErrorDomain.STORAGE,
|
|
238
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
239
|
+
details: { namespace, id },
|
|
240
|
+
text: 'Both vector and metadata must be provided for an update',
|
|
241
|
+
});
|
|
233
242
|
}
|
|
234
243
|
|
|
235
244
|
try {
|
|
236
|
-
const
|
|
237
|
-
if (update.vector) {
|
|
238
|
-
updatePayload.vector = update.vector;
|
|
239
|
-
}
|
|
240
|
-
if (update.metadata) {
|
|
241
|
-
updatePayload.metadata = update.metadata;
|
|
242
|
-
}
|
|
245
|
+
const points: any = { id };
|
|
243
246
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
metadata: updatePayload.metadata,
|
|
248
|
-
};
|
|
247
|
+
if (update.vector) points.vector = update.vector;
|
|
248
|
+
if (update.metadata) points.metadata = update.metadata;
|
|
249
|
+
if (update.sparseVector) points.sparseVector = update.sparseVector;
|
|
249
250
|
|
|
250
|
-
await this.client.upsert(points, {
|
|
251
|
-
namespace,
|
|
252
|
-
});
|
|
251
|
+
await this.client.upsert(points, { namespace });
|
|
253
252
|
} catch (error) {
|
|
254
253
|
throw new MastraError(
|
|
255
254
|
{
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { UpsertVectorParams, QueryVectorParams, UpdateVectorParams } from '@mastra/core/vector';
|
|
2
|
+
import type { FusionAlgorithm, QueryMode } from '@upstash/vector';
|
|
3
|
+
import type { UpstashVectorFilter } from './filter';
|
|
4
|
+
|
|
5
|
+
export interface UpstashSparseVector {
|
|
6
|
+
indices: number[];
|
|
7
|
+
values: number[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface UpstashUpsertVectorParams extends UpsertVectorParams {
|
|
11
|
+
sparseVectors?: UpstashSparseVector[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UpstashQueryVectorParams extends QueryVectorParams<UpstashVectorFilter> {
|
|
15
|
+
sparseVector?: UpstashSparseVector;
|
|
16
|
+
fusionAlgorithm?: FusionAlgorithm;
|
|
17
|
+
queryMode?: QueryMode;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface UpstashUpdateVectorParams extends UpdateVectorParams {
|
|
21
|
+
update: {
|
|
22
|
+
vector?: number[];
|
|
23
|
+
metadata?: Record<string, any>;
|
|
24
|
+
sparseVector?: UpstashSparseVector;
|
|
25
|
+
};
|
|
26
|
+
}
|