dsh-prime-memory 0.11.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.
Files changed (151) hide show
  1. package/CHANGELOG.en.md +28 -0
  2. package/CHANGELOG.ja.md +30 -0
  3. package/CHANGELOG.ko.md +30 -0
  4. package/CHANGELOG.md +1220 -0
  5. package/ENGINEERING-NOTES.md +452 -0
  6. package/INSTALL.en.md +92 -0
  7. package/INSTALL.ja.md +92 -0
  8. package/INSTALL.ko.md +92 -0
  9. package/INSTALL.md +92 -0
  10. package/LICENSE +21 -0
  11. package/README.en.md +458 -0
  12. package/README.ja.md +306 -0
  13. package/README.ko.md +306 -0
  14. package/README.md +425 -0
  15. package/assets/changelog/0.8.10/01-write-only-pill.png +0 -0
  16. package/assets/changelog/0.8.9/01-panel.png +0 -0
  17. package/assets/changelog/0.8.9/02-halo.png +0 -0
  18. package/assets/changelog/0.8.9/03-layer-segmented-panel.png +0 -0
  19. package/assets/changelog/0.8.9/04-layer-l1-panel.png +0 -0
  20. package/assets/img/EmbeddingSource.png +0 -0
  21. package/assets/img/Hero.png +0 -0
  22. package/assets/img/Layers.png +0 -0
  23. package/assets/img/MemoryTools.png +0 -0
  24. package/assets/img/Modes.png +0 -0
  25. package/assets/img/ToolTrajectory.png +0 -0
  26. package/assets/img/ui-dark.jpg +0 -0
  27. package/assets/img/ui-light.jpg +0 -0
  28. package/assets/readme/bench-dialog.svg +70 -0
  29. package/assets/readme/bench-workflow.svg +79 -0
  30. package/assets/readme/flow.svg +189 -0
  31. package/assets/readme/storage.svg +115 -0
  32. package/cordis.patch.yml +16 -0
  33. package/dist/bench-control.d.ts +34 -0
  34. package/dist/bench-control.js +16 -0
  35. package/dist/client.js +4293 -0
  36. package/dist/config.d.ts +683 -0
  37. package/dist/config.js +129 -0
  38. package/dist/contract.d.ts +820 -0
  39. package/dist/contract.js +1 -0
  40. package/dist/embedding-worker.cjs +176 -0
  41. package/dist/graph/apply.d.ts +37 -0
  42. package/dist/graph/apply.js +270 -0
  43. package/dist/graph/constraints.d.ts +47 -0
  44. package/dist/graph/constraints.js +38 -0
  45. package/dist/graph/search.d.ts +16 -0
  46. package/dist/graph/search.js +115 -0
  47. package/dist/graph/types.d.ts +142 -0
  48. package/dist/graph/types.js +14 -0
  49. package/dist/hooks/capture.d.ts +32 -0
  50. package/dist/hooks/capture.js +194 -0
  51. package/dist/hooks/recall.d.ts +63 -0
  52. package/dist/hooks/recall.js +429 -0
  53. package/dist/index.d.ts +534 -0
  54. package/dist/index.js +344 -0
  55. package/dist/llm-usage.d.ts +26 -0
  56. package/dist/llm-usage.js +37 -0
  57. package/dist/llm.d.ts +153 -0
  58. package/dist/llm.js +530 -0
  59. package/dist/pipeline/graph.d.ts +35 -0
  60. package/dist/pipeline/graph.js +104 -0
  61. package/dist/pipeline/l1.d.ts +19 -0
  62. package/dist/pipeline/l1.js +271 -0
  63. package/dist/pipeline/l2.d.ts +13 -0
  64. package/dist/pipeline/l2.js +83 -0
  65. package/dist/pipeline/l3.d.ts +15 -0
  66. package/dist/pipeline/l3.js +78 -0
  67. package/dist/pipeline/rebuild.d.ts +61 -0
  68. package/dist/pipeline/rebuild.js +307 -0
  69. package/dist/pipeline/ruminate.d.ts +89 -0
  70. package/dist/pipeline/ruminate.js +298 -0
  71. package/dist/pipeline/runner.d.ts +167 -0
  72. package/dist/pipeline/runner.js +638 -0
  73. package/dist/pipeline/trigger.d.ts +40 -0
  74. package/dist/pipeline/trigger.js +75 -0
  75. package/dist/prompts/graph-projection.d.ts +70 -0
  76. package/dist/prompts/graph-projection.js +167 -0
  77. package/dist/prompts/l1-dedup.d.ts +22 -0
  78. package/dist/prompts/l1-dedup.js +251 -0
  79. package/dist/prompts/l1-extraction.d.ts +22 -0
  80. package/dist/prompts/l1-extraction.js +457 -0
  81. package/dist/prompts/persona.d.ts +23 -0
  82. package/dist/prompts/persona.js +240 -0
  83. package/dist/prompts/scene.d.ts +32 -0
  84. package/dist/prompts/scene.js +414 -0
  85. package/dist/runtime-package-lock.json +982 -0
  86. package/dist/settings.d.ts +50 -0
  87. package/dist/settings.js +355 -0
  88. package/dist/stats.d.ts +109 -0
  89. package/dist/stats.js +929 -0
  90. package/dist/store/bm25.d.ts +19 -0
  91. package/dist/store/bm25.js +63 -0
  92. package/dist/store/cost-ledger.d.ts +75 -0
  93. package/dist/store/cost-ledger.js +171 -0
  94. package/dist/store/download-queue.d.ts +79 -0
  95. package/dist/store/download-queue.js +424 -0
  96. package/dist/store/embedding-source.d.ts +118 -0
  97. package/dist/store/embedding-source.js +443 -0
  98. package/dist/store/embedding.d.ts +90 -0
  99. package/dist/store/embedding.js +206 -0
  100. package/dist/store/graph-store.d.ts +94 -0
  101. package/dist/store/graph-store.js +641 -0
  102. package/dist/store/l0.d.ts +40 -0
  103. package/dist/store/l0.js +197 -0
  104. package/dist/store/l1.d.ts +93 -0
  105. package/dist/store/l1.js +297 -0
  106. package/dist/store/local-embedding.d.ts +89 -0
  107. package/dist/store/local-embedding.js +227 -0
  108. package/dist/store/model-catalog.d.ts +48 -0
  109. package/dist/store/model-catalog.js +81 -0
  110. package/dist/store/occupancy.d.ts +30 -0
  111. package/dist/store/occupancy.js +134 -0
  112. package/dist/store/pending.d.ts +36 -0
  113. package/dist/store/pending.js +103 -0
  114. package/dist/store/persona.d.ts +15 -0
  115. package/dist/store/persona.js +60 -0
  116. package/dist/store/recall-dedupe.d.ts +26 -0
  117. package/dist/store/recall-dedupe.js +138 -0
  118. package/dist/store/runtime-installer.d.ts +59 -0
  119. package/dist/store/runtime-installer.js +243 -0
  120. package/dist/store/scenes.d.ts +24 -0
  121. package/dist/store/scenes.js +160 -0
  122. package/dist/store/search-utils.d.ts +38 -0
  123. package/dist/store/search-utils.js +100 -0
  124. package/dist/store/session-modes.d.ts +35 -0
  125. package/dist/store/session-modes.js +144 -0
  126. package/dist/store/sqlite.d.ts +246 -0
  127. package/dist/store/sqlite.js +1491 -0
  128. package/dist/store/state.d.ts +41 -0
  129. package/dist/store/state.js +72 -0
  130. package/dist/token-cost.d.ts +23 -0
  131. package/dist/token-cost.js +185 -0
  132. package/dist/tools/index.d.ts +34 -0
  133. package/dist/tools/index.js +758 -0
  134. package/dist/types.d.ts +139 -0
  135. package/dist/types.js +38 -0
  136. package/dist/util/context-occupancy.d.ts +68 -0
  137. package/dist/util/context-occupancy.js +92 -0
  138. package/dist/util/filelog.d.ts +6 -0
  139. package/dist/util/filelog.js +108 -0
  140. package/dist/util/io.d.ts +18 -0
  141. package/dist/util/io.js +97 -0
  142. package/dist/util/recall-budget.d.ts +31 -0
  143. package/dist/util/recall-budget.js +84 -0
  144. package/dist/util/sanitize.d.ts +11 -0
  145. package/dist/util/sanitize.js +67 -0
  146. package/dist/util/text.d.ts +16 -0
  147. package/dist/util/text.js +61 -0
  148. package/dist/util/tokenizer.d.ts +9 -0
  149. package/dist/util/tokenizer.js +50 -0
  150. package/dsh.plugin.json +22 -0
  151. package/package.json +118 -0
