@equationalapplications/core-llm-wiki 4.3.0 → 4.4.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/dist/index.mjs CHANGED
@@ -1058,14 +1058,14 @@ After running the migration SQL, restart your application.`
1058
1058
  );
1059
1059
  }
1060
1060
  }
1061
- const entityScope = this._entityInClause(scoredEntityIds);
1061
+ const mismatchScope = this._entityInClause(entityIds);
1062
1062
  const mismatchedCount = await this.db.getFirstAsync(
1063
1063
  `SELECT COUNT(*) AS cnt FROM ${this.prefix}entries
1064
- WHERE ${entityScope.clause} AND deleted_at IS NULL
1064
+ WHERE ${mismatchScope.clause} AND deleted_at IS NULL
1065
1065
  AND embedding_blob IS NOT NULL
1066
1066
  AND (CAST(length(embedding_blob) AS INTEGER) % 4 = 0)
1067
1067
  AND (CAST(length(embedding_blob) AS INTEGER) / 4) != ?`,
1068
- [...entityScope.params, queryVec.length]
1068
+ [...mismatchScope.params, queryVec.length]
1069
1069
  );
1070
1070
  if (mismatchedCount && mismatchedCount.cnt > 0) {
1071
1071
  throw new Error(
@@ -1125,16 +1125,16 @@ After running the migration SQL, restart your application.`
1125
1125
  }
