dsh-layered-memory 0.8.8 → 0.8.9

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.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * 默认数据目录:$DSH_HOME/memory(用官方 dshHomePath 解析,DSH_HOME 缺省 ~/.dsh)。
5
5
  */
6
6
  import Schema from '@deepseek-ai/schemastery';
7
- import type { StaticFallbackEntry } from './contract.js';
7
+ import type { LayerRouteKey, StaticFallbackEntry } from './contract.js';
8
8
  import type { ExtractMode } from './types.js';
9
9
  /**
10
10
  * 蒸馏思考档位全词汇表(唯一事实源):'' = 自动(模型默认档 → high),
@@ -103,6 +103,14 @@ export interface MemoryConfig {
103
103
  * 旧档位键 reasoningEffort 的整体接管——含给条目盖章——仍对存量值生效);
104
104
  * 空数组(缺省)= 单路由行为不变。 */
105
105
  fallbacks?: StaticFallbackEntry[];
106
+ /** 按层静态路由链(#34):层键 l1/l2/l3 各一条完整链(条目形状同 fallbacks;
107
+ * 头行必须 provider+model 双显式)。非空即完整替换该层解析(该层主路由与回退都
108
+ * 归层链管,全局链对该层不参与);空/缺省 = 该层跟随全局解析。被运行时层链
109
+ * (设置页 distillLayerChains)压过;pin 不废静态层链(同为部署配置,同回退链先例)。 */
110
+ layerRoutes?: Partial<Record<LayerRouteKey, StaticFallbackEntry[]>>;
111
+ /** 运行时层链(effectiveCfg 从设置页 distillLayerChains 注入,层内第一优先级);
112
+ * 非静态 schema——与 primaryEffort/budgets 同类:运行时偏好,无部署上限语义。 */
113
+ layerChainsRuntime?: Partial<Record<LayerRouteKey, StaticFallbackEntry[]>>;
106
114
  /** 单次蒸馏调用的输出 token 上限(推理模型的 reasoning 与正文共享该预算)。 */
107
115
  maxTokens: number;
108
116
  /** 蒸馏调用的思考档位;空串不传(跟随模型默认)。 */
@@ -235,6 +243,63 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<{
235
243
  model: Schema<string, string>;
236
244
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
237
245
  }>[]>;
