@mastra/libsql 1.30.0-alpha.2 → 1.30.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.
@@ -3,7 +3,7 @@ name: mastra-libsql
3
3
  description: Documentation for @mastra/libsql. Use when working with @mastra/libsql APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/libsql"
6
- version: "1.30.0-alpha.2"
6
+ version: "1.30.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -22,7 +22,8 @@ Read the individual reference documents for detailed explanations and code examp
22
22
  - [Knowledge](references/docs-knowledge-overview.md) - Give agents shared pages and notes they search, read and write, with access decided by your configuration rather than by the model.
23
23
  - [Search](references/docs-knowledge-search.md) - How Knowledge search ranks results, and how to add search by meaning.
24
24
  - [Message history](references/docs-memory-message-history.md) - Store and retrieve recent Mastra conversation messages, configure history limits and thread titles, and query threads for chat interfaces.
25
- - [Multi-user threads](references/docs-memory-multi-user-threads.md) - Share one Mastra memory thread across multiple users by preserving speaker identity in messages and combining history with observational or working memory.
25
+ - [Multi-user threads](references/docs-memory-multi-user-threads.md) - Share one Mastra memory thread across multiple users by sending each message as a signal with the speaker in its attributes.
26
+ - [Observational Memory](references/docs-memory-observational-memory.md) - Give agents long-running memory with a small, stable, cache-friendly context. Observational Memory turns older messages into dense observations as a thread grows.
26
27
  - [Memory](references/docs-memory-overview.md) - Add memory to Mastra agents with message history, observational memory, and working memory across threads and multi-agent delegation.
27
28
  - [Signals](references/docs-signals-overview.md) - Send asynchronous input into a Mastra agent thread while Mastra manages whether the agent is active or idle.
28
29
  - [Editor](references/docs-studio-editor.md) - Use Mastra Studio Editor so collaborators can change agent instructions and tools without modifying source code, from draft testing through publication.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.30.0-alpha.2",
2
+ "version": "1.30.0",
3
3
  "package": "@mastra/libsql",
