dsh-prime-memory 0.20.0-beta.9 → 0.20.2

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
@@ -76,22 +76,6 @@ export interface MemoryConfig {
76
76
  * 同时为真才执行;图谱是 L1 的可重建投影,关闭不影响记忆主链路。 */
77
77
  enabled: boolean;
78
78
  };
79
- /** 长任务模式:浮动面板(非阻断建议)+ 尾部 turn 压缩 + todo 参考。
80
- * **默认关**——浮动 UI 与额外蒸馏都消耗注意力/额度,由用户显式打开。 */
81
- longTask: {
82
- /** 总开关:关闭时监听器不注册、RPC 返回 enabled:false、面板不挂载。 */
83
- enabled: boolean;
84
- /** 上下文占用告警阈值(% 窗口):最近一轮官方输入侧 token 达到该比例,
85
- * 且长任务未开启时,浮动面板建议开启(压缩灾难遗忘高风险区)。 */
86
- contextThresholdPct: number;
87
- /** todo 漂移阈值:相邻 todo/write 快照的词面 Jaccard 相似度低于
88
- * (1 - 该值) 视为"大幅漂移"。0.6 = 相似度不足 0.4。 */
89
- driftThreshold: number;
90
- /** 尾部压缩一次覆盖的最近轮数。 */
91
- tailTurns: number;
92
- /** 达到上下文阈值时自动执行尾部压缩(无需按压面板;长任务开启才生效)。 */
93
- autoCompress: boolean;
94
- };
95
79
  /** §C 矛盾冻结:去重判定"两边都像是对的、机器判不了"时不自动裁决,
96
80
  * 把冲突对停放到待人工裁决区(conflict_pending)。**默认关**——
97
81
  * 冻结消耗人的注意力,不可默认全开。 */
@@ -337,19 +321,6 @@ export declare function liveSettingsSchema(): Schema<NoInfer<Schemastery.ObjectS
337
321
  embedRemoteModel: Schema<string, string, "defined">;
338
322
  embedRemoteDimensions: Schema<number, number, "defined">;
339
323
  memoryMutate: Schema<boolean, boolean, "defined">;
340
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
341
- enabled: Schema<boolean, boolean, "defined">;
342
- contextThresholdPct: Schema<number, number, "defined">;
343
- driftThreshold: Schema<number, number, "defined">;
344
- tailTurns: Schema<number, number, "defined">;
345
- autoCompress: Schema<boolean, boolean, "defined">;
346
- }>>, Schemastery.ObjectT<NoInfer<{
347
- enabled: Schema<boolean, boolean, "defined">;
348
- contextThresholdPct: Schema<number, number, "defined">;
349
- driftThreshold: Schema<number, number, "defined">;
350
- tailTurns: Schema<number, number, "defined">;
351
- autoCompress: Schema<boolean, boolean, "defined">;
352
- }>>, "plain">;
353
324
  conflictFreeze: Schema<boolean, boolean, "defined">;
354
325
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
355
326
  enabled: Schema<boolean, boolean, "defined">;
@@ -447,19 +418,6 @@ export declare function liveSettingsSchema(): Schema<NoInfer<Schemastery.ObjectS
447
418
  embedRemoteModel: Schema<string, string, "defined">;
448
419
  embedRemoteDimensions: Schema<number, number, "defined">;
449
420
  memoryMutate: Schema<boolean, boolean, "defined">;
450
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
451
- enabled: Schema<boolean, boolean, "defined">;
452
- contextThresholdPct: Schema<number, number, "defined">;
453
- driftThreshold: Schema<number, number, "defined">;
454
- tailTurns: Schema<number, number, "defined">;
455
- autoCompress: Schema<boolean, boolean, "defined">;
456
- }>>, Schemastery.ObjectT<NoInfer<{
457
- enabled: Schema<boolean, boolean, "defined">;
458
- contextThresholdPct: Schema<number, number, "defined">;
459
- driftThreshold: Schema<number, number, "defined">;
460
- tailTurns: Schema<number, number, "defined">;
461
- autoCompress: Schema<boolean, boolean, "defined">;
462
- }>>, "plain">;
463
421
  conflictFreeze: Schema<boolean, boolean, "defined">;
464
422
  }>>>, "volatile">;
465
423
  export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
