@mastra/lance 0.0.0-roamin-openaivoice-speak-options-passing-20250926163614 → 0.0.0-safe-stringify-telemetry-20251205024938

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/index.js CHANGED
@@ -3,6 +3,7 @@ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
3
  import { MastraStorage, StoreOperations, LegacyEvalsStorage, TABLE_EVALS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, resolveMessageLimit, TABLE_RESOURCES, ScoresStorage, TABLE_SCORERS, TracesStorage, TABLE_TRACES, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ensureDate } from '@mastra/core/storage';
4
4
  import { MessageList } from '@mastra/core/agent';
5
5
  import { Utf8, Float64, Binary, Float32, Int32, Field, Schema } from 'apache-arrow';
6
+ import { saveScorePayloadSchema } from '@mastra/core/scores';
6
7
  import { MastraVector } from '@mastra/core/vector';
7
8
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
8
9
 
@@ -59,9 +60,9 @@ var StoreLegacyEvalsLance = class extends LegacyEvalsStorage {
59
60
  conditions.push(`agent_name = '${options.agentName}'`);
60
61
  }
61
62
  if (options.type === "live") {
62
- conditions.push("length(test_info) = 0");
63
+ conditions.push("test_info IS NULL");
63
64
  } else if (options.type === "test") {
64
- conditions.push("length(test_info) > 0");
65
+ conditions.push("test_info IS NOT NULL");
65
66
  }
66
67
  const startDate = options.dateRange?.start || options.fromDate;
67
68
  const endDate = options.dateRange?.end || options.toDate;
@@ -1396,13 +1397,27 @@ var StoreScoresLance = class extends ScoresStorage {
1396
1397
  this.client = client;
1397
1398
  }
1398
1399
  async saveScore(score) {
1400
+ let validatedScore;
1401
+ try {
1402
+ validatedScore = saveScorePayloadSchema.parse(score);
1403
+ } catch (error) {
1404
+ throw new MastraError(
1405
+ {
1406
+ id: "LANCE_STORAGE_SAVE_SCORE_FAILED",
1407
+ text: "Failed to save score in LanceStorage",
1408
+ domain: ErrorDomain.STORAGE,
1409
+ category: ErrorCategory.THIRD_PARTY
1410
+ },
1411
+ error
1412
+ );
1413
+ }
1399
1414
  try {
1400
1415
  const id = crypto.randomUUID();
1401
1416
  const table = await this.client.openTable(TABLE_SCORERS);
1402
1417
  const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1403
1418
  const allowedFields = new Set(schema.fields.map((f) => f.name));
1404
1419
  const filteredScore = {};
1405
- Object.keys(score).forEach((key) => {
1420
+ Object.keys(validatedScore).forEach((key) => {
1406
1421
  if (allowedFields.has(key)) {
1407
1422
  filteredScore[key] = score[key];
1408
1423
  }
@@ -1412,6 +1427,8 @@ var StoreScoresLance = class extends ScoresStorage {
1412
1427
  filteredScore[key] = JSON.stringify(filteredScore[key]);
1413
1428
  }
1414
1429
  }
1430
+ filteredScore.createdAt = /* @__PURE__ */ new Date();
1431
+ filteredScore.updatedAt = /* @__PURE__ */ new Date();
1415
1432
  filteredScore.id = id;
1416
1433
  await table.add([filteredScore], { mode: "append" });
1417
1434
  return { score };
@@ -1578,6 +1595,44 @@ var StoreScoresLance = class extends ScoresStorage {
1578
1595
  );
1579
1596
  }
1580
1597
  }
1598
+ async getScoresBySpan({
1599
+ traceId,
1600
+ spanId,
1601
+ pagination
1602
+ }) {
1603
+ try {
1604
+ const table = await this.client.openTable(TABLE_SCORERS);
1605
+ const { page = 0, perPage = 10 } = pagination || {};
1606
+ const offset = page * perPage;
1607
+ const query = table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).limit(perPage);
1608
+ if (offset > 0) query.offset(offset);
1609
+ const records = await query.toArray();
1610
+ const schema = await getTableSchema({ tableName: TABLE_SCORERS, client: this.client });
1611
+ const scores = processResultWithTypeConversion(records, schema);
1612
+ const allRecords = await table.query().where(`\`traceId\` = '${traceId}' AND \`spanId\` = '${spanId}'`).toArray();
1613
+ const total = allRecords.length;
1614
+ return {
1615
+ pagination: {
1616
+ page,
1617
+ perPage,
1618
+ total,
1619
+ hasMore: offset + scores.length < total
1620
+ },
1621
+ scores
1622
+ };
1623
+ } catch (error) {
1624
+ throw new MastraError(
1625
+ {
1626
+ id: "LANCE_STORAGE_GET_SCORES_BY_SPAN_FAILED",
1627
+ text: "Failed to get scores by traceId and spanId in LanceStorage",
1628
+ domain: ErrorDomain.STORAGE,
1629
+ category: ErrorCategory.THIRD_PARTY,
1630
+ details: { error: error?.message }
1631
+ },
1632
+ error
1633
+ );
1634
+ }
1635
+ }
1581
1636
  };
1582
1637
  var StoreTracesLance = class extends TracesStorage {
1583
1638
  client;
@@ -1828,11 +1883,13 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1828
1883
  } else {
1829
1884
  createdAt = now;
1830
1885
  }
1886
+ const { status, value, ...rest } = snapshot;
1831
1887
  const record = {
1832
1888
  workflow_name: workflowName,
1833
1889
  run_id: runId,
1834
1890
  resourceId,
1835
- snapshot: JSON.stringify(snapshot),
1891
+ snapshot: JSON.stringify({ status, value, ...rest }),
1892
+ // this is to ensure status is always just before value, for when querying the db by status
1836
1893
  createdAt,
1837
1894
  updatedAt: now
1838
1895
  };
@@ -1902,6 +1959,10 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1902
1959
  if (args?.workflowName) {
1903
1960
  conditions.push(`workflow_name = '${args.workflowName.replace(/'/g, "''")}'`);
1904
1961
  }
1962
+ if (args?.status) {
1963
+ const escapedStatus = args.status.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/%/g, "\\%").replace(/_/g, "\\_");
1964
+ conditions.push(`\`snapshot\` LIKE '%"status":"${escapedStatus}","value"%'`);
1965
+ }
1905
1966
  if (args?.resourceId) {
1906
1967
  conditions.push(`\`resourceId\` = '${args.resourceId}'`);
1907
1968
  }
