@melandlabs/memory-store 1.1.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{config-CnbqSek5.d.ts → config-DfvVZ--0.d.ts} +137 -1
- package/dist/http.d.ts +11 -2
- package/dist/http.js +401 -21
- package/dist/index.d.ts +10 -5
- package/dist/index.js +351 -21
- package/dist/mcp.d.ts +12 -2
- package/dist/mcp.js +456 -23
- package/dist/search/derive.d.ts +93 -0
- package/dist/search/derive.js +145 -0
- package/dist/search/distill.d.ts +60 -0
- package/dist/search/distill.js +61 -0
- package/dist/search/unified-search.d.ts +4 -2
- package/dist/search/unified-search.js +180 -23
- package/dist/server/cli-http.js +401 -21
- package/dist/server/cli-mcp.js +454 -21
- package/dist/server/cli-shared.d.ts +3 -1
- package/dist/storage/postgres-raw-message-factory.d.ts +3 -1
- package/dist/storage/raw-message-store.d.ts +3 -1
- package/dist/storage/sqlite-raw-message-store.d.ts +3 -1
- package/dist/storage/sqlite-vector-index.d.ts +3 -1
- package/dist/{unified-search-Bft57TRH.d.ts → unified-search-A8Q3JHwU.d.ts} +1 -1
- package/package.json +4 -4
|
@@ -2,6 +2,8 @@ import * as _melandlabs_memory_consolidation from '@melandlabs/memory-consolidat
|
|
|
2
2
|
import * as _melandlabs_contracts_peer from '@melandlabs/contracts/peer';
|
|
3
3
|
import { Peer } from '@melandlabs/contracts/peer';
|
|
4
4
|
import { FactType } from '@melandlabs/contracts';
|
|
5
|
+
import { DerivedFact } from '@melandlabs/contracts/derived-fact';
|
|
6
|
+
import { EntityEdge } from '@melandlabs/contracts/entity-edge';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Reranker adapter contract.
|
|
@@ -42,6 +44,49 @@ interface Reranker {
|
|
|
42
44
|
*/
|
|
43
45
|
|
|
44
46
|
type UnifiedMemorySearchSource = "memory" | "insights" | "knowledge";
|
|
47
|
+
/**
|
|
48
|
+
* A retrieval channel that contributed to a hit's final score.
|
|
49
|
+
*
|
|
50
|
+
* - `semantic` — dense embedding lookup (`searchRawMessagesAnn` or
|
|
51
|
+
* the SQLite manager's semantic-search fallback).
|
|
52
|
+
* - `lexical` — BM25 / FTS5 keyword match
|
|
53
|
+
* (`searchRawMessagesLexical` or the SQLite manager's lexical
|
|
54
|
+
* fallback).
|
|
55
|
+
* - `entity` — entity-link match supplied by the host's
|
|
56
|
+
* `entitySearch` dep.
|
|
57
|
+
*/
|
|
58
|
+
type HitChannel = "semantic" | "lexical" | "entity";
|
|
59
|
+
/**
|
|
60
|
+
* Per-hit score breakdown. Always emitted by `search()` (default merge
|
|
61
|
+
* strategy) so callers can threshold / re-rank without losing the
|
|
62
|
+
* individual channel contributions. The RRF fusion additionally
|
|
63
|
+
* populates `signals.rrf` and continues to mirror the fused score
|
|
64
|
+
* onto `metadata.rrfScore` (legacy field).
|
|
65
|
+
*
|
|
66
|
+
* Each numeric field is the raw per-channel score for the *first*
|
|
67
|
+
* (highest-ranked) appearance of the same `(type, id)` key in the
|
|
68
|
+
* channel's list. Channels that did not contribute are `undefined`.
|
|
69
|
+
*/
|
|
70
|
+
interface HitSignals {
|
|
71
|
+
/** Channels the hit actually appeared in. */
|
|
72
|
+
channels: HitChannel[];
|
|
73
|
+
/** Semantic sub-query similarity in [0..1] (undefined when absent). */
|
|
74
|
+
semantic?: number;
|
|
75
|
+
/** Lexical sub-query BM25 score (undefined when absent). */
|
|
76
|
+
lexical?: number;
|
|
77
|
+
/** Entity sub-query match score (undefined when absent). */
|
|
78
|
+
entity?: number;
|
|
79
|
+
/** RRF-fused score (only when mergeStrategy === "rrf"). */
|
|
80
|
+
rrf?: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Derive simple lexical keywords from a query string. Splits on any
|
|
84
|
+
* non-letter/non-digit Unicode boundary, lowercases, drops tokens
|
|
85
|
+
* shorter than 2 chars, and caps the list at 16. Used by the unified
|
|
86
|
+
* search lexical sub-query and by the `derive` primitive's candidate
|
|
87
|
+
* fetch fallback.
|
|
88
|
+
*/
|
|
89
|
+
declare function deriveLexicalKeywords(query: string): string[];
|
|
45
90
|
type UnifiedMemoryReasoningStrategy = "none" | "rewrite" | "iterative";
|
|
46
91
|
interface UnifiedMemorySearchWarning {
|
|
47
92
|
source: UnifiedMemorySearchSource;
|
|
@@ -158,6 +203,12 @@ interface UnifiedMemorySearchResult {
|
|
|
158
203
|
content: string;
|
|
159
204
|
similarity: number;
|
|
160
205
|
metadata: Record<string, unknown>;
|
|
206
|
+
/**
|
|
207
|
+
* Optional per-channel score breakdown. Always populated by the
|
|
208
|
+
* pipeline when at least one channel contributed a non-empty list;
|
|
209
|
+
* callers should treat absence as "no channel info available".
|
|
210
|
+
*/
|
|
211
|
+
signals?: HitSignals;
|
|
161
212
|
}
|
|
162
213
|
interface UnifiedMemorySearchOutput {
|
|
163
214
|
query: string;
|
|
@@ -280,6 +331,28 @@ declare function toMemoryResult(result: {
|
|
|
280
331
|
similarity: number;
|
|
281
332
|
metadata: Record<string, unknown>;
|
|
282
333
|
}): UnifiedMemorySearchResult;
|
|
334
|
+
/**
|
|
335
|
+
* Build the `signals` breakdown for a single hit from the per-channel
|
|
336
|
+
* ranked lists it appeared in. Only the highest-ranked (i.e. first)
|
|
337
|
+
* appearance of `(type, id)` per channel contributes — duplicate hits
|
|
338
|
+
* later in the same list are ignored so the breakdown stays
|
|
339
|
+
* deterministic.
|
|
340
|
+
*
|
|
341
|
+
* Used by `mergeAcrossSources` to attach `signals` to every emitted
|
|
342
|
+
* `UnifiedMemorySearchResult`. Pure; no I/O.
|
|
343
|
+
*/
|
|
344
|
+
declare function materializeSignals(lists: ReadonlyArray<{
|
|
345
|
+
name: string;
|
|
346
|
+
hits: UnifiedMemorySearchResult[];
|
|
347
|
+
}>, hit: UnifiedMemorySearchResult): HitSignals | undefined;
|
|
348
|
+
/**
|
|
349
|
+
* Map a `UnifiedMemoryRankedList.name` to a `HitChannel`. Unknown names
|
|
350
|
+
* (e.g. "insights", "knowledge", "summary") are not channels — they
|
|
351
|
+
* surface their similarity through the merge's `similarity` field and
|
|
352
|
+
* are simply skipped here so callers can still see which channel set
|
|
353
|
+
* the hit came from.
|
|
354
|
+
*/
|
|
355
|
+
declare function listNameToChannel(name: string): HitChannel | undefined;
|
|
283
356
|
declare function isRawMemorySemanticResult(result: unknown): result is {
|
|
284
357
|
id: string;
|
|
285
358
|
content: string;
|
|
@@ -616,6 +689,69 @@ interface UnifiedSearchDeps {
|
|
|
616
689
|
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
617
690
|
peers?: ReadonlyArray<Peer>;
|
|
618
691
|
}) => Promise<MemorySummaryHit[]>;
|
|
692
|
+
/**
|
|
693
|
+
* Optional entity sub-query provider. Hosts wire this in to opt
|
|
694
|
+
* into the `entity` channel of unified search: matches are
|
|
695
|
+
* projected back as `UnifiedMemorySearchResult`s and fused with
|
|
696
|
+
* semantic + lexical via RRF. Without it, the entity channel is
|
|
697
|
+
* skipped silently (with a `memory_entity_search_not_configured`
|
|
698
|
+
* warning when RRF was requested).
|
|
699
|
+
*
|
|
700
|
+
* The provider is intentionally narrow: it returns `(messageId,
|
|
701
|
+
* label, score)` tuples. The host is responsible for keeping its
|
|
702
|
+
* own entity store (graph nodes, separate SQLite table, etc.) —
|
|
703
|
+
* the SDK never persists entity edges itself.
|
|
704
|
+
*/
|
|
705
|
+
entitySearch?: (input: {
|
|
706
|
+
userId: string;
|
|
707
|
+
keywords: string[];
|
|
708
|
+
limit: number;
|
|
709
|
+
botId?: string;
|
|
710
|
+
/** Optional peer scope resolved from `UnifiedMemorySearchInput.peerFilter`. */
|
|
711
|
+
peers?: ReadonlyArray<Peer>;
|
|
712
|
+
}) => Promise<Array<{
|
|
713
|
+
messageId: string;
|
|
714
|
+
label: string;
|
|
715
|
+
score: number;
|
|
716
|
+
}>>;
|
|
717
|
+
/**
|
|
718
|
+
* Optional entity extractor wired into the `distill` primitive. The
|
|
719
|
+
* extractor receives the raw message text and returns a batch of
|
|
720
|
+
* `EntityEdge`s the host may persist via the `persist` callback
|
|
721
|
+
* supplied on the `distill` input.
|
|
722
|
+
*
|
|
723
|
+
* When omitted, `distill` short-circuits with a
|
|
724
|
+
* `distill_extractor_not_configured` warning — matching the
|
|
725
|
+
* `memory_iterative_planner_not_configured` precedent.
|
|
726
|
+
*/
|
|
727
|
+
entityExtractor?: (input: {
|
|
728
|
+
userId: string;
|
|
729
|
+
messageId: string;
|
|
730
|
+
content: string;
|
|
731
|
+
}) => Promise<EntityEdge[]>;
|
|
732
|
+
/**
|
|
733
|
+
* Optional deriver wired into the `derive` primitive. The deriver
|
|
734
|
+
* receives a window of candidate fact texts and returns a batch of
|
|
735
|
+
* `DerivedFact`s the host may persist via the `persist` callback
|
|
736
|
+
* supplied on the `derive` input.
|
|
737
|
+
*
|
|
738
|
+
* When omitted, `derive` short-circuits with a
|
|
739
|
+
* `derive_deriver_not_configured` warning — same precedent.
|
|
740
|
+
*/
|
|
741
|
+
deriver?: (input: {
|
|
742
|
+
userId: string;
|
|
743
|
+
userScope: {
|
|
744
|
+
userId: string;
|
|
745
|
+
botIds?: string[];
|
|
746
|
+
dateFrom?: string;
|
|
747
|
+
dateTo?: string;
|
|
748
|
+
};
|
|
749
|
+
recentFactTexts: string[];
|
|
750
|
+
window?: {
|
|
751
|
+
from: number;
|
|
752
|
+
to: number;
|
|
753
|
+
};
|
|
754
|
+
}) => Promise<DerivedFact[]>;
|
|
619
755
|
/**
|
|
620
756
|
* Optional host-side check that validates whether a `peerFilter` peer is
|
|
621
757
|
* actually reachable from this `userId`. Used by
|
|
@@ -680,4 +816,4 @@ interface MemoryStoreConfig {
|
|
|
680
816
|
logger?: Pick<Console, "log" | "warn" | "error">;
|
|
681
817
|
}
|
|
682
818
|
|
|
683
|
-
export {
|
|
819
|
+
export { 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 UnifiedMemoryReasoningInfo as P, type QueryRewriter as Q, type UnifiedSearchInsightsResult as R, type SearchTier as S, type UnifiedSearchKnowledgeResult as T, type UnifiedSearchDeps as U, type UnifiedSearchReasoningDeps as V, type VectorBackend as W, createIdentityIterativePlanner as X, createIdentityRewriter as Y, createIterativeRecallPlanner as Z, createUserVoiceRewriter 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 };
|
package/dist/http.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { M as MemoryStoreConfig } from './config-
|
|
1
|
+
import { M as MemoryStoreConfig } from './config-DfvVZ--0.js';
|
|
2
2
|
import '@melandlabs/memory-consolidation';
|
|
3
3
|
import '@melandlabs/contracts/peer';
|
|
4
4
|
import '@melandlabs/contracts';
|
|
5
|
+
import '@melandlabs/contracts/derived-fact';
|
|
6
|
+
import '@melandlabs/contracts/entity-edge';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* @melandlabs/memory-store/http — HTTP server entry.
|
|
@@ -16,7 +18,14 @@ import '@melandlabs/contracts';
|
|
|
16
18
|
* Endpoints (all POST, JSON in/out):
|
|
17
19
|
* GET /health → { ok: true }
|
|
18
20
|
* POST /v1/search → SearchOutput (set `synthesize: true` for
|
|
19
|
-
* LLM synthesis)
|
|
21
|
+
* LLM synthesis). Each hit carries a
|
|
22
|
+
* `signals` field with per-channel scores.
|
|
23
|
+
* POST /v1/distill → DistillOutput (entity extraction from
|
|
24
|
+
* a single raw message; requires
|
|
25
|
+
* `unified.entityExtractor`)
|
|
26
|
+
* POST /v1/derive → DeriveOutput (fact derivation over a
|
|
27
|
+
* window of candidate texts; requires
|
|
28
|
+
* `unified.deriver`)
|
|
20
29
|
* POST /v1/raw-messages → upsert raw messages (returns count)
|
|
21
30
|
* GET /v1/raw-messages/:id → single raw message
|
|
22
31
|
* POST /v1/consolidate:apply → ApplyConsolidateOutput (agentic write-back)
|