@mastra/upstash 0.15.8-alpha.0 → 0.15.9-alpha.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/upstash
2
2
 
3
+ ## 0.15.9-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix message sorting in listMessages when using semantic recall (include parameter). Messages are now always sorted by createdAt instead of storage order, ensuring correct chronological ordering of conversation history. ([#10545](https://github.com/mastra-ai/mastra/pull/10545))
8
+
9
+ - Updated dependencies [[`5657314`](https://github.com/mastra-ai/mastra/commit/5657314a1f9d49019bb53f357fa48f75a69247ca), [`e5aca78`](https://github.com/mastra-ai/mastra/commit/e5aca78bb7f263bb8b470bedae81efe9805d7544), [`33a607a`](https://github.com/mastra-ai/mastra/commit/33a607a1f716c2029d4a1ff1603dd756129a33b3), [`cc10fc1`](https://github.com/mastra-ai/mastra/commit/cc10fc192d9f527c71a23cc9def10d8718935ee1), [`1f7ee84`](https://github.com/mastra-ai/mastra/commit/1f7ee841a643ef12d90392125881f06fdf877293), [`e7d5149`](https://github.com/mastra-ai/mastra/commit/e7d514995260b63b2108308e85c64de37dcd0f71), [`f195082`](https://github.com/mastra-ai/mastra/commit/f1950822a2425d5ccae78c5d010e02ddb027a869), [`d9986dd`](https://github.com/mastra-ai/mastra/commit/d9986dd3513f7ca3244a8e599a440ccf4d8bc28b), [`a45b0f0`](https://github.com/mastra-ai/mastra/commit/a45b0f0cd19eab1fe4deceae3abf029442c22f74), [`f6e8eb3`](https://github.com/mastra-ai/mastra/commit/f6e8eb3dac53b70b06e906b2818b1d2a5b0486d7), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`3236f35`](https://github.com/mastra-ai/mastra/commit/3236f352ae13cc8552c2965164e97bd125dae48d), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`0230321`](https://github.com/mastra-ai/mastra/commit/02303217870bedea0ef009bea9a952f24ed38aaf), [`7b541f4`](https://github.com/mastra-ai/mastra/commit/7b541f49eda6f5a87b738198edbd136927599475), [`0eea842`](https://github.com/mastra-ai/mastra/commit/0eea8423cbdd37f2111593c6f7d2efcde4b7e4ce), [`63ae8a2`](https://github.com/mastra-ai/mastra/commit/63ae8a22c0c09bbb8b9779f5f38934cd75f616af), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`ac7ef07`](https://github.com/mastra-ai/mastra/commit/ac7ef07633caee89707142171d2873c888ffef85), [`522f0b4`](https://github.com/mastra-ai/mastra/commit/522f0b45330719858794eabffffde4f343f55549), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`8b51d55`](https://github.com/mastra-ai/mastra/commit/8b51d55bae531edf7e383958d7ecee04df31f5d5), [`2131ac5`](https://github.com/mastra-ai/mastra/commit/2131ac571d5065f0a656c57494bca98691bb7609)]:
10
+ - @mastra/core@0.24.6-alpha.0
11
+
12
+ ## 0.15.8
13
+
14
+ ### Patch Changes
15
+
16
+ - update peerdeps ([`5ca1cca`](https://github.com/mastra-ai/mastra/commit/5ca1ccac61ffa7141e6d9fa8f22d3ad4d03bf5dc))
17
+
18
+ - Updated dependencies [[`5ca1cca`](https://github.com/mastra-ai/mastra/commit/5ca1ccac61ffa7141e6d9fa8f22d3ad4d03bf5dc), [`6d7e90d`](https://github.com/mastra-ai/mastra/commit/6d7e90db09713e6250f4d6c3d3cff1b4740e50f9), [`f78b908`](https://github.com/mastra-ai/mastra/commit/f78b9080e11af765969b36b4a619761056030840), [`23c2614`](https://github.com/mastra-ai/mastra/commit/23c26140fdbf04b8c59e8d7d52106d67dad962ec), [`e365eda`](https://github.com/mastra-ai/mastra/commit/e365eda45795b43707310531cac1e2ce4e5a0712)]:
19
+ - @mastra/core@0.24.0
20
+
3
21
  ## 0.15.8-alpha.0
4
22
 
5
23
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -782,7 +782,7 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
782
782
  if (toDate) {
783
783
  messagesData = messagesData.filter((msg) => msg && new Date(msg.createdAt).getTime() <= toDate.getTime());
784
784
  }
785
- messagesData.sort((a, b) => allMessageIds.indexOf(a.id) - allMessageIds.indexOf(b.id));
785
+ messagesData.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
786
786
  const total = messagesData.length;
787
787
  const start = page * perPage;
788
788
  const end = start + perPage;
@@ -790,7 +790,8 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
790
790
  const paginatedMessages = messagesData.slice(start, end);
791
791
  messages.push(...paginatedMessages);
792
792
  const list = new agent.MessageList().add(messages, "memory");
793
- const finalMessages = format === `v2` ? list.get.all.v2() : list.get.all.v1();
793
+ let finalMessages = format === `v2` ? list.get.all.v2() : list.get.all.v1();
794
+ finalMessages = finalMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
794
795
  return {
795
796
  messages: finalMessages,
796
797
  total,
@@ -1245,7 +1246,9 @@ var ScoresUpstash = class extends storage.ScoresStorage {
1245
1246
  id: "STORAGE_UPSTASH_STORAGE_GET_SCORE_BY_ID_FAILED",
1246
1247
  domain: error.ErrorDomain.STORAGE,
1247
1248
  category: error.ErrorCategory.THIRD_PARTY,
1248
- details: { id }
1249
+ details: {
1250
+ ...id && { id }
1251
+ }
1249
1252
  },
1250
1253
  error$1
1251
1254
  );
@@ -2367,6 +2370,11 @@ var UpstashVector = class extends vector.MastraVector {
2367
2370
  try {
2368
2371
  await this.client.deleteNamespace(namespace);
2369
2372
  } catch (error$1) {
2373
+ const errorMessage = error$1?.message || "";
2374
+ if (errorMessage.includes("does not exist") || errorMessage.includes("not found")) {
2375
+ this.logger.info(`Namespace ${namespace} does not exist, treating as already deleted`);
2376
+ return;
2377
+ }
2370
2378
  throw new error.MastraError(
2371
2379
  {
2372
2380
  id: "STORAGE_UPSTASH_VECTOR_DELETE_INDEX_FAILED",
@@ -2379,47 +2387,124 @@ var UpstashVector = class extends vector.MastraVector {
2379
2387
  }
2380
2388
  }
2381
2389
  /**
2382
- * Updates a vector by its ID with the provided vector and/or metadata.
2383
- * @param indexName - The name of the namespace containing the vector.
2384
- * @param id - The ID of the vector to update.
2385
- * @param update - An object containing the vector and/or metadata to update.
2386
- * @param update.vector - An optional array of numbers representing the new vector.
2387
- * @param update.metadata - An optional record containing the new metadata.
2390
+ * Updates a vector by its ID or multiple vectors matching a filter.
2391
+ * @param params - Parameters containing the id or filter for targeting the vector(s) to update
2392
+ * @param params.indexName - The name of the namespace containing the vector.
2393
+ * @param params.id - The ID of the vector to update (mutually exclusive with filter).
2394
+ * @param params.filter - Filter to match multiple vectors to update (mutually exclusive with id).
2395
+ * @param params.update - An object containing the vector and/or metadata to update.
2388
2396
  * @returns A promise that resolves when the update is complete.
2389
2397
  * @throws Will throw an error if no updates are provided or if the update operation fails.
2390
2398
  */
2391
- async updateVector({ indexName: namespace, id, update }) {
2392
- if (!update.vector && !update.metadata && !update.sparseVector) {
2399
+ async updateVector(params) {
2400
+ const { indexName: namespace, update } = params;
2401
+ const upstashUpdate = update;
2402
+ const sparseVector = upstashUpdate.sparseVector;
2403
+ if ("id" in params && params.id && "filter" in params && params.filter) {
2393
2404
  throw new error.MastraError({
2394
- id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
2405
+ id: "STORAGE_UPSTASH_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE",
2406
+ text: "Cannot specify both id and filter - they are mutually exclusive",
2395
2407
  domain: error.ErrorDomain.STORAGE,
2396
- category: error.ErrorCategory.THIRD_PARTY,
2397
- details: { namespace, id },
2398
- text: "No update data provided"
2408
+ category: error.ErrorCategory.USER,
2409
+ details: { namespace }
2399
2410
  });
2400
2411
  }
2401
- if (!update.vector && !update.sparseVector && update.metadata) {
2412
+ if (!("id" in params && params.id) && !("filter" in params && params.filter)) {
2402
2413
  throw new error.MastraError({
2403
- id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
2414
+ id: "STORAGE_UPSTASH_VECTOR_UPDATE_NO_TARGET",
2415
+ text: "Either id or filter must be provided",
2404
2416
  domain: error.ErrorDomain.STORAGE,
2405
- category: error.ErrorCategory.THIRD_PARTY,
2406
- details: { namespace, id },
2407
- text: "Both vector and metadata must be provided for an update"
2417
+ category: error.ErrorCategory.USER,
2418
+ details: { namespace }
2419
+ });
2420
+ }
2421
+ if (!update.vector && !update.metadata && !sparseVector) {
2422
+ throw new error.MastraError({
2423
+ id: "STORAGE_UPSTASH_VECTOR_UPDATE_NO_PAYLOAD",
2424
+ text: "No update data provided",
2425
+ domain: error.ErrorDomain.STORAGE,
2426
+ category: error.ErrorCategory.USER,
2427
+ details: { namespace }
2428
+ });
2429
+ }
2430
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
2431
+ throw new error.MastraError({
2432
+ id: "STORAGE_UPSTASH_VECTOR_UPDATE_EMPTY_FILTER",
2433
+ text: "Filter cannot be an empty filter object",
2434
+ domain: error.ErrorDomain.STORAGE,
2435
+ category: error.ErrorCategory.USER,
2436
+ details: { namespace }
2408
2437
  });
2409
2438
  }
2410
2439
  try {
2411
- const points = { id };
2412
- if (update.vector) points.vector = update.vector;
2413
- if (update.metadata) points.metadata = update.metadata;
2414
- if (update.sparseVector) points.sparseVector = update.sparseVector;
2415
- await this.client.upsert(points, { namespace });
2440
+ const ns = this.client.namespace(namespace);
2441
+ if ("id" in params && params.id) {
2442
+ const points = { id: params.id };
2443
+ if (!update.vector || !update.metadata) {
2444
+ try {
2445
+ const existing = await ns.fetch([params.id], {
2446
+ includeVectors: true,
2447
+ includeMetadata: true
2448
+ });
2449
+ if (existing && existing.length > 0 && existing[0]) {
2450
+ if (!update.vector && existing[0]?.vector) {
2451
+ points.vector = existing[0].vector;
2452
+ }
2453
+ if (!update.metadata && existing[0]?.metadata) {
2454
+ points.metadata = existing[0].metadata;
2455
+ }
2456
+ }
2457
+ } catch (fetchError) {
2458
+ this.logger.warn(`Failed to fetch existing vector ${params.id} for partial update: ${fetchError}`);
2459
+ }
2460
+ }
2461
+ if (update.vector) points.vector = update.vector;
2462
+ if (update.metadata) points.metadata = update.metadata;
2463
+ if (sparseVector) points.sparseVector = sparseVector;
2464
+ await ns.upsert(points);
2465
+ } else if ("filter" in params && params.filter) {
2466
+ const filterString = this.transformFilter(params.filter);
2467
+ if (filterString) {
2468
+ const stats = await this.describeIndex({ indexName: namespace });
2469
+ const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));
2470
+ const needsVectors = !update.vector;
2471
+ const results = await ns.query({
2472
+ vector: dummyVector,
2473
+ topK: 1e3,
2474
+ // Upstash's max query limit
2475
+ filter: filterString,
2476
+ includeVectors: needsVectors,
2477
+ includeMetadata: needsVectors
2478
+ });
2479
+ for (const result of results) {
2480
+ const points = { id: `${result.id}` };
2481
+ if (update.vector) {
2482
+ points.vector = update.vector;
2483
+ } else if (result.vector) {
2484
+ points.vector = result.vector;
2485
+ }
2486
+ if (update.metadata) {
2487
+ points.metadata = update.metadata;
2488
+ } else if (result.metadata) {
2489
+ points.metadata = result.metadata;
2490
+ }
2491
+ if (sparseVector) points.sparseVector = sparseVector;
2492
+ await ns.upsert(points);
2493
+ }
2494
+ }
2495
+ }
2416
2496
  } catch (error$1) {
2497
+ if (error$1 instanceof error.MastraError) throw error$1;
2417
2498
  throw new error.MastraError(
2418
2499
  {
2419
2500
  id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
2420
2501
  domain: error.ErrorDomain.STORAGE,
2421
2502
  category: error.ErrorCategory.THIRD_PARTY,
2422
- details: { namespace, id }
2503
+ details: {
2504
+ namespace,
2505
+ ..."id" in params && params.id && { id: params.id },
2506
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) }
2507
+ }
2423
2508
  },
2424
2509
  error$1
2425
2510
  );
@@ -2434,22 +2519,109 @@ var UpstashVector = class extends vector.MastraVector {
2434
2519
  */
2435
2520
  async deleteVector({ indexName: namespace, id }) {
2436
2521
  try {
2437
- await this.client.delete(id, {
2438
- namespace
2439
- });
2522
+ const ns = this.client.namespace(namespace);
2523
+ await ns.delete(id);
2440
2524
  } catch (error$1) {
2441
2525
  const mastraError = new error.MastraError(
2442
2526
  {
2443
2527
  id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTOR_FAILED",
2444
2528
  domain: error.ErrorDomain.STORAGE,
2445
2529
  category: error.ErrorCategory.THIRD_PARTY,
2446
- details: { namespace, id }
2530
+ details: {
2531
+ namespace,
2532
+ ...id && { id }
2533
+ }
2447
2534
  },
2448
2535
  error$1
2449
2536
  );
2450
2537
  this.logger?.error(mastraError.toString());
2451
2538
  }
2452
2539
  }
2540
+ /**
2541
+ * Deletes multiple vectors by IDs or filter.
2542
+ * @param indexName - The name of the namespace containing the vectors.
2543
+ * @param ids - Array of vector IDs to delete (mutually exclusive with filter).
2544
+ * @param filter - Filter to match vectors to delete (mutually exclusive with ids).
2545
+ * @returns A promise that resolves when the deletion is complete.
2546
+ * @throws Will throw an error if both ids and filter are provided, or if neither is provided.
2547
+ */
2548
+ async deleteVectors({ indexName: namespace, filter, ids }) {
2549
+ if (ids && filter) {
2550
+ throw new error.MastraError({
2551
+ id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_MUTUALLY_EXCLUSIVE",
2552
+ text: "Cannot specify both ids and filter - they are mutually exclusive",
2553
+ domain: error.ErrorDomain.STORAGE,
2554
+ category: error.ErrorCategory.USER,
2555
+ details: { namespace }
2556
+ });
2557
+ }
2558
+ if (!ids && !filter) {
2559
+ throw new error.MastraError({
2560
+ id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_NO_TARGET",
2561
+ text: "Either filter or ids must be provided",
2562
+ domain: error.ErrorDomain.STORAGE,
2563
+ category: error.ErrorCategory.USER,
2564
+ details: { namespace }
2565
+ });
2566
+ }
2567
+ if (ids && ids.length === 0) {
2568
+ throw new error.MastraError({
2569
+ id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_EMPTY_IDS",
2570
+ text: "Cannot delete with empty ids array",
2571
+ domain: error.ErrorDomain.STORAGE,
2572
+ category: error.ErrorCategory.USER,
2573
+ details: { namespace }
2574
+ });
2575
+ }
2576
+ if (filter && Object.keys(filter).length === 0) {
2577
+ throw new error.MastraError({
2578
+ id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_EMPTY_FILTER",
2579
+ text: "Cannot delete with empty filter object",
2580
+ domain: error.ErrorDomain.STORAGE,
2581
+ category: error.ErrorCategory.USER,
2582
+ details: { namespace }
2583
+ });
2584
+ }
2585
+ try {
2586
+ const ns = this.client.namespace(namespace);
2587
+ if (ids) {
2588
+ await ns.delete(ids);
2589
+ } else if (filter) {
2590
+ const filterString = this.transformFilter(filter);
2591
+ if (filterString) {
2592
+ const stats = await this.describeIndex({ indexName: namespace });
2593
+ const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));
2594
+ const results = await ns.query({
2595
+ vector: dummyVector,
2596
+ topK: 1e3,
2597
+ // Upstash's max query limit
2598
+ filter: filterString,
2599
+ includeVectors: false,
2600
+ includeMetadata: false
2601
+ });
2602
+ const idsToDelete = results.map((r) => `${r.id}`);
2603
+ if (idsToDelete.length > 0) {
2604
+ await ns.delete(idsToDelete);
2605
+ }
2606
+ }
2607
+ }
2608
+ } catch (error$1) {
2609
+ if (error$1 instanceof error.MastraError) throw error$1;
2610
+ throw new error.MastraError(
2611
+ {
2612
+ id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_FAILED",
2613
+ domain: error.ErrorDomain.STORAGE,
2614
+ category: error.ErrorCategory.THIRD_PARTY,
2615
+ details: {
2616
+ namespace,
2617
+ ...filter && { filter: JSON.stringify(filter) },
2618
+ ...ids && { idsCount: ids.length }
2619
+ }
2620
+ },
2621
+ error$1
2622
+ );
2623
+ }
2624
+ }
2453
2625
  };
2454
2626
 
2455
2627
  // src/vector/prompt.ts