@@ -1935,7 +1996,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
1935
1996
  id: "LANCE_STORE_GET_WORKFLOW_RUNS_FAILED",
1936
1997
  domain: ErrorDomain.STORAGE,
1937
1998
  category: ErrorCategory.THIRD_PARTY,
1938
- details: { namespace: args?.namespace ?? "", workflowName: args?.workflowName ?? "" }
1999
+ details: { resourceId: args?.resourceId ?? "", workflowName: args?.workflowName ?? "" }
1939
2000
  },
1940
2001
  error
1941
2002
  );
@@ -2070,7 +2131,8 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2070
2131
  resourceWorkingMemory: true,
2071
2132
  hasColumn: true,
2072
2133
  createTable: true,
2073
- deleteMessages: false
2134
+ deleteMessages: false,
2135
+ getScoresBySpan: true
2074
2136
  };
2075
2137
  }
2076
2138
  async getResourceById({ resourceId }) {
@@ -2240,6 +2302,13 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
2240
2302
  }) {
2241
2303
  return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
2242
2304
  }
2305
+ async getScoresBySpan({
2306
+ traceId,
2307
+ spanId,
2308
+ pagination
2309
+ }) {
2310
+ return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
2311
+ }
2243
2312
  };
2244
2313
  var LanceFilterTranslator = class extends BaseFilterTranslator {
2245
2314
  translate(filter) {
@@ -3131,7 +3200,44 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3131
3200
  );
3132
3201
  }
3133
3202
  }