1126
1126
  } else {
1127
1127
  if (useRanker) {
1128
- const entityScope2 = this._entityInClause(scoredEntityIds);
1128
+ const entityScope = this._entityInClause(scoredEntityIds);
1129
1129
  candidateRows = await this.db.getAllAsync(
1130
- `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope2.clause} AND deleted_at IS NULL`,
1131
- entityScope2.params
1130
+ `SELECT id, entity_id, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,
1131
+ entityScope.params
1132
1132
  );
1133
1133
  } else {
1134
- const entityScope2 = this._entityInClause(scoredEntityIds);
1134
+ const entityScope = this._entityInClause(scoredEntityIds);
1135
1135
  candidateRows = await this.db.getAllAsync(
1136
- `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope2.clause} AND deleted_at IS NULL`,
1137
- entityScope2.params
1136
+ `SELECT id, entity_id, embedding_blob, embedding, updated_at, access_count FROM ${this.prefix}entries WHERE ${entityScope.clause} AND deleted_at IS NULL`,
1137
+ entityScope.params
1138
1138
  );
1139
1139
  }
1140
1140
  if (weight !== void 0 && weight < 1) {
@@ -1153,32 +1153,42 @@ After running the migration SQL, restart your application.`
1153
1153
  const entityCacheKey = entityIds.length === 1 ? entityIds[0] : entityIds.join("\0");
1154
1154
  let scored;
1155
1155
  if (useRanker) {
1156
- const candidateIds = entityIds.length > 1 || effectivePreFilterLimit !== void 0 ? candidateRows.map((r) => r.id) : void 0;
1156
+ const candidateRowsByEntity = /* @__PURE__ */ new Map();
1157
+ for (const row of candidateRows) {
1158
+ const rows = candidateRowsByEntity.get(row.entity_id) ?? [];
1159
+ rows.push(row);
1160
+ candidateRowsByEntity.set(row.entity_id, rows);
1161
+ }
1157
1162
  try {
1158
- const oversampledLimit = Math.max(maxResults * 2, maxResults + 50);
1159
- scored = await this._rankWithVectorRanker({
1160
- entityId: entityCacheKey,
1161
- queryVec,
1162
- candidateIds,
1163
- candidateRows,
1164
- weight,
1165
- miniSearchScores,
1166
- limit: oversampledLimit
1167
- });
1168
- if (scored.length > 0) {
1169
- const scoredIds2 = new Set(scored.map((s) => s.id));
1170
- const metaMap = /* @__PURE__ */ new Map();
1171
- for (const r of candidateRows) {
1172
- if (scoredIds2.has(r.id)) {
1173
- metaMap.set(r.id, { updated_at: r.updated_at, access_count: r.access_count });
1174
- }
1175
- }
1176
- scored = scored.map((s) => {
1177
- const meta = metaMap.get(s.id);
1178
- return { ...s, updated_at: meta?.updated_at ?? null, access_count: meta?.access_count ?? null };
1179
- });
1180
- }
1163
+ const rankerResultsByEntity = await Promise.all(
1164
+ scoredEntityIds.filter((id) => (candidateRowsByEntity.get(id)?.length ?? 0) > 0).map(async (scopedEntityId) => {
1165
+ const rowsForEntity = candidateRowsByEntity.get(scopedEntityId) ?? [];
1166
+ const candidateIds = effectivePreFilterLimit !== void 0 ? rowsForEntity.map((row) => row.id) : void 0;
1167
+ const ranked = await this._rankWithVectorRanker({
1168
+ entityId: scopedEntityId,
1169
+ queryVec,
1170
+ candidateIds,
1171
+ candidateRows: rowsForEntity,
1172
+ weight,
1173
+ miniSearchScores,
1174
+ limit: Math.max(maxResults * 2, maxResults + 50)
1175
+ });
1176
+ return ranked.map((row) => ({ ...row, entity_id: scopedEntityId }));
1177
+ })
1178
+ );
1179
+ scored = rankerResultsByEntity.flat();
1181
1180
  const scoredIds = new Set(scored.map((s) => s.id));
1181
+ const metadataById = new Map(
1182
+ candidateRows.filter((row) => scoredIds.has(row.id)).map((row) => [row.id, row])
1183
+ );
1184
+ scored = scored.map((row) => {
1185
+ const metadata = metadataById.get(row.id);
1186
+ return {
1187
+ ...row,
1188
+ updated_at: metadata?.updated_at ?? null,
1189
+ access_count: metadata?.access_count ?? null
1190
+ };
1191
+ });
1182
1192
  const isHybrid = weight !== void 0 && weight < 1;
1183
1193
  const maxBackfill = isHybrid ? maxResults : Math.max(0, maxResults - scored.length);
1184
1194
  if (maxBackfill > 0) {
@@ -1326,21 +1336,17 @@ After running the migration SQL, restart your application.`
1326
1336
  });
1327
1337
  const keywordOversampledLimit = Math.max(maxResults * 2, maxResults + 50);
1328
1338
  const topResults = msResults.slice(0, keywordOversampledLimit);
1329
- const resultIds = new Set(topResults.map((r) => r.id));
1330
- const candidateMap = /* @__PURE__ */ new Map();
1331
- for (const r of candidateRows) {
1332
- if (resultIds.has(r.id)) {
1333
- candidateMap.set(r.id, { entity_id: r.entity_id, updated_at: r.updated_at, access_count: r.access_count });
1334
- }
1335
- }
1336
- scored = topResults.map((r) => {
1337
- const meta = candidateMap.get(r.id);
1339
+ const topResultIds = new Set(topResults.map((r) => r.id));
1340
+ const candidateMap = new Map(candidateRows.filter((r) => topResultIds.has(r.id)).map((row) => [row.id, row]));
1341
+ scored = topResults.map((result) => {
1342
+ const metadata = candidateMap.get(result.id);
1343
+ const entityForScore = metadata?.entity_id ?? result.entity_id ?? "";
1338
1344
  return {
1339
- id: r.id,
1340
- entity_id: meta?.entity_id ?? r.entity_id,
1341
- score: r.score ?? 0,
1342
- access_count: meta?.access_count ?? null,
1343
- updated_at: meta?.updated_at ?? null
1345
+ id: result.id,
1346
+ entity_id: entityForScore,
1347
+ score: result.score ?? 0,
1348
+ access_count: metadata?.access_count ?? null,
1349
+ updated_at: metadata?.updated_at ?? null
1344
1350
  };
1345
1351
  });
1346
1352
  } else {