dsh-prime-memory 0.26.10 → 0.26.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.de.md +1638 -0
  2. package/CHANGELOG.en.md +15 -0
  3. package/CHANGELOG.es.md +1641 -0
  4. package/CHANGELOG.fr.md +1643 -0
  5. package/CHANGELOG.it.md +1643 -0
  6. package/CHANGELOG.ja.md +15 -0
  7. package/CHANGELOG.ko.md +15 -0
  8. package/CHANGELOG.md +38 -0
  9. package/CHANGELOG.ru.md +1640 -0
  10. package/INSTALL.de.md +92 -0
  11. package/INSTALL.es.md +92 -0
  12. package/INSTALL.fr.md +92 -0
  13. package/INSTALL.it.md +92 -0
  14. package/INSTALL.ru.md +92 -0
  15. package/README.de.md +1 -1
  16. package/README.en.md +3 -3
  17. package/README.es.md +1 -1
  18. package/README.fr.md +1 -1
  19. package/README.it.md +1 -1
  20. package/README.ja.md +1 -1
  21. package/README.ko.md +1 -1
  22. package/README.md +10 -3
  23. package/README.ru.md +1 -1
  24. package/dist/bench-control.js +3 -1
  25. package/dist/client.js +121 -12
  26. package/dist/clients/drsc.d.ts +34 -0
  27. package/dist/clients/drsc.js +56 -11
  28. package/dist/config.d.ts +10 -1
  29. package/dist/config.js +37 -18
  30. package/dist/contract.d.ts +48 -1
  31. package/dist/graph/gate.d.ts +17 -0
  32. package/dist/graph/gate.js +11 -0
  33. package/dist/graph/preview.d.ts +5 -0
  34. package/dist/graph/preview.js +2 -0
  35. package/dist/index.js +1 -1
  36. package/dist/pipeline/fact-source.d.ts +127 -0
  37. package/dist/pipeline/fact-source.js +192 -0
  38. package/dist/pipeline/rebuild-preserve.d.ts +31 -2
  39. package/dist/pipeline/rebuild-preserve.js +40 -14
  40. package/dist/pipeline/rebuild.d.ts +47 -13
  41. package/dist/pipeline/rebuild.js +153 -57
  42. package/dist/pipeline/runner.d.ts +4 -1
  43. package/dist/pipeline/runner.js +58 -21
  44. package/dist/pipeline/workspace-relink.js +7 -2
  45. package/dist/room-review.d.ts +1 -1
  46. package/dist/room-review.js +10 -5
  47. package/dist/settings.js +4 -0
  48. package/dist/stats.js +10 -3
  49. package/dist/store/graph-store.d.ts +20 -0
  50. package/dist/store/graph-store.js +50 -1
  51. package/dist/store/sqlite.d.ts +42 -0
  52. package/dist/store/sqlite.js +98 -0
  53. package/dist/tools/index.js +4 -3
  54. package/dsh.plugin.json +2 -2
  55. package/package.json +37 -21
@@ -163,6 +163,18 @@ export declare class GraphStore {
163
163
  queued: number;
164
164
  jobIds: string[];
165
165
  };
166
+ /**
167
+ * 只抹“已投影”凭证,**不排队**(issue #16 关闭期防护)。
168
+ *
169
+ * 关闭期写路径不入队,但记录内容已经变了;而 `graph_projected_records` 只按
170
+ * `record_id + projector_version` 记账、**不记内容版本** —— 不抹掉的话,重开后
171
+ * `queueMissing` 会认为“这条投过了”而永不补,图谱就永久陈旧(只能靠人工
172
+ * `memory_reproject`)。
173
+ *
174
+ * 不在这里入队:关闭期入队会造成“投了永不泵”的陈旧队列(与 `reprojectGraph`
175
+ * 关闭时回零同源),重开时由 `queueMissing` 统一补。
176
+ */
177
+ invalidateProjected(recordIds: readonly string[]): void;
166
178
  /**
167
179
  * 确定性边提案落库面(graph-write-plane R4 兜底支路):把"工具传入的显式边提案"
168
180
  * 当作一次确定性投影输入,经 `applyGraphProjection` **纯函数**校验后在同一事务内
@@ -236,6 +248,14 @@ export declare class GraphStore {
236
248
  * 返回新建 job 数。
237
249
  */