@@ -0,0 +1,246 @@
1
+ import type { EmbeddingProviderInfo } from './embedding.js';
2
+ import type { L0MessageRecord, MemoryFamily, MemoryLogger, MemoryRecord } from '../types.js';
3
+ export interface StoreInitResult {
4
+ /** embedding 配置(provider/model/维度)变化,需要后台全量重嵌入。 */
5
+ needsReindex: boolean;
6
+ reason?: string;
7
+ }
8
+ export interface StoreCapabilities {
9
+ ftsSearch: boolean;
10
+ vectorSearch: boolean;
11
+ }
12
+ import { CostLedger } from './cost-ledger.js';
13
+ import type { BucketRow, CostAggregate, CostByLayer } from './cost-ledger.js';
14
+ export type { BucketRow, CostAggregate, CostByLayer } from './cost-ledger.js';
15
+ import type { CostByModel } from '../contract.js';
16
+ import { GraphStore } from './graph-store.js';
17
+ /** L1 检索命中(含 BM25/余弦归一分数)。 */
18
+ export interface L1SearchHit {
19
+ id: string;
20
+ content: string;
21
+ type: string;
22
+ priority: number;
23
+ scene_name: string;
24
+ score: number;
25
+ family: MemoryFamily;
26
+ }
27
+ /** L0 检索命中。 */
28
+ export interface L0SearchHit extends L0MessageRecord {
29
+ score: number;
30
+ }
31
+ export declare class MemoryDb {
32
+ private db;
33
+ private degraded;
34
+ private ftsAvailable;
35
+ private vecLoaded;
36
+ private vecLoadWarned;
37
+ /** 向量维度:活切换嵌入源时会变——vec0 表随维度重建。 */
38
+ private dimensions;
39
+ private readonly logger?;
40
+ private stmtUpsertL1;
41
+ private stmtGetL1;
42
+ /** 主表存在性点查(防御性 FTS 删除的前置判断,走主键索引)。 */
43
+ private stmtL1Exists;
44
+ private stmtDeleteL1Meta;
45
+ private stmtDeleteL1Vec?;
46
+ private stmtInsertL1Vec?;
47
+ private stmtSearchL1Vec?;
48
+ private stmtL1FtsInsert;
49
+ private stmtL1FtsDelete;
50
+ private stmtL1FtsSearch;
51
+ private stmtL1FtsSearchFamily;
52
+ /** 成本账本(token_cost 表族;init 内初始化,未就绪时方法返回零值)。 */
53
+ readonly costLedger: CostLedger;
54
+ /** 图谱存储(graph_* 表族;init 独立 try/catch,失败仅图谱 no-op)。 */
55
+ readonly graphStore: GraphStore;
56
+ private stmtUpsertL0;
57
+ private stmtGetL0;
58
+ private stmtL0Exists;
59
+ private stmtDeleteL0Vec?;
60
+ private stmtInsertL0Vec?;
61
+ private stmtSearchL0Vec?;
62
+ private stmtL0FtsInsert;
63
+ private stmtL0FtsDelete;
64
+ private stmtL0FtsSearch;
65
+ /** 按块缓存的 IN 语句(表名/动作/尺寸 → 预编译语句):热路径不再每次动态 prepare。 */
66
+ private readonly inStmts;
67
+ constructor(dbPath: string, dimensions: number, logger?: MemoryLogger);
68
+ isDegraded(): boolean;
69
+ getCapabilities(): StoreCapabilities;
70
+ /** 统一事务边界:fn 抛出即 ROLLBACK 并把错误上抛(替代散落的手写 BEGIN/COMMIT/ROLLBACK)。 */
71
+ private withTransaction;
72
+ /**
73
+ * 加载 sqlite-vec 扩展并建 schema。构造后必须调用一次。
74
+ * providerInfo 变化(provider/model/维度)时 drop 向量表并返回 needsReindex。
75
+ */
76
+ init(providerInfo?: EmbeddingProviderInfo): StoreInitResult;
77
+ /** 惰性加载 sqlite-vec(纯 FTS 起步后切本地嵌入时补加载);失败只停用向量能力并告警一次。 */
78
+ private ensureVecLoaded;
79
+ /**
80
+ * 活切换嵌入源:provider/model/维度任一变化 → drop 向量表按新维度重建,
81
+ * 返回 needsReindex=true(调用方后台重嵌,全部成功后 markEmbeddingSynced);
82
+ * 配置未变化 → false(切回同一模型不重嵌)。
83
+ * 新维度 > 0 但 sqlite-vec 不可用 → ok=false(调用方向用户说明,维持 FTS)。
84
+ */
85
+ swapProvider(info: EmbeddingProviderInfo): {
86
+ ok: boolean;
87
+ needsReindex: boolean;
88
+ error?: string;
89
+ };
90
+ /** l1_vec 物理表的向量维度(建表 DDL 里的 float[N]);无表返回 null。 */
91
+ private physicalVecDims;
92
+ private initSchema;
93
+ private prepareL1VecStatements;
94
+ private prepareL0VecStatements;
95
+ private dropVectorTables;
96
+ private tableExists;
97
+ private hasColumn;
98
+ /**
99
+ * 时间增强列:valid_from / valid_to / persistence。
100
+ *
101
+ * 与 family 列同款增量迁移——DDL 契约不改,只在缺列时补,幂等。
102
+ * 存储形态与 created_time/updated_time 一致(ISO-8601 UTC 的 TEXT),
103
+ * 于是区间比较既可按字典序,也能沿用 idx_l1_updated 的既有用法。
104
+ *
105
+ * 存量数据的 metadata.activity_start_time/activity_end_time 是这两列的前身,不回填:
106
+ * 图谱时间锚仍读 metadata,列由新写入路径填充。
107
+ */
108
+ private ensureTemporalColumns;
109
+ /** 重建后的 l1_fts 从 l1_records 全量回灌(仅在 drop 重建时调用;iterate 流式防大库内存峰值)。 */
110
+ private backfillL1Fts;
111
+ /** 重建后的 l0_fts 从 l0_conversations 全量回灌(仅 drop 重建时调用;iterate 流式)。 */
112
+ private backfillL0Fts;
113
+ private readEmbeddingMeta;
114
+ private writeEmbeddingMeta;
115
+ /** 通用字符串 kv(embedding_meta 表兼作元数据 kv 存储,如 FTS 分词器版本戳)。 */
116
+ private readMetaString;
117
+ private writeMetaString;
118
+ /**
119
+ * 持久化 embedding meta(语义:物理向量表当前对应的 provider/维度)。
120
+ * 活切换在 swapProvider 成功后即写(表已是新维度);启动/补齐链在
121
+ * 缺失向量补齐收敛(missing=0)后写——缺失行补齐判据是行数差,不依赖 meta。
122
+ */
123
+ markEmbeddingSynced(info: EmbeddingProviderInfo): void;
124
+ /** upsert 一条 L1(元数据 + FTS 同步;embedding 非零时写向量)。失败返回 false 不抛。 */
125
+ upsertL1(record: MemoryRecord, embedding?: Float32Array): boolean;
126
+ /**
127
+ * 批量 upsert L1(单事务;与单条同语义:FTS 失败整批回滚)。
128
+ * 追加/导入热路径用它——逐条开事务在 WAL FULL 下每条一次 fsync。
129
+ * 整批失败时回退逐条写入:好记录照常入库、坏记录只丢自身——否则
130
+ * JSONL 事实源已先行追加,检索库却整批缺失且无自动重导路径(批次空洞)。
131
+ */
132
+ upsertL1Batch(records: MemoryRecord[], embeddings?: Array<Float32Array | undefined>): boolean;
133
+ /** 事务内的单条写入体(upsertL1 / upsertL1Batch 共用;调用方负责事务)。 */
134
+ private upsertL1InTx;
135
+ /** 批量删除 L1(元数据 + 向量 + FTS),返回删除条数。IN 按 ≤900 分块(避变量数上限)。
136
+ * 删除成功后触发图谱删除传播(来源全失效的节点/边惰性标 archived;失败不影响删除结果)。 */
137
+ deleteL1Batch(ids: string[]): number;
138
+ private inStatement;
139
+ /**
140
+ * 清空 L1 检索库全部数据(重建用)。records/FTS 直接 DELETE;
141
+ * 向量表走 DROP + 重建(vec0 的全表 DELETE 语义不可靠,dropVectorTables
142
+ * 会连 l0_vec 一起删——L0 向量必须保留——故此处单独处理 l1_vec)。
143
+ * L0 表与 embedding_meta 不动:backfill 的行数比对天然重新一致。
144
+ * 图谱表族一并清空——图谱是 L1 的可重建投影,记录清空即投影作废(B2)。
145
+ */
146
+ clearL1(): boolean;
147
+ countL1(): number;
148
+ /** 全量读取(调试/迁移/重嵌入用;检索请走 FTS/向量)。 */
149
+ getAllL1(): MemoryRecord[];
150
+ getL1ByIds(ids: string[]): MemoryRecord[];
151
+ /** 浏览列表(UI 用):按更新时间倒序,支持类型/场景/族/Hall 过滤与分页。失败返回空。 */
152
+ listL1(opts: {
153
+ type?: string;
154
+ scene?: string;
155
+ family?: string;
156
+ hall?: string;
157
+ limit: number;
158
+ offset: number;
159
+ }): {
160
+ items: MemoryRecord[];
161
+ total: number;
162
+ };
163
+ /** 场景名去重列表(UI 筛选器数据源)。失败返回空。 */
164
+ distinctL1Scenes(): string[];
165
+ /** FTS5 BM25 检索(family 缺省不过滤)。失败返回空数组(调用方降级)。 */
166
+ searchL1Fts(query: string, limit: number, family?: string): L1SearchHit[];
167
+ /** vec0 余弦 KNN 检索(score = 1 - cosine distance;family 过滤走过度召回 + 回查过滤,vec0 无法 WHERE)。失败返回空数组。 */
168
+ searchL1Vector(embedding: Float32Array, topK: number, family?: string): L1SearchHit[];
169
+ /** 批量 upsert L0 消息(元数据 + FTS;embeddings 与 records 等长,可省略)。 */
170
+ upsertL0Batch(records: L0MessageRecord[], embeddings?: Array<Float32Array | undefined>): boolean;
171
+ /** 记录一次蒸馏调用成本(委托 cost-ledger;语义见 CostLedger.insertCostCall)。 */
172
+ insertCostCall(provider: string, model: string, layer: string, inputChars: number, outputTokens: number, reasoningTokens: number, retentionDays: number): void;
173
+ /** 查询 token_cost 单窗口聚合(委托 cost-ledger;降级/异常返回零值)。 */
174
+ aggregateCost(since: number): {
175
+ total: CostAggregate;
176
+ byModel: CostByModel[];
177
+ };
178
+ /** 按层级归并聚合(委托 cost-ledger;降级/异常返回空数组)。 */
179
+ aggregateCostByLayer(since: number): CostByLayer[];
180
+ /** 按时间桶 + model 聚合(委托 cost-ledger;趋势图与日均/周均/月均共用)。 */
181
+ aggregateByBucket(bucketMs: number, offsetMs: number, since: number, layer: string): BucketRow[];
182
+ countL0(): number;
183
+ /** 统计 recorded_at >= iso 的消息数(状态面板"今日捕获"用)。 */
184
+ countL0Since(iso: string): number;
185
+ /** 统计某会话已捕获消息数(session-stats 数据源;idx_l0_session_id 索引点查)。 */
186
+ countL0BySession(sessionId: string): number;
187
+ /** 按会话取最近消息(时间升序返回;走 idx_l0_session_id 索引)。
188
+ * 蒸馏背景参考专用——按会话现查替代全局内存数组(ADR-0003)。 */
189
+ recentL0BySession(sessionId: string, limit: number): L0MessageRecord[];
190
+ /** L0 全量列举(重建快照用;按时间升序,事务一致性避开 JSONL 追加竞态)。 */
191
+ listL0All(): L0MessageRecord[];
192
+ /** 重建成本预估(一次全表聚合:会话数 / 消息数 / 字符量)。 */
193
+ l0RebuildEstimate(): {
194
+ sessions: number;
195
+ messages: number;
196
+ chars: number;
197
+ };
198
+ /** 向量表行数(backfill 判据:与元数据行数的差值即缺失向量数;不可用时返回 -1)。 */
199
+ countL1Vec(): number;
200
+ countL0Vec(): number;
201
+ searchL0Fts(query: string, limit: number): L0SearchHit[];
202
+ searchL0Vector(embedding: Float32Array, topK: number): L0SearchHit[];
203
+ /** L1 缺失向量的记录数(排除 skip 集后的补齐判据;向量能力不可用返回 -1)。 */
204
+ countL1VecMissing(exclude?: Set<string>): number;
205
+ /** L0 缺失向量的记录数(同上)。 */
206
+ countL0VecMissing(exclude?: Set<string>): number;
207
+ private countVecMissing;
208
+ /**
209
+ * 待重嵌入的 L1:只取缺失向量的记录(增量),排除 skip 集里已判定
210
+ * "当前 provider 下不可嵌入(零向量)"的 id——缺 1 条不再全量重嵌,
211
+ * 零向量记录也不再反复喂给 embeddings API(死循环双根因)。
212
+ */
213
+ getL1ForReindex(exclude?: Set<string>): Array<{
214
+ id: string;
215
+ content: string;
216
+ }>;
217
+ /** 待重嵌入的 L0(增量 + 排除 skip 集,同 getL1ForReindex)。 */
218
+ getL0ForReindex(exclude?: Set<string>): Array<{
219
+ id: string;
220
+ text: string;
221
+ }>;
222
+ getVecSkipSet(kind: 'l1' | 'l0'): Set<string>;
223
+ addVecSkippedIds(kind: 'l1' | 'l0', ids: string[]): void;
224
+ clearVecSkipIds(kind: 'l1' | 'l0'): void;
225
+ /** 只更新向量行(重嵌入用)。 */
226
+ updateL1Vec(id: string, embedding: Float32Array): boolean;
227
+ updateL0Vec(id: string, embedding: Float32Array, recordedAt: string): boolean;
228
+ /**
229
+ * 批量更新 L1 向量行(重嵌入热路径):单事务写入整批——逐条每行一次隐式事务,
230
+ * 批量场景(万级记录重嵌)开销集中在 fsync 上。
231
+ * 整批失败回退逐条:好行照常入库,坏行只丢自身(向量行 id 寻址,无顺序依赖)。
232
+ * 返回成功写入的行数(零向量行防御性跳过、不计入)。
233
+ */
234
+ updateL1VecBatch(items: Array<{
235
+ id: string;
236
+ embedding: Float32Array;
237
+ }>): number;
238
+ /** L0 版 updateL1VecBatch(语义同:单事务 + 失败回退逐条)。recordedAt 整批统一。 */
239
+ updateL0VecBatch(items: Array<{
240
+ id: string;
241
+ embedding: Float32Array;
242
+ }>, recordedAt: string): number;
243
+ close(): void;
244
+ }
245
+ /** 全零向量(cosine 未定义,不可入向量表)。reindex 侧用它区分"不可嵌入"与"写入失败"。 */
246
+ export declare function isZeroVector(vec: Float32Array): boolean;