@mastra/upstash 1.0.3 → 1.0.4

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,29 @@
1
1
  # @mastra/upstash
2
2
 
3
+ ## 1.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - dependencies updates: ([#13822](https://github.com/mastra-ai/mastra/pull/13822))
8
+ - Updated dependency [`@upstash/redis@^1.36.3` ↗︎](https://www.npmjs.com/package/@upstash/redis/v/1.36.3) (from `^1.36.2`, in `dependencies`)
9
+
10
+ - Improved semantic recall performance for large message histories. Semantic recall no longer loads entire threads when only the recalled messages are needed, eliminating delays that previously scaled with total message count. (Fixes #11702) ([#14022](https://github.com/mastra-ai/mastra/pull/14022))
11
+
12
+ - Updated dependencies [[`4f71b43`](https://github.com/mastra-ai/mastra/commit/4f71b436a4a6b8839842d8da47b57b84509af56c), [`a070277`](https://github.com/mastra-ai/mastra/commit/a07027766ce195ba74d0783116d894cbab25d44c), [`b628b91`](https://github.com/mastra-ai/mastra/commit/b628b9128b372c0f54214d902b07279f03443900), [`332c014`](https://github.com/mastra-ai/mastra/commit/332c014e076b81edf7fe45b58205882726415e90), [`6b63153`](https://github.com/mastra-ai/mastra/commit/6b63153878ea841c0f4ce632ba66bb33e57e9c1b), [`4246e34`](https://github.com/mastra-ai/mastra/commit/4246e34cec9c26636d0965942268e6d07c346671), [`b8837ee`](https://github.com/mastra-ai/mastra/commit/b8837ee77e2e84197609762bfabd8b3da326d30c), [`866cc2c`](https://github.com/mastra-ai/mastra/commit/866cc2cb1f0e3b314afab5194f69477fada745d1), [`5d950f7`](https://github.com/mastra-ai/mastra/commit/5d950f7bf426a215a1808f0abef7de5c8336ba1c), [`28c85b1`](https://github.com/mastra-ai/mastra/commit/28c85b184fc32b40f7f160483c982da6d388ecbd), [`e9a08fb`](https://github.com/mastra-ai/mastra/commit/e9a08fbef1ada7e50e961e2f54f55e8c10b4a45c), [`1d0a8a8`](https://github.com/mastra-ai/mastra/commit/1d0a8a8acf33203d5744fc429b090ad8598aa8ed), [`631ffd8`](https://github.com/mastra-ai/mastra/commit/631ffd82fed108648b448b28e6a90e38c5f53bf5), [`6bcbf8a`](https://github.com/mastra-ai/mastra/commit/6bcbf8a6774d5a53b21d61db8a45ce2593ca1616), [`aae2295`](https://github.com/mastra-ai/mastra/commit/aae2295838a2d329ad6640829e87934790ffe5b8), [`aa61f29`](https://github.com/mastra-ai/mastra/commit/aa61f29ff8095ce46a4ae16e46c4d8c79b2b685b), [`7ff3714`](https://github.com/mastra-ai/mastra/commit/7ff37148515439bb3be009a60e02c3e363299760), [`18c3a90`](https://github.com/mastra-ai/mastra/commit/18c3a90c9e48cf69500e308affeb8eba5860b2af), [`41d79a1`](https://github.com/mastra-ai/mastra/commit/41d79a14bd8cb6de1e2565fd0a04786bae2f211b), [`f35487b`](https://github.com/mastra-ai/mastra/commit/f35487bb2d46c636e22aa71d90025613ae38235a), [`6dc2192`](https://github.com/mastra-ai/mastra/commit/6dc21921aef0f0efab15cd0805fa3d18f277a76f), [`eeb3a3f`](https://github.com/mastra-ai/mastra/commit/eeb3a3f43aca10cf49479eed2a84b7d9ecea02ba), [`e673376`](https://github.com/mastra-ai/mastra/commit/e6733763ad1321aa7e5ae15096b9c2104f93b1f3), [`05f8d90`](https://github.com/mastra-ai/mastra/commit/05f8d9009290ce6aa03428b3add635268615db85), [`b2204c9`](https://github.com/mastra-ai/mastra/commit/b2204c98a42848bbfb6f0440f005dc2b6354f1cd), [`a1bf1e3`](https://github.com/mastra-ai/mastra/commit/a1bf1e385ed4c0ef6f11b56c5887442970d127f2), [`b6f647a`](https://github.com/mastra-ai/mastra/commit/b6f647ae2388e091f366581595feb957e37d5b40), [`0c57b8b`](https://github.com/mastra-ai/mastra/commit/0c57b8b0a69a97b5a4ae3f79be6c610f29f3cf7b), [`b081f27`](https://github.com/mastra-ai/mastra/commit/b081f272cf411716e1d6bd72ceac4bcee2657b19), [`4b8da97`](https://github.com/mastra-ai/mastra/commit/4b8da97a5ce306e97869df6c39535d9069e563db), [`0c09eac`](https://github.com/mastra-ai/mastra/commit/0c09eacb1926f64cfdc9ae5c6d63385cf8c9f72c), [`6b9b93d`](https://github.com/mastra-ai/mastra/commit/6b9b93d6f459d1ba6e36f163abf62a085ddb3d64), [`31b6067`](https://github.com/mastra-ai/mastra/commit/31b6067d0cc3ab10e1b29c36147f3b5266bc714a), [`797ac42`](https://github.com/mastra-ai/mastra/commit/797ac4276de231ad2d694d9aeca75980f6cd0419), [`0bc289e`](https://github.com/mastra-ai/mastra/commit/0bc289e2d476bf46c5b91c21969e8d0c6864691c), [`9b75a06`](https://github.com/mastra-ai/mastra/commit/9b75a06e53ebb0b950ba7c1e83a0142047185f46), [`4c3a1b1`](https://github.com/mastra-ai/mastra/commit/4c3a1b122ea083e003d71092f30f3b31680b01c0), [`256df35`](https://github.com/mastra-ai/mastra/commit/256df3571d62beb3ad4971faa432927cc140e603), [`85cc3b3`](https://github.com/mastra-ai/mastra/commit/85cc3b3b6f32ae4b083c26498f50d5b250ba944b), [`97ea28c`](https://github.com/mastra-ai/mastra/commit/97ea28c746e9e4147d56047bbb1c4a92417a3fec), [`d567299`](https://github.com/mastra-ai/mastra/commit/d567299cf81e02bd9d5221d4bc05967d6c224161), [`716ffe6`](https://github.com/mastra-ai/mastra/commit/716ffe68bed81f7c2690bc8581b9e140f7bf1c3d), [`8296332`](https://github.com/mastra-ai/mastra/commit/8296332de21c16e3dfc3d0b2d615720a6dc88f2f), [`4df2116`](https://github.com/mastra-ai/mastra/commit/4df211619dd922c047d396ca41cd7027c8c4c8e7), [`2219c1a`](https://github.com/mastra-ai/mastra/commit/2219c1acbd21da116da877f0036ffb985a9dd5a3), [`17c4145`](https://github.com/mastra-ai/mastra/commit/17c4145166099354545582335b5252bdfdfd908b)]:
13
+ - @mastra/core@1.11.0
14
+
15
+ ## 1.0.4-alpha.0
16
+
17
+ ### Patch Changes
18
+
19
+ - dependencies updates: ([#13822](https://github.com/mastra-ai/mastra/pull/13822))
20
+ - Updated dependency [`@upstash/redis@^1.36.3` ↗︎](https://www.npmjs.com/package/@upstash/redis/v/1.36.3) (from `^1.36.2`, in `dependencies`)
21
+
22
+ - Improved semantic recall performance for large message histories. Semantic recall no longer loads entire threads when only the recalled messages are needed, eliminating delays that previously scaled with total message count. (Fixes #11702) ([#14022](https://github.com/mastra-ai/mastra/pull/14022))
23
+
24
+ - Updated dependencies [[`4f71b43`](https://github.com/mastra-ai/mastra/commit/4f71b436a4a6b8839842d8da47b57b84509af56c), [`a070277`](https://github.com/mastra-ai/mastra/commit/a07027766ce195ba74d0783116d894cbab25d44c), [`b628b91`](https://github.com/mastra-ai/mastra/commit/b628b9128b372c0f54214d902b07279f03443900), [`332c014`](https://github.com/mastra-ai/mastra/commit/332c014e076b81edf7fe45b58205882726415e90), [`6b63153`](https://github.com/mastra-ai/mastra/commit/6b63153878ea841c0f4ce632ba66bb33e57e9c1b), [`4246e34`](https://github.com/mastra-ai/mastra/commit/4246e34cec9c26636d0965942268e6d07c346671), [`b8837ee`](https://github.com/mastra-ai/mastra/commit/b8837ee77e2e84197609762bfabd8b3da326d30c), [`5d950f7`](https://github.com/mastra-ai/mastra/commit/5d950f7bf426a215a1808f0abef7de5c8336ba1c), [`28c85b1`](https://github.com/mastra-ai/mastra/commit/28c85b184fc32b40f7f160483c982da6d388ecbd), [`e9a08fb`](https://github.com/mastra-ai/mastra/commit/e9a08fbef1ada7e50e961e2f54f55e8c10b4a45c), [`631ffd8`](https://github.com/mastra-ai/mastra/commit/631ffd82fed108648b448b28e6a90e38c5f53bf5), [`aae2295`](https://github.com/mastra-ai/mastra/commit/aae2295838a2d329ad6640829e87934790ffe5b8), [`aa61f29`](https://github.com/mastra-ai/mastra/commit/aa61f29ff8095ce46a4ae16e46c4d8c79b2b685b), [`7ff3714`](https://github.com/mastra-ai/mastra/commit/7ff37148515439bb3be009a60e02c3e363299760), [`41d79a1`](https://github.com/mastra-ai/mastra/commit/41d79a14bd8cb6de1e2565fd0a04786bae2f211b), [`e673376`](https://github.com/mastra-ai/mastra/commit/e6733763ad1321aa7e5ae15096b9c2104f93b1f3), [`b2204c9`](https://github.com/mastra-ai/mastra/commit/b2204c98a42848bbfb6f0440f005dc2b6354f1cd), [`a1bf1e3`](https://github.com/mastra-ai/mastra/commit/a1bf1e385ed4c0ef6f11b56c5887442970d127f2), [`b6f647a`](https://github.com/mastra-ai/mastra/commit/b6f647ae2388e091f366581595feb957e37d5b40), [`0c57b8b`](https://github.com/mastra-ai/mastra/commit/0c57b8b0a69a97b5a4ae3f79be6c610f29f3cf7b), [`b081f27`](https://github.com/mastra-ai/mastra/commit/b081f272cf411716e1d6bd72ceac4bcee2657b19), [`0c09eac`](https://github.com/mastra-ai/mastra/commit/0c09eacb1926f64cfdc9ae5c6d63385cf8c9f72c), [`6b9b93d`](https://github.com/mastra-ai/mastra/commit/6b9b93d6f459d1ba6e36f163abf62a085ddb3d64), [`31b6067`](https://github.com/mastra-ai/mastra/commit/31b6067d0cc3ab10e1b29c36147f3b5266bc714a), [`797ac42`](https://github.com/mastra-ai/mastra/commit/797ac4276de231ad2d694d9aeca75980f6cd0419), [`0bc289e`](https://github.com/mastra-ai/mastra/commit/0bc289e2d476bf46c5b91c21969e8d0c6864691c), [`9b75a06`](https://github.com/mastra-ai/mastra/commit/9b75a06e53ebb0b950ba7c1e83a0142047185f46), [`4c3a1b1`](https://github.com/mastra-ai/mastra/commit/4c3a1b122ea083e003d71092f30f3b31680b01c0), [`85cc3b3`](https://github.com/mastra-ai/mastra/commit/85cc3b3b6f32ae4b083c26498f50d5b250ba944b), [`97ea28c`](https://github.com/mastra-ai/mastra/commit/97ea28c746e9e4147d56047bbb1c4a92417a3fec), [`d567299`](https://github.com/mastra-ai/mastra/commit/d567299cf81e02bd9d5221d4bc05967d6c224161), [`716ffe6`](https://github.com/mastra-ai/mastra/commit/716ffe68bed81f7c2690bc8581b9e140f7bf1c3d), [`8296332`](https://github.com/mastra-ai/mastra/commit/8296332de21c16e3dfc3d0b2d615720a6dc88f2f), [`4df2116`](https://github.com/mastra-ai/mastra/commit/4df211619dd922c047d396ca41cd7027c8c4c8e7), [`2219c1a`](https://github.com/mastra-ai/mastra/commit/2219c1acbd21da116da877f0036ffb985a9dd5a3), [`17c4145`](https://github.com/mastra-ai/mastra/commit/17c4145166099354545582335b5252bdfdfd908b)]:
25
+ - @mastra/core@1.11.0-alpha.0
26
+
3
27
  ## 1.0.3
4
28
 
5
29
  ### Patch Changes
@@ -3,7 +3,7 @@ name: mastra-upstash
3
3
  description: Documentation for @mastra/upstash. Use when working with @mastra/upstash APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/upstash"
6
- version: "1.0.3"
6
+ version: "1.0.4"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -16,14 +16,14 @@ Read the individual reference documents for detailed explanations and code examp
16
16
 
17
17
  ### Docs
18
18
 
19
- - [Working Memory](references/docs-memory-working-memory.md) - Learn how to configure working memory in Mastra to store persistent user data, preferences.
20
- - [Retrieval, Semantic Search, Reranking](references/docs-rag-retrieval.md) - Guide on retrieval processes in Mastra's RAG systems, including semantic search, filtering, and re-ranking.
21
- - [Storing Embeddings in A Vector Database](references/docs-rag-vector-databases.md) - Guide on vector storage options in Mastra, including embedded and dedicated vector databases for similarity search.
19
+ - [Working memory](references/docs-memory-working-memory.md) - Learn how to configure working memory in Mastra to store persistent user data, preferences.
20
+ - [Retrieval, semantic search, reranking](references/docs-rag-retrieval.md) - Guide on retrieval processes in Mastra's RAG systems, including semantic search, filtering, and re-ranking.
21
+ - [Storing embeddings in a vector database](references/docs-rag-vector-databases.md) - Guide on vector storage options in Mastra, including embedded and dedicated vector databases for similarity search.
22
22
 
23
23
  ### Reference
24
24
 
25
- - [Reference: Upstash Storage](references/reference-storage-upstash.md) - Documentation for the Upstash storage implementation in Mastra.
26
- - [Reference: Upstash Vector Store](references/reference-vectors-upstash.md) - Documentation for the UpstashVector class in Mastra, which provides vector search using Upstash Vector.
25
+ - [Reference: Upstash storage](references/reference-storage-upstash.md) - Documentation for the Upstash storage implementation in Mastra.
26
+ - [Reference: Upstash vector store](references/reference-vectors-upstash.md) - Documentation for the UpstashVector class in Mastra, which provides vector search using Upstash Vector.
27
27
 
28
28
 
29
29
  Read [assets/SOURCE_MAP.json](assets/SOURCE_MAP.json) for source code references.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.3",
2
+ "version": "1.0.4",
3
3
  "package": "@mastra/upstash",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -13,7 +13,7 @@ Working memory can persist at two different scopes:
13
13
 
14
14
  **Important:** Switching between scopes means the agent won't see memory from the other scope - thread-scoped memory is completely separate from resource-scoped memory.
15
15
 
16
- ## Quick Start
16
+ ## Quick start
17
17
 
18
18
  Here's a minimal example of setting up an agent with working memory:
19
19
 
@@ -37,13 +37,13 @@ const agent = new Agent({
37
37
  })
38
38
  ```
39
39
 
40
- ## How it Works
40
+ ## How it works
41
41
 
42
42
  Working memory is a block of Markdown text that the agent is able to update over time to store continuously relevant information:
43
43
 
44
44
  [YouTube video player](https://www.youtube-nocookie.com/embed/UMy_JHLf1n8)
45
45
 
46
- ## Memory Persistence Scopes
46
+ ## Memory persistence scopes
47
47
 
48
48
  Working memory can operate in two different scopes, allowing you to choose how memory persists across conversations:
49
49
 
@@ -117,7 +117,7 @@ const memory = new Memory({
117
117
  - Temporary or session-specific information
118
118
  - Workflows where each thread needs working memory but threads are ephemeral and not related to each other
119
119
 
120
- ## Storage Adapter Support
120
+ ## Storage adapter support
121
121
 
122
122
  Resource-scoped working memory requires specific storage adapters that support the `mastra_resources` table:
123
123
 
@@ -128,7 +128,7 @@ Resource-scoped working memory requires specific storage adapters that support t
128
128
  - **Upstash** (`@mastra/upstash`)
129
129
  - **MongoDB** (`@mastra/mongodb`)
130
130
 
131
- ## Custom Templates
131
+ ## Custom templates
132
132
 
133
133
  Templates guide the agent on what information to track and update in working memory. While a default template is used if none is provided, you'll typically want to define a custom template tailored to your agent's specific use case to ensure it remembers the most relevant information.
134
134
 
@@ -142,7 +142,7 @@ const memory = new Memory({
142
142
  template: `
143
143
  # User Profile
144
144
 
145
- ## Personal Info
145
+ ## Personal info
146
146
 
147
147
  - Name:
148
148
  - Location:
@@ -156,7 +156,7 @@ const memory = new Memory({
156
156
  - [Deadline 1]: [Date]
157
157
  - [Deadline 2]: [Date]
158
158
 
159
- ## Session State
159
+ ## Session state
160
160
 
161
161
  - Last Task Discussed:
162
162
  - Open Questions:
@@ -168,13 +168,13 @@ const memory = new Memory({
168
168
  })
169
169
  ```
170
170
 
171
- ## Designing Effective Templates
171
+ ## Designing effective templates
172
172
 
173
- A well-structured template keeps the information easy for the agent to parse and update. Treat the template as a short form that you want the assistant to keep up to date.
173
+ A well-structured template keeps the information straightforward for the agent to parse and update. Treat the template as a short form that you want the assistant to keep up to date.
174
174
 
175
- - **Short, focused labels.** Avoid paragraphs or very long headings. Keep labels brief (for example `## Personal Info` or `- Name:`) so updates are easy to read and less likely to be truncated.
175
+ - **Short, focused labels.** Avoid paragraphs or very long headings. Keep labels brief (for example `## Personal Info` or `- Name:`) so updates are readable and less likely to be truncated.
176
176
  - **Use consistent casing.** Inconsistent capitalization (`Timezone:` vs `timezone:`) can cause messy updates. Stick to Title Case or lower case for headings and bullet labels.
177
- - **Keep placeholder text simple.** Use hints such as `[e.g., Formal]` or `[Date]` to help the LLM fill in the correct spots.
177
+ - **Keep placeholder text minimal.** Use hints such as `[e.g., Formal]` or `[Date]` to help the LLM fill in the correct spots.
178
178
  - **Abbreviate very long values.** If you only need a short form, include guidance like `- Name: [First name or nickname]` or `- Address (short):` rather than the full legal text.
179
179
  - **Mention update rules in `instructions`.** You can instruct how and when to fill or clear parts of the template directly in the agent's `instructions` field.
180
180
 
@@ -206,7 +206,7 @@ const paragraphMemory = new Memory({
206
206
  })
207
207
  ```
208
208
 
209
- ## Structured Working Memory
209
+ ## Structured working memory
210
210
 
211
211
  Working memory can also be defined using a structured schema instead of a Markdown template. This allows you to specify the exact fields and types that should be tracked, using a [Zod](https://zod.dev/) schema. When using a schema, the agent will see and update working memory as a JSON object matching your schema.
212
212
 
@@ -263,22 +263,22 @@ Schema-based working memory uses **merge semantics**, meaning the agent only nee
263
263
 
264
264
  - **Object fields are deep merged:** Only provided fields are updated; others remain unchanged
265
265
  - **Set a field to `null` to delete it:** This explicitly removes the field from memory
266
- - **Arrays are replaced entirely:** When an array field is provided, it replaces the existing array (arrays are not merged element-by-element)
266
+ - **Arrays are replaced entirely:** When an array field is provided, it replaces the existing array (arrays aren't merged element-by-element)
267
267
 
268
- ## Choosing Between Template and Schema
268
+ ## Choosing between template and schema
269
269
 
270
270
  - Use a **template** (Markdown) if you want the agent to maintain memory as a free-form text block, such as a user profile or scratchpad. Templates use **replace semantics** — the agent must provide the complete memory content on each update.
271
271
  - Use a **schema** if you need structured, type-safe data that can be validated and programmatically accessed as JSON. Schemas use **merge semantics** — the agent only provides fields to update, and existing fields are preserved.
272
- - Only one mode can be active at a time: setting both `template` and `schema` is not supported.
272
+ - Only one mode can be active at a time: setting both `template` and `schema` isn't supported.
273
273
 
274
- ## Example: Multi-step Retention
274
+ ## Example: Multi-step retention
275
275
 
276
276
  Below is a simplified view of how the `User Profile` template updates across a short user conversation:
277
277
 
278
278
  ```nohighlight
279
279
  # User Profile
280
280
 
281
- ## Personal Info
281
+ ## Personal info
282
282
 
283
283
  - Name:
284
284
  - Location:
@@ -301,9 +301,9 @@ Below is a simplified view of how the `User Profile` template updates across a s
301
301
 
302
302
  The agent can now refer to `Sam` or `Berlin` in later responses without requesting the information again because it has been stored in working memory.
303
303
 
304
- If your agent is not properly updating working memory when you expect it to, you can add system instructions on _how_ and _when_ to use this template in your agent's `instructions` setting.
304
+ If your agent isn't properly updating working memory when you expect it to, you can add system instructions on _how_ and _when_ to use this template in your agent's `instructions` setting.
305
305
 
306
- ## Setting Initial Working Memory
306
+ ## Setting initial working memory
307
307
 
308
308
  While agents typically update working memory through the `updateWorkingMemory` tool, you can also set initial working memory programmatically when creating or updating threads. This is useful for injecting user data (like their name, preferences, or other info) that you want available to the agent without passing it in every request.
309
309
 
@@ -372,7 +372,7 @@ await memory.updateWorkingMemory({
372
372
  })
373
373
  ```
374
374
 
375
- ## Read-Only Working Memory
375
+ ## Read-only working memory
376
376
 
377
377
  In some scenarios, you may want an agent to have access to working memory data without the ability to modify it. This is useful for:
378
378
 
@@ -1,10 +1,10 @@
1
- # Retrieval in RAG Systems
1
+ # Retrieval in RAG systems
2
2
 
3
3
  After storing embeddings, you need to retrieve relevant chunks to answer user queries.
4
4
 
5
5
  Mastra provides flexible retrieval options with support for semantic search, filtering, and re-ranking.
6
6
 
7
- ## How Retrieval Works
7
+ ## How retrieval works
8
8
 
9
9
  1. The user's query is converted to an embedding using the same model used for document embeddings
10
10
  2. This embedding is compared to stored embeddings using vector similarity
@@ -14,7 +14,7 @@ Mastra provides flexible retrieval options with support for semantic search, fil
14
14
  - Re-ranked for better relevance
15
15
  - Processed through a knowledge graph
16
16
 
17
- ## Basic Retrieval
17
+ ## Basic retrieval
18
18
 
19
19
  The simplest approach is direct semantic search. This method uses vector similarity to find chunks that are semantically similar to the query:
20
20
 
@@ -63,7 +63,7 @@ Results include both the text content and a similarity score:
63
63
  ]
64
64
  ```
65
65
 
66
- ## Advanced Retrieval options
66
+ ## Advanced retrieval options
67
67
 
68
68
  ### Metadata Filtering
69
69
 
@@ -1,8 +1,8 @@
1
- # Storing Embeddings in A Vector Database
1
+ # Storing embeddings in a vector database
2
2
 
3
3
  After generating embeddings, you need to store them in a database that supports vector similarity search. Mastra provides a consistent interface for storing and querying embeddings across various vector databases.
4
4
 
5
- ## Supported Databases
5
+ ## Supported databases
6
6
 
7
7
  **MongoDB**:
8
8
 
@@ -234,7 +234,7 @@ await store.upsert({
234
234
  })
235
235
  ```
236
236
 
237
- **ElasticSearch**:
237
+ **Elasticsearch**:
238
238
 
239
239
  ```ts
240
240
  import { ElasticSearchVector } from '@mastra/elasticsearch'
@@ -337,7 +337,7 @@ await store.upsert({
337
337
  })
338
338
  ```
339
339
 
340
- ## Using Vector Storage
340
+ ## Using vector storage
341
341
 
342
342
  Once initialized, all vector stores share the same interface for creating indexes, upserting embeddings, and querying.
343
343
 
@@ -355,11 +355,11 @@ await store.createIndex({
355
355
 
356
356
  The dimension size must match the output dimension of your chosen embedding model. Common dimension sizes are:
357
357
 
358
- - OpenAI text-embedding-3-small: 1536 dimensions (or custom, e.g., 256)
359
- - Cohere embed-multilingual-v3: 1024 dimensions
360
- - Google gemini-embedding-001: 768 dimensions (or custom)
358
+ - `OpenAI text-embedding-3-small`: 1536 dimensions (or custom, e.g., 256)
359
+ - `Cohere embed-multilingual-v3`: 1024 dimensions
360
+ - `Google gemini-embedding-001`: 768 dimensions (or custom)
361
361
 
362
- > **Warning:** Index dimensions cannot be changed after creation. To use a different model, delete and recreate the index with the new dimension size.
362
+ > **Warning:** Index dimensions can't be changed after creation. To use a different model, delete and recreate the index with the new dimension size.
363
363
 
364
364
  ### Naming Rules for Databases
365
365
 
@@ -490,7 +490,7 @@ Index names must:
490
490
  - Example: `My_Index` is not valid (contains uppercase letters)
491
491
  - Example: `_myindex` is not valid (begins with underscore)
492
492
 
493
- **ElasticSearch**:
493
+ **Elasticsearch**:
494
494
 
495
495
  Index names must:
496
496
 
@@ -543,7 +543,7 @@ The upsert operation:
543
543
  - Creates new vectors if they don't exist
544
544
  - Automatically handles batching for large datasets
545
545
 
546
- ## Adding Metadata
546
+ ## Adding metadata
547
547
 
548
548
  Vector stores support rich metadata (any JSON-serializable fields) for filtering and organization. Since metadata is stored with no fixed schema, use consistent field naming to avoid unexpected query results.
549
549
 
@@ -581,9 +581,9 @@ Key metadata considerations:
581
581
  - Only include fields you plan to filter or sort by - extra fields add overhead
582
582
  - Add timestamps (e.g., 'createdAt', 'lastUpdated') to track content freshness
583
583
 
584
- ## Deleting Vectors
584
+ ## Deleting vectors
585
585
 
586
- When building RAG applications, you often need to clean up stale vectors when documents are deleted or updated. Mastra provides the `deleteVectors` method that supports deleting vectors by metadata filters, making it easy to remove all embeddings associated with a specific document.
586
+ When building RAG applications, you often need to clean up stale vectors when documents are deleted or updated. Mastra provides the `deleteVectors` method that supports deleting vectors by metadata filters, making it straightforward to remove all embeddings associated with a specific document.
587
587
 
588
588
  ### Delete by Metadata Filter
589
589
 
@@ -637,7 +637,7 @@ await store.deleteVectors({
637
637
  })
638
638
  ```
639
639
 
640
- ## Best Practices
640
+ ## Best practices
641
641
 
642
642
  - Create indexes before bulk insertions
643
643
  - Use batch operations for large insertions (the upsert method handles batching automatically)
@@ -1,10 +1,10 @@
1
- # Upstash Storage
1
+ # Upstash storage
2
2
 
3
3
  The Upstash storage implementation provides a serverless-friendly storage solution using Upstash's Redis-compatible key-value store.
4
4
 
5
5
  > **Pricing:** When using Mastra with Upstash, the pay-as-you-go model can result in unexpectedly high costs due to the high volume of Redis commands generated during agent conversations. We strongly recommend using a **fixed pricing plan** for predictable costs. See [Upstash pricing](https://upstash.com/pricing/redis) for details and [GitHub issue #5850](https://github.com/mastra-ai/mastra/issues/5850) for context.
6
6
 
7
- > **Observability Not Supported:** Upstash storage **does not support the observability domain**. Traces from the `DefaultExporter` cannot be persisted to Upstash, and Mastra Studio's observability features won't work with Upstash as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
7
+ > **Observability Not Supported:** Upstash storage **doesn't support the observability domain**. Traces from the `DefaultExporter` can't be persisted to Upstash, and Mastra Studio's observability features won't work with Upstash as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
8
8
 
9
9
  ## Installation
10
10
 
@@ -46,13 +46,13 @@ const storage = new UpstashStore({
46
46
 
47
47
  ## Parameters
48
48
 
49
- **url:** (`string`): Upstash Redis URL
49
+ **url** (`string`): Upstash Redis URL
50
50
 
51
- **token:** (`string`): Upstash Redis authentication token
51
+ **token** (`string`): Upstash Redis authentication token
52
52
 
53
- **prefix?:** (`string`): Key prefix for all stored items (Default: `mastra:`)
53
+ **prefix** (`string`): Key prefix for all stored items (Default: `mastra:`)
54
54
 
55
- ## Additional Notes
55
+ ## Additional notes
56
56
 
57
57
  ### Key Structure
58
58
 
@@ -87,7 +87,7 @@ For optimal performance:
87
87
  - Monitor Redis memory usage
88
88
  - Consider data expiration policies if needed
89
89
 
90
- ## Usage Example
90
+ ## Usage example
91
91
 
92
92
  ### Adding memory to an agent
93
93
 
@@ -1,62 +1,62 @@
1
- # Upstash Vector Store
1
+ # Upstash vector store
2
2
 
3
3
  The UpstashVector class provides vector search using [Upstash Vector](https://upstash.com/vector), a serverless vector database service that provides vector similarity search with metadata filtering capabilities and hybrid search support.
4
4
 
5
- ## Constructor Options
5
+ ## Constructor options
6
6
 
7
- **url:** (`string`): Upstash Vector database URL
7
+ **url** (`string`): Upstash Vector database URL
8
8
 
9
- **token:** (`string`): Upstash Vector API token
9
+ **token** (`string`): Upstash Vector API token
10
10
 
11
11
  ## Methods
12
12
 
13
- ### createIndex()
13
+ ### `createIndex()`
14
14
 
15
15
  Note: This method is a no-op for Upstash as indexes are created automatically.
16
16
 
17
- **indexName:** (`string`): Name of the index to create
17
+ **indexName** (`string`): Name of the index to create
18
18
 
19
- **dimension:** (`number`): Vector dimension (must match your embedding model)
19
+ **dimension** (`number`): Vector dimension (must match your embedding model)
20
20
 
21
- **metric?:** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search (Default: `cosine`)
21
+ **metric** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search (Default: `cosine`)
22
22
 
23
- ### upsert()
23
+ ### `upsert()`
24
24
 
25
- **indexName:** (`string`): Name of the index to upsert into
25
+ **indexName** (`string`): Name of the index to upsert into
26
26
 
27
- **vectors:** (`number[][]`): Array of embedding vectors
27
+ **vectors** (`number[][]`): Array of embedding vectors
28
28
 
29
- **sparseVectors?:** (`{ indices: number[], values: number[] }[]`): Array of sparse vectors for hybrid search. Each sparse vector must have matching indices and values arrays.
29
+ **sparseVectors** (`{ indices: number[], values: number[] }[]`): Array of sparse vectors for hybrid search. Each sparse vector must have matching indices and values arrays.
30
30
 
31
- **metadata?:** (`Record<string, any>[]`): Metadata for each vector
31
+ **metadata** (`Record<string, any>[]`): Metadata for each vector
32
32
 
33
- **ids?:** (`string[]`): Optional vector IDs (auto-generated if not provided)
33
+ **ids** (`string[]`): Optional vector IDs (auto-generated if not provided)
34
34
 
35
- ### query()
35
+ ### `query()`
36
36
 
37
- **indexName:** (`string`): Name of the index to query
37
+ **indexName** (`string`): Name of the index to query
38
38
 
39
- **queryVector:** (`number[]`): Query vector to find similar vectors
39
+ **queryVector** (`number[]`): Query vector to find similar vectors
40
40
 
41
- **sparseVector?:** (`{ indices: number[], values: number[] }`): Optional sparse vector for hybrid search. Must have matching indices and values arrays.
41
+ **sparseVector** (`{ indices: number[], values: number[] }`): Optional sparse vector for hybrid search. Must have matching indices and values arrays.
42
42
 
43
- **topK?:** (`number`): Number of results to return (Default: `10`)
43
+ **topK** (`number`): Number of results to return (Default: `10`)
44
44
 
45
- **filter?:** (`Record<string, any>`): Metadata filters for the query
45
+ **filter** (`Record<string, any>`): Metadata filters for the query
46
46
 
47
- **includeVector?:** (`boolean`): Whether to include vectors in the results (Default: `false`)
47
+ **includeVector** (`boolean`): Whether to include vectors in the results (Default: `false`)
48
48
 
49
- **fusionAlgorithm?:** (`FusionAlgorithm`): Algorithm used to combine dense and sparse search results in hybrid search (e.g., RRF - Reciprocal Rank Fusion)
49
+ **fusionAlgorithm** (`FusionAlgorithm`): Algorithm used to combine dense and sparse search results in hybrid search (e.g., RRF - Reciprocal Rank Fusion)
50
50
 
51
- **queryMode?:** (`QueryMode`): Search mode: 'DENSE' for dense-only, 'SPARSE' for sparse-only, or 'HYBRID' for combined search
51
+ **queryMode** (`QueryMode`): Search mode: 'DENSE' for dense-only, 'SPARSE' for sparse-only, or 'HYBRID' for combined search
52
52
 
53
- ### listIndexes()
53
+ ### `listIndexes()`
54
54
 
55
55
  Returns an array of index names (namespaces) as strings.
56
56
 
57
- ### describeIndex()
57
+ ### `describeIndex()`
58
58
 
59
- **indexName:** (`string`): Name of the index to describe
59
+ **indexName** (`string`): Name of the index to describe
60
60
 
61
61
  Returns:
62
62
 
@@ -68,17 +68,17 @@ interface IndexStats {
68
68
  }
69
69
  ```
70
70
 
71
- ### deleteIndex()
71
+ ### `deleteIndex()`
72
72
 
73
- **indexName:** (`string`): Name of the index (namespace) to delete
73
+ **indexName** (`string`): Name of the index (namespace) to delete
74
74
 
75
- ### updateVector()
75
+ ### `updateVector()`
76
76
 
77
- **indexName:** (`string`): Name of the index to update
77
+ **indexName** (`string`): Name of the index to update
78
78
 
79
- **id:** (`string`): ID of the item to update
79
+ **id** (`string`): ID of the item to update
80
80
 
81
- **update:** (`object`): Update object containing vector, sparse vector, and/or metadata
81
+ **update** (`object`): Update object containing vector, sparse vector, and/or metadata
82
82
 
83
83
  The `update` object can have the following properties:
84
84
 
@@ -86,15 +86,15 @@ The `update` object can have the following properties:
86
86
  - `sparseVector` (optional): A sparse vector object with `indices` and `values` arrays for hybrid indexes.
87
87
  - `metadata` (optional): A record of key-value pairs for metadata.
88
88
 
89
- ### deleteVector()
89
+ ### `deleteVector()`
90
90
 
91
- **indexName:** (`string`): Name of the index from which to delete the item
91
+ **indexName** (`string`): Name of the index from which to delete the item
92
92
 
93
- **id:** (`string`): ID of the item to delete
93
+ **id** (`string`): ID of the item to delete
94
94
 
95
95
  Attempts to delete an item by its ID from the specified index. Logs an error message if the deletion fails.
96
96
 
97
- ## Hybrid Vector Search
97
+ ## Hybrid vector search
98
98
 
99
99
  Upstash Vector supports hybrid search that combines semantic search (dense vectors) with keyword-based search (sparse vectors) for improved relevance and accuracy.
100
100
 
@@ -182,7 +182,7 @@ await vectorStore.updateVector({
182
182
  })
183
183
  ```
184
184
 
185
- ## Response Types
185
+ ## Response types
186
186
 
187
187
  Query results are returned in this format:
188
188
 
@@ -195,7 +195,7 @@ interface QueryResult {
195
195
  }
196
196
  ```
197
197
 
198
- ## Error Handling
198
+ ## Error handling
199
199
 
200
200
  The store throws typed errors that can be caught:
201
201
 
@@ -213,14 +213,14 @@ try {
213
213
  }
214
214
  ```
215
215
 
216
- ## Environment Variables
216
+ ## Environment variables
217
217
 
218
218
  Required environment variables:
219
219
 
220
220
  - `UPSTASH_VECTOR_URL`: Your Upstash Vector database URL
221
221
  - `UPSTASH_VECTOR_TOKEN`: Your Upstash Vector API token
222
222
 
223
- ## Usage Example
223
+ ## Usage example
224
224
 
225
225
  ### Local embeddings with fastembed
226
226
 
package/dist/index.cjs CHANGED
@@ -504,6 +504,22 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
504
504
  }
505
505
  return messageData.threadId || null;
506
506
  }
507
+ _sortMessages(messages, field, direction) {
508
+ return messages.sort((a, b) => {
509
+ const getVal = (msg) => {
510
+ if (field === "createdAt") {
511
+ return new Date(msg.createdAt).getTime();
512
+ }
513
+ const value = msg[field];
514
+ if (typeof value === "number") return value;
515
+ if (value instanceof Date) return value.getTime();
516
+ return 0;
517
+ };
518
+ const aValue = getVal(a);
519
+ const bValue = getVal(b);
520
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
521
+ });
522
+ }
507
523
  async _getIncludedMessages(include) {
508
524
  if (!include?.length) return [];
509
525
  const messageIds = /* @__PURE__ */ new Set();
@@ -640,11 +656,25 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
640
656
  new Error("page must be >= 0")
641
657
  );
642
658
  }
659
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
660
+ if (perPage === 0 && (!include || include.length === 0)) {
661
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
662
+ }
643
663
  let includedMessages = [];
644
664
  if (include && include.length > 0) {
645
665
  const included = await this._getIncludedMessages(include);
646
666
  includedMessages = included.map(this.parseStoredMessage);
647
667
  }
668
+ if (perPage === 0 && include && include.length > 0) {
669
+ const list2 = new agent.MessageList().add(includedMessages, "memory");
670
+ return {
671
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
672
+ total: 0,
673
+ page,
674
+ perPage: perPageForResponse,
675
+ hasMore: false
676
+ };
677
+ }
648
678
  const allMessageIdsWithThreads = [];
649
679
  for (const tid of threadIds) {
650
680
  const threadMessagesKey = getThreadMessagesKey(tid);
@@ -674,25 +704,7 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
674
704
  (msg) => new Date(msg.createdAt),
675
705
  filter?.dateRange
676
706
  );
677
- const { field, direction } = this.parseOrderBy(orderBy, "ASC");
678
- const getFieldValue = (msg) => {
679
- if (field === "createdAt") {
680
- return new Date(msg.createdAt).getTime();
681
- }
682
- const value = msg[field];
683
- if (typeof value === "number") {
684
- return value;
685
- }
686
- if (value instanceof Date) {
687
- return value.getTime();
688
- }
689
- return 0;
690
- };
691
- messagesData.sort((a, b) => {
692
- const aValue = getFieldValue(a);
693
- const bValue = getFieldValue(b);
694
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
695
- });
707
+ messagesData = this._sortMessages(messagesData, field, direction);
696
708
  const total = messagesData.length;
697
709
  const start = offset;
698
710
  const end = perPageInput === false ? total : start + perPage;
@@ -713,11 +725,7 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
713
725
  }
714
726
  const list = new agent.MessageList().add(allMessages, "memory");
715
727
  let finalMessages = list.get.all.db();
716
- finalMessages = finalMessages.sort((a, b) => {
717
- const aValue = getFieldValue(a);
718
- const bValue = getFieldValue(b);
719
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
720
- });
728
+ finalMessages = this._sortMessages(finalMessages, field, direction);
721
729
  const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
722
730
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
723
731
  const hasMore = perPageInput !== false && !allThreadMessagesReturned && end < total;