@mastra/libsql 1.23.1-alpha.3 → 1.23.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-human-in-the-loop.md +38 -1
- package/dist/docs/references/docs-memory-memory-processors.md +7 -1
- package/dist/docs/references/docs-memory-message-history.md +3 -1
- package/dist/docs/references/reference-core-mastra-class.md +2 -0
- package/dist/docs/references/reference-memory-memory-class.md +2 -0
- package/dist/docs/references/reference-storage-retention.md +9 -7
- package/dist/index.cjs +20 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +20 -16
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/docs/SKILL.md
CHANGED
|
@@ -116,7 +116,44 @@ const stream = await agent.stream('Clean up old records', {
|
|
|
116
116
|
})
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
The function can be asynchronous. For decisions that depend on the tool name and arguments, use a [classifier](https://mastra.ai/reference/classifier/classifier) to estimate whether the call needs human review:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { Classifier } from '@mastra/core/classifier'
|
|
123
|
+
import { model } from '../models/evaluation-model'
|
|
124
|
+
import { agent } from './agent'
|
|
125
|
+
|
|
126
|
+
const approvalClassifier = new Classifier({
|
|
127
|
+
id: 'tool-approval-classifier',
|
|
128
|
+
model,
|
|
129
|
+
questions: {
|
|
130
|
+
requiresApproval: {
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
instructions:
|
|
133
|
+
'Does this tool call need human approval because it is destructive, irreversible, expensive, or handles sensitive data?',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
const stream = await agent.stream('Clean up old records', {
|
|
139
|
+
requireToolApproval: async ({ toolName, args }) => {
|
|
140
|
+
const result = await approvalClassifier.evaluate({
|
|
141
|
+
state: {
|
|
142
|
+
toolName,
|
|
143
|
+
argumentNames: Object.keys(args),
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
return result.answers.requiresApproval.probability >= 0.7
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The example sends argument names rather than values because the classifier forwards its state to the configured evaluation model. If the decision requires argument values, redact sensitive data first or use an evaluation model and provider that meet the protected tool's data-handling requirements.
|
|
153
|
+
|
|
154
|
+
Returning `true` pauses the tool call for human approval. It doesn't approve or decline the call automatically. Choose a threshold that matches the risk of the tools available to the agent. If this `requireToolApproval` function throws, it defaults to requiring approval.
|
|
155
|
+
|
|
156
|
+
The runtime then combines that result with the tool's `requireApproval` setting. A boolean `true` requires approval, while `false` doesn't disable approval required by `requireToolApproval`. A tool-level `requireApproval` function is authoritative and replaces the combined result for that tool.
|
|
120
157
|
|
|
121
158
|
> **Note:** Function-based `requireToolApproval` is only available on regular `stream()` / `generate()` calls. Durable agents and stored agents persist their options, and a function can't be serialized, so they accept only a boolean. If you pass a function in those contexts it falls back to requiring approval for every tool call.
|
|
122
159
|
|
|
@@ -14,6 +14,12 @@ Memory processors are [processors](https://mastra.ai/docs/agents/processors) tha
|
|
|
14
14
|
|
|
15
15
|
Mastra automatically adds these processors when memory is enabled:
|
|
16
16
|
|
|
17
|
+
### `MemoryInputFilter`
|
|
18
|
+
|
|
19
|
+
Trims client-echoed history before memory loaders run. For an existing thread, it keeps only the current user turn or new tool results. For an empty thread, it keeps the full initial input and removes provider item metadata from assistant parts that could refer to items that don't exist in storage.
|
|
20
|
+
|
|
21
|
+
This processor runs first so `MessageHistory`, `SemanticRecall`, and Observational Memory receive only the new input they need.
|
|
22
|
+
|
|
17
23
|
### `MessageHistory`
|
|
18
24
|
|
|
19
25
|
Retrieves message history and persists new messages.
|
|
@@ -206,7 +212,7 @@ Understanding the execution order is important when combining guardrails with me
|
|
|
206
212
|
[Memory Processors] → [Your inputProcessors]
|
|
207
213
|
```
|
|
208
214
|
|
|
209
|
-
1. **Memory processors run FIRST**: `WorkingMemory`, `MessageHistory`, `SemanticRecall`
|
|
215
|
+
1. **Memory processors run FIRST**: `MemoryInputFilter`, then `WorkingMemory`, `MessageHistory`, and `SemanticRecall`
|
|
210
216
|
2. **Your input processors run AFTER**: guardrails, filters, validators
|
|
211
217
|
|
|
212
218
|
As a result, memory loads message history before your processors can validate or filter the input.
|
|
@@ -12,7 +12,9 @@ You can also retrieve message history to display past conversations in your UI.
|
|
|
12
12
|
|
|
13
13
|
> **Warning:** When you use memory with a client application, send **only the new message** from the client instead of the full conversation history.
|
|
14
14
|
>
|
|
15
|
-
> Sending the full history is redundant because Mastra loads messages from storage
|
|
15
|
+
> Sending the full history is redundant because Mastra loads messages from storage. Mastra filters client-echoed history before loading stored messages and uses the stored copy as the base when message IDs match, preserving stored timestamps and provider metadata while retaining new tool results.
|
|
16
|
+
>
|
|
17
|
+
> If you assemble the request input yourself and need it processed exactly as sent, set `retainFullInput: true` on `memory.options` for that call, or in the memory constructor options to apply it agent-wide. This disables the filtering described above. History still loads underneath. Every input message that isn't already stored is saved to the thread, including few-shot examples.
|
|
16
18
|
>
|
|
17
19
|
> For an AI SDK example, see [Using Mastra Memory](https://mastra.ai/integrations/agentic-ui/ai-sdk-ui).
|
|
18
20
|
|
|
@@ -85,6 +85,8 @@ Visit the [Configuration reference](https://mastra.ai/reference/configuration) f
|
|
|
85
85
|
|
|
86
86
|
**scorers** (`Record<string, Scorer>`): Scorers for evaluating agent responses and workflow outputs. Registration also makes a scorer resolvable by ID, which is required to persist its scores. See Score persistence (Default: `{}`)
|
|
87
87
|
|
|
88
|
+
**classifiers** (`Record<string, Classifier>`): Classifiers for typed fixed-option evaluation. Registered classifiers can be retrieved by key or ID. See Classifier (Default: `{}`)
|
|
89
|
+
|
|
88
90
|
**processors** (`Record<string, Processor>`): Input/output processors for transforming agent inputs and outputs (Default: `{}`)
|
|
89
91
|
|
|
90
92
|
**gateways** (`Record<string, MastraModelGateway>`): Custom model gateways to register for accessing AI models through alternative providers or private deployments. Structured as a key-value pair, with keys being the registry key (used for getGateway()) and values being gateway instances. (Default: `{}`)
|
|
@@ -45,6 +45,8 @@ export const agent = new Agent({
|
|
|
45
45
|
|
|
46
46
|
**options.readOnly** (`boolean`): When true, prevents memory from saving new messages and provides working memory as read-only context (without the updateWorkingMemory tool). Useful for read-only operations like previews, internal routing agents, or sub agents that should reference but not modify memory.
|
|
47
47
|
|
|
48
|
+
**options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
|
|
49
|
+
|
|
48
50
|
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires both vector store and embedder to be configured. Default topK is 4, default messageRange is {before: 1, after: 1}.
|
|
49
51
|
|
|
50
52
|
**options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
|
|
@@ -15,7 +15,7 @@ Storage adapters use the shared core retention contract for `prune()`, or a data
|
|
|
15
15
|
| Adapter | Mechanism | Retention support |
|
|
16
16
|
| -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
17
|
| libSQL | `prune()` | All supported growth domains |
|
|
18
|
-
| PostgreSQL | `prune()` | All supported growth domains.
|
|
18
|
+
| PostgreSQL | `prune()` | All supported growth domains. vNext observability drops expired partitions or chunks |
|
|
19
19
|
| MongoDB | `prune()` or native TTL | All supported growth domains. Native TTL indexes are also available |
|
|
20
20
|
| DuckDB | `prune()` | Observability spans, metrics, logs, scores, and feedback |
|
|
21
21
|
| MySQL | `prune()` | Observability spans |
|
|
@@ -102,10 +102,10 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
|
|
|
102
102
|
| `memory` | `resources` | `createdAt` | Resource age |
|
|
103
103
|
| `threadState` | `threadState` | `updatedAt` | Inactivity: state for still-active threads survives |
|
|
104
104
|
| `observability` | `spans` | `startedAt` | Span age |
|
|
105
|
-
| `observability` | `metrics` | `timestamp` | Metric event age (
|
|
106
|
-
| `observability` | `logs` | `timestamp` | Log event age (
|
|
107
|
-
| `observability` | `scores` | `timestamp` | Score event age (
|
|
108
|
-
| `observability` | `feedback` | `timestamp` | Feedback event age (
|
|
105
|
+
| `observability` | `metrics` | `timestamp` | Metric event age (vNext only) |
|
|
106
|
+
| `observability` | `logs` | `timestamp` | Log event age (vNext only) |
|
|
107
|
+
| `observability` | `scores` | `timestamp` | Score event age (vNext only) |
|
|
108
|
+
| `observability` | `feedback` | `timestamp` | Feedback event age (vNext only) |
|
|
109
109
|
| `scores` | `scorers` | `createdAt` | Score record age |
|
|
110
110
|
| `workflows` | `workflowSnapshot` | `updatedAt` | Inactivity, suspended or long-running workflows survive |
|
|
111
111
|
| `backgroundTasks` | `backgroundTasks` | `completedAt` | Time since completion, in-flight tasks (`NULL`) are never pruned |
|
|
@@ -122,7 +122,7 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
|
|
|
122
122
|
> - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
|
|
123
123
|
> - DuckDB observability stores append-only events for all five signals. Its `spans` policy uses the event `timestamp` column rather than `startedAt`.
|
|
124
124
|
> - LibSQL and PostgreSQL support all domains above except `harness`, which PostgreSQL doesn't implement. MongoDB supports all except `threadState` and `harness`. DuckDB, MySQL, Microsoft SQL Server, Oracle Database, Amazon Aurora DSQL, and Google Cloud Spanner currently support retention only in their `observability` domains, with the signal coverage shown in the support matrix.
|
|
125
|
-
> - The
|
|
125
|
+
> - The vNext PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
|
|
126
126
|
|
|
127
127
|
## Methods
|
|
128
128
|
|
|
@@ -208,7 +208,9 @@ You can also cancel a long-running prune with an `AbortSignal`: the loop stops b
|
|
|
208
208
|
|
|
209
209
|
ClickHouse observability storage uses native table TTLs instead of `prune()`. Configure retention as days per signal. `init()` applies the TTLs to new and existing tables and skips `ALTER TABLE` statements when the configured TTL is already present.
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
Omitted signals, and signals set to zero or less, get no TTL. When you remove a signal from `retention`, the next `init()` or `applyRetention()` removes that table's TTL. If Mastra can't read the current TTLs from `system.tables`, it applies the configured TTLs and leaves the others unchanged.
|
|
212
|
+
|
|
213
|
+
For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the vNext observability store:
|
|
212
214
|
|
|
213
215
|
```typescript
|
|
214
216
|
import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse'
|
package/dist/index.cjs
CHANGED
|
@@ -3503,6 +3503,10 @@ function buildScopedWhere(idColumn, idValue, filters) {
|
|
|
3503
3503
|
function jsonbArg(value) {
|
|
3504
3504
|
return value === void 0 || value === null ? null : JSON.stringify(value);
|
|
3505
3505
|
}
|
|
3506
|
+
/** Arbitrary JSON fields distinguish authored JSON null from an absent SQL value. */
|
|
3507
|
+
function jsonDataArg(value) {
|
|
3508
|
+
return value === void 0 ? null : JSON.stringify(value);
|
|
3509
|
+
}
|
|
3506
3510
|
var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
3507
3511
|
#db;
|
|
3508
3512
|
#client;
|
|
@@ -3608,7 +3612,7 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
3608
3612
|
return {
|
|
3609
3613
|
id: row.id,
|
|
3610
3614
|
name: row.name,
|
|
3611
|
-
description: row.description,
|
|
3615
|
+
description: row.description ?? void 0,
|
|
3612
3616
|
metadata: row.metadata ? (0, _mastra_core_storage.safelyParseJSON)(row.metadata) : void 0,
|
|
3613
3617
|
inputSchema: row.inputSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.inputSchema) : void 0,
|
|
3614
3618
|
groundTruthSchema: row.groundTruthSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.groundTruthSchema) : void 0,
|
|
@@ -3996,9 +4000,9 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
3996
4000
|
args.externalId ?? null,
|
|
3997
4001
|
args.datasetId,
|
|
3998
4002
|
args.datasetId,
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4003
|
+
jsonDataArg(args.input),
|
|
4004
|
+
jsonDataArg(args.groundTruth),
|
|
4005
|
+
jsonDataArg(args.expectedTrajectory),
|
|
4002
4006
|
jsonbArg(args.toolMocks),
|
|
4003
4007
|
args.unmockedToolPolicy ?? null,
|
|
4004
4008
|
jsonbArg(args.scorerIds),
|
|
@@ -4120,9 +4124,9 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
4120
4124
|
existing.externalId ?? null,
|
|
4121
4125
|
organizationId,
|
|
4122
4126
|
projectId,
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4127
|
+
jsonDataArg(mergedInput),
|
|
4128
|
+
jsonDataArg(mergedGroundTruth),
|
|
4129
|
+
jsonDataArg(mergedExpectedTrajectory),
|
|
4126
4130
|
jsonbArg(mergedToolMocks),
|
|
4127
4131
|
mergedUnmockedToolPolicy ?? null,
|
|
4128
4132
|
jsonbArg(mergedScorerIds),
|
|
@@ -4219,9 +4223,9 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
4219
4223
|
existing.externalId ?? null,
|
|
4220
4224
|
dataset.organizationId ?? null,
|
|
4221
4225
|
dataset.projectId ?? null,
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4226
|
+
jsonDataArg(existing.input),
|
|
4227
|
+
jsonDataArg(existing.groundTruth),
|
|
4228
|
+
jsonDataArg(existing.expectedTrajectory),
|
|
4225
4229
|
jsonbArg(existing.toolMocks),
|
|
4226
4230
|
existing.unmockedToolPolicy ?? null,
|
|
4227
4231
|
jsonbArg(existing.scorerIds),
|
|
@@ -4609,9 +4613,9 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
4609
4613
|
item.externalId ?? null,
|
|
4610
4614
|
dataset.organizationId ?? null,
|
|
4611
4615
|
dataset.projectId ?? null,
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4616
|
+
jsonDataArg(item.input),
|
|
4617
|
+
jsonDataArg(item.groundTruth),
|
|
4618
|
+
jsonDataArg(item.expectedTrajectory),
|
|
4615
4619
|
jsonbArg(item.toolMocks),
|
|
4616
4620
|
item.unmockedToolPolicy ?? null,
|
|
4617
4621
|
jsonbArg(item.scorerIds),
|
|
@@ -4716,9 +4720,9 @@ var DatasetsLibSQL = class extends _mastra_core_storage.DatasetsStorage {
|
|
|
4716
4720
|
item.externalId ?? null,
|
|
4717
4721
|
dataset.organizationId ?? null,
|
|
4718
4722
|
dataset.projectId ?? null,
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4723
|
+
jsonDataArg(item.input),
|
|
4724
|
+
jsonDataArg(item.groundTruth),
|
|
4725
|
+
jsonDataArg(item.expectedTrajectory),
|
|
4722
4726
|
jsonbArg(item.toolMocks),
|
|
4723
4727
|
item.unmockedToolPolicy ?? null,
|
|
4724
4728
|
jsonbArg(item.scorerIds),
|