@@ -522,19 +480,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
522
480
  }>>, Schemastery.ObjectT<NoInfer<{
523
481
  enabled: Schema<boolean, boolean, "defined">;
524
482
  }>>, "plain">;
525
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
526
- enabled: Schema<boolean, boolean, "defined">;
527
- contextThresholdPct: Schema<number, number, "defined">;
528
- driftThreshold: Schema<number, number, "defined">;
529
- tailTurns: Schema<number, number, "defined">;
530
- autoCompress: Schema<boolean, boolean, "defined">;
531
- }>>, Schemastery.ObjectT<NoInfer<{
532
- enabled: Schema<boolean, boolean, "defined">;
533
- contextThresholdPct: Schema<number, number, "defined">;
534
- driftThreshold: Schema<number, number, "defined">;
535
- tailTurns: Schema<number, number, "defined">;
536
- autoCompress: Schema<boolean, boolean, "defined">;
537
- }>>, "plain">;
538
483
  conflictFreeze: Schema<Schemastery.ObjectS<NoInfer<{
539
484
  enabled: Schema<boolean, boolean, "defined">;
540
485
  maxPending: Schema<number, number, "defined">;
@@ -880,19 +825,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
880
825
  embedRemoteModel: Schema<string, string, "defined">;
881
826
  embedRemoteDimensions: Schema<number, number, "defined">;
882
827
  memoryMutate: Schema<boolean, boolean, "defined">;
883
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
884
- enabled: Schema<boolean, boolean, "defined">;
885
- contextThresholdPct: Schema<number, number, "defined">;
886
- driftThreshold: Schema<number, number, "defined">;
887
- tailTurns: Schema<number, number, "defined">;
888
- autoCompress: Schema<boolean, boolean, "defined">;
889
- }>>, Schemastery.ObjectT<NoInfer<{
890
- enabled: Schema<boolean, boolean, "defined">;
891
- contextThresholdPct: Schema<number, number, "defined">;
892
- driftThreshold: Schema<number, number, "defined">;
893
- tailTurns: Schema<number, number, "defined">;
894
- autoCompress: Schema<boolean, boolean, "defined">;
895
- }>>, "plain">;
896
828
  conflictFreeze: Schema<boolean, boolean, "defined">;
897
829
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
898
830
  enabled: Schema<boolean, boolean, "defined">;
@@ -990,19 +922,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
990
922
  embedRemoteModel: Schema<string, string, "defined">;
991
923
  embedRemoteDimensions: Schema<number, number, "defined">;
992
924
  memoryMutate: Schema<boolean, boolean, "defined">;
993
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
994
- enabled: Schema<boolean, boolean, "defined">;
995
- contextThresholdPct: Schema<number, number, "defined">;
996
- driftThreshold: Schema<number, number, "defined">;
997
- tailTurns: Schema<number, number, "defined">;
998
- autoCompress: Schema<boolean, boolean, "defined">;
999
- }>>, Schemastery.ObjectT<NoInfer<{
1000
- enabled: Schema<boolean, boolean, "defined">;
1001
- contextThresholdPct: Schema<number, number, "defined">;
1002
- driftThreshold: Schema<number, number, "defined">;
1003
- tailTurns: Schema<number, number, "defined">;
1004
- autoCompress: Schema<boolean, boolean, "defined">;
1005
- }>>, "plain">;
1006
925
  conflictFreeze: Schema<boolean, boolean, "defined">;
1007
926
  }>>>, "volatile">;
1008
927
  }>>, Schemastery.ObjectT<NoInfer<{
@@ -1065,19 +984,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
1065
984
  }>>, Schemastery.ObjectT<NoInfer<{
1066
985
  enabled: Schema<boolean, boolean, "defined">;
1067
986
  }>>, "plain">;
