@mastra/upstash 0.12.4-alpha.0 → 0.13.0-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.
@@ -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 = 1536;
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: 1536,
253
+ dimension: 1024,
254
254
  metric: 'cosine',
255
255
  count: 0,
256
256
  });
@@ -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({ indexName: namespace, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {
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 }: UpdateVectorParams): Promise<void> {
213
- try {
214
- if (!update.vector && !update.metadata) {
215
- throw new Error('No update data provided');
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
- // The upstash client throws an exception as: 'This index requires dense vectors' when
219
- // only metadata is present in the update object.
220
- if (!update.vector && update.metadata) {
221
- throw new Error('Both vector and metadata must be provided for an update');
222
- }
223
- } catch (error) {
224
- throw new MastraError(
225
- {
226
- id: 'STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED',
227
- domain: ErrorDomain.STORAGE,
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 updatePayload: any = { id: id };
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
- const points = {
245
- id: updatePayload.id,
246
- vector: updatePayload.vector,
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
+ }