@mastra/duckdb 1.11.0-alpha.0 → 1.11.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/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-storage-retention.md +9 -7
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{observability-CdS3iFtO.cjs → observability-3LOqabpn.cjs} +50 -6
- package/dist/observability-3LOqabpn.cjs.map +1 -0
- package/dist/{observability-DyP55NQC.js → observability-DtZoxBur.js} +50 -6
- package/dist/observability-DtZoxBur.js.map +1 -0
- package/dist/storage/domains/observability/helpers.d.ts +5 -0
- package/dist/storage/domains/observability/helpers.d.ts.map +1 -1
- package/dist/storage/domains/observability/trace-query.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/observability-CdS3iFtO.cjs.map +0 -1
- package/dist/observability-DyP55NQC.js.map +0 -1
package/dist/docs/SKILL.md
CHANGED
|
@@ -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
|
@@ -534,7 +534,7 @@ var ObservabilityStorageDuckDB = class extends _mastra_core_storage.Observabilit
|
|
|
534
534
|
async loadDelegate() {
|
|
535
535
|
if (this.delegate) return this.delegate;
|
|
536
536
|
if (this.unavailableError) return null;
|
|
537
|
-
if (!this.loadPromise) this.loadPromise = Promise.resolve().then(() => require("./observability-
|
|
537
|
+
if (!this.loadPromise) this.loadPromise = Promise.resolve().then(() => require("./observability-3LOqabpn.cjs")).then(({ ObservabilityStorageDuckDB }) => {
|
|
538
538
|
const delegate = new ObservabilityStorageDuckDB({ db: this.db });
|
|
539
539
|
this.delegate = delegate;
|
|
540
540
|
return delegate;
|
package/dist/index.js
CHANGED
|
@@ -533,7 +533,7 @@ var ObservabilityStorageDuckDB = class extends ObservabilityStorage {
|
|
|
533
533
|
async loadDelegate() {
|
|
534
534
|
if (this.delegate) return this.delegate;
|
|
535
535
|
if (this.unavailableError) return null;
|
|
536
|
-
if (!this.loadPromise) this.loadPromise = import("./observability-
|
|
536
|
+
if (!this.loadPromise) this.loadPromise = import("./observability-DtZoxBur.js").then(({ ObservabilityStorageDuckDB }) => {
|
|
537
537
|
const delegate = new ObservabilityStorageDuckDB({ db: this.db });
|
|
538
538
|
this.delegate = delegate;
|
|
539
539
|
return delegate;
|
|
@@ -709,6 +709,23 @@ function jsonV(val) {
|
|
|
709
709
|
if (val === null || val === void 0) return "NULL";
|
|
710
710
|
return require_db.DuckDBConnection.sqlValue(JSON.stringify(val));
|
|
711
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* Trim, drop blank, and dedupe tags before they are written, matching the
|
|
714
|
+
* PostgreSQL and ClickHouse stores so tag predicates and discovery agree.
|
|
715
|
+
*/
|
|
716
|
+
function normalizeTags(tags) {
|
|
717
|
+
if (!Array.isArray(tags)) return [];
|
|
718
|
+
const seen = /* @__PURE__ */ new Set();
|
|
719
|
+
const result = [];
|
|
720
|
+
for (const t of tags) {
|
|
721
|
+
if (typeof t !== "string") continue;
|
|
722
|
+
const trimmed = t.trim();
|
|
723
|
+
if (trimmed === "" || seen.has(trimmed)) continue;
|
|
724
|
+
seen.add(trimmed);
|
|
725
|
+
result.push(trimmed);
|
|
726
|
+
}
|
|
727
|
+
return result;
|
|
728
|
+
}
|
|
712
729
|
/** Coerce a value to a Date. Throws if value is nullish. */
|
|
713
730
|
function toDate(val) {
|
|
714
731
|
if (val === null || val === void 0) throw new Error("Expected date value but received null/undefined");
|
|
@@ -2741,6 +2758,10 @@ const TRACE_FIELDS = {
|
|
|
2741
2758
|
status: {
|
|
2742
2759
|
sql: TRACE_STATUS_SQL,
|
|
2743
2760
|
parameterType: "scalar"
|
|
2761
|
+
},
|
|
2762
|
+
tags: {
|
|
2763
|
+
sql: "r.tags",
|
|
2764
|
+
parameterType: "scalar"
|
|
2744
2765
|
}
|
|
2745
2766
|
};
|
|
2746
2767
|
const SPAN_FIELDS = {
|
|
@@ -2943,6 +2964,25 @@ function compileScalarPredicate(predicate, registry, allowMetadata = false) {
|
|
|
2943
2964
|
sql: `${field.sql} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
|
|
2944
2965
|
values: fieldValues
|
|
2945
2966
|
};
|
|
2967
|
+
if (predicate.type === "collection") {
|
|
2968
|
+
const members = `coalesce(TRY_CAST(${field.sql} AS VARCHAR[]), []::VARCHAR[])`;
|
|
2969
|
+
if (!("value" in predicate)) return {
|
|
2970
|
+
sql: `len(${members}) ${predicate.operator === "empty" ? "=" : ">"} 0`,
|
|
2971
|
+
values: fieldValues
|
|
2972
|
+
};
|
|
2973
|
+
if (predicate.operator === "includes") return {
|
|
2974
|
+
sql: `list_contains(${members}, ?)`,
|
|
2975
|
+
values: [...fieldValues, predicate.value]
|
|
2976
|
+
};
|
|
2977
|
+
return {
|
|
2978
|
+
sql: `len(${members}) > 0 AND NOT list_contains(${members}, ?)`,
|
|
2979
|
+
values: [
|
|
2980
|
+
...fieldValues,
|
|
2981
|
+
...fieldValues,
|
|
2982
|
+
predicate.value
|
|
2983
|
+
]
|
|
2984
|
+
};
|
|
2985
|
+
}
|
|
2946
2986
|
if (predicate.type === "membership") {
|
|
2947
2987
|
const list = predicate.values.map(() => parameterSql(field.parameterType)).join(", ");
|
|
2948
2988
|
if (predicate.operator === "in") return {
|
|
@@ -3007,7 +3047,7 @@ function compileFeedbackScalarPredicate(predicate) {
|
|
|
3007
3047
|
values: compiled.values
|
|
3008
3048
|
};
|
|
3009
3049
|
}
|
|
3010
|
-
if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS);
|
|
3050
|
+
if (predicate.field !== "value" || predicate.type === "collection") return compileScalarPredicate(predicate, FEEDBACK_FIELDS);
|
|
3011
3051
|
if (predicate.type === "presence") return {
|
|
3012
3052
|
sql: `s.value IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
|
|
3013
3053
|
values: []
|
|
@@ -3393,7 +3433,11 @@ function compileDuckDBTraceQueryValues(plan) {
|
|
|
3393
3433
|
...scopeValues
|
|
3394
3434
|
];
|
|
3395
3435
|
let fieldSql;
|
|
3396
|
-
|
|
3436
|
+
let source = discoverySource(plan.predicateScope);
|
|
3437
|
+
if (plan.predicateScope === "trace" && plan.path === "tags") {
|
|
3438
|
+
fieldSql = "unnest(list_distinct(TRY_CAST(r.tags AS VARCHAR[])))";
|
|
3439
|
+
source = `${source} WHERE r.tags IS NOT NULL`;
|
|
3440
|
+
} else if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
|
|
3397
3441
|
const jsonPath = `$.${JSON.stringify(plan.path.slice(9))}`;
|
|
3398
3442
|
fieldSql = `NULLIF(trim(CASE WHEN json_type(r.metadata, ?) = 'VARCHAR' THEN json_extract_string(r.metadata, ?) END), '')`;
|
|
3399
3443
|
values.push(jsonPath, jsonPath);
|
|
@@ -3403,7 +3447,7 @@ function compileDuckDBTraceQueryValues(plan) {
|
|
|
3403
3447
|
const search = plan.search ? "AND strpos(lower(CAST(value AS VARCHAR)), lower(?)) > 0" : "";
|
|
3404
3448
|
return {
|
|
3405
3449
|
sql: `WITH ${ctes.join(",\n ")}, extracted AS (
|
|
3406
|
-
SELECT ${fieldSql} AS value FROM ${
|
|
3450
|
+
SELECT ${fieldSql} AS value FROM ${source}
|
|
3407
3451
|
)
|
|
3408
3452
|
SELECT CAST(value AS VARCHAR) AS value, count(*) AS count
|
|
3409
3453
|
FROM extracted
|
|
@@ -4001,7 +4045,7 @@ function createStartSpanRow(s) {
|
|
|
4001
4045
|
serviceName: s.serviceName ?? null,
|
|
4002
4046
|
attributes: s.attributes ?? null,
|
|
4003
4047
|
metadata: s.metadata ?? null,
|
|
4004
|
-
tags: s.tags
|
|
4048
|
+
tags: s.tags == null ? null : normalizeTags(s.tags),
|
|
4005
4049
|
scope: s.scope ?? null,
|
|
4006
4050
|
links: null,
|
|
4007
4051
|
input: s.input ?? null,
|
|
@@ -4040,7 +4084,7 @@ function createEndSpanRow(s) {
|
|
|
4040
4084
|
serviceName: s.serviceName ?? null,
|
|
4041
4085
|
attributes: s.attributes ?? null,
|
|
4042
4086
|
metadata: s.metadata ?? null,
|
|
4043
|
-
tags: s.tags
|
|
4087
|
+
tags: s.tags == null ? null : normalizeTags(s.tags),
|
|
4044
4088
|
scope: s.scope ?? null,
|
|
4045
4089
|
links: s.links ?? null,
|
|
4046
4090
|
input: s.input ?? null,
|
|
@@ -5008,4 +5052,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
|
|
|
5008
5052
|
//#endregion
|
|
5009
5053
|
exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
|
|
5010
5054
|
|
|
5011
|
-
//# sourceMappingURL=observability-
|
|
5055
|
+
//# sourceMappingURL=observability-3LOqabpn.cjs.map
|