@equationalapplications/core-llm-wiki 7.7.5 → 7.7.6
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/{chunk-JV2OQ5CM.mjs → chunk-PBUZLSOM.mjs} +127 -8
- package/dist/chunk-PBUZLSOM.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +158 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-CH_Kk34-.d.mts → testing-BIFNLUva.d.mts} +69 -0
- package/dist/{testing-CH_Kk34-.d.ts → testing-BIFNLUva.d.ts} +69 -0
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +125 -6
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-JV2OQ5CM.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { C as ChunkFailure, d as ClassifierAnswer, e as ClassifierQuestion, f as ClassifyRequest, g as ClassifyResponse, D as DegradedRecord, h as DraftPage, E as EmbedFactResult, i as EmbedFailureKind, j as EmbeddingMarkerKind, k as EntityStatus, l as ExtractedFact, m as ExtractedFactEdge, n as ExtractedFactWithOntology, o as ExtractedTask, p as GraphTraversalOptions, q as GroundingConfig, H as HEAL_BATCH_SIZE, r as HEAL_RECHECK_MS, s as HOOK_TIMEOUT_MARKER, t as HealResult, I as IngestDocumentResult, L as LLMProvider, O as ONTOLOGY_BACKFILL_BATCH_SIZE, u as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, v as ONTOLOGY_BACKFILL_RECHECK_MS, w as OntologyBackfillResult, x as OntologyConfig, y as OntologyEdgeType, z as OntologyManifest, A as OntologyMode, B as OntologyNodeType, J as OntologyPromptContext, K as OntologyUpdates, P as PendingSourceStatus, N as PromptOverrides, Q as PromptService, T as PrunePartialFailureError, U as ReembedResult, V as VectorRanker, X as VectorRankerFallback, Y as VectorRankerRankArgs, Z as VectorRankerSemanticResult, _ as WikiBusyError, $ as WikiBusyOperation, a0 as WikiCheckpoint, a1 as WikiConfig, a2 as WikiDiagnostic, a3 as WikiDiagnosticCode, a4 as WikiDiagnosticDetail, a5 as WikiDiagnosticOperation, a6 as WikiDiagnosticSeverity, a7 as WikiDiagnosticTrigger, a8 as WikiDraftNotFound, a9 as WikiDuplicateHashError, aa as WikiEdge, ab as WikiEvent, ac as WikiFact, ad as WikiGraphNodeOwnershipConflict, ae as WikiIngestEmptyError, af as WikiInstructions, ag as WikiInvalidReadOptions, ah as WikiLintReport, ai as WikiMemoryTestAccess, aj as WikiOutboxEvent, ak as WikiParseError, al as WikiSourceRefHashCollision, am as WikiStrictOntologyViolation, an as WikiTask, ao as WikiTransactionError, ap as validateManifest } from './testing-
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-BIFNLUva.mjs';
|
|
2
|
+
export { C as ChunkFailure, d as ClassifierAnswer, e as ClassifierQuestion, f as ClassifyRequest, g as ClassifyResponse, D as DegradedRecord, h as DraftPage, E as EmbedFactResult, i as EmbedFailureKind, j as EmbeddingMarkerKind, k as EntityStatus, l as ExtractedFact, m as ExtractedFactEdge, n as ExtractedFactWithOntology, o as ExtractedTask, p as GraphTraversalOptions, q as GroundingConfig, H as HEAL_BATCH_SIZE, r as HEAL_RECHECK_MS, s as HOOK_TIMEOUT_MARKER, t as HealResult, I as IngestDocumentResult, L as LLMProvider, O as ONTOLOGY_BACKFILL_BATCH_SIZE, u as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, v as ONTOLOGY_BACKFILL_RECHECK_MS, w as OntologyBackfillResult, x as OntologyConfig, y as OntologyEdgeType, z as OntologyManifest, A as OntologyMode, B as OntologyNodeType, J as OntologyPromptContext, K as OntologyUpdates, P as PendingSourceStatus, N as PromptOverrides, Q as PromptService, T as PrunePartialFailureError, U as ReembedResult, V as VectorRanker, X as VectorRankerFallback, Y as VectorRankerRankArgs, Z as VectorRankerSemanticResult, _ as WikiBusyError, $ as WikiBusyOperation, a0 as WikiCheckpoint, a1 as WikiConfig, a2 as WikiDiagnostic, a3 as WikiDiagnosticCode, a4 as WikiDiagnosticDetail, a5 as WikiDiagnosticOperation, a6 as WikiDiagnosticSeverity, a7 as WikiDiagnosticTrigger, a8 as WikiDraftNotFound, a9 as WikiDuplicateHashError, aa as WikiEdge, ab as WikiEvent, ac as WikiFact, ad as WikiGraphNodeOwnershipConflict, ae as WikiIngestEmptyError, af as WikiInstructions, ag as WikiInvalidReadOptions, ah as WikiLintReport, ai as WikiMemoryTestAccess, aj as WikiOutboxEvent, ak as WikiParseError, al as WikiSourceRefHashCollision, am as WikiStrictOntologyViolation, an as WikiTask, ao as WikiTransactionError, ap as validateManifest } from './testing-BIFNLUva.mjs';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { C as ChunkFailure, d as ClassifierAnswer, e as ClassifierQuestion, f as ClassifyRequest, g as ClassifyResponse, D as DegradedRecord, h as DraftPage, E as EmbedFactResult, i as EmbedFailureKind, j as EmbeddingMarkerKind, k as EntityStatus, l as ExtractedFact, m as ExtractedFactEdge, n as ExtractedFactWithOntology, o as ExtractedTask, p as GraphTraversalOptions, q as GroundingConfig, H as HEAL_BATCH_SIZE, r as HEAL_RECHECK_MS, s as HOOK_TIMEOUT_MARKER, t as HealResult, I as IngestDocumentResult, L as LLMProvider, O as ONTOLOGY_BACKFILL_BATCH_SIZE, u as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, v as ONTOLOGY_BACKFILL_RECHECK_MS, w as OntologyBackfillResult, x as OntologyConfig, y as OntologyEdgeType, z as OntologyManifest, A as OntologyMode, B as OntologyNodeType, J as OntologyPromptContext, K as OntologyUpdates, P as PendingSourceStatus, N as PromptOverrides, Q as PromptService, T as PrunePartialFailureError, U as ReembedResult, V as VectorRanker, X as VectorRankerFallback, Y as VectorRankerRankArgs, Z as VectorRankerSemanticResult, _ as WikiBusyError, $ as WikiBusyOperation, a0 as WikiCheckpoint, a1 as WikiConfig, a2 as WikiDiagnostic, a3 as WikiDiagnosticCode, a4 as WikiDiagnosticDetail, a5 as WikiDiagnosticOperation, a6 as WikiDiagnosticSeverity, a7 as WikiDiagnosticTrigger, a8 as WikiDraftNotFound, a9 as WikiDuplicateHashError, aa as WikiEdge, ab as WikiEvent, ac as WikiFact, ad as WikiGraphNodeOwnershipConflict, ae as WikiIngestEmptyError, af as WikiInstructions, ag as WikiInvalidReadOptions, ah as WikiLintReport, ai as WikiMemoryTestAccess, aj as WikiOutboxEvent, ak as WikiParseError, al as WikiSourceRefHashCollision, am as WikiStrictOntologyViolation, an as WikiTask, ao as WikiTransactionError, ap as validateManifest } from './testing-
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-BIFNLUva.js';
|
|
2
|
+
export { C as ChunkFailure, d as ClassifierAnswer, e as ClassifierQuestion, f as ClassifyRequest, g as ClassifyResponse, D as DegradedRecord, h as DraftPage, E as EmbedFactResult, i as EmbedFailureKind, j as EmbeddingMarkerKind, k as EntityStatus, l as ExtractedFact, m as ExtractedFactEdge, n as ExtractedFactWithOntology, o as ExtractedTask, p as GraphTraversalOptions, q as GroundingConfig, H as HEAL_BATCH_SIZE, r as HEAL_RECHECK_MS, s as HOOK_TIMEOUT_MARKER, t as HealResult, I as IngestDocumentResult, L as LLMProvider, O as ONTOLOGY_BACKFILL_BATCH_SIZE, u as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, v as ONTOLOGY_BACKFILL_RECHECK_MS, w as OntologyBackfillResult, x as OntologyConfig, y as OntologyEdgeType, z as OntologyManifest, A as OntologyMode, B as OntologyNodeType, J as OntologyPromptContext, K as OntologyUpdates, P as PendingSourceStatus, N as PromptOverrides, Q as PromptService, T as PrunePartialFailureError, U as ReembedResult, V as VectorRanker, X as VectorRankerFallback, Y as VectorRankerRankArgs, Z as VectorRankerSemanticResult, _ as WikiBusyError, $ as WikiBusyOperation, a0 as WikiCheckpoint, a1 as WikiConfig, a2 as WikiDiagnostic, a3 as WikiDiagnosticCode, a4 as WikiDiagnosticDetail, a5 as WikiDiagnosticOperation, a6 as WikiDiagnosticSeverity, a7 as WikiDiagnosticTrigger, a8 as WikiDraftNotFound, a9 as WikiDuplicateHashError, aa as WikiEdge, ab as WikiEvent, ac as WikiFact, ad as WikiGraphNodeOwnershipConflict, ae as WikiIngestEmptyError, af as WikiInstructions, ag as WikiInvalidReadOptions, ah as WikiLintReport, ai as WikiMemoryTestAccess, aj as WikiOutboxEvent, ak as WikiParseError, al as WikiSourceRefHashCollision, am as WikiStrictOntologyViolation, an as WikiTask, ao as WikiTransactionError, ap as validateManifest } from './testing-BIFNLUva.js';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -744,7 +744,7 @@ function mapRowToFactWithBlobs(row) {
|
|
|
744
744
|
const embeddingBlob = normalizeEmbeddingBlobValue(row.embedding_blob);
|
|
745
745
|
return embeddingBlob ? { ...base, embedding_blob: embeddingBlob } : base;
|
|
746
746
|
}
|
|
747
|
-
var
|
|
747
|
+
var _EntryRepository = class _EntryRepository extends BaseRepository {
|
|
748
748
|
constructor(db, prefix, outbox) {
|
|
749
749
|
super(db, prefix);
|
|
750
750
|
this.outbox = outbox;
|
|
@@ -1429,14 +1429,34 @@ var EntryRepository = class extends BaseRepository {
|
|
|
1429
1429
|
const executor = this.getExecutor(tx);
|
|
1430
1430
|
if (entityId !== void 0) {
|
|
1431
1431
|
return executor.getAllAsync(
|
|
1432
|
-
`SELECT
|
|
1432
|
+
`SELECT ${_EntryRepository.MINI_SEARCH_COLUMNS} FROM ${this.prefix}entries ${_EntryRepository.MINI_SEARCH_LIVE_WHERE} AND entity_id = ?`,
|
|
1433
1433
|
[entityId]
|
|
1434
1434
|
);
|
|
1435
1435
|
}
|
|
1436
1436
|
return executor.getAllAsync(
|
|
1437
|
-
`SELECT
|
|
1437
|
+
`SELECT ${_EntryRepository.MINI_SEARCH_COLUMNS} FROM ${this.prefix}entries ${_EntryRepository.MINI_SEARCH_LIVE_WHERE}`
|
|
1438
1438
|
);
|
|
1439
1439
|
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Keyword-index rows for specific ids — the incremental counterpart of
|
|
1442
|
+
* {@link findMiniSearchRows}, with identical columns. Soft-deleted rows and
|
|
1443
|
+
* rows of other entities are omitted, so a caller can pass every id a write
|
|
1444
|
+
* touched and get back exactly what should be indexed. Spec 2026-09-28 §4.4.
|
|
1445
|
+
*/
|
|
1446
|
+
async findMiniSearchRowsByIds(entityId, ids, tx) {
|
|
1447
|
+
if (ids.length === 0) return [];
|
|
1448
|
+
const executor = this.getExecutor(tx);
|
|
1449
|
+
const rows = [];
|
|
1450
|
+
for (let i = 0; i < ids.length; i += this.chunkSize) {
|
|
1451
|
+
const chunk = ids.slice(i, i + this.chunkSize);
|
|
1452
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
1453
|
+
rows.push(...await executor.getAllAsync(
|
|
1454
|
+
`SELECT ${_EntryRepository.MINI_SEARCH_COLUMNS} FROM ${this.prefix}entries ${_EntryRepository.MINI_SEARCH_LIVE_WHERE} AND entity_id = ? AND id IN (${placeholders})`,
|
|
1455
|
+
[entityId, ...chunk]
|
|
1456
|
+
));
|
|
1457
|
+
}
|
|
1458
|
+
return rows;
|
|
1459
|
+
}
|
|
1440
1460
|
async updateEmbeddingBlob(id, blob, tx) {
|
|
1441
1461
|
const executor = this.getExecutor(tx);
|
|
1442
1462
|
await executor.runAsync(
|
|
@@ -1977,6 +1997,15 @@ var EntryRepository = class extends BaseRepository {
|
|
|
1977
1997
|
return rows.map((r) => ({ id: r.id, title: r.title }));
|
|
1978
1998
|
}
|
|
1979
1999
|
};
|
|
2000
|
+
/**
|
|
2001
|
+
* Column list and liveness predicate shared by findMiniSearchRows and
|
|
2002
|
+
* findMiniSearchRowsByIds, so the full rebuild and the incremental read
|
|
2003
|
+
* can never drift apart (spec 2026-09-28 §4.4: both must produce
|
|
2004
|
+
* identical documents).
|
|
2005
|
+
*/
|
|
2006
|
+
_EntryRepository.MINI_SEARCH_COLUMNS = "id, entity_id, title, body, tags";
|
|
2007
|
+
_EntryRepository.MINI_SEARCH_LIVE_WHERE = "WHERE deleted_at IS NULL";
|
|
2008
|
+
var EntryRepository = _EntryRepository;
|
|
1980
2009
|
|
|
1981
2010
|
// src/utils/ids.ts
|
|
1982
2011
|
var _injectedGetRandomValues = null;
|
|
@@ -3113,7 +3142,31 @@ var _SearchService = class _SearchService {
|
|
|
3113
3142
|
* auto-vacuum debt behind the TypeError in #64.
|
|
3114
3143
|
*/
|
|
3115
3144
|
this.syncChain = Promise.resolve();
|
|
3116
|
-
|
|
3145
|
+
/**
|
|
3146
|
+
* Entities whose index may have drifted from SQLite: an incremental update
|
|
3147
|
+
* failed part-way, or core wrote rows it could not index (upsertGraph runs in
|
|
3148
|
+
* the host's transaction). Their next syncEntries rebuilds the entity in full.
|
|
3149
|
+
* See spec 2026-09-28 §5.
|
|
3150
|
+
*/
|
|
3151
|
+
this.staleEntities = /* @__PURE__ */ new Set();
|
|
3152
|
+
/**
|
|
3153
|
+
* Per-entity count of markStale() calls. A rebuild clears an entity's stale
|
|
3154
|
+
* flag only when the count it snapshotted before its read still holds
|
|
3155
|
+
* afterwards: markStale() runs inside the host's still-open transaction, so
|
|
3156
|
+
* a call landing mid-read belongs to rows the read cannot have seen, and
|
|
3157
|
+
* its flag must outlive the turn (#233 review).
|
|
3158
|
+
*/
|
|
3159
|
+
this.staleEpochs = /* @__PURE__ */ new Map();
|
|
3160
|
+
this.miniSearch = this.createMiniSearch();
|
|
3161
|
+
}
|
|
3162
|
+
/**
|
|
3163
|
+
* A fresh index with the production options. clearAll() swaps one in because
|
|
3164
|
+
* MiniSearch.removeAll() empties the index but leaves dirtCount (and its
|
|
3165
|
+
* vacuum bookkeeping) at its old value, which would trip syncEntries'
|
|
3166
|
+
* conditional vacuum early after a clear.
|
|
3167
|
+
*/
|
|
3168
|
+
createMiniSearch() {
|
|
3169
|
+
return new MiniSearch__default.default({
|
|
3117
3170
|
fields: ["title", "body", "tags"],
|
|
3118
3171
|
storeFields: ["entity_id"],
|
|
3119
3172
|
// Vacuuming is driven explicitly at the end of each serialized rebuild
|
|
@@ -3140,7 +3193,19 @@ var _SearchService = class _SearchService {
|
|
|
3140
3193
|
const work = this.syncChain.then(async () => {
|
|
3141
3194
|
try {
|
|
3142
3195
|
try {
|
|
3196
|
+
const epochsBefore = new Map(this.staleEpochs);
|
|
3143
3197
|
await this.rebuildIndex(entityId);
|
|
3198
|
+
if (entityId) {
|
|
3199
|
+
if ((this.staleEpochs.get(entityId) ?? 0) === (epochsBefore.get(entityId) ?? 0)) {
|
|
3200
|
+
this.staleEntities.delete(entityId);
|
|
3201
|
+
}
|
|
3202
|
+
} else {
|
|
3203
|
+
for (const id of [...this.staleEntities]) {
|
|
3204
|
+
if ((this.staleEpochs.get(id) ?? 0) === (epochsBefore.get(id) ?? 0)) {
|
|
3205
|
+
this.staleEntities.delete(id);
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3144
3209
|
await this.miniSearch.vacuum();
|
|
3145
3210
|
} finally {
|
|
3146
3211
|
this.evictCache(entityId);
|
|
@@ -3152,6 +3217,68 @@ var _SearchService = class _SearchService {
|
|
|
3152
3217
|
this.syncChain = work;
|
|
3153
3218
|
return work;
|
|
3154
3219
|
}
|
|
3220
|
+
/**
|
|
3221
|
+
* Re-indexes only `ids` for `entityId`: drops each from the index, then
|
|
3222
|
+
* re-adds the ones still live in SQLite, so soft-deleted or missing ids end
|
|
3223
|
+
* up absent. Costs O(ids), where sync(entityId) costs O(entity) — callers that
|
|
3224
|
+
* know what a write touched use this so chunked imports stay linear (#232).
|
|
3225
|
+
*
|
|
3226
|
+
* Serialized with sync() on the same chain and, like it, never rejects. An
|
|
3227
|
+
* entity that is stale or has never been indexed gets a full rebuild instead
|
|
3228
|
+
* — including on an empty `ids` list, which is a no-op only for an entity
|
|
3229
|
+
* the index already tracks, and even then one that waits for rebuilds
|
|
3230
|
+
* already queued on the chain.
|
|
3231
|
+
*/
|
|
3232
|
+
async syncEntries(entityId, ids) {
|
|
3233
|
+
const uniqueIds = [...new Set(ids)];
|
|
3234
|
+
if (uniqueIds.length === 0 && !this.staleEntities.has(entityId) && this.miniSearchEntryIdsByEntity.has(entityId)) {
|
|
3235
|
+
return this.syncChain;
|
|
3236
|
+
}
|
|
3237
|
+
const work = this.syncChain.then(async () => {
|
|
3238
|
+
try {
|
|
3239
|
+
try {
|
|
3240
|
+
const epochsBefore = new Map(this.staleEpochs);
|
|
3241
|
+
const needsRebuild = () => this.staleEntities.has(entityId) || !this.miniSearchEntryIdsByEntity.has(entityId);
|
|
3242
|
+
if (!needsRebuild()) {
|
|
3243
|
+
const rows = await this.entryRepo.findMiniSearchRowsByIds(entityId, uniqueIds);
|
|
3244
|
+
const tracked = this.miniSearchEntryIdsByEntity.get(entityId);
|
|
3245
|
+
if (tracked && !this.staleEntities.has(entityId)) {
|
|
3246
|
+
for (const id of uniqueIds) {
|
|
3247
|
+
if (tracked.delete(id) && this.miniSearch.has(id)) this.miniSearch.discard(id);
|
|
3248
|
+
}
|
|
3249
|
+
const documents = rows.map((row) => this.normalizeMiniSearchRow(row));
|
|
3250
|
+
if (documents.length > 0) this.miniSearch.addAll(documents);
|
|
3251
|
+
for (const document of documents) tracked.add(document.id);
|
|
3252
|
+
if (this.miniSearch.dirtCount > 0) {
|
|
3253
|
+
await this.miniSearch.vacuum();
|
|
3254
|
+
}
|
|
3255
|
+
return;
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
await this.rebuildIndex(entityId);
|
|
3259
|
+
if ((this.staleEpochs.get(entityId) ?? 0) === (epochsBefore.get(entityId) ?? 0)) {
|
|
3260
|
+
this.staleEntities.delete(entityId);
|
|
3261
|
+
}
|
|
3262
|
+
await this.miniSearch.vacuum();
|
|
3263
|
+
} finally {
|
|
3264
|
+
this.evictCache(entityId);
|
|
3265
|
+
}
|
|
3266
|
+
} catch (err) {
|
|
3267
|
+
this.staleEntities.add(entityId);
|
|
3268
|
+
console.warn(`[WikiMemory] search index incremental sync failed for ${entityId}:`, err);
|
|
3269
|
+
}
|
|
3270
|
+
});
|
|
3271
|
+
this.syncChain = work;
|
|
3272
|
+
return work;
|
|
3273
|
+
}
|
|
3274
|
+
/**
|
|
3275
|
+
* Forces the entity's next syncEntries to rebuild it in full. For writes core
|
|
3276
|
+
* cannot index itself, such as upsertGraph inside a host transaction.
|
|
3277
|
+
*/
|
|
3278
|
+
markStale(entityId) {
|
|
3279
|
+
this.staleEntities.add(entityId);
|
|
3280
|
+
this.staleEpochs.set(entityId, (this.staleEpochs.get(entityId) ?? 0) + 1);
|
|
3281
|
+
}
|
|
3155
3282
|
/**
|
|
3156
3283
|
* Clears the parsed vector cache. Useful for mid-loop flush guarantees
|
|
3157
3284
|
* or memory pressure evictions.
|
|
@@ -3168,8 +3295,10 @@ var _SearchService = class _SearchService {
|
|
|
3168
3295
|
*/
|
|
3169
3296
|
clearAll() {
|
|
3170
3297
|
this.vectorCache.clear();
|
|
3171
|
-
this.miniSearch.
|
|
3298
|
+
this.miniSearch = this.createMiniSearch();
|
|
3172
3299
|
this.miniSearchEntryIdsByEntity.clear();
|
|
3300
|
+
this.staleEntities.clear();
|
|
3301
|
+
this.staleEpochs.clear();
|
|
3173
3302
|
}
|
|
3174
3303
|
/**
|
|
3175
3304
|
* Executes a keyword search against the active MiniSearch index.
|
|
@@ -3180,7 +3309,7 @@ var _SearchService = class _SearchService {
|
|
|
3180
3309
|
filter: (r) => entityIdSet.has(r.entity_id),
|
|
3181
3310
|
combineWith: "OR"
|
|
3182
3311
|
});
|
|
3183
|
-
return results.slice(0, limit);
|
|
3312
|
+
return results.sort((a, b) => this._compareSearchResults(a, b)).slice(0, limit);
|
|
3184
3313
|
}
|
|
3185
3314
|
/**
|
|
3186
3315
|
* Pre-fetches MiniSearch scores for candidate hydration, used during hybrid weighting.
|
|
@@ -3190,7 +3319,7 @@ var _SearchService = class _SearchService {
|
|
|
3190
3319
|
let results = this.miniSearch.search(query, {
|
|
3191
3320
|
filter: (r) => entityIdSet.has(r.entity_id),
|
|
3192
3321
|
combineWith: "OR"
|
|
3193
|
-
});
|
|
3322
|
+
}).sort((a, b) => this._compareSearchResults(a, b));
|
|
3194
3323
|
if (preFilterLimit !== void 0) {
|
|
3195
3324
|
results = results.slice(0, preFilterLimit);
|
|
3196
3325
|
}
|
|
@@ -3318,6 +3447,18 @@ var _SearchService = class _SearchService {
|
|
|
3318
3447
|
if (updatedAtDiff !== 0) return updatedAtDiff;
|
|
3319
3448
|
return a.id.localeCompare(b.id);
|
|
3320
3449
|
}
|
|
3450
|
+
/**
|
|
3451
|
+
* MiniSearch breaks equal-score ties by internal insertion order, which
|
|
3452
|
+
* syncEntries changes: a discarded-and-re-added id moves to the end. Every
|
|
3453
|
+
* caller truncates these results to a limit, so which ids survive a tie at
|
|
3454
|
+
* the boundary must not depend on write history. Re-sort exact score ties
|
|
3455
|
+
* by id — the same final tie-break _compareScoredRows applies.
|
|
3456
|
+
*/
|
|
3457
|
+
_compareSearchResults(a, b) {
|
|
3458
|
+
const scoreDiff = b.score - a.score;
|
|
3459
|
+
if (!Number.isNaN(scoreDiff) && scoreDiff !== 0) return scoreDiff;
|
|
3460
|
+
return a.id.localeCompare(b.id);
|
|
3461
|
+
}
|
|
3321
3462
|
};
|
|
3322
3463
|
/**
|
|
3323
3464
|
* Maximum number of entities whose parsed embedding vectors are held in
|
|
@@ -4971,7 +5112,10 @@ var IngestionService = class {
|
|
|
4971
5112
|
return zeroChunkResult(canonical);
|
|
4972
5113
|
}
|
|
4973
5114
|
diagBuffer.flush(this.options);
|
|
4974
|
-
await this.searchService.
|
|
5115
|
+
await this.searchService.syncEntries(
|
|
5116
|
+
entityId,
|
|
5117
|
+
[...deletedSourceFactIds, ...insertedFacts.map((fact) => fact.id)]
|
|
5118
|
+
);
|
|
4975
5119
|
if (failedChunks === 0) {
|
|
4976
5120
|
const uniqueDeletedSourceFactIds = Array.from(new Set(deletedSourceFactIds));
|
|
4977
5121
|
for (const factId of uniqueDeletedSourceFactIds) {
|
|
@@ -6974,7 +7118,11 @@ var ImportExportService = class {
|
|
|
6974
7118
|
);
|
|
6975
7119
|
}
|
|
6976
7120
|
});
|
|
6977
|
-
|
|
7121
|
+
if (merge) {
|
|
7122
|
+
await this.searchService.syncEntries(entityId, [...upsertedFactIds]);
|
|
7123
|
+
} else {
|
|
7124
|
+
await this.searchService.sync(entityId);
|
|
7125
|
+
}
|
|
6978
7126
|
for (const fact of bundle.facts) {
|
|
6979
7127
|
if (!fact.deleted_at && upsertedFactIds.has(fact.id) && !factsWithPreservedBlob.has(fact.id)) {
|
|
6980
7128
|
const clipped = clippedTextByFactId.get(fact.id);
|
|
@@ -9112,6 +9260,7 @@ var WikiMemory = class {
|
|
|
9112
9260
|
adapter,
|
|
9113
9261
|
{ diag: { buffer: diagBuffer, operation: "upsertGraph" } }
|
|
9114
9262
|
);
|
|
9263
|
+
this.searchService.markStale(entityId);
|
|
9115
9264
|
diagBuffer.flush(this.options);
|
|
9116
9265
|
return result;
|
|
9117
9266
|
}
|