238
250
  queueMissing(limit: number): number;
251
+ /**
252
+ * 尚未投影(当前版本)且无在途 mapping 的 L1 条数。
253
+ *
254
+ * 面板“首次开启投影大概要花多少”的分母(issue #16):本方法必须与 `queueMissing`
255
+ * 用**同一段 WHERE** —— 两处口径一旦分叉,面板报的数字就不是实际会被拉起的量。
256
+ * 只读聚合,不写库。
257
+ */
258
+ countMissing(): number;
239
259
  /**
240
260
  * 删除传播(L1 批量删除后的惰性墓碑):来源在 L1 已全部不存在的 active/disputed
241
261
  * 节点与边标 archived(保留行,expand 可见墓碑)。挂在 MemoryDb.deleteL1Batch
@@ -529,7 +529,7 @@ export class GraphStore {
529
529
  catch (err) {
530
530
  this.logger?.warn(`${TAG} 预览 job 计数失败(计数回零): ${err instanceof Error ? err.message : String(err)}`);
531
531
  }
532
- const r = buildGraphPreview(nodes, edges, { seedId, pendingJobs, jobsTotal, deadJobs });
532
+ const r = buildGraphPreview(nodes, edges, { seedId, pendingJobs, jobsTotal, deadJobs, missing: this.countMissing() });
533
533
  if (mode === 'full')
534
534
  return { ...r, full: buildFullView(nodes, edges) };
535
535
  return r;
@@ -650,6 +650,33 @@ export class GraphStore {
650
650
  return { queued: 0, jobIds: [] };
651
651
  }
652
652
  }
653
+ /**
654
+ * 只抹“已投影”凭证,**不排队**(issue #16 关闭期防护)。
655
+ *
656
+ * 关闭期写路径不入队,但记录内容已经变了;而 `graph_projected_records` 只按
657
+ * `record_id + projector_version` 记账、**不记内容版本** —— 不抹掉的话,重开后
658
+ * `queueMissing` 会认为“这条投过了”而永不补,图谱就永久陈旧(只能靠人工
659
+ * `memory_reproject`)。
660
+ *
661
+ * 不在这里入队:关闭期入队会造成“投了永不泵”的陈旧队列(与 `reprojectGraph`
662
+ * 关闭时回零同源),重开时由 `queueMissing` 统一补。
663
+ */
664
+ invalidateProjected(recordIds) {
665
+ if (!this.db || recordIds.length === 0)
666
+ return;
667
+ const ids = [...new Set(recordIds)];
668
+ try {
669
+ this.tx(() => {
670
+ for (const chunk of chunkOf(ids)) {
671
+ const ph = chunk.map(() => '?').join(',');
672
+ this.db.prepare(`DELETE FROM graph_projected_records WHERE record_id IN (${ph})`).run(...chunk);
673
+ }
674
+ });
675
+ }
676
+ catch (err) {
677
+ this.logger?.warn(`${TAG} 投影凭证失效失败(忽略): ${err instanceof Error ? err.message : String(err)}`);
678
+ }
679
+ }
653
680
  /**
654
681
  * 确定性边提案落库面(graph-write-plane R4 兜底支路):把"工具传入的显式边提案"
655
682
  * 当作一次确定性投影输入,经 `applyGraphProjection` **纯函数**校验后在同一事务内
@@ -947,6 +974,28 @@ export class GraphStore {
947
974
  return 0;
948
975
  }
949
976
  }
977
+ /**
978
+ * 尚未投影(当前版本)且无在途 mapping 的 L1 条数。
979
+ *
980
+ * 面板“首次开启投影大概要花多少”的分母(issue #16):本方法必须与 `queueMissing`
981
+ * 用**同一段 WHERE** —— 两处口径一旦分叉,面板报的数字就不是实际会被拉起的量。
982
+ * 只读聚合,不写库。
983
+ */
984
+ countMissing() {
985
+ if (!this.db)
986
+ return 0;
987
+ try {
988
+ const row = this.db
989
+ .prepare(`SELECT COUNT(*) AS n FROM l1_records r
990
+ WHERE NOT EXISTS (SELECT 1 FROM graph_projected_records p WHERE p.record_id = r.record_id AND p.projector_version = ?)
991
+ AND NOT EXISTS (SELECT 1 FROM graph_job_records m WHERE m.record_id = r.record_id)`)
992
+ .get(GRAPH_PROJECTOR_VERSION);
993
+ return Number(row?.n ?? 0);
994
+ }
995
+ catch {
996
+ return 0;
997
+ }
998
+ }
950
999
  // ============================