3134
- async updateVector({ indexName, id, update }) {
3203
+ async updateVector(params) {
3204
+ const { indexName, update } = params;
3205
+ if ("id" in params && "filter" in params && params.id && params.filter) {
3206
+ throw new MastraError({
3207
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3208
+ domain: ErrorDomain.STORAGE,
3209
+ category: ErrorCategory.USER,
3210
+ text: "id and filter are mutually exclusive",
3211
+ details: { indexName }
3212
+ });
3213
+ }
3214
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
3215
+ throw new MastraError({
3216
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3217
+ domain: ErrorDomain.STORAGE,
3218
+ category: ErrorCategory.USER,
3219
+ text: "Either id or filter must be provided",
3220
+ details: { indexName }
3221
+ });
3222
+ }
3223
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
3224
+ throw new MastraError({
3225
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3226
+ domain: ErrorDomain.STORAGE,
3227
+ category: ErrorCategory.USER,
3228
+ text: "Cannot update with empty filter",
3229
+ details: { indexName }
3230
+ });
3231
+ }
3232
+ if (!update.vector && !update.metadata) {
3233
+ throw new MastraError({
3234
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
3235
+ domain: ErrorDomain.STORAGE,
3236
+ category: ErrorCategory.USER,
3237
+ text: "No updates provided",
3238
+ details: { indexName }
3239
+ });
3240
+ }
3135
3241
  try {
3136
3242
  if (!this.lanceClient) {
3137
3243
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -3139,21 +3245,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3139
3245
  if (!indexName) {
3140
3246
  throw new Error("indexName is required");
3141
3247
  }
3142
- if (!id) {
3143
- throw new Error("id is required");
3144
- }
3145
- } catch (err) {
3146
- throw new MastraError(
3147
- {
3148
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
3149
- domain: ErrorDomain.STORAGE,
3150
- category: ErrorCategory.USER,
3151
- details: { indexName, id }
3152
- },
3153
- err
3154
- );
3155
- }
3156
- try {
3157
3248
  const tables = await this.lanceClient.tableNames();
3158
3249
  for (const tableName of tables) {
3159
3250
  this.logger.debug("Checking table:" + tableName);
@@ -3163,39 +3254,66 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3163
3254
  const hasColumn = schema.fields.some((field) => field.name === indexName);
3164
3255
  if (hasColumn) {
3165
3256
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3166
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
3167
- if (existingRecord.length === 0) {
3168
- throw new Error(`Record with id '${id}' not found in table ${tableName}`);
3257
+ let whereClause;
3258
+ if ("id" in params && params.id) {
3259
+ whereClause = `id = '${params.id}'`;
3260
+ } else if ("filter" in params && params.filter) {
3261
+ const translator = new LanceFilterTranslator();
3262
+ const processFilterKeys = (filter) => {
3263
+ const processedFilter = {};
3264
+ Object.entries(filter).forEach(([key, value]) => {
3265
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3266
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3267
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3268
+ });
3269
+ } else {
3270
+ processedFilter[`metadata_${key}`] = value;
3271
+ }
3272
+ });
3273
+ return processedFilter;
3274
+ };
3275
+ const prefixedFilter = processFilterKeys(params.filter);
3276
+ whereClause = translator.translate(prefixedFilter) || "";
3277
+ if (!whereClause) {
3278
+ throw new Error("Failed to translate filter to SQL");
3279
+ }
3280
+ } else {
3281
+ throw new Error("Either id or filter must be provided");
3169
3282
  }
3170
- const rowData = {
3171
- id
3172
- };
3173
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
3174
- if (key !== "id" && key !== "_distance") {
3175
- if (key === indexName) {
3176
- if (!update.vector) {
3177
- if (Array.isArray(value)) {
3178
- rowData[key] = [...value];
3179
- } else if (typeof value === "object" && value !== null) {
3180
- rowData[key] = Array.from(value);
3283
+ const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
3284
+ if (existingRecords.length === 0) {
3285
+ this.logger.info(`No records found matching criteria in table ${tableName}`);
3286
+ return;
3287
+ }
3288
+ const updatedRecords = existingRecords.map((record) => {
3289
+ const rowData = {};
3290
+ Object.entries(record).forEach(([key, value]) => {
3291
+ if (key !== "_distance") {
3292
+ if (key === indexName) {
3293
+ if (update.vector) {
3294
+ rowData[key] = update.vector;
3181
3295
  } else {
3182
- rowData[key] = value;
3296
+ if (Array.isArray(value)) {
3297
+ rowData[key] = [...value];
3298
+ } else if (typeof value === "object" && value !== null) {
3299
+ rowData[key] = Array.from(value);
3300
+ } else {
3301
+ rowData[key] = value;
3302
+ }
3183
3303
  }
3304
+ } else {
3305
+ rowData[key] = value;
3184
3306
  }
3185
- } else {
3186
- rowData[key] = value;
3187
3307
  }
3308
+ });
3309
+ if (update.metadata) {
3310
+ Object.entries(update.metadata).forEach(([key, value]) => {
3311
+ rowData[`metadata_${key}`] = value;
3312
+ });
3188
3313
  }
3314
+ return rowData;
3189
3315
  });
3190
- if (update.vector) {
3191
- rowData[indexName] = update.vector;
3192
- }
3193
- if (update.metadata) {
3194
- Object.entries(update.metadata).forEach(([key, value]) => {
3195
- rowData[`metadata_${key}`] = value;
3196
- });
3197
- }
3198
- await table.add([rowData], { mode: "overwrite" });
3316
+ await table.add(updatedRecords, { mode: "overwrite" });
3199
3317
  return;
3200
3318
  }
3201
3319
  } catch (err) {
@@ -3205,12 +3323,19 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3205
3323
  }
3206
3324
  throw new Error(`No table found with column/index '${indexName}'`);
3207
3325
  } catch (error) {
3326
+ if (error instanceof MastraError) throw error;
3208
3327
  throw new MastraError(
3209
3328
  {
3210
3329
  id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
3211
3330
  domain: ErrorDomain.STORAGE,
3212
3331
  category: ErrorCategory.THIRD_PARTY,
3213
- details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
3332
+ details: {
3333
+ indexName,
3334
+ ..."id" in params && params.id && { id: params.id },
3335
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
3336
+ hasVector: !!update.vector,
3337
+ hasMetadata: !!update.metadata
3338
+ }
3214
3339
  },
3215
3340
  error
3216
3341
  );
@@ -3233,7 +3358,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3233
3358
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
3234
3359
  domain: ErrorDomain.STORAGE,
3235
3360
  category: ErrorCategory.USER,
3236
- details: { indexName, id }
3361
+ details: {
3362
+ indexName,
3363
+ ...id && { id }
3364
+ }
3237
3365
  },
3238
3366
  err
3239
3367
  );
@@ -3263,7 +3391,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3263
3391
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
3264
3392
  domain: ErrorDomain.STORAGE,
3265
3393
  category: ErrorCategory.THIRD_PARTY,
3266
- details: { indexName, id }
3394
+ details: {
3395
+ indexName,
3396
+ ...id && { id }
3397
+ }
3267
3398
  },
3268
3399
  error
3269
3400
  );
