@equationalapplications/core-llm-wiki 7.8.0 → 7.9.1
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/README.md +9 -0
- package/dist/{chunk-M76CF2Q6.mjs → chunk-7FRLQ7ZO.mjs} +83 -129
- package/dist/chunk-7FRLQ7ZO.mjs.map +1 -0
- package/dist/index.d.mts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +305 -130
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +227 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-CWZaXKLj.d.mts → testing-Bf6etdUy.d.mts} +156 -26
- package/dist/{testing-CWZaXKLj.d.ts → testing-Bf6etdUy.d.ts} +156 -26
- package/dist/testing.d.mts +1 -2
- package/dist/testing.d.ts +1 -2
- package/dist/testing.js +83 -131
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +3 -3
- package/dist/chunk-M76CF2Q6.mjs.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OkfSource, OkfVerifiedEntry, OkfSourceUsageWindow } from '@equationalapplications/core-okf';
|
|
2
|
-
import { SearchResult } from 'minisearch';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Platform-agnostic SQLite driver interface.
|
|
@@ -1923,6 +1922,108 @@ declare class MetadataRepository extends BaseRepository {
|
|
|
1923
1922
|
mergeManifestUpdates(entityId: string, updates: OntologyUpdates, tx: SQLiteAdapter): Promise<OntologyManifest>;
|
|
1924
1923
|
}
|
|
1925
1924
|
|
|
1925
|
+
/**
|
|
1926
|
+
* One document that both keyword-index strategies must understand. Both
|
|
1927
|
+
* implementations expect `tags` to be a single string with the JSON array's
|
|
1928
|
+
* tokens space-joined (see `toIndexDoc` in utils/indexDoc.ts). The exact token
|
|
1929
|
+
* shape is strategy-private — callers do not see it.
|
|
1930
|
+
*/
|
|
1931
|
+
interface IndexDocument {
|
|
1932
|
+
id: string;
|
|
1933
|
+
entity_id: string;
|
|
1934
|
+
title: string;
|
|
1935
|
+
body: string;
|
|
1936
|
+
tags: string;
|
|
1937
|
+
}
|
|
1938
|
+
interface IndexSearchOptions {
|
|
1939
|
+
/** Empty array means "no entities match"; strategy returns []. */
|
|
1940
|
+
entityIds: string[];
|
|
1941
|
+
/** Upper bound on results returned. Strategy MUST return ≤ `limit`. */
|
|
1942
|
+
limit: number;
|
|
1943
|
+
/** Optional pre-filter cap used by hybrid retrieval. */
|
|
1944
|
+
preFilterLimit?: number;
|
|
1945
|
+
}
|
|
1946
|
+
interface IndexSearchResult {
|
|
1947
|
+
id: string;
|
|
1948
|
+
/**
|
|
1949
|
+
* Strategy-native relevance: finite, non-negative, higher is better,
|
|
1950
|
+
* comparable only within one result set. Not normalized —
|
|
1951
|
+
* `SearchService.getKeywordScores` divides by `max(1, top)` for the hybrid
|
|
1952
|
+
* blend, and `searchKeyword` passes scores through unscaled. SearchService
|
|
1953
|
+
* drops any result whose score is not finite.
|
|
1954
|
+
*/
|
|
1955
|
+
score: number;
|
|
1956
|
+
/**
|
|
1957
|
+
* The entity id this search result belongs to. Populated from
|
|
1958
|
+
* `IndexDocument.entity_id` by the strategy on every result.
|
|
1959
|
+
*/
|
|
1960
|
+
entity_id: string;
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* Keyword-index abstraction. The strategy owns its own backing store
|
|
1964
|
+
* (in-RAM MiniSearch vs on-disk FTS5) and is responsible for keeping it
|
|
1965
|
+
* consistent with the rows it has been told to write. The strategy also owns
|
|
1966
|
+
* the per-entity id bookkeeping — `SearchService` never sees the ids, only
|
|
1967
|
+
* an indexed-or-not probe.
|
|
1968
|
+
*
|
|
1969
|
+
* Concurrency: writes are called from serialized turns on
|
|
1970
|
+
* `SearchService.syncChain`, but searches are not, so each write method MUST
|
|
1971
|
+
* apply as one step — a concurrent `search()` sees the index wholly before or
|
|
1972
|
+
* wholly after it, never between its removal and its insertion. MiniSearch
|
|
1973
|
+
* gets this by never awaiting inside a write; FTS5 by one transaction per
|
|
1974
|
+
* write. Strategies MUST NOT spawn background work.
|
|
1975
|
+
*/
|
|
1976
|
+
interface IndexStrategy {
|
|
1977
|
+
/**
|
|
1978
|
+
* Replace documents under `entityId`: remove the given `ids` only if they
|
|
1979
|
+
* are currently tracked under `entityId` (ids under other entities and ids
|
|
1980
|
+
* the strategy never indexed are silently ignored), then upsert
|
|
1981
|
+
* `documents` by id. The strategy owns its id-tracking structure; callers
|
|
1982
|
+
* do not see it. Used for incremental sync.
|
|
1983
|
+
*
|
|
1984
|
+
* Argument order is `(entityId, ids, documents)` so the FTS5 SQL
|
|
1985
|
+
* `DELETE … WHERE entity_id = ? AND id IN (…)` matches the call shape.
|
|
1986
|
+
*/
|
|
1987
|
+
replace(entityId: string, ids: readonly string[], documents: readonly IndexDocument[]): Promise<void>;
|
|
1988
|
+
/**
|
|
1989
|
+
* Drop every document currently tracked under `entityId`, then add
|
|
1990
|
+
* `documents` (all of which belong to `entityId`). The entity stays
|
|
1991
|
+
* registered as indexed, even when `documents` is empty — `hasIndexedEntity`
|
|
1992
|
+
* continues to return `true` so the next incremental sync can take the
|
|
1993
|
+
* fast path. Used for per-entity rebuilds.
|
|
1994
|
+
*/
|
|
1995
|
+
replaceEntity(entityId: string, documents: readonly IndexDocument[]): Promise<void>;
|
|
1996
|
+
/**
|
|
1997
|
+
* Empty the entire index, then add `documents`. After this call, no entity
|
|
1998
|
+
* is registered as indexed (`hasIndexedEntity` returns `false` for every
|
|
1999
|
+
* entity). Used for global rebuilds and clears.
|
|
2000
|
+
*/
|
|
2001
|
+
replaceAll(documents: readonly IndexDocument[]): Promise<void>;
|
|
2002
|
+
/**
|
|
2003
|
+
* Search the index, best match first. If `preFilterLimit` is set, the
|
|
2004
|
+
* strategy MAY return up to `preFilterLimit` candidates before the `limit`
|
|
2005
|
+
* cap is applied (hybrid retrieval uses this to over-fetch candidates for
|
|
2006
|
+
* downstream vector blending). Score semantics are in `IndexSearchResult`.
|
|
2007
|
+
*/
|
|
2008
|
+
search(query: string, options: IndexSearchOptions): Promise<IndexSearchResult[]>;
|
|
2009
|
+
/**
|
|
2010
|
+
* Strategy-internal cleanup. For MiniSearch, this is the explicit vacuum
|
|
2011
|
+
* that `syncEntries` invokes after a discard-bearing turn (#64). FTS5 has
|
|
2012
|
+
* no equivalent; the default implementation is a no-op.
|
|
2013
|
+
*/
|
|
2014
|
+
vacuum?(): Promise<void>;
|
|
2015
|
+
/**
|
|
2016
|
+
* `true` when `entityId` has been indexed at least once under the current
|
|
2017
|
+
* strategy state; `false` otherwise. `SearchService.syncEntries` uses this
|
|
2018
|
+
* to choose between the empty-ids no-op fast path and the full-rebuild
|
|
2019
|
+
* fallback. Implementations MUST return `false` after `replaceAll([])` and
|
|
2020
|
+
* MUST return `true` after a `replace`/`replaceEntity` that wrote at least
|
|
2021
|
+
* one document (including `replace(entityId, [], [])` for tracking alone).
|
|
2022
|
+
* Returning `undefined` means "unknown — take the rebuild path".
|
|
2023
|
+
*/
|
|
2024
|
+
hasIndexedEntity?(entityId: string): boolean | undefined;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1926
2027
|
interface ScoredRow {
|
|
1927
2028
|
id: string;
|
|
1928
2029
|
entity_id: string;
|
|
@@ -1961,8 +2062,7 @@ declare class SearchService {
|
|
|
1961
2062
|
* entities while still maintaining a bounded memory footprint.
|
|
1962
2063
|
*/
|
|
1963
2064
|
private static readonly MAX_VECTOR_CACHE_FACTS_PER_ENTITY;
|
|
1964
|
-
private
|
|
1965
|
-
private miniSearchEntryIdsByEntity;
|
|
2065
|
+
private indexStrategy;
|
|
1966
2066
|
private vectorCache;
|
|
1967
2067
|
/**
|
|
1968
2068
|
* Serializes rebuilds. `rebuildIndex` awaits a repository read between
|
|
@@ -1988,19 +2088,12 @@ declare class SearchService {
|
|
|
1988
2088
|
* its flag must outlive the turn (#233 review).
|
|
1989
2089
|
*/
|
|
1990
2090
|
private staleEpochs;
|
|
1991
|
-
constructor(entryRepo: EntryRepository);
|
|
1992
|
-
/**
|
|
1993
|
-
* A fresh index with the production options. clearAll() swaps one in because
|
|
1994
|
-
* MiniSearch.removeAll() empties the index but leaves dirtCount (and its
|
|
1995
|
-
* vacuum bookkeeping) at its old value, which would trip syncEntries'
|
|
1996
|
-
* conditional vacuum early after a clear.
|
|
1997
|
-
*/
|
|
1998
|
-
private createMiniSearch;
|
|
2091
|
+
constructor(entryRepo: EntryRepository, indexStrategy: IndexStrategy);
|
|
1999
2092
|
/**
|
|
2000
2093
|
* Rebuilds the search index and clears the vector cache for a given entity.
|
|
2001
2094
|
* A direct replacement for manually syncing state after a DB transaction.
|
|
2002
2095
|
*
|
|
2003
|
-
* Rebuilds are serialized per instance and never reject: the
|
|
2096
|
+
* Rebuilds are serialized per instance and never reject: the keyword index
|
|
2004
2097
|
* is a rebuildable cache over SQLite, so degraded keyword search is the
|
|
2005
2098
|
* correct failure mode and killing the host process is not.
|
|
2006
2099
|
*/
|
|
@@ -2023,6 +2116,13 @@ declare class SearchService {
|
|
|
2023
2116
|
* cannot index itself, such as upsertGraph inside a host transaction.
|
|
2024
2117
|
*/
|
|
2025
2118
|
markStale(entityId: string): void;
|
|
2119
|
+
/**
|
|
2120
|
+
* Runs syncEntries(id, []) for each entity marked stale when this is called,
|
|
2121
|
+
* so only those entities are rebuilt. Each rebuild still takes its own turn
|
|
2122
|
+
* on the sync chain, and like syncEntries this never rejects. With nothing
|
|
2123
|
+
* stale it resolves at once, without waiting on work already on the chain.
|
|
2124
|
+
*/
|
|
2125
|
+
syncStale(): Promise<void>;
|
|
2026
2126
|
/**
|
|
2027
2127
|
* Clears the parsed vector cache. Useful for mid-loop flush guarantees
|
|
2028
2128
|
* or memory pressure evictions.
|
|
@@ -2031,30 +2131,36 @@ declare class SearchService {
|
|
|
2031
2131
|
/**
|
|
2032
2132
|
* Fully resets the search service.
|
|
2033
2133
|
*/
|
|
2034
|
-
clearAll(): void
|
|
2134
|
+
clearAll(): Promise<void>;
|
|
2035
2135
|
/**
|
|
2036
|
-
* Executes a keyword search against the active
|
|
2136
|
+
* Executes a keyword search against the active index strategy.
|
|
2037
2137
|
*/
|
|
2038
|
-
searchKeyword(query: string, entityIds: string[], limit: number):
|
|
2138
|
+
searchKeyword(query: string, entityIds: string[], limit: number): Promise<IndexSearchResult[]>;
|
|
2039
2139
|
/**
|
|
2040
|
-
* Pre-fetches
|
|
2140
|
+
* Pre-fetches keyword scores for candidate hydration, used during hybrid weighting.
|
|
2041
2141
|
*/
|
|
2042
|
-
|
|
2142
|
+
getKeywordScores(query: string, entityIds: string[], preFilterLimit?: number): Promise<Map<string, number>>;
|
|
2043
2143
|
/**
|
|
2044
2144
|
* Score candidate rows using in-process JS cosine similarity.
|
|
2045
2145
|
* Applies hybrid blending (if weight set) and tie-break sorting before returning.
|
|
2046
2146
|
*/
|
|
2047
2147
|
rankSemantic(args: RankSemanticArgs): Promise<ScoredRow[]>;
|
|
2148
|
+
/**
|
|
2149
|
+
* Rebuild a single entity's index from scratch. Reads every row for
|
|
2150
|
+
* `entityId` from the repository (already filtered by `deleted_at IS NULL`)
|
|
2151
|
+
* and hands the lot to `indexStrategy.replaceEntity`, which owns the
|
|
2152
|
+
* drop-then-add bookkeeping so callers don't need to know the strategy's
|
|
2153
|
+
* id-tracking shape.
|
|
2154
|
+
*/
|
|
2048
2155
|
private rebuildIndex;
|
|
2049
|
-
private normalizeMiniSearchRow;
|
|
2050
2156
|
private _tieBreakSort;
|
|
2051
2157
|
private _compareScoredRows;
|
|
2052
2158
|
/**
|
|
2053
|
-
*
|
|
2054
|
-
* syncEntries changes: a discarded-and-re-added id moves to the end.
|
|
2055
|
-
* caller truncates these results to a limit, so which ids survive a
|
|
2056
|
-
* the boundary must not depend on write history. Re-sort exact
|
|
2057
|
-
* by id — the same final tie-break _compareScoredRows applies.
|
|
2159
|
+
* The keyword index breaks equal-score ties by internal insertion order,
|
|
2160
|
+
* which syncEntries changes: a discarded-and-re-added id moves to the end.
|
|
2161
|
+
* Every caller truncates these results to a limit, so which ids survive a
|
|
2162
|
+
* tie at the boundary must not depend on write history. Re-sort exact
|
|
2163
|
+
* score ties by id — the same final tie-break _compareScoredRows applies.
|
|
2058
2164
|
*/
|
|
2059
2165
|
private _compareSearchResults;
|
|
2060
2166
|
}
|
|
@@ -3486,6 +3592,28 @@ declare class WikiMemory {
|
|
|
3486
3592
|
getEntityStatus(entityId: string): EntityStatus;
|
|
3487
3593
|
subscribeEntityStatus(entityId: string, callback: (status: EntityStatus) => void): () => void;
|
|
3488
3594
|
clearVectorCache(): void;
|
|
3595
|
+
/**
|
|
3596
|
+
* Brings the keyword search index up to date with SQLite after a host
|
|
3597
|
+
* transaction that used `upsertGraph` has committed. Core never sees that
|
|
3598
|
+
* commit, so without this the nodes stay out of keyword, hybrid and
|
|
3599
|
+
* fallback retrieval until the entity's next core write.
|
|
3600
|
+
*
|
|
3601
|
+
* With `entityId`, rebuilds that entity if it is stale or has never been
|
|
3602
|
+
* indexed; otherwise it is a no-op that still waits for rebuilds already
|
|
3603
|
+
* queued. Without an argument, rebuilds every entity currently marked
|
|
3604
|
+
* stale; when none is, it resolves immediately and does not wait for rebuilds
|
|
3605
|
+
* already queued.
|
|
3606
|
+
*
|
|
3607
|
+
* Call only after the host's transaction commits: called inside it, the
|
|
3608
|
+
* rebuild may index rows that later roll back, or miss them and clear the
|
|
3609
|
+
* stale flag anyway. Serialized with core's internal index syncs and takes
|
|
3610
|
+
* no maintenance lock. Never rejects for a valid `entityId` — on failure the
|
|
3611
|
+
* entity stays stale and the next call retries it. Does not compute
|
|
3612
|
+
* embeddings; that remains the maintenance sweep's job.
|
|
3613
|
+
*
|
|
3614
|
+
* @throws {TypeError} when `entityId` is given but is not a non-empty string.
|
|
3615
|
+
*/
|
|
3616
|
+
syncSearchIndex(entityId?: string): Promise<void>;
|
|
3489
3617
|
exportDump(entityIds?: string[]): Promise<MemoryDump>;
|
|
3490
3618
|
/** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */
|
|
3491
3619
|
getEntitySummary(entityId: string): Promise<string | null>;
|
|
@@ -3548,9 +3676,11 @@ declare class WikiMemory {
|
|
|
3548
3676
|
* MUST be called from inside an open `db.withTransactionAsync` callback —
|
|
3549
3677
|
* the third argument is the caller's `tx`. The method does not open a
|
|
3550
3678
|
* nested transaction, does not acquire any lock, and does not perform
|
|
3551
|
-
* post-commit work (search sync, embedding, cache eviction).
|
|
3552
|
-
*
|
|
3553
|
-
* (`
|
|
3679
|
+
* post-commit work (search sync, embedding, cache eviction). After the
|
|
3680
|
+
* transaction commits, call `syncSearchIndex(entityId)` — or
|
|
3681
|
+
* `syncSearchIndex()` after writing several entities in one transaction —
|
|
3682
|
+
* to make the new nodes keyword-searchable. Embeddings still come from the maintenance
|
|
3683
|
+
* sweep (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,
|
|
3554
3684
|
* scoped via `listEntityIds`).
|
|
3555
3685
|
*
|
|
3556
3686
|
* Contract (full pre-flight validation lives inside
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OkfSource, OkfVerifiedEntry, OkfSourceUsageWindow } from '@equationalapplications/core-okf';
|
|
2
|
-
import { SearchResult } from 'minisearch';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Platform-agnostic SQLite driver interface.
|
|
@@ -1923,6 +1922,108 @@ declare class MetadataRepository extends BaseRepository {
|
|
|
1923
1922
|
mergeManifestUpdates(entityId: string, updates: OntologyUpdates, tx: SQLiteAdapter): Promise<OntologyManifest>;
|
|
1924
1923
|
}
|
|
1925
1924
|
|
|
1925
|
+
/**
|
|
1926
|
+
* One document that both keyword-index strategies must understand. Both
|
|
1927
|
+
* implementations expect `tags` to be a single string with the JSON array's
|
|
1928
|
+
* tokens space-joined (see `toIndexDoc` in utils/indexDoc.ts). The exact token
|
|
1929
|
+
* shape is strategy-private — callers do not see it.
|
|
1930
|
+
*/
|
|
1931
|
+
interface IndexDocument {
|
|
1932
|
+
id: string;
|
|
1933
|
+
entity_id: string;
|
|
1934
|
+
title: string;
|
|
1935
|
+
body: string;
|
|
1936
|
+
tags: string;
|
|
1937
|
+
}
|
|
1938
|
+
interface IndexSearchOptions {
|
|
1939
|
+
/** Empty array means "no entities match"; strategy returns []. */
|
|
1940
|
+
entityIds: string[];
|
|
1941
|
+
/** Upper bound on results returned. Strategy MUST return ≤ `limit`. */
|
|
1942
|
+
limit: number;
|
|
1943
|
+
/** Optional pre-filter cap used by hybrid retrieval. */
|
|
1944
|
+
preFilterLimit?: number;
|
|
1945
|
+
}
|
|
1946
|
+
interface IndexSearchResult {
|
|
1947
|
+
id: string;
|
|
1948
|
+
/**
|
|
1949
|
+
* Strategy-native relevance: finite, non-negative, higher is better,
|
|
1950
|
+
* comparable only within one result set. Not normalized —
|
|
1951
|
+
* `SearchService.getKeywordScores` divides by `max(1, top)` for the hybrid
|
|
1952
|
+
* blend, and `searchKeyword` passes scores through unscaled. SearchService
|
|
1953
|
+
* drops any result whose score is not finite.
|
|
1954
|
+
*/
|
|
1955
|
+
score: number;
|
|
1956
|
+
/**
|
|
1957
|
+
* The entity id this search result belongs to. Populated from
|
|
1958
|
+
* `IndexDocument.entity_id` by the strategy on every result.
|
|
1959
|
+
*/
|
|
1960
|
+
entity_id: string;
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* Keyword-index abstraction. The strategy owns its own backing store
|
|
1964
|
+
* (in-RAM MiniSearch vs on-disk FTS5) and is responsible for keeping it
|
|
1965
|
+
* consistent with the rows it has been told to write. The strategy also owns
|
|
1966
|
+
* the per-entity id bookkeeping — `SearchService` never sees the ids, only
|
|
1967
|
+
* an indexed-or-not probe.
|
|
1968
|
+
*
|
|
1969
|
+
* Concurrency: writes are called from serialized turns on
|
|
1970
|
+
* `SearchService.syncChain`, but searches are not, so each write method MUST
|
|
1971
|
+
* apply as one step — a concurrent `search()` sees the index wholly before or
|
|
1972
|
+
* wholly after it, never between its removal and its insertion. MiniSearch
|
|
1973
|
+
* gets this by never awaiting inside a write; FTS5 by one transaction per
|
|
1974
|
+
* write. Strategies MUST NOT spawn background work.
|
|
1975
|
+
*/
|
|
1976
|
+
interface IndexStrategy {
|
|
1977
|
+
/**
|
|
1978
|
+
* Replace documents under `entityId`: remove the given `ids` only if they
|
|
1979
|
+
* are currently tracked under `entityId` (ids under other entities and ids
|
|
1980
|
+
* the strategy never indexed are silently ignored), then upsert
|
|
1981
|
+
* `documents` by id. The strategy owns its id-tracking structure; callers
|
|
1982
|
+
* do not see it. Used for incremental sync.
|
|
1983
|
+
*
|
|
1984
|
+
* Argument order is `(entityId, ids, documents)` so the FTS5 SQL
|
|
1985
|
+
* `DELETE … WHERE entity_id = ? AND id IN (…)` matches the call shape.
|
|
1986
|
+
*/
|
|
1987
|
+
replace(entityId: string, ids: readonly string[], documents: readonly IndexDocument[]): Promise<void>;
|
|
1988
|
+
/**
|
|
1989
|
+
* Drop every document currently tracked under `entityId`, then add
|
|
1990
|
+
* `documents` (all of which belong to `entityId`). The entity stays
|
|
1991
|
+
* registered as indexed, even when `documents` is empty — `hasIndexedEntity`
|
|
1992
|
+
* continues to return `true` so the next incremental sync can take the
|
|
1993
|
+
* fast path. Used for per-entity rebuilds.
|
|
1994
|
+
*/
|
|
1995
|
+
replaceEntity(entityId: string, documents: readonly IndexDocument[]): Promise<void>;
|
|
1996
|
+
/**
|
|
1997
|
+
* Empty the entire index, then add `documents`. After this call, no entity
|
|
1998
|
+
* is registered as indexed (`hasIndexedEntity` returns `false` for every
|
|
1999
|
+
* entity). Used for global rebuilds and clears.
|
|
2000
|
+
*/
|
|
2001
|
+
replaceAll(documents: readonly IndexDocument[]): Promise<void>;
|
|
2002
|
+
/**
|
|
2003
|
+
* Search the index, best match first. If `preFilterLimit` is set, the
|
|
2004
|
+
* strategy MAY return up to `preFilterLimit` candidates before the `limit`
|
|
2005
|
+
* cap is applied (hybrid retrieval uses this to over-fetch candidates for
|
|
2006
|
+
* downstream vector blending). Score semantics are in `IndexSearchResult`.
|
|
2007
|
+
*/
|
|
2008
|
+
search(query: string, options: IndexSearchOptions): Promise<IndexSearchResult[]>;
|
|
2009
|
+
/**
|
|
2010
|
+
* Strategy-internal cleanup. For MiniSearch, this is the explicit vacuum
|
|
2011
|
+
* that `syncEntries` invokes after a discard-bearing turn (#64). FTS5 has
|
|
2012
|
+
* no equivalent; the default implementation is a no-op.
|
|
2013
|
+
*/
|
|
2014
|
+
vacuum?(): Promise<void>;
|
|
2015
|
+
/**
|
|
2016
|
+
* `true` when `entityId` has been indexed at least once under the current
|
|
2017
|
+
* strategy state; `false` otherwise. `SearchService.syncEntries` uses this
|
|
2018
|
+
* to choose between the empty-ids no-op fast path and the full-rebuild
|
|
2019
|
+
* fallback. Implementations MUST return `false` after `replaceAll([])` and
|
|
2020
|
+
* MUST return `true` after a `replace`/`replaceEntity` that wrote at least
|
|
2021
|
+
* one document (including `replace(entityId, [], [])` for tracking alone).
|
|
2022
|
+
* Returning `undefined` means "unknown — take the rebuild path".
|
|
2023
|
+
*/
|
|
2024
|
+
hasIndexedEntity?(entityId: string): boolean | undefined;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1926
2027
|
interface ScoredRow {
|
|
1927
2028
|
id: string;
|
|
1928
2029
|
entity_id: string;
|
|
@@ -1961,8 +2062,7 @@ declare class SearchService {
|
|
|
1961
2062
|
* entities while still maintaining a bounded memory footprint.
|
|
1962
2063
|
*/
|
|
1963
2064
|
private static readonly MAX_VECTOR_CACHE_FACTS_PER_ENTITY;
|
|
1964
|
-
private
|
|
1965
|
-
private miniSearchEntryIdsByEntity;
|
|
2065
|
+
private indexStrategy;
|
|
1966
2066
|
private vectorCache;
|
|
1967
2067
|
/**
|
|
1968
2068
|
* Serializes rebuilds. `rebuildIndex` awaits a repository read between
|
|
@@ -1988,19 +2088,12 @@ declare class SearchService {
|
|
|
1988
2088
|
* its flag must outlive the turn (#233 review).
|
|
1989
2089
|
*/
|
|
1990
2090
|
private staleEpochs;
|
|
1991
|
-
constructor(entryRepo: EntryRepository);
|
|
1992
|
-
/**
|
|
1993
|
-
* A fresh index with the production options. clearAll() swaps one in because
|
|
1994
|
-
* MiniSearch.removeAll() empties the index but leaves dirtCount (and its
|
|
1995
|
-
* vacuum bookkeeping) at its old value, which would trip syncEntries'
|
|
1996
|
-
* conditional vacuum early after a clear.
|
|
1997
|
-
*/
|
|
1998
|
-
private createMiniSearch;
|
|
2091
|
+
constructor(entryRepo: EntryRepository, indexStrategy: IndexStrategy);
|
|
1999
2092
|
/**
|
|
2000
2093
|
* Rebuilds the search index and clears the vector cache for a given entity.
|
|
2001
2094
|
* A direct replacement for manually syncing state after a DB transaction.
|
|
2002
2095
|
*
|
|
2003
|
-
* Rebuilds are serialized per instance and never reject: the
|
|
2096
|
+
* Rebuilds are serialized per instance and never reject: the keyword index
|
|
2004
2097
|
* is a rebuildable cache over SQLite, so degraded keyword search is the
|
|
2005
2098
|
* correct failure mode and killing the host process is not.
|
|
2006
2099
|
*/
|
|
@@ -2023,6 +2116,13 @@ declare class SearchService {
|
|
|
2023
2116
|
* cannot index itself, such as upsertGraph inside a host transaction.
|
|
2024
2117
|
*/
|
|
2025
2118
|
markStale(entityId: string): void;
|
|
2119
|
+
/**
|
|
2120
|
+
* Runs syncEntries(id, []) for each entity marked stale when this is called,
|
|
2121
|
+
* so only those entities are rebuilt. Each rebuild still takes its own turn
|
|
2122
|
+
* on the sync chain, and like syncEntries this never rejects. With nothing
|
|
2123
|
+
* stale it resolves at once, without waiting on work already on the chain.
|
|
2124
|
+
*/
|
|
2125
|
+
syncStale(): Promise<void>;
|
|
2026
2126
|
/**
|
|
2027
2127
|
* Clears the parsed vector cache. Useful for mid-loop flush guarantees
|
|
2028
2128
|
* or memory pressure evictions.
|
|
@@ -2031,30 +2131,36 @@ declare class SearchService {
|
|
|
2031
2131
|
/**
|
|
2032
2132
|
* Fully resets the search service.
|
|
2033
2133
|
*/
|
|
2034
|
-
clearAll(): void
|
|
2134
|
+
clearAll(): Promise<void>;
|
|
2035
2135
|
/**
|
|
2036
|
-
* Executes a keyword search against the active
|
|
2136
|
+
* Executes a keyword search against the active index strategy.
|
|
2037
2137
|
*/
|
|
2038
|
-
searchKeyword(query: string, entityIds: string[], limit: number):
|
|
2138
|
+
searchKeyword(query: string, entityIds: string[], limit: number): Promise<IndexSearchResult[]>;
|
|
2039
2139
|
/**
|
|
2040
|
-
* Pre-fetches
|
|
2140
|
+
* Pre-fetches keyword scores for candidate hydration, used during hybrid weighting.
|
|
2041
2141
|
*/
|
|
2042
|
-
|
|
2142
|
+
getKeywordScores(query: string, entityIds: string[], preFilterLimit?: number): Promise<Map<string, number>>;
|
|
2043
2143
|
/**
|
|
2044
2144
|
* Score candidate rows using in-process JS cosine similarity.
|
|
2045
2145
|
* Applies hybrid blending (if weight set) and tie-break sorting before returning.
|
|
2046
2146
|
*/
|
|
2047
2147
|
rankSemantic(args: RankSemanticArgs): Promise<ScoredRow[]>;
|
|
2148
|
+
/**
|
|
2149
|
+
* Rebuild a single entity's index from scratch. Reads every row for
|
|
2150
|
+
* `entityId` from the repository (already filtered by `deleted_at IS NULL`)
|
|
2151
|
+
* and hands the lot to `indexStrategy.replaceEntity`, which owns the
|
|
2152
|
+
* drop-then-add bookkeeping so callers don't need to know the strategy's
|
|
2153
|
+
* id-tracking shape.
|
|
2154
|
+
*/
|
|
2048
2155
|
private rebuildIndex;
|
|
2049
|
-
private normalizeMiniSearchRow;
|
|
2050
2156
|
private _tieBreakSort;
|
|
2051
2157
|
private _compareScoredRows;
|
|
2052
2158
|
/**
|
|
2053
|
-
*
|
|
2054
|
-
* syncEntries changes: a discarded-and-re-added id moves to the end.
|
|
2055
|
-
* caller truncates these results to a limit, so which ids survive a
|
|
2056
|
-
* the boundary must not depend on write history. Re-sort exact
|
|
2057
|
-
* by id — the same final tie-break _compareScoredRows applies.
|
|
2159
|
+
* The keyword index breaks equal-score ties by internal insertion order,
|
|
2160
|
+
* which syncEntries changes: a discarded-and-re-added id moves to the end.
|
|
2161
|
+
* Every caller truncates these results to a limit, so which ids survive a
|
|
2162
|
+
* tie at the boundary must not depend on write history. Re-sort exact
|
|
2163
|
+
* score ties by id — the same final tie-break _compareScoredRows applies.
|
|
2058
2164
|
*/
|
|
2059
2165
|
private _compareSearchResults;
|
|
2060
2166
|
}
|
|
@@ -3486,6 +3592,28 @@ declare class WikiMemory {
|
|
|
3486
3592
|
getEntityStatus(entityId: string): EntityStatus;
|
|
3487
3593
|
subscribeEntityStatus(entityId: string, callback: (status: EntityStatus) => void): () => void;
|
|
3488
3594
|
clearVectorCache(): void;
|
|
3595
|
+
/**
|
|
3596
|
+
* Brings the keyword search index up to date with SQLite after a host
|
|
3597
|
+
* transaction that used `upsertGraph` has committed. Core never sees that
|
|
3598
|
+
* commit, so without this the nodes stay out of keyword, hybrid and
|
|
3599
|
+
* fallback retrieval until the entity's next core write.
|
|
3600
|
+
*
|
|
3601
|
+
* With `entityId`, rebuilds that entity if it is stale or has never been
|
|
3602
|
+
* indexed; otherwise it is a no-op that still waits for rebuilds already
|
|
3603
|
+
* queued. Without an argument, rebuilds every entity currently marked
|
|
3604
|
+
* stale; when none is, it resolves immediately and does not wait for rebuilds
|
|
3605
|
+
* already queued.
|
|
3606
|
+
*
|
|
3607
|
+
* Call only after the host's transaction commits: called inside it, the
|
|
3608
|
+
* rebuild may index rows that later roll back, or miss them and clear the
|
|
3609
|
+
* stale flag anyway. Serialized with core's internal index syncs and takes
|
|
3610
|
+
* no maintenance lock. Never rejects for a valid `entityId` — on failure the
|
|
3611
|
+
* entity stays stale and the next call retries it. Does not compute
|
|
3612
|
+
* embeddings; that remains the maintenance sweep's job.
|
|
3613
|
+
*
|
|
3614
|
+
* @throws {TypeError} when `entityId` is given but is not a non-empty string.
|
|
3615
|
+
*/
|
|
3616
|
+
syncSearchIndex(entityId?: string): Promise<void>;
|
|
3489
3617
|
exportDump(entityIds?: string[]): Promise<MemoryDump>;
|
|
3490
3618
|
/** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */
|
|
3491
3619
|
getEntitySummary(entityId: string): Promise<string | null>;
|
|
@@ -3548,9 +3676,11 @@ declare class WikiMemory {
|
|
|
3548
3676
|
* MUST be called from inside an open `db.withTransactionAsync` callback —
|
|
3549
3677
|
* the third argument is the caller's `tx`. The method does not open a
|
|
3550
3678
|
* nested transaction, does not acquire any lock, and does not perform
|
|
3551
|
-
* post-commit work (search sync, embedding, cache eviction).
|
|
3552
|
-
*
|
|
3553
|
-
* (`
|
|
3679
|
+
* post-commit work (search sync, embedding, cache eviction). After the
|
|
3680
|
+
* transaction commits, call `syncSearchIndex(entityId)` — or
|
|
3681
|
+
* `syncSearchIndex()` after writing several entities in one transaction —
|
|
3682
|
+
* to make the new nodes keyword-searchable. Embeddings still come from the maintenance
|
|
3683
|
+
* sweep (`runLibrarian` / `runHeal` / `runOntologyBackfill` / `runPrune`,
|
|
3554
3684
|
* scoped via `listEntityIds`).
|
|
3555
3685
|
*
|
|
3556
3686
|
* Contract (full pre-flight validation lives inside
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { aB as EmbeddingService, aC as ImportExportService, aD as IngestionService, aE as JobManager, aE as JobManagerType, aF as MaintenanceService, aG as RetrievalService, aH as SearchService, aH as SearchServiceType, ar as WikiMemoryTestAccess, aI as WriteService } from './testing-
|
|
1
|
+
export { aB as EmbeddingService, aC as ImportExportService, aD as IngestionService, aE as JobManager, aE as JobManagerType, aF as MaintenanceService, aG as RetrievalService, aH as SearchService, aH as SearchServiceType, ar as WikiMemoryTestAccess, aI as WriteService } from './testing-Bf6etdUy.mjs';
|
|
2
2
|
import '@equationalapplications/core-okf';
|
|
3
|
-
import 'minisearch';
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { aB as EmbeddingService, aC as ImportExportService, aD as IngestionService, aE as JobManager, aE as JobManagerType, aF as MaintenanceService, aG as RetrievalService, aH as SearchService, aH as SearchServiceType, ar as WikiMemoryTestAccess, aI as WriteService } from './testing-
|
|
1
|
+
export { aB as EmbeddingService, aC as ImportExportService, aD as IngestionService, aE as JobManager, aE as JobManagerType, aF as MaintenanceService, aG as RetrievalService, aH as SearchService, aH as SearchServiceType, ar as WikiMemoryTestAccess, aI as WriteService } from './testing-Bf6etdUy.js';
|
|
2
2
|
import '@equationalapplications/core-okf';
|
|
3
|
-
import 'minisearch';
|