951
1000
  // 删除传播(B10)
952
1001
  // ============================
@@ -623,6 +623,23 @@ export declare class MemoryDb {
623
623
  * 使"无锚点"与"锚点为空"在类型层就是两件事。
624
624
  */
625
625
  private toL0Record;
626
+ /**
627
+ * 有 L0 正文的会话 id,按**首条消息时间升序**(流式重建的会话游标)。
628
+ *
629
+ * 为什么不是直接 `listL0All()`:那个接口全量拉正文(3 万条约 88MB)且整个重建期
630
+ * 常驻。按会话走 `idx_l0_session_id` 点查,峰值降到单会话量级。
631
+ * 排序与 `groupL0Sessions` 的“会话按首条时间升序”同一口径(情境链按时间衔接)。
632
+ */
633
+ l0SessionIds(): string[];
634
+ /** 某会话的全部 L0 正文(时间升序;走 idx_l0_session_id,只占单会话内存)。 */
635
+ l0MessagesBySession(sessionId: string): L0MessageRecord[];
636
+ /**
637
+ * 仅取 L0 消息 id 集(post-watermark 判据用)。
638
+ *
639
+ * 刻意**不读 `message_text`**:判据只需要 id,而正文才是内存大头。
640
+ * 2.5 万条 id 约 1.5MB,比全量快照小一个数量级。
641
+ */
642
+ l0MessageIds(): Set<string>;
626
643
  /** L0 全量列举(重建快照用;按时间升序,事务一致性避开 JSONL 追加竞态)。 */
627
644
  listL0All(): L0MessageRecord[];
628
645
  /** 重建成本预估(一次全表聚合:会话数 / 消息数 / 字符量)。 */
@@ -631,6 +648,31 @@ export declare class MemoryDb {
631
648
  messages: number;
632
649
  chars: number;
633
650
  };
651
+ /**
652
+ * 重建水位探针(issue #14)。
653
+ *
654
+ * 回答三个问题:
655
+ * - 本地 L0 **覆盖到什么时候**(`l0Iso`):L0 正文已于 T8.4 写停,这个值是
656
+ * **常量**,不会随使用前移;
657
+ * - 检索库现有多少条、其中多少条**晚于**该水位(`l1After`):**仅用于面板提示**
658
+ * “本次重建只覆盖到 X”,**绝不用作拒绝门槛** —— L1 的 `created_time` 每次
659
+ * 蒸馏都会前移,拿它做阈值会把重建永久锁死;
660
+ * - `l0SessionCount`:面板口径(多少个会话的正文在快照里)。
661
+ *
662
+ * 注意 `l0_conversations` **没有 `created_time` 列**,只有 `recorded_at`(TEXT)
663
+ * 与 `timestamp`(INTEGER ms):主用前者(与 L1 同为 ISO 文本可直接比),
664
+ * 空串回退后者。两列都建了索引,`MAX` 走覆盖索引。
665
+ *
666
+ * L0 全空时 `l0Iso` 为 `null`,此时 `l1After` 取 `l1Total`(没有水位而 L1 有记录
667
+ * = 一条都重蒸不出来),而不是 0 —— 否则面板会把“最危险的情况”显示成“无影响”。
668
+ */
669
+ rebuildWatermark(): {
670
+ l0Iso: string | null;
671
+ l0Ms: number | null;
672
+ l0SessionCount: number;
673
+ l1Total: number;
674
+ l1After: number;
675
+ };
634
676
  /** 向量表行数(backfill 判据:与元数据行数的差值即缺失向量数;不可用时返回 -1)。 */
635
677
  countL1Vec(): number;
636
678
  countL0Vec(): number;
@@ -2405,6 +2405,63 @@ export class MemoryDb {
2405
2405
  rec.step = r.step;
2406
2406
  return rec;
2407
2407
  }
2408
+ /**
2409
+ * 有 L0 正文的会话 id,按**首条消息时间升序**(流式重建的会话游标)。
2410
+ *
2411
+ * 为什么不是直接 `listL0All()`:那个接口全量拉正文(3 万条约 88MB)且整个重建期
2412
+ * 常驻。按会话走 `idx_l0_session_id` 点查,峰值降到单会话量级。
2413
+ * 排序与 `groupL0Sessions` 的“会话按首条时间升序”同一口径(情境链按时间衔接)。
2414
+ */
2415
+ l0SessionIds() {
2416
+ if (this.degraded)
2417
+ return [];
2418
+ try {
2419
+ const rows = this.db
2420
+ .prepare('SELECT session_id FROM l0_conversations GROUP BY session_id ORDER BY MIN(timestamp) ASC')
2421
+ .all();
2422
+ return rows.map((r) => r.session_id).filter((s) => typeof s === 'string' && s !== '');
2423
+ }
2424
+ catch (err) {
2425
+ this.logger?.warn(`${TAG} L0 会话列表失败(返回空): ${err instanceof Error ? err.message : String(err)}`);
2426
+ return [];
2427
+ }
2428
+ }
2429
+ /** 某会话的全部 L0 正文(时间升序;走 idx_l0_session_id,只占单会话内存)。 */
2430
+ l0MessagesBySession(sessionId) {
2431
+ if (this.degraded || !sessionId)
2432
+ return [];
2433
+ try {
2434
+ const rows = this.db
2435
+ .prepare('SELECT record_id, session_id, role, message_text, recorded_at, timestamp, turn, step FROM l0_conversations WHERE session_id = ? ORDER BY timestamp ASC')
2436
+ .all(sessionId);
2437
+ return rows.map((r) => this.toL0Record(r));
2438
+ }
2439
+ catch (err) {
2440
+ this.logger?.warn(`${TAG} L0 会话读取失败(session=${sessionId}): ${err instanceof Error ? err.message : String(err)}`);
2441
+ return [];
2442
+ }
2443
+ }
2444
+ /**
2445
+ * 仅取 L0 消息 id 集(post-watermark 判据用)。
2446
+ *
2447
+ * 刻意**不读 `message_text`**:判据只需要 id,而正文才是内存大头。
2448
+ * 2.5 万条 id 约 1.5MB,比全量快照小一个数量级。
2449
+ */
2450
+ l0MessageIds() {
2451
+ const out = new Set();
2452
+ if (this.degraded)
2453
+ return out;
2454
+ try {
2455
+ for (const r of this.db.prepare('SELECT record_id FROM l0_conversations').iterate()) {
2456
+ if (typeof r.record_id === 'string' && r.record_id !== '')
2457
+ out.add(r.record_id);
2458
+ }
2459
+ }
2460
+ catch (err) {
2461
+ this.logger?.warn(`${TAG} L0 id 集读取失败(按空处理): ${err instanceof Error ? err.message : String(err)}`);
2462
+ }
2463
+ return out;
2464
+ }
2408
2465
  /** L0 全量列举(重建快照用;按时间升序,事务一致性避开 JSONL 追加竞态)。 */
2409
2466
  listL0All() {
2410
2467
  if (this.degraded)
@@ -2434,6 +2491,47 @@ export class MemoryDb {
2434
2491
  return { sessions: 0, messages: 0, chars: 0 };
2435
2492
  }
2436
2493
  }
2494
+ /**
2495
+ * 重建水位探针(issue #14)。
2496
+ *
2497
+ * 回答三个问题:
2498
+ * - 本地 L0 **覆盖到什么时候**(`l0Iso`):L0 正文已于 T8.4 写停,这个值是
2499
+ * **常量**,不会随使用前移;
2500
+ * - 检索库现有多少条、其中多少条**晚于**该水位(`l1After`):**仅用于面板提示**
2501
+ * “本次重建只覆盖到 X”,**绝不用作拒绝门槛** —— L1 的 `created_time` 每次
2502
+ * 蒸馏都会前移,拿它做阈值会把重建永久锁死;
2503
+ * - `l0SessionCount`:面板口径(多少个会话的正文在快照里)。
2504
+ *
2505
+ * 注意 `l0_conversations` **没有 `created_time` 列**,只有 `recorded_at`(TEXT)
2506
+ * 与 `timestamp`(INTEGER ms):主用前者(与 L1 同为 ISO 文本可直接比),
2507
+ * 空串回退后者。两列都建了索引,`MAX` 走覆盖索引。
2508
+ *
2509
+ * L0 全空时 `l0Iso` 为 `null`,此时 `l1After` 取 `l1Total`(没有水位而 L1 有记录
2510
+ * = 一条都重蒸不出来),而不是 0 —— 否则面板会把“最危险的情况”显示成“无影响”。
2511
+ */
2512
+ rebuildWatermark() {
2513
+ const empty = { l0Iso: null, l0Ms: null, l0SessionCount: 0, l1Total: 0, l1After: 0 };
2514
+ if (this.degraded)
2515
+ return empty;
2516
+ try {
2517
+ const l0 = this.db
2518
+ .prepare('SELECT COUNT(DISTINCT session_id) AS s, MAX(recorded_at) AS iso, MAX(timestamp) AS ms FROM l0_conversations')
2519
+ .get();
2520
+ const ms = typeof l0?.ms === 'number' ? l0.ms : null;
2521
+ const rawIso = typeof l0?.iso === 'string' ? l0.iso.trim() : '';
2522
+ const iso = rawIso !== '' ? rawIso : ms === null ? null : new Date(ms).toISOString();
2523
+ const total = this.db.prepare('SELECT COUNT(*) AS n FROM l1_records').get();
2524
+ const l1Total = total?.n ?? 0;
2525
+ const l1After = iso
2526
+ ? this.db.prepare('SELECT COUNT(*) AS n FROM l1_records WHERE created_time > ?').get(iso).n ?? 0
2527
+ : l1Total;
2528
+ return { l0Iso: iso, l0Ms: ms, l0SessionCount: l0?.s ?? 0, l1Total, l1After };
2529
+ }
2530
+ catch (err) {
2531
+ this.logger?.warn(`${TAG} 重建水位探针失败(按空处理): ${err instanceof Error ? err.message : String(err)}`);
2532
+ return empty;
2533
+ }
2534
+ }
2437
2535
  /** 向量表行数(backfill 判据:与元数据行数的差值即缺失向量数;不可用时返回 -1)。 */
2438
2536
  countL1Vec() {
2439
2537
  if (this.degraded || !this.stmtSearchL1Vec)
@@ -14,6 +14,7 @@
14
14
  import { createHash } from 'node:crypto';
15
15
  import { defineTool } from '@deepseek-ai/dsh-tools';
16
16
  import { DOWNGRADE_TARGET, familyOf, isKnownType, typeEnumSep } from '../memory-types.js';
17
+ import { graphFeatureOn } from '../graph/gate.js';
17
18
  import { drscRoleOf } from '../clients/drsc.js';
18
19
  import { RECEIPTS_QUERY_LIMIT_MAX, dimensionOf, toReceiptView, buildReceipts, newRunId } from '../store/receipts.js';
19
20
  import { persistReceiptsSafely } from '../store/receipts.js';
@@ -1049,7 +1050,7 @@ graphWrite) {
1049
1050
  },
1050
1051
  })));
