@melandlabs/memory-store 1.3.6 → 1.3.8
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 +5 -0
- package/dist/config-9RzSCdXG.d.ts +550 -0
- package/dist/contracts.d.ts +3 -1
- package/dist/evidence-selector-uOHsxwch.d.ts +597 -0
- package/dist/http.d.ts +2 -1
- package/dist/http.js +676 -153
- package/dist/index.d.ts +6 -4
- package/dist/index.js +768 -148
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.js +689 -153
- package/dist/search/derive.d.ts +2 -1
- package/dist/search/derive.js +5 -1
- package/dist/search/distill.d.ts +2 -1
- package/dist/search/evidence-selector.d.ts +3 -0
- package/dist/search/evidence-selector.js +153 -0
- package/dist/search/unified-search.d.ts +3 -2
- package/dist/search/unified-search.js +589 -136
- package/dist/server/cli-http.js +1150 -271
- package/dist/server/cli-mcp.js +1163 -271
- package/dist/server/cli-shared.d.ts +18 -2
- package/dist/server/cli-shared.js +493 -119
- package/dist/storage/postgres-raw-message-factory.d.ts +2 -1
- package/dist/storage/raw-message-store.d.ts +10 -2
- package/dist/storage/sqlite-raw-message-store.d.ts +2 -1
- package/dist/storage/sqlite-vector-index.d.ts +2 -1
- package/dist/{unified-search-CtFFRj2O.d.ts → unified-search-BBC3jkPJ.d.ts} +2 -1
- package/package.json +15 -14
- package/dist/config-BuWr-nvt.d.ts +0 -988
|
@@ -1,988 +0,0 @@
|
|
|
1
|
-
import * as _melandlabs_memory_consolidation from '@melandlabs/memory-consolidation';
|
|
2
|
-
import { MemoryApplicabilityContext } from '@melandlabs/memory-consolidation';
|
|
3
|
-
import * as _melandlabs_contracts_peer from '@melandlabs/contracts/peer';
|
|
4
|
-
import { Peer } from '@melandlabs/contracts/peer';
|
|
5
|
-
import { FactType } from '@melandlabs/contracts';
|
|
6
|
-
import { DerivedFact } from '@melandlabs/contracts/derived-fact';
|
|
7
|
-
import { EntityEdge } from '@melandlabs/contracts/entity-edge';
|
|
8
|
-
import { RawMessage, RawMessageSearchChunk } from '@melandlabs/indexeddb';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Reranker adapter contract.
|
|
12
|
-
*
|
|
13
|
-
* A `Reranker` is an optional plug-in applied to the unified-search output
|
|
14
|
-
* after per-source merge but before the final `slice(0, limit)`. It lets a
|
|
15
|
-
* host swap in a cross-encoder, a learned ranker, or any other deterministic
|
|
16
|
-
* ordering without changing the retrieval pipeline.
|
|
17
|
-
*
|
|
18
|
-
* Implementations MUST be deterministic for the same `(query, candidates)`
|
|
19
|
-
* pair — non-deterministic orderings would defeat the existing
|
|
20
|
-
* `rrfScore`/`similarity` tie-break tests.
|
|
21
|
-
*/
|
|
22
|
-
interface RerankerCandidate {
|
|
23
|
-
id: string;
|
|
24
|
-
content: string;
|
|
25
|
-
metadata?: Record<string, unknown>;
|
|
26
|
-
}
|
|
27
|
-
interface RerankerInput {
|
|
28
|
-
query: string;
|
|
29
|
-
candidates: RerankerCandidate[];
|
|
30
|
-
topK?: number;
|
|
31
|
-
}
|
|
32
|
-
interface RerankerScore {
|
|
33
|
-
id: string;
|
|
34
|
-
score: number;
|
|
35
|
-
}
|
|
36
|
-
interface Reranker {
|
|
37
|
-
rerank(input: RerankerInput): Promise<RerankerScore[]>;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Pure helpers used by the unified memory search pipeline.
|
|
42
|
-
*
|
|
43
|
-
* Kept side-effect free so they can be reused by tests, MCP tools,
|
|
44
|
-
* and the HTTP daemon without pulling in any of the heavier
|
|
45
|
-
* storage/search implementations.
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
type UnifiedMemorySearchSource = "memory" | "insights" | "knowledge";
|
|
49
|
-
/**
|
|
50
|
-
* A retrieval channel that contributed to a hit's final score.
|
|
51
|
-
*
|
|
52
|
-
* - `semantic` — dense embedding lookup (`searchRawMessagesAnn` or
|
|
53
|
-
* the SQLite manager's semantic-search fallback).
|
|
54
|
-
* - `lexical` — BM25 / FTS5 keyword match
|
|
55
|
-
* (`searchRawMessagesLexical` or the SQLite manager's lexical
|
|
56
|
-
* fallback).
|
|
57
|
-
* - `entity` — entity-link match supplied by the host's
|
|
58
|
-
* `entitySearch` dep.
|
|
59
|
-
*/
|
|
60
|
-
type HitChannel = "semantic" | "lexical" | "hybrid" | "entity";
|
|
61
|
-
/**
|
|
62
|
-
* Per-hit score breakdown. Always emitted by `search()` (default merge
|
|
63
|
-
* strategy) so callers can threshold / re-rank without losing the
|
|
64
|
-
* individual channel contributions. The RRF fusion additionally
|
|
65
|
-
* populates `signals.rrf` and continues to mirror the fused score
|
|
66
|
-
* onto `metadata.rrfScore` (legacy field).
|
|
67
|
-
*
|
|
68
|
-
* Each numeric field is the raw per-channel score for the *first*
|
|
69
|
-
* (highest-ranked) appearance of the same `(type, id)` key in the
|
|
70
|
-
* channel's list. Channels that did not contribute are `undefined`.
|
|
71
|
-
*/
|
|
72
|
-
interface HitSignals {
|
|
73
|
-
/** Channels the hit actually appeared in. */
|
|
74
|
-
channels: HitChannel[];
|
|
75
|
-
/** Semantic sub-query similarity in [0..1] (undefined when absent). */
|
|
76
|
-
semantic?: number;
|
|
77
|
-
/** Lexical sub-query BM25 score (undefined when absent). */
|
|
78
|
-
lexical?: number;
|
|
79
|
-
/** Native backend dense+BM25 fused score (undefined when absent). */
|
|
80
|
-
hybrid?: number;
|
|
81
|
-
/** Entity sub-query match score (undefined when absent). */
|
|
82
|
-
entity?: number;
|
|
83
|
-
/** RRF-fused score (only when mergeStrategy === "rrf"). */
|
|
84
|
-
rrf?: number;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Derive simple lexical keywords from a query string. Splits on any
|
|
88
|
-
* non-letter/non-digit Unicode boundary, lowercases, drops tokens
|
|
89
|
-
* shorter than 2 chars, and caps the list at 16. Used by the unified
|
|
90
|
-
* search lexical sub-query and by the `derive` primitive's candidate
|
|
91
|
-
* fetch fallback.
|
|
92
|
-
*/
|
|
93
|
-
declare function deriveLexicalKeywords(query: string): string[];
|
|
94
|
-
type UnifiedMemoryReasoningStrategy = "none" | "rewrite" | "iterative" | "union";
|
|
95
|
-
interface UnifiedMemorySearchWarning {
|
|
96
|
-
source: UnifiedMemorySearchSource;
|
|
97
|
-
code: string;
|
|
98
|
-
message: string;
|
|
99
|
-
}
|
|
100
|
-
interface UnifiedMemoryReasoningInfo {
|
|
101
|
-
strategy: UnifiedMemoryReasoningStrategy;
|
|
102
|
-
/**
|
|
103
|
-
* True when the caller asked for a non-`"none"` strategy but the
|
|
104
|
-
* corresponding reasoning provider was not configured (or its LLM
|
|
105
|
-
* call failed), so the unified search silently fell back to the default
|
|
106
|
-
* one-shot semantic + lexical path. Callers can use this to surface a
|
|
107
|
-
* degraded-mode warning to their users.
|
|
108
|
-
*/
|
|
109
|
-
degraded?: boolean;
|
|
110
|
-
/** Query variants produced by the rewriter (original + rewritten). */
|
|
111
|
-
rewrittenQueries?: string[];
|
|
112
|
-
/** Number of planner iterations executed (iterative mode only). */
|
|
113
|
-
iterations?: number;
|
|
114
|
-
/** Number of evidence items collected by the planner (iterative mode only). */
|
|
115
|
-
evidenceCount?: number;
|
|
116
|
-
/** Date range that was applied to the memory source, if any. */
|
|
117
|
-
dateRange?: {
|
|
118
|
-
from?: string;
|
|
119
|
-
to?: string;
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
interface UnifiedMemorySearchInput {
|
|
123
|
-
userId: string;
|
|
124
|
-
query: string;
|
|
125
|
-
sources?: UnifiedMemorySearchSource[];
|
|
126
|
-
limit?: number;
|
|
127
|
-
threshold?: number;
|
|
128
|
-
authToken?: string;
|
|
129
|
-
includeArchivedInsights?: boolean;
|
|
130
|
-
botIds?: string[];
|
|
131
|
-
documentIds?: string[];
|
|
132
|
-
/**
|
|
133
|
-
* Optional ISO-8601 timestamp. When set, graph-aware retrieval and other
|
|
134
|
-
* snapshot consumers drop nodes / edges whose `applicability.validFrom` /
|
|
135
|
-
* `validUntil` window is closed at that instant. Backward-compatible:
|
|
136
|
-
* omitted `asOf` keeps the legacy behaviour exactly.
|
|
137
|
-
*
|
|
138
|
-
* This is a single-point snapshot, not a date range. For interval filtering
|
|
139
|
-
* over memory timestamps use `dateFrom` / `dateTo`.
|
|
140
|
-
*/
|
|
141
|
-
asOf?: string;
|
|
142
|
-
/**
|
|
143
|
-
* Optional inclusive start date (ISO-8601). When set, the memory source
|
|
144
|
-
* filters out candidates whose timestamp is before this boundary. The
|
|
145
|
-
* iterative planner also receives this bound and may emit narrower ranges.
|
|
146
|
-
*
|
|
147
|
-
* This only affects the `memory` source; `insights` and `knowledge` are
|
|
148
|
-
* not filtered by this range. Candidates without a recognised timestamp are
|
|
149
|
-
* retained.
|
|
150
|
-
*/
|
|
151
|
-
dateFrom?: string;
|
|
152
|
-
/**
|
|
153
|
-
* Optional inclusive end date (ISO-8601). When set, the memory source
|
|
154
|
-
* filters out candidates whose timestamp is after this boundary. Date-only
|
|
155
|
-
* strings are treated as the end of that day.
|
|
156
|
-
*
|
|
157
|
-
* This only affects the `memory` source; `insights` and `knowledge` are
|
|
158
|
-
* not filtered by this range. Candidates without a recognised timestamp are
|
|
159
|
-
* retained.
|
|
160
|
-
*/
|
|
161
|
-
dateTo?: string;
|
|
162
|
-
/**
|
|
163
|
-
* How to merge per-source result lists. Defaults to `"rrf"` reciprocal-rank
|
|
164
|
-
* fusion. `"similarity"` preserves the legacy global similarity sort.
|
|
165
|
-
*/
|
|
166
|
-
mergeStrategy?: UnifiedMemoryMergeStrategy;
|
|
167
|
-
/**
|
|
168
|
-
* Optional additive scope-narrowing filter expressed as structured
|
|
169
|
-
* peers. Coexists with `userId`/`botIds`. When supplied, the host's
|
|
170
|
-
* `UnifiedSearchDeps.peerScopeCheck` is consulted; peers that fall
|
|
171
|
-
* outside `userId` are dropped with a `peer_filter_outside_user_scope`
|
|
172
|
-
* warning rather than broadening the scope.
|
|
173
|
-
*/
|
|
174
|
-
peerFilter?: ReadonlyArray<Peer>;
|
|
175
|
-
/**
|
|
176
|
-
* Optional reasoning strategy. `"rewrite"` rewrites the query before
|
|
177
|
-
* embedding; `"iterative"` runs an LLM planner that searches, notes
|
|
178
|
-
* evidence, and searches again. Defaults to `"none"`.
|
|
179
|
-
*/
|
|
180
|
-
reasoningStrategy?: UnifiedMemoryReasoningStrategy;
|
|
181
|
-
/**
|
|
182
|
-
* Optional `FactType` read-side filter. When supplied, the memory
|
|
183
|
-
* source narrows candidates to rows whose `factType` is in this set.
|
|
184
|
-
* Only affects the `memory` source; `insights` and `knowledge` are
|
|
185
|
-
* not filtered by this. Empty array is treated as "no filter" so
|
|
186
|
-
* callers can pass `searchInput.factTypes ?? []` without surprises.
|
|
187
|
-
*/
|
|
188
|
-
factTypes?: FactType[];
|
|
189
|
-
/** Include pre-fusion channel candidates in the response for diagnostics. */
|
|
190
|
-
includeRetrievalDiagnostics?: boolean;
|
|
191
|
-
/**
|
|
192
|
-
* Include messages that have been soft-deprecated
|
|
193
|
-
* (`raw_messages.deprecated_at IS NOT NULL`). Default `false` keeps
|
|
194
|
-
* `current-truth` retrievals clean: a row that was marked superseded
|
|
195
|
-
* via `deprecateMessages` (or the `opencontext deprecate` CLI) is
|
|
196
|
-
* excluded from results. Set to `true` for audits and historical
|
|
197
|
-
* exploration.
|
|
198
|
-
*/
|
|
199
|
-
includeDeprecated?: boolean;
|
|
200
|
-
}
|
|
201
|
-
type UnifiedMemoryMergeStrategy = "similarity" | "rrf";
|
|
202
|
-
/**
|
|
203
|
-
* A single ranked list from one retrieval channel. Used by the RRF merge to
|
|
204
|
-
* combine multiple signals (semantic + lexical + insights + knowledge) without
|
|
205
|
-
* flattening them into a single similarity score first.
|
|
206
|
-
*/
|
|
207
|
-
interface UnifiedMemoryRankedList {
|
|
208
|
-
/** Label for the source list (e.g. a tier or channel). Free-form; the
|
|
209
|
-
* RRF fusion only reads `hits`, so `name` is purely diagnostic. */
|
|
210
|
-
name: string;
|
|
211
|
-
hits: UnifiedMemorySearchResult[];
|
|
212
|
-
}
|
|
213
|
-
interface UnifiedMemorySearchResult {
|
|
214
|
-
type: "memory" | "insight" | "knowledge";
|
|
215
|
-
id: string;
|
|
216
|
-
content: string;
|
|
217
|
-
similarity: number;
|
|
218
|
-
metadata: Record<string, unknown>;
|
|
219
|
-
/**
|
|
220
|
-
* Optional per-channel score breakdown. Always populated by the
|
|
221
|
-
* pipeline when at least one channel contributed a non-empty list;
|
|
222
|
-
* callers should treat absence as "no channel info available".
|
|
223
|
-
*/
|
|
224
|
-
signals?: HitSignals;
|
|
225
|
-
}
|
|
226
|
-
interface UnifiedMemorySearchOutput {
|
|
227
|
-
query: string;
|
|
228
|
-
sources: UnifiedMemorySearchSource[];
|
|
229
|
-
results: UnifiedMemorySearchResult[];
|
|
230
|
-
count: number;
|
|
231
|
-
warnings: UnifiedMemorySearchWarning[];
|
|
232
|
-
retrievalDiagnostics?: UnifiedMemoryRetrievalDiagnostics;
|
|
233
|
-
/**
|
|
234
|
-
* Diagnostic information about reasoning and date filtering. Present
|
|
235
|
-
* when (a) a non-`"none"` reasoning strategy was requested, or (b) a
|
|
236
|
-
* `dateFrom` / `dateTo` filter was applied to the memory source.
|
|
237
|
-
*/
|
|
238
|
-
reasoning?: UnifiedMemoryReasoningInfo;
|
|
239
|
-
}
|
|
240
|
-
interface UnifiedMemoryRetrievalDiagnostics {
|
|
241
|
-
mergeStrategy: UnifiedMemoryMergeStrategy;
|
|
242
|
-
candidateLimit: number;
|
|
243
|
-
backend?: string;
|
|
244
|
-
semanticDegradedReason?: string;
|
|
245
|
-
candidateCounts?: {
|
|
246
|
-
semantic: number;
|
|
247
|
-
lexical: number;
|
|
248
|
-
hybrid: number;
|
|
249
|
-
entity: number;
|
|
250
|
-
fused: number;
|
|
251
|
-
final: number;
|
|
252
|
-
};
|
|
253
|
-
channels: {
|
|
254
|
-
semantic: UnifiedMemorySearchResult[];
|
|
255
|
-
lexical: UnifiedMemorySearchResult[];
|
|
256
|
-
hybrid?: UnifiedMemorySearchResult[];
|
|
257
|
-
entity?: UnifiedMemorySearchResult[];
|
|
258
|
-
};
|
|
259
|
-
/** Results after channel/source fusion and before an optional host reranker. */
|
|
260
|
-
fusedBeforeRerank: UnifiedMemorySearchResult[];
|
|
261
|
-
reranker?: {
|
|
262
|
-
enabled: boolean;
|
|
263
|
-
provider?: string;
|
|
264
|
-
model?: string;
|
|
265
|
-
inputCount: number;
|
|
266
|
-
outputCount: number;
|
|
267
|
-
latencyMs: number;
|
|
268
|
-
orderChanged: boolean;
|
|
269
|
-
};
|
|
270
|
-
/** Final results after optional reranking and Top-K truncation. */
|
|
271
|
-
final: UnifiedMemorySearchResult[];
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Cross-source retrieval surface for the unified search. Mirrors
|
|
275
|
-
* `UnifiedMemorySearchSource` but is exposed under a more discoverable
|
|
276
|
-
* name.
|
|
277
|
-
*/
|
|
278
|
-
type SearchSource = UnifiedMemorySearchSource;
|
|
279
|
-
/**
|
|
280
|
-
* Per-tier evidence bucket consulted by `reflect`-style synthesis.
|
|
281
|
-
* Includes the `summary` tier that the read-only sources do not surface.
|
|
282
|
-
*/
|
|
283
|
-
type SearchTier = "summary" | "raw" | "insight" | "knowledge";
|
|
284
|
-
interface SearchInput {
|
|
285
|
-
userId: string;
|
|
286
|
-
query: string;
|
|
287
|
-
/** Cross-source retrieval surface (defaults to all three sources). */
|
|
288
|
-
sources?: ReadonlyArray<SearchSource>;
|
|
289
|
-
/**
|
|
290
|
-
* Per-tier subset — when omitted, defaults to all four tiers.
|
|
291
|
-
* Forwarded to the gather step so the read pipeline can scope the
|
|
292
|
-
* evidence. Most callers pass nothing; `synthesize` callers can
|
|
293
|
-
* narrow to `["raw"]` or `["summary", "raw"]` for cheaper synthesis.
|
|
294
|
-
*/
|
|
295
|
-
tiers?: ReadonlyArray<SearchTier>;
|
|
296
|
-
/**
|
|
297
|
-
* Opt-in LLM synthesis. When `true`, runs `reasoning.complete` after
|
|
298
|
-
* gathering evidence and returns `answer` in the output. When
|
|
299
|
-
* omitted / `false`, no LLM call is made (matches today's
|
|
300
|
-
* `searchUnifiedMemory`). The `responseSchema` form lets the LLM
|
|
301
|
-
* return JSON; the SDK extracts `{ answer: string }` from the
|
|
302
|
-
* payload and surfaces the rest via warnings.
|
|
303
|
-
*/
|
|
304
|
-
synthesize?: boolean | {
|
|
305
|
-
responseSchema?: Record<string, unknown>;
|
|
306
|
-
};
|
|
307
|
-
limit?: number;
|
|
308
|
-
threshold?: number;
|
|
309
|
-
botIds?: string[];
|
|
310
|
-
documentIds?: string[];
|
|
311
|
-
dateFrom?: string;
|
|
312
|
-
dateTo?: string;
|
|
313
|
-
asOf?: string;
|
|
314
|
-
peerFilter?: ReadonlyArray<Peer>;
|
|
315
|
-
authToken?: string;
|
|
316
|
-
factTypes?: FactType[];
|
|
317
|
-
mergeStrategy?: UnifiedMemoryMergeStrategy;
|
|
318
|
-
reasoningStrategy?: UnifiedMemoryReasoningStrategy;
|
|
319
|
-
/**
|
|
320
|
-
* Backward-compat pass-through for callers that previously passed
|
|
321
|
-
* `responseSchema` at the top level. When set, it overrides
|
|
322
|
-
* `synthesize.responseSchema`.
|
|
323
|
-
*/
|
|
324
|
-
responseSchema?: Record<string, unknown>;
|
|
325
|
-
/**
|
|
326
|
-
* Backward-compat pass-through for callers that previously passed
|
|
327
|
-
* `includeArchivedInsights` to the read-only search.
|
|
328
|
-
*/
|
|
329
|
-
includeArchivedInsights?: boolean;
|
|
330
|
-
/** Include pre-fusion retrieval candidates; intended for evaluation/debugging. */
|
|
331
|
-
includeRetrievalDiagnostics?: boolean;
|
|
332
|
-
/**
|
|
333
|
-
* Include messages that have been soft-deprecated
|
|
334
|
-
* (`raw_messages.deprecated_at IS NOT NULL`). Default `false` keeps
|
|
335
|
-
* `current-truth` retrievals clean: a row that was marked superseded
|
|
336
|
-
* via `deprecateMessages` (or the `opencontext deprecate` CLI) is
|
|
337
|
-
* excluded from results. Set to `true` for audits and historical
|
|
338
|
-
* exploration.
|
|
339
|
-
*/
|
|
340
|
-
includeDeprecated?: boolean;
|
|
341
|
-
}
|
|
342
|
-
interface SearchEvidence {
|
|
343
|
-
id: string;
|
|
344
|
-
source: SearchSource | SearchTier;
|
|
345
|
-
snippet: string;
|
|
346
|
-
score: number;
|
|
347
|
-
timestamp?: number;
|
|
348
|
-
/**
|
|
349
|
-
* Forwarded from the underlying hit's `metadata`. Surfaces per-fact
|
|
350
|
-
* provenance (`metadata.source`, `metadata.factType`, etc.) to the
|
|
351
|
-
* synthesis prompt and the CLI's `--context-only` / `--json` output.
|
|
352
|
-
*/
|
|
353
|
-
metadata?: Record<string, unknown>;
|
|
354
|
-
}
|
|
355
|
-
interface SearchOutput {
|
|
356
|
-
query: string;
|
|
357
|
-
sources: ReadonlyArray<SearchSource>;
|
|
358
|
-
results: UnifiedMemorySearchResult[];
|
|
359
|
-
/** Same hits as `results`, with the source labelled for synthesis callers. */
|
|
360
|
-
evidence: SearchEvidence[];
|
|
361
|
-
count: number;
|
|
362
|
-
warnings: UnifiedMemorySearchWarning[];
|
|
363
|
-
retrievalDiagnostics?: UnifiedMemoryRetrievalDiagnostics;
|
|
364
|
-
reasoning?: UnifiedMemoryReasoningInfo;
|
|
365
|
-
/** Only present when `synthesize` was truthy. */
|
|
366
|
-
answer?: string;
|
|
367
|
-
}
|
|
368
|
-
declare function normalizeUnifiedMemorySearchSources(sources: unknown): UnifiedMemorySearchSource[];
|
|
369
|
-
declare function clampUnifiedMemorySearchLimit(limit: unknown): number;
|
|
370
|
-
declare function clampUnifiedMemorySearchThreshold(threshold: unknown): number;
|
|
371
|
-
declare function mergeUnifiedMemorySearchResults(results: UnifiedMemorySearchResult[], limit: number, options?: {
|
|
372
|
-
strategy?: UnifiedMemoryMergeStrategy;
|
|
373
|
-
rankedLists?: UnifiedMemoryRankedList[];
|
|
374
|
-
}): UnifiedMemorySearchResult[];
|
|
375
|
-
declare function normalizeUnifiedMemoryMergeStrategy(value: unknown): UnifiedMemoryMergeStrategy;
|
|
376
|
-
declare function normalizeUnifiedMemoryReasoningStrategy(value: unknown, defaultStrategy?: UnifiedMemoryReasoningStrategy): UnifiedMemoryReasoningStrategy;
|
|
377
|
-
/**
|
|
378
|
-
* Reciprocal Rank Fusion across multiple ranked lists. Each list contributes
|
|
379
|
-
* `1 / (k + rank + 1)` to a hit's accumulated score. Hits are de-duplicated by
|
|
380
|
-
* `(type, id)` so the same message surfaced by both lexical and semantic
|
|
381
|
-
* channels naturally outranks single-channel matches. Tie-break is
|
|
382
|
-
* deterministic: descending RRF score, then `(type, id)` lexical.
|
|
383
|
-
*/
|
|
384
|
-
declare function mergeUnifiedMemorySearchResultsRrf(lists: UnifiedMemoryRankedList[], limit: number, k?: number): UnifiedMemorySearchResult[];
|
|
385
|
-
declare function toKnowledgeResult(result: {
|
|
386
|
-
chunkId: string;
|
|
387
|
-
documentId: string;
|
|
388
|
-
documentName: string;
|
|
389
|
-
content: string;
|
|
390
|
-
similarity: number;
|
|
391
|
-
chunkIndex: number;
|
|
392
|
-
}): UnifiedMemorySearchResult;
|
|
393
|
-
declare function toMemoryResult(result: {
|
|
394
|
-
id: string;
|
|
395
|
-
content: string;
|
|
396
|
-
similarity: number;
|
|
397
|
-
metadata: Record<string, unknown>;
|
|
398
|
-
}): UnifiedMemorySearchResult;
|
|
399
|
-
/**
|
|
400
|
-
* Build the `signals` breakdown for a single hit from the per-channel
|
|
401
|
-
* ranked lists it appeared in. Only the highest-ranked (i.e. first)
|
|
402
|
-
* appearance of `(type, id)` per channel contributes — duplicate hits
|
|
403
|
-
* later in the same list are ignored so the breakdown stays
|
|
404
|
-
* deterministic.
|
|
405
|
-
*
|
|
406
|
-
* Used by `mergeAcrossSources` to attach `signals` to every emitted
|
|
407
|
-
* `UnifiedMemorySearchResult`. Pure; no I/O.
|
|
408
|
-
*/
|
|
409
|
-
declare function materializeSignals(lists: ReadonlyArray<{
|
|
410
|
-
name: string;
|
|
411
|
-
hits: UnifiedMemorySearchResult[];
|
|
412
|
-
}>, hit: UnifiedMemorySearchResult): HitSignals | undefined;
|
|
413
|
-
/**
|
|
414
|
-
* Map a `UnifiedMemoryRankedList.name` to a `HitChannel`. Unknown names
|
|
415
|
-
* (e.g. "insights", "knowledge", "summary") are not channels — they
|
|
416
|
-
* surface their similarity through the merge's `similarity` field and
|
|
417
|
-
* are simply skipped here so callers can still see which channel set
|
|
418
|
-
* the hit came from.
|
|
419
|
-
*/
|
|
420
|
-
declare function listNameToChannel(name: string): HitChannel | undefined;
|
|
421
|
-
declare function isRawMemorySemanticResult(result: unknown): result is {
|
|
422
|
-
id: string;
|
|
423
|
-
content: string;
|
|
424
|
-
similarity: number;
|
|
425
|
-
metadata: Record<string, unknown>;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Iterative, LLM-driven memory retrieval.
|
|
430
|
-
*
|
|
431
|
-
* Instead of issuing one fixed query, a small planner model examines the
|
|
432
|
-
* original question and the evidence collected so far, then decides:
|
|
433
|
-
* - search again with different keywords / time bounds
|
|
434
|
-
* - save some of the last results as evidence
|
|
435
|
-
* - finish gathering
|
|
436
|
-
*
|
|
437
|
-
* This trades latency and token cost for better evidence location on
|
|
438
|
-
* multi-hop, temporal, or underspecified questions.
|
|
439
|
-
*
|
|
440
|
-
* The module is provider-agnostic: callers inject a `complete` callback.
|
|
441
|
-
*/
|
|
442
|
-
interface IterativeRecallCandidate {
|
|
443
|
-
id: string;
|
|
444
|
-
content: string;
|
|
445
|
-
similarity: number;
|
|
446
|
-
metadata: Record<string, unknown>;
|
|
447
|
-
}
|
|
448
|
-
interface IterativeRecallSearchRequest {
|
|
449
|
-
keywords: string[];
|
|
450
|
-
dateFrom?: string;
|
|
451
|
-
dateTo?: string;
|
|
452
|
-
}
|
|
453
|
-
interface IterativeRecallSearchResult {
|
|
454
|
-
candidates: IterativeRecallCandidate[];
|
|
455
|
-
}
|
|
456
|
-
interface IterativeRecallExecutor {
|
|
457
|
-
search(request: IterativeRecallSearchRequest): Promise<IterativeRecallSearchResult>;
|
|
458
|
-
}
|
|
459
|
-
interface IterativeRecallStats {
|
|
460
|
-
iterations: number;
|
|
461
|
-
searches: number;
|
|
462
|
-
notes: number;
|
|
463
|
-
}
|
|
464
|
-
interface IterativeRecallResult {
|
|
465
|
-
/** Evidence selected by the planner, in the order it was collected. */
|
|
466
|
-
evidence: IterativeRecallCandidate[];
|
|
467
|
-
/** Diagnostic statistics. */
|
|
468
|
-
stats: IterativeRecallStats;
|
|
469
|
-
}
|
|
470
|
-
interface IterativeRecallPlanner {
|
|
471
|
-
plan(input: {
|
|
472
|
-
query: string;
|
|
473
|
-
executor: IterativeRecallExecutor;
|
|
474
|
-
options?: IterativeRecallPlannerOptions;
|
|
475
|
-
/**
|
|
476
|
-
* Optional absolute date range for the search. The planner passes these
|
|
477
|
-
* bounds to the executor and may also emit narrower ranges in later actions.
|
|
478
|
-
*/
|
|
479
|
-
dateFrom?: string;
|
|
480
|
-
dateTo?: string;
|
|
481
|
-
}): Promise<IterativeRecallResult>;
|
|
482
|
-
/**
|
|
483
|
-
* Optional. When implemented, returns true iff the most recent `plan()`
|
|
484
|
-
* could not run the planner as designed and fell back to a degraded
|
|
485
|
-
* result — for example the LLM call threw, every iteration produced an
|
|
486
|
-
* unparseable action, or the result relied on the fallback path
|
|
487
|
-
* (recent-hits or baseline search) because the planner never committed
|
|
488
|
-
* any evidence via a `note` action.
|
|
489
|
-
*/
|
|
490
|
-
lastDegraded?: () => boolean;
|
|
491
|
-
}
|
|
492
|
-
interface IterativeRecallPlannerOptions {
|
|
493
|
-
/** Maximum planner actions. @default 4 */
|
|
494
|
-
maxIterations?: number;
|
|
495
|
-
/** Results exposed to the planner per internal search. @default 5 */
|
|
496
|
-
searchTopK?: number;
|
|
497
|
-
/** When true, skip planning and return no evidence. @default false */
|
|
498
|
-
disabled?: boolean;
|
|
499
|
-
/**
|
|
500
|
-
* When true (default), if the planner finishes without noting any
|
|
501
|
-
* evidence the planner falls back to either the most recent hits or a
|
|
502
|
-
* baseline keyword search against the original query, so the call is
|
|
503
|
-
* never a total loss. Set to false to surface empty results honestly
|
|
504
|
-
* when the planner never committed anything.
|
|
505
|
-
* @default true
|
|
506
|
-
*/
|
|
507
|
-
fallbackToBaseline?: boolean;
|
|
508
|
-
}
|
|
509
|
-
interface IterativeRecallPlannerDeps {
|
|
510
|
-
/** LLM completion callback. */
|
|
511
|
-
complete: (prompt: string) => Promise<string>;
|
|
512
|
-
/** Default options. */
|
|
513
|
-
options?: IterativeRecallPlannerOptions;
|
|
514
|
-
}
|
|
515
|
-
declare function createIterativeRecallPlanner(deps: IterativeRecallPlannerDeps): IterativeRecallPlanner;
|
|
516
|
-
/**
|
|
517
|
-
* A no-op planner that never runs iterative retrieval.
|
|
518
|
-
*/
|
|
519
|
-
declare function createIdentityIterativePlanner(): IterativeRecallPlanner;
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Query rewriting for memory retrieval.
|
|
523
|
-
*
|
|
524
|
-
* The memory corpus is usually a first-person chat log ("I told you ...",
|
|
525
|
-
* "I prefer ..."). A query asked in the assistant's register ("What does the
|
|
526
|
-
* user prefer?") often misses the best evidence. A rewriter rephrases the
|
|
527
|
-
* question into the register the memory was written in, improving dense
|
|
528
|
-
* retrieval without changing the underlying index.
|
|
529
|
-
*
|
|
530
|
-
* The module is provider-agnostic: callers inject a `complete` callback that
|
|
531
|
-
* talks to whatever LLM they already use.
|
|
532
|
-
*/
|
|
533
|
-
interface QueryRewriterInput {
|
|
534
|
-
query: string;
|
|
535
|
-
userId: string;
|
|
536
|
-
authToken?: string;
|
|
537
|
-
}
|
|
538
|
-
interface QueryRewriter {
|
|
539
|
-
/**
|
|
540
|
-
* Return one or more query variants. The first element is always the
|
|
541
|
-
* original query; subsequent elements are rewritten variants.
|
|
542
|
-
*/
|
|
543
|
-
rewrite(input: QueryRewriterInput): Promise<string[]>;
|
|
544
|
-
/**
|
|
545
|
-
* Optional hook that reports whether the most recent `rewrite` call
|
|
546
|
-
* silently degraded to the original query (for example because the LLM
|
|
547
|
-
* call failed or produced no usable variants).
|
|
548
|
-
*/
|
|
549
|
-
lastDegraded?(): boolean;
|
|
550
|
-
}
|
|
551
|
-
interface QueryRewriterOptions {
|
|
552
|
-
/**
|
|
553
|
-
* LLM completion callback. Receives the full prompt and returns the raw
|
|
554
|
-
* model output. The rewriter parses the output and falls back to the
|
|
555
|
-
* original query on any failure.
|
|
556
|
-
*/
|
|
557
|
-
complete: (prompt: string) => Promise<string>;
|
|
558
|
-
/**
|
|
559
|
-
* Maximum number of rewritten variants to return in addition to the
|
|
560
|
-
* original query. Use `0` to return only the original. Higher values ask
|
|
561
|
-
* the LLM for more alternatives and multiply embedding/search cost
|
|
562
|
-
* proportionally, so callers should bound it (typical: 1–3).
|
|
563
|
-
* @default 1
|
|
564
|
-
*/
|
|
565
|
-
maxVariants?: number;
|
|
566
|
-
/**
|
|
567
|
-
* When true, the rewriter returns only the original query and skips the
|
|
568
|
-
* LLM call. Useful as a kill-switch.
|
|
569
|
-
* @default false
|
|
570
|
-
*/
|
|
571
|
-
disabled?: boolean;
|
|
572
|
-
}
|
|
573
|
-
declare function createUserVoiceRewriter(options: QueryRewriterOptions): QueryRewriter;
|
|
574
|
-
/**
|
|
575
|
-
* A no-op rewriter that always returns the original query.
|
|
576
|
-
*/
|
|
577
|
-
declare function createIdentityRewriter(): QueryRewriter;
|
|
578
|
-
|
|
579
|
-
interface MemoryStoreDb {
|
|
580
|
-
/** Resolve the active Drizzle DB handle. Must be server-side. */
|
|
581
|
-
getDb(): unknown;
|
|
582
|
-
/** Whether the DB has finished initializing (optional, for startup gating). */
|
|
583
|
-
isDbInitialized?(): boolean;
|
|
584
|
-
/** Initialize the DB (optional, called by `createMemoryStore` if present). */
|
|
585
|
-
initDb?(): unknown;
|
|
586
|
-
/**
|
|
587
|
-
* Drizzle table references for the postgres backend. Required when
|
|
588
|
-
* running outside Tauri mode without a registered factory. The host
|
|
589
|
-
* application owns the actual schema.
|
|
590
|
-
*/
|
|
591
|
-
tables?: {
|
|
592
|
-
rawMessages?: unknown;
|
|
593
|
-
memorySummaries?: unknown;
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
/**
|
|
597
|
-
* Placeholder for the historical host-injected environment. The fields
|
|
598
|
-
* it used to expose (`isTauriMode`, `getTauriDbPath`, `getTauriDataDir`)
|
|
599
|
-
* were Tauri-specific and have been removed. Backend selection is now
|
|
600
|
-
* driven entirely by the `OPENCONTEXT_MEMORY_STORE_BACKEND` env var.
|
|
601
|
-
*
|
|
602
|
-
* The interface is kept (empty) so existing `env?: MemoryStoreEnv`
|
|
603
|
-
* parameters on the public surface still type-check, but new code
|
|
604
|
-
* should not need to construct a value of this type.
|
|
605
|
-
*/
|
|
606
|
-
interface MemoryStoreEnv {
|
|
607
|
-
}
|
|
608
|
-
type VectorBackend = "sqlite-vec" | "chroma" | "lancedb" | "milvus";
|
|
609
|
-
interface MemoryStoreVectorConfig {
|
|
610
|
-
/** Active backend selector. Defaults to env-based detection. */
|
|
611
|
-
backend?: VectorBackend;
|
|
612
|
-
/** SQLite-vec options (used when backend === "sqlite-vec"). */
|
|
613
|
-
sqliteVec?: {
|
|
614
|
-
dbPath?: string;
|
|
615
|
-
insightsCollection?: string;
|
|
616
|
-
};
|
|
617
|
-
/** Chroma options (used when backend === "chroma"). */
|
|
618
|
-
chroma?: {
|
|
619
|
-
url?: string;
|
|
620
|
-
rawMessagesCollection?: string;
|
|
621
|
-
insightsCollection?: string;
|
|
622
|
-
};
|
|
623
|
-
/** LanceDB options (used when backend === "lancedb"). */
|
|
624
|
-
lancedb?: {
|
|
625
|
-
uri: string;
|
|
626
|
-
table?: string;
|
|
627
|
-
};
|
|
628
|
-
/** Milvus options (used when backend === "milvus"). */
|
|
629
|
-
milvus?: {
|
|
630
|
-
address: string;
|
|
631
|
-
token?: string;
|
|
632
|
-
database?: string;
|
|
633
|
-
collection?: string;
|
|
634
|
-
dimension?: number;
|
|
635
|
-
};
|
|
636
|
-
}
|
|
637
|
-
type EmbedQueryFn = (input: {
|
|
638
|
-
userId: string;
|
|
639
|
-
query: string;
|
|
640
|
-
authToken?: string;
|
|
641
|
-
}) => Promise<number[]>;
|
|
642
|
-
type EmbedDocumentsFn = (input: {
|
|
643
|
-
userId: string;
|
|
644
|
-
texts: string[];
|
|
645
|
-
authToken?: string;
|
|
646
|
-
}) => Promise<number[][]>;
|
|
647
|
-
interface UnifiedSearchKnowledgeResult {
|
|
648
|
-
chunkId: string;
|
|
649
|
-
documentId: string;
|
|
650
|
-
documentName: string;
|
|
651
|
-
content: string;
|
|
652
|
-
similarity: number;
|
|
653
|
-
chunkIndex: number;
|
|
654
|
-
}
|
|
655
|
-
interface UnifiedSearchInsightsResult {
|
|
656
|
-
id: string;
|
|
657
|
-
content: string;
|
|
658
|
-
similarity: number;
|
|
659
|
-
metadata: Record<string, unknown>;
|
|
660
|
-
}
|
|
661
|
-
interface UnifiedSearchReasoningDeps {
|
|
662
|
-
/**
|
|
663
|
-
* LLM single-turn synthesis callback. Wired into
|
|
664
|
-
* `search({ synthesize: true })` so a host that wants synthesis
|
|
665
|
-
* responses only has to drop in one callable. When omitted, the
|
|
666
|
-
* synthesis path returns the gathered evidence with a
|
|
667
|
-
* `synthesize_llm_not_configured` warning instead of throwing.
|
|
668
|
-
*/
|
|
669
|
-
complete?: (prompt: string) => Promise<string>;
|
|
670
|
-
/** Default merge strategy used by `searchUnifiedMemory` when the caller does not specify one. @default "rrf" */
|
|
671
|
-
defaultMergeStrategy?: UnifiedMemoryMergeStrategy;
|
|
672
|
-
/** Optional query rewriter. When present, "rewrite" strategy is available. */
|
|
673
|
-
queryRewriter?: QueryRewriter;
|
|
674
|
-
/** Optional iterative recall planner. When present, "iterative" strategy is available. */
|
|
675
|
-
iterativePlanner?: IterativeRecallPlanner;
|
|
676
|
-
/** Default reasoning strategy when callers do not specify one. @default "none" */
|
|
677
|
-
defaultStrategy?: UnifiedMemoryReasoningStrategy;
|
|
678
|
-
}
|
|
679
|
-
interface MemorySummaryHit {
|
|
680
|
-
summaryId: string;
|
|
681
|
-
summaryText: string;
|
|
682
|
-
summaryTier?: "L1" | "L2" | "L3";
|
|
683
|
-
keywords?: string[];
|
|
684
|
-
startTimestamp?: number;
|
|
685
|
-
endTimestamp?: number;
|
|
686
|
-
}
|
|
687
|
-
/**
|
|
688
|
-
* Trusted applicability fields forwarded together to retrieval providers.
|
|
689
|
-
* They are absent for legacy unscoped searches and always present together
|
|
690
|
-
* for scoped searches. Providers must enforce the canonical applicability
|
|
691
|
-
* contract at `applicabilityAt`; these values must not be derived from public
|
|
692
|
-
* request payloads.
|
|
693
|
-
*/
|
|
694
|
-
interface SearchProviderApplicabilityInput {
|
|
695
|
-
applicabilityContexts?: readonly MemoryApplicabilityContext[];
|
|
696
|
-
/** Epoch milliseconds resolved once at the `search()` boundary. */
|
|
697
|
-
applicabilityAt?: number;
|
|
698
|
-
}
|
|
699
|
-
interface UnifiedSearchDeps {
|
|
700
|
-
/** Embed a query string using the active user's provider. */
|
|
701
|
-
embedQuery?: EmbedQueryFn;
|
|
702
|
-
/** Batch document embedding used by child indexing when the provider supports it. */
|
|
703
|
-
embedDocuments?: EmbedDocumentsFn;
|
|
704
|
-
/** Safe, non-secret identity used by health checks and child-index metadata. */
|
|
705
|
-
embeddingInfo?: {
|
|
706
|
-
provider?: string;
|
|
707
|
-
model?: string;
|
|
708
|
-
dimensions?: number;
|
|
709
|
-
maxTokens?: number;
|
|
710
|
-
};
|
|
711
|
-
/** Runtime-safe retrieval readiness used by health and diagnostics. */
|
|
712
|
-
getRawMessageRetrievalStatus?: () => Promise<{
|
|
713
|
-
backend: string;
|
|
714
|
-
embeddingProvider?: string;
|
|
715
|
-
embeddingModel?: string;
|
|
716
|
-
embeddingDimensions?: number;
|
|
717
|
-
childCount: number;
|
|
718
|
-
embeddedChildCount: number;
|
|
719
|
-
indexedDimensions: number[];
|
|
720
|
-
semanticReady: boolean;
|
|
721
|
-
lexicalReady: boolean;
|
|
722
|
-
semanticDegradedReason?: string;
|
|
723
|
-
rerankerProvider?: string;
|
|
724
|
-
rerankerModel?: string;
|
|
725
|
-
rerankerReady?: boolean;
|
|
726
|
-
}>;
|
|
727
|
-
/** Optional external child-vector index used by the shared write path. */
|
|
728
|
-
rawMessageChildIndex?: {
|
|
729
|
-
replaceMessages(messages: RawMessage[], chunks: RawMessageSearchChunk[]): Promise<void>;
|
|
730
|
-
};
|
|
731
|
-
/**
|
|
732
|
-
* Dense raw-message search supplied by the selected child-vector backend.
|
|
733
|
-
* External Postgres hosts may also provide their legacy parent-level
|
|
734
|
-
* implementation here; Postgres schema changes are outside this package.
|
|
735
|
-
*/
|
|
736
|
-
searchRawMessagesAnn?: (input: SearchProviderApplicabilityInput & {
|
|
737
|
-
userId: string;
|
|
738
|
-
queryEmbedding: number[];
|
|
739
|
-
limit: number;
|
|
740
|
-
threshold: number;
|
|
741
|
-
botId?: string;
|
|
742
|
-
/**
|
|
743
|
-
* Forward `includeDeprecated` from `UnifiedMemorySearchInput` so
|
|
744
|
-
* supersession-aware callers can opt into deprecated rows for
|
|
745
|
-
* audits. Default `false` preserves the current-truth behaviour.
|
|
746
|
-
*/
|
|
747
|
-
includeDeprecated?: boolean;
|
|
748
|
-
/**
|
|
749
|
-
* Forward `asOf` from `UnifiedMemorySearchInput` so time-travel
|
|
750
|
-
* callers can ask "what was true at this instant?". Implementations
|
|
751
|
-
* that don't yet honour the field should ignore it — the rest of
|
|
752
|
-
* the unified pipeline stays correct.
|
|
753
|
-
*/
|
|
754
|
-
asOf?: string;
|
|
755
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
756
|
-
peers?: ReadonlyArray<Peer>;
|
|
757
|
-
/** Optional `FactType` filter resolved from `UnifiedMemorySearchInput.factTypes`. */
|
|
758
|
-
factTypes?: FactType[];
|
|
759
|
-
}) => Promise<Array<{
|
|
760
|
-
id: string;
|
|
761
|
-
content: string;
|
|
762
|
-
similarity: number;
|
|
763
|
-
metadata: Record<string, unknown>;
|
|
764
|
-
}>>;
|
|
765
|
-
/** Native dense+BM25 path for backends such as LanceDB and Milvus. */
|
|
766
|
-
searchRawMessagesHybrid?: (input: SearchProviderApplicabilityInput & {
|
|
767
|
-
userId: string;
|
|
768
|
-
query: string;
|
|
769
|
-
queryEmbedding: number[];
|
|
770
|
-
limit: number;
|
|
771
|
-
botId?: string;
|
|
772
|
-
}) => Promise<Array<{
|
|
773
|
-
id: string;
|
|
774
|
-
content: string;
|
|
775
|
-
similarity: number;
|
|
776
|
-
metadata: Record<string, unknown>;
|
|
777
|
-
}>>;
|
|
778
|
-
/** RAG over uploaded knowledge documents. Returns a list of chunk hits. */
|
|
779
|
-
searchKnowledge?: (input: SearchProviderApplicabilityInput & {
|
|
780
|
-
userId: string;
|
|
781
|
-
query: string;
|
|
782
|
-
options: {
|
|
783
|
-
limit: number;
|
|
784
|
-
threshold: number;
|
|
785
|
-
documentIds?: string[];
|
|
786
|
-
};
|
|
787
|
-
authToken?: string;
|
|
788
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
789
|
-
peers?: ReadonlyArray<Peer>;
|
|
790
|
-
}) => Promise<UnifiedSearchKnowledgeResult[]>;
|
|
791
|
-
/** Semantic search over extracted insights. */
|
|
792
|
-
searchInsights?: (input: SearchProviderApplicabilityInput & {
|
|
793
|
-
userId: string;
|
|
794
|
-
query: string;
|
|
795
|
-
limit: number;
|
|
796
|
-
threshold: number;
|
|
797
|
-
botIds?: string[];
|
|
798
|
-
includeArchived?: boolean;
|
|
799
|
-
authToken?: string;
|
|
800
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
801
|
-
peers?: ReadonlyArray<Peer>;
|
|
802
|
-
}) => Promise<UnifiedSearchInsightsResult[]>;
|
|
803
|
-
/**
|
|
804
|
-
* Optional BM25 (lexical) sub-query for the memory source. Mirrors the
|
|
805
|
-
* `searchRawMessagesAnn` shape but operates on FTS5 keywords instead of
|
|
806
|
-
* dense embeddings. When absent, the unified pipeline skips the lexical
|
|
807
|
-
* path and emits a `memory_lexical_search_not_configured` warning.
|
|
808
|
-
*/
|
|
809
|
-
searchRawMessagesLexical?: (input: SearchProviderApplicabilityInput & {
|
|
810
|
-
userId: string;
|
|
811
|
-
keywords: string[];
|
|
812
|
-
limit: number;
|
|
813
|
-
botId?: string;
|
|
814
|
-
/**
|
|
815
|
-
* Forward `includeDeprecated` from `UnifiedMemorySearchInput` so
|
|
816
|
-
* supersession-aware callers can opt into deprecated rows for
|
|
817
|
-
* audits. Default `false` preserves the current-truth behaviour.
|
|
818
|
-
*/
|
|
819
|
-
includeDeprecated?: boolean;
|
|
820
|
-
/**
|
|
821
|
-
* Forward `asOf` from `UnifiedMemorySearchInput` so time-travel
|
|
822
|
-
* callers can ask "what was true at this instant?". Implementations
|
|
823
|
-
* that don't yet honour the field should ignore it — the rest of
|
|
824
|
-
* the unified pipeline stays correct.
|
|
825
|
-
*/
|
|
826
|
-
asOf?: string;
|
|
827
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
828
|
-
peers?: ReadonlyArray<Peer>;
|
|
829
|
-
/** Optional `FactType` filter resolved from `UnifiedMemorySearchInput.factTypes`. */
|
|
830
|
-
factTypes?: FactType[];
|
|
831
|
-
}) => Promise<Array<{
|
|
832
|
-
id: string;
|
|
833
|
-
content: string;
|
|
834
|
-
similarity: number;
|
|
835
|
-
metadata: Record<string, unknown>;
|
|
836
|
-
}>>;
|
|
837
|
-
/**
|
|
838
|
-
* Optional summary-tier search. When wired in, `reflect()` consults the
|
|
839
|
-
* summary tier alongside raw messages and emits a
|
|
840
|
-
* `reflect_summaries_unavailable` warning if the call fails.
|
|
841
|
-
*/
|
|
842
|
-
searchSummaries?: (input: SearchProviderApplicabilityInput & {
|
|
843
|
-
userId: string;
|
|
844
|
-
query: string;
|
|
845
|
-
keywords: string[];
|
|
846
|
-
limit: number;
|
|
847
|
-
threshold: number;
|
|
848
|
-
dateFrom?: string;
|
|
849
|
-
dateTo?: string;
|
|
850
|
-
authToken?: string;
|
|
851
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
852
|
-
peers?: ReadonlyArray<Peer>;
|
|
853
|
-
}) => Promise<MemorySummaryHit[]>;
|
|
854
|
-
/**
|
|
855
|
-
* Optional entity sub-query provider. Hosts wire this in to opt
|
|
856
|
-
* into the `entity` channel of unified search: matches are
|
|
857
|
-
* projected back as `UnifiedMemorySearchResult`s and fused with
|
|
858
|
-
* semantic + lexical via RRF. Without it, the entity channel is
|
|
859
|
-
* skipped silently (with a `memory_entity_search_not_configured`
|
|
860
|
-
* warning when RRF was requested).
|
|
861
|
-
*
|
|
862
|
-
* The provider is intentionally narrow: it returns `(messageId,
|
|
863
|
-
* label, score)` tuples. The host is responsible for keeping its
|
|
864
|
-
* own entity store (graph nodes, separate SQLite table, etc.) —
|
|
865
|
-
* the SDK never persists entity edges itself.
|
|
866
|
-
*/
|
|
867
|
-
entitySearch?: (input: SearchProviderApplicabilityInput & {
|
|
868
|
-
userId: string;
|
|
869
|
-
keywords: string[];
|
|
870
|
-
limit: number;
|
|
871
|
-
botId?: string;
|
|
872
|
-
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
873
|
-
peers?: ReadonlyArray<Peer>;
|
|
874
|
-
}) => Promise<Array<{
|
|
875
|
-
messageId: string;
|
|
876
|
-
label: string;
|
|
877
|
-
score: number;
|
|
878
|
-
}>>;
|
|
879
|
-
/**
|
|
880
|
-
* Optional entity extractor wired into the `distill` primitive. The
|
|
881
|
-
* extractor receives the raw message text and returns a batch of
|
|
882
|
-
* `EntityEdge`s the host may persist via the `persist` callback
|
|
883
|
-
* supplied on the `distill` input.
|
|
884
|
-
*
|
|
885
|
-
* When omitted, `distill` short-circuits with a
|
|
886
|
-
* `distill_extractor_not_configured` warning — matching the
|
|
887
|
-
* `memory_iterative_planner_not_configured` precedent.
|
|
888
|
-
*/
|
|
889
|
-
entityExtractor?: (input: {
|
|
890
|
-
userId: string;
|
|
891
|
-
messageId: string;
|
|
892
|
-
content: string;
|
|
893
|
-
}) => Promise<EntityEdge[]>;
|
|
894
|
-
/**
|
|
895
|
-
* Optional deriver wired into the `derive` primitive. The deriver
|
|
896
|
-
* receives a window of candidate fact texts and returns a batch of
|
|
897
|
-
* `DerivedFact`s the host may persist via the `persist` callback
|
|
898
|
-
* supplied on the `derive` input.
|
|
899
|
-
*
|
|
900
|
-
* When omitted, `derive` short-circuits with a
|
|
901
|
-
* `derive_deriver_not_configured` warning — same precedent.
|
|
902
|
-
*/
|
|
903
|
-
deriver?: (input: {
|
|
904
|
-
userId: string;
|
|
905
|
-
userScope: {
|
|
906
|
-
userId: string;
|
|
907
|
-
botIds?: string[];
|
|
908
|
-
dateFrom?: string;
|
|
909
|
-
dateTo?: string;
|
|
910
|
-
};
|
|
911
|
-
recentFactTexts: string[];
|
|
912
|
-
window?: {
|
|
913
|
-
from: number;
|
|
914
|
-
to: number;
|
|
915
|
-
};
|
|
916
|
-
}) => Promise<DerivedFact[]>;
|
|
917
|
-
/**
|
|
918
|
-
* Optional host-side check that validates whether a `peerFilter` peer is
|
|
919
|
-
* actually reachable from this `userId`. Used by
|
|
920
|
-
* `resolveScopePeer` to drop out-of-scope peers with a warning
|
|
921
|
-
* rather than broadening the search. May be omitted for hosts that
|
|
922
|
-
* have no peer-permission model.
|
|
923
|
-
*/
|
|
924
|
-
peerScopeCheck?: (input: {
|
|
925
|
-
userId: string;
|
|
926
|
-
peers: ReadonlyArray<_melandlabs_contracts_peer.Peer>;
|
|
927
|
-
}) => Promise<boolean> | boolean;
|
|
928
|
-
/** Optional reasoning providers. */
|
|
929
|
-
reasoning?: UnifiedSearchReasoningDeps;
|
|
930
|
-
/**
|
|
931
|
-
* Optional reranker applied after per-source merge and before the
|
|
932
|
-
* final limit. Defaults to an identity pass-through so the merge order
|
|
933
|
-
* is preserved.
|
|
934
|
-
*/
|
|
935
|
-
reranker?: Reranker;
|
|
936
|
-
/** Safe, non-secret reranker identity surfaced by health and diagnostics. */
|
|
937
|
-
rerankerInfo?: {
|
|
938
|
-
provider: string;
|
|
939
|
-
model?: string;
|
|
940
|
-
maxTokens?: number;
|
|
941
|
-
ready: boolean;
|
|
942
|
-
};
|
|
943
|
-
/**
|
|
944
|
-
* Optional logger. When set (e.g. via `MemoryStoreConfig.logger`),
|
|
945
|
-
* `reflect` / `consolidate` log through it instead of `console`.
|
|
946
|
-
* Falls back to `console` when omitted.
|
|
947
|
-
*/
|
|
948
|
-
logger?: Pick<Console, "log" | "warn" | "error">;
|
|
949
|
-
}
|
|
950
|
-
interface MemoryStoreConfig {
|
|
951
|
-
/**
|
|
952
|
-
* Database handle factory. Required for the Postgres backend
|
|
953
|
-
* (`OPENCONTEXT_MEMORY_STORE_BACKEND=postgres`).
|
|
954
|
-
*/
|
|
955
|
-
db?: MemoryStoreDb;
|
|
956
|
-
/**
|
|
957
|
-
* Custom SQLite database file path for the default SQLite backend.
|
|
958
|
-
*
|
|
959
|
-
* If provided, this takes precedence over the `MEMORY_STORE_DB_PATH`
|
|
960
|
-
* environment variable and the default `~/.opencontext/memory/store.db`.
|
|
961
|
-
*
|
|
962
|
-
* For backward compatibility with early tutorials, `db.path` is also
|
|
963
|
-
* honoured when `db` is supplied as `{ type, path }`.
|
|
964
|
-
*/
|
|
965
|
-
dbPath?: string;
|
|
966
|
-
/** Environment helpers. Defaults to a process.env-only stub if omitted. */
|
|
967
|
-
env?: MemoryStoreEnv;
|
|
968
|
-
/** Vector backend config. Defaults to env-based detection. */
|
|
969
|
-
vector?: MemoryStoreVectorConfig;
|
|
970
|
-
/** Optional cross-source search providers. */
|
|
971
|
-
unified?: UnifiedSearchDeps;
|
|
972
|
-
/**
|
|
973
|
-
* Optional write-back graph store. When set, `createMemoryStore` wires
|
|
974
|
-
* it into `store.graphStore` and forwards it to `consolidate`. Hosts
|
|
975
|
-
* that prefer post-construction wiring can use `attachMemoryGraphStore`.
|
|
976
|
-
*/
|
|
977
|
-
graphStore?: _melandlabs_memory_consolidation.MemoryGraphStoreWithOperationHistory;
|
|
978
|
-
/**
|
|
979
|
-
* Optional storage adapter carrying `deprecateRecords`. Forwarded into
|
|
980
|
-
* `consolidate` for callers that want deprecation writes without
|
|
981
|
-
* attaching a full graph store.
|
|
982
|
-
*/
|
|
983
|
-
storage?: _melandlabs_memory_consolidation.MemoryStorageAdapterLike;
|
|
984
|
-
/** Optional logger. Defaults to console. */
|
|
985
|
-
logger?: Pick<Console, "log" | "warn" | "error">;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
export { createUserVoiceRewriter as $, toMemoryResult as A, type IterativeRecallExecutor as B, type IterativeRecallPlanner as C, type IterativeRecallPlannerOptions as D, type EmbedQueryFn as E, type IterativeRecallResult as F, type IterativeRecallSearchRequest as G, type HitChannel as H, type IterativeRecallCandidate as I, type IterativeRecallSearchResult as J, type IterativeRecallStats as K, type MemoryStoreDb as L, type MemoryStoreConfig as M, type QueryRewriterInput as N, type QueryRewriterOptions as O, type SearchProviderApplicabilityInput as P, type QueryRewriter as Q, type UnifiedMemoryReasoningInfo as R, type SearchTier as S, type UnifiedSearchInsightsResult as T, type UnifiedSearchDeps as U, type UnifiedSearchKnowledgeResult as V, type UnifiedSearchReasoningDeps as W, type VectorBackend as X, createIdentityIterativePlanner as Y, createIdentityRewriter as Z, createIterativeRecallPlanner as _, type MemoryStoreEnv as a, type UnifiedMemorySearchWarning as b, type SearchEvidence as c, type SearchInput as d, type SearchOutput as e, type UnifiedMemorySearchInput as f, type UnifiedMemorySearchOutput as g, type UnifiedMemorySearchResult as h, type HitSignals as i, type SearchSource as j, type UnifiedMemoryMergeStrategy as k, type UnifiedMemoryRankedList as l, type UnifiedMemoryReasoningStrategy as m, type UnifiedMemorySearchSource as n, clampUnifiedMemorySearchLimit as o, clampUnifiedMemorySearchThreshold as p, deriveLexicalKeywords as q, isRawMemorySemanticResult as r, listNameToChannel as s, materializeSignals as t, mergeUnifiedMemorySearchResults as u, mergeUnifiedMemorySearchResultsRrf as v, normalizeUnifiedMemoryMergeStrategy as w, normalizeUnifiedMemoryReasoningStrategy as x, normalizeUnifiedMemorySearchSources as y, toKnowledgeResult as z };
|