@modusensus/dsh-mneme 0.8.3 → 0.8.5
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/LICENSE +21 -21
- package/README.md +727 -636
- package/bin/cli.mjs +0 -0
- package/bin/dsh-mneme-mcp.mjs +510 -0
- package/cordis.patch.yml +21 -21
- package/lib/api-standalone.js +506 -316
- package/lib/api.js +1403 -1316
- package/lib/bootstrap.js +211 -0
- package/lib/client.js +4657 -4366
- package/lib/commands.js +95 -95
- package/lib/config.js +615 -510
- package/lib/document.js +221 -0
- package/lib/dream/clustering.js +118 -118
- package/lib/dream/decisions.js +658 -658
- package/lib/dream/narratives.js +44 -0
- package/lib/dream/sleep.js +702 -700
- package/lib/dream.js +147 -16
- package/lib/embedding.js +177 -177
- package/lib/entities/extractor.js +249 -249
- package/lib/guide.js +44 -0
- package/lib/heat.js +144 -136
- package/lib/hot-memory.js +46 -46
- package/lib/index.js +515 -515
- package/lib/inject.js +375 -295
- package/lib/lang.js +208 -179
- package/lib/local-embedder.js +320 -320
- package/lib/mirror.js +198 -198
- package/lib/organize.js +450 -0
- package/lib/quality-filter.js +126 -126
- package/lib/recall-stats.js +125 -0
- package/lib/reranker.js +269 -269
- package/lib/runtime/adopt.js +176 -176
- package/lib/runtime/closure.js +172 -172
- package/lib/runtime/download.js +247 -247
- package/lib/runtime/layout.js +265 -235
- package/lib/runtime/loader.js +252 -249
- package/lib/runtime/model-fetch.js +361 -361
- package/lib/runtime/provision.js +237 -237
- package/lib/runtime/tarball.js +130 -130
- package/lib/runtime/verify.js +204 -191
- package/lib/scope.js +118 -118
- package/lib/search/adaptive.js +60 -22
- package/lib/search/bm25.js +96 -96
- package/lib/service.js +2324 -2087
- package/lib/settings.js +459 -420
- package/lib/store.js +2549 -2367
- package/lib/summarize.js +820 -449
- package/lib/tools.js +702 -574
- package/lib/vector-index.js +110 -110
- package/lib/version-check.js +122 -122
- package/package.json +109 -108
- package/runtime-manifest.json +526 -596
- package/scripts/benchmark-embed.js +201 -201
- package/scripts/benchmark-recall.js +199 -199
- package/scripts/benchmark-rerank.js +166 -166
- package/scripts/build-runtime-manifest.mjs +224 -217
- package/scripts/check-sync.js +42 -42
- package/scripts/e2e-dsh.js +220 -220
- package/scripts/mneme-runtime.mjs +277 -277
- package/scripts/stress-dsh.js +255 -255
- package/scripts/sync-lib.js +47 -47
- package/scripts/sync-test-badge.mjs +67 -61
- package/src/api-standalone.js +506 -316
- package/src/api.js +1403 -1316
- package/src/bootstrap.js +211 -0
- package/src/commands.js +95 -95
- package/src/config.js +615 -510
- package/src/document.js +221 -0
- package/src/dream/clustering.js +118 -118
- package/src/dream/decisions.js +658 -658
- package/src/dream/narratives.js +44 -0
- package/src/dream/sleep.js +702 -700
- package/src/dream.js +147 -16
- package/src/embedding.js +177 -177
- package/src/entities/extractor.js +249 -249
- package/src/guide.js +44 -0
- package/src/heat.js +144 -136
- package/src/hot-memory.js +46 -46
- package/src/index.js +515 -515
- package/src/inject.js +375 -295
- package/src/lang.js +208 -179
- package/src/local-embedder.js +320 -320
- package/src/mirror.js +198 -198
- package/src/organize.js +450 -0
- package/src/quality-filter.js +126 -126
- package/src/recall-stats.js +125 -0
- package/src/reranker.js +269 -269
- package/src/runtime/adopt.js +176 -176
- package/src/runtime/closure.js +172 -172
- package/src/runtime/download.js +247 -247
- package/src/runtime/layout.js +265 -235
- package/src/runtime/loader.js +252 -249
- package/src/runtime/model-fetch.js +361 -361
- package/src/runtime/provision.js +237 -237
- package/src/runtime/tarball.js +130 -130
- package/src/runtime/verify.js +204 -191
- package/src/scope.js +118 -118
- package/src/search/adaptive.js +60 -22
- package/src/search/bm25.js +96 -96
- package/src/service.js +2324 -2087
- package/src/settings.js +459 -420
- package/src/store.js +2549 -2367
- package/src/summarize.js +820 -449
- package/src/tools.js +702 -574
- package/src/vector-index.js +110 -110
- package/src/version-check.js +122 -122
- package/test/adaptive-inject-budget.test.js +85 -0
- package/test/api-routes-gaps.test.js +218 -218
- package/test/api.test.js +1640 -1482
- package/test/audit.test.js +448 -448
- package/test/benchmark.test.js +94 -94
- package/test/bootstrap.test.js +220 -0
- package/test/client.test.js +860 -736
- package/test/clustering.test.js +100 -100
- package/test/commands.test.js +106 -106
- package/test/config.test.js +66 -66
- package/test/conflict-freeze.test.js +300 -300
- package/test/document.test.js +523 -0
- package/test/dream-archive-guardrail.test.js +116 -116
- package/test/dream-candidate-hybrid.test.js +281 -281
- package/test/dream-coverage-degrade.test.js +86 -86
- package/test/dream.test.js +1308 -1254
- package/test/embedding-ready.test.js +196 -196
- package/test/entities.test.js +547 -547
- package/test/entity-recall.test.js +179 -0
- package/test/epistemic.test.js +298 -298
- package/test/fnew-0112.test.js +311 -311
- package/test/fnew-03.test.js +422 -422
- package/test/graph-api.test.js +175 -175
- package/test/heat.test.js +175 -148
- package/test/helpers/dream-mock.js +82 -82
- package/test/helpers/peer-worker.mjs +25 -25
- package/test/helpers/runtime-source.js +60 -60
- package/test/helpers/tar-builder.js +80 -80
- package/test/hot-memory.test.js +145 -145
- package/test/inject-content-cap.test.js +91 -0
- package/test/inject-first-round-bm25.test.js +89 -89
- package/test/inject-heat.test.js +61 -0
- package/test/inject-pools.test.js +170 -0
- package/test/inject-recall.test.js +105 -0
- package/test/inject-rotation.test.js +161 -161
- package/test/inject.test.js +283 -249
- package/test/lang.test.js +87 -87
- package/test/lib-smoke.test.js +96 -96
- package/test/llm-audit.test.js +462 -309
- package/test/llm-message-source.test.js +177 -177
- package/test/local-embedder.test.js +249 -249
- package/test/mcp-stdio.test.js +385 -0
- package/test/mirror-dirty.test.js +424 -424
- package/test/mirror-edit-digest.test.js +187 -187
- package/test/mirror-generation.test.js +499 -499
- package/test/mirror.test.js +249 -249
- package/test/narrative-bars.test.js +162 -0
- package/test/organize.test.js +418 -0
- package/test/peer-blockers.test.js +193 -193
- package/test/policy-epoch.test.js +259 -259
- package/test/quality-filter.test.js +186 -186
- package/test/reasoning-effort.test.js +746 -746
- package/test/recall-evals.test.js +235 -235
- package/test/recall-layer.test.js +326 -326
- package/test/recall-stats.test.js +123 -0
- package/test/receipt-chain.test.js +451 -451
- package/test/reflection.test.js +226 -226
- package/test/reindex-backfill.test.js +62 -62
- package/test/reranker-single-logit.test.js +73 -73
- package/test/reranker.test.js +197 -197
- package/test/resident-status.test.js +83 -0
- package/test/runtime-adopt.test.js +206 -206
- package/test/runtime-cli.test.js +89 -89
- package/test/runtime-closure.test.js +193 -193
- package/test/runtime-download.test.js +302 -302
- package/test/runtime-layout.test.js +163 -163
- package/test/runtime-loader.test.js +255 -237
- package/test/runtime-manifest.test.js +159 -158
- package/test/runtime-model-fetch.test.js +348 -348
- package/test/runtime-provision.test.js +101 -101
- package/test/runtime-tarball.test.js +81 -81
- package/test/runtime-verify.test.js +279 -214
- package/test/scope-candidates.test.js +239 -239
- package/test/scope-explicit.test.js +452 -452
- package/test/scope-retrieval.test.js +197 -197
- package/test/scope-storage.test.js +255 -255
- package/test/scope-strict.test.js +231 -231
- package/test/search-fusion.test.js +90 -90
- package/test/semantic.test.js +124 -124
- package/test/service-search.test.js +174 -174
- package/test/service.test.js +405 -405
- package/test/settings.test.js +261 -261
- package/test/skip-invalid-restore.test.js +262 -262
- package/test/sleep-action-set.test.js +422 -422
- package/test/sleep-heat.test.js +126 -125
- package/test/sleep-scheduler-rearm.test.js +89 -89
- package/test/sleep.test.js +410 -373
- package/test/standalone-api.test.js +544 -359
- package/test/store-vector-cache.test.js +98 -98
- package/test/store.test.js +396 -383
- package/test/stress.test.js +209 -209
- package/test/summarize.test.js +1288 -575
- package/test/tools-dto-schema-matrix.test.js +325 -0
- package/test/tools-memory-get-schema.test.js +65 -65
- package/test/tools.test.js +374 -341
- package/test/updated-at-semantics.test.js +113 -113
- package/test/vector-index.test.js +221 -221
- package/test/version-check.test.js +152 -152
- package/test/webServer-optional.test.js +82 -82
package/src/config.js
CHANGED
|
@@ -1,510 +1,615 @@
|
|
|
1
|
-
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { TYPE_DECAY_DEFAULTS } from "./heat.js";
|
|
3
|
-
|
|
4
|
-
export const Config = z.object({
|
|
5
|
-
// 记忆语言:生成记忆、注入标题与后台 LLM 提示词所用语言;'zh'(默认,
|
|
6
|
-
// 行为不变)/ 'en'。启动时读入,切换后重启生效。
|
|
7
|
-
language: z.union([z.const("zh"), z.const("en")]).default("zh")
|
|
8
|
-
.description("记忆语言:生成的记忆条目、注入标题与后台 LLM 提示词所用语言(zh=默认中文,en=英文)。"),
|
|
9
|
-
memoryDir: z.string().default("~/.dsh/memory"),
|
|
10
|
-
autoInject: z.boolean().default(true),
|
|
11
|
-
autoSummarize: z.boolean().default(true),
|
|
12
|
-
// Optional model override for summarization. When both are non-empty, they
|
|
13
|
-
// take priority over the session's current model. Empty = use the session's
|
|
14
|
-
// active provider/model (same as before).
|
|
15
|
-
summarizeProvider: z.string().default(""),
|
|
16
|
-
summarizeModel: z.string().default(""),
|
|
17
|
-
// 蒸馏转录上限(字符)。借鉴 Codex「保留原始、替代压缩摘要」的思路:
|
|
18
|
-
// 蒸馏把完整对话上下文交给 LLM 提炼,不硬裁到 8000 字就截断语义;默认
|
|
19
|
-
// 24000 字符(约覆盖一整轮中等对话),需要更完整可调大。
|
|
20
|
-
distillMaxChars: z.natural().min(1000).max(200000).default(24000),
|
|
21
|
-
// autoSummarize 节流、产出上限与写入端同会话去重(Issue #127,默认全 0/off =
|
|
22
|
-
// 零行为变化)。此前每个 turn/end 必跑、产出条数由模型输出决定、写入端只按
|
|
23
|
-
// 「同类型 + 标题 trim 全等」去重——本机实测单日 84 次、单会话一天 198 条、
|
|
24
|
-
// 同一事实 6 小时铸出 28+ 条。阀门交给用户按需拧,升级本身不改行为。
|
|
25
|
-
summarizeMinIntervalMinutes: z.natural().min(0).max(10080).default(0),
|
|
26
|
-
summarizeMaxEntriesPerRun: z.natural().min(0).max(50).default(0),
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// Issue #
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
// and
|
|
288
|
-
|
|
289
|
-
//
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
//
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
//
|
|
329
|
-
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
//
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
//
|
|
360
|
-
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
//
|
|
367
|
-
//
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
//
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
//
|
|
392
|
-
|
|
393
|
-
//
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
//
|
|
407
|
-
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
|
|
411
|
-
//
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
//
|
|
421
|
-
//
|
|
422
|
-
//
|
|
423
|
-
//
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
//
|
|
438
|
-
|
|
439
|
-
//
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
//
|
|
444
|
-
//
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
//
|
|
456
|
-
//
|
|
457
|
-
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
//
|
|
466
|
-
//
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
//
|
|
471
|
-
//
|
|
472
|
-
|
|
473
|
-
//
|
|
474
|
-
//
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
//
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { TYPE_DECAY_DEFAULTS } from "./heat.js";
|
|
3
|
+
|
|
4
|
+
export const Config = z.object({
|
|
5
|
+
// 记忆语言:生成记忆、注入标题与后台 LLM 提示词所用语言;'zh'(默认,
|
|
6
|
+
// 行为不变)/ 'en'。启动时读入,切换后重启生效。
|
|
7
|
+
language: z.union([z.const("zh"), z.const("en")]).default("zh")
|
|
8
|
+
.description("记忆语言:生成的记忆条目、注入标题与后台 LLM 提示词所用语言(zh=默认中文,en=英文)。"),
|
|
9
|
+
memoryDir: z.string().default("~/.dsh/memory"),
|
|
10
|
+
autoInject: z.boolean().default(true),
|
|
11
|
+
autoSummarize: z.boolean().default(true),
|
|
12
|
+
// Optional model override for summarization. When both are non-empty, they
|
|
13
|
+
// take priority over the session's current model. Empty = use the session's
|
|
14
|
+
// active provider/model (same as before).
|
|
15
|
+
summarizeProvider: z.string().default(""),
|
|
16
|
+
summarizeModel: z.string().default(""),
|
|
17
|
+
// 蒸馏转录上限(字符)。借鉴 Codex「保留原始、替代压缩摘要」的思路:
|
|
18
|
+
// 蒸馏把完整对话上下文交给 LLM 提炼,不硬裁到 8000 字就截断语义;默认
|
|
19
|
+
// 24000 字符(约覆盖一整轮中等对话),需要更完整可调大。
|
|
20
|
+
distillMaxChars: z.natural().min(1000).max(200000).default(24000),
|
|
21
|
+
// autoSummarize 节流、产出上限与写入端同会话去重(Issue #127,默认全 0/off =
|
|
22
|
+
// 零行为变化)。此前每个 turn/end 必跑、产出条数由模型输出决定、写入端只按
|
|
23
|
+
// 「同类型 + 标题 trim 全等」去重——本机实测单日 84 次、单会话一天 198 条、
|
|
24
|
+
// 同一事实 6 小时铸出 28+ 条。阀门交给用户按需拧,升级本身不改行为。
|
|
25
|
+
summarizeMinIntervalMinutes: z.natural().min(0).max(10080).default(0),
|
|
26
|
+
summarizeMaxEntriesPerRun: z.natural().min(0).max(50).default(0),
|
|
27
|
+
// Issue #239(成本感知级联第一级):蒸馏前的零 LLM 预判——窗口内可蒸馏文本
|
|
28
|
+
// 不足此字符数时直接跳过 LLM 调用(0 = 关闭,行为与现状逐字节一致)。判定
|
|
29
|
+
// 纯规则、无模型参与;被挡下的窗口照常消费游标(否则每个 turn/end 都会重新
|
|
30
|
+
// 评估同一段短文本),并留一行 status='skipped' 审计,error_message 写明原因
|
|
31
|
+
// ——「这一窗为什么没蒸馏」必须可观测,否则阀门等于黑盒。
|
|
32
|
+
summarizeMinWindowChars: z.natural().min(0).max(100000).default(0),
|
|
33
|
+
// Issue #239(有界检查点):同一会话最多发起多少次蒸馏(0 = 不限,等同现状)。
|
|
34
|
+
// 只统计真正发起过 LLM 调用的 run——被预判挡下的窗口不占预算,否则阀门会把
|
|
35
|
+
// 额度浪费在零成本窗口上。计数是进程内 per-session(与最小间隔闸门同生命
|
|
36
|
+
// 周期),宿主重启即清零,与 #229 的游标持久化是两件事。
|
|
37
|
+
summarizeMaxRunsPerSession: z.natural().min(0).max(1000).default(0),
|
|
38
|
+
// Issue #239(第 4 项,错峰队列):高峰期蒸馏顺延。空串 = 关闭,行为与现状逐
|
|
39
|
+
// 字节一致。取值是本地时间的时段列表(逗号分隔,支持跨零点),可带**星期前缀**
|
|
40
|
+
// (可省;ISO 1=周一…7=周日,也认 mon..sun;省略 = 每天):
|
|
41
|
+
// "09:00-18:00" 每天 09:00-18:00
|
|
42
|
+
// "mon-fri 08:00-12:00,14:00-18:00" 工作日两段(按高峰计费的供应商即此形态)
|
|
43
|
+
// "sat,sun 23:00-06:00" 周末跨零点段
|
|
44
|
+
// 命中高峰时:不调 LLM、不消费游标(窗口继续累积,留到非高峰一次性蒸馏——批量
|
|
45
|
+
// 比逐轮碎蒸更省),登记一行 status='skipped' / error_message='peak-hours' 审计,
|
|
46
|
+
// 并按下面的上限择时补跑。任一写法非法则整串按「未配置」处理:排程是省钱
|
|
47
|
+
// 手段,绝不该因为写错格式把蒸馏停掉。
|
|
48
|
+
summarizePeakHours: z.string().default(""),
|
|
49
|
+
// 高峰顺延上限(分钟,0 = 不设上限):到点仍处高峰就照常跑,避免整天高峰把蒸馏
|
|
50
|
+
// 饿死。默认 120 分钟。仅在上面的时段串非空时生效。
|
|
51
|
+
summarizePeakMaxDeferMinutes: z.natural().min(0).max(1440).default(120),
|
|
52
|
+
// 落库前去重档位:off(默认,等同现状)/ title(零成本,仅拦完全同名)/
|
|
53
|
+
// vector(复用已有 embedding 列做同会话语义近邻,无 LLM 调用)。
|
|
54
|
+
summarizeDedupeMode: z.union([z.const("off"), z.const("title"), z.const("vector")]).default("off"),
|
|
55
|
+
summarizeDedupeMinSim: z.number().min(0.5).max(0.99).default(0.92),
|
|
56
|
+
summarizeDedupeWindowHours: z.natural().min(0).max(168).default(24),
|
|
57
|
+
// 智能调速器(429 保护,默认开):蒸馏 LLM 调用全局串行排队,相邻请求
|
|
58
|
+
// 间隔 distillRateLimitIntervalMs(默认 1s 一次);命中 429 限流时按
|
|
59
|
+
// distillRateLimitBaseDelayMs 指数退避(1s→2s→4s…)自动重试
|
|
60
|
+
// distillRateLimitRetries 次,全程对用户透明,不把 429 错误码抛给用户。
|
|
61
|
+
distillRateLimitIntervalMs: z.natural().min(0).max(60000).default(1000),
|
|
62
|
+
distillRateLimitRetries: z.natural().min(0).max(10).default(3),
|
|
63
|
+
distillRateLimitBaseDelayMs: z.natural().min(100).max(60000).default(1000),
|
|
64
|
+
maxInjectedItems: z.natural().min(1).max(20).default(5),
|
|
65
|
+
// Issue #205:注入位跨轮轮换。同一会话里,最近 N 个不同用户查询轮次注入过
|
|
66
|
+
// 的记忆本轮不再优先(新鲜优先、原序回填,槽位数不变);长会话中避免相邻
|
|
67
|
+
// 轮次反复注入同一条(实测 15.5h 会话 86 次注入 93% 重复)。0 = 关闭(默认,
|
|
68
|
+
// 保持既有行为)。会话边界自动重置:新会话从零开始。
|
|
69
|
+
injectRotationTurns: z.natural().min(0).max(20).default(0),
|
|
70
|
+
// Issue #164①:注入单条正文截断上限可配(原硬编码 300)。截断时尾部带
|
|
71
|
+
// 提示:上限/原长/全文 memory_get 指引(BUDGET_EXCEEDED 原则——绝不静默)。
|
|
72
|
+
// 默认 300 = 与既有行为一致。
|
|
73
|
+
injectContentMaxChars: z.natural().min(60).max(4000).default(300),
|
|
74
|
+
importanceThreshold: z.natural().min(1).max(5).default(3),
|
|
75
|
+
// Issue #239(第 5 项):注入条数的查询自适应(默认关)。确定性强的话题收缩注入
|
|
76
|
+
// 条数(减半、下限 1),模糊话题(回指/时间线索,或极短查询)维持
|
|
77
|
+
// maxInjectedItems 上限——只做**单向收缩**,绝不越过用户配置的上限;判据只看
|
|
78
|
+
// 查询本身,不做额外检索(先探针检索等于白付一次 fuseRecall)。
|
|
79
|
+
injectUncertaintyAdaptive: z.boolean().default(false),
|
|
80
|
+
// #249(第一批):能力说明——「怎么用记忆」的判断指引。落两个零注入成本的
|
|
81
|
+
// 位:①`memory_search` / `memory_save` 的工具描述补一句判断指引(工具描述是
|
|
82
|
+
// 常驻文本,不进每轮上下文);②一段 order 150 的系统提示段(一次性、同会话
|
|
83
|
+
// 内不随轮次变化,因此不作废前缀缓存),只讲总则(优先序、何时查、何时写、
|
|
84
|
+
// 何时 no-op)。默认关:关闭时工具描述与提示段与既有行为逐字节一致。
|
|
85
|
+
injectGuidanceEnabled: z.boolean().default(false),
|
|
86
|
+
// #249(第一批):B1 pin 池预算——约束/偏好类注入条目的独立小上限。约束与
|
|
87
|
+
// 偏好被静默降级是本议题的立项核心(同类知识与情景日志同池同速率摘要,实测
|
|
88
|
+
// 一轮压缩后仅保 53%、五轮 10%),故这两类不进相关性竞争、不参与跨轮轮换、
|
|
89
|
+
// 逐字保真(仅受超大条目的硬顶保护,截断仍带提示)并排在块内排序之前。
|
|
90
|
+
// 独立预算的意义:pin 不占 maxInjectedItems 名额,不会把当前任务需要的情景
|
|
91
|
+
// 候选挤出预算(另一种「批量塞历史」)。0(默认)= 关闭,注入块构成与既有
|
|
92
|
+
// 行为逐字节一致;超出预算的条数在块内如实标注未展示条数,绝不静默。
|
|
93
|
+
pinnedInjectBudget: z.natural().min(0).max(5).default(0),
|
|
94
|
+
// 编码记忆蒸馏(codingRetrospect,opt-in,默认关)。开启时,turn/end 蒸馏
|
|
95
|
+
// 额外提取三类编码专属记忆:rejected_solution(被否决方案)/ pitfall(踩坑)/
|
|
96
|
+
// constraint(工程约束)。蒸馏上下文为整轮完整对话(用户输入 → 助手思考/回答
|
|
97
|
+
// → 工具调用与结果 → 代码执行),不再只看用户消息,便于提炼踩坑根因。
|
|
98
|
+
// 关闭时行为与之前完全一致。
|
|
99
|
+
codingRetrospect: z.boolean().default(false),
|
|
100
|
+
// 编码任务识别词表(读取侧门控用):命中即视为编码类任务,编码记忆才注入。
|
|
101
|
+
codingKeywords: z.array(z.string()).default([
|
|
102
|
+
"代码", "编码", "写一个", "写个", "实现", "函数", "方法", "类",
|
|
103
|
+
"接口", "bug", "调试", "报错", "错误", "异常", "堆栈", "脚本",
|
|
104
|
+
"python", "javascript", "typescript", "node", "js", "ts",
|
|
105
|
+
"sql", "sqlite", "数据库", "算法", "重构", "优化", "性能",
|
|
106
|
+
"测试", "单测", "修复", "补丁", "依赖", "npm", "pip",
|
|
107
|
+
"命令行", "shell", "配置", "配置文件", "yaml", "json",
|
|
108
|
+
"插件", "开发", "编译", "构建", "部署", "git", "commit",
|
|
109
|
+
"review", "前端", "后端", "页面", "组件", "dsh", "memos"
|
|
110
|
+
]),
|
|
111
|
+
// 编码记忆注入加权系数:编码任务时对 rejected_solution/pitfall/constraint
|
|
112
|
+
// 记忆的 importance 乘以该系数排序,让编码记忆在编码场景更靠前。
|
|
113
|
+
codingBoostFactor: z.number().min(1).max(5).default(2),
|
|
114
|
+
// 注入边界花括号转义(issue #162,v0.7.4 曾修后被 v0.7.11 重构误删):默认开启,
|
|
115
|
+
// 在 memory / 短期上下文 / 用户设置三处注入出口对连续 2+ 个花括号插 `\`
|
|
116
|
+
// (`{{a}}`→`{\{a\}\}`),让 DSH 的 interpolate() 不再扫到非法变量名而 throw。
|
|
117
|
+
// 关闭时按原样透传。
|
|
118
|
+
escapePromptVariables: z.boolean().default(true),
|
|
119
|
+
autoDream: z.boolean().default(true),
|
|
120
|
+
dreamThresholdCount: z.natural().min(1).max(1000).default(10),
|
|
121
|
+
dreamThresholdChars: z.natural().min(100).max(100000).default(5000),
|
|
122
|
+
dreamDelayMs: z.natural().min(0).max(60000).default(2000),
|
|
123
|
+
// autoDream 触发最小间隔(分钟,0 = 不限制,Issue #89 请求 2):高频写入
|
|
124
|
+
// 场景下防止巩固调用(含失败重试)连发刷爆配额。间隔从每次实际开跑时刻
|
|
125
|
+
// 起算,失败/degraded 的 run 也占用间隔;间隔内的触发请求静默跳过,下一次
|
|
126
|
+
// 写入事件会重新评估。
|
|
127
|
+
dreamMinIntervalMinutes: z.natural().min(0).max(10080).default(0),
|
|
128
|
+
// 巩固模型路由(settings panel「巩固模型」/ dreamProvider+dreamModel):
|
|
129
|
+
// dream 的记忆沉淀专用 LLM 路由,显式配置优先于 agent 默认模型(config-first,
|
|
130
|
+
// Issue #25)。模型分类声明:
|
|
131
|
+
// - 非思考模型(推荐,如 glm-5-2 类):无 reasoning 声明,effort 请求被 harness
|
|
132
|
+
// 拒绝后 withEffortFallback 去掉字段重试即成功;空体/no json array 风险最低。
|
|
133
|
+
// - 思考模型(如 deepseek-v4-flash-ga 等 v4-flash-ga 系):默认开推理,可能烧光
|
|
134
|
+
// token 预算返回空体;且部分(如 v4-flash-ga)在 harness 侧被声明为不接受任何
|
|
135
|
+
// reasoning effort —— 即使去掉 effort 重试,harness 的 defaultEffort 也会顶上来
|
|
136
|
+
// 再次拒绝(UNSUPPORTED_REASONING_EFFORT),插件 fallback 无法绕开。
|
|
137
|
+
// 选用时建议配 dreamReasoningEffort 并实测;不行就换非思考模型。
|
|
138
|
+
dreamProvider: z.string().description("记忆巩固专用模型的服务商(settings「巩固模型」)。巩固反复失败时,优先改用官方非思考模型的服务商(如 deepseek / glm)。"),
|
|
139
|
+
dreamModel: z.string().description("记忆巩固专用模型。建议选非思考模型(如 deepseek-chat、glm-5-2 类):思考模型可能烧光 token 预算返回空体,导致巩固失败(UNSUPPORTED_REASONING_EFFORT)。"),
|
|
140
|
+
// Issue #135 建议 3:#9 只抬了 max(8192→131072),default 停在 32768。思考型
|
|
141
|
+
// 模型的推理与正文共享该预算,effort 未压低时 32768 恰好被推理烧光 → 空体
|
|
142
|
+
// ("no json array in llm output",报告实测 146 轮因此失败)。默认抬到上限,
|
|
143
|
+
// 让默认配置也留足正文预算;流式计费按实际用量,不按上限。
|
|
144
|
+
dreamMaxTokens: z.natural().min(256).max(131072).default(131072),
|
|
145
|
+
// Pass-through reasoning effort for dream's LLM calls (Issue #135 建议 4/5).
|
|
146
|
+
// Unset (no value) resolves to the LOWEST effort the model declares before
|
|
147
|
+
// streaming: background consolidation must produce JSON, and omitting the
|
|
148
|
+
// field lets the harness substitute the model's defaultEffort (thinking-type
|
|
149
|
+
// models often default to high/max) — the reasoning then drains the whole
|
|
150
|
+
// token budget and the run dies with an empty body. Explicit 'none' still
|
|
151
|
+
// omits the field (provider default applies); off/low/medium/high are
|
|
152
|
+
// forwarded verbatim, unsupported values are remapped (v0.7.26+).
|
|
153
|
+
// Caveat: on some thinking models (e.g. v4-flash-ga) the harness declares NO
|
|
154
|
+
// supported effort, so even the fallback retry (field stripped) is rejected
|
|
155
|
+
// again via its defaultEffort — prefer a non-reasoning dreamProvider/dreamModel.
|
|
156
|
+
dreamReasoningEffort: z.union([
|
|
157
|
+
z.const("off"),
|
|
158
|
+
z.const("low"),
|
|
159
|
+
z.const("medium"),
|
|
160
|
+
z.const("high"),
|
|
161
|
+
z.const("none")
|
|
162
|
+
]).description("巩固模型的推理档位:未配置 = 自动取模型支持的最低档(避免思考模型用自带默认档烧光预算返回空体,#135);显式 'none' = 不发送字段、用服务商自带默认;off/low/medium/high 原样传递。模型不支持的值会自动换用其支持的档位(v0.7.26+)。"),
|
|
163
|
+
// 滑动窗口上限(v0.4.4):autoDream 每次只对最近 dreamMaxSnapshotSize 条
|
|
164
|
+
// 记忆做 consolidation。大记忆量下全量快照会把 LLM 输入撑爆(636 记忆 →
|
|
165
|
+
// 677 "missing" errors、applied=0),窗口外的旧记忆不进 snapshot。
|
|
166
|
+
dreamMaxSnapshotSize: z.natural().min(1).max(1000).default(200),
|
|
167
|
+
// Issue #104 方向 2:单轮 archive 决策上限。一次性大扫除(12 条互不相关主题
|
|
168
|
+
// 被批量归档,其中 8 条疑似误伤长保留类型)是失控信号,与 update 上限同类的
|
|
169
|
+
// 全局闸门:skipInvalid 也不豁免,超限整单拒绝。正常清理可调高。
|
|
170
|
+
dreamMaxArchivePerRun: z.natural().min(1).max(200).default(8),
|
|
171
|
+
// Issue #125:候选集构造方式。"window"(默认,等同现状)只取最近
|
|
172
|
+
// dreamMaxSnapshotSize 条;"hybrid" 在此基础上并入**向量翻出的高相似组**——
|
|
173
|
+
// 本机实测 45 对「双方活跃且 sim≥0.85」里 0 对能同时进窗口(窗口覆盖率 11.7%),
|
|
174
|
+
// 纯时间窗口让"该合并的一对"几乎永远碰不到面。候选总量仍由下面的上限封顶、
|
|
175
|
+
// 与库总量解耦,这是相对"调大窗口"的核心收益:输入成本不随库增长。
|
|
176
|
+
dreamCandidateMode: z.union([
|
|
177
|
+
z.const("window"),
|
|
178
|
+
z.const("hybrid")
|
|
179
|
+
]).default("window"),
|
|
180
|
+
// hybrid 的候选总量上限;0 = 复用 dreamMaxSnapshotSize(不迁移,需要时显式覆盖)。
|
|
181
|
+
dreamCandidateMax: z.natural().min(0).max(5000).default(0),
|
|
182
|
+
// Issue #258:总览(dream_summarize)独立路由。consolidate 有 dreamMaxSnapshotSize
|
|
183
|
+
// 窗口、总览原为全库无界——两者对 ctx 的需求差 4 倍以上却强制共用 dream 路由,
|
|
184
|
+
// dreamProvider 指向小 ctx 模型时总览当场 CONTEXT_WINDOW_EXCEEDED(实测 120,969
|
|
185
|
+
// tokens > 32,768),指向大 ctx 模型则 consolidate 的卸载收益归零。未配置 = 回落
|
|
186
|
+
// dream 路由,行为逐字节不变。
|
|
187
|
+
dreamSummaryProvider: z.string().default("").description("记忆总览(dream_summarize)专用模型服务商,留空用巩固模型。总览输入为全库(或 dreamSummaryMaxInputs 上限),ctx 需求远大于 consolidation,建议大 ctx 模型(issue #258)。"),
|
|
188
|
+
dreamSummaryModel: z.string().default("").description("记忆总览(dream_summarize)专用模型,留空用巩固模型;总览输入随库增长,建议大 ctx 非思考模型(issue #258)。"),
|
|
189
|
+
// Issue #258:总览输入条数硬上限。0 = 不设上限(历史行为,库增长可能撑爆小
|
|
190
|
+
// ctx 模型);>0 时按 updated_at 倒序保留最新的 N 条(与 consolidate 窗口同一
|
|
191
|
+
// 排序口径)。总览是常驻叙述而非逐条巩固,限输入只影响口径脚注里的条数。
|
|
192
|
+
dreamSummaryMaxInputs: z.natural().min(0).max(100000).default(0),
|
|
193
|
+
// hybrid 判"高相似"的阈值;0.85 与 sleep normal 档对齐——两个模块对"高相似"
|
|
194
|
+
// 保持同一个定义。
|
|
195
|
+
dreamCandidateMinSim: z.number().min(0.5).max(0.99).default(0.85),
|
|
196
|
+
// 叙述条(#164 对齐,opt-in):dream 期间按共享 tag 主题聚类(dream/
|
|
197
|
+
// narratives.js),每簇 LLM 合成一条叙述落库(source=narrative、evidence
|
|
198
|
+
// 回链簇内原子记忆、求交防捏造)。按需检索、不常驻注入。默认关=行为与
|
|
199
|
+
// 此前一致;lightMode 强制关闭。
|
|
200
|
+
dreamNarrativeEnabled: z.boolean().default(false),
|
|
201
|
+
// 成簇门槛:共享同一 tag 的记忆 ≥ 此值才合成叙述条。
|
|
202
|
+
dreamNarrativeMinCluster: z.natural().min(2).max(20).default(3),
|
|
203
|
+
// document 型记忆(#164/#230,opt-in):agent 产长文档的指针行——注册校验
|
|
204
|
+
// (文件存在 + 路径合法 + evidence 求交)、摘要 + doc_path 落库、C2 比对
|
|
205
|
+
// 去重、supersede 记账。全文归 agent,管线零触碰;默认关=行为与此前一致;
|
|
206
|
+
// lightMode 强制关闭。
|
|
207
|
+
documentMemoryEnabled: z.boolean().default(false),
|
|
208
|
+
// document 摘要行的注入预算(#230 拍板):次优先档内最多注入的 document
|
|
209
|
+
// 行数,超预算跳过由后续候选补位。只约束注入,不约束检索。
|
|
210
|
+
documentInjectBudget: z.natural().min(1).max(5).default(2),
|
|
211
|
+
// 隐式 keep(v0.4.4):LLM 未提及的 snapshot 记忆自动补 {action:"keep"},
|
|
212
|
+
// 避免"未覆盖即全拒"白白浪费整轮 run。设为 false 时保留旧的严格校验
|
|
213
|
+
// (未覆盖即拒绝整单)。
|
|
214
|
+
dreamImplicitKeep: z.boolean().default(true),
|
|
215
|
+
// 显式决策覆盖率下限(v0.4.4 fix):dreamImplicitKeep 开启时,LLM 输出被
|
|
216
|
+
// 截断只显式 claim 少量 snapshot 记忆(claimed.size / snapshot.size < 该阈值)
|
|
217
|
+
// → 整单拒绝,防止残缺输出被隐式 keep 洗白成 ok 后再被真实 apply。0-1,
|
|
218
|
+
// 默认 0.5(至少显式覆盖一半 snapshot)。
|
|
219
|
+
dreamMinExplicitCoverage: z.number().min(0).max(1).default(0.5),
|
|
220
|
+
// Issue #89:v0.6.9(Issue #26)的宽容路径回归。默认跳过单条非法决策
|
|
221
|
+
// (未知 id / 跨类型合并等)、应用合法子集、run 记 degraded;设 false 恢复
|
|
222
|
+
// 整单拒绝的严格模式。全局上限与覆盖率下限不受此开关影响、始终整单拒绝。
|
|
223
|
+
dreamSkipInvalid: z.boolean().default(true),
|
|
224
|
+
// 显式开启后放宽跨类型合并检查(类型边界由用户自行承担);配合
|
|
225
|
+
// dreamSkipInvalid 理解:关闭 skipInvalid 时跨类型 merge 直接整单拒绝。
|
|
226
|
+
allowCrossTypeMerge: z.boolean().default(false),
|
|
227
|
+
// Rule version for dream adjudication: when this bumps, older dream_runs
|
|
228
|
+
// degrade to historical evidence (their receipts no longer drive live
|
|
229
|
+
// decisions). Default 0 = no versioning in use yet.
|
|
230
|
+
policyEpoch: z.natural().min(0).max(1000000).default(0),
|
|
231
|
+
|
|
232
|
+
// --- API protection ------------------------------------------------------
|
|
233
|
+
// Optional shared token for the plugin's HTTP API. Empty (default) keeps
|
|
234
|
+
// the API open (DSH binds to 127.0.0.1 and has no built-in auth); when set,
|
|
235
|
+
// sensitive endpoints (vector-config, vector-reindex, and all write ops on
|
|
236
|
+
// profile/rules/commands) require `Authorization: Bearer <apiToken>` (or
|
|
237
|
+
// `X-DSH-Mneme-Token`). Read-only list/search/semantic stay open so the
|
|
238
|
+
// Web panel keeps working without the token.
|
|
239
|
+
apiToken: z.string(),
|
|
240
|
+
|
|
241
|
+
// --- semantic: local embedding provider (v0.2) --------------------------
|
|
242
|
+
// "openai" keeps the legacy external-API path (settings vector config);
|
|
243
|
+
// "local" runs an ONNX model in-process; "ollama" calls a local Ollama.
|
|
244
|
+
embedProvider: z.union([z.const("openai"), z.const("local"), z.const("ollama")]).default("openai"),
|
|
245
|
+
|
|
246
|
+
// Local ONNX embedder (transformers.js / onnxruntime).
|
|
247
|
+
localEmbedModel: z.string().default("Xenova/bge-small-zh-v1.5"),
|
|
248
|
+
localEmbedDimension: z.natural().default(512),
|
|
249
|
+
localEmbedDevice: z.union([z.const("cpu"), z.const("gpu")]).default("cpu"),
|
|
250
|
+
localEmbedBatchSize: z.natural().min(1).max(64).default(8),
|
|
251
|
+
|
|
252
|
+
// Ollama embedder.
|
|
253
|
+
ollamaBaseUrl: z.string().default("http://localhost:11434"),
|
|
254
|
+
ollamaModel: z.string().default("nomic-embed-text"),
|
|
255
|
+
|
|
256
|
+
// Model download/cache. When empty (default), models are cached under the
|
|
257
|
+
// user-level path ~/.dsh/mneme/models (resolved in local-embedder/reranker);
|
|
258
|
+
// a non-empty value is used verbatim.
|
|
259
|
+
embedModelCacheDir: z.string().default(""),
|
|
260
|
+
embedModelMirror: z.string().default("https://hf-mirror.com"),
|
|
261
|
+
|
|
262
|
+
// issue #194:模型文件下载的断点续传与重试。开启时 transformers.js 的 env.fetch 被
|
|
263
|
+
// 替换为带断点续传的实现(已收字节落盘、Range/If-Range 续传、空闲看门狗),大文件
|
|
264
|
+
// 中断后不必整份重来;关闭 = env.fetch 保持原样(线上回滚开关)。
|
|
265
|
+
resilientModelDownload: z.boolean().default(true),
|
|
266
|
+
|
|
267
|
+
// 自管运行时目录(issue #131)。空 = ~/.dsh/mneme/runtime:里面放收编或下载来的
|
|
268
|
+
// transformers + onnxruntime 闭包,插件经 src/runtime/loader.js 的三层解析加载它。
|
|
269
|
+
// 目的就是让这条重依赖不必留在宿主 profile 的依赖图里——profile 是所有插件共用的
|
|
270
|
+
// 依赖图,留在里面会让「装任何插件都要替它重走一遍这条链」。
|
|
271
|
+
runtimeDir: z.string().default(""),
|
|
272
|
+
|
|
273
|
+
// 运行时取件的两个来源(issue #131 / PR-C)。都是「克制」的默认:留空 = 不额外改变行为。
|
|
274
|
+
// - runtimeTarballDir:本地 .tgz 目录。某个包网络下不到时(例如 onnxruntime-node),
|
|
275
|
+
// 把 `npm pack <pkg>` 出来的 tgz 丢进这个目录即可离线取件;有它就优先于联网。
|
|
276
|
+
// - runtimeMirror:registry 镜像前缀,例如 https://npmmirror.com/mirrors/npm/ 。
|
|
277
|
+
// 留空则用 runtime-manifest.json 里写死的官方地址(那是随包发布的固定清单)。
|
|
278
|
+
runtimeTarballDir: z.string().default(""),
|
|
279
|
+
runtimeMirror: z.string().default(""),
|
|
280
|
+
|
|
281
|
+
// Vector search tuning.
|
|
282
|
+
vectorSearchTopK: z.natural().min(1).max(100).default(20),
|
|
283
|
+
vectorSearchThreshold: z.number().min(0).max(1).default(0.65),
|
|
284
|
+
hybridSearchVectorWeight: z.number().min(0).max(1).default(0.6),
|
|
285
|
+
hybridSearchKeywordWeight: z.number().min(0).max(1).default(0.4),
|
|
286
|
+
// Lazy auto-backfill of missing embeddings on boot (Bug2): when the vector
|
|
287
|
+
// API is configured and rows still lack an embedding, the index is rebuilt
|
|
288
|
+
// in the background after a short delay, rate-limited in batches. On by
|
|
289
|
+
// default; set false to keep the backfill manual only.
|
|
290
|
+
autoReindexOnBoot: z.boolean().default(true),
|
|
291
|
+
// Semantic-first injection (Bug4): when enabled, injectCandidates with a
|
|
292
|
+
// non-empty query recalls via the vector index first and falls back to the
|
|
293
|
+
// rule-based pick to fill/dedupe. Empty query / no vector → legacy behavior.
|
|
294
|
+
hybridInject: z.boolean().default(true),
|
|
295
|
+
|
|
296
|
+
// --- recall optimization (v0.5.0) ----------------------------------------
|
|
297
|
+
// BM25 third recall path beside vector + LIKE keyword (1.1): per-token IDF
|
|
298
|
+
// scoring recalls rows whose query terms are scattered — identifiers, code
|
|
299
|
+
// fragments, mixed CJK/ASCII — where substring LIKE cannot match.
|
|
300
|
+
bm25SearchEnabled: z.boolean().default(true),
|
|
301
|
+
// Query-aware vector cutoff (1.2) replacing the fixed 0.65: entity:/attr:
|
|
302
|
+
// prefixes loosen to 0.5, short queries tighten to 0.7, long queries loosen
|
|
303
|
+
// to 0.6, and a decisive top-1/top-5 score gap loosens to 0.5 so the tail
|
|
304
|
+
// still reaches the reranker. Off = legacy fixed threshold behavior.
|
|
305
|
+
adaptiveThresholdEnabled: z.boolean().default(true),
|
|
306
|
+
// Session-scoped hot memory (1.3): the latest N dialogue rounds rendered
|
|
307
|
+
// ahead of the long-term recall block — short-term context that never
|
|
308
|
+
// enters the memory store.
|
|
309
|
+
hotMemoryEnabled: z.boolean().default(true),
|
|
310
|
+
hotMemoryRounds: z.natural().min(1).max(50).default(5),
|
|
311
|
+
hotMemoryMaxTokens: z.natural().min(200).max(32000).default(2000),
|
|
312
|
+
// Topic-ranked injection (2.2): when a query vector is available the whole
|
|
313
|
+
// injection candidate list is re-ordered by similarity to the current
|
|
314
|
+
// query instead of keeping the rule-based order.
|
|
315
|
+
selectiveInjectEnabled: z.boolean().default(true),
|
|
316
|
+
// Search-time semantic dedup (2.3): greedy pass over the merged candidate
|
|
317
|
+
// list dropping rows whose embedding cosine-similarity to an already-kept
|
|
318
|
+
// row exceeds the threshold — duplicates are filtered at recall time
|
|
319
|
+
// instead of waiting for a dream consolidation. Opt-in aggressive mode:
|
|
320
|
+
// small embedding models can collapse legitimately distinct rows, so the
|
|
321
|
+
// default keeps every recalled row.
|
|
322
|
+
searchSemanticDedup: z.boolean().default(false),
|
|
323
|
+
searchSemanticDedupThreshold: z.number().min(0.5).max(1).default(0.95),
|
|
324
|
+
|
|
325
|
+
// Recall fusion recipe (plan #1): how the keyword/vector/BM25 ranked lists
|
|
326
|
+
// are combined into the final ranking. `blend` (default) is the legacy
|
|
327
|
+
// behavior — weighted sum for vector/hybrid, union backfill for auto —
|
|
328
|
+
// unchanged. `rrf` (Reciprocal Rank Fusion) and `minmax` (min-max normalized
|
|
329
|
+
// weighted sum) are rank/scale-aware recipes that fix the unit mismatch the
|
|
330
|
+
// issue describes (raw cosine vs keyword score vs normalized IDF are added
|
|
331
|
+
// directly). Off by default so existing behavior holds exactly.
|
|
332
|
+
recallFusion: z.union([z.const("blend"), z.const("rrf"), z.const("minmax")]).default("blend"),
|
|
333
|
+
// Attach a `signals` object { keyword, vector, bm25, final } to each search
|
|
334
|
+
// result for transparency/debugging (plan #2). Default off; when on it only
|
|
335
|
+
// decorates the returned rows, never changes the ranking.
|
|
336
|
+
signalTransparency: z.boolean().default(false),
|
|
337
|
+
|
|
338
|
+
// --- semantic: rerank layer (v0.2) --------------------------------------
|
|
339
|
+
// Opt-in by default (item ⑥): the local cross-encoder pulls in onnxruntime
|
|
340
|
+
// (transformers.js) at init, so a bare install must not load it. Only an
|
|
341
|
+
// explicit rerankEnabled=true + rerankProvider="local" constructs LocalReranker.
|
|
342
|
+
rerankEnabled: z.boolean().default(false),
|
|
343
|
+
rerankProvider: z.union([z.const("local"), z.const("none")]).default("none"),
|
|
344
|
+
rerankModel: z.string().default("Xenova/bge-reranker-base"),
|
|
345
|
+
rerankBatchSize: z.natural().min(1).max(64).default(8),
|
|
346
|
+
rerankMaxCandidates: z.natural().min(5).max(100).default(30),
|
|
347
|
+
rerankScoreThreshold: z.number().min(0).max(1).default(0.1),
|
|
348
|
+
// #188:量化档,与嵌入层的 useDtype 同语义(q8 = model_quantized.onnx,约为
|
|
349
|
+
// fp32 体积的 1/4)。此前重排层不传 dtype,即使缓存里已有量化文件也会去下载
|
|
350
|
+
// 1GB 级的 model.onnx。非法值由 transformers 在 init 时抛出 → 重排降级并告警。
|
|
351
|
+
rerankDtype: z.string().default("q8"),
|
|
352
|
+
|
|
353
|
+
// --- reflection: update decision + failure tracking (v0.2.1) ------------
|
|
354
|
+
reflectionUpdateEnabled: z.boolean().default(true),
|
|
355
|
+
reflectionFailureTracking: z.boolean().default(true),
|
|
356
|
+
reflectionUpdateMaxPerRun: z.natural().min(0).max(5).default(2),
|
|
357
|
+
reflectionUpdateMinAgeHours: z.natural().min(0).max(168).default(24),
|
|
358
|
+
|
|
359
|
+
// --- conflict freeze: manual review for conflicting memories (v0.2.1) ---
|
|
360
|
+
// Opt-in by default: when true, conflicting memories are not auto-merged
|
|
361
|
+
// and are marked as pending manual review instead.
|
|
362
|
+
conflictFreezeEnabled: z.boolean().default(false),
|
|
363
|
+
// Maximum number of frozen conflicts to keep pending for manual review.
|
|
364
|
+
conflictFreezeMaxPending: z.natural().min(1).max(1000).default(100),
|
|
365
|
+
|
|
366
|
+
// --- entity gene (v0.3.0) -----------------------------------------------
|
|
367
|
+
// Opt-in: when false (default) nothing in the pipeline extracts entities.
|
|
368
|
+
// The storage layer (entities/entity_attrs/entity_relations tables + CRUD)
|
|
369
|
+
// is always available regardless of this flag.
|
|
370
|
+
entityExtractionEnabled: z.boolean().default(false),
|
|
371
|
+
// Optional provider override for entity extraction; empty = use the caller's
|
|
372
|
+
// default provider/model. Combined with entityExtractionModel — provider
|
|
373
|
+
// without model (or vice versa) falls through to the caller default.
|
|
374
|
+
entityExtractionProvider: z.string().default(""),
|
|
375
|
+
// Optional model override for entity extraction; empty = use the caller's
|
|
376
|
+
// default provider/model.
|
|
377
|
+
entityExtractionModel: z.string().default(""),
|
|
378
|
+
// Reasoning effort for entity extraction (issue #109), mirrors
|
|
379
|
+
// dreamReasoningEffort pass-through: 'none' omits the field / provider
|
|
380
|
+
// default; off/low/medium/high passed through. A provider that rejects the
|
|
381
|
+
// effort retries once without it, so opting in is safe to experiment with.
|
|
382
|
+
entityExtractionReasoning: z.union([
|
|
383
|
+
z.const("low"),
|
|
384
|
+
z.const("medium"),
|
|
385
|
+
z.const("high"),
|
|
386
|
+
z.const("none")
|
|
387
|
+
]).default("none"),
|
|
388
|
+
// Cap on entities per extraction pass and attributes per entity.
|
|
389
|
+
entityExtractionMaxEntities: z.natural().min(1).max(20).default(10),
|
|
390
|
+
entityExtractionMaxAttrs: z.natural().min(1).max(50).default(20),
|
|
391
|
+
// Prefix/semantic search over entity names (used by recall).
|
|
392
|
+
entitySearchEnabled: z.boolean().default(true),
|
|
393
|
+
// 图召回轴(issue #219):查询文本命中实体名时,把该实体挂联的记忆并入
|
|
394
|
+
// 检索融合池(与 BM25 同级的确认/回填信号)。默认关=检索行为与 #219 前
|
|
395
|
+
// 逐字节一致;走 feature_flags 面板可启停,lightMode 强制关闭。
|
|
396
|
+
entityRecallEnabled: z.boolean().default(false),
|
|
397
|
+
|
|
398
|
+
// --- sleep mode: idle-triggered deep maintenance (v0.4.0) ---------------
|
|
399
|
+
// Opt-in, off by default. Unlike autoDream (threshold-triggered, lightweight)
|
|
400
|
+
// sleep fires when the store has been quiet for sleepIdleMinutes and deep-
|
|
401
|
+
// maintains the whole library: conflict resolution, archival demotion,
|
|
402
|
+
// pattern discovery and entity relation completion. Abortable on user
|
|
403
|
+
// activity, audited into dream_runs (run_type='sleep'), and serialized with
|
|
404
|
+
// autoDream so the two never overlap.
|
|
405
|
+
sleepModeEnabled: z.boolean().default(false),
|
|
406
|
+
// Quiet window before a cycle fires (minutes).
|
|
407
|
+
sleepIdleMinutes: z.natural().min(1).max(60).default(5),
|
|
408
|
+
// Minimum gap between two sleep runs (hours) — a second idle window within
|
|
409
|
+
// this interval does not retrigger.
|
|
410
|
+
sleepMinIntervalHours: z.natural().min(1).max(168).default(8),
|
|
411
|
+
// Conflict adjudication strictness:
|
|
412
|
+
// gentle only high-confidence conflicts (threshold 0.92) are resolved
|
|
413
|
+
// normal standard dream-level (threshold 0.85)
|
|
414
|
+
// aggressive low-confidence pairs are also adjudicated (threshold 0.75)
|
|
415
|
+
sleepConflictStrictness: z.union([
|
|
416
|
+
z.const("gentle"),
|
|
417
|
+
z.const("normal"),
|
|
418
|
+
z.const("aggressive")
|
|
419
|
+
]).default("normal"),
|
|
420
|
+
// Issue #126:冲突阶段的动作集。"conflict"(默认 = 现状)只用 conflict/keep——
|
|
421
|
+
// 后台自动流程不静默扩张行为;"full" 开放六分支(merge / update / supersede /
|
|
422
|
+
// differentiate / conflict / keep),互补型与演进型重复因此有了正确出口,不再
|
|
423
|
+
// 被迫"输赢化"(实测抽样 10 对里 2 对属演进型/互补型,用 conflict 处理会丢信息)。
|
|
424
|
+
sleepActionSet: z.union([
|
|
425
|
+
z.const("conflict"),
|
|
426
|
+
z.const("full")
|
|
427
|
+
]).default("conflict"),
|
|
428
|
+
// Archival demotion tiering (days since last access):
|
|
429
|
+
// >= sleepArchiveDays → shrink to summary, full body kept in _full_content
|
|
430
|
+
// >= sleepCompressDays → archived outright (entity relations preserved)
|
|
431
|
+
sleepArchiveDays: z.natural().min(7).max(365).default(30),
|
|
432
|
+
sleepCompressDays: z.natural().min(7).max(365).default(90),
|
|
433
|
+
// Pattern discovery scan window (most recent memories to scan).
|
|
434
|
+
sleepPatternMinMemories: z.natural().min(10).max(1000).default(100),
|
|
435
|
+
// How far back pattern discovery considers entity attr changes (days).
|
|
436
|
+
sleepPatternLookbackDays: z.natural().min(1).max(90).default(30),
|
|
437
|
+
// Max pattern memories minted per run (0 = disabled).
|
|
438
|
+
sleepMaxPatternPerRun: z.natural().min(0).max(10).default(3),
|
|
439
|
+
// Optional LLM route override for sleep's bulk passes (empty = use dream
|
|
440
|
+
// route / agent default model).
|
|
441
|
+
sleepProvider: z.string().default("").description("sleep 深维护专用模型服务商,留空用巩固模型或当前模型。"),
|
|
442
|
+
sleepModel: z.string().default("").description("sleep 深维护专用模型,留空用巩固模型或当前模型;建议同巩固模型选非思考模型。"),
|
|
443
|
+
// Pass-through reasoning effort for sleep's LLM passes, same semantics as
|
|
444
|
+
// dreamReasoningEffort (Issue #135 建议 4/5): unset resolves to the lowest
|
|
445
|
+
// effort the model declares; explicit 'none' omits the field; off/low/
|
|
446
|
+
// medium/high are forwarded verbatim.
|
|
447
|
+
sleepReasoningEffort: z.union([
|
|
448
|
+
z.const("off"),
|
|
449
|
+
z.const("low"),
|
|
450
|
+
z.const("medium"),
|
|
451
|
+
z.const("high"),
|
|
452
|
+
z.const("none")
|
|
453
|
+
]).description("同 dreamReasoningEffort:sleep 各阶段 LLM 的推理档位,未配置 = 自动取模型支持的最低档;显式 'none' = 不发送字段、用服务商自带默认。"),
|
|
454
|
+
// Issue #257:sleep 冲突/模式两阶段的输出预算(原硬编码 2048)。实测默认档
|
|
455
|
+
// 每对裁决约 90 token、24 对 2097——2048 恰好压在边界(53 次运行 48 败);
|
|
456
|
+
// full 档六分支实测约 290 token/对、24 对 6967,2048 必然截断。默认 8192
|
|
457
|
+
// 覆盖实测峰值(候选对按「每记忆至多一对」去重,饱和在 ~25 对、不随库无限
|
|
458
|
+
// 增长);流式计费按实际用量,不按上限。
|
|
459
|
+
sleepMaxTokens: z.natural().min(256).max(131072).default(8192).description("sleep 冲突消解与模式发现阶段的 LLM 输出预算上限(token)。原为硬编码 2048,sleepActionSet=full 实测需约 7000 导致裁决被截断而整轮失败;流式计费按实际用量,调大不增加成本。"),
|
|
460
|
+
|
|
461
|
+
// --- epistemic trust: memory source credibility (v0.4.5) -----------------
|
|
462
|
+
// Distinguish memories by source: observation (measured / witnessed),
|
|
463
|
+
// subjective (opinion / guess) and inferred (derived from other evidence).
|
|
464
|
+
// Opt-in by default: when false (default) retrieval ranking, injection
|
|
465
|
+
// marking and dream merge/conflict keepSource are untouched and
|
|
466
|
+
// epistemic_status stays inert data (still written + inferred on save, just
|
|
467
|
+
// never used to influence behavior).
|
|
468
|
+
trustEpistemicWeighting: z.boolean().default(false),
|
|
469
|
+
|
|
470
|
+
// --- memory quality filter (Bug7) ------------------------------------------
|
|
471
|
+
// Heuristic gate on what deserves the injection/recall surface. When enabled,
|
|
472
|
+
// saveWithDedupe scores each new memory after dedupe and before write:
|
|
473
|
+
// score >= degradeThreshold (60) → stored normally
|
|
474
|
+
// archiveThreshold (30) <= score < 60 → quality_score persisted and the
|
|
475
|
+
// injection sort re-ranks by importance * quality_score/100 (degraded)
|
|
476
|
+
// score < 30 → archived + tagged low_quality (still explicitly searchable)
|
|
477
|
+
// Meta-memory markers, near-duplicates and repetitive filler lose points.
|
|
478
|
+
memoryQualityFilter: z.object({
|
|
479
|
+
enabled: z.boolean().default(true),
|
|
480
|
+
archiveThreshold: z.natural().min(1).max(100).default(30),
|
|
481
|
+
degradeThreshold: z.natural().min(1).max(100).default(60),
|
|
482
|
+
minContentLength: z.natural().min(1).max(1000).default(10),
|
|
483
|
+
// Issue #135 附属发现 1:importance ≥ 该值的记忆不参与静默自动归档——评分
|
|
484
|
+
// 与信号标签照常写入(可观测)、注入排序照常降权,但 setArchived 跳过。
|
|
485
|
+
// 报告实测 150 条低分归档里 128 条 importance ≥ 4(51 条 = 5)。设 1 = 全部
|
|
486
|
+
// 豁免(等效关闭自动归档),设 5 = 仅最重要的豁免。
|
|
487
|
+
exemptImportance: z.natural().min(1).max(5).default(4)
|
|
488
|
+
}).default({}),
|
|
489
|
+
|
|
490
|
+
// --- LLM audit trail (Bug8) ------------------------------------------------
|
|
491
|
+
// Records every background LLM call (autoDream consolidation + summary,
|
|
492
|
+
// autoSummarize compression) into llm_audit_logs: tokens, duration, status
|
|
493
|
+
// and which trigger produced it. Failures are recorded as status=error and
|
|
494
|
+
// never block the feature. retentionDays bounds the table: older rows are
|
|
495
|
+
// purged on boot.
|
|
496
|
+
llmAudit: z.object({
|
|
497
|
+
enabled: z.boolean().default(true),
|
|
498
|
+
retentionDays: z.natural().min(1).max(3650).default(90)
|
|
499
|
+
}).default({}),
|
|
500
|
+
|
|
501
|
+
// --- recall evaluation: test-result storage (v0.4.6, 方案 B) --------------
|
|
502
|
+
// Separate retrieval evaluation snapshots from the production recall audit.
|
|
503
|
+
// When false (default) evaluateRetrieval still computes precision/recall/mrr
|
|
504
|
+
// and returns them to the caller, but writes nothing to recall_evals — the
|
|
505
|
+
// eval table only grows when the operator opts in. Production searchMemories
|
|
506
|
+
// audits to recall_runs and NEVER touches recall_evals, regardless of this
|
|
507
|
+
// flag (production isolation is unconditional).
|
|
508
|
+
evalPersistTestResults: z.boolean().default(false),
|
|
509
|
+
|
|
510
|
+
// --- standalone external API (v0.7.12) ------------------------------------
|
|
511
|
+
// A plain node:http server for ecosystem integrations that cannot reach the
|
|
512
|
+
// DSH-internal webServer. Disabled by default; when enabled the Bearer token
|
|
513
|
+
// is persisted in the settings kv ("external_api"), auto-generated on first
|
|
514
|
+
// boot. Bind host: keep the loopback default — moving it to a non-loopback
|
|
515
|
+
// address exposes the whole memory store to the network and is the
|
|
516
|
+
// operator's responsibility.
|
|
517
|
+
externalApiEnabled: z.boolean().default(false),
|
|
518
|
+
externalApiPort: z.natural().default(8790),
|
|
519
|
+
externalApiHost: z.string().default("127.0.0.1"),
|
|
520
|
+
|
|
521
|
+
// --- light mode preset (v0.7.12) -------------------------------------------
|
|
522
|
+
// One switch for low-resource setups: turns off every background/semantic
|
|
523
|
+
// heavy path (dream consolidation, entity extraction, vector pipeline,
|
|
524
|
+
// reranker, BM25, semantic dedup / selective inject, sleep mode) while
|
|
525
|
+
// keeping the core loop (autoInject, autoSummarize, hot memory, quality
|
|
526
|
+
// filter, keyword search). Applied by applyLightModePreset before the config
|
|
527
|
+
// reaches any service; a persisted panel_mode="light" (settings kv) counts
|
|
528
|
+
// as lightMode=true too and wins over the bundle config.
|
|
529
|
+
lightMode: z.boolean().default(false),
|
|
530
|
+
|
|
531
|
+
// --- heat: v0.7.0 self-evolution (heat + interest drift) ----------------
|
|
532
|
+
// 总开关,默认关(v0.7.12+ 用户已习惯无 heat 行为,默认开=全员行为变更)。
|
|
533
|
+
// 开启后:提供热度字段 / sleep 降级联合判定保护 / 前端热度投影,并只在
|
|
534
|
+
// 注入排序的优先级层内乘 heat(#218 v1;store 的 order=chrono 分页序与
|
|
535
|
+
// 召回融合序不动)。关闭则跳过所有 heat 计算与热度触达,注入排序乘数
|
|
536
|
+
// 恒 1,sleep 降级退回纯时间分层。
|
|
537
|
+
// 也走 feature_flags(FEATURE_FLAG_BOOLEANS 白名单),面板可启停=线上回滚开关。
|
|
538
|
+
heatEnabled: z.boolean().default(false),
|
|
539
|
+
// 广义指数形状参数 β(heat = exp(-λ·Δt^β),issue #218 拍板):β=1 纯指数。
|
|
540
|
+
// 快慢以 Δt>1 小时为准——β<1 衰减更慢(亚线性长尾)、β>1 更快(超线性);
|
|
541
|
+
// 0<Δt<1 的首小时内方向相反(Δt^β 随 β 增大而变小)。专家调优项,不进面板白名单。
|
|
542
|
+
heatGlobalBeta: z.number().min(0.5).max(2).default(1.0),
|
|
543
|
+
// per-type 衰减因子 λ;λ=0 的类型免疫(热度恒 1.0,sleep 永不降级)。
|
|
544
|
+
// 未知类型走默认 0.002。dict 的键为 type 字符串、值为数字 λ。
|
|
545
|
+
heatTypeDecay: z.dict(z.number(), z.string()).default({ ...TYPE_DECAY_DEFAULTS }),
|
|
546
|
+
// sleep 降级联合判定的热度下限:heat < 该值 且 importance<5 才允许降级。
|
|
547
|
+
sleepHeatThreshold: z.number().min(0).max(1).default(0.05),
|
|
548
|
+
// recordRecall 默认值(recall_runs 记录默认开;显式传 false 的调用方不受影响)。
|
|
549
|
+
recallRecordDefault: z.boolean().default(true),
|
|
550
|
+
// recall_runs 滚动清理保留天数。
|
|
551
|
+
recallRetentionDays: z.natural().min(1).max(3650).default(90),
|
|
552
|
+
|
|
553
|
+
// --- tool exposure: 慢模型/轻量模型的工具往返节流(v0.8.5)----------------
|
|
554
|
+
// 跨会话记忆已由 inject.js 每轮自动注入系统提示词,memory_search 只用于
|
|
555
|
+
// 「注入里没有、需要深挖」的补充检索;memory_archive 是隐藏/恢复条目的整理
|
|
556
|
+
// 操作,正常会话里很少需要。轻量模型对「何时该用工具」判断弱,容易每轮
|
|
557
|
+
// 顺手调一遍——每次工具调用都是一次串行往返(生成参数→执行→回填→再生成),
|
|
558
|
+
// 在慢模型上会被放大成明显卡顿。这两个开关允许直接隐藏对应工具(默认全
|
|
559
|
+
// 开=行为不变),隐藏后模型根本看不到它,也就不会调。也走 feature_flags
|
|
560
|
+
// 白名单,面板可启停=线上回滚开关。
|
|
561
|
+
disableMemorySearch: z.boolean().default(false),
|
|
562
|
+
disableMemoryArchive: z.boolean().default(false),
|
|
563
|
+
|
|
564
|
+
// --- scope: v0.8.0 A1 存储层(issue #17)--------------------------------
|
|
565
|
+
// 总开关默认关:关闭时写入不标注 scope、去重维持 (type, title) 现状,行为
|
|
566
|
+
// 逐字节不变。开启后 memory_save 写入 agent_scope(session header 的
|
|
567
|
+
// agentPreset)与 workspace_scope(registry 反查 canonical path,header.cwd
|
|
568
|
+
// 兜底,取不到 NULL——解析绝不阻塞写入),去重键扩展为 (type, title,
|
|
569
|
+
// agent_scope, workspace_scope, sensitivity)。检索侧加权/过滤在 A2/A3 落地。
|
|
570
|
+
// 也走 feature_flags(FEATURE_FLAG_BOOLEANS 白名单),面板可启停=线上回滚开关。
|
|
571
|
+
scopeEnabled: z.boolean().default(false),
|
|
572
|
+
// strictScope(A3):硬过滤模式。关闭=A2 软隔离(他 scope 降权保留可见);
|
|
573
|
+
// 开启后检索/注入/list/get 按 issue #17 四象限可见性公式硬过滤——带他 scope
|
|
574
|
+
// 的记忆完全不可见,未标注(NULL)恒可见;当前会话某维度解析不到时该维度
|
|
575
|
+
// 带标注的记忆一律不可见(fail-closed:身份不明只见全局)。依赖 scopeEnabled
|
|
576
|
+
// 打开才有意义(没有写入标注就无可过滤维度),但独立成键:可先开标注积累
|
|
577
|
+
// 数据、观察 A2 加权质量后再切硬过滤。
|
|
578
|
+
strictScope: z.boolean().default(false),
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
// Fields forced to false by the light-mode preset. Everything not listed here
|
|
582
|
+
// (autoInject, autoSummarize, hotMemory*, memoryQualityFilter, dream
|
|
583
|
+
// thresholds/delays, ...) is left untouched — those are the core loop.
|
|
584
|
+
const LIGHT_MODE_OFF = [
|
|
585
|
+
"entityExtractionEnabled",
|
|
586
|
+
"autoDream",
|
|
587
|
+
"sleepModeEnabled",
|
|
588
|
+
"rerankEnabled",
|
|
589
|
+
"autoReindexOnBoot",
|
|
590
|
+
"hybridInject",
|
|
591
|
+
"searchSemanticDedup",
|
|
592
|
+
"selectiveInjectEnabled",
|
|
593
|
+
"bm25SearchEnabled",
|
|
594
|
+
// 轻量模式不开图召回轴(#219,依赖实体抽取产出;抽取本身已被关掉)。
|
|
595
|
+
"entityRecallEnabled",
|
|
596
|
+
// 轻量模式不开叙述条(额外 LLM 调用;#164 对齐,opt-in)。
|
|
597
|
+
"dreamNarrativeEnabled",
|
|
598
|
+
// 轻量模式不开 document 指针行(#230,opt-in:注册/注入/检索增强全随闸)。
|
|
599
|
+
"documentMemoryEnabled",
|
|
600
|
+
// 轻量模式不开热计算(heat 属于重型增强;关掉后 sleep 降级也退回纯时间分层)。
|
|
601
|
+
"heatEnabled"
|
|
602
|
+
];
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Apply the light-mode preset to a resolved config object (pure function,
|
|
606
|
+
* exported for tests). When cfg.lightMode is not exactly true the config is
|
|
607
|
+
* returned unchanged; otherwise a shallow copy carries false for every heavy
|
|
608
|
+
* feature. Idempotent and side-effect free.
|
|
609
|
+
*/
|
|
610
|
+
export function applyLightModePreset(cfg) {
|
|
611
|
+
if (cfg?.lightMode !== true) return cfg;
|
|
612
|
+
const preset = { ...cfg, lightMode: true };
|
|
613
|
+
for (const key of LIGHT_MODE_OFF) preset[key] = false;
|
|
614
|
+
return preset;
|
|
615
|
+
}
|