@@ -3294,6 +3425,109 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
3294
3425
  });
3295
3426
  return result;
3296
3427
  }
3428
+ async deleteVectors({ indexName, filter, ids }) {
3429
+ if (ids && filter) {
3430
+ throw new MastraError({
3431
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3432
+ domain: ErrorDomain.STORAGE,
3433
+ category: ErrorCategory.USER,
3434
+ text: "ids and filter are mutually exclusive",
3435
+ details: { indexName }
3436
+ });
3437
+ }
3438
+ if (!ids && !filter) {
3439
+ throw new MastraError({
3440
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3441
+ domain: ErrorDomain.STORAGE,
3442
+ category: ErrorCategory.USER,
3443
+ text: "Either filter or ids must be provided",
3444
+ details: { indexName }
3445
+ });
3446
+ }
3447
+ if (ids && ids.length === 0) {
3448
+ throw new MastraError({
3449
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3450
+ domain: ErrorDomain.STORAGE,
3451
+ category: ErrorCategory.USER,
3452
+ text: "Cannot delete with empty ids array",
3453
+ details: { indexName }
3454
+ });
3455
+ }
3456
+ if (filter && Object.keys(filter).length === 0) {
3457
+ throw new MastraError({
3458
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3459
+ domain: ErrorDomain.STORAGE,
3460
+ category: ErrorCategory.USER,
3461
+ text: "Cannot delete with empty filter",
3462
+ details: { indexName }
3463
+ });
3464
+ }
3465
+ try {
3466
+ if (!this.lanceClient) {
3467
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3468
+ }
3469
+ if (!indexName) {
3470
+ throw new Error("indexName is required");
3471
+ }
3472
+ const tables = await this.lanceClient.tableNames();
3473
+ for (const tableName of tables) {
3474
+ this.logger.debug("Checking table:" + tableName);
3475
+ const table = await this.lanceClient.openTable(tableName);
3476
+ try {
3477
+ const schema = await table.schema();
3478
+ const hasColumn = schema.fields.some((field) => field.name === indexName);
3479
+ if (hasColumn) {
3480
+ this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3481
+ if (ids) {
3482
+ const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
3483
+ await table.delete(idsConditions);
3484
+ } else if (filter) {
3485
+ const translator = new LanceFilterTranslator();
3486
+ const processFilterKeys = (filter2) => {
3487
+ const processedFilter = {};
3488
+ Object.entries(filter2).forEach(([key, value]) => {
3489
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3490
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3491
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3492
+ });
3493
+ } else {
3494
+ processedFilter[`metadata_${key}`] = value;
3495
+ }
3496
+ });
3497
+ return processedFilter;
3498
+ };
3499
+ const prefixedFilter = processFilterKeys(filter);
3500
+ const whereClause = translator.translate(prefixedFilter);
3501
+ if (!whereClause) {
3502
+ throw new Error("Failed to translate filter to SQL");
3503
+ }
3504
+ await table.delete(whereClause);
3505
+ }
3506
+ return;
3507
+ }
3508
+ } catch (err) {
3509
+ this.logger.error(`Error checking schema for table ${tableName}:` + err);
3510
+ continue;
3511
+ }
3512
+ }
3513
+ throw new Error(`No table found with column/index '${indexName}'`);
3514
+ } catch (error) {
3515
+ if (error instanceof MastraError) throw error;
3516
+ throw new MastraError(
3517
+ {
3518
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
3519
+ domain: ErrorDomain.STORAGE,
3520
+ category: ErrorCategory.THIRD_PARTY,
3521
+ details: {
3522
+ indexName,
3523
+ ...filter && { filter: JSON.stringify(filter) },
3524
+ ...ids && { idsCount: ids.length }
3525
+ }
3526
+ },
3527
+ error
3528
+ );
3529
+ }
3530
+ }
3297
3531
  };
3298
3532
 
3299
3533
  export { LanceStorage, LanceVectorStore };