@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 +24 -0
- package/dist/docs/SKILL.md +6 -6
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +20 -20
- package/dist/docs/references/docs-rag-retrieval.md +4 -4
- package/dist/docs/references/docs-rag-vector-databases.md +13 -13
- package/dist/docs/references/reference-storage-upstash.md +7 -7
- package/dist/docs/references/reference-vectors-upstash.md +40 -40
- package/dist/index.cjs +32 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -24
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +1 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +9 -9
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
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -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.
|
|
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
|
|
20
|
-
- [Retrieval,
|
|
21
|
-
- [Storing
|
|
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
|
|
26
|
-
- [Reference: Upstash
|
|
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.
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
171
|
+
## Designing effective templates
|
|
172
172
|
|
|
173
|
-
A well-structured template keeps the information
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
272
|
+
- Only one mode can be active at a time: setting both `template` and `schema` isn't supported.
|
|
273
273
|
|
|
274
|
-
## Example: Multi-step
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
66
|
+
## Advanced retrieval options
|
|
67
67
|
|
|
68
68
|
### Metadata Filtering
|
|
69
69
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Storing
|
|
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
|
|
5
|
+
## Supported databases
|
|
6
6
|
|
|
7
7
|
**MongoDB**:
|
|
8
8
|
|
|
@@ -234,7 +234,7 @@ await store.upsert({
|
|
|
234
234
|
})
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
-
**
|
|
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
|
|
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
|
|
359
|
-
- Cohere embed-multilingual-v3
|
|
360
|
-
- Google gemini-embedding-001
|
|
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
|
|
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
|
-
**
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 **
|
|
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
|
|
49
|
+
**url** (`string`): Upstash Redis URL
|
|
50
50
|
|
|
51
|
-
**token
|
|
51
|
+
**token** (`string`): Upstash Redis authentication token
|
|
52
52
|
|
|
53
|
-
**prefix
|
|
53
|
+
**prefix** (`string`): Key prefix for all stored items (Default: `mastra:`)
|
|
54
54
|
|
|
55
|
-
## Additional
|
|
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
|
|
90
|
+
## Usage example
|
|
91
91
|
|
|
92
92
|
### Adding memory to an agent
|
|
93
93
|
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
# Upstash
|
|
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
|
|
5
|
+
## Constructor options
|
|
6
6
|
|
|
7
|
-
**url
|
|
7
|
+
**url** (`string`): Upstash Vector database URL
|
|
8
8
|
|
|
9
|
-
**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
|
|
17
|
+
**indexName** (`string`): Name of the index to create
|
|
18
18
|
|
|
19
|
-
**dimension
|
|
19
|
+
**dimension** (`number`): Vector dimension (must match your embedding model)
|
|
20
20
|
|
|
21
|
-
**metric
|
|
21
|
+
**metric** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search (Default: `cosine`)
|
|
22
22
|
|
|
23
|
-
### upsert()
|
|
23
|
+
### `upsert()`
|
|
24
24
|
|
|
25
|
-
**indexName
|
|
25
|
+
**indexName** (`string`): Name of the index to upsert into
|
|
26
26
|
|
|
27
|
-
**vectors
|
|
27
|
+
**vectors** (`number[][]`): Array of embedding vectors
|
|
28
28
|
|
|
29
|
-
**sparseVectors
|
|
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
|
|
31
|
+
**metadata** (`Record<string, any>[]`): Metadata for each vector
|
|
32
32
|
|
|
33
|
-
**ids
|
|
33
|
+
**ids** (`string[]`): Optional vector IDs (auto-generated if not provided)
|
|
34
34
|
|
|
35
|
-
### query()
|
|
35
|
+
### `query()`
|
|
36
36
|
|
|
37
|
-
**indexName
|
|
37
|
+
**indexName** (`string`): Name of the index to query
|
|
38
38
|
|
|
39
|
-
**queryVector
|
|
39
|
+
**queryVector** (`number[]`): Query vector to find similar vectors
|
|
40
40
|
|
|
41
|
-
**sparseVector
|
|
41
|
+
**sparseVector** (`{ indices: number[], values: number[] }`): Optional sparse vector for hybrid search. Must have matching indices and values arrays.
|
|
42
42
|
|
|
43
|
-
**topK
|
|
43
|
+
**topK** (`number`): Number of results to return (Default: `10`)
|
|
44
44
|
|
|
45
|
-
**filter
|
|
45
|
+
**filter** (`Record<string, any>`): Metadata filters for the query
|
|
46
46
|
|
|
47
|
-
**includeVector
|
|
47
|
+
**includeVector** (`boolean`): Whether to include vectors in the results (Default: `false`)
|
|
48
48
|
|
|
49
|
-
**fusionAlgorithm
|
|
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
|
|
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
|
|
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
|
|
73
|
+
**indexName** (`string`): Name of the index (namespace) to delete
|
|
74
74
|
|
|
75
|
-
### updateVector()
|
|
75
|
+
### `updateVector()`
|
|
76
76
|
|
|
77
|
-
**indexName
|
|
77
|
+
**indexName** (`string`): Name of the index to update
|
|
78
78
|
|
|
79
|
-
**id
|
|
79
|
+
**id** (`string`): ID of the item to update
|
|
80
80
|
|
|
81
|
-
**update
|
|
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
|
|
91
|
+
**indexName** (`string`): Name of the index from which to delete the item
|
|
92
92
|
|
|
93
|
-
**id
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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;
|