246
+ layerRoutes: Schema<Schemastery.ObjectS<{
247
+ l1: Schema<({
248
+ provider?: string | null | undefined;
249
+ model?: string | null | undefined;
250
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
251
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
252
+ provider: Schema<string, string>;
253
+ model: Schema<string, string>;
254
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
255
+ }>[]>;
256
+ l2: Schema<({
257
+ provider?: string | null | undefined;
258
+ model?: string | null | undefined;
259
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
260
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
261
+ provider: Schema<string, string>;
262
+ model: Schema<string, string>;
263
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
264
+ }>[]>;
265
+ l3: Schema<({
266
+ provider?: string | null | undefined;
267
+ model?: string | null | undefined;
268
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
269
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
270
+ provider: Schema<string, string>;
271
+ model: Schema<string, string>;
272
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
273
+ }>[]>;
274
+ }>, Schemastery.ObjectT<{
275
+ l1: Schema<({
276
+ provider?: string | null | undefined;
277
+ model?: string | null | undefined;
278
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
279
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
280
+ provider: Schema<string, string>;
281
+ model: Schema<string, string>;
282
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
283
+ }>[]>;
284
+ l2: Schema<({
285
+ provider?: string | null | undefined;
286
+ model?: string | null | undefined;
287
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
288
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
289
+ provider: Schema<string, string>;
290
+ model: Schema<string, string>;
291
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
292
+ }>[]>;
293
+ l3: Schema<({
294
+ provider?: string | null | undefined;
295
+ model?: string | null | undefined;
296
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
297
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
298
+ provider: Schema<string, string>;
299
+ model: Schema<string, string>;
300
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
301
+ }>[]>;
302
+ }>>;
238
303
  maxTokens: Schema<number, number>;
239
304
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
240
305
  temperature: Schema<number, number>;
@@ -252,6 +317,63 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<{
252
317
  model: Schema<string, string>;
253
318
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
254
319
  }>[]>;
320
+ layerRoutes: Schema<Schemastery.ObjectS<{
321
+ l1: Schema<({
322
+ provider?: string | null | undefined;
323
+ model?: string | null | undefined;
324
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
325
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
326
+ provider: Schema<string, string>;
327
+ model: Schema<string, string>;
328
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
329
+ }>[]>;
330
+ l2: Schema<({
331
+ provider?: string | null | undefined;
332
+ model?: string | null | undefined;
333
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
334
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
335
+ provider: Schema<string, string>;
336
+ model: Schema<string, string>;
337
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
338
+ }>[]>;
339
+ l3: Schema<({
340
+ provider?: string | null | undefined;
341
+ model?: string | null | undefined;
342
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
343
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
344
+ provider: Schema<string, string>;
345
+ model: Schema<string, string>;
346
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
347
+ }>[]>;
348
+ }>, Schemastery.ObjectT<{
349
+ l1: Schema<({
350
+ provider?: string | null | undefined;
351
+ model?: string | null | undefined;
352
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
353
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
354
+ provider: Schema<string, string>;
355
+ model: Schema<string, string>;
356
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
357
+ }>[]>;
358
+ l2: Schema<({
359
+ provider?: string | null | undefined;
360
+ model?: string | null | undefined;
361
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
362
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
363
+ provider: Schema<string, string>;
364
+ model: Schema<string, string>;
365
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
366
+ }>[]>;
367
+ l3: Schema<({
368
+ provider?: string | null | undefined;
369
+ model?: string | null | undefined;
370
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
371
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
372
+ provider: Schema<string, string>;
373
+ model: Schema<string, string>;
374
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
375
+ }>[]>;
376
+ }>>;
255
377
  maxTokens: Schema<number, number>;
256
378
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
257
379
  temperature: Schema<number, number>;
@@ -366,6 +488,63 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<{
366
488
  model: Schema<string, string>;
367
489
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
368
490
  }>[]>;
491
+ layerRoutes: Schema<Schemastery.ObjectS<{
492
+ l1: Schema<({
493
+ provider?: string | null | undefined;
494
+ model?: string | null | undefined;
495
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
496
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
497
+ provider: Schema<string, string>;
498
+ model: Schema<string, string>;
499
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
500
+ }>[]>;
501
+ l2: Schema<({
502
+ provider?: string | null | undefined;
503
+ model?: string | null | undefined;
504
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
505
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
506
+ provider: Schema<string, string>;
507
+ model: Schema<string, string>;
508
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
509
+ }>[]>;
510
+ l3: Schema<({
511
+ provider?: string | null | undefined;
512
+ model?: string | null | undefined;
513
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
514
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
515
+ provider: Schema<string, string>;
516
+ model: Schema<string, string>;
517
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
518
+ }>[]>;
519
+ }>, Schemastery.ObjectT<{
520
+ l1: Schema<({
521
+ provider?: string | null | undefined;
522
+ model?: string | null | undefined;
523
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
524
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
525
+ provider: Schema<string, string>;
526
+ model: Schema<string, string>;
527
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
528
+ }>[]>;
529
+ l2: Schema<({
530
+ provider?: string | null | undefined;
531
+ model?: string | null | undefined;
532
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
533
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
534
+ provider: Schema<string, string>;
535
+ model: Schema<string, string>;
536
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
537
+ }>[]>;
538
+ l3: Schema<({
539
+ provider?: string | null | undefined;
540
+ model?: string | null | undefined;
541
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
542
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
543
+ provider: Schema<string, string>;
544
+ model: Schema<string, string>;
545
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
546
+ }>[]>;
547
+ }>>;
369
548
  maxTokens: Schema<number, number>;
370
549
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
371
550
  temperature: Schema<number, number>;
@@ -383,6 +562,63 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<{
383
562
  model: Schema<string, string>;
384
563
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
385
564
  }>[]>;
565
+ layerRoutes: Schema<Schemastery.ObjectS<{
566
+ l1: Schema<({
567
+ provider?: string | null | undefined;
568
+ model?: string | null | undefined;
569
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
570
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
571
+ provider: Schema<string, string>;
572
+ model: Schema<string, string>;
573
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
574
+ }>[]>;
575
+ l2: Schema<({
576
+ provider?: string | null | undefined;
577
+ model?: string | null | undefined;
578
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
579
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
580
+ provider: Schema<string, string>;
581
+ model: Schema<string, string>;
582
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
583
+ }>[]>;
584
+ l3: Schema<({
585
+ provider?: string | null | undefined;
586
+ model?: string | null | undefined;
587
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
588
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
589
+ provider: Schema<string, string>;
590
+ model: Schema<string, string>;
591
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
592
+ }>[]>;
593
+ }>, Schemastery.ObjectT<{
594
+ l1: Schema<({
595
+ provider?: string | null | undefined;
596
+ model?: string | null | undefined;
597
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
598
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
599
+ provider: Schema<string, string>;
600
+ model: Schema<string, string>;
601
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
602
+ }>[]>;
603
+ l2: Schema<({
604
+ provider?: string | null | undefined;
605
+ model?: string | null | undefined;
606
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
607
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
608
+ provider: Schema<string, string>;
609
+ model: Schema<string, string>;
610
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
611
+ }>[]>;
612
+ l3: Schema<({
613
+ provider?: string | null | undefined;
614
+ model?: string | null | undefined;
615
+ reasoningEffort?: "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | null | undefined;
616
+ } & import("@deepseek-ai/cosmokit").Dict)[], Schemastery.ObjectT<{
617
+ provider: Schema<string, string>;
618
+ model: Schema<string, string>;
619
+ reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
620
+ }>[]>;
621
+ }>>;
386
622
  maxTokens: Schema<number, number>;
387
623
  reasoningEffort: Schema<"" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", "" | "off" | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
388
624
  temperature: Schema<number, number>;
package/dist/config.js CHANGED
@@ -76,6 +76,25 @@ export const memorySchema = Schema.object({
76
76
  model: Schema.string().default(''),
77
77
  reasoningEffort: Schema.union([...EFFORT_CHOICES]).default(''),
78
78
  })).default([]),
79
+ // 按层静态路由链(#34):每层一条完整链(头行须双显式——启动侧只做形状默认,
80
+ // 语义校验(头行/去重/上限)在解析侧防御 + 设置页写入门;空数组 = 该层跟随全局)
81
+ layerRoutes: Schema.object({
82
+ l1: Schema.array(Schema.object({
83
+ provider: Schema.string().default(''),
84
+ model: Schema.string().default(''),
85
+ reasoningEffort: Schema.union([...EFFORT_CHOICES]).default(''),
86
+ })).default([]),
87
+ l2: Schema.array(Schema.object({
88
+ provider: Schema.string().default(''),
89
+ model: Schema.string().default(''),
90
+ reasoningEffort: Schema.union([...EFFORT_CHOICES]).default(''),
91
+ })).default([]),
92
+ l3: Schema.array(Schema.object({
93
+ provider: Schema.string().default(''),
94
+ model: Schema.string().default(''),
95
+ reasoningEffort: Schema.union([...EFFORT_CHOICES]).default(''),
96
+ })).default([]),
97
+ }).default({ l1: [], l2: [], l3: [] }),
79
98
  // 推理模型(如 v4-flash)的 reasoning 计入输出预算:预算不足会被思考吃光导致正文 0 字符。
80
99
  // 0.8.0 起各蒸馏层显式传分层预算(见 llm.ts LAYER_MAX_TOKENS_*),本值为未分层调用的兜底总闸
81
100
  maxTokens: Schema.number().min(1024).max(1_000_000).default(65_536),
@@ -40,6 +40,9 @@ export interface StaticFallbackEntry {
40
40
  model: string;
41
41
  reasoningEffort?: string;
42
42
  }
43
+ /** 按层路由的层键(#34):l1 同管 l1-extract + l1-dedup 两个调用点(与成本看板
44
+ * 按层级归并口径同源);预算键(DistillBudgetLayer)是另一套四键词表,不混用。 */
45
+ export type LayerRouteKey = 'l1' | 'l2' | 'l3';
43
46
  /** 记忆模式运行时开关(settings-get/set 的 settings 载荷)。 */
44
47
  export interface MemoryLiveSettings {
45
48
  /** 总开关:关 = 捕获/蒸馏/召回注入全停(数据保留) */
@@ -67,6 +70,10 @@ export interface MemoryLiveSettings {
67
70
  /** 输入预算运行时覆盖(字符,≈token):单次蒸馏调用的输入上限,L1 按此分块、
68
71
  * 超限截断;0 = 跟随静态配置 llm.maxInputChars。 */
69
72
  distillMaxInputChars: number;
73
+ /** 运行时按层路由链(#34):层键 l1/l2/l3 各一条完整链(条目同 DistillChainEntry);
74
+ * 非空即完整接管该层解析(压过静态 layerRoutes,层内第一优先级);空数组 = 该层
75
+ * 跟随(静态层链 → 全局解析逐级兜底)。写入经 settings-set 逐层校验(头行必须显式)。 */
76
+ distillLayerChains: Record<LayerRouteKey, DistillChainEntry[]>;
70
77
  }
71
78
  /** 单会话召回统计(悬浮卡信息区数据源;口径见 recall.ts 注释)。 */
72
79
  export interface RecallSessionStats {
@@ -87,6 +94,12 @@ export interface RecallSessionStats {
87
94
  /** 最近一次记账时间(LRU 清理依据)。 */
88
95
  updatedAt: number;
89
96
  }
97
+ /**
98
+ * 单会话记忆上下文占用(session-stats.memoryOccupancy;悬浮卡与输入栏占用指示器共用)。
99
+ * 形状与算术的唯一来源是 util/context-occupancy 的 OccupancyLedger——官方 token-meter
100
+ * 同式启发式,禁止任何一侧另写换算。null = 本会话从未注入过。
101
+ */
102
+ export type MemoryOccupancy = import('./util/context-occupancy.js').OccupancyLedger;
90
103
  /** 重建阶段。 */
91
104
  export type RebuildPhase = 'idle' | 'preparing' | 'distilling' | 'finalizing' | 'done' | 'cancelled' | 'failed';
92
105
  /** 重建状态(rebuild-status/start/cancel 端点返回值)。 */
@@ -350,6 +363,16 @@ export type SessionStatsResponse = {
350
363
  recall: {
351
364
  enabled: boolean;
352
365
  } & RecallSessionStats;
366
+ /** 记忆上下文占用账本(未注入过的会话为 null)。 */
367
+ memoryOccupancy: MemoryOccupancy | null;
368
+ /** 旧会话回填(票08):host 侧估出的双通道份额——召回按 live 会话 surface 现扫
369
+ * (null = 会话不在 store),稳定区按当前组词折算。账本存在时客户端取两者较大值。 */
370
+ occupancyBackfill: {
371
+ recallTokens: number | null;
372
+ profileTokens: number;
373
+ } | null;
374
+ /** 主对话模型的官方声明上下文窗口(占用占比分母;null = 未声明/解析失败,UI 降级隐藏占比)。 */
375
+ contextWindowTokens: number | null;
353
376
  distill: SessionDistillView;
354
377
  l0Count: number;
355
378
  retrieval: 'hybrid' | 'vector' | 'keyword' | 'none';
@@ -397,6 +420,8 @@ export interface SettingsSetRequest {
397
420
  distill?: boolean;
398
421
  recall?: boolean;
399
422
  distillChain?: DistillChainEntry[];
423
+ /** 运行时按层路由链(#34):逐层 patch(只带要改的层;空数组 = 该层回到跟随)。 */
424
+ distillLayerChains?: Partial<Record<LayerRouteKey, DistillChainEntry[]>>;
400
425
  reasoningEffort?: EffortChoice;
401
426
  distillProvider?: string;
402
427
  distillModel?: string;
@@ -484,6 +509,16 @@ export interface EffectiveChainRoute {
484
509
  model: string;
485
510
  effort: string;
486
511
  }
512
+ /** 按层层链视图(#34 B 分段 UI 数据源):runtime = 设置页运行时层链(pinned 下不生效,
513
+ * 视图照实返回存量);static = 部署 YAML layerRoutes;effectiveChain = 该层实际链
514
+ * (层链完整替换,或跟随全局时与全局链同值);source 三态:runtime 接管 / static
515
+ * 生效 / global 跟随全局解析。 */
516
+ export interface LayerChainView {
517
+ runtime: DistillChainEntry[];
518
+ static: StaticFallbackEntry[];
519
+ effectiveChain: EffectiveChainRoute[];
520
+ source: 'runtime' | 'static' | 'global';
521
+ }
487
522
  export interface LlmProvidersResponse {
488
523
  supported: true;
489
524
  providers: Array<{
@@ -512,6 +547,8 @@ export interface LlmProvidersResponse {
512
547
  effectiveChain: EffectiveChainRoute[];
513
548
  source: 'runtime' | 'static';
514
549
  };
550
+ /** 按层层链(l1/l2/l3;l1 同管抽取+去重两个调用点)。 */
551
+ layerChains: Record<LayerRouteKey, LayerChainView>;
515
552
  }
516
553
  /** dsh-memory/llm-models */
517
554
  export interface LlmModelsRequest {
@@ -23,6 +23,7 @@ import type { PersonaStore } from '../store/persona.js';
23
23
  import type { SceneStore } from '../store/scenes.js';
24
24
  import type { SessionModeStore } from '../store/session-modes.js';
25
25
  import type { MemoryLogger } from '../types.js';
26
+ import { type OccupancyLedger } from '../util/context-occupancy.js';
26
27
  /**
27
28
  * 从会话消息构建召回查询(纯函数):末尾 N 条 + 总长截断,空输入返回空串。
28
29
  * 全史拼接会让 MATCH 表达式随会话长度线性膨胀(整会话累计二次方成本)。
@@ -44,6 +45,16 @@ export interface RecallHooks {
44
45
  invalidateProfile(): void;
45
46
  /** 会话召回统计只读视图(未发生过检索的会话返回 undefined)。 */
46
47
  stats(sessionId: string): RecallSessionStats | undefined;
48
+ /** 记忆占用账本只读出口:内存优先,miss 时从流水复生(重启后历史会话);从未注入返回 null。 */
49
+ occupancy(sessionId: string): OccupancyLedger | null;
50
+ /**
51
+ * 稳定区份额估算(票08 旧会话回填):按当前画像/导航/指南组词折算 token,
52
+ * 纯读不记账——旧会话系统提示里"现在大约坐着多少稳定区"的最佳可得估计。
53
+ */
54
+ estimateProfileTokens(agentId: string): number;
55
+ /** 召回份额回填(票08):live 会话 surface 现扫本插件注入,miss 时读盘上日志兜底;
56
+ * 均不可得返回 null。 */
57
+ estimateRecallTokens(sessionId: string): Promise<number | null>;
47
58
  }
48
59
  export declare function registerRecall(ctx: Context, cfg: MemoryConfig, stores: {
49
60
  l1: L1Store;