1051
1052
  // ── 图谱工具(读;受与 memory_search 同款的档位/注入拒读门 + 族过滤) ──
1052
- const GRAPH_OFF_NOTICE = '图谱功能未启用:部署配置 graph.enabled 未开启,当前没有可用的知识图谱。';
1053
+ const GRAPH_OFF_NOTICE = '知识图谱未启用:请在概览页开启「知识图谱」(或部署配置 graph.enabled),当前没有任何可用的知识图谱。';
1053
1054
  // memory_search_graph: 图谱节点检索(紧凑节点卡)
1054
1055
  reg('graph', () => ctx.tools.register(defineTool({
1055
1056
  name: 'memory_search_graph',
@@ -1203,7 +1204,7 @@ graphWrite) {
1203
1204
  },
1204
1205
  execute: async (args) => {
1205
1206
  const graph = stores.graph;
1206
- if (!graph || !cfg.graph?.enabled)
1207
+ if (!graph || !graphFeatureOn(cfg, live))
1207
1208
  return { queued: 0, job_ids: [], skipped_ids: [], notice: GRAPH_OFF_NOTICE };
1208
1209
  if (!graphWrite)
1209
1210
  return { queued: 0, job_ids: [], skipped_ids: [], notice: '图谱写面未接线(runner 未装配),无法入队。' };
@@ -1273,7 +1274,7 @@ graphWrite) {
1273
1274
  if (!live.get().memoryMutate)
1274
1275
  return { notice: MUTATE_OFF_NOTICE };
1275
1276
  const graph = stores.graph;
1276
- if (!graph || !cfg.graph?.enabled)
1277
+ if (!graph || !graphFeatureOn(cfg, live))
1277
1278
  return { notice: GRAPH_OFF_NOTICE };
1278
1279
  if (!graphWrite)
1279
1280
  return { notice: '图谱写面未接线(runner 未装配),无法迁移。' };
package/dsh.plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "dsh-prime-memory",
3
3
  "name": "dsh-prime-memory",
4
- "version": "0.26.10",
4
+ "version": "0.26.12",
5
5
  "description": {
6
6
  "en": "Layered distilled memory plugin (L0 capture → L1 atomic memory → L2 scenes → L3 persona) with automatic recall injection before each model step.",
7
7
  "zh": "L0~L3 分层蒸馏记忆插件:自动捕获对话、抽取原子记忆、整合场景块、蒸馏核心画像,并在模型步骤前自动召回注入。"
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "license": "MIT",
15
15
  "engines": {
16
- "dsh": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3"
16
+ "dsh": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4"
17
17
  },
18
18
  "components": {
19
19
  "host": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-prime-memory",
3
- "version": "0.26.10",
3
+ "version": "0.26.12",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public",
@@ -41,14 +41,30 @@
41
41
  "README.en.md",
42
42
  "README.ja.md",
43
43
  "README.ko.md",
44
+ "README.de.md",
45
+ "README.es.md",
46
+ "README.fr.md",
47
+ "README.it.md",
48
+ "README.ru.md",
44
49
  "INSTALL.md",
45
50
  "INSTALL.en.md",
46
51
  "INSTALL.ja.md",
47
52
  "INSTALL.ko.md",
53
+ "INSTALL.de.md",
54
+ "INSTALL.es.md",
55
+ "INSTALL.fr.md",
56
+ "INSTALL.it.md",
57
+ "INSTALL.ru.md",
48
58
  "CHANGELOG.md",
49
59
  "CHANGELOG.en.md",
50
60
  "CHANGELOG.ja.md",
51
61
  "CHANGELOG.ko.md",
62
+ "CHANGELOG.de.md",
63
+ "CHANGELOG.es.md",
64
+ "CHANGELOG.fr.md",
65
+ "CHANGELOG.it.md",
66
+ "CHANGELOG.ru.md",
67
+ "LICENSE",
52
68
  "ENGINEERING-NOTES.md"
53
69
  ],
54
70
  "scripts": {
@@ -64,7 +80,7 @@
64
80
  },
65
81
  "engines": {
66
82
  "node": ">=22.16.0",
67
- "dsh": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3"
83
+ "dsh": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4"
68
84
  },
69
85
  "keywords": [
70
86
  "dsh",
@@ -88,15 +104,15 @@
88
104
  },
89
105
  "peerDependencies": {
90
106
  "@deepseek-ai/cordis": "^4.0.1",
91
- "@deepseek-ai/dsh-agent": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
92
- "@deepseek-ai/dsh-client-connection": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
93
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
94
- "@deepseek-ai/dsh-home-paths": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
95
- "@deepseek-ai/dsh-llm": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
96
- "@deepseek-ai/dsh-session": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
97
- "@deepseek-ai/dsh-settings": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
98
- "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3",
99
- "@deepseek-ai/dsh-tools": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3"
107
+ "@deepseek-ai/dsh-agent": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
108
+ "@deepseek-ai/dsh-client-connection": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
109
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
110
+ "@deepseek-ai/dsh-home-paths": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
111
+ "@deepseek-ai/dsh-llm": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
112
+ "@deepseek-ai/dsh-session": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
113
+ "@deepseek-ai/dsh-settings": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
114
+ "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4",
115
+ "@deepseek-ai/dsh-tools": "0.1.0-rc.2 || 0.1.0-rc.3 || 0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.5-rc.3 || 0.1.7-rc.1 || 0.1.7-rc.2 || 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3 || 0.2.1-rc.4"
100
116
  },
101
117
  "peerDependenciesMeta": {
102
118
  "@deepseek-ai/dsh-agent": {
@@ -132,16 +148,16 @@
132
148
  "@deepseek-ai/cordis": "^4.0.4",
133
149
  "@deepseek-ai/cordis-plugin-loader": "^1.0.5",
134
150
  "@deepseek-ai/cosmokit": "1.8.5",
135
- "@deepseek-ai/dsh-agent": "0.2.0-rc.1",
136
- "@deepseek-ai/dsh-agent-default-model": "0.2.0-rc.1",
137
- "@deepseek-ai/dsh-client-connection": "0.2.0-rc.1",
138
- "@deepseek-ai/dsh-compaction": "0.2.0-rc.1",
139
- "@deepseek-ai/dsh-home-paths": "0.2.0-rc.1",
140
- "@deepseek-ai/dsh-llm": "0.2.0-rc.1",
141
- "@deepseek-ai/dsh-session": "0.2.0-rc.1",
142
- "@deepseek-ai/dsh-settings": "0.2.0-rc.1",
143
- "@deepseek-ai/dsh-system-prompt": "0.2.0-rc.1",
144
- "@deepseek-ai/dsh-tools": "0.2.0-rc.1",
151
+ "@deepseek-ai/dsh-agent": "0.2.1-rc.3",
152
+ "@deepseek-ai/dsh-agent-default-model": "0.2.1-rc.3",
153
+ "@deepseek-ai/dsh-client-connection": "0.2.1-rc.3",
154
+ "@deepseek-ai/dsh-compaction": "0.2.1-rc.3",
155
+ "@deepseek-ai/dsh-home-paths": "0.2.1-rc.3",
156
+ "@deepseek-ai/dsh-llm": "0.2.1-rc.3",
157
+ "@deepseek-ai/dsh-session": "0.2.1-rc.3",
158
+ "@deepseek-ai/dsh-settings": "0.2.1-rc.3",
159
+ "@deepseek-ai/dsh-system-prompt": "0.2.1-rc.3",
160
+ "@deepseek-ai/dsh-tools": "0.2.1-rc.3",
145
161
  "@eslint/js": "^10.0.1",
146
162
  "@types/node": "^22.0.0",
147
163
  "@types/react": "^19.2.18",