@avantf/dsh-mem 0.6.0 → 0.6.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/lib/client.js +1 -0
- package/lib/engine/mem/db/dao/chunks.d.ts +60 -4
- package/lib/engine/mem/db/dao/shared.d.ts +153 -0
- package/lib/engine/mem/eval/index.d.ts +4 -0
- package/lib/engine/mem/index.d.ts +1 -0
- package/lib/engine/mem/runtime.d.ts +2 -2
- package/lib/engine/mem/store/entity_sweep.d.ts +121 -0
- package/lib/engine/mem/store/hybrid.d.ts +50 -0
- package/lib/engine/mem/store/knowledge.d.ts +116 -12
- package/lib/engine/mem/store/legs.d.ts +171 -0
- package/lib/engine/mem/store/lexical.d.ts +8 -0
- package/lib/engine/mem/store/memory.d.ts +84 -72
- package/lib/engine/mem/store/vector_repair.d.ts +248 -0
- package/lib/engine/mem-contract/tools.d.ts +4 -0
- package/lib/engine/mem-contract/types.d.ts +37 -6
- package/lib/engine/mem-retrieval/adapters/local_reranker.d.ts +52 -0
- package/lib/engine/mem-retrieval/adapters/none_reranker.d.ts +10 -0
- package/lib/engine/mem-retrieval/rerank.d.ts +13 -0
- package/lib/index.js +1370 -538
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/remote.d.ts.map +1 -1
- package/lib/types/vectorMigration.d.ts +22 -18
- package/lib/types/vectorMigration.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE vector-space repair flow both stores run.
|
|
3
|
+
*
|
|
4
|
+
* Changing the embedding space (model, width, pooling, normalization, input window, weights) is a
|
|
5
|
+
* DATA MIGRATION: persisted vectors keep decoding but live in another model's coordinates, so the
|
|
6
|
+
* semantic leg must not serve them. `common.ts` owns the cheap DETECTION (`reportStaleVectors`); this
|
|
7
|
+
* module owns the REPAIR — a bounded, resumable, switchable loop that re-encodes the corpus in
|
|
8
|
+
* slices and yields the event loop between them.
|
|
9
|
+
*
|
|
10
|
+
* It is a template method implemented by COMPOSITION (AGENTS.md / the design note in
|
|
11
|
+
* `docs/vector-repair-shared-flow.md`): the skeleton lives here as free functions, each store
|
|
12
|
+
* supplies a {@link VectorRepairTarget} adapter. No common base class — the two stores are separate
|
|
13
|
+
* databases with separate DAOs, and a base class would be a structural rewrite of two hub files.
|
|
14
|
+
*
|
|
15
|
+
* What is shared, and therefore must never be copied back into `store/memory.ts` /
|
|
16
|
+
* `store/knowledge.ts`: the batch size, the `yieldToEventLoop` call, the stop / resume / no-progress
|
|
17
|
+
* rules, the `semantic.auto_migrate` decision, the `dry_run` split, the order invariant
|
|
18
|
+
* (unusable bytes leave first, then re-encode), the warmup policy and the four log kinds.
|
|
19
|
+
*
|
|
20
|
+
* What stays in the stores (correct differences, DESIGN §2.3): the DAO calls and row shapes, the
|
|
21
|
+
* `conflict_checked` re-queue on the memory side, the `content_hash` reuse and failure counting on
|
|
22
|
+
* the knowledge side, the HRR column, and which live index a row is added to.
|
|
23
|
+
*
|
|
24
|
+
* @module store/vector_repair
|
|
25
|
+
*/
|
|
26
|
+
import type { AvantfLogger, VectorMigrationOutcome, VectorMigrationProgress, VectorsFixReport, VectorsFixStoreReport } from '../../mem-contract/index.js';
|
|
27
|
+
import type { VectorStore } from '../../mem-retrieval/index.js';
|
|
28
|
+
import { type StaleVectorCounts } from './common.js';
|
|
29
|
+
/** The two stores this flow can drive. */
|
|
30
|
+
export type VectorRepairStore = 'memory' | 'knowledge';
|
|
31
|
+
/**
|
|
32
|
+
* Rows one background vector-space migration slice may re-encode.
|
|
33
|
+
*
|
|
34
|
+
* Small on purpose: the point of batching is that a query arriving mid-migration waits for at most
|
|
35
|
+
* one ONNX forward pass batch, not for a whole corpus. At ~30 ms per bge-base-zh encode a batch of 16
|
|
36
|
+
* is well under a second of contested model time, and the event loop is yielded between batches
|
|
37
|
+
* (`yieldToEventLoop`). The value is a default, not a promise — `migrateVectorSlice` takes whatever
|
|
38
|
+
* the caller needs.
|
|
39
|
+
*/
|
|
40
|
+
export declare const DEFAULT_VECTOR_MIGRATION_BATCH = 16;
|
|
41
|
+
/**
|
|
42
|
+
* What one store's persisted-vector scan found, before any write.
|
|
43
|
+
*
|
|
44
|
+
* `stale` and `space_stale` mirror the cheap detection counts (`StaleVectorCounts`); `missing` is
|
|
45
|
+
* "ACTIVE row with no persisted vector at all" — the third reason the semantic leg cannot use a row.
|
|
46
|
+
*/
|
|
47
|
+
export interface VectorsClassification {
|
|
48
|
+
/** ACTIVE rows whose persisted vector has the wrong width (it cannot even be decoded). */
|
|
49
|
+
stale: number;
|
|
50
|
+
/** ACTIVE rows whose usable-width vector was recorded in another space. */
|
|
51
|
+
space_stale: number;
|
|
52
|
+
/** ACTIVE rows with no persisted vector at all. */
|
|
53
|
+
missing: number;
|
|
54
|
+
/**
|
|
55
|
+
* Ids whose unusable bytes must leave the store before a re-encode picks them up (the `limit`
|
|
56
|
+
* passed to {@link VectorRepairTarget.classifyVectors} is applied). Knowledge overwrites vectors
|
|
57
|
+
* in place, so it reports none.
|
|
58
|
+
*/
|
|
59
|
+
dropIds: readonly number[];
|
|
60
|
+
/**
|
|
61
|
+
* Usable persisted vectors absent from the LIVE index, decoded and ready to re-add. Only stores
|
|
62
|
+
* whose diagnose surface tracks the live index report this (memory); knowledge rebuilds its index
|
|
63
|
+
* at open and keeps it in sync on every write, so it omits the property entirely.
|
|
64
|
+
*/
|
|
65
|
+
unindexed?: readonly {
|
|
66
|
+
id: number;
|
|
67
|
+
vec: Float32Array;
|
|
68
|
+
}[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One store's half of the repair flow — the "key methods" of the template.
|
|
72
|
+
*
|
|
73
|
+
* Every method is a PRIMITIVE the store can answer from its own DAO; none of them contains the
|
|
74
|
+
* loop, the batch size or the switch logic (those are in this module, once).
|
|
75
|
+
*/
|
|
76
|
+
export interface VectorRepairTarget {
|
|
77
|
+
readonly store: VectorRepairStore;
|
|
78
|
+
/** The manual entry the stale-vector warning points at, as the operator would type it. */
|
|
79
|
+
readonly manualEntry: string;
|
|
80
|
+
/** The representation fingerprint this store writes into now. */
|
|
81
|
+
vectorSpace(): string;
|
|
82
|
+
/** Is the embedding model loaded RIGHT NOW? (Never warms — the flow owns the warmup policy.) */
|
|
83
|
+
semanticAvailable(): boolean;
|
|
84
|
+
/** The RAW `semantic.auto_migrate` value; the flow decides what it means (`!== false`). */
|
|
85
|
+
autoMigrate(): boolean | undefined;
|
|
86
|
+
/** Cheap `{ stale, space_stale, legacy? }` — blob LENGTHS only, never decodes. */
|
|
87
|
+
vectorSpaceHealth(): StaleVectorCounts;
|
|
88
|
+
/** Cheap count of ACTIVE rows with no persisted vector (part of `remaining`). */
|
|
89
|
+
missingVectorCount(): number;
|
|
90
|
+
/** One scan classifying what needs dropping and re-encoding; `limit` bounds `dropIds`. */
|
|
91
|
+
classifyVectors(limit: number): VectorsClassification;
|
|
92
|
+
/**
|
|
93
|
+
* Optional: put usable persisted vectors missing from the live index back into it, returning how
|
|
94
|
+
* many were added. Called with the slice of {@link VectorsClassification.unindexed} the current
|
|
95
|
+
* `limit` allows, so the flow does not re-scan the corpus for it.
|
|
96
|
+
*/
|
|
97
|
+
reindexUsable?(rows: readonly {
|
|
98
|
+
id: number;
|
|
99
|
+
vec: Float32Array;
|
|
100
|
+
}[]): number;
|
|
101
|
+
/** Clear unusable bytes (table + live index); returns how many rows were actually cleared. */
|
|
102
|
+
dropVectors(ids: readonly number[]): number;
|
|
103
|
+
/** Encode + persist up to `limit` rows into the current space, one row isolated at a time. */
|
|
104
|
+
reencodeVectors(limit: number): Promise<{
|
|
105
|
+
encoded: number;
|
|
106
|
+
failed: number;
|
|
107
|
+
}>;
|
|
108
|
+
/** Optional: wait for the embedding model (explicit repair only; the background never waits). */
|
|
109
|
+
warmup?(): Promise<boolean>;
|
|
110
|
+
}
|
|
111
|
+
/** A persisted vector row as read back from a store, for the shared open-time load. */
|
|
112
|
+
export interface PersistedVectorRow {
|
|
113
|
+
id: number;
|
|
114
|
+
vec: Uint8Array | null;
|
|
115
|
+
embedding_model?: string | null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Rebuild one store's live vstore from its persisted rows, count what is unusable in the current
|
|
119
|
+
* space, and say so once — the shared "open for business" step both stores used to write twice.
|
|
120
|
+
*
|
|
121
|
+
* The owning store's ONLY half is the row read (`facts.activeVectorRows()` /
|
|
122
|
+
* `chunks.vectorRows()`); the reload, the count and the loud warning are one implementation, so a
|
|
123
|
+
* change to what counts as stale cannot land on one store only (the incident this exists for: the
|
|
124
|
+
* memory store checked the SPACE while knowledge checked only the WIDTH, so a model swap mixed two
|
|
125
|
+
* spaces in one index until someone happened to run `kb_reindex`).
|
|
126
|
+
*/
|
|
127
|
+
export declare function loadVectorIndex(opts: {
|
|
128
|
+
store: VectorRepairStore;
|
|
129
|
+
vstore: VectorStore;
|
|
130
|
+
rows: readonly PersistedVectorRow[];
|
|
131
|
+
space: string;
|
|
132
|
+
manualEntry: string;
|
|
133
|
+
}): StaleVectorCounts;
|
|
134
|
+
/** One row the shared encode flow should turn into a vector. */
|
|
135
|
+
export interface VectorEncodeRow {
|
|
136
|
+
id: number;
|
|
137
|
+
text: string;
|
|
138
|
+
}
|
|
139
|
+
/** One encoded row ready to be persisted. */
|
|
140
|
+
export interface EncodedVector {
|
|
141
|
+
id: number;
|
|
142
|
+
bytes: Buffer;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* One store's half of {@link encodeAndPersist}: how to encode, where the live index is, and how a
|
|
146
|
+
* group of vectors is persisted.
|
|
147
|
+
*/
|
|
148
|
+
export interface EncodeWriteTarget {
|
|
149
|
+
readonly store: VectorRepairStore;
|
|
150
|
+
/** The space recorded beside every persisted vector. */
|
|
151
|
+
readonly space: string;
|
|
152
|
+
/** One text → vector. Throwing skips that row (never the group). */
|
|
153
|
+
encode(text: string): Promise<Float32Array>;
|
|
154
|
+
/** Add a freshly encoded vector to THIS store's live index. */
|
|
155
|
+
add(id: number, vec: Float32Array): void;
|
|
156
|
+
/**
|
|
157
|
+
* Persist one group of encoded rows. Throwing fails the WHOLE group, which is what lets the store
|
|
158
|
+
* decide how to reconcile its live index (see {@link onWriteError}).
|
|
159
|
+
*/
|
|
160
|
+
write(rows: readonly EncodedVector[]): void;
|
|
161
|
+
/** Rows per `write` call (default 1). Knowledge uses its measured `WRITE_BATCH`. */
|
|
162
|
+
readonly writeBatch?: number;
|
|
163
|
+
/** Called once per row whose encode (or live-index add) failed. */
|
|
164
|
+
onRowError?(row: VectorEncodeRow, error: unknown): void;
|
|
165
|
+
/** Called once per group whose `write` failed, with the rows that never reached the database. */
|
|
166
|
+
onWriteError?(rows: readonly EncodedVector[], error: unknown): void;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Encode rows one at a time, add each to the live index, and persist them in groups.
|
|
170
|
+
*
|
|
171
|
+
* The shared skeleton: serial encode (a MEASURED decision for chunks — a padded batched forward pass
|
|
172
|
+
* is 1.79x slower on real 53–550 character chunks), `add` right after a successful encode, one
|
|
173
|
+
* `write` call per `writeBatch` rows, per-row isolation of encode failures, per-group isolation of
|
|
174
|
+
* write failures, and the `{ encoded, failed }` count.
|
|
175
|
+
*
|
|
176
|
+
* What stays with the store: the backend call, the live index, the write statement, the replay of a
|
|
177
|
+
* failed group, and the summary log — the memory store logs per row and keeps a half-written index
|
|
178
|
+
* (documented as the benign direction for it), the knowledge store evicts the group so both sides
|
|
179
|
+
* agree that the vectors are missing.
|
|
180
|
+
*/
|
|
181
|
+
export declare function encodeAndPersist(rows: readonly VectorEncodeRow[], target: EncodeWriteTarget): Promise<{
|
|
182
|
+
encoded: number;
|
|
183
|
+
failed: number;
|
|
184
|
+
}>;
|
|
185
|
+
/**
|
|
186
|
+
* ONE bounded slice of the repair: re-add unusable-but-readable vectors that the live index lost,
|
|
187
|
+
* drop the rows a re-encode has to replace, then encode up to `limit` missing/foreign rows.
|
|
188
|
+
*
|
|
189
|
+
* `limit` is what makes the SAME logic usable as a background migration: one call is a bounded unit
|
|
190
|
+
* of work the caller can yield between. The explicit fix passes no limit (the operator action drains
|
|
191
|
+
* everything); the background drive passes its batch size.
|
|
192
|
+
*
|
|
193
|
+
* The ORDER is an invariant: unusable bytes leave the table and the live index first, so a
|
|
194
|
+
* re-encode can pick them up and a process that dies mid-migration leaves at most one batch
|
|
195
|
+
* vector-less — exactly the `missing` rows the next run resumes on.
|
|
196
|
+
*/
|
|
197
|
+
export declare function repairVectorSlice(target: VectorRepairTarget, opts: {
|
|
198
|
+
dryRun: boolean;
|
|
199
|
+
limit?: number;
|
|
200
|
+
}): Promise<{
|
|
201
|
+
report: VectorsFixStoreReport;
|
|
202
|
+
remaining: number;
|
|
203
|
+
}>;
|
|
204
|
+
/**
|
|
205
|
+
* ONE bounded slice of the background migration — the unit the drive (and the tests) step.
|
|
206
|
+
*
|
|
207
|
+
* Resumability is a property of the DATABASE, not of this process: every slice re-derives what is
|
|
208
|
+
* stale from the persisted width/space, so a restart simply continues where the last slice stopped.
|
|
209
|
+
*/
|
|
210
|
+
export declare function migrateVectorSlice(target: VectorRepairTarget, batchSize?: number): Promise<VectorMigrationProgress>;
|
|
211
|
+
/** Options for the background drive; the four log kinds go to `log` (the host logger by default). */
|
|
212
|
+
export interface DriveVectorRepairOptions {
|
|
213
|
+
batchSize?: number;
|
|
214
|
+
/** Plugin unmount / runtime shutdown: stop at the next batch boundary. */
|
|
215
|
+
shouldStop?: () => boolean;
|
|
216
|
+
onProgress?: (progress: VectorMigrationOutcome) => void;
|
|
217
|
+
/** Log sink; `retrievalLogger()` (the host logger once the runtime installed it) when omitted. */
|
|
218
|
+
log?: AvantfLogger;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Drive the bounded background migration for one store until it is current, the model is
|
|
222
|
+
* unavailable, or `shouldStop()` turns true (plugin unmount / process shutdown). A batch FAILURE
|
|
223
|
+
* never rejects: it is logged and reported as `remaining > 0`, which is what makes the next
|
|
224
|
+
* heartbeat a retry. Never blocks the event loop for longer than one batch.
|
|
225
|
+
*
|
|
226
|
+
* Honours `semantic.auto_migrate` (default on) — the switch exists so a host that must not spend CPU
|
|
227
|
+
* on background re-encoding can leave the loud warning and the manual entry as the only path. The
|
|
228
|
+
* switch is read through the adapter so a new store cannot forget it.
|
|
229
|
+
*/
|
|
230
|
+
export declare function driveVectorRepair(target: VectorRepairTarget, opts?: DriveVectorRepairOptions): Promise<VectorMigrationOutcome>;
|
|
231
|
+
/**
|
|
232
|
+
* Drive every store in order. A stop request keeps the drive from starting another store, but each
|
|
233
|
+
* store still answers with its snapshot (so the caller can report what is left everywhere).
|
|
234
|
+
*/
|
|
235
|
+
export declare function driveVectorRepairs(targets: readonly VectorRepairTarget[], opts?: DriveVectorRepairOptions): Promise<VectorMigrationOutcome[]>;
|
|
236
|
+
/**
|
|
237
|
+
* The explicit, unbounded repair behind `mem_admin vectors_fix` / `avantf-mem vectors --fix`,
|
|
238
|
+
* covering one or both stores.
|
|
239
|
+
*
|
|
240
|
+
* `store` selects a single store (omitted = both); `dry_run` previews every count without writing —
|
|
241
|
+
* and without loading the model (so a preview also reports `would_warm`). The top-level
|
|
242
|
+
* `semantic_available` is AND over the selected stores: `false` means at least one store's repair
|
|
243
|
+
* could not encode anything.
|
|
244
|
+
*/
|
|
245
|
+
export declare function vectorsFix(targets: Partial<Record<VectorRepairStore, VectorRepairTarget>>, opts: {
|
|
246
|
+
dryRun: boolean;
|
|
247
|
+
store?: VectorRepairStore;
|
|
248
|
+
}): Promise<VectorsFixReport>;
|
|
@@ -161,6 +161,10 @@ export declare const AdminUnion: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
161
161
|
}, z.core.$strip>, z.ZodObject<{
|
|
162
162
|
action: z.ZodLiteral<"vectors_fix">;
|
|
163
163
|
dry_run: z.ZodOptional<z.ZodBoolean>;
|
|
164
|
+
store: z.ZodOptional<z.ZodEnum<{
|
|
165
|
+
memory: "memory";
|
|
166
|
+
knowledge: "knowledge";
|
|
167
|
+
}>>;
|
|
164
168
|
}, z.core.$strip>, z.ZodObject<{
|
|
165
169
|
action: z.ZodLiteral<"contradict_check">;
|
|
166
170
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -507,22 +507,53 @@ export interface VectorMigrationOutcome extends VectorMigrationProgress {
|
|
|
507
507
|
enabled: boolean;
|
|
508
508
|
}
|
|
509
509
|
/**
|
|
510
|
-
*
|
|
510
|
+
* ONE store's part of a vector repair (`mem_admin vectors_fix`).
|
|
511
|
+
*
|
|
512
|
+
* The common subset (`stale` / `space_stale` / `dropped` / `encoded` / `failed` /
|
|
513
|
+
* `semantic_available`) is what both stores report; `missing` and `would_warm` are shared steps of
|
|
514
|
+
* the repair flow, and `unindexed` / `reindexed` are only meaningful to a store that tracks its live
|
|
515
|
+
* index (memory — knowledge rebuilds it at open and keeps it in sync on every write).
|
|
511
516
|
*
|
|
512
517
|
* `semantic_available` is "the model is loaded RIGHT NOW" (a dry run must not load it), so the
|
|
513
518
|
* preview also carries `would_warm`: together they separate "unknown until you run it" from
|
|
514
519
|
* "the warmup was attempted and failed".
|
|
515
520
|
*/
|
|
516
|
-
export interface
|
|
517
|
-
|
|
521
|
+
export interface VectorsFixStoreReport {
|
|
522
|
+
/** ACTIVE rows whose persisted vector has the wrong width. */
|
|
518
523
|
stale: number;
|
|
524
|
+
/** ACTIVE rows whose usable-width vector was recorded in another space. */
|
|
519
525
|
space_stale: number;
|
|
520
|
-
|
|
521
|
-
|
|
526
|
+
/** ACTIVE rows with no persisted vector at all (what the repair has to encode). */
|
|
527
|
+
missing: number;
|
|
528
|
+
/** Rows whose unusable old-space bytes were cleared so a re-encode could replace them. */
|
|
522
529
|
dropped: number;
|
|
523
|
-
|
|
530
|
+
/** Rows re-encoded into the current space by this repair. */
|
|
531
|
+
encoded: number;
|
|
532
|
+
/** Rows whose encode or write failed; they stay `missing` / `stale` for the next pass. */
|
|
533
|
+
failed: number;
|
|
534
|
+
/** The model is loaded right now. */
|
|
524
535
|
semantic_available: boolean;
|
|
536
|
+
/** The model was NOT loaded at entry, so a real run would attempt a warmup. */
|
|
525
537
|
would_warm: boolean;
|
|
538
|
+
/** Usable persisted vectors absent from the live index (memory only). */
|
|
539
|
+
unindexed?: number;
|
|
540
|
+
/** Usable persisted vectors put back into the live index by this repair (memory only). */
|
|
541
|
+
reindexed?: number;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* `mem_admin vectors_fix`: what a repair did, or — with `dry_run` — what it WOULD do, per store.
|
|
545
|
+
*
|
|
546
|
+
* The report is per-store because one switch and one call now cover BOTH libraries (a model swap
|
|
547
|
+
* leaves memory and knowledge in the same state, and the repair used to exist for memory only).
|
|
548
|
+
* `store` on the request narrows the call to one library; the top-level `semantic_available` is the
|
|
549
|
+
* AND over the stores actually repaired.
|
|
550
|
+
*/
|
|
551
|
+
export interface VectorsFixReport {
|
|
552
|
+
stores: {
|
|
553
|
+
memory?: VectorsFixStoreReport;
|
|
554
|
+
knowledge?: VectorsFixStoreReport;
|
|
555
|
+
};
|
|
556
|
+
semantic_available: boolean;
|
|
526
557
|
dry_run: boolean;
|
|
527
558
|
}
|
|
528
559
|
/** `kb_manage ingest`: what one document produced. */
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Reranker } from '../interfaces.js';
|
|
2
|
+
import { type ModelEnv } from './local_bge.js';
|
|
3
|
+
/** One text-classification result: transformers.js yields `{label, score}`; tolerate a raw `{data}` tensor too. */
|
|
4
|
+
type ClassifyResult = {
|
|
5
|
+
label?: string;
|
|
6
|
+
score?: number;
|
|
7
|
+
data?: number[];
|
|
8
|
+
};
|
|
9
|
+
/** The injected pipeline surface: a batch of (query, document) pairs in, scores out. */
|
|
10
|
+
export type ClassifyFn = (inputs: [string, string][], opts?: Record<string, unknown>) => Promise<ClassifyResult[]>;
|
|
11
|
+
/** Injectable seam: tests supply a fake classifier instead of the transformers.js import. */
|
|
12
|
+
export type RerankerPipeFactory = (model: string, env: ModelEnv) => Promise<ClassifyFn>;
|
|
13
|
+
/** Never hand the classifier a degenerate document; below this the score is meaningless. */
|
|
14
|
+
export declare const MIN_DOC_TOKENS = 16;
|
|
15
|
+
/**
|
|
16
|
+
* Local cross-encoder reranker via `@huggingface/transformers` (`bge-reranker`).
|
|
17
|
+
* Lazily imported; `warmUp()` configures the mirror/cache and triggers a load.
|
|
18
|
+
* Degrades to identity order when the package/model is not available.
|
|
19
|
+
*
|
|
20
|
+
* Like {@link LocalBgeBackend}, a failed warmup is retryable through
|
|
21
|
+
* `ensureWarm()` rather than being final until the next restart.
|
|
22
|
+
*/
|
|
23
|
+
export declare class LocalReranker implements Reranker {
|
|
24
|
+
readonly name = "bge_reranker";
|
|
25
|
+
private _available;
|
|
26
|
+
private _pipe;
|
|
27
|
+
private _warming;
|
|
28
|
+
private _lengthWarned;
|
|
29
|
+
private _window;
|
|
30
|
+
private readonly configuredMax;
|
|
31
|
+
private readonly model;
|
|
32
|
+
private readonly env;
|
|
33
|
+
private readonly pipeFactory;
|
|
34
|
+
private readonly gate;
|
|
35
|
+
constructor(model: string, env?: Partial<ModelEnv>, pipeFactory?: RerankerPipeFactory);
|
|
36
|
+
isAvailable(): boolean;
|
|
37
|
+
/** Fire-and-forget retry for call sites that only observe availability (see `warm_gate.ts`). */
|
|
38
|
+
ensureWarm(): void;
|
|
39
|
+
warmUp(): Promise<void>;
|
|
40
|
+
private _doWarmup;
|
|
41
|
+
private window;
|
|
42
|
+
/**
|
|
43
|
+
* Bound one document for a pair, given how much of the window the query already spends.
|
|
44
|
+
* Returns the document text unchanged when it fits.
|
|
45
|
+
*/
|
|
46
|
+
private boundDocument;
|
|
47
|
+
rerank(query: string, candidates: {
|
|
48
|
+
id: number;
|
|
49
|
+
text: string;
|
|
50
|
+
}[]): Promise<number[]>;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Reranker } from '../interfaces.js';
|
|
2
|
+
/** `none` — reranking disabled (the default). Reports unavailable so callers skip the rerank pass entirely. */
|
|
3
|
+
export declare class NoneReranker implements Reranker {
|
|
4
|
+
readonly name = "none";
|
|
5
|
+
isAvailable(): boolean;
|
|
6
|
+
rerank(_query: string, candidates: {
|
|
7
|
+
id: number;
|
|
8
|
+
text: string;
|
|
9
|
+
}[]): Promise<number[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Reranker } from './interfaces.js';
|
|
2
|
+
/**
|
|
3
|
+
* The one rerank-and-reorder pass shared by every retrieval leg (memory search,
|
|
4
|
+
* knowledge search — the blocks were byte-identical and had already drifted once
|
|
5
|
+
* on the miss-sort sentinel).
|
|
6
|
+
*
|
|
7
|
+
* Contract: `reranker.rerank` returns candidate ids best-first; ids it omits sort
|
|
8
|
+
* last with their fused order preserved (stable sort). A disabled/unavailable
|
|
9
|
+
* reranker is a pass-through.
|
|
10
|
+
*/
|
|
11
|
+
export declare function rerankHits<T extends {
|
|
12
|
+
id: number;
|
|
13
|
+
}>(reranker: Reranker, query: string, hits: T[], textOf: (id: number) => string): Promise<T[]>;
|