1068
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
1069
- enabled: Schema<boolean, boolean, "defined">;
1070
- contextThresholdPct: Schema<number, number, "defined">;
1071
- driftThreshold: Schema<number, number, "defined">;
1072
- tailTurns: Schema<number, number, "defined">;
1073
- autoCompress: Schema<boolean, boolean, "defined">;
1074
- }>>, Schemastery.ObjectT<NoInfer<{
1075
- enabled: Schema<boolean, boolean, "defined">;
1076
- contextThresholdPct: Schema<number, number, "defined">;
1077
- driftThreshold: Schema<number, number, "defined">;
1078
- tailTurns: Schema<number, number, "defined">;
1079
- autoCompress: Schema<boolean, boolean, "defined">;
1080
- }>>, "plain">;
1081
987
  conflictFreeze: Schema<Schemastery.ObjectS<NoInfer<{
1082
988
  enabled: Schema<boolean, boolean, "defined">;
1083
989
  maxPending: Schema<number, number, "defined">;
@@ -1423,19 +1329,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
1423
1329
  embedRemoteModel: Schema<string, string, "defined">;
1424
1330
  embedRemoteDimensions: Schema<number, number, "defined">;
1425
1331
  memoryMutate: Schema<boolean, boolean, "defined">;
1426
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
1427
- enabled: Schema<boolean, boolean, "defined">;
1428
- contextThresholdPct: Schema<number, number, "defined">;
1429
- driftThreshold: Schema<number, number, "defined">;
1430
- tailTurns: Schema<number, number, "defined">;
1431
- autoCompress: Schema<boolean, boolean, "defined">;
1432
- }>>, Schemastery.ObjectT<NoInfer<{
1433
- enabled: Schema<boolean, boolean, "defined">;
1434
- contextThresholdPct: Schema<number, number, "defined">;
1435
- driftThreshold: Schema<number, number, "defined">;
1436
- tailTurns: Schema<number, number, "defined">;
1437
- autoCompress: Schema<boolean, boolean, "defined">;
1438
- }>>, "plain">;
1439
1332
  conflictFreeze: Schema<boolean, boolean, "defined">;
1440
1333
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
1441
1334
  enabled: Schema<boolean, boolean, "defined">;
@@ -1533,19 +1426,6 @@ export declare const memorySchema: Schema<Schemastery.ObjectS<NoInfer<{
1533
1426
  embedRemoteModel: Schema<string, string, "defined">;
1534
1427
  embedRemoteDimensions: Schema<number, number, "defined">;
1535
1428
  memoryMutate: Schema<boolean, boolean, "defined">;
1536
- longTask: Schema<Schemastery.ObjectS<NoInfer<{
1537
- enabled: Schema<boolean, boolean, "defined">;
1538
- contextThresholdPct: Schema<number, number, "defined">;
1539
- driftThreshold: Schema<number, number, "defined">;
1540
- tailTurns: Schema<number, number, "defined">;
1541
- autoCompress: Schema<boolean, boolean, "defined">;
1542
- }>>, Schemastery.ObjectT<NoInfer<{
1543
- enabled: Schema<boolean, boolean, "defined">;
1544
- contextThresholdPct: Schema<number, number, "defined">;
1545
- driftThreshold: Schema<number, number, "defined">;
1546
- tailTurns: Schema<number, number, "defined">;
1547
- autoCompress: Schema<boolean, boolean, "defined">;
1548
- }>>, "plain">;
1549
1429
  conflictFreeze: Schema<boolean, boolean, "defined">;
1550
1430
  }>>>, "volatile">;
1551
1431
  }>>, "plain">;
package/dist/config.js CHANGED
@@ -68,13 +68,6 @@ export function liveSettingsSchema() {
68
68
  // 记忆写删权限门:默认 false(模型写删风险高,须显式在面板开启高权限模式)
69
69
  memoryMutate: Schema.boolean().default(false),
70
70
  // §C 人工冲突裁决总开关:默认 false(冻结消耗注意力,不可默认全开)
71
- longTask: Schema.object({
72
- enabled: Schema.boolean().default(false),
73
- contextThresholdPct: Schema.number().min(10).max(95).default(70),
74
- driftThreshold: Schema.number().min(0.1).max(1).default(0.6),
75
- tailTurns: Schema.number().min(1).max(50).default(6),
76
- autoCompress: Schema.boolean().default(false),
77
- }),
78
71
  conflictFreeze: Schema.boolean().default(false),
79
72
  }).volatile();
80
73
  }
