@mastra/libsql 1.19.0-alpha.0 → 1.19.0-alpha.1
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 +42 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-agent-approval.md +2 -2
- package/dist/docs/references/docs-deployment-workers.md +14 -14
- package/dist/docs/references/docs-memory-overview.md +14 -0
- package/dist/docs/references/reference-core-mastra-class.md +1 -1
- package/dist/index.cjs +169 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +170 -15
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/workflow-definitions/index.d.ts +14 -0
- package/dist/storage/domains/workflow-definitions/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.19.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Stored workflow definitions now persist across restarts on every major database backend. ([#20471](https://github.com/mastra-ai/mastra/pull/20471))
|
|
8
|
+
|
|
9
|
+
Implement the `workflowDefinitions` storage domain for libsql, pg, mysql, mssql, mongodb, and spanner. Previously the stored-workflow persistence path (`POST /stored/workflows`, `Mastra.addStoredWorkflow`) only worked against `@mastra/core`'s in-memory store. Persistent adapters returned `undefined` from `storage.getStore('workflowDefinitions')` and threw when the HTTP handler tried to read/write a workflow.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const workflowDefinitions = await storage.getStore('workflowDefinitions');
|
|
13
|
+
if (!workflowDefinitions) {
|
|
14
|
+
throw new Error('This storage adapter does not support the workflowDefinitions domain');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
await workflowDefinitions.upsert({
|
|
18
|
+
id: 'greeting-workflow',
|
|
19
|
+
inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
|
|
20
|
+
outputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
|
|
21
|
+
graph: [{ type: 'agent', id: 'greet', agentId: 'greeter-agent' }],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const { definitions, total } = await workflowDefinitions.list({ status: 'active' });
|
|
25
|
+
const definition = await workflowDefinitions.get('greeting-workflow');
|
|
26
|
+
await workflowDefinitions.delete('greeting-workflow');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each adapter now ships a `WorkflowDefinitions*` domain that:
|
|
30
|
+
|
|
31
|
+
- Creates the shared `mastra_workflow_definitions` table (or Mongo collection) from `WORKFLOW_DEFINITIONS_SCHEMA` during `init()`, plus a default index on `status`.
|
|
32
|
+
- Implements `upsert` / `get` / `list` / `delete` matching `WorkflowDefinitionsStorage` semantics (`list` supports `status` and `authorId` filters and orders by `updatedAt` desc). Partial upserts preserve unspecified fields, including `authorId` updates and `createdAt` / `updatedAt` semantics.
|
|
33
|
+
- Handles concurrent first-writes race-safely: if two callers upsert the same new id simultaneously, the losing insert detects the duplicate key, re-reads the row, and applies the partial-update path instead of failing.
|
|
34
|
+
- Round-trips the JSON columns (`inputSchema`, `outputSchema`, `stateSchema`, `requestContextSchema`, `metadata`, `graph`) through each adapter's JSON handling, so declarative workflow graphs rehydrate identically no matter which backend they were stored in. Malformed persisted JSON surfaces as an actionable error naming the row and column instead of hydrating raw strings.
|
|
35
|
+
|
|
36
|
+
Exported class names by adapter: `WorkflowDefinitionsLibSQL`, `WorkflowDefinitionsPG`, `WorkflowDefinitionsMySQL`, `WorkflowDefinitionsMSSQL`, `MongoDBWorkflowDefinitionsStore`, `WorkflowDefinitionsSpanner`. The composite stores (`LibSQLStore`, `PostgresStore`, `MySQLStore`, `MSSQLStore`, `MongoDBStore`, `SpannerStore`) auto-wire the new domain, so callers do not need to construct it manually — `storage.getStore('workflowDefinitions')` now returns a live handle.
|
|
37
|
+
|
|
38
|
+
The pg adapter reads `createdAt` / `updatedAt` from the auto-added `createdAtZ` / `updatedAtZ` `timestamptz` companion columns to avoid the naive-timestamp / local-TZ drift that a plain `TIMESTAMP` read exhibits under node-pg.
|
|
39
|
+
|
|
40
|
+
`@mastra/clickhouse` and `@mastra/cloudflare` register the new `mastra_workflow_definitions` table in their table/type maps so shared table constants stay exhaustive (no workflow-definitions domain implementation yet).
|
|
41
|
+
|
|
42
|
+
- Updated dependencies [[`4844167`](https://github.com/mastra-ai/mastra/commit/4844167cff2d5ec5004e94edd34970833040fa3f), [`5faf93f`](https://github.com/mastra-ai/mastra/commit/5faf93f03e19daea394b9e2a923f2e4f833407f2), [`80ad891`](https://github.com/mastra-ai/mastra/commit/80ad891f8cd10379aa5b5af7510c763783b2ab56), [`a1cb98d`](https://github.com/mastra-ai/mastra/commit/a1cb98d11990b560b98482292a1f34aa1a2d9092), [`598ad82`](https://github.com/mastra-ai/mastra/commit/598ad82d41c41389a686338a1d0e50b7400e1938), [`1fd6aad`](https://github.com/mastra-ai/mastra/commit/1fd6aad1ea4a9d32f65efa832307c35e981a4c0a)]:
|
|
43
|
+
- @mastra/core@1.56.0-alpha.4
|
|
44
|
+
|
|
3
45
|
## 1.19.0-alpha.0
|
|
4
46
|
|
|
5
47
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -108,7 +108,7 @@ A tool's own `requireApproval` setting takes precedence over the function above.
|
|
|
108
108
|
|
|
109
109
|
For sensitive tools, bind the approval to the exact tool name and arguments that were shown to the reviewer. If those arguments drift before execution, the tool shouldn't run under the old approval.
|
|
110
110
|
|
|
111
|
-
The `tool-call-approval` chunk already includes `toolName`, `toolCallId`, and `args`. You can fingerprint those fields when the approval request is shown. The example below uses a
|
|
111
|
+
The `tool-call-approval` chunk already includes `toolName`, `toolCallId`, and `args`. You can fingerprint those fields when the approval request is shown. The example below uses a JSON string as the fingerprint, but in production you should use a stable hash of the tool name and arguments:
|
|
112
112
|
|
|
113
113
|
```typescript
|
|
114
114
|
import { Agent } from '@mastra/core/agent'
|
|
@@ -174,7 +174,7 @@ async function approveReviewedToolCall(runId: string, toolCallId: string, finger
|
|
|
174
174
|
await consumeApprovalStream(stream)
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
In production, store the approved fingerprint in durable storage scoped to the user, run, tool call, and policy version. The `Set` above is intentionally small so the boundary is
|
|
177
|
+
In production, store the approved fingerprint in durable storage scoped to the user, run, tool call, and policy version. The `Set` above is intentionally small so the boundary is clear: the approval is consumed once, and only for the same canonical tool arguments that were reviewed.
|
|
178
178
|
|
|
179
179
|
### Runtime suspension with `suspend()`
|
|
180
180
|
|
|
@@ -17,7 +17,7 @@ Workers matter when any of these apply:
|
|
|
17
17
|
- Different parts of the system need to scale independently (e.g., more orchestration capacity without more API instances)
|
|
18
18
|
- Background tool calls should run on dedicated compute
|
|
19
19
|
|
|
20
|
-
If your application handles light traffic and workflows complete
|
|
20
|
+
If your application handles light traffic and workflows complete fast, the default in-process setup works fine. Skip the worker infrastructure until you need it.
|
|
21
21
|
|
|
22
22
|
## Worker types
|
|
23
23
|
|
|
@@ -33,11 +33,11 @@ The orchestration worker requires a PubSub backend that supports pull mode (e.g.
|
|
|
33
33
|
|
|
34
34
|
### Scheduler worker
|
|
35
35
|
|
|
36
|
-
Polls storage for due cron schedules and publishes `workflow.start` events. It
|
|
36
|
+
Polls storage for due cron schedules and publishes `workflow.start` events. It's a producer only, meaning it creates work for the orchestration worker to pick up.
|
|
37
37
|
|
|
38
38
|
The scheduler reads declarative `schedule` fields from your workflow definitions automatically. See [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows) for how to declare schedules.
|
|
39
39
|
|
|
40
|
-
**
|
|
40
|
+
**Don't run more than one scheduler instance.** Multiple schedulers polling the same storage would fire duplicate events for the same schedule.
|
|
41
41
|
|
|
42
42
|
### Background task worker
|
|
43
43
|
|
|
@@ -47,7 +47,7 @@ The background task worker manages concurrency limits, task lifecycle, and resul
|
|
|
47
47
|
|
|
48
48
|
## How workers run
|
|
49
49
|
|
|
50
|
-
### In-process (default)
|
|
50
|
+
### In-process mode (default)
|
|
51
51
|
|
|
52
52
|
With no configuration, Mastra creates and starts workers inside the API process. Events flow through an in-memory PubSub, and everything shares a single Node.js runtime.
|
|
53
53
|
|
|
@@ -64,7 +64,7 @@ This setup needs no external infrastructure beyond your storage adapter. It does
|
|
|
64
64
|
|
|
65
65
|
### Split processes
|
|
66
66
|
|
|
67
|
-
To run workers
|
|
67
|
+
To run workers in their own processes, configure a distributed [PubSub](https://mastra.ai/docs/server/pubsub) backend and use the `MASTRA_WORKERS` environment variable to control which workers start in each process.
|
|
68
68
|
|
|
69
69
|
**Redis Streams + PostgreSQL**:
|
|
70
70
|
|
|
@@ -100,38 +100,38 @@ export const mastra = new Mastra({
|
|
|
100
100
|
})
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
Any [supported storage backend](https://mastra.ai/reference/workers/overview) works
|
|
103
|
+
Any [supported storage backend](https://mastra.ai/reference/workers/overview) works. Swap the storage adapter for your preferred database.
|
|
104
104
|
|
|
105
105
|
Run the same build artifact in multiple containers, each with a different [`MASTRA_WORKERS`](https://mastra.ai/reference/workers/overview) value to control which worker starts in each process.
|
|
106
106
|
|
|
107
107
|
Split deployments require a distributed PubSub backend ([`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) or [`GoogleCloudPubSub`](https://mastra.ai/reference/pubsub/google-cloud-pubsub)), a shared [storage backend](https://mastra.ai/reference/workers/overview), and network connectivity between the orchestration worker and the API.
|
|
108
108
|
|
|
109
|
-
The [worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers) walks through this setup with
|
|
109
|
+
The [worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers) walks through this setup with Docker Compose and Kubernetes examples.
|
|
110
110
|
|
|
111
111
|
## Network architecture
|
|
112
112
|
|
|
113
|
-
Workers are internal infrastructure. They
|
|
113
|
+
Workers are internal infrastructure. They're not exposed to end users and don't need their own subdomain, public URL, or inbound HTTP route.
|
|
114
114
|
|
|
115
115
|
In a split deployment:
|
|
116
116
|
|
|
117
|
-
- **The API server is the only public-facing process
|
|
118
|
-
- **Workers connect outbound only
|
|
119
|
-
- **The orchestration worker calls the API internally
|
|
117
|
+
- **The API server is the only public-facing process**: It serves all client HTTP requests, including REST endpoints, agent interactions, workflow triggers, and any custom routes.
|
|
118
|
+
- **Workers connect outbound only**: They pull events from the distributed PubSub backend and read/write to the shared storage database. They don't accept inbound traffic from clients.
|
|
119
|
+
- **The orchestration worker calls the API internally**: It sends step execution requests to the API over the container network using `MASTRA_STEP_EXECUTION_URL`. This is internal service-to-service communication, not a public endpoint.
|
|
120
120
|
|
|
121
121
|
All three worker types (orchestration, scheduler, background task) sit behind the API on a private network. They share access to the PubSub backend and storage database but never receive traffic directly from clients. If a worker-related feature needs an HTTP route (for example, token minting for a voice integration), that route runs on the API server, not on the worker process.
|
|
122
122
|
|
|
123
123
|
## Known limitations
|
|
124
124
|
|
|
125
|
-
- **No dead-letter queue**: Failed events are nacked and retried, but there
|
|
125
|
+
- **No dead-letter queue**: Failed events are nacked and retried, but there's no DLQ for events that fail after all retries.
|
|
126
126
|
- **No built-in health endpoint**: Workers don't expose an HTTP health check. Use container-level liveness probes or process monitoring.
|
|
127
127
|
- **Scheduler is single-instance**: Running multiple scheduler processes causes duplicate schedule fires.
|
|
128
128
|
- **Runs stuck in "running" after API crash**: If the API process crashes while executing a workflow step, the run remains in `running` status with no automatic retry. For [durable agents](https://mastra.ai/docs/long-running-agents/durable-agents), set `recovery.durableAgents` to `'auto'` in the Mastra config to automatically re-drive orphaned runs on server restart. See [Crash recovery](https://mastra.ai/docs/long-running-agents/durable-agents) for details.
|
|
129
129
|
|
|
130
130
|
## Related
|
|
131
131
|
|
|
132
|
-
- [Worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers): Docker Compose
|
|
132
|
+
- [Worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers): Docker Compose and Kubernetes examples
|
|
133
133
|
- [Worker authentication](https://mastra.ai/docs/server/auth/workers): Secure worker-to-API communication
|
|
134
|
-
- [Workers reference](https://mastra.ai/reference/workers/overview):
|
|
134
|
+
- [Workers reference](https://mastra.ai/reference/workers/overview): Details about worker environment variables and types, with a list of supported storage backends
|
|
135
135
|
- [CLI reference](https://mastra.ai/reference/cli/mastra): `mastra worker build` and `mastra worker start`
|
|
136
136
|
- [PubSub](https://mastra.ai/docs/server/pubsub): Event delivery backends
|
|
137
137
|
- [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows): Declare cron schedules on workflows
|
|
@@ -172,6 +172,20 @@ export const memoryAgent = new Agent({
|
|
|
172
172
|
|
|
173
173
|
See [Observational Memory](https://mastra.ai/docs/memory/observational-memory) for details on how observations and reflections work, and [the reference](https://mastra.ai/reference/memory/observational-memory) for all configuration options.
|
|
174
174
|
|
|
175
|
+
## What the model sees
|
|
176
|
+
|
|
177
|
+
Each memory feature is added to either the system messages or the conversation messages in the request sent to the model. The layers depend on the features you've enabled. Working memory and semantic recall only appear when configured. The same applies to Observational Memory, while message history is on by default. The diagram shows where each enabled layer is placed in the request. The list below describes what each layer contributes:
|
|
178
|
+
|
|
179
|
+

|
|
180
|
+
|
|
181
|
+
- [Working memory](https://mastra.ai/docs/memory/working-memory) is injected as a system message containing the template and the stored data. With `useStateSignals`, it's delivered as a state signal instead.
|
|
182
|
+
- [Semantic recall](https://mastra.ai/docs/memory/semantic-recall) matches from the current thread are inserted as regular messages and interleave with message history by timestamp. Matches from other threads are formatted into a system message instead.
|
|
183
|
+
- [Message history](https://mastra.ai/docs/memory/message-history) adds the last N messages in chronological order. Your new message always comes last.
|
|
184
|
+
- [Observational Memory](https://mastra.ai/docs/memory/observational-memory) replaces old raw history: reflections and observations live in a system message, and only messages that haven't been observed yet remain in the conversation. A short continuation reminder is placed at the start of the conversation messages.
|
|
185
|
+
- Context messages are the optional `context` array passed on a call, for example `agent.generate(msg, { context: [...] })`. Use them for one-off background such as app state or your own RAG results. They appear as regular conversation messages for that request only and are never saved to memory.
|
|
186
|
+
|
|
187
|
+
Conversation messages are ordered by timestamp and deduplicated by message ID, so recalled older messages appear before recent history. Context messages passed at call time are stamped with the current time, which places them after history and recall but before your new message. To inspect the exact context for a real request, use [Tracing](https://mastra.ai/docs/observability/tracing/overview) and open the LLM call spans, see [Observability](#observability) below.
|
|
188
|
+
|
|
175
189
|
## Memory in multi-agent systems
|
|
176
190
|
|
|
177
191
|
When a [supervisor agent](https://mastra.ai/docs/agents/supervisor-agents) delegates to a subagent, Mastra isolates subagent memory automatically. No flag enables this as it happens on every delegation. Understanding how this scoping works lets you decide what stays private and what to share intentionally.
|
|
@@ -135,7 +135,7 @@ Visit the [Configuration reference](https://mastra.ai/reference/configuration) f
|
|
|
135
135
|
|
|
136
136
|
Re-drives every orphaned `running` durable-agent run across all registered durable agents. Called automatically on boot when `recovery.durableAgents` is `'auto'`. You can also call it directly for manual recovery or from a scheduled task.
|
|
137
137
|
|
|
138
|
-
Requires persistent storage
|
|
138
|
+
Requires persistent storage. With an in-memory store, there's nothing to recover after a process restart.
|
|
139
139
|
|
|
140
140
|
```typescript
|
|
141
141
|
const result = await mastra.recoverAllDurableAgents()
|
package/dist/index.cjs
CHANGED
|
@@ -2854,7 +2854,7 @@ function serializeJson(v) {
|
|
|
2854
2854
|
if (typeof v === "object" && v != null) return JSON.stringify(v);
|
|
2855
2855
|
return v ?? null;
|
|
2856
2856
|
}
|
|
2857
|
-
function parseJson$
|
|
2857
|
+
function parseJson$3(val) {
|
|
2858
2858
|
if (val == null) return void 0;
|
|
2859
2859
|
if (typeof val === "string") try {
|
|
2860
2860
|
return JSON.parse(val);
|
|
@@ -2869,14 +2869,14 @@ function rowToTask(row) {
|
|
|
2869
2869
|
status: String(row.status),
|
|
2870
2870
|
toolName: String(row.tool_name),
|
|
2871
2871
|
toolCallId: String(row.tool_call_id),
|
|
2872
|
-
args: parseJson$
|
|
2872
|
+
args: parseJson$3(row.args) ?? {},
|
|
2873
2873
|
agentId: String(row.agent_id),
|
|
2874
2874
|
threadId: row.thread_id != null ? String(row.thread_id) : void 0,
|
|
2875
2875
|
resourceId: row.resource_id != null ? String(row.resource_id) : void 0,
|
|
2876
2876
|
runId: String(row.run_id),
|
|
2877
|
-
result: parseJson$
|
|
2878
|
-
error: parseJson$
|
|
2879
|
-
suspendPayload: parseJson$
|
|
2877
|
+
result: parseJson$3(row.result),
|
|
2878
|
+
error: parseJson$3(row.error),
|
|
2879
|
+
suspendPayload: parseJson$3(row.suspend_payload),
|
|
2880
2880
|
retryCount: Number(row.retry_count),
|
|
2881
2881
|
maxRetries: Number(row.max_retries),
|
|
2882
2882
|
timeoutMs: Number(row.timeout_ms),
|
|
@@ -8530,7 +8530,7 @@ const statusTimestamp = (status, now) => {
|
|
|
8530
8530
|
if (status === "discarded") return { discardedAt: now };
|
|
8531
8531
|
return {};
|
|
8532
8532
|
};
|
|
8533
|
-
function parseJson$
|
|
8533
|
+
function parseJson$2(value) {
|
|
8534
8534
|
if (value == null) return void 0;
|
|
8535
8535
|
if (typeof value === "string") try {
|
|
8536
8536
|
return JSON.parse(value);
|
|
@@ -8552,14 +8552,14 @@ function rowToNotification(row) {
|
|
|
8552
8552
|
priority: String(row.priority),
|
|
8553
8553
|
status: String(row.status),
|
|
8554
8554
|
summary: String(row.summary),
|
|
8555
|
-
payload: parseJson$
|
|
8555
|
+
payload: parseJson$2(row.payload),
|
|
8556
8556
|
resourceId: row.resourceId == null ? void 0 : String(row.resourceId),
|
|
8557
8557
|
agentId: row.agentId == null ? void 0 : String(row.agentId),
|
|
8558
8558
|
sourceId: row.sourceId == null ? void 0 : String(row.sourceId),
|
|
8559
8559
|
dedupeKey: row.dedupeKey == null ? void 0 : String(row.dedupeKey),
|
|
8560
8560
|
coalesceKey: row.coalesceKey == null ? void 0 : String(row.coalesceKey),
|
|
8561
8561
|
coalescedCount: Number(row.coalescedCount ?? 1),
|
|
8562
|
-
attributes: parseJson$
|
|
8562
|
+
attributes: parseJson$2(row.attributes),
|
|
8563
8563
|
createdAt: new Date(String(row.createdAt)),
|
|
8564
8564
|
updatedAt: new Date(String(row.updatedAt)),
|
|
8565
8565
|
deliveredAt: parseDate(row.deliveredAt),
|
|
@@ -8575,7 +8575,7 @@ function rowToNotification(row) {
|
|
|
8575
8575
|
lastDeliveryError: row.lastDeliveryError == null ? void 0 : String(row.lastDeliveryError),
|
|
8576
8576
|
deliveredSignalId: row.deliveredSignalId == null ? void 0 : String(row.deliveredSignalId),
|
|
8577
8577
|
summarySignalId: row.summarySignalId == null ? void 0 : String(row.summarySignalId),
|
|
8578
|
-
metadata: parseJson$
|
|
8578
|
+
metadata: parseJson$2(row.metadata)
|
|
8579
8579
|
};
|
|
8580
8580
|
}
|
|
8581
8581
|
function addArrayFilter(conditions, args, column, value) {
|
|
@@ -9766,7 +9766,7 @@ var PromptBlocksLibSQL = class extends _mastra_core_storage.PromptBlocksStorage
|
|
|
9766
9766
|
};
|
|
9767
9767
|
//#endregion
|
|
9768
9768
|
//#region src/storage/domains/schedules/index.ts
|
|
9769
|
-
function parseJson(val) {
|
|
9769
|
+
function parseJson$1(val) {
|
|
9770
9770
|
if (val == null) return void 0;
|
|
9771
9771
|
if (typeof val === "string") try {
|
|
9772
9772
|
return JSON.parse(val);
|
|
@@ -9780,7 +9780,7 @@ function toNumber(val) {
|
|
|
9780
9780
|
return Number(val);
|
|
9781
9781
|
}
|
|
9782
9782
|
function rowToSchedule(row) {
|
|
9783
|
-
const target = parseJson(row.target);
|
|
9783
|
+
const target = parseJson$1(row.target);
|
|
9784
9784
|
if (!target) throw new Error(`Schedule row ${row.id} has invalid target`);
|
|
9785
9785
|
const schedule = {
|
|
9786
9786
|
id: String(row.id),
|
|
@@ -9794,7 +9794,7 @@ function rowToSchedule(row) {
|
|
|
9794
9794
|
if (row.timezone != null) schedule.timezone = String(row.timezone);
|
|
9795
9795
|
if (row.last_fire_at != null) schedule.lastFireAt = toNumber(row.last_fire_at);
|
|
9796
9796
|
if (row.last_run_id != null) schedule.lastRunId = String(row.last_run_id);
|
|
9797
|
-
const metadata = parseJson(row.metadata);
|
|
9797
|
+
const metadata = parseJson$1(row.metadata);
|
|
9798
9798
|
if (metadata !== void 0) schedule.metadata = metadata;
|
|
9799
9799
|
if (row.owner_type != null) schedule.ownerType = String(row.owner_type);
|
|
9800
9800
|
if (row.owner_id != null) schedule.ownerId = String(row.owner_id);
|
|
@@ -9812,7 +9812,7 @@ function rowToTrigger(row) {
|
|
|
9812
9812
|
};
|
|
9813
9813
|
if (row.error != null) trigger.error = String(row.error);
|
|
9814
9814
|
if (row.parent_trigger_id != null) trigger.parentTriggerId = String(row.parent_trigger_id);
|
|
9815
|
-
const metadata = parseJson(row.metadata);
|
|
9815
|
+
const metadata = parseJson$1(row.metadata);
|
|
9816
9816
|
if (metadata !== void 0) trigger.metadata = metadata;
|
|
9817
9817
|
return trigger;
|
|
9818
9818
|
}
|
|
@@ -11693,6 +11693,159 @@ var ToolProviderConnectionsLibSQL = class extends _mastra_core_storage.ToolProvi
|
|
|
11693
11693
|
}
|
|
11694
11694
|
};
|
|
11695
11695
|
//#endregion
|
|
11696
|
+
//#region src/storage/domains/workflow-definitions/index.ts
|
|
11697
|
+
function parseJson(val, column, rowId) {
|
|
11698
|
+
if (val == null) return void 0;
|
|
11699
|
+
if (typeof val === "string") try {
|
|
11700
|
+
return JSON.parse(val);
|
|
11701
|
+
} catch {
|
|
11702
|
+
throw new Error(`Workflow definition row "${String(rowId)}" has malformed JSON in column "${column}".`);
|
|
11703
|
+
}
|
|
11704
|
+
return val;
|
|
11705
|
+
}
|
|
11706
|
+
function rowToDefinition(row) {
|
|
11707
|
+
const inputSchema = parseJson(row.inputSchema, "inputSchema", row.id);
|
|
11708
|
+
const outputSchema = parseJson(row.outputSchema, "outputSchema", row.id);
|
|
11709
|
+
const graph = parseJson(row.graph, "graph", row.id);
|
|
11710
|
+
if (inputSchema === void 0 || outputSchema === void 0 || graph === void 0) throw new Error(`Workflow definition row "${row.id}" is missing required JSON columns.`);
|
|
11711
|
+
const def = {
|
|
11712
|
+
id: String(row.id),
|
|
11713
|
+
inputSchema,
|
|
11714
|
+
outputSchema,
|
|
11715
|
+
graph,
|
|
11716
|
+
status: row.status,
|
|
11717
|
+
source: row.source,
|
|
11718
|
+
createdAt: new Date(row.createdAt),
|
|
11719
|
+
updatedAt: new Date(row.updatedAt)
|
|
11720
|
+
};
|
|
11721
|
+
if (row.description != null) def.description = String(row.description);
|
|
11722
|
+
const metadata = parseJson(row.metadata, "metadata", row.id);
|
|
11723
|
+
if (metadata !== void 0) def.metadata = metadata;
|
|
11724
|
+
const stateSchema = parseJson(row.stateSchema, "stateSchema", row.id);
|
|
11725
|
+
if (stateSchema !== void 0) def.stateSchema = stateSchema;
|
|
11726
|
+
const requestContextSchema = parseJson(row.requestContextSchema, "requestContextSchema", row.id);
|
|
11727
|
+
if (requestContextSchema !== void 0) def.requestContextSchema = requestContextSchema;
|
|
11728
|
+
if (row.authorId != null) def.authorId = String(row.authorId);
|
|
11729
|
+
return def;
|
|
11730
|
+
}
|
|
11731
|
+
var WorkflowDefinitionsLibSQL = class extends _mastra_core_storage.WorkflowDefinitionsStorage {
|
|
11732
|
+
#db;
|
|
11733
|
+
#client;
|
|
11734
|
+
constructor(config) {
|
|
11735
|
+
super();
|
|
11736
|
+
const client = resolveClient(config);
|
|
11737
|
+
this.#client = client;
|
|
11738
|
+
this.#db = new LibSQLDB({
|
|
11739
|
+
client,
|
|
11740
|
+
maxRetries: config.maxRetries,
|
|
11741
|
+
initialBackoffMs: config.initialBackoffMs
|
|
11742
|
+
});
|
|
11743
|
+
}
|
|
11744
|
+
async init() {
|
|
11745
|
+
await this.#db.createTable({
|
|
11746
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
|
|
11747
|
+
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS]
|
|
11748
|
+
});
|
|
11749
|
+
await this.#client.execute({
|
|
11750
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_definitions_status ON "${_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS}" ("status")`,
|
|
11751
|
+
args: []
|
|
11752
|
+
});
|
|
11753
|
+
}
|
|
11754
|
+
async dangerouslyClearAll() {
|
|
11755
|
+
await this.#db.deleteData({ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS });
|
|
11756
|
+
}
|
|
11757
|
+
async upsert(input) {
|
|
11758
|
+
const now = /* @__PURE__ */ new Date();
|
|
11759
|
+
if (!await this.get(input.id)) {
|
|
11760
|
+
if (!("inputSchema" in input) || !input.inputSchema) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
|
|
11761
|
+
if (!("outputSchema" in input) || !input.outputSchema) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
|
|
11762
|
+
if (!("graph" in input) || !input.graph) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
|
|
11763
|
+
const record = {
|
|
11764
|
+
id: input.id,
|
|
11765
|
+
description: input.description ?? null,
|
|
11766
|
+
metadata: input.metadata ?? null,
|
|
11767
|
+
inputSchema: input.inputSchema,
|
|
11768
|
+
outputSchema: input.outputSchema,
|
|
11769
|
+
stateSchema: input.stateSchema ?? null,
|
|
11770
|
+
requestContextSchema: input.requestContextSchema ?? null,
|
|
11771
|
+
graph: input.graph,
|
|
11772
|
+
status: "active",
|
|
11773
|
+
source: "storage",
|
|
11774
|
+
authorId: "authorId" in input ? input.authorId ?? null : null,
|
|
11775
|
+
createdAt: now,
|
|
11776
|
+
updatedAt: now
|
|
11777
|
+
};
|
|
11778
|
+
try {
|
|
11779
|
+
await this.#db.insertOnly({
|
|
11780
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
|
|
11781
|
+
record
|
|
11782
|
+
});
|
|
11783
|
+
} catch (error) {
|
|
11784
|
+
if (!await this.get(input.id)) throw error;
|
|
11785
|
+
return this.#applyUpdate(input, now);
|
|
11786
|
+
}
|
|
11787
|
+
const created = await this.get(input.id);
|
|
11788
|
+
if (!created) throw new Error(`Failed to persist workflow definition "${input.id}".`);
|
|
11789
|
+
return created;
|
|
11790
|
+
}
|
|
11791
|
+
return this.#applyUpdate(input, now);
|
|
11792
|
+
}
|
|
11793
|
+
async #applyUpdate(input, now) {
|
|
11794
|
+
const data = { updatedAt: now };
|
|
11795
|
+
if ("description" in input && input.description !== void 0) data.description = input.description;
|
|
11796
|
+
if ("metadata" in input && input.metadata !== void 0) data.metadata = input.metadata;
|
|
11797
|
+
if ("inputSchema" in input && input.inputSchema !== void 0) data.inputSchema = input.inputSchema;
|
|
11798
|
+
if ("outputSchema" in input && input.outputSchema !== void 0) data.outputSchema = input.outputSchema;
|
|
11799
|
+
if ("stateSchema" in input && input.stateSchema !== void 0) data.stateSchema = input.stateSchema;
|
|
11800
|
+
if ("requestContextSchema" in input && input.requestContextSchema !== void 0) data.requestContextSchema = input.requestContextSchema;
|
|
11801
|
+
if ("graph" in input && input.graph !== void 0) data.graph = input.graph;
|
|
11802
|
+
if ("status" in input && input.status !== void 0) data.status = input.status;
|
|
11803
|
+
if ("authorId" in input && input.authorId !== void 0) data.authorId = input.authorId;
|
|
11804
|
+
await this.#db.update({
|
|
11805
|
+
tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
|
|
11806
|
+
keys: { id: input.id },
|
|
11807
|
+
data
|
|
11808
|
+
});
|
|
11809
|
+
const updated = await this.get(input.id);
|
|
11810
|
+
if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
|
|
11811
|
+
return updated;
|
|
11812
|
+
}
|
|
11813
|
+
async get(id) {
|
|
11814
|
+
const row = (await this.#client.execute({
|
|
11815
|
+
sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS)} FROM "${_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS}" WHERE id = ?`,
|
|
11816
|
+
args: [id]
|
|
11817
|
+
})).rows[0];
|
|
11818
|
+
return row ? rowToDefinition(row) : null;
|
|
11819
|
+
}
|
|
11820
|
+
async list(args) {
|
|
11821
|
+
const conditions = [];
|
|
11822
|
+
const params = [];
|
|
11823
|
+
if (args?.status) {
|
|
11824
|
+
conditions.push("status = ?");
|
|
11825
|
+
params.push(args.status);
|
|
11826
|
+
}
|
|
11827
|
+
if (args?.authorId !== void 0) {
|
|
11828
|
+
conditions.push("authorId = ?");
|
|
11829
|
+
params.push(args.authorId);
|
|
11830
|
+
}
|
|
11831
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
11832
|
+
const definitions = (await this.#client.execute({
|
|
11833
|
+
sql: `SELECT ${buildSelectColumns(_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS)} FROM "${_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS}" ${where} ORDER BY updatedAt DESC`,
|
|
11834
|
+
args: params
|
|
11835
|
+
})).rows.map((row) => rowToDefinition(row));
|
|
11836
|
+
return {
|
|
11837
|
+
definitions,
|
|
11838
|
+
total: definitions.length
|
|
11839
|
+
};
|
|
11840
|
+
}
|
|
11841
|
+
async delete(id) {
|
|
11842
|
+
await this.#client.execute({
|
|
11843
|
+
sql: `DELETE FROM "${_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS}" WHERE id = ?`,
|
|
11844
|
+
args: [id]
|
|
11845
|
+
});
|
|
11846
|
+
}
|
|
11847
|
+
};
|
|
11848
|
+
//#endregion
|
|
11696
11849
|
//#region src/storage/domains/workflows/index.ts
|
|
11697
11850
|
var WorkflowsLibSQL = class WorkflowsLibSQL extends _mastra_core_storage.WorkflowsStorage {
|
|
11698
11851
|
/**
|
|
@@ -12987,6 +13140,7 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
12987
13140
|
};
|
|
12988
13141
|
const scores = new ScoresLibSQL(domainConfig);
|
|
12989
13142
|
const workflows = new WorkflowsLibSQL(domainConfig);
|
|
13143
|
+
const workflowDefinitions = new WorkflowDefinitionsLibSQL(domainConfig);
|
|
12990
13144
|
const memory = new MemoryLibSQL(domainConfig);
|
|
12991
13145
|
const observability = new ObservabilityLibSQL(domainConfig);
|
|
12992
13146
|
const agents = new AgentsLibSQL(domainConfig);
|
|
@@ -13010,6 +13164,7 @@ var LibSQLStore = class extends _mastra_core_storage.MastraCompositeStore {
|
|
|
13010
13164
|
this.stores = {
|
|
13011
13165
|
scores,
|
|
13012
13166
|
workflows,
|
|
13167
|
+
workflowDefinitions,
|
|
13013
13168
|
memory,
|
|
13014
13169
|
observability,
|
|
13015
13170
|
agents,
|
|
@@ -13223,6 +13378,7 @@ exports.ScoresLibSQL = ScoresLibSQL;
|
|
|
13223
13378
|
exports.SkillsLibSQL = SkillsLibSQL;
|
|
13224
13379
|
exports.ThreadStateLibSQL = ThreadStateLibSQL;
|
|
13225
13380
|
exports.ToolProviderConnectionsLibSQL = ToolProviderConnectionsLibSQL;
|
|
13381
|
+
exports.WorkflowDefinitionsLibSQL = WorkflowDefinitionsLibSQL;
|
|
13226
13382
|
exports.WorkflowsLibSQL = WorkflowsLibSQL;
|
|
13227
13383
|
exports.WorkspacesLibSQL = WorkspacesLibSQL;
|
|
13228
13384
|
|