@happyvertical/smrt-core 0.40.70 → 0.42.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/AGENTS.md +3 -3
- package/agents/change-feed.md +1 -1
- package/agents/schema-paths.md +561 -32
- package/dist/browser.js +5 -4
- package/dist/cascade.d.ts +120 -0
- package/dist/cascade.d.ts.map +1 -0
- package/dist/cascade.js +430 -0
- package/dist/cascade.js.map +1 -0
- package/dist/change-feed.d.ts +34 -2
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +54 -13
- package/dist/change-feed.js.map +1 -1
- package/dist/change-signals.d.ts.map +1 -1
- package/dist/change-signals.js +8 -1
- package/dist/change-signals.js.map +1 -1
- package/dist/class.d.ts +36 -3
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +69 -14
- package/dist/class.js.map +1 -1
- package/dist/collection-cache.js +0 -0
- package/dist/collection-cache.js.map +1 -1
- package/dist/collection.d.ts +29 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +68 -16
- package/dist/collection.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/decorators/index.d.ts +63 -5
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +37 -5
- package/dist/decorators/index.js.map +1 -1
- package/dist/dispatch/collections/Dispatches.d.ts.map +1 -1
- package/dist/dispatch/collections/Dispatches.js +21 -6
- package/dist/dispatch/collections/Dispatches.js.map +1 -1
- package/dist/dispatch/models/Dispatch.d.ts +1 -1
- package/dist/dispatch/models/Dispatch.d.ts.map +1 -1
- package/dist/dispatch/models/Dispatch.js +3 -2
- package/dist/dispatch/models/Dispatch.js.map +1 -1
- package/dist/dispatch/models/DispatchSubscription.d.ts +1 -1
- package/dist/dispatch/models/DispatchSubscription.d.ts.map +1 -1
- package/dist/dispatch/models/DispatchSubscription.js +2 -1
- package/dist/dispatch/models/DispatchSubscription.js.map +1 -1
- package/dist/dispatch/types.d.ts +5 -0
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/embedded-write-queue.d.ts +46 -0
- package/dist/embedded-write-queue.d.ts.map +1 -0
- package/dist/embedded-write-queue.js +66 -0
- package/dist/embedded-write-queue.js.map +1 -0
- package/dist/embeddings/storage.d.ts +7 -0
- package/dist/embeddings/storage.d.ts.map +1 -1
- package/dist/embeddings/storage.js +31 -13
- package/dist/embeddings/storage.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/hierarchical.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/interceptors.d.ts +21 -0
- package/dist/interceptors.d.ts.map +1 -1
- package/dist/interceptors.js +27 -1
- package/dist/interceptors.js.map +1 -1
- package/dist/learning/memory.d.ts.map +1 -1
- package/dist/learning/memory.js +5 -4
- package/dist/learning/memory.js.map +1 -1
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +4 -7
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/static-manifest.js +10 -10
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest.json +19 -19
- package/dist/migrations/differ.d.ts +9 -1
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +12 -7
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -1
- package/dist/migrations/integer-width.d.ts +99 -0
- package/dist/migrations/integer-width.d.ts.map +1 -0
- package/dist/migrations/integer-width.js +237 -0
- package/dist/migrations/integer-width.js.map +1 -0
- package/dist/migrations/minor-units.d.ts +162 -0
- package/dist/migrations/minor-units.d.ts.map +1 -0
- package/dist/migrations/minor-units.js +383 -0
- package/dist/migrations/minor-units.js.map +1 -0
- package/dist/migrations/tracker.d.ts.map +1 -1
- package/dist/migrations/tracker.js +28 -20
- package/dist/migrations/tracker.js.map +1 -1
- package/dist/migrations.js +3 -1
- package/dist/object.d.ts +98 -5
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +138 -30
- package/dist/object.js.map +1 -1
- package/dist/query-bounds.d.ts +5 -1
- package/dist/query-bounds.d.ts.map +1 -1
- package/dist/query-bounds.js +5 -1
- package/dist/query-bounds.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +3 -1
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/manifest-field-merge.d.ts +12 -0
- package/dist/registry/manifest-field-merge.d.ts.map +1 -1
- package/dist/registry/manifest-field-merge.js +14 -2
- package/dist/registry/manifest-field-merge.js.map +1 -1
- package/dist/registry/schema-builder.d.ts +22 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +205 -165
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +3 -2
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +41 -46
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +61 -83
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts +45 -0
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +92 -28
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/schema/conflict-target.d.ts +104 -0
- package/dist/schema/conflict-target.d.ts.map +1 -0
- package/dist/schema/conflict-target.js +129 -0
- package/dist/schema/conflict-target.js.map +1 -0
- package/dist/schema/ddl/duckdb-strategy.d.ts.map +1 -1
- package/dist/schema/ddl/duckdb-strategy.js +3 -1
- package/dist/schema/ddl/duckdb-strategy.js.map +1 -1
- package/dist/schema/ddl/postgres-strategy.d.ts.map +1 -1
- package/dist/schema/ddl/postgres-strategy.js +14 -1
- package/dist/schema/ddl/postgres-strategy.js.map +1 -1
- package/dist/schema/generator.d.ts +245 -41
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +397 -241
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/index-utils.d.ts +120 -0
- package/dist/schema/index-utils.d.ts.map +1 -1
- package/dist/schema/index-utils.js +242 -1
- package/dist/schema/index-utils.js.map +1 -1
- package/dist/schema/index.d.ts +2 -3
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -3
- package/dist/schema/live-parity.d.ts +3 -1
- package/dist/schema/live-parity.d.ts.map +1 -1
- package/dist/schema/live-parity.js +23 -2
- package/dist/schema/live-parity.js.map +1 -1
- package/dist/schema/system-table-shapes.d.ts +13 -0
- package/dist/schema/system-table-shapes.d.ts.map +1 -1
- package/dist/schema/system-table-shapes.js +14 -1
- package/dist/schema/system-table-shapes.js.map +1 -1
- package/dist/schema/types.d.ts +17 -10
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/utils.d.ts +1 -1
- package/dist/schema/utils.d.ts.map +1 -1
- package/dist/schema/utils.js +3 -3
- package/dist/schema/utils.js.map +1 -1
- package/dist/schema.js +2 -3
- package/dist/smrt-knowledge.json +9 -9
- package/dist/system/compatibility.d.ts +42 -0
- package/dist/system/compatibility.d.ts.map +1 -1
- package/dist/system/compatibility.js +182 -9
- package/dist/system/compatibility.js.map +1 -1
- package/dist/system/index.d.ts +1 -0
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +3 -2
- package/dist/system/retention.d.ts +237 -0
- package/dist/system/retention.d.ts.map +1 -0
- package/dist/system/retention.js +497 -0
- package/dist/system/retention.js.map +1 -0
- package/dist/system/schema.d.ts +102 -16
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +85 -47
- package/dist/system/schema.js.map +1 -1
- package/dist/system/types.d.ts +0 -2
- package/dist/system/types.d.ts.map +1 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js.map +1 -1
- package/dist/utils/safe-integer.d.ts +19 -0
- package/dist/utils/safe-integer.d.ts.map +1 -0
- package/dist/utils/safe-integer.js +31 -0
- package/dist/utils/safe-integer.js.map +1 -0
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +6 -3
- package/dist/utils.js.map +1 -1
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +4 -62
- package/dist/vite-plugin/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/schema/override-system.d.ts +0 -43
- package/dist/schema/override-system.d.ts.map +0 -1
- package/dist/schema/override-system.js +0 -205
- package/dist/schema/override-system.js.map +0 -1
package/dist/collection.js
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
|
+
import { chunkArray } from "./utils/chunk.js";
|
|
2
|
+
import { classnameToTablename, toSnakeCase } from "./utils/naming.js";
|
|
1
3
|
import { buildQueryCacheKey, ensureCacheInvalidationListener, getCacheGeneration, getCachedRows, invalidateCollectionCache, registerCrossProcessCacheInterest, resolveDbCacheKey, setCachedRows } from "./collection-cache.js";
|
|
2
|
-
import {
|
|
4
|
+
import { toSafeInteger } from "./utils/safe-integer.js";
|
|
5
|
+
import { isTenantScopedClassResolved, resolveDispatchTenantScope } from "./dispatch/tenant-resolver.js";
|
|
6
|
+
import { GlobalInterceptors, createInterceptorContext, resolveGetStringFilter } from "./interceptors.js";
|
|
3
7
|
import { SmrtClass } from "./class.js";
|
|
4
8
|
import { EmbeddingProvider } from "./embeddings/provider.js";
|
|
5
9
|
import { EmbeddingStorage } from "./embeddings/storage.js";
|
|
6
10
|
import { QueryBoundsError, QueryOrderByError } from "./query-bounds.js";
|
|
7
|
-
import { classnameToTablename, toSnakeCase } from "./utils/naming.js";
|
|
8
11
|
import { verifyPersistenceTable } from "./schema/table-verifier.js";
|
|
9
12
|
import { fieldsFromClass, formatDataJs, toCamelCase } from "./utils.js";
|
|
10
13
|
import { ObjectRegistry } from "./registry.js";
|
|
11
|
-
import { chunkArray } from "./utils/chunk.js";
|
|
12
14
|
import { createLogger } from "@happyvertical/logger";
|
|
13
15
|
import { buildWhere } from "@happyvertical/sql";
|
|
14
16
|
//#region src/collection.ts
|
|
15
17
|
var logger = createLogger({ level: "info" });
|
|
16
18
|
/**
|
|
19
|
+
* `_smrt_contexts.owner_id` value for collection-level (as opposed to
|
|
20
|
+
* per-object) memory. Tenant-scoped collections suffix the active tenant id
|
|
21
|
+
* (`__collection__:<tenantId>`) so learned memory never crosses tenants —
|
|
22
|
+
* see {@link SmrtCollection.resolveCollectionMemoryOwnerId} (#2365).
|
|
23
|
+
*/
|
|
24
|
+
var COLLECTION_MEMORY_OWNER_ID = "__collection__";
|
|
25
|
+
/**
|
|
17
26
|
* Validate an optional collection-level list bound (#2367).
|
|
18
27
|
*
|
|
19
28
|
* @returns the bound, or `undefined` when the option was not supplied
|
|
@@ -752,10 +761,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
752
761
|
const itemQualifiedName = this.getResolvedItemQualifiedName();
|
|
753
762
|
const interceptorContext = createInterceptorContext(itemClassName, "get", this.constructor.name);
|
|
754
763
|
const interceptedFilter = await GlobalInterceptors.executeBeforeGet(itemClassName, filter, interceptorContext);
|
|
755
|
-
let where = typeof interceptedFilter === "string" ?
|
|
756
|
-
slug: interceptedFilter,
|
|
757
|
-
context: ""
|
|
758
|
-
} : interceptedFilter;
|
|
764
|
+
let where = typeof interceptedFilter === "string" ? resolveGetStringFilter(interceptedFilter) : interceptedFilter;
|
|
759
765
|
const isSTI = ObjectRegistry.getTableStrategy(itemQualifiedName) === "sti";
|
|
760
766
|
if (isSTI) {
|
|
761
767
|
const stiBase = ObjectRegistry.getSTIBase(itemQualifiedName);
|
|
@@ -1361,8 +1367,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1361
1367
|
}
|
|
1362
1368
|
where = resolveMetaTypeInWhere(where);
|
|
1363
1369
|
const { sql: whereSql, values: whereValues } = buildWhere(this.convertWhereKeys(where || {}));
|
|
1364
|
-
|
|
1365
|
-
return Number.parseInt(result.rows[0].count, 10);
|
|
1370
|
+
return toSafeInteger((await this.db.query(`SELECT COUNT(*) as count FROM ${this.tableName} ${whereSql}`, ...whereValues)).rows[0].count, "Collection count");
|
|
1366
1371
|
}
|
|
1367
1372
|
/**
|
|
1368
1373
|
* Resolve this collection's STI child discriminator — the qualified item
|
|
@@ -1470,11 +1475,41 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1470
1475
|
return instances;
|
|
1471
1476
|
}
|
|
1472
1477
|
/**
|
|
1478
|
+
* Resolve the `_smrt_contexts.owner_id` key for collection-level memory
|
|
1479
|
+
* (#2365).
|
|
1480
|
+
*
|
|
1481
|
+
* `_smrt_contexts` has no tenant column, so before this hook a tenant-scoped
|
|
1482
|
+
* collection's learned memory (`remember()`/`recall()`) was filed under one
|
|
1483
|
+
* shared `__collection__` key and leaked across tenants. For a tenant-scoped
|
|
1484
|
+
* item class under an active tenant context the key becomes
|
|
1485
|
+
* `__collection__:<tenantId>`; everything else (tenancy disabled, no active
|
|
1486
|
+
* tenant, system context, non-tenant-scoped class) keeps the shared
|
|
1487
|
+
* `__collection__` key. Tenant-keyed memory is strictly isolated — a tenant
|
|
1488
|
+
* recall does NOT fall back to the shared key, so memory learned outside a
|
|
1489
|
+
* tenant context is invisible inside one (and vice versa).
|
|
1490
|
+
*
|
|
1491
|
+
* Tenant resolution uses the same core-side trust anchors as the generated
|
|
1492
|
+
* REST read scope (#1782): `resolveDispatchTenantScope()` for the active
|
|
1493
|
+
* tenant and the triple tenant-scoped-class check covering `@smrt()` config,
|
|
1494
|
+
* manifest config, and the tenancy-filled `@TenantScoped()` resolver.
|
|
1495
|
+
*/
|
|
1496
|
+
resolveCollectionMemoryOwnerId() {
|
|
1497
|
+
const itemClassName = this.getResolvedItemClassName();
|
|
1498
|
+
if (!(ObjectRegistry.isTenantScoped(itemClassName) || !!ObjectRegistry.getConfig(itemClassName)?.tenantScoped || isTenantScopedClassResolved(itemClassName))) return COLLECTION_MEMORY_OWNER_ID;
|
|
1499
|
+
const scope = resolveDispatchTenantScope();
|
|
1500
|
+
if (!scope.enforced || !scope.tenantId) return COLLECTION_MEMORY_OWNER_ID;
|
|
1501
|
+
return `${COLLECTION_MEMORY_OWNER_ID}:${scope.tenantId}`;
|
|
1502
|
+
}
|
|
1503
|
+
/**
|
|
1473
1504
|
* Remember collection-level context
|
|
1474
1505
|
*
|
|
1475
1506
|
* Stores context applicable to all instances of this collection type.
|
|
1476
1507
|
* Use for patterns that apply to the entire collection (e.g., default parsing strategies).
|
|
1477
1508
|
*
|
|
1509
|
+
* Under an active tenant context on a tenant-scoped class, memory is keyed
|
|
1510
|
+
* per tenant and never shared across tenants (#2365) — see
|
|
1511
|
+
* {@link resolveCollectionMemoryOwnerId}.
|
|
1512
|
+
*
|
|
1478
1513
|
* `expiresAt` is stored on the `_smrt_contexts` row as caller-managed metadata.
|
|
1479
1514
|
* {@link recall} and {@link recallAll} do **not** filter on it, so an expired
|
|
1480
1515
|
* entry is still returned; filter or delete expired entries yourself.
|
|
@@ -1514,7 +1549,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1514
1549
|
], {
|
|
1515
1550
|
id,
|
|
1516
1551
|
owner_class: this._itemClass.name,
|
|
1517
|
-
owner_id:
|
|
1552
|
+
owner_id: this.resolveCollectionMemoryOwnerId(),
|
|
1518
1553
|
scope: options.scope,
|
|
1519
1554
|
key: options.key,
|
|
1520
1555
|
value: JSON.stringify(options.value),
|
|
@@ -1548,12 +1583,13 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1548
1583
|
*/
|
|
1549
1584
|
async recall(options) {
|
|
1550
1585
|
if (!this.systemDb) throw new Error("Database not initialized. Call initialize() first.");
|
|
1586
|
+
const ownerId = this.resolveCollectionMemoryOwnerId();
|
|
1551
1587
|
let result;
|
|
1552
1588
|
if (options.minConfidence !== void 0) result = await this.systemDb.single`
|
|
1553
1589
|
SELECT value, confidence
|
|
1554
1590
|
FROM _smrt_contexts
|
|
1555
1591
|
WHERE owner_class = ${this._itemClass.name}
|
|
1556
|
-
AND owner_id = ${
|
|
1592
|
+
AND owner_id = ${ownerId}
|
|
1557
1593
|
AND scope = ${options.scope}
|
|
1558
1594
|
AND key = ${options.key}
|
|
1559
1595
|
AND confidence >= ${options.minConfidence}
|
|
@@ -1564,7 +1600,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1564
1600
|
SELECT value, confidence
|
|
1565
1601
|
FROM _smrt_contexts
|
|
1566
1602
|
WHERE owner_class = ${this._itemClass.name}
|
|
1567
|
-
AND owner_id = ${
|
|
1603
|
+
AND owner_id = ${ownerId}
|
|
1568
1604
|
AND scope = ${options.scope}
|
|
1569
1605
|
AND key = ${options.key}
|
|
1570
1606
|
ORDER BY confidence DESC, version DESC
|
|
@@ -1619,7 +1655,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1619
1655
|
FROM _smrt_contexts
|
|
1620
1656
|
WHERE owner_class = ? AND owner_id = ?
|
|
1621
1657
|
`;
|
|
1622
|
-
const params = [this._itemClass.name,
|
|
1658
|
+
const params = [this._itemClass.name, this.resolveCollectionMemoryOwnerId()];
|
|
1623
1659
|
if (options.scope) if (options.includeDescendants) {
|
|
1624
1660
|
query += ` AND (scope = ? OR scope LIKE ?)`;
|
|
1625
1661
|
params.push(options.scope, `${options.scope}/%`);
|
|
@@ -1664,7 +1700,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1664
1700
|
async forget(options) {
|
|
1665
1701
|
if (!this.systemDb) throw new Error("Database not initialized. Call initialize() first.");
|
|
1666
1702
|
await this.systemDb.query(`DELETE FROM _smrt_contexts
|
|
1667
|
-
WHERE owner_class = ? AND owner_id = ? AND scope = ? AND key = ?`, this._itemClass.name,
|
|
1703
|
+
WHERE owner_class = ? AND owner_id = ? AND scope = ? AND key = ?`, this._itemClass.name, this.resolveCollectionMemoryOwnerId(), options.scope, options.key);
|
|
1668
1704
|
}
|
|
1669
1705
|
/**
|
|
1670
1706
|
* Forget all collection-level context in a scope
|
|
@@ -1688,7 +1724,7 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1688
1724
|
DELETE FROM _smrt_contexts
|
|
1689
1725
|
WHERE owner_class = ? AND owner_id = ?
|
|
1690
1726
|
`;
|
|
1691
|
-
const params = [this._itemClass.name,
|
|
1727
|
+
const params = [this._itemClass.name, this.resolveCollectionMemoryOwnerId()];
|
|
1692
1728
|
if (options.includeDescendants) {
|
|
1693
1729
|
query += ` AND (scope = ? OR scope LIKE ?)`;
|
|
1694
1730
|
params.push(options.scope, `${options.scope}/%`);
|
|
@@ -1705,6 +1741,11 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1705
1741
|
* Generates an embedding for the query text and finds similar objects
|
|
1706
1742
|
* based on cosine similarity of stored embeddings.
|
|
1707
1743
|
*
|
|
1744
|
+
* Under an active tenant context on a tenant-scoped class, candidates are
|
|
1745
|
+
* restricted to the tenant's rows BEFORE top-K ranking (#2365), so results
|
|
1746
|
+
* are never starved by — and similarity ranks never leak — other tenants'
|
|
1747
|
+
* content.
|
|
1748
|
+
*
|
|
1708
1749
|
* @param query - Text to search for
|
|
1709
1750
|
* @param options - Search options
|
|
1710
1751
|
* @param options.field - Specific field to search (defaults to first embedding
|
|
@@ -1837,11 +1878,22 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1837
1878
|
fallbackToAI: embeddingConfig.fallbackToAI
|
|
1838
1879
|
}, this.ai).getModelName();
|
|
1839
1880
|
const vector = (ObjectRegistry.getProjectEmbeddingConfig()?.storage || "json") === "native" ? this.systemDb.vector : void 0;
|
|
1881
|
+
const itemClassName = this.getResolvedItemClassName();
|
|
1882
|
+
const tenantPrefilterContext = createInterceptorContext(itemClassName, "list", this.constructor.name);
|
|
1883
|
+
const tenantPrefilter = await GlobalInterceptors.executeBeforeList(itemClassName, { where: {} }, tenantPrefilterContext);
|
|
1884
|
+
let candidateObjectIds;
|
|
1885
|
+
if (tenantPrefilter.where && Object.keys(tenantPrefilter.where).length > 0) {
|
|
1886
|
+
const { sql: candidateWhereSql, values: candidateValues } = buildWhere(this.convertWhereKeys(tenantPrefilter.where));
|
|
1887
|
+
const { rows: candidateRows } = await this.db.query(`SELECT id FROM ${this.tableName} ${candidateWhereSql}`, ...candidateValues);
|
|
1888
|
+
candidateObjectIds = candidateRows.map((row) => String(row.id));
|
|
1889
|
+
if (candidateObjectIds.length === 0) return [];
|
|
1890
|
+
}
|
|
1840
1891
|
const scored = await EmbeddingStorage.searchSimilar(this.systemDb, this._itemClass.name, embedding, {
|
|
1841
1892
|
field: searchField,
|
|
1842
1893
|
model,
|
|
1843
1894
|
limit,
|
|
1844
|
-
minSimilarity
|
|
1895
|
+
minSimilarity,
|
|
1896
|
+
objectIds: candidateObjectIds
|
|
1845
1897
|
}, vector);
|
|
1846
1898
|
if (scored.length === 0) return [];
|
|
1847
1899
|
const objectIds = scored.map((s) => s.objectId);
|