@@ -120,20 +113,7 @@ export const memorySchema = Schema.object({
120
113
  graph: Schema.object({
121
114
  enabled: Schema.boolean().default(false),
122
115
  }),
123
- // §C 矛盾冻结:默认关(新功能默认关)。开启后去重决策词表多出 conflict 动作,
124
- // 冲突对停放待人工裁决,不再由 LLM 直接 update/merge 覆盖。
125
- longTask: Schema.object({
126
- // 总开关:关闭时监听器不注册、建议面板不挂载(部署级上限)。
127
- enabled: Schema.boolean().default(false),
128
- // 上下文占用告警阈值(%,官方输入侧 / 模型窗口)。
129
- contextThresholdPct: Schema.number().min(10).max(95).default(70),
130
- // todo 漂移阈值:Jaccard 相似度低于 (1 - driftThreshold) 视为大幅漂移。
131
- driftThreshold: Schema.number().min(0.1).max(1).default(0.6),
132
- // 尾部压缩一次覆盖的最近轮数。
133
- tailTurns: Schema.number().min(1).max(50).default(6),
134
- // 跨阈值自动尾部压缩(长任务开启才生效)。
135
- autoCompress: Schema.boolean().default(false),
136
- }),
116
+ // §C 矛盾冻结:默认关。开启后去重决策词表多出 conflict 动作,冲突对停放待人工裁决。
137
117
  conflictFreeze: Schema.object({
138
118
  enabled: Schema.boolean().default(false),
139
119
  // 上限给"人会看"留出余量:100 条待裁决 ≈ 连续 5~20 轮蒸馏全在冲突,
@@ -456,14 +456,11 @@ export interface SessionModeGetResponse {
456
456
  hallIncludeUnlabeled: boolean;
457
457
  /** 锁定域边界开关:跨域兜底 general 是否参与召回(默认不含)。 */
458
458
  hallIncludeGeneral: boolean;
459
- /** 长任务模式(浮动面板切换;尾部 turn 压缩与 todo 参考仅在开启时可用)。 */
460
- longTask: boolean;
461
459
  }
462
460
  export interface SessionModeSetRequest {
463
461
  sessionId: string;
464
- /** 档位。**与 longTask 二选一必传**:纯切档传 mode,只切长任务开关传 longTask
465
- * (mode 缺省时不触碰档位——浮动面板切开关不能顺带重置用户档位)。 */
466
- mode?: MemoryMode;
462
+ /** 档位(必传)。 */
463
+ mode: MemoryMode;
467
464
  /** 会话级注入覆盖:布尔 = 设置覆盖;显式 null = 清除(跟随全局);缺省 = 不动
468
465
  * (旧 client 纯切档兼容,覆盖不丢)。mode 与 recall 可独立设置。 */
469
466
  recall?: boolean | null;
@@ -475,8 +472,6 @@ export interface SessionModeSetRequest {
475
472
  /** 锁定域边界开关(缺省 = 不动)。 */
476
473
  hallIncludeUnlabeled?: boolean;
477
474
  hallIncludeGeneral?: boolean;
478
- /** 长任务模式:布尔 = 切换(关闭时服务端同步撤下 todo 参考槽位);缺省 = 不动。 */
479
- longTask?: boolean;
480
475
  }
481
476
  export interface SessionModeSetResponse {
482
477
  sessionId: string;
@@ -490,50 +485,6 @@ export interface SessionModeSetResponse {
490
485
  halls: string[];
491
486
  hallIncludeUnlabeled: boolean;
492
487
  hallIncludeGeneral: boolean;
493
- /** 设置后的长任务态。 */
494
- longTask: boolean;
495
- }
496
- /** dsh-memory/longtask-hint-get | 长任务建议状态(浮动面板轮询;热路径:全内存读)。 */
497
- export interface LongTaskHintGetRequest {
498
- sessionId: string;
499
- }
500
- export interface LongTaskHintGetResponse {
501
- sessionId: string;
502
- /** 部署总开关(cfg.longTask.enabled):false 时面板不应挂载。 */
503
- enabled: boolean;
504
- /** 会话长任务态。 */
505
- longTask: boolean;
506
- /** 上下文占用百分比(最近官方输入侧 / 模型窗口;无样本或窗口未知 = null)。 */
507
- contextPct: number | null;
508
- contextThresholdPct: number;
509
- /** 最近一次 todo 快照漂移度(无快照 = null)。 */
510
- drift: number | null;
511
- driftThreshold: number;
512
- /** 最新 todo 快照条目数。 */
513
- todoCount: number;
514
- /** 非阻断建议:达到任一阈值且长任务未开启。 */
515
- suggest: boolean;
516
- reasons: Array<'context-threshold' | 'todo-drift'>;
517
- /** 尾部压缩一次覆盖的轮数(cfg)。 */
518
- tailTurns: number;
519
- /** 已压缩水位线(null = 从未压缩)。 */
520
- lastTailCompressedTurn: number | null;
521
- /** 水位线之上、可压缩的已捕获轮数(长任务关闭时 null)。 */
522
- pendingTailTurns: number | null;
523
- }
524
- /** dsh-memory/longtask-compress-tail | 尾部 turn 压缩(强制蒸馏最近 N 轮入记忆)。 */
525
- export interface LongTaskCompressTailRequest {
526
- sessionId: string;
527
- /** 覆盖 cfg.longTask.tailTurns(≤50)。 */
528
- turns?: number;
529
- }
530
- export interface LongTaskCompressTailResponse {
531
- sessionId: string;
532
- /** 实际入队蒸馏的消息条数(0 = 无可压轮/长任务未开启)。 */
533
- enqueued: number;
534
- fromTurn: number | null;
535
- toTurn: number | null;
536
- longTask: boolean;
537
488
  }
538
489
  /** dsh-memory/wing-overview(八边形角计数;WingWheel 打开时拉取,非热路径)。 */
539
490
  export interface WingOverviewResponse {
@@ -609,8 +560,12 @@ export interface RoomsExportResponse {
609
560
  }
610
561
  /** dsh-memory/room-admin(Room 破坏性面管理;高权限:面板 memoryMutate 开启才生效)。 */
611
562
  export interface RoomAdminRequest {
612
- /** merge/rename:from→to(mergeRoom/renameRoom 编排:预览→实跑+自动备份+入队场景重算);retire:slug 退役/恢复。 */
613
- action: 'merge' | 'rename' | 'retire';
563
+ /** merge/rename:from→to(mergeRoom/renameRoom 编排:预览→实跑+自动备份+入队场景重算);retire:slug 退役/恢复;update:改写 label/description。 */
564
+ action: 'merge' | 'rename' | 'retire' | 'update';
565
+ /** update 的显示名(可中文;非空才改写)。 */
566
+ label?: string;
567
+ /** update 的归类说明(喂标注器;非空才改写)。 */
568
+ description?: string;
614
569
  /** merge/rename 的源 Room slug。 */
615
570
  from?: string;
616
571
  /** merge/rename 的目标 Room slug。 */
@@ -619,6 +574,8 @@ export interface RoomAdminRequest {
619
574
  slug?: string;
620
575
  /** retire:true=恢复 active;缺省/false=退役。 */
621
576
  active?: boolean;
577
+ /** retire:同时把该 room 下全部**活跃**记录退场(软删,可在「已退场」区恢复)。 */
578
+ withRecords?: boolean;
622
579
  /** merge/rename:缺省 true 只返预览;实跑需显式 false。 */
623
580
  dryRun?: boolean;
624
581
  }
@@ -634,6 +591,8 @@ export interface RoomAdminResponse {
634
591
  hasMore?: boolean;
635
592
  /** 实跑时改写前备份文件名(rooms-merge-backups/)。 */
636
593
  backupFile?: string;
594
+ /** retire withRecords 实际退场的记录条数(软删,可恢复)。 */
595
+ retiredRecords?: number;
637
596
  }
638
597
  /** dsh-memory/wing-backfill(一键回填,后台任务;端点立即返回,进度以 wing-overview 轮询)。 */
639
598
  export interface WingBackfillResponse {
@@ -814,6 +773,15 @@ export interface UiRecord {
814
773
  sourceAnchors: string[];
815
774
  /** 检索相关度(列表路径无 score → null)。 */
816
775
  score: number | null;
776
+ /** 老化权重:读路径衰减系数 max(0.5, 0.5^(Δ天/半衰期))(Δ=updatedAt;半衰期 0=关 → null)。 */
777
+ agingWeight?: number | null;
778
+ /** 召回使用统计:**进 topN(被注入)才算 used**;参与尝试未进 = 仅 attempts。缺省 = 未装配。 */
779
+ usage?: {
780
+ attempts: number;
781
+ used: number;
782
+ lastAttemptAt: number | null;
783
+ lastUsedAt: number | null;
784
+ } | null;
817
785
  /**
818
786
  * 是否已退场(软删)。`true` 时该记录在活动列表里仍以「已退场」态呈现(置灰 + 徽标),
819
787
  * 可被 `records-restore` 找回——这正是设计要的「不静默消失、可恢复」,而非真删。
@@ -832,6 +800,13 @@ export interface ListRecordsResponse {
832
800
  truncated: boolean;
833
801
  /** 场景筛选下拉选项(仅 offset===0 时附带)。 */
834
802
  scenes?: string[];
803
+ /** 召回使用汇总(老化权重效果口径:进 topN 才算 used)。未装配 = undefined。 */
804
+ usageSummary?: {
805
+ tracked: number;
806
+ attempted: number;
807
+ used: number;
808
+ rate: number;
809
+ } | null;
835
810
  /**
836
811
  * Wing 词表(R8 单一事实源:服务端随 list-records 下发,client 不再手抄;仅 offset===0 时附带)。
837
812
  * 含 8 角 + `general`(跨域兜底,存量大 reserved 值仍可筛)。缺省(旧服务端)时 client
@@ -1327,8 +1302,6 @@ export interface DshMemoryRequestMap {
1327
1302
  'dsh-memory/token-cost': TokenCostRequest;
1328
1303
  'dsh-memory/session-mode-get': SessionModeGetRequest;
1329
1304
  'dsh-memory/session-mode-set': SessionModeSetRequest;
1330
- 'dsh-memory/longtask-hint-get': LongTaskHintGetRequest;
1331
- 'dsh-memory/longtask-compress-tail': LongTaskCompressTailRequest;
1332
1305
  'dsh-memory/wing-overview': Record<string, never>;
1333
1306
  'dsh-memory/rooms-get': Record<string, never>;
1334
1307
  'dsh-memory/rooms-export': RoomsExportRequest;
@@ -1376,8 +1349,6 @@ export interface DshMemoryResponseMap {
1376
1349
  'dsh-memory/stats': StatsResponse;
1377
1350
  'dsh-memory/token-cost': TokenCostResponse;
1378
1351
  'dsh-memory/session-mode-get': SessionModeGetResponse;
1379
- 'dsh-memory/longtask-hint-get': LongTaskHintGetResponse;
1380
- 'dsh-memory/longtask-compress-tail': LongTaskCompressTailResponse;
1381
1352
  'dsh-memory/session-mode-set': SessionModeSetResponse;
1382
1353
  'dsh-memory/wing-overview': WingOverviewResponse;
1383
1354
  'dsh-memory/rooms-get': RoomsGetResponse;
@@ -22,6 +22,7 @@ import type { L1Store } from '../store/l1.js';
22
22
  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
+ import type { RecallUsageStore } from '../store/recall-usage.js';
25
26
  import type { MemoryLogger } from '../types.js';
26
27
  import { type OccupancyLedger } from '../util/context-occupancy.js';
27
28
  /**
@@ -89,4 +90,6 @@ export declare function registerRecall(ctx: Context, cfg: MemoryConfig, stores:
89
90
  l1: L1Store;
90
91
  scenes: Record<'chat' | 'work', SceneStore>;
91
92
  persona: Record<'chat' | 'work', PersonaStore>;
92
- }, logger: MemoryLogger, live: LiveSettingsHandle, modes: SessionModeStore, dataDir: string): RecallHooks;
93
+ }, logger: MemoryLogger, live: LiveSettingsHandle, modes: SessionModeStore, dataDir: string,
94
+ /** 召回使用统计(可选;未装配 = 零成本旁路):进 topN(注入)才算 used。 */
95
+ usage?: RecallUsageStore): RecallHooks;
@@ -114,7 +114,9 @@ export function emptyRecallStats(now = Date.now()) {
114
114
  updatedAt: now,
115
115
  };
116
116
  }
117
- export function registerRecall(ctx, cfg, stores, logger, live, modes, dataDir) {
117
+ export function registerRecall(ctx, cfg, stores, logger, live, modes, dataDir,
118
+ /** 召回使用统计(可选;未装配 = 零成本旁路):进 topN(注入)才算 used。 */
119
+ usage) {
118
120
  /** 召回去重存储(同会话已注入的记忆不再重复注入;写穿持久化,重启不丢)。 */
119
121
  const dedupe = new RecallDedupeStore(dataDir, logger);
120
122
  /** 记忆占用流水(账本迁移写穿;重启后历史会话账目由此复生)。 */
@@ -393,6 +395,7 @@ export function registerRecall(ctx, cfg, stores, logger, live, modes, dataDir) {
393
395
  injectedIds: [], suppressedCount: scoped.length - fresh.length,
394
396
  durationMs: Date.now() - searchStart, outcome: 'suppressed',
395
397
  });
398
+ usage?.recordAttempt(scoped.map((h) => h.id), []);
396
399
  return decision;
397
400
  }
398
401
  const lines = applyRecallBudget(fresh.map((h) => `- [${h.scene_name ? `${h.type}|${h.scene_name}` : h.type}] ${h.content}`), { maxCharsPerMemory: cfg.recall.maxCharsPerMemory, maxTotalRecallChars: cfg.recall.maxTotalRecallChars });
@@ -404,6 +407,7 @@ export function registerRecall(ctx, cfg, stores, logger, live, modes, dataDir) {
404
407
  injectedIds: [], suppressedCount: scoped.length - fresh.length,
405
408
  durationMs: Date.now() - searchStart, outcome: 'suppressed',
406
409
  });
410
+ usage?.recordAttempt(fresh.map((h) => h.id), []);
407
411
  return decision;
408
412
  }
409
413
  st.lastHits = lines.length;
@@ -436,6 +440,8 @@ export function registerRecall(ctx, cfg, stores, logger, live, modes, dataDir) {
436
440
  injectedIds: fresh.slice(0, lines.length).map((h) => h.id), suppressedCount: scoped.length - fresh.length,
437
441
  durationMs: Date.now() - searchStart, outcome: 'injected',
438
442
  });
443
+ // 使用统计:候选=scoped(尝试),进 topN(注入)=used
444
+ usage?.recordAttempt(scoped.map((h) => h.id), fresh.slice(0, lines.length).map((h) => h.id));
439
445
  // 入账在成功构造注入消息之后、返回 enter 之前——任何前置抛错路径账目零扰动
440
446
  const led = ledgerFor(payload.agent.id);
441
447
  recordRecallInjection(led, text.length);
@@ -1,4 +1,22 @@
1
1
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
2
+ /**
3
+ * 对齐宿主 house style(dsh-agent-instructions 的 AGENTS.md 注入):user 角色
4
+ * 承载 + `<system-reminder>` 标签框。宿主对自家指令刻意**不用** system 角色——
5
+ * 会话中段的 system 消息会破坏部分聊天模板(qwen-chat-template 等),标签框即可
6
+ * 让模型把它识别为系统级元信息(Claude Code 同款语义)。
7
+ */
8
+ const SYSTEM_REMINDER_OPEN = '<system-reminder>';
9
+ const SYSTEM_REMINDER_CLOSE = '</system-reminder>';
10
+ const SLOTS_INTRO = '以下是本环境的常驻记忆槽位(激活槽位):跨会话持续生效的背景约定,仅在与之相关时作为指引遵循。' +
11
+ '它们是系统注入的元信息,不是用户发言——无需回应,请勿在回复中复述本节内容;' +
12
+ '且不覆盖系统提示与用户的直接指令,更具体的指令优先于更一般的约定。';
13
+ /**
14
+ * 槽位标题/正文来自模型工具调用,可能含有闭合标签;不转义会让槽位内容伪造
15
+ * 帧边界(宿主对指令文件正文做同样的转义)。
16
+ */
17
+ function escapeFrameBody(body) {
18
+ return body.replaceAll(SYSTEM_REMINDER_CLOSE, '<\\/system-reminder>');
19
+ }
2
20
  export function registerSlotRecall(ctx, cfg, slots, logger, _live) {
3
21
  const buildInjection = () => {
4
22
  if (!cfg.slots.enabled || !cfg.slots.inject)
@@ -13,7 +31,12 @@ export function registerSlotRecall(ctx, cfg, slots, logger, _live) {
13
31
  if (truncatedCount > 0) {
14
32
  lines.push(`… 另有 ${truncatedCount} 个常驻槽位因预算未显示,可用 memory_slot_list 查看`);
15
33
  }
16
- return '【激活槽位 · 常驻上下文】\n' + lines.join('\n');
34
+ return [
35
+ SYSTEM_REMINDER_OPEN,
36
+ SLOTS_INTRO,
37
+ escapeFrameBody(lines.join('\n')),
38
+ SYSTEM_REMINDER_CLOSE,
39
+ ].join('\n');
17
40
  };
18
41
  ctx.on('agent/pre-step', async (payload, next) => {
19
42
  const decision = await next();
package/dist/index.d.ts CHANGED
@@ -75,19 +75,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
75
75
  }>>, Schemastery.ObjectT<NoInfer<{
76
76
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
77
77
  }>>, "plain">;
78
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
79
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
80
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
81
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
82
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
83
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
84
- }>>, Schemastery.ObjectT<NoInfer<{
85
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
86
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
87
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
88
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
89
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
90
- }>>, "plain">;
91
78
  conflictFreeze: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
92
79
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
93
80
  maxPending: import("@deepseek-ai/schemastery").default<number, number, "defined">;
@@ -433,19 +420,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
433
420
  embedRemoteModel: import("@deepseek-ai/schemastery").default<string, string, "defined">;
434
421
  embedRemoteDimensions: import("@deepseek-ai/schemastery").default<number, number, "defined">;
435
422
  memoryMutate: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
436
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
437
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
438
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
439
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
440
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
441
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
442
- }>>, Schemastery.ObjectT<NoInfer<{
443
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
444
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
445
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
446
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
447
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
448
- }>>, "plain">;
449
423
  conflictFreeze: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
450
424
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
451
425
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
@@ -543,19 +517,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
543
517
  embedRemoteModel: import("@deepseek-ai/schemastery").default<string, string, "defined">;
544
518
  embedRemoteDimensions: import("@deepseek-ai/schemastery").default<number, number, "defined">;
545
519
  memoryMutate: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
546
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
547
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
548
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
549
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
550
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
551
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
552
- }>>, Schemastery.ObjectT<NoInfer<{
553
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
554
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
555
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
556
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
557
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
558
- }>>, "plain">;
559
520
  conflictFreeze: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
560
521
  }>>>, "volatile">;
561
522
  }>>, Schemastery.ObjectT<NoInfer<{
@@ -618,19 +579,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
618
579
  }>>, Schemastery.ObjectT<NoInfer<{
619
580
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
620
581
  }>>, "plain">;
621
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
622
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
623
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
624
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
625
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
626
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
627
- }>>, Schemastery.ObjectT<NoInfer<{
628
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
629
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
630
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
631
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
632
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
633
- }>>, "plain">;
634
582
  conflictFreeze: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
635
583
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
636
584
  maxPending: import("@deepseek-ai/schemastery").default<number, number, "defined">;
@@ -976,19 +924,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
976
924
  embedRemoteModel: import("@deepseek-ai/schemastery").default<string, string, "defined">;
977
925
  embedRemoteDimensions: import("@deepseek-ai/schemastery").default<number, number, "defined">;
978
926
  memoryMutate: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
979
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
980
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
981
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
982
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
983
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
984
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
985
- }>>, Schemastery.ObjectT<NoInfer<{
986
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
987
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
988
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
989
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
990
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
991
- }>>, "plain">;
992
927
  conflictFreeze: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
993
928
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
994
929
  enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
@@ -1086,19 +1021,6 @@ export declare const Config: import("@deepseek-ai/schemastery").default<Schemast
1086
1021
  embedRemoteModel: import("@deepseek-ai/schemastery").default<string, string, "defined">;
1087
1022
  embedRemoteDimensions: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1088
1023
  memoryMutate: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1089
- longTask: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
1090
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1091
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1092
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1093
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1094
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1095
- }>>, Schemastery.ObjectT<NoInfer<{
1096
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1097
- contextThresholdPct: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1098
- driftThreshold: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1099
- tailTurns: import("@deepseek-ai/schemastery").default<number, number, "defined">;
1100
- autoCompress: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1101
- }>>, "plain">;
1102
1024
  conflictFreeze: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
1103
1025
  }>>>, "volatile">;
1104
1026
  }>>, "plain">;