@mastra/lance 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +946 -0
- package/dist/docs/README.md +33 -0
- package/dist/docs/SKILL.md +34 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/rag/01-vector-databases.md +643 -0
- package/dist/docs/storage/01-reference.md +113 -0
- package/dist/docs/vectors/01-reference.md +149 -0
- package/dist/index.cjs +196 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +195 -89
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -2
- package/dist/storage/domains/memory/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 +8 -4
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +15 -5
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { connect, Index } from '@lancedb/lancedb';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import {
|
|
3
|
+
import { MemoryStorage, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, createStorageErrorId, normalizePerPage, calculatePagination, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, WorkflowsStorage, ensureDate, TABLE_WORKFLOW_SNAPSHOT, MastraCompositeStore, createVectorErrorId, getDefaultValue } from '@mastra/core/storage';
|
|
4
4
|
import { MessageList } from '@mastra/core/agent';
|
|
5
5
|
import { MastraBase } from '@mastra/core/base';
|
|
6
6
|
import { Utf8, Float64, Binary, Float32, Int32, Field, Schema } from 'apache-arrow';
|
|
@@ -797,11 +797,13 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
797
797
|
}
|
|
798
798
|
if (filter?.dateRange?.start) {
|
|
799
799
|
const startTime = filter.dateRange.start instanceof Date ? filter.dateRange.start.getTime() : new Date(filter.dateRange.start).getTime();
|
|
800
|
-
|
|
800
|
+
const startOp = filter.dateRange.startExclusive ? ">" : ">=";
|
|
801
|
+
conditions.push(`\`createdAt\` ${startOp} ${startTime}`);
|
|
801
802
|
}
|
|
802
803
|
if (filter?.dateRange?.end) {
|
|
803
804
|
const endTime = filter.dateRange.end instanceof Date ? filter.dateRange.end.getTime() : new Date(filter.dateRange.end).getTime();
|
|
804
|
-
|
|
805
|
+
const endOp = filter.dateRange.endExclusive ? "<" : "<=";
|
|
806
|
+
conditions.push(`\`createdAt\` ${endOp} ${endTime}`);
|
|
805
807
|
}
|
|
806
808
|
const whereClause = conditions.join(" AND ");
|
|
807
809
|
const total = await table.countRows(whereClause);
|
|
@@ -948,27 +950,63 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
948
950
|
);
|
|
949
951
|
}
|
|
950
952
|
}
|
|
951
|
-
async
|
|
953
|
+
async listThreads(args) {
|
|
954
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
955
|
+
try {
|
|
956
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
957
|
+
} catch (error) {
|
|
958
|
+
throw new MastraError(
|
|
959
|
+
{
|
|
960
|
+
id: createStorageErrorId("LANCE", "LIST_THREADS", "INVALID_PAGE"),
|
|
961
|
+
domain: ErrorDomain.STORAGE,
|
|
962
|
+
category: ErrorCategory.USER,
|
|
963
|
+
details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
|
|
964
|
+
},
|
|
965
|
+
error instanceof Error ? error : new Error("Invalid pagination parameters")
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
969
|
+
try {
|
|
970
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
971
|
+
} catch (error) {
|
|
972
|
+
throw new MastraError(
|
|
973
|
+
{
|
|
974
|
+
id: createStorageErrorId("LANCE", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
975
|
+
domain: ErrorDomain.STORAGE,
|
|
976
|
+
category: ErrorCategory.USER,
|
|
977
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
978
|
+
},
|
|
979
|
+
error instanceof Error ? error : new Error("Invalid metadata key")
|
|
980
|
+
);
|
|
981
|
+
}
|
|
952
982
|
try {
|
|
953
|
-
const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
|
|
954
|
-
const perPage = normalizePerPage(perPageInput, 100);
|
|
955
|
-
if (page < 0) {
|
|
956
|
-
throw new MastraError(
|
|
957
|
-
{
|
|
958
|
-
id: createStorageErrorId("LANCE", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
|
|
959
|
-
domain: ErrorDomain.STORAGE,
|
|
960
|
-
category: ErrorCategory.USER,
|
|
961
|
-
details: { page }
|
|
962
|
-
},
|
|
963
|
-
new Error("page must be >= 0")
|
|
964
|
-
);
|
|
965
|
-
}
|
|
966
983
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
967
984
|
const { field, direction } = this.parseOrderBy(orderBy);
|
|
968
985
|
const table = await this.client.openTable(TABLE_THREADS);
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
|
|
986
|
+
const whereClauses = [];
|
|
987
|
+
if (filter?.resourceId) {
|
|
988
|
+
whereClauses.push(`\`resourceId\` = '${this.escapeSql(filter.resourceId)}'`);
|
|
989
|
+
}
|
|
990
|
+
const whereClause = whereClauses.length > 0 ? whereClauses.join(" AND ") : "";
|
|
991
|
+
const query = whereClause ? table.query().where(whereClause) : table.query();
|
|
992
|
+
let records = await query.toArray();
|
|
993
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
994
|
+
records = records.filter((record) => {
|
|
995
|
+
if (!record.metadata) return false;
|
|
996
|
+
let recordMeta;
|
|
997
|
+
if (typeof record.metadata === "string") {
|
|
998
|
+
try {
|
|
999
|
+
recordMeta = JSON.parse(record.metadata);
|
|
1000
|
+
} catch {
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
} else {
|
|
1004
|
+
recordMeta = record.metadata;
|
|
1005
|
+
}
|
|
1006
|
+
return Object.entries(filter.metadata).every(([key, value]) => recordMeta[key] === value);
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
const total = records.length;
|
|
972
1010
|
records.sort((a, b) => {
|
|
973
1011
|
const aValue = ["createdAt", "updatedAt"].includes(field) ? new Date(a[field]).getTime() : a[field];
|
|
974
1012
|
const bValue = ["createdAt", "updatedAt"].includes(field) ? new Date(b[field]).getTime() : b[field];
|
|
@@ -995,7 +1033,7 @@ var StoreMemoryLance = class extends MemoryStorage {
|
|
|
995
1033
|
} catch (error) {
|
|
996
1034
|
throw new MastraError(
|
|
997
1035
|
{
|
|
998
|
-
id: createStorageErrorId("LANCE", "
|
|
1036
|
+
id: createStorageErrorId("LANCE", "LIST_THREADS", "FAILED"),
|
|
999
1037
|
domain: ErrorDomain.STORAGE,
|
|
1000
1038
|
category: ErrorCategory.THIRD_PARTY
|
|
1001
1039
|
},
|
|
@@ -1601,24 +1639,6 @@ var StoreScoresLance = class extends ScoresStorage {
|
|
|
1601
1639
|
function escapeSql(str) {
|
|
1602
1640
|
return str.replace(/'/g, "''");
|
|
1603
1641
|
}
|
|
1604
|
-
function parseWorkflowRun(row) {
|
|
1605
|
-
let parsedSnapshot = row.snapshot;
|
|
1606
|
-
if (typeof parsedSnapshot === "string") {
|
|
1607
|
-
try {
|
|
1608
|
-
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1609
|
-
} catch (e) {
|
|
1610
|
-
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
return {
|
|
1614
|
-
workflowName: row.workflow_name,
|
|
1615
|
-
runId: row.run_id,
|
|
1616
|
-
snapshot: parsedSnapshot,
|
|
1617
|
-
createdAt: ensureDate(row.createdAt),
|
|
1618
|
-
updatedAt: ensureDate(row.updatedAt),
|
|
1619
|
-
resourceId: row.resourceId
|
|
1620
|
-
};
|
|
1621
|
-
}
|
|
1622
1642
|
var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
1623
1643
|
client;
|
|
1624
1644
|
#db;
|
|
@@ -1628,6 +1648,24 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1628
1648
|
this.client = client;
|
|
1629
1649
|
this.#db = new LanceDB({ client });
|
|
1630
1650
|
}
|
|
1651
|
+
parseWorkflowRun(row) {
|
|
1652
|
+
let parsedSnapshot = row.snapshot;
|
|
1653
|
+
if (typeof parsedSnapshot === "string") {
|
|
1654
|
+
try {
|
|
1655
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1656
|
+
} catch (e) {
|
|
1657
|
+
this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
return {
|
|
1661
|
+
workflowName: row.workflow_name,
|
|
1662
|
+
runId: row.run_id,
|
|
1663
|
+
snapshot: parsedSnapshot,
|
|
1664
|
+
createdAt: ensureDate(row.createdAt),
|
|
1665
|
+
updatedAt: ensureDate(row.updatedAt),
|
|
1666
|
+
resourceId: row.resourceId
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1631
1669
|
async init() {
|
|
1632
1670
|
const schema = TABLE_SCHEMAS[TABLE_WORKFLOW_SNAPSHOT];
|
|
1633
1671
|
await this.#db.createTable({ tableName: TABLE_WORKFLOW_SNAPSHOT, schema });
|
|
@@ -1759,7 +1797,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1759
1797
|
const records = await query.toArray();
|
|
1760
1798
|
if (records.length === 0) return null;
|
|
1761
1799
|
const record = records[0];
|
|
1762
|
-
return parseWorkflowRun(record);
|
|
1800
|
+
return this.parseWorkflowRun(record);
|
|
1763
1801
|
} catch (error) {
|
|
1764
1802
|
throw new MastraError(
|
|
1765
1803
|
{
|
|
@@ -1836,7 +1874,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1836
1874
|
}
|
|
1837
1875
|
const records = await query.toArray();
|
|
1838
1876
|
return {
|
|
1839
|
-
runs: records.map((record) => parseWorkflowRun(record)),
|
|
1877
|
+
runs: records.map((record) => this.parseWorkflowRun(record)),
|
|
1840
1878
|
total: total || records.length
|
|
1841
1879
|
};
|
|
1842
1880
|
} catch (error) {
|
|
@@ -1854,7 +1892,7 @@ var StoreWorkflowsLance = class extends WorkflowsStorage {
|
|
|
1854
1892
|
};
|
|
1855
1893
|
|
|
1856
1894
|
// src/storage/index.ts
|
|
1857
|
-
var LanceStorage = class _LanceStorage extends
|
|
1895
|
+
var LanceStorage = class _LanceStorage extends MastraCompositeStore {
|
|
1858
1896
|
stores;
|
|
1859
1897
|
lanceClient;
|
|
1860
1898
|
/**
|
|
@@ -1949,19 +1987,6 @@ var LanceStorage = class _LanceStorage extends MastraStorage {
|
|
|
1949
1987
|
super({ id, name, disableInit });
|
|
1950
1988
|
this.stores = {};
|
|
1951
1989
|
}
|
|
1952
|
-
get supports() {
|
|
1953
|
-
return {
|
|
1954
|
-
selectByIncludeResourceScope: true,
|
|
1955
|
-
resourceWorkingMemory: true,
|
|
1956
|
-
hasColumn: true,
|
|
1957
|
-
createTable: true,
|
|
1958
|
-
deleteMessages: true,
|
|
1959
|
-
observability: false,
|
|
1960
|
-
indexManagement: false,
|
|
1961
|
-
listScoresBySpan: true,
|
|
1962
|
-
agents: false
|
|
1963
|
-
};
|
|
1964
|
-
}
|
|
1965
1990
|
};
|
|
1966
1991
|
var LanceFilterTranslator = class extends BaseFilterTranslator {
|
|
1967
1992
|
translate(filter) {
|
|
@@ -2339,6 +2364,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2339
2364
|
}
|
|
2340
2365
|
async query({
|
|
2341
2366
|
tableName,
|
|
2367
|
+
indexName,
|
|
2342
2368
|
queryVector,
|
|
2343
2369
|
filter,
|
|
2344
2370
|
includeVector = false,
|
|
@@ -2346,12 +2372,13 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2346
2372
|
columns = [],
|
|
2347
2373
|
includeAllColumns = false
|
|
2348
2374
|
}) {
|
|
2375
|
+
const resolvedTableName = tableName ?? indexName;
|
|
2349
2376
|
try {
|
|
2350
2377
|
if (!this.lanceClient) {
|
|
2351
2378
|
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
2352
2379
|
}
|
|
2353
|
-
if (!
|
|
2354
|
-
throw new Error("tableName is required");
|
|
2380
|
+
if (!resolvedTableName) {
|
|
2381
|
+
throw new Error("tableName or indexName is required");
|
|
2355
2382
|
}
|
|
2356
2383
|
if (!queryVector) {
|
|
2357
2384
|
throw new Error("queryVector is required");
|
|
@@ -2362,25 +2389,30 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2362
2389
|
id: createVectorErrorId("LANCE", "QUERY", "INVALID_ARGS"),
|
|
2363
2390
|
domain: ErrorDomain.STORAGE,
|
|
2364
2391
|
category: ErrorCategory.USER,
|
|
2365
|
-
text:
|
|
2366
|
-
details: { tableName }
|
|
2392
|
+
text: error instanceof Error ? error.message : "Invalid query arguments",
|
|
2393
|
+
details: { tableName: resolvedTableName }
|
|
2367
2394
|
},
|
|
2368
2395
|
error
|
|
2369
2396
|
);
|
|
2370
2397
|
}
|
|
2371
2398
|
try {
|
|
2372
|
-
const
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2399
|
+
const tables = await this.lanceClient.tableNames();
|
|
2400
|
+
if (!tables.includes(resolvedTableName)) {
|
|
2401
|
+
this.logger.debug(`Table ${resolvedTableName} does not exist. Returning empty results.`);
|
|
2402
|
+
return [];
|
|
2376
2403
|
}
|
|
2404
|
+
const table = await this.lanceClient.openTable(resolvedTableName);
|
|
2377
2405
|
let query = table.search(queryVector);
|
|
2378
2406
|
if (filter && Object.keys(filter).length > 0) {
|
|
2379
2407
|
const whereClause = this.filterTranslator(filter);
|
|
2380
2408
|
this.logger.debug(`Where clause generated: ${whereClause}`);
|
|
2381
2409
|
query = query.where(whereClause);
|
|
2382
2410
|
}
|
|
2383
|
-
if (!includeAllColumns &&
|
|
2411
|
+
if (!includeAllColumns && columns.length > 0) {
|
|
2412
|
+
const selectColumns = [...columns];
|
|
2413
|
+
if (!selectColumns.includes("id")) {
|
|
2414
|
+
selectColumns.push("id");
|
|
2415
|
+
}
|
|
2384
2416
|
query = query.select(selectColumns);
|
|
2385
2417
|
}
|
|
2386
2418
|
query = query.limit(topK);
|
|
@@ -2410,7 +2442,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2410
2442
|
id: createVectorErrorId("LANCE", "QUERY", "FAILED"),
|
|
2411
2443
|
domain: ErrorDomain.STORAGE,
|
|
2412
2444
|
category: ErrorCategory.THIRD_PARTY,
|
|
2413
|
-
details: { tableName, includeVector, columnsCount: columns?.length, includeAllColumns }
|
|
2445
|
+
details: { tableName: resolvedTableName, includeVector, columnsCount: columns?.length, includeAllColumns }
|
|
2414
2446
|
},
|
|
2415
2447
|
error
|
|
2416
2448
|
);
|
|
@@ -2445,13 +2477,14 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2445
2477
|
const translator = new LanceFilterTranslator();
|
|
2446
2478
|
return translator.translate(prefixedFilter);
|
|
2447
2479
|
}
|
|
2448
|
-
async upsert({ tableName, vectors, metadata = [], ids = [] }) {
|
|
2480
|
+
async upsert({ tableName, indexName, vectors, metadata = [], ids = [] }) {
|
|
2481
|
+
const resolvedTableName = tableName ?? indexName;
|
|
2449
2482
|
try {
|
|
2450
2483
|
if (!this.lanceClient) {
|
|
2451
2484
|
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
2452
2485
|
}
|
|
2453
|
-
if (!
|
|
2454
|
-
throw new Error("tableName is required");
|
|
2486
|
+
if (!resolvedTableName) {
|
|
2487
|
+
throw new Error("tableName or indexName is required");
|
|
2455
2488
|
}
|
|
2456
2489
|
if (!vectors || !Array.isArray(vectors) || vectors.length === 0) {
|
|
2457
2490
|
throw new Error("vectors array is required and must not be empty");
|
|
@@ -2462,18 +2495,21 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2462
2495
|
id: createVectorErrorId("LANCE", "UPSERT", "INVALID_ARGS"),
|
|
2463
2496
|
domain: ErrorDomain.STORAGE,
|
|
2464
2497
|
category: ErrorCategory.USER,
|
|
2465
|
-
text:
|
|
2466
|
-
details: { tableName }
|
|
2498
|
+
text: error instanceof Error ? error.message : "Invalid upsert arguments",
|
|
2499
|
+
details: { tableName: resolvedTableName }
|
|
2467
2500
|
},
|
|
2468
2501
|
error
|
|
2469
2502
|
);
|
|
2470
2503
|
}
|
|
2471
2504
|
try {
|
|
2472
2505
|
const tables = await this.lanceClient.tableNames();
|
|
2473
|
-
|
|
2474
|
-
|
|
2506
|
+
const tableExists = tables.includes(resolvedTableName);
|
|
2507
|
+
let table = null;
|
|
2508
|
+
if (!tableExists) {
|
|
2509
|
+
this.logger.debug(`Table ${resolvedTableName} does not exist. Creating it with the first upsert data.`);
|
|
2510
|
+
} else {
|
|
2511
|
+
table = await this.lanceClient.openTable(resolvedTableName);
|
|
2475
2512
|
}
|
|
2476
|
-
const table = await this.lanceClient.openTable(tableName);
|
|
2477
2513
|
const vectorIds = ids.length === vectors.length ? ids : vectors.map((_, i) => ids[i] || crypto.randomUUID());
|
|
2478
2514
|
const data = vectors.map((vector, i) => {
|
|
2479
2515
|
const id = String(vectorIds[i]);
|
|
@@ -2490,7 +2526,42 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2490
2526
|
}
|
|
2491
2527
|
return rowData;
|
|
2492
2528
|
});
|
|
2493
|
-
|
|
2529
|
+
if (table !== null) {
|
|
2530
|
+
const rowCount = await table.countRows();
|
|
2531
|
+
const schema = await table.schema();
|
|
2532
|
+
const existingColumns = new Set(schema.fields.map((f) => f.name));
|
|
2533
|
+
const dataColumns = new Set(Object.keys(data[0] || {}));
|
|
2534
|
+
const extraColumns = [...dataColumns].filter((col) => !existingColumns.has(col));
|
|
2535
|
+
const missingSchemaColumns = [...existingColumns].filter((col) => !dataColumns.has(col));
|
|
2536
|
+
const hasSchemaMismatch = extraColumns.length > 0 || missingSchemaColumns.length > 0;
|
|
2537
|
+
if (rowCount === 0 && extraColumns.length > 0) {
|
|
2538
|
+
this.logger.warn(
|
|
2539
|
+
`Table ${resolvedTableName} is empty and data has extra columns ${extraColumns.join(", ")}. Recreating with new schema.`
|
|
2540
|
+
);
|
|
2541
|
+
await this.lanceClient.dropTable(resolvedTableName);
|
|
2542
|
+
await this.lanceClient.createTable(resolvedTableName, data);
|
|
2543
|
+
} else if (hasSchemaMismatch) {
|
|
2544
|
+
if (extraColumns.length > 0) {
|
|
2545
|
+
this.logger.warn(
|
|
2546
|
+
`Table ${resolvedTableName} has ${rowCount} rows. Columns ${extraColumns.join(", ")} will be dropped from upsert.`
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
const schemaFieldNames = schema.fields.map((f) => f.name);
|
|
2550
|
+
const normalizedData = data.map((row) => {
|
|
2551
|
+
const normalized = {};
|
|
2552
|
+
for (const col of schemaFieldNames) {
|
|
2553
|
+
normalized[col] = col in row ? row[col] : null;
|
|
2554
|
+
}
|
|
2555
|
+
return normalized;
|
|
2556
|
+
});
|
|
2557
|
+
await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(normalizedData);
|
|
2558
|
+
} else {
|
|
2559
|
+
await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(data);
|
|
2560
|
+
}
|
|
2561
|
+
} else {
|
|
2562
|
+
this.logger.debug(`Creating table ${resolvedTableName} with initial data`);
|
|
2563
|
+
await this.lanceClient.createTable(resolvedTableName, data);
|
|
2564
|
+
}
|
|
2494
2565
|
return vectorIds;
|
|
2495
2566
|
} catch (error) {
|
|
2496
2567
|
throw new MastraError(
|
|
@@ -2498,7 +2569,12 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2498
2569
|
id: createVectorErrorId("LANCE", "UPSERT", "FAILED"),
|
|
2499
2570
|
domain: ErrorDomain.STORAGE,
|
|
2500
2571
|
category: ErrorCategory.THIRD_PARTY,
|
|
2501
|
-
details: {
|
|
2572
|
+
details: {
|
|
2573
|
+
tableName: resolvedTableName,
|
|
2574
|
+
vectorCount: vectors.length,
|
|
2575
|
+
metadataCount: metadata.length,
|
|
2576
|
+
idsCount: ids.length
|
|
2577
|
+
}
|
|
2502
2578
|
},
|
|
2503
2579
|
error
|
|
2504
2580
|
);
|
|
@@ -2595,7 +2671,17 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2595
2671
|
}
|
|
2596
2672
|
}
|
|
2597
2673
|
/**
|
|
2598
|
-
*
|
|
2674
|
+
* Creates a vector index on a table.
|
|
2675
|
+
*
|
|
2676
|
+
* The behavior of `indexName` depends on whether `tableName` is provided:
|
|
2677
|
+
* - With `tableName`: `indexName` is the column to index (advanced use case)
|
|
2678
|
+
* - Without `tableName`: `indexName` becomes the table name, and 'vector' is used as the column (Memory compatibility)
|
|
2679
|
+
*
|
|
2680
|
+
* @param tableName - Optional table name. If not provided, defaults to indexName.
|
|
2681
|
+
* @param indexName - The index/column name, or table name if tableName is not provided.
|
|
2682
|
+
* @param dimension - Vector dimension size.
|
|
2683
|
+
* @param metric - Distance metric: 'cosine', 'euclidean', or 'dotproduct'.
|
|
2684
|
+
* @param indexConfig - Optional index configuration.
|
|
2599
2685
|
*/
|
|
2600
2686
|
async createIndex({
|
|
2601
2687
|
tableName,
|
|
@@ -2604,13 +2690,12 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2604
2690
|
metric = "cosine",
|
|
2605
2691
|
indexConfig = {}
|
|
2606
2692
|
}) {
|
|
2693
|
+
const resolvedTableName = tableName ?? indexName;
|
|
2694
|
+
const columnToIndex = tableName ? indexName : "vector";
|
|
2607
2695
|
try {
|
|
2608
2696
|
if (!this.lanceClient) {
|
|
2609
2697
|
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
2610
2698
|
}
|
|
2611
|
-
if (!tableName) {
|
|
2612
|
-
throw new Error("tableName is required");
|
|
2613
|
-
}
|
|
2614
2699
|
if (!indexName) {
|
|
2615
2700
|
throw new Error("indexName is required");
|
|
2616
2701
|
}
|
|
@@ -2623,19 +2708,33 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2623
2708
|
id: createVectorErrorId("LANCE", "CREATE_INDEX", "INVALID_ARGS"),
|
|
2624
2709
|
domain: ErrorDomain.STORAGE,
|
|
2625
2710
|
category: ErrorCategory.USER,
|
|
2626
|
-
details: { tableName:
|
|
2711
|
+
details: { tableName: resolvedTableName, indexName, dimension, metric }
|
|
2627
2712
|
},
|
|
2628
2713
|
err
|
|
2629
2714
|
);
|
|
2630
2715
|
}
|
|
2631
2716
|
try {
|
|
2632
2717
|
const tables = await this.lanceClient.tableNames();
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2718
|
+
let table;
|
|
2719
|
+
if (!tables.includes(resolvedTableName)) {
|
|
2720
|
+
this.logger.debug(
|
|
2721
|
+
`Table ${resolvedTableName} does not exist. Creating empty table with dimension ${dimension}.`
|
|
2636
2722
|
);
|
|
2723
|
+
const initVector = new Array(dimension).fill(0);
|
|
2724
|
+
table = await this.lanceClient.createTable(resolvedTableName, [{ id: "__init__", vector: initVector }]);
|
|
2725
|
+
try {
|
|
2726
|
+
await table.delete("id = '__init__'");
|
|
2727
|
+
} catch (deleteError) {
|
|
2728
|
+
this.logger.warn(
|
|
2729
|
+
`Failed to delete initialization row from ${resolvedTableName}. Subsequent queries may include '__init__' row.`,
|
|
2730
|
+
deleteError
|
|
2731
|
+
);
|
|
2732
|
+
}
|
|
2733
|
+
this.logger.debug(`Table ${resolvedTableName} created. Index creation deferred until data is available.`);
|
|
2734
|
+
return;
|
|
2735
|
+
} else {
|
|
2736
|
+
table = await this.lanceClient.openTable(resolvedTableName);
|
|
2637
2737
|
}
|
|
2638
|
-
const table = await this.lanceClient.openTable(tableName);
|
|
2639
2738
|
let metricType;
|
|
2640
2739
|
if (metric === "euclidean") {
|
|
2641
2740
|
metricType = "l2";
|
|
@@ -2644,8 +2743,15 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2644
2743
|
} else if (metric === "cosine") {
|
|
2645
2744
|
metricType = "cosine";
|
|
2646
2745
|
}
|
|
2746
|
+
const rowCount = await table.countRows();
|
|
2747
|
+
if (rowCount < 256) {
|
|
2748
|
+
this.logger.warn(
|
|
2749
|
+
`Table ${resolvedTableName} has ${rowCount} rows, which is below the 256 row minimum for index creation. Skipping index creation.`
|
|
2750
|
+
);
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2647
2753
|
if (indexConfig.type === "ivfflat") {
|
|
2648
|
-
await table.createIndex(
|
|
2754
|
+
await table.createIndex(columnToIndex, {
|
|
2649
2755
|
config: Index.ivfPq({
|
|
2650
2756
|
numPartitions: indexConfig.numPartitions || 128,
|
|
2651
2757
|
numSubVectors: indexConfig.numSubVectors || 16,
|
|
@@ -2654,7 +2760,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2654
2760
|
});
|
|
2655
2761
|
} else {
|
|
2656
2762
|
this.logger.debug("Creating HNSW PQ index with config:", indexConfig);
|
|
2657
|
-
await table.createIndex(
|
|
2763
|
+
await table.createIndex(columnToIndex, {
|
|
2658
2764
|
config: Index.hnswPq({
|
|
2659
2765
|
m: indexConfig?.hnsw?.m || 16,
|
|
2660
2766
|
efConstruction: indexConfig?.hnsw?.efConstruction || 100,
|
|
@@ -2668,7 +2774,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2668
2774
|
id: createVectorErrorId("LANCE", "CREATE_INDEX", "FAILED"),
|
|
2669
2775
|
domain: ErrorDomain.STORAGE,
|
|
2670
2776
|
category: ErrorCategory.THIRD_PARTY,
|
|
2671
|
-
details: { tableName:
|
|
2777
|
+
details: { tableName: resolvedTableName, indexName, dimension }
|
|
2672
2778
|
},
|
|
2673
2779
|
error
|
|
2674
2780
|
);
|
|
@@ -2966,7 +3072,7 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2966
3072
|
}
|
|
2967
3073
|
return rowData;
|
|
2968
3074
|
});
|
|
2969
|
-
await table.
|
|
3075
|
+
await table.mergeInsert("id").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(updatedRecords);
|
|
2970
3076
|
return;
|
|
2971
3077
|
}
|
|
2972
3078
|
} catch (err) {
|
|
@@ -3183,6 +3289,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3183
3289
|
}
|
|
3184
3290
|
};
|
|
3185
3291
|
|
|
3186
|
-
export { LanceStorage, LanceVectorStore };
|
|
3292
|
+
export { LanceStorage, LanceVectorStore, StoreMemoryLance, StoreScoresLance, StoreWorkflowsLance };
|
|
3187
3293
|
//# sourceMappingURL=index.js.map
|
|
3188
3294
|
//# sourceMappingURL=index.js.map
|