4
4
  "exports": {
5
5
  "AgentsLibSQL": {
@@ -30,12 +30,12 @@
30
30
  "DefaultStorage": {
31
31
  "types": "dist/storage/index.d.ts",
32
32
  "implementation": "dist/index.js",
33
- "line": 17344
33
+ "line": 17363
34
34
  },
35
35
  "LibSQLStore": {
36
36
  "types": "dist/storage/index.d.ts",
37
37
  "implementation": "dist/index.js",
38
- "line": 17344
38
+ "line": 17363
39
39
  },
40
40
  "ExperimentsLibSQL": {
41
41
  "types": "dist/storage/domains/experiments/index.d.ts",
@@ -60,12 +60,12 @@
60
60
  "LIBSQL_PROMPT": {
61
61
  "types": "dist/vector/prompt.d.ts",
62
62
  "implementation": "dist/index.js",
63
- "line": 17543
63
+ "line": 17562
64
64
  },
65
65
  "LibSQLFactoryStorage": {
66
66
  "types": "dist/storage/factory-storage.d.ts",
67
67
  "implementation": "dist/index.js",
68
- "line": 17196
68
+ "line": 17215
69
69
  },
70
70
  "LibSQLVector": {
71
71
  "types": "dist/vector/index.d.ts",
@@ -105,47 +105,47 @@
105
105
  "SchedulesLibSQL": {
106
106
  "types": "dist/storage/domains/schedules/index.d.ts",
107
107
  "implementation": "dist/index.js",
108
- "line": 13011
108
+ "line": 13013
109
109
  },
110
110
  "ScorerDefinitionsLibSQL": {
111
111
  "types": "dist/storage/domains/scorer-definitions/index.d.ts",
112
112
  "implementation": "dist/index.js",
113
- "line": 13309
113
+ "line": 13330
114
114
  },
115
115
  "ScoresLibSQL": {
116
116
  "types": "dist/storage/domains/scores/index.d.ts",
117
117
  "implementation": "dist/index.js",
118
- "line": 13747
118
+ "line": 13768
119
119
  },
120
120
  "SkillsLibSQL": {
121
121
  "types": "dist/storage/domains/skills/index.d.ts",
122
122
  "implementation": "dist/index.js",
123
- "line": 14089
123
+ "line": 14110
124
124
  },
125
125
  "ThreadStateLibSQL": {
126
126
  "types": "dist/storage/domains/thread-state/index.d.ts",
127
127
  "implementation": "dist/index.js",
128
- "line": 14645
128
+ "line": 14666
129
129
  },
130
130
  "ToolProviderConnectionsLibSQL": {
131
131
  "types": "dist/storage/domains/tool-provider-connections/index.d.ts",
132
132
  "implementation": "dist/index.js",
133
- "line": 14788
133
+ "line": 14809
134
134
  },
135
135
  "WorkflowDefinitionsLibSQL": {
136
136
  "types": "dist/storage/domains/workflow-definitions/index.d.ts",
137
137
  "implementation": "dist/index.js",
138
- "line": 15023
138
+ "line": 15044
139
139
  },
140
140
  "WorkflowsLibSQL": {
141
141
  "types": "dist/storage/domains/workflows/index.d.ts",
142
142
  "implementation": "dist/index.js",
143
- "line": 15381
143
+ "line": 15402
144
144
  },
145
145
  "WorkspacesLibSQL": {
146
146
  "types": "dist/storage/domains/workspaces/index.d.ts",
147
147
  "implementation": "dist/index.js",
148
- "line": 16433
148
+ "line": 16452
149
149
  }
150
150
  },
151
151
  "modules": {}
@@ -4,60 +4,50 @@
4
4
 
5
5
  # Multi-user threads
6
6
 
7
- A single Mastra thread can be shared by multiple users, each with their own name and functional role. You carry speaker identity in the message body so the agent can tell users apart while reading from a single shared thread.
7
+ A single Mastra thread can be shared by several users. Send each user's message with [`sendMessage()`](https://mastra.ai/docs/signals/sending-signals) and put the speaker in the message's `attributes`. Mastra renders the message as a `<user>` tag carrying those attributes, so the agent can tell the participants apart, now and when the message is loaded from history later.
8
8
 
9
9
  ## When to use multi-user threads
10
10
 
11
- Use multi-user threads when several people collaborate on the same subject through one agent:
11
+ Use multi-user threads when several people work on the same subject through one agent:
12
12
 
13
- - Collaborative documents with editors, reviewers, and approvers
13
+ - Collaborative documents with editors, reviewers and approvers
14
14
  - Group chats where one assistant serves many participants
15
- - Multi-stakeholder reviews where different roles have different authority
15
+ - Reviews where different roles have different authority
16
16
 
17
17
  ## Share one `resourceId` across all participants
18
18
 
19
- A thread belongs to exactly one `resourceId`, so all participants on a shared thread need to pass the same value. Instead of using a user id (the default for single-user apps), key `resourceId` on the conversation itself, for example `doc_${docId}` for a shared document, or `room_${roomId}` for a group chat. With everyone pointing at the same `resourceId`, they read and write the same history.
19
+ A thread belongs to exactly one `resourceId`, so everyone on a shared thread needs to pass the same value. Instead of a user ID (the default for single-user apps), key `resourceId` on the conversation itself, for example `doc_${docId}` for a shared document or `room_${roomId}` for a group chat. With everyone pointing at the same `resourceId` and `threadId`, they read and write the same history.
20
20
 
21
- ## Tag each user message with the speaker's identity
21
+ ## Send each message with the speaker's identity
22
22
 
23
- The model needs to know who's talking on every turn. Since the message body is the one place that survives into history and back into context, wrap each user message in a small `<turn>` tag with the speaker's id, name, and role. The tag stays attached to the message, so when prior turns are recalled the model still sees who said what.
24
-
25
- Build the tag with a small helper. The example below is one way to do it, copy it into your project and adapt it to your shape of user data:
23
+ Pass the message as an object with `contents` and `attributes`. Each attribute becomes an XML attribute on the `<user>` tag the model reads:
26
24
 
27
25
  ```typescript
28
- export type Speaker = {
29
- id: string
30
- name: string
31
- role: string
32
- }
26
+ agent.sendMessage(
27
+ {
28
+ contents: 'Please make the cover page teal.',
29
+ attributes: { name: 'Alice', role: 'editor' },
30
+ },
31
+ { resourceId: 'doc_42', threadId: 'doc_42' },
32
+ )
33
+ ```
33
34
 
34
- function escapeAttr(value: string) {
35
- return value
36
- .replace(/&/g, '&amp;')
37
- .replace(/"/g, '&quot;')
38
- .replace(/</g, '&lt;')
39
- .replace(/>/g, '&gt;')
40
- }
35
+ The model receives:
41
36
 
42
- export function asUserTurn(speaker: Speaker, text: string) {
43
- const id = escapeAttr(speaker.id)
44
- const name = escapeAttr(speaker.name)
45
- const role = escapeAttr(speaker.role)
46
- return {
47
- role: 'user' as const,
48
- content: `<turn author_id="${id}" author_name="${name}" functional_role="${role}">
49
- ${text}
50
- </turn>`,
51
- }
52
- }
37
+ ```xml
38
+ <user name="Alice" role="editor">Please make the cover page teal.</user>
53
39
  ```
54
40
 
55
- Teach the agent how to read the `<turn>` tag in its instructions. The agent must have `memory` configured so it can be called with a `thread` and `resource`:
41
+ Mastra escapes attribute values for you. Attribute names must be valid XML names, such as `name`, `role` or `user_id`. Any other name fails with `Invalid signal XML attribute name` when the message is rendered for the model. The attributes are stored with the message, so when history loads on a later turn, the model still sees who said what.
42
+
43
+ ## Tell the agent how to read the tag
44
+
45
+ Describe the `<user>` tag and its attributes in the agent's instructions. The agent needs `memory` so its messages are stored on the thread:
56
46
 
57
47
  ```typescript
58
48
  import { Agent } from '@mastra/core/agent'
59
- import { Memory } from '@mastra/memory'
60
49
  import { LibSQLStore } from '@mastra/libsql'
50
+ import { Memory } from '@mastra/memory'
61
51
 
62
52
  const memory = new Memory({
63
53
  storage: new LibSQLStore({ id: 'collab-storage', url: 'file:./collab.db' }),
@@ -72,139 +62,79 @@ export const collabAgent = new Agent({
72
62
  model: 'openai/gpt-6-luna',
73
63
  memory,
74
64
  instructions: `
75
- You are a collaborative document assistant. Multiple users talk to you in the SAME thread.
65
+ You are a collaborative document assistant. Several people talk to you in the same thread.
76
66
 
77
- Every user message is wrapped in a <turn> tag carrying the user's identity:
67
+ Each user message arrives in a <user> tag whose attributes say who sent it:
78
68
 
79
- <turn author_id="u_alice" author_name="Alice" functional_role="editor">
80
- ...message text...
81
- </turn>
69
+ <user name="Alice" role="editor">...message text...</user>
82
70
 
83
- Rules:
84
- 1. Address users by their author_name.
85
- 2. Respect functional_role: editors propose changes, reviewers approve.
86
- 3. When attributing past statements, read author_name from the surrounding <turn> tag.
87
- 4. Do not echo the <turn> tags back at users.
71
+ Address people by name. Editors propose changes and reviewers approve them.
72
+ When you refer to something said earlier, name the person who said it.
88
73
  `.trim(),
89
74
  })
90
75
  ```
91
76
 
92
- Call the agent with the wrapped message. Every participant shares the same `thread` and `resource`:
77
+ Send every participant's message to the same thread. When the thread is idle, `sendMessage()` starts a run and `accepted` resolves with its output:
93
78
 
94
79
  ```typescript
95
- import { asUserTurn } from './identity'
80
+ import { collabAgent } from './agents/collab'
96
81
 
97
- const docResourceId = 'doc_42'
98
- const docThreadId = 'doc_42'
82
+ const doc = { resourceId: 'doc_42', threadId: 'doc_42' }
99
83
 
100
- const alice = { id: 'u_alice', name: 'Alice', role: 'editor' }
101
- const bob = { id: 'u_bob', name: 'Bob', role: 'reviewer' }
102
-
103
- await collabAgent.generate([asUserTurn(alice, 'My favorite color is teal.')], {
104
- memory: { thread: docThreadId, resource: docResourceId },
105
- })
84
+ async function send(speaker: { name: string; role: string }, text: string) {
85
+ const { accepted } = collabAgent.sendMessage({ contents: text, attributes: speaker }, doc)
86
+ const result = await accepted
87
+ if (result.action === 'wake') {
88
+ return (await result.output.getFullOutput()).text
89
+ }
90
+ }
106
91
 
107
- await collabAgent.generate([asUserTurn(bob, 'I want QA sign-off before publish.')], {
108
- memory: { thread: docThreadId, resource: docResourceId },
109
- })
92
+ await send({ name: 'Alice', role: 'editor' }, 'Please make the cover page teal.')
93
+ await send({ name: 'Bob', role: 'reviewer' }, 'I want QA sign-off before we publish.')
94
+ await send({ name: 'Alice', role: 'editor' }, 'Who asked for QA sign-off?')
95
+ // The agent answers that Bob asked for it.
110
96
  ```
111
97
 
112
- The `<turn>` tag persists in the message body, so when history is recalled on later turns the model still sees who said what.
98
+ When a message arrives while the agent is still answering someone else, Mastra delivers it into the running turn instead of starting a new one, and `accepted` resolves with `action: 'deliver'`. In a live app, render replies from the [thread stream](https://mastra.ai/docs/signals/thread-streams) rather than from each `sendMessage()` call. That way every participant sees the same conversation.
113
99
 
114
100
  ## Combining with memory layers
115
101
 
116
- The user-tagging pattern composes with every memory layer. Pick the layer based on how long the conversation needs to remember per-user facts:
102
+ Pick the memory layer by how long the conversation needs to remember each participant:
117
103
 
118
- - **Short conversations** (a single session, or a thread small enough to fit in `lastMessages`), or when you need a verbatim record of who said what: use [message history alone](#message-history-alone). The user tags in history are enough. No extra memory layer needed.
119
- - **Long-running threads** (conversations that outgrow `lastMessages`, where you need per-user facts to survive history eviction): use [observational memory](#with-observational-memory-recommended).
120
- - **Need a structured participants list, or your storage adapter doesn't support OM** (OM requires LibSQL, PG, or MongoDB): use [working memory](#with-working-memory).
121
-
122
- We recommend using either observational memory or working memory because they cover overlapping needs. Running both adds latency and token cost without much benefit.
104
+ - **Short conversations**, or when you need a verbatim record of who said what: use [message history alone](#message-history-alone).
105
+ - **Long-running threads** that outgrow the context window: use [Observational Memory](#with-observational-memory).
123
106
 
124
107
  ### Message history alone
125
108
 
126
- For short conversations, or when you need a verbatim record of who said what, the user tags in history are enough. `lastMessages` brings prior turns back into context with their attribution intact:
127
-
128
- ```typescript
129
- import { Memory } from '@mastra/memory'
130
- import { LibSQLStore } from '@mastra/libsql'
131
-
132
- const memory = new Memory({
133
- storage: new LibSQLStore({ id: 'collab-storage', url: 'file:./collab.db' }),
134
- options: {
135
- lastMessages: 20,
136
- },
137
- })
138
- ```
139
-
140
- The model reads identity from the `<turn>` tag on the current message and from prior tagged messages brought back through `lastMessages`.
141
-
142
- ### With Observational Memory (recommended)
109
+ `lastMessages` brings earlier messages back into context with their `<user>` attributes, so attribution survives across turns. The agent example above uses this setup.
143
110
 
144
- [Observational Memory](https://mastra.ai/docs/memory/observational-memory) (OM) extracts per-user facts into a background log without burning the agent's tool budget. The default Observer model reads `<turn>` tags natively and produces attribution like `Alice stated her favorite color is teal.` and `Bob asked for QA sign-off before publish.`
111
+ ### With Observational Memory
145
112
 
146
- Prefer OM over working memory for multi-user threads when your storage supports it. OM extracts facts automatically, scales to any number of participants, and doesn't need template upkeep. Enable it with no overrides:
113
+ [Observational Memory](https://mastra.ai/docs/memory/observational-memory) (OM) keeps a long shared thread inside the context window by replacing older messages with observations. Enable it on the same `Memory`:
147
114
 
148
115
  ```typescript
149
- import { Memory } from '@mastra/memory'
150
116
  import { LibSQLStore } from '@mastra/libsql'
151
-
152
- const memory = new Memory({
153
- storage: new LibSQLStore({ id: 'collab-storage', url: 'file:./collab.db' }),
154
- options: {
155
- lastMessages: 20,
156
- observationalMemory: true,
157
- },
158
- })
159
- ```
160
-
161
- OM requires a storage adapter that supports it: `@mastra/libsql`, `@mastra/pg`, `@mastra/mongodb`, `@mastra/mysql`, `@mastra/convex`, or `@mastra/oracledb`.
162
-
163
- > **Note:** If you switch the Observer to a less capable model and see facts attributed to a generic `User` instead of individual participants, use [`observation.instruction`](https://mastra.ai/reference/memory/observational-memory) to explain how to interpret the `<turn>` tag.
164
-
165
- ### With working memory
166
-
167
- Use working memory when OM isn't an option, for example, when your storage adapter doesn't support OM, or when you need a structured, deterministic participants list the agent can read and write on every turn.
168
-
169
- The default [working memory](https://mastra.ai/docs/memory/working-memory) template assumes one user per thread ("First Name", "Last Name", etc.). For multi-user threads, provide a template with a participants list:
170
-
171
- ```typescript
172
117
  import { Memory } from '@mastra/memory'
173
- import { LibSQLStore } from '@mastra/libsql'
174
118
 
175
119
  const memory = new Memory({
176
120
  storage: new LibSQLStore({ id: 'collab-storage', url: 'file:./collab.db' }),
177
121
  options: {
178
- lastMessages: 20,
179
- workingMemory: {
180
- enabled: true,
181
- scope: 'thread',
182
- template: `# Document Collaboration State
183
-
184
- ## Participants
185
- <!-- One entry per known collaborator. Use author_id as the stable key. -->
186
- <!-- - **<author_name>** (<author_id>, <functional_role>): <their position> -->
187
-
188
- ## Open Questions
189
-
190
- ## Decisions
191
- `,
192
- },
122
+ observationalMemory: true,
193
123
  },
194
124
  })
195
125
  ```
196
126
 
197
- Set `scope: 'thread'` so the participants list belongs to the document, not to any individual user. Add one instruction telling the agent to append new participants to the list whenever a new `author_id` shows up in a `<turn>`.
127
+ OM replaces `lastMessages` history loading, so leave `lastMessages` out when OM is on.
198
128
 
199
- For more on templates, see [Custom templates](https://mastra.ai/docs/memory/working-memory).
129
+ The Observer keeps the speaker's attributes, so observations say who said what. A message sent with `attributes: { name: 'Alice', role: 'editor' }` is labeled `User (name="Alice" role="editor")`. Messages sent without attributes are labeled plain `User`.
200
130
 
201
131
  ## Security
202
132
 
203
- Set the `speaker` from your authenticated request context, never from the request body. If a client can choose its own `author_id`, one user can impersonate another. Use [Request Context](https://mastra.ai/docs/server/request-context) to read the verified user from your auth layer and build the `<turn>` tag on the server before calling the agent.
133
+ Set the attributes on your server from the authenticated user, never from the request body. If a client can choose its own `name`, one user can impersonate another. Use [request context](https://mastra.ai/docs/server/request-context) to read the verified user from your auth layer and build the `attributes` before calling `sendMessage()`.
204
134
 
205
135
  ## Related
206
136
 
207
- - [Working memory](https://mastra.ai/docs/memory/working-memory)
208
- - [Observational memory](https://mastra.ai/docs/memory/observational-memory)
209
- - [Share memory between agents](https://mastra.ai/docs/memory/overview)
137
+ - [Sending signals](https://mastra.ai/docs/signals/sending-signals)
138
+ - [Agent `sendMessage()` reference](https://mastra.ai/reference/agents/agent)
139
+ - [Observational Memory](https://mastra.ai/docs/memory/observational-memory)
210
140
  - [`Memory` reference](https://mastra.ai/reference/memory/memory-class)