@mastra/libsql 0.0.0-bundle-studio-cloud-20251222034739 → 0.0.0-bundle-version-20260121132824
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 +927 -4
- package/dist/docs/README.md +39 -0
- package/dist/docs/SKILL.md +40 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/agents/01-agent-memory.md +166 -0
- package/dist/docs/agents/02-networks.md +292 -0
- package/dist/docs/agents/03-agent-approval.md +377 -0
- package/dist/docs/agents/04-network-approval.md +274 -0
- package/dist/docs/core/01-reference.md +151 -0
- package/dist/docs/guides/01-ai-sdk.md +141 -0
- package/dist/docs/memory/01-overview.md +76 -0
- package/dist/docs/memory/02-storage.md +233 -0
- package/dist/docs/memory/03-working-memory.md +390 -0
- package/dist/docs/memory/04-semantic-recall.md +233 -0
- package/dist/docs/memory/05-memory-processors.md +318 -0
- package/dist/docs/memory/06-reference.md +133 -0
- package/dist/docs/observability/01-overview.md +64 -0
- package/dist/docs/observability/02-default.md +177 -0
- package/dist/docs/rag/01-retrieval.md +548 -0
- package/dist/docs/storage/01-reference.md +538 -0
- package/dist/docs/vectors/01-reference.md +213 -0
- package/dist/docs/workflows/01-snapshots.md +240 -0
- package/dist/index.cjs +839 -351
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +837 -354
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +46 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/db/utils.d.ts +17 -13
- package/dist/storage/db/utils.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +3 -2
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +37 -22
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +6 -19
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +1 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +28 -156
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +6 -2
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/sql-builder.d.ts.map +1 -1
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createClient } from '@libsql/client';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import { createVectorErrorId,
|
|
3
|
+
import { createVectorErrorId, AgentsStorage, AGENTS_SCHEMA, TABLE_AGENTS, createStorageErrorId, normalizePerPage, calculatePagination, MemoryStorage, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, SPAN_SCHEMA, TABLE_SPANS, listTracesArgsSchema, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, transformScoreRow, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MastraCompositeStore, TraceStatus, getSqlType, safelyParseJSON } from '@mastra/core/storage';
|
|
4
4
|
import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
|
|
5
|
-
import { MastraVector } from '@mastra/core/vector';
|
|
5
|
+
import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
|
|
6
6
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
7
7
|
import { MastraBase } from '@mastra/core/base';
|
|
8
8
|
import { MessageList } from '@mastra/core/agent';
|
|
@@ -242,10 +242,10 @@ var FILTER_OPERATORS = {
|
|
|
242
242
|
};
|
|
243
243
|
},
|
|
244
244
|
// Element Operators
|
|
245
|
-
$exists: (key) => {
|
|
245
|
+
$exists: (key, value) => {
|
|
246
246
|
const jsonPath = getJsonPath(key);
|
|
247
247
|
return {
|
|
248
|
-
sql: `json_extract(metadata, ${jsonPath}) IS NOT NULL`,
|
|
248
|
+
sql: value === false ? `json_extract(metadata, ${jsonPath}) IS NULL` : `json_extract(metadata, ${jsonPath}) IS NOT NULL`,
|
|
249
249
|
needsValue: false
|
|
250
250
|
};
|
|
251
251
|
},
|
|
@@ -509,7 +509,7 @@ var LibSQLVector = class extends MastraVector {
|
|
|
509
509
|
maxRetries;
|
|
510
510
|
initialBackoffMs;
|
|
511
511
|
constructor({
|
|
512
|
-
|
|
512
|
+
url,
|
|
513
513
|
authToken,
|
|
514
514
|
syncUrl,
|
|
515
515
|
syncInterval,
|
|
@@ -519,14 +519,14 @@ var LibSQLVector = class extends MastraVector {
|
|
|
519
519
|
}) {
|
|
520
520
|
super({ id });
|
|
521
521
|
this.turso = createClient({
|
|
522
|
-
url
|
|
522
|
+
url,
|
|
523
523
|
syncUrl,
|
|
524
524
|
authToken,
|
|
525
525
|
syncInterval
|
|
526
526
|
});
|
|
527
527
|
this.maxRetries = maxRetries;
|
|
528
528
|
this.initialBackoffMs = initialBackoffMs;
|
|
529
|
-
if (
|
|
529
|
+
if (url.includes(`file:`) || url.includes(`:memory:`)) {
|
|
530
530
|
this.turso.execute("PRAGMA journal_mode=WAL;").then(() => this.logger.debug("LibSQLStore: PRAGMA journal_mode=WAL set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA journal_mode=WAL.", err));
|
|
531
531
|
this.turso.execute("PRAGMA busy_timeout = 5000;").then(() => this.logger.debug("LibSQLStore: PRAGMA busy_timeout=5000 set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA busy_timeout=5000.", err));
|
|
532
532
|
}
|
|
@@ -538,7 +538,7 @@ var LibSQLVector = class extends MastraVector {
|
|
|
538
538
|
try {
|
|
539
539
|
return await operation();
|
|
540
540
|
} catch (error) {
|
|
541
|
-
if (error.code === "SQLITE_BUSY" || error.message && error.message.toLowerCase().includes("database is locked")) {
|
|
541
|
+
if (error.code === "SQLITE_BUSY" || error.code === "SQLITE_LOCKED" || error.code === "SQLITE_LOCKED_SHAREDCACHE" || error.message && error.message.toLowerCase().includes("database is locked") || error.message && error.message.toLowerCase().includes("database table is locked")) {
|
|
542
542
|
attempts++;
|
|
543
543
|
if (attempts >= this.maxRetries) {
|
|
544
544
|
this.logger.error(
|
|
@@ -572,22 +572,14 @@ var LibSQLVector = class extends MastraVector {
|
|
|
572
572
|
minScore = -1
|
|
573
573
|
// Default to -1 to include all results (cosine similarity ranges from -1 to 1)
|
|
574
574
|
}) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
throw new MastraError(
|
|
584
|
-
{
|
|
585
|
-
id: createVectorErrorId("LIBSQL", "QUERY", "INVALID_ARGS"),
|
|
586
|
-
domain: ErrorDomain.STORAGE,
|
|
587
|
-
category: ErrorCategory.USER
|
|
588
|
-
},
|
|
589
|
-
error
|
|
590
|
-
);
|
|
575
|
+
validateTopK("LIBSQL", topK);
|
|
576
|
+
if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
|
|
577
|
+
throw new MastraError({
|
|
578
|
+
id: createVectorErrorId("LIBSQL", "QUERY", "INVALID_ARGS"),
|
|
579
|
+
domain: ErrorDomain.STORAGE,
|
|
580
|
+
category: ErrorCategory.USER,
|
|
581
|
+
details: { message: "queryVector must be an array of finite numbers" }
|
|
582
|
+
});
|
|
591
583
|
}
|
|
592
584
|
try {
|
|
593
585
|
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
@@ -647,6 +639,7 @@ var LibSQLVector = class extends MastraVector {
|
|
|
647
639
|
}
|
|
648
640
|
}
|
|
649
641
|
async doUpsert({ indexName, vectors, metadata, ids }) {
|
|
642
|
+
validateUpsertInput("LIBSQL", vectors, metadata, ids);
|
|
650
643
|
const tx = await this.turso.transaction("write");
|
|
651
644
|
try {
|
|
652
645
|
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
@@ -1093,6 +1086,14 @@ var LibSQLVector = class extends MastraVector {
|
|
|
1093
1086
|
});
|
|
1094
1087
|
}
|
|
1095
1088
|
};
|
|
1089
|
+
function buildSelectColumns(tableName) {
|
|
1090
|
+
const schema = TABLE_SCHEMAS[tableName];
|
|
1091
|
+
return Object.keys(schema).map((col) => {
|
|
1092
|
+
const colDef = schema[col];
|
|
1093
|
+
const parsedCol = parseSqlIdentifier(col, "column name");
|
|
1094
|
+
return colDef?.type === "jsonb" ? `json(${parsedCol}) as ${parsedCol}` : parsedCol;
|
|
1095
|
+
}).join(", ");
|
|
1096
|
+
}
|
|
1096
1097
|
function isLockError(error) {
|
|
1097
1098
|
return error.code === "SQLITE_BUSY" || error.code === "SQLITE_LOCKED" || error.message?.toLowerCase().includes("database is locked") || error.message?.toLowerCase().includes("database table is locked") || error.message?.toLowerCase().includes("table is locked") || error.constructor.name === "SqliteError" && error.message?.toLowerCase().includes("locked");
|
|
1098
1099
|
}
|
|
@@ -1141,17 +1142,27 @@ function createExecuteWriteOperationWithRetry({
|
|
|
1141
1142
|
}
|
|
1142
1143
|
function prepareStatement({ tableName, record }) {
|
|
1143
1144
|
const parsedTableName = parseSqlIdentifier(tableName, "table name");
|
|
1144
|
-
const
|
|
1145
|
-
const
|
|
1145
|
+
const schema = TABLE_SCHEMAS[tableName];
|
|
1146
|
+
const columnNames = Object.keys(record);
|
|
1147
|
+
const columns = columnNames.map((col) => parseSqlIdentifier(col, "column name"));
|
|
1148
|
+
const values = columnNames.map((col) => {
|
|
1149
|
+
const v = record[col];
|
|
1146
1150
|
if (typeof v === `undefined` || v === null) {
|
|
1147
1151
|
return null;
|
|
1148
1152
|
}
|
|
1153
|
+
const colDef = schema[col];
|
|
1154
|
+
if (colDef?.type === "jsonb") {
|
|
1155
|
+
return JSON.stringify(v);
|
|
1156
|
+
}
|
|
1149
1157
|
if (v instanceof Date) {
|
|
1150
1158
|
return v.toISOString();
|
|
1151
1159
|
}
|
|
1152
1160
|
return typeof v === "object" ? JSON.stringify(v) : v;
|
|
1153
1161
|
});
|
|
1154
|
-
const placeholders =
|
|
1162
|
+
const placeholders = columnNames.map((col) => {
|
|
1163
|
+
const colDef = schema[col];
|
|
1164
|
+
return colDef?.type === "jsonb" ? "jsonb(?)" : "?";
|
|
1165
|
+
}).join(", ");
|
|
1155
1166
|
return {
|
|
1156
1167
|
sql: `INSERT OR REPLACE INTO ${parsedTableName} (${columns.join(", ")}) VALUES (${placeholders})`,
|
|
1157
1168
|
args: values
|
|
@@ -1164,19 +1175,33 @@ function prepareUpdateStatement({
|
|
|
1164
1175
|
}) {
|
|
1165
1176
|
const parsedTableName = parseSqlIdentifier(tableName, "table name");
|
|
1166
1177
|
const schema = TABLE_SCHEMAS[tableName];
|
|
1167
|
-
const
|
|
1168
|
-
const
|
|
1169
|
-
const
|
|
1178
|
+
const updateColumnNames = Object.keys(updates);
|
|
1179
|
+
const updateColumns = updateColumnNames.map((col) => parseSqlIdentifier(col, "column name"));
|
|
1180
|
+
const updateValues = updateColumnNames.map((col) => {
|
|
1181
|
+
const colDef = schema[col];
|
|
1182
|
+
const v = updates[col];
|
|
1183
|
+
if (colDef?.type === "jsonb") {
|
|
1184
|
+
return transformToSqlValue(v, true);
|
|
1185
|
+
}
|
|
1186
|
+
return transformToSqlValue(v, false);
|
|
1187
|
+
});
|
|
1188
|
+
const setClause = updateColumns.map((col, i) => {
|
|
1189
|
+
const colDef = schema[updateColumnNames[i]];
|
|
1190
|
+
return colDef?.type === "jsonb" ? `${col} = jsonb(?)` : `${col} = ?`;
|
|
1191
|
+
}).join(", ");
|
|
1170
1192
|
const whereClause = prepareWhereClause(keys, schema);
|
|
1171
1193
|
return {
|
|
1172
1194
|
sql: `UPDATE ${parsedTableName} SET ${setClause}${whereClause.sql}`,
|
|
1173
1195
|
args: [...updateValues, ...whereClause.args]
|
|
1174
1196
|
};
|
|
1175
1197
|
}
|
|
1176
|
-
function transformToSqlValue(value) {
|
|
1198
|
+
function transformToSqlValue(value, forceJsonStringify = false) {
|
|
1177
1199
|
if (typeof value === "undefined" || value === null) {
|
|
1178
1200
|
return null;
|
|
1179
1201
|
}
|
|
1202
|
+
if (forceJsonStringify) {
|
|
1203
|
+
return JSON.stringify(value);
|
|
1204
|
+
}
|
|
1180
1205
|
if (value instanceof Date) {
|
|
1181
1206
|
return value.toISOString();
|
|
1182
1207
|
}
|
|
@@ -1239,19 +1264,6 @@ function buildDateRangeCondition(columnName, range) {
|
|
|
1239
1264
|
args
|
|
1240
1265
|
};
|
|
1241
1266
|
}
|
|
1242
|
-
function buildDateRangeFilter(dateRange, columnName = "createdAt") {
|
|
1243
|
-
if (!dateRange?.start && !dateRange?.end) {
|
|
1244
|
-
return {};
|
|
1245
|
-
}
|
|
1246
|
-
const filter = {};
|
|
1247
|
-
if (dateRange.start) {
|
|
1248
|
-
filter.startAt = new Date(dateRange.start).toISOString();
|
|
1249
|
-
}
|
|
1250
|
-
if (dateRange.end) {
|
|
1251
|
-
filter.endAt = new Date(dateRange.end).toISOString();
|
|
1252
|
-
}
|
|
1253
|
-
return { [columnName]: filter };
|
|
1254
|
-
}
|
|
1255
1267
|
function transformFromSqlRow({
|
|
1256
1268
|
tableName,
|
|
1257
1269
|
sqlRow
|
|
@@ -1546,11 +1558,12 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1546
1558
|
*/
|
|
1547
1559
|
async select({ tableName, keys }) {
|
|
1548
1560
|
const parsedTableName = parseSqlIdentifier(tableName, "table name");
|
|
1561
|
+
const columns = buildSelectColumns(tableName);
|
|
1549
1562
|
const parsedKeys = Object.keys(keys).map((key) => parseSqlIdentifier(key, "column name"));
|
|
1550
1563
|
const conditions = parsedKeys.map((key) => `${key} = ?`).join(" AND ");
|
|
1551
1564
|
const values = Object.values(keys);
|
|
1552
1565
|
const result = await this.client.execute({
|
|
1553
|
-
sql: `SELECT
|
|
1566
|
+
sql: `SELECT ${columns} FROM ${parsedTableName} WHERE ${conditions} ORDER BY createdAt DESC LIMIT 1`,
|
|
1554
1567
|
args: values
|
|
1555
1568
|
});
|
|
1556
1569
|
if (!result.rows || result.rows.length === 0) {
|
|
@@ -1590,9 +1603,10 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1590
1603
|
args
|
|
1591
1604
|
}) {
|
|
1592
1605
|
const parsedTableName = parseSqlIdentifier(tableName, "table name");
|
|
1593
|
-
|
|
1606
|
+
const columns = buildSelectColumns(tableName);
|
|
1607
|
+
let statement = `SELECT ${columns} FROM ${parsedTableName}`;
|
|
1594
1608
|
if (whereClause?.sql) {
|
|
1595
|
-
statement +=
|
|
1609
|
+
statement += ` ${whereClause.sql}`;
|
|
1596
1610
|
}
|
|
1597
1611
|
if (orderBy) {
|
|
1598
1612
|
statement += ` ORDER BY ${orderBy}`;
|
|
@@ -1607,7 +1621,17 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1607
1621
|
sql: statement,
|
|
1608
1622
|
args: [...whereClause?.args ?? [], ...args ?? []]
|
|
1609
1623
|
});
|
|
1610
|
-
return result.rows
|
|
1624
|
+
return (result.rows ?? []).map((row) => {
|
|
1625
|
+
return Object.fromEntries(
|
|
1626
|
+
Object.entries(row || {}).map(([k, v]) => {
|
|
1627
|
+
try {
|
|
1628
|
+
return [k, typeof v === "string" ? v.startsWith("{") || v.startsWith("[") ? JSON.parse(v) : v : v];
|
|
1629
|
+
} catch {
|
|
1630
|
+
return [k, v];
|
|
1631
|
+
}
|
|
1632
|
+
})
|
|
1633
|
+
);
|
|
1634
|
+
});
|
|
1611
1635
|
}
|
|
1612
1636
|
/**
|
|
1613
1637
|
* Returns the total count of records matching the optional WHERE clause.
|
|
@@ -1651,7 +1675,7 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1651
1675
|
// SQLite uses 0/1 for booleans
|
|
1652
1676
|
case "jsonb":
|
|
1653
1677
|
return "TEXT";
|
|
1654
|
-
//
|
|
1678
|
+
// SQLite: column stores TEXT, we use jsonb()/json() functions for binary optimization
|
|
1655
1679
|
default:
|
|
1656
1680
|
return getSqlType(type);
|
|
1657
1681
|
}
|
|
@@ -1679,13 +1703,22 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1679
1703
|
if (tableName === TABLE_WORKFLOW_SNAPSHOT) {
|
|
1680
1704
|
tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
1681
1705
|
}
|
|
1706
|
+
if (tableName === TABLE_SPANS) {
|
|
1707
|
+
tableConstraints.push("UNIQUE (spanId, traceId)");
|
|
1708
|
+
}
|
|
1682
1709
|
const allDefinitions = [...columnDefinitions, ...tableConstraints].join(",\n ");
|
|
1683
1710
|
const sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (
|
|
1684
1711
|
${allDefinitions}
|
|
1685
1712
|
)`;
|
|
1686
1713
|
await this.client.execute(sql);
|
|
1687
1714
|
this.logger.debug(`LibSQLDB: Created table ${tableName}`);
|
|
1715
|
+
if (tableName === TABLE_SPANS) {
|
|
1716
|
+
await this.migrateSpansTable();
|
|
1717
|
+
}
|
|
1688
1718
|
} catch (error) {
|
|
1719
|
+
if (error instanceof MastraError) {
|
|
1720
|
+
throw error;
|
|
1721
|
+
}
|
|
1689
1722
|
throw new MastraError(
|
|
1690
1723
|
{
|
|
1691
1724
|
id: createStorageErrorId("LIBSQL", "CREATE_TABLE", "FAILED"),
|
|
@@ -1697,6 +1730,221 @@ var LibSQLDB = class extends MastraBase {
|
|
|
1697
1730
|
);
|
|
1698
1731
|
}
|
|
1699
1732
|
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Migrates the spans table schema from OLD_SPAN_SCHEMA to current SPAN_SCHEMA.
|
|
1735
|
+
* This adds new columns that don't exist in old schema and ensures required indexes exist.
|
|
1736
|
+
*/
|
|
1737
|
+
async migrateSpansTable() {
|
|
1738
|
+
const schema = TABLE_SCHEMAS[TABLE_SPANS];
|
|
1739
|
+
try {
|
|
1740
|
+
for (const [columnName, columnDef] of Object.entries(schema)) {
|
|
1741
|
+
const columnExists = await this.hasColumn(TABLE_SPANS, columnName);
|
|
1742
|
+
if (!columnExists) {
|
|
1743
|
+
const sqlType = this.getSqlType(columnDef.type);
|
|
1744
|
+
const alterSql = `ALTER TABLE "${TABLE_SPANS}" ADD COLUMN "${columnName}" ${sqlType}`;
|
|
1745
|
+
await this.client.execute(alterSql);
|
|
1746
|
+
this.logger.debug(`LibSQLDB: Added column '${columnName}' to ${TABLE_SPANS}`);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
const indexExists = await this.spansUniqueIndexExists();
|
|
1750
|
+
if (!indexExists) {
|
|
1751
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
1752
|
+
if (duplicateInfo.hasDuplicates) {
|
|
1753
|
+
const errorMessage = `
|
|
1754
|
+
===========================================================================
|
|
1755
|
+
MIGRATION REQUIRED: Duplicate spans detected in ${TABLE_SPANS}
|
|
1756
|
+
===========================================================================
|
|
1757
|
+
|
|
1758
|
+
Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations.
|
|
1759
|
+
|
|
1760
|
+
The spans table requires a unique constraint on (traceId, spanId), but your
|
|
1761
|
+
database contains duplicate entries that must be resolved first.
|
|
1762
|
+
|
|
1763
|
+
To fix this, run the manual migration command:
|
|
1764
|
+
|
|
1765
|
+
npx mastra migrate
|
|
1766
|
+
|
|
1767
|
+
This command will:
|
|
1768
|
+
1. Remove duplicate spans (keeping the most complete/recent version)
|
|
1769
|
+
2. Add the required unique constraint
|
|
1770
|
+
|
|
1771
|
+
Note: This migration may take some time for large tables.
|
|
1772
|
+
===========================================================================
|
|
1773
|
+
`;
|
|
1774
|
+
throw new MastraError({
|
|
1775
|
+
id: createStorageErrorId("LIBSQL", "MIGRATION_REQUIRED", "DUPLICATE_SPANS"),
|
|
1776
|
+
domain: ErrorDomain.STORAGE,
|
|
1777
|
+
category: ErrorCategory.USER,
|
|
1778
|
+
text: errorMessage
|
|
1779
|
+
});
|
|
1780
|
+
} else {
|
|
1781
|
+
await this.client.execute(
|
|
1782
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS "mastra_ai_spans_spanid_traceid_idx" ON "${TABLE_SPANS}" ("spanId", "traceId")`
|
|
1783
|
+
);
|
|
1784
|
+
this.logger.debug(`LibSQLDB: Created unique index on (spanId, traceId) for ${TABLE_SPANS}`);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
this.logger.info(`LibSQLDB: Migration completed for ${TABLE_SPANS}`);
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
if (error instanceof MastraError) {
|
|
1790
|
+
throw error;
|
|
1791
|
+
}
|
|
1792
|
+
this.logger.warn(`LibSQLDB: Failed to migrate spans table ${TABLE_SPANS}:`, error);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* Checks if the unique index on (spanId, traceId) already exists on the spans table.
|
|
1797
|
+
* Used to skip deduplication when the index already exists (migration already complete).
|
|
1798
|
+
*/
|
|
1799
|
+
async spansUniqueIndexExists() {
|
|
1800
|
+
try {
|
|
1801
|
+
const result = await this.client.execute(
|
|
1802
|
+
`SELECT 1 FROM sqlite_master WHERE type = 'index' AND name = 'mastra_ai_spans_spanid_traceid_idx'`
|
|
1803
|
+
);
|
|
1804
|
+
return (result.rows?.length ?? 0) > 0;
|
|
1805
|
+
} catch {
|
|
1806
|
+
return false;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
/**
|
|
1810
|
+
* Checks for duplicate (traceId, spanId) combinations in the spans table.
|
|
1811
|
+
* Returns information about duplicates for logging/CLI purposes.
|
|
1812
|
+
*/
|
|
1813
|
+
async checkForDuplicateSpans() {
|
|
1814
|
+
try {
|
|
1815
|
+
const result = await this.client.execute(`
|
|
1816
|
+
SELECT COUNT(*) as duplicate_count FROM (
|
|
1817
|
+
SELECT "spanId", "traceId"
|
|
1818
|
+
FROM "${TABLE_SPANS}"
|
|
1819
|
+
GROUP BY "spanId", "traceId"
|
|
1820
|
+
HAVING COUNT(*) > 1
|
|
1821
|
+
)
|
|
1822
|
+
`);
|
|
1823
|
+
const duplicateCount = Number(result.rows?.[0]?.duplicate_count ?? 0);
|
|
1824
|
+
return {
|
|
1825
|
+
hasDuplicates: duplicateCount > 0,
|
|
1826
|
+
duplicateCount
|
|
1827
|
+
};
|
|
1828
|
+
} catch (error) {
|
|
1829
|
+
this.logger.debug(`LibSQLDB: Could not check for duplicates: ${error}`);
|
|
1830
|
+
return { hasDuplicates: false, duplicateCount: 0 };
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Manually run the spans migration to deduplicate and add the unique constraint.
|
|
1835
|
+
* This is intended to be called from the CLI when duplicates are detected.
|
|
1836
|
+
*
|
|
1837
|
+
* @returns Migration result with status and details
|
|
1838
|
+
*/
|
|
1839
|
+
async migrateSpans() {
|
|
1840
|
+
const indexExists = await this.spansUniqueIndexExists();
|
|
1841
|
+
if (indexExists) {
|
|
1842
|
+
return {
|
|
1843
|
+
success: true,
|
|
1844
|
+
alreadyMigrated: true,
|
|
1845
|
+
duplicatesRemoved: 0,
|
|
1846
|
+
message: `Migration already complete. Unique index exists on ${TABLE_SPANS}.`
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
1850
|
+
if (duplicateInfo.hasDuplicates) {
|
|
1851
|
+
this.logger.info(
|
|
1852
|
+
`Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations. Starting deduplication...`
|
|
1853
|
+
);
|
|
1854
|
+
await this.deduplicateSpans();
|
|
1855
|
+
} else {
|
|
1856
|
+
this.logger.info(`No duplicate spans found.`);
|
|
1857
|
+
}
|
|
1858
|
+
await this.client.execute(
|
|
1859
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS "mastra_ai_spans_spanid_traceid_idx" ON "${TABLE_SPANS}" ("spanId", "traceId")`
|
|
1860
|
+
);
|
|
1861
|
+
return {
|
|
1862
|
+
success: true,
|
|
1863
|
+
alreadyMigrated: false,
|
|
1864
|
+
duplicatesRemoved: duplicateInfo.duplicateCount,
|
|
1865
|
+
message: duplicateInfo.hasDuplicates ? `Migration complete. Removed duplicates and added unique index to ${TABLE_SPANS}.` : `Migration complete. Added unique index to ${TABLE_SPANS}.`
|
|
1866
|
+
};
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Check migration status for the spans table.
|
|
1870
|
+
* Returns information about whether migration is needed.
|
|
1871
|
+
*/
|
|
1872
|
+
async checkSpansMigrationStatus() {
|
|
1873
|
+
const indexExists = await this.spansUniqueIndexExists();
|
|
1874
|
+
if (indexExists) {
|
|
1875
|
+
return {
|
|
1876
|
+
needsMigration: false,
|
|
1877
|
+
hasDuplicates: false,
|
|
1878
|
+
duplicateCount: 0,
|
|
1879
|
+
constraintExists: true,
|
|
1880
|
+
tableName: TABLE_SPANS
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
1884
|
+
return {
|
|
1885
|
+
needsMigration: true,
|
|
1886
|
+
hasDuplicates: duplicateInfo.hasDuplicates,
|
|
1887
|
+
duplicateCount: duplicateInfo.duplicateCount,
|
|
1888
|
+
constraintExists: false,
|
|
1889
|
+
tableName: TABLE_SPANS
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Deduplicates spans table by removing duplicate (spanId, traceId) combinations.
|
|
1894
|
+
* Keeps the "best" record for each duplicate group based on:
|
|
1895
|
+
* 1. Completed spans (endedAt IS NOT NULL) over incomplete ones
|
|
1896
|
+
* 2. Most recently updated (updatedAt DESC)
|
|
1897
|
+
* 3. Most recently created (createdAt DESC) as tiebreaker
|
|
1898
|
+
*/
|
|
1899
|
+
async deduplicateSpans() {
|
|
1900
|
+
try {
|
|
1901
|
+
const duplicateCheck = await this.client.execute(`
|
|
1902
|
+
SELECT COUNT(*) as duplicate_count FROM (
|
|
1903
|
+
SELECT "spanId", "traceId"
|
|
1904
|
+
FROM "${TABLE_SPANS}"
|
|
1905
|
+
GROUP BY "spanId", "traceId"
|
|
1906
|
+
HAVING COUNT(*) > 1
|
|
1907
|
+
)
|
|
1908
|
+
`);
|
|
1909
|
+
const duplicateCount = Number(duplicateCheck.rows?.[0]?.duplicate_count ?? 0);
|
|
1910
|
+
if (duplicateCount === 0) {
|
|
1911
|
+
this.logger.debug(`LibSQLDB: No duplicate spans found, skipping deduplication`);
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
this.logger.warn(`LibSQLDB: Found ${duplicateCount} duplicate (spanId, traceId) combinations, deduplicating...`);
|
|
1915
|
+
const deleteResult = await this.client.execute(`
|
|
1916
|
+
DELETE FROM "${TABLE_SPANS}"
|
|
1917
|
+
WHERE rowid NOT IN (
|
|
1918
|
+
SELECT MIN(best_rowid) FROM (
|
|
1919
|
+
SELECT
|
|
1920
|
+
rowid as best_rowid,
|
|
1921
|
+
"spanId",
|
|
1922
|
+
"traceId",
|
|
1923
|
+
ROW_NUMBER() OVER (
|
|
1924
|
+
PARTITION BY "spanId", "traceId"
|
|
1925
|
+
ORDER BY
|
|
1926
|
+
CASE WHEN "endedAt" IS NOT NULL THEN 0 ELSE 1 END,
|
|
1927
|
+
"updatedAt" DESC,
|
|
1928
|
+
"createdAt" DESC
|
|
1929
|
+
) as rn
|
|
1930
|
+
FROM "${TABLE_SPANS}"
|
|
1931
|
+
) ranked
|
|
1932
|
+
WHERE rn = 1
|
|
1933
|
+
GROUP BY "spanId", "traceId"
|
|
1934
|
+
)
|
|
1935
|
+
AND ("spanId", "traceId") IN (
|
|
1936
|
+
SELECT "spanId", "traceId"
|
|
1937
|
+
FROM "${TABLE_SPANS}"
|
|
1938
|
+
GROUP BY "spanId", "traceId"
|
|
1939
|
+
HAVING COUNT(*) > 1
|
|
1940
|
+
)
|
|
1941
|
+
`);
|
|
1942
|
+
const deletedCount = deleteResult.rowsAffected ?? 0;
|
|
1943
|
+
this.logger.warn(`LibSQLDB: Deleted ${deletedCount} duplicate span records`);
|
|
1944
|
+
} catch (error) {
|
|
1945
|
+
this.logger.warn(`LibSQLDB: Failed to deduplicate spans:`, error);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1700
1948
|
/**
|
|
1701
1949
|
* Gets a default value for a column type (used when adding NOT NULL columns).
|
|
1702
1950
|
*/
|
|
@@ -2199,13 +2447,15 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2199
2447
|
queryParams.push(resourceId);
|
|
2200
2448
|
}
|
|
2201
2449
|
if (filter?.dateRange?.start) {
|
|
2202
|
-
|
|
2450
|
+
const startOp = filter.dateRange.startExclusive ? ">" : ">=";
|
|
2451
|
+
conditions.push(`"createdAt" ${startOp} ?`);
|
|
2203
2452
|
queryParams.push(
|
|
2204
2453
|
filter.dateRange.start instanceof Date ? filter.dateRange.start.toISOString() : filter.dateRange.start
|
|
2205
2454
|
);
|
|
2206
2455
|
}
|
|
2207
2456
|
if (filter?.dateRange?.end) {
|
|
2208
|
-
|
|
2457
|
+
const endOp = filter.dateRange.endExclusive ? "<" : "<=";
|
|
2458
|
+
conditions.push(`"createdAt" ${endOp} ?`);
|
|
2209
2459
|
queryParams.push(
|
|
2210
2460
|
filter.dateRange.end instanceof Date ? filter.dateRange.end.toISOString() : filter.dateRange.end
|
|
2211
2461
|
);
|
|
@@ -2511,8 +2761,8 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2511
2761
|
await this.#db.insert({
|
|
2512
2762
|
tableName: TABLE_RESOURCES,
|
|
2513
2763
|
record: {
|
|
2514
|
-
...resource
|
|
2515
|
-
metadata
|
|
2764
|
+
...resource
|
|
2765
|
+
// metadata is handled by prepareStatement which stringifies jsonb columns
|
|
2516
2766
|
}
|
|
2517
2767
|
});
|
|
2518
2768
|
return resource;
|
|
@@ -2549,7 +2799,7 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2549
2799
|
values.push(workingMemory);
|
|
2550
2800
|
}
|
|
2551
2801
|
if (metadata) {
|
|
2552
|
-
updates.push("metadata = ?");
|
|
2802
|
+
updates.push("metadata = jsonb(?)");
|
|
2553
2803
|
values.push(JSON.stringify(updatedResource.metadata));
|
|
2554
2804
|
}
|
|
2555
2805
|
updates.push("updatedAt = ?");
|
|
@@ -2588,33 +2838,76 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2588
2838
|
);
|
|
2589
2839
|
}
|
|
2590
2840
|
}
|
|
2591
|
-
async
|
|
2592
|
-
const {
|
|
2593
|
-
|
|
2841
|
+
async listThreads(args) {
|
|
2842
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
2843
|
+
try {
|
|
2844
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
2845
|
+
} catch (error) {
|
|
2594
2846
|
throw new MastraError(
|
|
2595
2847
|
{
|
|
2596
|
-
id: createStorageErrorId("LIBSQL", "
|
|
2848
|
+
id: createStorageErrorId("LIBSQL", "LIST_THREADS", "INVALID_PAGE"),
|
|
2597
2849
|
domain: ErrorDomain.STORAGE,
|
|
2598
2850
|
category: ErrorCategory.USER,
|
|
2599
|
-
details: { page }
|
|
2851
|
+
details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
|
|
2600
2852
|
},
|
|
2601
|
-
new Error("
|
|
2853
|
+
error instanceof Error ? error : new Error("Invalid pagination parameters")
|
|
2602
2854
|
);
|
|
2603
2855
|
}
|
|
2604
2856
|
const perPage = normalizePerPage(perPageInput, 100);
|
|
2857
|
+
try {
|
|
2858
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
2859
|
+
} catch (error) {
|
|
2860
|
+
throw new MastraError(
|
|
2861
|
+
{
|
|
2862
|
+
id: createStorageErrorId("LIBSQL", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
2863
|
+
domain: ErrorDomain.STORAGE,
|
|
2864
|
+
category: ErrorCategory.USER,
|
|
2865
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
2866
|
+
},
|
|
2867
|
+
error instanceof Error ? error : new Error("Invalid metadata key")
|
|
2868
|
+
);
|
|
2869
|
+
}
|
|
2605
2870
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
2606
2871
|
const { field, direction } = this.parseOrderBy(orderBy);
|
|
2607
2872
|
try {
|
|
2608
|
-
const
|
|
2609
|
-
const queryParams = [
|
|
2873
|
+
const whereClauses = [];
|
|
2874
|
+
const queryParams = [];
|
|
2875
|
+
if (filter?.resourceId) {
|
|
2876
|
+
whereClauses.push("resourceId = ?");
|
|
2877
|
+
queryParams.push(filter.resourceId);
|
|
2878
|
+
}
|
|
2879
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
2880
|
+
for (const [key, value] of Object.entries(filter.metadata)) {
|
|
2881
|
+
if (value === null) {
|
|
2882
|
+
whereClauses.push(`json_extract(metadata, '$.${key}') IS NULL`);
|
|
2883
|
+
} else if (typeof value === "boolean") {
|
|
2884
|
+
whereClauses.push(`json_extract(metadata, '$.${key}') = ?`);
|
|
2885
|
+
queryParams.push(value ? 1 : 0);
|
|
2886
|
+
} else if (typeof value === "number") {
|
|
2887
|
+
whereClauses.push(`json_extract(metadata, '$.${key}') = ?`);
|
|
2888
|
+
queryParams.push(value);
|
|
2889
|
+
} else if (typeof value === "string") {
|
|
2890
|
+
whereClauses.push(`json_extract(metadata, '$.${key}') = ?`);
|
|
2891
|
+
queryParams.push(value);
|
|
2892
|
+
} else {
|
|
2893
|
+
throw new MastraError({
|
|
2894
|
+
id: createStorageErrorId("LIBSQL", "LIST_THREADS", "INVALID_METADATA_VALUE"),
|
|
2895
|
+
domain: ErrorDomain.STORAGE,
|
|
2896
|
+
category: ErrorCategory.USER,
|
|
2897
|
+
text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${typeof value}`,
|
|
2898
|
+
details: { key, valueType: typeof value }
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
2904
|
+
const baseQuery = `FROM ${TABLE_THREADS} ${whereClause}`;
|
|
2610
2905
|
const mapRowToStorageThreadType = (row) => ({
|
|
2611
2906
|
id: row.id,
|
|
2612
2907
|
resourceId: row.resourceId,
|
|
2613
2908
|
title: row.title,
|
|
2614
2909
|
createdAt: new Date(row.createdAt),
|
|
2615
|
-
// Convert string to Date
|
|
2616
2910
|
updatedAt: new Date(row.updatedAt),
|
|
2617
|
-
// Convert string to Date
|
|
2618
2911
|
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata
|
|
2619
2912
|
});
|
|
2620
2913
|
const countResult = await this.#client.execute({
|
|
@@ -2633,7 +2926,7 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2633
2926
|
}
|
|
2634
2927
|
const limitValue = perPageInput === false ? total : perPage;
|
|
2635
2928
|
const dataResult = await this.#client.execute({
|
|
2636
|
-
sql: `SELECT
|
|
2929
|
+
sql: `SELECT ${buildSelectColumns(TABLE_THREADS)} ${baseQuery} ORDER BY "${field}" ${direction} LIMIT ? OFFSET ?`,
|
|
2637
2930
|
args: [...queryParams, limitValue, offset]
|
|
2638
2931
|
});
|
|
2639
2932
|
const threads = (dataResult.rows || []).map(mapRowToStorageThreadType);
|
|
@@ -2645,12 +2938,18 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2645
2938
|
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
2646
2939
|
};
|
|
2647
2940
|
} catch (error) {
|
|
2941
|
+
if (error instanceof MastraError && error.category === ErrorCategory.USER) {
|
|
2942
|
+
throw error;
|
|
2943
|
+
}
|
|
2648
2944
|
const mastraError = new MastraError(
|
|
2649
2945
|
{
|
|
2650
|
-
id: createStorageErrorId("LIBSQL", "
|
|
2946
|
+
id: createStorageErrorId("LIBSQL", "LIST_THREADS", "FAILED"),
|
|
2651
2947
|
domain: ErrorDomain.STORAGE,
|
|
2652
2948
|
category: ErrorCategory.THIRD_PARTY,
|
|
2653
|
-
details: {
|
|
2949
|
+
details: {
|
|
2950
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
2951
|
+
hasMetadataFilter: !!filter?.metadata
|
|
2952
|
+
}
|
|
2654
2953
|
},
|
|
2655
2954
|
error
|
|
2656
2955
|
);
|
|
@@ -2670,8 +2969,8 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2670
2969
|
await this.#db.insert({
|
|
2671
2970
|
tableName: TABLE_THREADS,
|
|
2672
2971
|
record: {
|
|
2673
|
-
...thread
|
|
2674
|
-
metadata
|
|
2972
|
+
...thread
|
|
2973
|
+
// metadata is handled by prepareStatement which stringifies jsonb columns
|
|
2675
2974
|
}
|
|
2676
2975
|
});
|
|
2677
2976
|
return thread;
|
|
@@ -2718,7 +3017,7 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2718
3017
|
};
|
|
2719
3018
|
try {
|
|
2720
3019
|
await this.#client.execute({
|
|
2721
|
-
sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
|
|
3020
|
+
sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = jsonb(?) WHERE id = ?`,
|
|
2722
3021
|
args: [title, JSON.stringify(updatedThread.metadata), id]
|
|
2723
3022
|
});
|
|
2724
3023
|
return updatedThread;
|
|
@@ -2757,6 +3056,148 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2757
3056
|
);
|
|
2758
3057
|
}
|
|
2759
3058
|
}
|
|
3059
|
+
async cloneThread(args) {
|
|
3060
|
+
const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
|
|
3061
|
+
const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
|
|
3062
|
+
if (!sourceThread) {
|
|
3063
|
+
throw new MastraError({
|
|
3064
|
+
id: createStorageErrorId("LIBSQL", "CLONE_THREAD", "SOURCE_NOT_FOUND"),
|
|
3065
|
+
domain: ErrorDomain.STORAGE,
|
|
3066
|
+
category: ErrorCategory.USER,
|
|
3067
|
+
text: `Source thread with id ${sourceThreadId} not found`,
|
|
3068
|
+
details: { sourceThreadId }
|
|
3069
|
+
});
|
|
3070
|
+
}
|
|
3071
|
+
const newThreadId = providedThreadId || crypto.randomUUID();
|
|
3072
|
+
const existingThread = await this.getThreadById({ threadId: newThreadId });
|
|
3073
|
+
if (existingThread) {
|
|
3074
|
+
throw new MastraError({
|
|
3075
|
+
id: createStorageErrorId("LIBSQL", "CLONE_THREAD", "THREAD_EXISTS"),
|
|
3076
|
+
domain: ErrorDomain.STORAGE,
|
|
3077
|
+
category: ErrorCategory.USER,
|
|
3078
|
+
text: `Thread with id ${newThreadId} already exists`,
|
|
3079
|
+
details: { newThreadId }
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
try {
|
|
3083
|
+
let messageQuery = `SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
|
|
3084
|
+
FROM "${TABLE_MESSAGES}" WHERE thread_id = ?`;
|
|
3085
|
+
const messageParams = [sourceThreadId];
|
|
3086
|
+
if (options?.messageFilter?.startDate) {
|
|
3087
|
+
messageQuery += ` AND "createdAt" >= ?`;
|
|
3088
|
+
messageParams.push(
|
|
3089
|
+
options.messageFilter.startDate instanceof Date ? options.messageFilter.startDate.toISOString() : options.messageFilter.startDate
|
|
3090
|
+
);
|
|
3091
|
+
}
|
|
3092
|
+
if (options?.messageFilter?.endDate) {
|
|
3093
|
+
messageQuery += ` AND "createdAt" <= ?`;
|
|
3094
|
+
messageParams.push(
|
|
3095
|
+
options.messageFilter.endDate instanceof Date ? options.messageFilter.endDate.toISOString() : options.messageFilter.endDate
|
|
3096
|
+
);
|
|
3097
|
+
}
|
|
3098
|
+
if (options?.messageFilter?.messageIds && options.messageFilter.messageIds.length > 0) {
|
|
3099
|
+
messageQuery += ` AND id IN (${options.messageFilter.messageIds.map(() => "?").join(", ")})`;
|
|
3100
|
+
messageParams.push(...options.messageFilter.messageIds);
|
|
3101
|
+
}
|
|
3102
|
+
messageQuery += ` ORDER BY "createdAt" ASC`;
|
|
3103
|
+
if (options?.messageLimit && options.messageLimit > 0) {
|
|
3104
|
+
const limitQuery = `SELECT * FROM (${messageQuery.replace('ORDER BY "createdAt" ASC', 'ORDER BY "createdAt" DESC')} LIMIT ?) ORDER BY "createdAt" ASC`;
|
|
3105
|
+
messageParams.push(options.messageLimit);
|
|
3106
|
+
messageQuery = limitQuery;
|
|
3107
|
+
}
|
|
3108
|
+
const sourceMessagesResult = await this.#client.execute({ sql: messageQuery, args: messageParams });
|
|
3109
|
+
const sourceMessages = sourceMessagesResult.rows || [];
|
|
3110
|
+
const now = /* @__PURE__ */ new Date();
|
|
3111
|
+
const nowStr = now.toISOString();
|
|
3112
|
+
const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1].id : void 0;
|
|
3113
|
+
const cloneMetadata = {
|
|
3114
|
+
sourceThreadId,
|
|
3115
|
+
clonedAt: now,
|
|
3116
|
+
...lastMessageId && { lastMessageId }
|
|
3117
|
+
};
|
|
3118
|
+
const newThread = {
|
|
3119
|
+
id: newThreadId,
|
|
3120
|
+
resourceId: resourceId || sourceThread.resourceId,
|
|
3121
|
+
title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : void 0),
|
|
3122
|
+
metadata: {
|
|
3123
|
+
...metadata,
|
|
3124
|
+
clone: cloneMetadata
|
|
3125
|
+
},
|
|
3126
|
+
createdAt: now,
|
|
3127
|
+
updatedAt: now
|
|
3128
|
+
};
|
|
3129
|
+
const tx = await this.#client.transaction("write");
|
|
3130
|
+
try {
|
|
3131
|
+
await tx.execute({
|
|
3132
|
+
sql: `INSERT INTO "${TABLE_THREADS}" (id, "resourceId", title, metadata, "createdAt", "updatedAt")
|
|
3133
|
+
VALUES (?, ?, ?, jsonb(?), ?, ?)`,
|
|
3134
|
+
args: [
|
|
3135
|
+
newThread.id,
|
|
3136
|
+
newThread.resourceId,
|
|
3137
|
+
newThread.title || null,
|
|
3138
|
+
JSON.stringify(newThread.metadata),
|
|
3139
|
+
nowStr,
|
|
3140
|
+
nowStr
|
|
3141
|
+
]
|
|
3142
|
+
});
|
|
3143
|
+
const clonedMessages = [];
|
|
3144
|
+
const targetResourceId = resourceId || sourceThread.resourceId;
|
|
3145
|
+
for (const sourceMsg of sourceMessages) {
|
|
3146
|
+
const newMessageId = crypto.randomUUID();
|
|
3147
|
+
const contentStr = sourceMsg.content;
|
|
3148
|
+
let parsedContent;
|
|
3149
|
+
try {
|
|
3150
|
+
parsedContent = JSON.parse(contentStr);
|
|
3151
|
+
} catch {
|
|
3152
|
+
parsedContent = { format: 2, parts: [{ type: "text", text: contentStr }] };
|
|
3153
|
+
}
|
|
3154
|
+
await tx.execute({
|
|
3155
|
+
sql: `INSERT INTO "${TABLE_MESSAGES}" (id, thread_id, content, role, type, "createdAt", "resourceId")
|
|
3156
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
3157
|
+
args: [
|
|
3158
|
+
newMessageId,
|
|
3159
|
+
newThreadId,
|
|
3160
|
+
contentStr,
|
|
3161
|
+
sourceMsg.role,
|
|
3162
|
+
sourceMsg.type || "v2",
|
|
3163
|
+
sourceMsg.createdAt,
|
|
3164
|
+
targetResourceId
|
|
3165
|
+
]
|
|
3166
|
+
});
|
|
3167
|
+
clonedMessages.push({
|
|
3168
|
+
id: newMessageId,
|
|
3169
|
+
threadId: newThreadId,
|
|
3170
|
+
content: parsedContent,
|
|
3171
|
+
role: sourceMsg.role,
|
|
3172
|
+
type: sourceMsg.type || void 0,
|
|
3173
|
+
createdAt: new Date(sourceMsg.createdAt),
|
|
3174
|
+
resourceId: targetResourceId
|
|
3175
|
+
});
|
|
3176
|
+
}
|
|
3177
|
+
await tx.commit();
|
|
3178
|
+
return {
|
|
3179
|
+
thread: newThread,
|
|
3180
|
+
clonedMessages
|
|
3181
|
+
};
|
|
3182
|
+
} catch (error) {
|
|
3183
|
+
await tx.rollback();
|
|
3184
|
+
throw error;
|
|
3185
|
+
}
|
|
3186
|
+
} catch (error) {
|
|
3187
|
+
if (error instanceof MastraError) {
|
|
3188
|
+
throw error;
|
|
3189
|
+
}
|
|
3190
|
+
throw new MastraError(
|
|
3191
|
+
{
|
|
3192
|
+
id: createStorageErrorId("LIBSQL", "CLONE_THREAD", "FAILED"),
|
|
3193
|
+
domain: ErrorDomain.STORAGE,
|
|
3194
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3195
|
+
details: { sourceThreadId, newThreadId }
|
|
3196
|
+
},
|
|
3197
|
+
error
|
|
3198
|
+
);
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
2760
3201
|
};
|
|
2761
3202
|
var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
2762
3203
|
#db;
|
|
@@ -2771,11 +3212,38 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2771
3212
|
async dangerouslyClearAll() {
|
|
2772
3213
|
await this.#db.deleteData({ tableName: TABLE_SPANS });
|
|
2773
3214
|
}
|
|
2774
|
-
|
|
3215
|
+
/**
|
|
3216
|
+
* Manually run the spans migration to deduplicate and add the unique constraint.
|
|
3217
|
+
* This is intended to be called from the CLI when duplicates are detected.
|
|
3218
|
+
*
|
|
3219
|
+
* @returns Migration result with status and details
|
|
3220
|
+
*/
|
|
3221
|
+
async migrateSpans() {
|
|
3222
|
+
return this.#db.migrateSpans();
|
|
3223
|
+
}
|
|
3224
|
+
/**
|
|
3225
|
+
* Check migration status for the spans table.
|
|
3226
|
+
* Returns information about whether migration is needed.
|
|
3227
|
+
*/
|
|
3228
|
+
async checkSpansMigrationStatus() {
|
|
3229
|
+
return this.#db.checkSpansMigrationStatus();
|
|
3230
|
+
}
|
|
3231
|
+
get tracingStrategy() {
|
|
3232
|
+
return {
|
|
3233
|
+
preferred: "batch-with-updates",
|
|
3234
|
+
supported: ["batch-with-updates", "insert-only"]
|
|
3235
|
+
};
|
|
3236
|
+
}
|
|
3237
|
+
async createSpan(args) {
|
|
3238
|
+
const { span } = args;
|
|
2775
3239
|
try {
|
|
3240
|
+
const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
|
|
3241
|
+
const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
|
|
2776
3242
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2777
3243
|
const record = {
|
|
2778
3244
|
...span,
|
|
3245
|
+
startedAt,
|
|
3246
|
+
endedAt,
|
|
2779
3247
|
createdAt: now,
|
|
2780
3248
|
updatedAt: now
|
|
2781
3249
|
};
|
|
@@ -2790,19 +3258,72 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2790
3258
|
spanId: span.spanId,
|
|
2791
3259
|
traceId: span.traceId,
|
|
2792
3260
|
spanType: span.spanType,
|
|
2793
|
-
|
|
3261
|
+
name: span.name
|
|
2794
3262
|
}
|
|
2795
3263
|
},
|
|
2796
3264
|
error
|
|
2797
3265
|
);
|
|
2798
3266
|
}
|
|
2799
3267
|
}
|
|
2800
|
-
async
|
|
3268
|
+
async getSpan(args) {
|
|
3269
|
+
const { traceId, spanId } = args;
|
|
3270
|
+
try {
|
|
3271
|
+
const rows = await this.#db.selectMany({
|
|
3272
|
+
tableName: TABLE_SPANS,
|
|
3273
|
+
whereClause: { sql: " WHERE traceId = ? AND spanId = ?", args: [traceId, spanId] },
|
|
3274
|
+
limit: 1
|
|
3275
|
+
});
|
|
3276
|
+
if (!rows || rows.length === 0) {
|
|
3277
|
+
return null;
|
|
3278
|
+
}
|
|
3279
|
+
return {
|
|
3280
|
+
span: transformFromSqlRow({ tableName: TABLE_SPANS, sqlRow: rows[0] })
|
|
3281
|
+
};
|
|
3282
|
+
} catch (error) {
|
|
3283
|
+
throw new MastraError(
|
|
3284
|
+
{
|
|
3285
|
+
id: createStorageErrorId("LIBSQL", "GET_SPAN", "FAILED"),
|
|
3286
|
+
domain: ErrorDomain.STORAGE,
|
|
3287
|
+
category: ErrorCategory.USER,
|
|
3288
|
+
details: { traceId, spanId }
|
|
3289
|
+
},
|
|
3290
|
+
error
|
|
3291
|
+
);
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
async getRootSpan(args) {
|
|
3295
|
+
const { traceId } = args;
|
|
3296
|
+
try {
|
|
3297
|
+
const rows = await this.#db.selectMany({
|
|
3298
|
+
tableName: TABLE_SPANS,
|
|
3299
|
+
whereClause: { sql: " WHERE traceId = ? AND parentSpanId IS NULL", args: [traceId] },
|
|
3300
|
+
limit: 1
|
|
3301
|
+
});
|
|
3302
|
+
if (!rows || rows.length === 0) {
|
|
3303
|
+
return null;
|
|
3304
|
+
}
|
|
3305
|
+
return {
|
|
3306
|
+
span: transformFromSqlRow({ tableName: TABLE_SPANS, sqlRow: rows[0] })
|
|
3307
|
+
};
|
|
3308
|
+
} catch (error) {
|
|
3309
|
+
throw new MastraError(
|
|
3310
|
+
{
|
|
3311
|
+
id: createStorageErrorId("LIBSQL", "GET_ROOT_SPAN", "FAILED"),
|
|
3312
|
+
domain: ErrorDomain.STORAGE,
|
|
3313
|
+
category: ErrorCategory.USER,
|
|
3314
|
+
details: { traceId }
|
|
3315
|
+
},
|
|
3316
|
+
error
|
|
3317
|
+
);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
async getTrace(args) {
|
|
3321
|
+
const { traceId } = args;
|
|
2801
3322
|
try {
|
|
2802
3323
|
const spans = await this.#db.selectMany({
|
|
2803
3324
|
tableName: TABLE_SPANS,
|
|
2804
3325
|
whereClause: { sql: " WHERE traceId = ?", args: [traceId] },
|
|
2805
|
-
orderBy: "startedAt
|
|
3326
|
+
orderBy: "startedAt ASC"
|
|
2806
3327
|
});
|
|
2807
3328
|
if (!spans || spans.length === 0) {
|
|
2808
3329
|
return null;
|
|
@@ -2825,16 +3346,21 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2825
3346
|
);
|
|
2826
3347
|
}
|
|
2827
3348
|
}
|
|
2828
|
-
async updateSpan({
|
|
2829
|
-
spanId,
|
|
2830
|
-
traceId,
|
|
2831
|
-
updates
|
|
2832
|
-
}) {
|
|
3349
|
+
async updateSpan(args) {
|
|
3350
|
+
const { traceId, spanId, updates } = args;
|
|
2833
3351
|
try {
|
|
3352
|
+
const data = { ...updates };
|
|
3353
|
+
if (data.endedAt instanceof Date) {
|
|
3354
|
+
data.endedAt = data.endedAt.toISOString();
|
|
3355
|
+
}
|
|
3356
|
+
if (data.startedAt instanceof Date) {
|
|
3357
|
+
data.startedAt = data.startedAt.toISOString();
|
|
3358
|
+
}
|
|
3359
|
+
data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2834
3360
|
await this.#db.update({
|
|
2835
3361
|
tableName: TABLE_SPANS,
|
|
2836
3362
|
keys: { spanId, traceId },
|
|
2837
|
-
data
|
|
3363
|
+
data
|
|
2838
3364
|
});
|
|
2839
3365
|
} catch (error) {
|
|
2840
3366
|
throw new MastraError(
|
|
@@ -2851,83 +3377,175 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2851
3377
|
);
|
|
2852
3378
|
}
|
|
2853
3379
|
}
|
|
2854
|
-
async
|
|
2855
|
-
filters,
|
|
2856
|
-
pagination
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
3380
|
+
async listTraces(args) {
|
|
3381
|
+
const { filters, pagination, orderBy } = listTracesArgsSchema.parse(args);
|
|
3382
|
+
const { page, perPage } = pagination;
|
|
3383
|
+
const tableName = parseSqlIdentifier(TABLE_SPANS, "table name");
|
|
3384
|
+
try {
|
|
3385
|
+
const conditions = ["parentSpanId IS NULL"];
|
|
3386
|
+
const queryArgs = [];
|
|
3387
|
+
if (filters) {
|
|
3388
|
+
if (filters.startedAt?.start) {
|
|
3389
|
+
conditions.push(`startedAt >= ?`);
|
|
3390
|
+
queryArgs.push(filters.startedAt.start.toISOString());
|
|
3391
|
+
}
|
|
3392
|
+
if (filters.startedAt?.end) {
|
|
3393
|
+
conditions.push(`startedAt <= ?`);
|
|
3394
|
+
queryArgs.push(filters.startedAt.end.toISOString());
|
|
3395
|
+
}
|
|
3396
|
+
if (filters.endedAt?.start) {
|
|
3397
|
+
conditions.push(`endedAt >= ?`);
|
|
3398
|
+
queryArgs.push(filters.endedAt.start.toISOString());
|
|
3399
|
+
}
|
|
3400
|
+
if (filters.endedAt?.end) {
|
|
3401
|
+
conditions.push(`endedAt <= ?`);
|
|
3402
|
+
queryArgs.push(filters.endedAt.end.toISOString());
|
|
3403
|
+
}
|
|
3404
|
+
if (filters.spanType !== void 0) {
|
|
3405
|
+
conditions.push(`spanType = ?`);
|
|
3406
|
+
queryArgs.push(filters.spanType);
|
|
3407
|
+
}
|
|
3408
|
+
if (filters.entityType !== void 0) {
|
|
3409
|
+
conditions.push(`entityType = ?`);
|
|
3410
|
+
queryArgs.push(filters.entityType);
|
|
3411
|
+
}
|
|
3412
|
+
if (filters.entityId !== void 0) {
|
|
3413
|
+
conditions.push(`entityId = ?`);
|
|
3414
|
+
queryArgs.push(filters.entityId);
|
|
3415
|
+
}
|
|
3416
|
+
if (filters.entityName !== void 0) {
|
|
3417
|
+
conditions.push(`entityName = ?`);
|
|
3418
|
+
queryArgs.push(filters.entityName);
|
|
3419
|
+
}
|
|
3420
|
+
if (filters.userId !== void 0) {
|
|
3421
|
+
conditions.push(`userId = ?`);
|
|
3422
|
+
queryArgs.push(filters.userId);
|
|
3423
|
+
}
|
|
3424
|
+
if (filters.organizationId !== void 0) {
|
|
3425
|
+
conditions.push(`organizationId = ?`);
|
|
3426
|
+
queryArgs.push(filters.organizationId);
|
|
3427
|
+
}
|
|
3428
|
+
if (filters.resourceId !== void 0) {
|
|
3429
|
+
conditions.push(`resourceId = ?`);
|
|
3430
|
+
queryArgs.push(filters.resourceId);
|
|
3431
|
+
}
|
|
3432
|
+
if (filters.runId !== void 0) {
|
|
3433
|
+
conditions.push(`runId = ?`);
|
|
3434
|
+
queryArgs.push(filters.runId);
|
|
3435
|
+
}
|
|
3436
|
+
if (filters.sessionId !== void 0) {
|
|
3437
|
+
conditions.push(`sessionId = ?`);
|
|
3438
|
+
queryArgs.push(filters.sessionId);
|
|
3439
|
+
}
|
|
3440
|
+
if (filters.threadId !== void 0) {
|
|
3441
|
+
conditions.push(`threadId = ?`);
|
|
3442
|
+
queryArgs.push(filters.threadId);
|
|
3443
|
+
}
|
|
3444
|
+
if (filters.requestId !== void 0) {
|
|
3445
|
+
conditions.push(`requestId = ?`);
|
|
3446
|
+
queryArgs.push(filters.requestId);
|
|
3447
|
+
}
|
|
3448
|
+
if (filters.environment !== void 0) {
|
|
3449
|
+
conditions.push(`environment = ?`);
|
|
3450
|
+
queryArgs.push(filters.environment);
|
|
3451
|
+
}
|
|
3452
|
+
if (filters.source !== void 0) {
|
|
3453
|
+
conditions.push(`source = ?`);
|
|
3454
|
+
queryArgs.push(filters.source);
|
|
3455
|
+
}
|
|
3456
|
+
if (filters.serviceName !== void 0) {
|
|
3457
|
+
conditions.push(`serviceName = ?`);
|
|
3458
|
+
queryArgs.push(filters.serviceName);
|
|
3459
|
+
}
|
|
3460
|
+
if (filters.scope != null) {
|
|
3461
|
+
for (const [key, value] of Object.entries(filters.scope)) {
|
|
3462
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
|
3463
|
+
throw new MastraError({
|
|
3464
|
+
id: createStorageErrorId("LIBSQL", "LIST_TRACES", "INVALID_FILTER_KEY"),
|
|
3465
|
+
domain: ErrorDomain.STORAGE,
|
|
3466
|
+
category: ErrorCategory.USER,
|
|
3467
|
+
details: { key }
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
conditions.push(`json_extract(scope, '$.${key}') = ?`);
|
|
3471
|
+
queryArgs.push(typeof value === "string" ? value : JSON.stringify(value));
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
if (filters.metadata != null) {
|
|
3475
|
+
for (const [key, value] of Object.entries(filters.metadata)) {
|
|
3476
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
|
3477
|
+
throw new MastraError({
|
|
3478
|
+
id: createStorageErrorId("LIBSQL", "LIST_TRACES", "INVALID_FILTER_KEY"),
|
|
3479
|
+
domain: ErrorDomain.STORAGE,
|
|
3480
|
+
category: ErrorCategory.USER,
|
|
3481
|
+
details: { key }
|
|
3482
|
+
});
|
|
3483
|
+
}
|
|
3484
|
+
conditions.push(`json_extract(metadata, '$.${key}') = ?`);
|
|
3485
|
+
queryArgs.push(typeof value === "string" ? value : JSON.stringify(value));
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
if (filters.tags != null && filters.tags.length > 0) {
|
|
3489
|
+
for (const tag of filters.tags) {
|
|
3490
|
+
conditions.push(`EXISTS (SELECT 1 FROM json_each(${tableName}.tags) WHERE value = ?)`);
|
|
3491
|
+
queryArgs.push(tag);
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
if (filters.status !== void 0) {
|
|
3495
|
+
switch (filters.status) {
|
|
3496
|
+
case TraceStatus.ERROR:
|
|
3497
|
+
conditions.push(`error IS NOT NULL`);
|
|
3498
|
+
break;
|
|
3499
|
+
case TraceStatus.RUNNING:
|
|
3500
|
+
conditions.push(`endedAt IS NULL AND error IS NULL`);
|
|
3501
|
+
break;
|
|
3502
|
+
case TraceStatus.SUCCESS:
|
|
3503
|
+
conditions.push(`endedAt IS NOT NULL AND error IS NULL`);
|
|
3504
|
+
break;
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
if (filters.hasChildError !== void 0) {
|
|
3508
|
+
if (filters.hasChildError) {
|
|
3509
|
+
conditions.push(`EXISTS (
|
|
3510
|
+
SELECT 1 FROM ${tableName} c
|
|
3511
|
+
WHERE c.traceId = ${tableName}.traceId AND c.error IS NOT NULL
|
|
3512
|
+
)`);
|
|
3513
|
+
} else {
|
|
3514
|
+
conditions.push(`NOT EXISTS (
|
|
3515
|
+
SELECT 1 FROM ${tableName} c
|
|
3516
|
+
WHERE c.traceId = ${tableName}.traceId AND c.error IS NOT NULL
|
|
3517
|
+
)`);
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
2887
3520
|
}
|
|
2888
|
-
whereClause.
|
|
2889
|
-
|
|
2890
|
-
|
|
3521
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
3522
|
+
const sortField = orderBy.field;
|
|
3523
|
+
const sortDirection = orderBy.direction;
|
|
3524
|
+
let orderByClause;
|
|
3525
|
+
if (sortField === "endedAt") {
|
|
3526
|
+
orderByClause = sortDirection === "DESC" ? `CASE WHEN ${sortField} IS NULL THEN 0 ELSE 1 END, ${sortField} DESC` : `CASE WHEN ${sortField} IS NULL THEN 1 ELSE 0 END, ${sortField} ASC`;
|
|
2891
3527
|
} else {
|
|
2892
|
-
|
|
3528
|
+
orderByClause = `${sortField} ${sortDirection}`;
|
|
2893
3529
|
}
|
|
2894
|
-
|
|
2895
|
-
const orderBy = "startedAt DESC";
|
|
2896
|
-
let count = 0;
|
|
2897
|
-
try {
|
|
2898
|
-
count = await this.#db.selectTotalCount({
|
|
3530
|
+
const count = await this.#db.selectTotalCount({
|
|
2899
3531
|
tableName: TABLE_SPANS,
|
|
2900
|
-
whereClause: { sql:
|
|
3532
|
+
whereClause: { sql: whereClause, args: queryArgs }
|
|
2901
3533
|
});
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
return {
|
|
2914
|
-
pagination: {
|
|
2915
|
-
total: 0,
|
|
2916
|
-
page,
|
|
2917
|
-
perPage,
|
|
2918
|
-
hasMore: false
|
|
2919
|
-
},
|
|
2920
|
-
spans: []
|
|
2921
|
-
};
|
|
2922
|
-
}
|
|
2923
|
-
try {
|
|
3534
|
+
if (count === 0) {
|
|
3535
|
+
return {
|
|
3536
|
+
pagination: {
|
|
3537
|
+
total: 0,
|
|
3538
|
+
page,
|
|
3539
|
+
perPage,
|
|
3540
|
+
hasMore: false
|
|
3541
|
+
},
|
|
3542
|
+
spans: []
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
2924
3545
|
const spans = await this.#db.selectMany({
|
|
2925
3546
|
tableName: TABLE_SPANS,
|
|
2926
|
-
whereClause: {
|
|
2927
|
-
|
|
2928
|
-
args: whereClause.args
|
|
2929
|
-
},
|
|
2930
|
-
orderBy,
|
|
3547
|
+
whereClause: { sql: whereClause, args: queryArgs },
|
|
3548
|
+
orderBy: orderByClause,
|
|
2931
3549
|
offset: page * perPage,
|
|
2932
3550
|
limit: perPage
|
|
2933
3551
|
});
|
|
@@ -2936,14 +3554,14 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2936
3554
|
total: count,
|
|
2937
3555
|
page,
|
|
2938
3556
|
perPage,
|
|
2939
|
-
hasMore:
|
|
3557
|
+
hasMore: (page + 1) * perPage < count
|
|
2940
3558
|
},
|
|
2941
3559
|
spans: spans.map((span) => transformFromSqlRow({ tableName: TABLE_SPANS, sqlRow: span }))
|
|
2942
3560
|
};
|
|
2943
3561
|
} catch (error) {
|
|
2944
3562
|
throw new MastraError(
|
|
2945
3563
|
{
|
|
2946
|
-
id: createStorageErrorId("LIBSQL", "
|
|
3564
|
+
id: createStorageErrorId("LIBSQL", "LIST_TRACES", "FAILED"),
|
|
2947
3565
|
domain: ErrorDomain.STORAGE,
|
|
2948
3566
|
category: ErrorCategory.USER
|
|
2949
3567
|
},
|
|
@@ -2954,13 +3572,20 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2954
3572
|
async batchCreateSpans(args) {
|
|
2955
3573
|
try {
|
|
2956
3574
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
3575
|
+
const records = args.records.map((record) => {
|
|
3576
|
+
const startedAt = record.startedAt instanceof Date ? record.startedAt.toISOString() : record.startedAt;
|
|
3577
|
+
const endedAt = record.endedAt instanceof Date ? record.endedAt.toISOString() : record.endedAt;
|
|
3578
|
+
return {
|
|
2960
3579
|
...record,
|
|
3580
|
+
startedAt,
|
|
3581
|
+
endedAt,
|
|
2961
3582
|
createdAt: now,
|
|
2962
3583
|
updatedAt: now
|
|
2963
|
-
}
|
|
3584
|
+
};
|
|
3585
|
+
});
|
|
3586
|
+
return this.#db.batchInsert({
|
|
3587
|
+
tableName: TABLE_SPANS,
|
|
3588
|
+
records
|
|
2964
3589
|
});
|
|
2965
3590
|
} catch (error) {
|
|
2966
3591
|
throw new MastraError(
|
|
@@ -2974,13 +3599,24 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
|
2974
3599
|
}
|
|
2975
3600
|
}
|
|
2976
3601
|
async batchUpdateSpans(args) {
|
|
3602
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2977
3603
|
try {
|
|
2978
3604
|
return this.#db.batchUpdate({
|
|
2979
3605
|
tableName: TABLE_SPANS,
|
|
2980
|
-
updates: args.records.map((record) =>
|
|
2981
|
-
|
|
2982
|
-
data
|
|
2983
|
-
|
|
3606
|
+
updates: args.records.map((record) => {
|
|
3607
|
+
const data = { ...record.updates };
|
|
3608
|
+
if (data.endedAt instanceof Date) {
|
|
3609
|
+
data.endedAt = data.endedAt.toISOString();
|
|
3610
|
+
}
|
|
3611
|
+
if (data.startedAt instanceof Date) {
|
|
3612
|
+
data.startedAt = data.startedAt.toISOString();
|
|
3613
|
+
}
|
|
3614
|
+
data.updatedAt = now;
|
|
3615
|
+
return {
|
|
3616
|
+
keys: { spanId: record.spanId, traceId: record.traceId },
|
|
3617
|
+
data
|
|
3618
|
+
};
|
|
3619
|
+
})
|
|
2984
3620
|
});
|
|
2985
3621
|
} catch (error) {
|
|
2986
3622
|
throw new MastraError(
|
|
@@ -3059,7 +3695,7 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3059
3695
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3060
3696
|
const end = perPageInput === false ? total : start + perPage;
|
|
3061
3697
|
const result = await this.#client.execute({
|
|
3062
|
-
sql: `SELECT
|
|
3698
|
+
sql: `SELECT ${buildSelectColumns(TABLE_SCORERS)} FROM ${TABLE_SCORERS} WHERE runId = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
|
|
3063
3699
|
args: [runId, limitValue, start]
|
|
3064
3700
|
});
|
|
3065
3701
|
const scores = result.rows?.map((row) => this.transformScoreRow(row)) ?? [];
|
|
@@ -3132,7 +3768,7 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3132
3768
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3133
3769
|
const end = perPageInput === false ? total : start + perPage;
|
|
3134
3770
|
const result = await this.#client.execute({
|
|
3135
|
-
sql: `SELECT
|
|
3771
|
+
sql: `SELECT ${buildSelectColumns(TABLE_SCORERS)} FROM ${TABLE_SCORERS} ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
|
|
3136
3772
|
args: [...queryParams, limitValue, start]
|
|
3137
3773
|
});
|
|
3138
3774
|
const scores = result.rows?.map((row) => this.transformScoreRow(row)) ?? [];
|
|
@@ -3158,16 +3794,13 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3158
3794
|
}
|
|
3159
3795
|
/**
|
|
3160
3796
|
* LibSQL-specific score row transformation.
|
|
3161
|
-
* Maps additionalLLMContext column to additionalContext field.
|
|
3162
3797
|
*/
|
|
3163
3798
|
transformScoreRow(row) {
|
|
3164
|
-
return transformScoreRow(row
|
|
3165
|
-
fieldMappings: { additionalContext: "additionalLLMContext" }
|
|
3166
|
-
});
|
|
3799
|
+
return transformScoreRow(row);
|
|
3167
3800
|
}
|
|
3168
3801
|
async getScoreById({ id }) {
|
|
3169
3802
|
const result = await this.#client.execute({
|
|
3170
|
-
sql: `SELECT
|
|
3803
|
+
sql: `SELECT ${buildSelectColumns(TABLE_SCORERS)} FROM ${TABLE_SCORERS} WHERE id = ?`,
|
|
3171
3804
|
args: [id]
|
|
3172
3805
|
});
|
|
3173
3806
|
return result.rows?.[0] ? this.transformScoreRow(result.rows[0]) : null;
|
|
@@ -3183,7 +3816,7 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3183
3816
|
domain: ErrorDomain.STORAGE,
|
|
3184
3817
|
category: ErrorCategory.USER,
|
|
3185
3818
|
details: {
|
|
3186
|
-
scorer: score.scorer?.id ?? "unknown",
|
|
3819
|
+
scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
|
|
3187
3820
|
entityId: score.entityId ?? "unknown",
|
|
3188
3821
|
entityType: score.entityType ?? "unknown",
|
|
3189
3822
|
traceId: score.traceId ?? "",
|
|
@@ -3245,7 +3878,7 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3245
3878
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3246
3879
|
const end = perPageInput === false ? total : start + perPage;
|
|
3247
3880
|
const result = await this.#client.execute({
|
|
3248
|
-
sql: `SELECT
|
|
3881
|
+
sql: `SELECT ${buildSelectColumns(TABLE_SCORERS)} FROM ${TABLE_SCORERS} WHERE entityId = ? AND entityType = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
|
|
3249
3882
|
args: [entityId, entityType, limitValue, start]
|
|
3250
3883
|
});
|
|
3251
3884
|
const scores = result.rows?.map((row) => this.transformScoreRow(row)) ?? [];
|
|
@@ -3286,7 +3919,7 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3286
3919
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3287
3920
|
const end = perPageInput === false ? total : start + perPage;
|
|
3288
3921
|
const result = await this.#client.execute({
|
|
3289
|
-
sql: `SELECT
|
|
3922
|
+
sql: `SELECT ${buildSelectColumns(TABLE_SCORERS)} FROM ${TABLE_SCORERS} WHERE traceId = ? AND spanId = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
|
|
3290
3923
|
args: [traceId, spanId, limitValue, start]
|
|
3291
3924
|
});
|
|
3292
3925
|
const scores = result.rows?.map((row) => this.transformScoreRow(row)) ?? [];
|
|
@@ -3311,24 +3944,6 @@ var ScoresLibSQL = class extends ScoresStorage {
|
|
|
3311
3944
|
}
|
|
3312
3945
|
}
|
|
3313
3946
|
};
|
|
3314
|
-
function parseWorkflowRun(row) {
|
|
3315
|
-
let parsedSnapshot = row.snapshot;
|
|
3316
|
-
if (typeof parsedSnapshot === "string") {
|
|
3317
|
-
try {
|
|
3318
|
-
parsedSnapshot = JSON.parse(row.snapshot);
|
|
3319
|
-
} catch (e) {
|
|
3320
|
-
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
3321
|
-
}
|
|
3322
|
-
}
|
|
3323
|
-
return {
|
|
3324
|
-
workflowName: row.workflow_name,
|
|
3325
|
-
runId: row.run_id,
|
|
3326
|
-
snapshot: parsedSnapshot,
|
|
3327
|
-
resourceId: row.resourceId,
|
|
3328
|
-
createdAt: new Date(row.createdAt),
|
|
3329
|
-
updatedAt: new Date(row.updatedAt)
|
|
3330
|
-
};
|
|
3331
|
-
}
|
|
3332
3947
|
var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
3333
3948
|
#db;
|
|
3334
3949
|
#client;
|
|
@@ -3349,6 +3964,24 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3349
3964
|
(err) => this.logger.warn("LibSQL Workflows: Failed to setup PRAGMA settings.", err)
|
|
3350
3965
|
);
|
|
3351
3966
|
}
|
|
3967
|
+
parseWorkflowRun(row) {
|
|
3968
|
+
let parsedSnapshot = row.snapshot;
|
|
3969
|
+
if (typeof parsedSnapshot === "string") {
|
|
3970
|
+
try {
|
|
3971
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
3972
|
+
} catch (e) {
|
|
3973
|
+
this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
return {
|
|
3977
|
+
workflowName: row.workflow_name,
|
|
3978
|
+
runId: row.run_id,
|
|
3979
|
+
snapshot: parsedSnapshot,
|
|
3980
|
+
resourceId: row.resourceId,
|
|
3981
|
+
createdAt: new Date(row.createdAt),
|
|
3982
|
+
updatedAt: new Date(row.updatedAt)
|
|
3983
|
+
};
|
|
3984
|
+
}
|
|
3352
3985
|
async init() {
|
|
3353
3986
|
const schema = TABLE_SCHEMAS[TABLE_WORKFLOW_SNAPSHOT];
|
|
3354
3987
|
await this.#db.createTable({ tableName: TABLE_WORKFLOW_SNAPSHOT, schema });
|
|
@@ -3392,7 +4025,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3392
4025
|
const tx = await this.#client.transaction("write");
|
|
3393
4026
|
try {
|
|
3394
4027
|
const existingSnapshotResult = await tx.execute({
|
|
3395
|
-
sql: `SELECT snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
|
|
4028
|
+
sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
|
|
3396
4029
|
args: [workflowName, runId]
|
|
3397
4030
|
});
|
|
3398
4031
|
let snapshot;
|
|
@@ -3417,9 +4050,13 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3417
4050
|
}
|
|
3418
4051
|
snapshot.context[stepId] = result;
|
|
3419
4052
|
snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
|
|
4053
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3420
4054
|
await tx.execute({
|
|
3421
|
-
sql: `
|
|
3422
|
-
|
|
4055
|
+
sql: `INSERT INTO ${TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, snapshot, createdAt, updatedAt)
|
|
4056
|
+
VALUES (?, ?, jsonb(?), ?, ?)
|
|
4057
|
+
ON CONFLICT(workflow_name, run_id)
|
|
4058
|
+
DO UPDATE SET snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
|
|
4059
|
+
args: [workflowName, runId, JSON.stringify(snapshot), now, now]
|
|
3423
4060
|
});
|
|
3424
4061
|
await tx.commit();
|
|
3425
4062
|
return snapshot.context;
|
|
@@ -3440,7 +4077,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3440
4077
|
const tx = await this.#client.transaction("write");
|
|
3441
4078
|
try {
|
|
3442
4079
|
const existingSnapshotResult = await tx.execute({
|
|
3443
|
-
sql: `SELECT snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
|
|
4080
|
+
sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
|
|
3444
4081
|
args: [workflowName, runId]
|
|
3445
4082
|
});
|
|
3446
4083
|
if (!existingSnapshotResult.rows?.[0]) {
|
|
@@ -3455,7 +4092,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3455
4092
|
}
|
|
3456
4093
|
const updatedSnapshot = { ...snapshot, ...opts };
|
|
3457
4094
|
await tx.execute({
|
|
3458
|
-
sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = ? WHERE workflow_name = ? AND run_id = ?`,
|
|
4095
|
+
sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
|
|
3459
4096
|
args: [JSON.stringify(updatedSnapshot), workflowName, runId]
|
|
3460
4097
|
});
|
|
3461
4098
|
await tx.commit();
|
|
@@ -3519,13 +4156,13 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3519
4156
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
3520
4157
|
try {
|
|
3521
4158
|
const result = await this.#client.execute({
|
|
3522
|
-
sql: `SELECT
|
|
4159
|
+
sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC LIMIT 1`,
|
|
3523
4160
|
args
|
|
3524
4161
|
});
|
|
3525
4162
|
if (!result.rows?.[0]) {
|
|
3526
4163
|
return null;
|
|
3527
4164
|
}
|
|
3528
|
-
return parseWorkflowRun(result.rows[0]);
|
|
4165
|
+
return this.parseWorkflowRun(result.rows[0]);
|
|
3529
4166
|
} catch (error) {
|
|
3530
4167
|
throw new MastraError(
|
|
3531
4168
|
{
|
|
@@ -3591,7 +4228,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3591
4228
|
conditions.push("resourceId = ?");
|
|
3592
4229
|
args.push(resourceId);
|
|
3593
4230
|
} else {
|
|
3594
|
-
|
|
4231
|
+
this.logger.warn(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
|
|
3595
4232
|
}
|
|
3596
4233
|
}
|
|
3597
4234
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
@@ -3607,10 +4244,10 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3607
4244
|
const normalizedPerPage = usePagination ? normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
|
|
3608
4245
|
const offset = usePagination ? page * normalizedPerPage : 0;
|
|
3609
4246
|
const result = await this.#client.execute({
|
|
3610
|
-
sql: `SELECT
|
|
4247
|
+
sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC${usePagination ? ` LIMIT ? OFFSET ?` : ""}`,
|
|
3611
4248
|
args: usePagination ? [...args, normalizedPerPage, offset] : args
|
|
3612
4249
|
});
|
|
3613
|
-
const runs = (result.rows || []).map((row) => parseWorkflowRun(row));
|
|
4250
|
+
const runs = (result.rows || []).map((row) => this.parseWorkflowRun(row));
|
|
3614
4251
|
return { runs, total: total || runs.length };
|
|
3615
4252
|
} catch (error) {
|
|
3616
4253
|
throw new MastraError(
|
|
@@ -3626,7 +4263,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
|
|
|
3626
4263
|
};
|
|
3627
4264
|
|
|
3628
4265
|
// src/storage/index.ts
|
|
3629
|
-
var LibSQLStore = class extends
|
|
4266
|
+
var LibSQLStore = class extends MastraCompositeStore {
|
|
3630
4267
|
client;
|
|
3631
4268
|
maxRetries;
|
|
3632
4269
|
initialBackoffMs;
|
|
@@ -3671,160 +4308,6 @@ var LibSQLStore = class extends MastraStorage {
|
|
|
3671
4308
|
agents
|
|
3672
4309
|
};
|
|
3673
4310
|
}
|
|
3674
|
-
get supports() {
|
|
3675
|
-
return {
|
|
3676
|
-
selectByIncludeResourceScope: true,
|
|
3677
|
-
resourceWorkingMemory: true,
|
|
3678
|
-
hasColumn: true,
|
|
3679
|
-
createTable: true,
|
|
3680
|
-
deleteMessages: true,
|
|
3681
|
-
observabilityInstance: true,
|
|
3682
|
-
listScoresBySpan: true,
|
|
3683
|
-
agents: true
|
|
3684
|
-
};
|
|
3685
|
-
}
|
|
3686
|
-
async getThreadById({ threadId }) {
|
|
3687
|
-
return this.stores.memory.getThreadById({ threadId });
|
|
3688
|
-
}
|
|
3689
|
-
async saveThread({ thread }) {
|
|
3690
|
-
return this.stores.memory.saveThread({ thread });
|
|
3691
|
-
}
|
|
3692
|
-
async updateThread({
|
|
3693
|
-
id,
|
|
3694
|
-
title,
|
|
3695
|
-
metadata
|
|
3696
|
-
}) {
|
|
3697
|
-
return this.stores.memory.updateThread({ id, title, metadata });
|
|
3698
|
-
}
|
|
3699
|
-
async deleteThread({ threadId }) {
|
|
3700
|
-
return this.stores.memory.deleteThread({ threadId });
|
|
3701
|
-
}
|
|
3702
|
-
async listMessagesById({ messageIds }) {
|
|
3703
|
-
return this.stores.memory.listMessagesById({ messageIds });
|
|
3704
|
-
}
|
|
3705
|
-
async saveMessages(args) {
|
|
3706
|
-
const result = await this.stores.memory.saveMessages({ messages: args.messages });
|
|
3707
|
-
return { messages: result.messages };
|
|
3708
|
-
}
|
|
3709
|
-
async updateMessages({
|
|
3710
|
-
messages
|
|
3711
|
-
}) {
|
|
3712
|
-
return this.stores.memory.updateMessages({ messages });
|
|
3713
|
-
}
|
|
3714
|
-
async deleteMessages(messageIds) {
|
|
3715
|
-
return this.stores.memory.deleteMessages(messageIds);
|
|
3716
|
-
}
|
|
3717
|
-
async getScoreById({ id }) {
|
|
3718
|
-
return this.stores.scores.getScoreById({ id });
|
|
3719
|
-
}
|
|
3720
|
-
async saveScore(score) {
|
|
3721
|
-
return this.stores.scores.saveScore(score);
|
|
3722
|
-
}
|
|
3723
|
-
async listScoresByScorerId({
|
|
3724
|
-
scorerId,
|
|
3725
|
-
entityId,
|
|
3726
|
-
entityType,
|
|
3727
|
-
source,
|
|
3728
|
-
pagination
|
|
3729
|
-
}) {
|
|
3730
|
-
return this.stores.scores.listScoresByScorerId({ scorerId, entityId, entityType, source, pagination });
|
|
3731
|
-
}
|
|
3732
|
-
async listScoresByRunId({
|
|
3733
|
-
runId,
|
|
3734
|
-
pagination
|
|
3735
|
-
}) {
|
|
3736
|
-
return this.stores.scores.listScoresByRunId({ runId, pagination });
|
|
3737
|
-
}
|
|
3738
|
-
async listScoresByEntityId({
|
|
3739
|
-
entityId,
|
|
3740
|
-
entityType,
|
|
3741
|
-
pagination
|
|
3742
|
-
}) {
|
|
3743
|
-
return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
|
|
3744
|
-
}
|
|
3745
|
-
/**
|
|
3746
|
-
* WORKFLOWS
|
|
3747
|
-
*/
|
|
3748
|
-
async updateWorkflowResults({
|
|
3749
|
-
workflowName,
|
|
3750
|
-
runId,
|
|
3751
|
-
stepId,
|
|
3752
|
-
result,
|
|
3753
|
-
requestContext
|
|
3754
|
-
}) {
|
|
3755
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
|
|
3756
|
-
}
|
|
3757
|
-
async updateWorkflowState({
|
|
3758
|
-
workflowName,
|
|
3759
|
-
runId,
|
|
3760
|
-
opts
|
|
3761
|
-
}) {
|
|
3762
|
-
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
3763
|
-
}
|
|
3764
|
-
async persistWorkflowSnapshot({
|
|
3765
|
-
workflowName,
|
|
3766
|
-
runId,
|
|
3767
|
-
resourceId,
|
|
3768
|
-
snapshot
|
|
3769
|
-
}) {
|
|
3770
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
3771
|
-
}
|
|
3772
|
-
async loadWorkflowSnapshot({
|
|
3773
|
-
workflowName,
|
|
3774
|
-
runId
|
|
3775
|
-
}) {
|
|
3776
|
-
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
3777
|
-
}
|
|
3778
|
-
async listWorkflowRuns(args = {}) {
|
|
3779
|
-
return this.stores.workflows.listWorkflowRuns(args);
|
|
3780
|
-
}
|
|
3781
|
-
async getWorkflowRunById({
|
|
3782
|
-
runId,
|
|
3783
|
-
workflowName
|
|
3784
|
-
}) {
|
|
3785
|
-
return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
|
|
3786
|
-
}
|
|
3787
|
-
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
3788
|
-
return this.stores.workflows.deleteWorkflowRunById({ runId, workflowName });
|
|
3789
|
-
}
|
|
3790
|
-
async getResourceById({ resourceId }) {
|
|
3791
|
-
return this.stores.memory.getResourceById({ resourceId });
|
|
3792
|
-
}
|
|
3793
|
-
async saveResource({ resource }) {
|
|
3794
|
-
return this.stores.memory.saveResource({ resource });
|
|
3795
|
-
}
|
|
3796
|
-
async updateResource({
|
|
3797
|
-
resourceId,
|
|
3798
|
-
workingMemory,
|
|
3799
|
-
metadata
|
|
3800
|
-
}) {
|
|
3801
|
-
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
3802
|
-
}
|
|
3803
|
-
async createSpan(span) {
|
|
3804
|
-
return this.stores.observability.createSpan(span);
|
|
3805
|
-
}
|
|
3806
|
-
async updateSpan(params) {
|
|
3807
|
-
return this.stores.observability.updateSpan(params);
|
|
3808
|
-
}
|
|
3809
|
-
async getTrace(traceId) {
|
|
3810
|
-
return this.stores.observability.getTrace(traceId);
|
|
3811
|
-
}
|
|
3812
|
-
async getTracesPaginated(args) {
|
|
3813
|
-
return this.stores.observability.getTracesPaginated(args);
|
|
3814
|
-
}
|
|
3815
|
-
async listScoresBySpan({
|
|
3816
|
-
traceId,
|
|
3817
|
-
spanId,
|
|
3818
|
-
pagination
|
|
3819
|
-
}) {
|
|
3820
|
-
return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
|
|
3821
|
-
}
|
|
3822
|
-
async batchCreateSpans(args) {
|
|
3823
|
-
return this.stores.observability.batchCreateSpans(args);
|
|
3824
|
-
}
|
|
3825
|
-
async batchUpdateSpans(args) {
|
|
3826
|
-
return this.stores.observability.batchUpdateSpans(args);
|
|
3827
|
-
}
|
|
3828
4311
|
};
|
|
3829
4312
|
|
|
3830
4313
|
// src/vector/prompt.ts
|
|
@@ -3926,6 +4409,6 @@ Example Complex Query:
|
|
|
3926
4409
|
]
|
|
3927
4410
|
}`;
|
|
3928
4411
|
|
|
3929
|
-
export { LibSQLStore as DefaultStorage, LIBSQL_PROMPT, LibSQLStore, LibSQLVector };
|
|
4412
|
+
export { AgentsLibSQL, LibSQLStore as DefaultStorage, LIBSQL_PROMPT, LibSQLStore, LibSQLVector, MemoryLibSQL, ObservabilityLibSQL, ScoresLibSQL, WorkflowsLibSQL };
|
|
3930
4413
|
//# sourceMappingURL=index.js.map
|
|
3931
4414
|
//# sourceMappingURL=index.js.map
|