dsh-data-domain-knowledge 0.1.0-alpha.1

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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/cordis.patch.yml +410 -0
  4. package/eval/README.md +76 -0
  5. package/eval/evaluate-retrieval.mjs +121 -0
  6. package/eval/queries.example.jsonl +2 -0
  7. package/lib/client.js +111415 -0
  8. package/lib/types/config-schema.d.ts +35 -0
  9. package/lib/types/config-schema.d.ts.map +1 -0
  10. package/lib/types/config-schema.js +34 -0
  11. package/lib/types/config-schema.js.map +1 -0
  12. package/lib/types/convert/core-loader.d.ts +32 -0
  13. package/lib/types/convert/core-loader.d.ts.map +1 -0
  14. package/lib/types/convert/core-loader.js +60 -0
  15. package/lib/types/convert/core-loader.js.map +1 -0
  16. package/lib/types/convert/host.d.ts +88 -0
  17. package/lib/types/convert/host.d.ts.map +1 -0
  18. package/lib/types/convert/host.js +479 -0
  19. package/lib/types/convert/host.js.map +1 -0
  20. package/lib/types/convert/ingest.d.ts +125 -0
  21. package/lib/types/convert/ingest.d.ts.map +1 -0
  22. package/lib/types/convert/ingest.js +228 -0
  23. package/lib/types/convert/ingest.js.map +1 -0
  24. package/lib/types/convert/settings-schema.d.ts +18 -0
  25. package/lib/types/convert/settings-schema.d.ts.map +1 -0
  26. package/lib/types/convert/settings-schema.js +26 -0
  27. package/lib/types/convert/settings-schema.js.map +1 -0
  28. package/lib/types/convert/types.d.ts +46 -0
  29. package/lib/types/convert/types.d.ts.map +1 -0
  30. package/lib/types/convert/types.js +41 -0
  31. package/lib/types/convert/types.js.map +1 -0
  32. package/lib/types/diagnosis/cards.d.ts +71 -0
  33. package/lib/types/diagnosis/cards.d.ts.map +1 -0
  34. package/lib/types/diagnosis/cards.js +482 -0
  35. package/lib/types/diagnosis/cards.js.map +1 -0
  36. package/lib/types/diagnosis/problem-classes.d.ts +51 -0
  37. package/lib/types/diagnosis/problem-classes.d.ts.map +1 -0
  38. package/lib/types/diagnosis/problem-classes.js +66 -0
  39. package/lib/types/diagnosis/problem-classes.js.map +1 -0
  40. package/lib/types/diagnosis/schema.d.ts +65 -0
  41. package/lib/types/diagnosis/schema.d.ts.map +1 -0
  42. package/lib/types/diagnosis/schema.js +208 -0
  43. package/lib/types/diagnosis/schema.js.map +1 -0
  44. package/lib/types/diagnosis/seed-source.d.ts +20 -0
  45. package/lib/types/diagnosis/seed-source.d.ts.map +1 -0
  46. package/lib/types/diagnosis/seed-source.js +96 -0
  47. package/lib/types/diagnosis/seed-source.js.map +1 -0
  48. package/lib/types/diagnosis/seed.d.ts +50 -0
  49. package/lib/types/diagnosis/seed.d.ts.map +1 -0
  50. package/lib/types/diagnosis/seed.js +242 -0
  51. package/lib/types/diagnosis/seed.js.map +1 -0
  52. package/lib/types/diagnosis/store.d.ts +81 -0
  53. package/lib/types/diagnosis/store.d.ts.map +1 -0
  54. package/lib/types/diagnosis/store.js +409 -0
  55. package/lib/types/diagnosis/store.js.map +1 -0
  56. package/lib/types/diagnosis/types.d.ts +124 -0
  57. package/lib/types/diagnosis/types.d.ts.map +1 -0
  58. package/lib/types/diagnosis/types.js +13 -0
  59. package/lib/types/diagnosis/types.js.map +1 -0
  60. package/lib/types/directory-picker.d.ts +94 -0
  61. package/lib/types/directory-picker.d.ts.map +1 -0
  62. package/lib/types/directory-picker.js +110 -0
  63. package/lib/types/directory-picker.js.map +1 -0
  64. package/lib/types/extract-model.d.ts +76 -0
  65. package/lib/types/extract-model.d.ts.map +1 -0
  66. package/lib/types/extract-model.js +193 -0
  67. package/lib/types/extract-model.js.map +1 -0
  68. package/lib/types/extract.d.ts +121 -0
  69. package/lib/types/extract.d.ts.map +1 -0
  70. package/lib/types/extract.js +549 -0
  71. package/lib/types/extract.js.map +1 -0
  72. package/lib/types/fts.d.ts +96 -0
  73. package/lib/types/fts.d.ts.map +1 -0
  74. package/lib/types/fts.js +184 -0
  75. package/lib/types/fts.js.map +1 -0
  76. package/lib/types/index.d.ts +39 -0
  77. package/lib/types/index.d.ts.map +1 -0
  78. package/lib/types/index.js +1112 -0
  79. package/lib/types/index.js.map +1 -0
  80. package/lib/types/intent/engine.d.ts +108 -0
  81. package/lib/types/intent/engine.d.ts.map +1 -0
  82. package/lib/types/intent/engine.js +501 -0
  83. package/lib/types/intent/engine.js.map +1 -0
  84. package/lib/types/intent/host.d.ts +88 -0
  85. package/lib/types/intent/host.d.ts.map +1 -0
  86. package/lib/types/intent/host.js +389 -0
  87. package/lib/types/intent/host.js.map +1 -0
  88. package/lib/types/intent/preset-tools.d.ts +37 -0
  89. package/lib/types/intent/preset-tools.d.ts.map +1 -0
  90. package/lib/types/intent/preset-tools.js +45 -0
  91. package/lib/types/intent/preset-tools.js.map +1 -0
  92. package/lib/types/intent/settings-schema.d.ts +59 -0
  93. package/lib/types/intent/settings-schema.d.ts.map +1 -0
  94. package/lib/types/intent/settings-schema.js +57 -0
  95. package/lib/types/intent/settings-schema.js.map +1 -0
  96. package/lib/types/intent/store.d.ts +75 -0
  97. package/lib/types/intent/store.d.ts.map +1 -0
  98. package/lib/types/intent/store.js +139 -0
  99. package/lib/types/intent/store.js.map +1 -0
  100. package/lib/types/intent/tools.d.ts +63 -0
  101. package/lib/types/intent/tools.d.ts.map +1 -0
  102. package/lib/types/intent/tools.js +108 -0
  103. package/lib/types/intent/tools.js.map +1 -0
  104. package/lib/types/intent/types.d.ts +189 -0
  105. package/lib/types/intent/types.d.ts.map +1 -0
  106. package/lib/types/intent/types.js +62 -0
  107. package/lib/types/intent/types.js.map +1 -0
  108. package/lib/types/knowledge-bases.d.ts +266 -0
  109. package/lib/types/knowledge-bases.d.ts.map +1 -0
  110. package/lib/types/knowledge-bases.js +1107 -0
  111. package/lib/types/knowledge-bases.js.map +1 -0
  112. package/lib/types/layout.d.ts +262 -0
  113. package/lib/types/layout.d.ts.map +1 -0
  114. package/lib/types/layout.js +312 -0
  115. package/lib/types/layout.js.map +1 -0
  116. package/lib/types/migrate.d.ts +110 -0
  117. package/lib/types/migrate.d.ts.map +1 -0
  118. package/lib/types/migrate.js +280 -0
  119. package/lib/types/migrate.js.map +1 -0
  120. package/lib/types/recall-rank.d.ts +158 -0
  121. package/lib/types/recall-rank.d.ts.map +1 -0
  122. package/lib/types/recall-rank.js +261 -0
  123. package/lib/types/recall-rank.js.map +1 -0
  124. package/lib/types/runtime.d.ts +568 -0
  125. package/lib/types/runtime.d.ts.map +1 -0
  126. package/lib/types/runtime.js +3045 -0
  127. package/lib/types/runtime.js.map +1 -0
  128. package/lib/types/settings-schema.d.ts +117 -0
  129. package/lib/types/settings-schema.d.ts.map +1 -0
  130. package/lib/types/settings-schema.js +92 -0
  131. package/lib/types/settings-schema.js.map +1 -0
  132. package/lib/types/settings-volatile.d.ts +102 -0
  133. package/lib/types/settings-volatile.d.ts.map +1 -0
  134. package/lib/types/settings-volatile.js +114 -0
  135. package/lib/types/settings-volatile.js.map +1 -0
  136. package/lib/types/types.d.ts +799 -0
  137. package/lib/types/types.d.ts.map +1 -0
  138. package/lib/types/types.js +387 -0
  139. package/lib/types/types.js.map +1 -0
  140. package/lib/types/wiki-types.d.ts +68 -0
  141. package/lib/types/wiki-types.d.ts.map +1 -0
  142. package/lib/types/wiki-types.js +322 -0
  143. package/lib/types/wiki-types.js.map +1 -0
  144. package/package.json +101 -0
  145. package/preset/tita-data-agent/agent.cordis.yml +376 -0
  146. package/preset/tita-data-agent/preset.yml +3 -0
  147. package/python/requirements.txt +8 -0
  148. package/scripts/doctor.mjs +70 -0
  149. package/scripts/e2e-pipeline.mjs +355 -0
  150. package/scripts/install-agent-preset.mjs +92 -0
  151. package/scripts/setup-embedding.sh +34 -0
  152. package/scripts/sync-agent-preset.mjs +188 -0
  153. package/src/client/AgentPresetCard.tsx +247 -0
  154. package/src/client/DirectoryPicker.tsx +357 -0
  155. package/src/client/InfoHint.tsx +65 -0
  156. package/src/client/IntentLogicTab.tsx +185 -0
  157. package/src/client/IntentTab.tsx +715 -0
  158. package/src/client/KnowledgeBaseTab.tsx +1454 -0
  159. package/src/client/KnowledgeGraphView.tsx +306 -0
  160. package/src/client/KnowledgePanel.tsx +381 -0
  161. package/src/client/KnowledgeStepRail.tsx +60 -0
  162. package/src/client/NodeSettings.tsx +392 -0
  163. package/src/client/PreviewSections.tsx +116 -0
  164. package/src/client/RecallPanel.tsx +399 -0
  165. package/src/client/TypeDefinitionDrawer.tsx +215 -0
  166. package/src/client/WikiFlowCard.tsx +226 -0
  167. package/src/client/WikiTypeEditor.tsx +332 -0
  168. package/src/client/agent-preset.ts +121 -0
  169. package/src/client/arch/AgentArchitectureGraph.tsx +219 -0
  170. package/src/client/arch/NodeLogicPanel.tsx +133 -0
  171. package/src/client/arch/ProblemDetailPanel.tsx +88 -0
  172. package/src/client/arch/model.ts +691 -0
  173. package/src/client/architecture.css +191 -0
  174. package/src/client/architecture.tsx +530 -0
  175. package/src/client/attribution/AttributionGraph.tsx +104 -0
  176. package/src/client/attribution/AttributionTab.tsx +332 -0
  177. package/src/client/attribution/CaseView.tsx +102 -0
  178. package/src/client/attribution/GraphStage.tsx +87 -0
  179. package/src/client/attribution/RunView.tsx +184 -0
  180. package/src/client/attribution/StageChrome.tsx +403 -0
  181. package/src/client/attribution/ViewSwitch.tsx +107 -0
  182. package/src/client/attribution/graph-options.ts +381 -0
  183. package/src/client/attribution/model.ts +462 -0
  184. package/src/client/config-scope.ts +119 -0
  185. package/src/client/convert/ConvertPanel.tsx +594 -0
  186. package/src/client/convert/styles.css +138 -0
  187. package/src/client/convert/styles.ts +49 -0
  188. package/src/client/format.ts +39 -0
  189. package/src/client/graph/layout.ts +181 -0
  190. package/src/client/graph.css +113 -0
  191. package/src/client/index.ts +98 -0
  192. package/src/client/problem-domains.ts +114 -0
  193. package/src/client/styles.css +940 -0
  194. package/src/client/styles.ts +11 -0
  195. package/src/client/useFitScale.ts +68 -0
  196. package/src/config-schema.ts +45 -0
  197. package/src/convert/core-loader.ts +68 -0
  198. package/src/convert/host.ts +579 -0
  199. package/src/convert/ingest.ts +367 -0
  200. package/src/convert/settings-schema.ts +27 -0
  201. package/src/convert/types.ts +65 -0
  202. package/src/diagnosis/cards.ts +498 -0
  203. package/src/diagnosis/problem-classes.ts +117 -0
  204. package/src/diagnosis/schema.ts +260 -0
  205. package/src/diagnosis/seed-source.ts +107 -0
  206. package/src/diagnosis/seed.ts +291 -0
  207. package/src/diagnosis/store.ts +432 -0
  208. package/src/diagnosis/types.ts +152 -0
  209. package/src/directory-picker.ts +164 -0
  210. package/src/extract-model.ts +227 -0
  211. package/src/extract.ts +632 -0
  212. package/src/fts.ts +203 -0
  213. package/src/index.ts +1091 -0
  214. package/src/intent/README.md +63 -0
  215. package/src/intent/engine.ts +527 -0
  216. package/src/intent/host.ts +462 -0
  217. package/src/intent/preset-tools.ts +48 -0
  218. package/src/intent/settings-schema.ts +63 -0
  219. package/src/intent/store.ts +143 -0
  220. package/src/intent/tools.ts +139 -0
  221. package/src/intent/types.ts +245 -0
  222. package/src/knowledge-bases.ts +1160 -0
  223. package/src/layout.ts +350 -0
  224. package/src/migrate.ts +262 -0
  225. package/src/python/embedding_worker.py +471 -0
  226. package/src/recall-rank.ts +299 -0
  227. package/src/runtime.ts +3069 -0
  228. package/src/settings-schema.ts +94 -0
  229. package/src/settings-volatile.ts +122 -0
  230. package/src/types.ts +1140 -0
  231. package/src/wiki-types.ts +357 -0
@@ -0,0 +1,280 @@
1
+ /**
2
+ * 0029 的一次性迁移:把旧布局的知识树搬进新根路径。
3
+ *
4
+ * ## 为什么要迁移
5
+ *
6
+ * 0029 之前,「知识树在哪」由用户直接设的那个 `rootDir` 决定,而它指向的是**知识树
7
+ * 本身** —— `01_source_truth` 直接躺在它下面。新布局多了一层:`rootDir` 变成
8
+ * `agentRoot`,知识树退到 `<agentRoot>/domain_knowledge/<知识库 id>`。
9
+ *
10
+ * 也就是说,对**改过** `rootDir` 的用户,磁盘上那棵树的位置变了。数据不能跟着
11
+ * 设置一起改语义就消失,所以这里搬一次。
12
+ *
13
+ * ## 四条纪律
14
+ *
15
+ * 1. **只在真的有必要时动手。** 四个前置条件缺一不可:旧设置非空、旧位置确实是一棵
16
+ * 知识树、新位置不是同一处、新旧不是同一个目录。
17
+ * 2. **目标已有树就不碰。** 那说明用户已经在新布局下建过库,旧的那棵不是它的前身;
18
+ * 合并两棵来路不同的树比不迁移更糟。
19
+ * 3. **逐个目录搬,且只搬目标里还没有的。** 这既让迁移可重入(中断后重跑接着搬),
20
+ * 也保证永远不覆盖目标里已有的数据。
21
+ * 4. **搬不动就如实说,不回滚也不假装。** 失败时返回 `failed` 与原因,两边数据
22
+ * 都留在原地;调用方把它写进 `/knowledge/stats`,界面上能看到。
23
+ *
24
+ * 用同步 fs:迁移发生在设置解析的回调里,而 runtime 必须在**迁移完成之后**才按新
25
+ * 路径构造 —— 异步化会把这段顺序打散。搬的是目录项(`rename` 是元数据操作,与树
26
+ * 的大小无关),跨卷时退化成复制,代价可控。
27
+ *
28
+ * @module
29
+ */
30
+ import { cpSync, existsSync, mkdirSync, readdirSync, renameSync, rmdirSync, rmSync, statSync } from 'node:fs';
31
+ import { basename, join, resolve } from 'node:path';
32
+ import { knowledgeBaseRoot, looksLikeKnowledgeTree, memoryRoot, resourceRoot } from './layout.js';
33
+ /**
34
+ * 知识树的段。与 `runtime.ts` 的 `LAYOUT` 同源,这里重列是为了不引入 runtime 依赖。
35
+ *
36
+ * 0030 撤掉了 `00_schema`:它从建出来起就是空目录,分类与 Wiki 类型注册表一直住在
37
+ * `<agentRoot>/resource/knowledge-bases.json`。这里也一并去掉,免得迁移又把一个
38
+ * 没人用的空目录建回新树上。
39
+ *
40
+ * 0032 撤掉了 `04_memory`:记忆(版本快照 / 反馈 / 访问审计)搬到了
41
+ * `<agentRoot>/memory/<库 id>`,由 `migrateLegacyMemory` 负责搬。它留在这里会让
42
+ * 知识树迁移把 `04_memory` 当成「一段知识」搬进新树 —— 那是搬错方向。
43
+ */
44
+ const LAYOUT_DIRS = ['01_source_truth', '02_wiki', '03_compiled', '05_diagnosis'];
45
+ /** 无需迁移的结论。 */
46
+ function skipped(reason, from, to) {
47
+ return { status: 'skipped', reason, ...(from ? { from } : {}), ...(to ? { to } : {}) };
48
+ }
49
+ /**
50
+ * 把 `legacyRoot` 下的知识树搬进 `<agentRoot>/domain_knowledge/<kbId>`。
51
+ *
52
+ * @param input.agentRoot - 新的 Tita Agent 根路径。
53
+ * @param input.legacyRoot - 用户旧设置里的知识树根;空串表示没有旧设置。
54
+ * @param input.kbId - 承接这棵树的知识库 id,缺省 `default`。
55
+ * @returns 迁移结论。**不抛异常** —— 迁移失败不该让插件起不来。
56
+ */
57
+ export function migrateLegacyKnowledgeTree(input) {
58
+ const to = knowledgeBaseRoot(input.agentRoot, input.kbId ?? 'default');
59
+ const legacy = input.legacyRoot?.trim();
60
+ if (!legacy)
61
+ return skipped('没有旧的根目录设置', undefined, to);
62
+ const from = resolve(legacy);
63
+ if (from === resolve(to))
64
+ return skipped('新旧路径相同', from, to);
65
+ if (!existsSync(from))
66
+ return skipped('旧路径不存在', from, to);
67
+ if (!looksLikeKnowledgeTree(from))
68
+ return skipped('旧路径不是一棵知识树', from, to);
69
+ // 目标已经是一棵树 = 用户已在新布局下建过库,旧的那棵不是它的前身。
70
+ if (looksLikeKnowledgeTree(to))
71
+ return skipped('新位置已有一棵知识树,不覆盖', from, to);
72
+ const moved = [];
73
+ try {
74
+ mkdirSync(to, { recursive: true });
75
+ for (const name of LAYOUT_DIRS) {
76
+ const source = join(from, name);
77
+ const target = join(to, name);
78
+ if (!existsSync(source) || existsSync(target))
79
+ continue;
80
+ try {
81
+ renameSync(source, target);
82
+ }
83
+ catch (cause) {
84
+ // 跨卷(EXDEV)或权限受限:退化成复制 + 删除,语义仍然是「搬」。
85
+ if (cause?.code !== 'EXDEV')
86
+ throw cause;
87
+ cpSync(source, target, { recursive: true });
88
+ rmSync(source, { recursive: true, force: true });
89
+ }
90
+ moved.push(name);
91
+ }
92
+ }
93
+ catch (cause) {
94
+ return {
95
+ status: 'failed',
96
+ from,
97
+ to,
98
+ moved,
99
+ reason: cause instanceof Error ? cause.message : String(cause),
100
+ };
101
+ }
102
+ if (moved.length === 0)
103
+ return skipped('旧位置没有可搬的目录', from, to);
104
+ return { status: 'moved', from, to, moved, reason: `已搬迁 ${moved.length} 个目录` };
105
+ }
106
+ /**
107
+ * 0029:把 Agent 的**家当**从 `~/.tita-data-agent` 搬进 `<agentRoot>/resource`。
108
+ *
109
+ * 搬三样:`models/` → `resource/models`、`embedding-venv/` → `resource/python`、
110
+ * `knowledge-bases.json` → `resource/knowledge-bases.json`。
111
+ *
112
+ * ## 四条纪律
113
+ *
114
+ * 1. **先 rename,不先 copy。** 这三样加起来 2.7G,而 `~/.tita-data-agent` 与默认
115
+ * 根路径在同一个卷上,`rename` 是元数据操作、瞬间完成。跨卷(EXDEV)时**不自动
116
+ * 复制** —— 一个 2.7G 的静默复制可能填满磁盘、可能花十分钟,那不是迁移该偷偷
117
+ * 做的事,所以如实报 `failed` 让用户自己决定。
118
+ * 2. **目标已存在就不动。** 用户可能已经在新位置放了自己的模型;覆盖它是不可接受
119
+ * 的失败。
120
+ * 3. **只搬存在的。** 全新安装没有这些东西,那就不搬,不是错误。
121
+ * 4. **按条目合并,不按目录整体跳过。** 「目标目录存在」不等于「这一样搬完了」:
122
+ * 用户可能只往 `resource/models/` 里放了一个重排模型,而 `models/` 里的嵌入模型
123
+ * 还留在旧位置 —— 整体跳过会让它**永远搬不过来**(因为迁移只跑一次)。所以
124
+ * `models/` 逐个子项搬,目标里已有的子项跳过。这同时让迁移更可重入。
125
+ *
126
+ * @param input.agentRoot - 新的 Tita Agent 根路径。
127
+ * @param input.legacyHome - 旧的 `TITA_DATA_AGENT_HOME`(默认 `~/.tita-data-agent`)。
128
+ * @returns 迁移结论;`moved` 里是真正搬过去的项(`models/<名字>` 会带上子项名)。
129
+ */
130
+ export function migrateLegacyResources(input) {
131
+ const from = resolve(input.legacyHome);
132
+ const to = resourceRoot(input.agentRoot);
133
+ if (from === resolve(to))
134
+ return { status: 'skipped', reason: '家当目录与根路径相同', from, to };
135
+ if (!existsSync(from))
136
+ return { status: 'skipped', reason: '旧家当目录不存在', from, to };
137
+ /**
138
+ * 一样家当的搬法:`source` 是一个目录时逐个子项合并,是文件时整体搬。
139
+ * 返回真正搬过去的条目名。
140
+ */
141
+ const move = (source, target) => {
142
+ if (!existsSync(source))
143
+ return [];
144
+ if (!statSync(source).isDirectory()) {
145
+ if (existsSync(target))
146
+ return [];
147
+ renameSync(source, target);
148
+ return [basename(source)];
149
+ }
150
+ const moved = [];
151
+ for (const name of readdirSync(source)) {
152
+ const child = join(source, name);
153
+ const childTarget = join(target, name);
154
+ if (existsSync(childTarget))
155
+ continue;
156
+ mkdirSync(target, { recursive: true });
157
+ renameSync(child, childTarget);
158
+ moved.push(name);
159
+ }
160
+ return moved;
161
+ };
162
+ const plan = [
163
+ ['models', join(to, 'models')],
164
+ ['embedding-venv', join(to, 'python')],
165
+ ['knowledge-bases.json', join(to, 'knowledge-bases.json')],
166
+ ];
167
+ const moved = [];
168
+ try {
169
+ let created = false;
170
+ for (const [name, target] of plan) {
171
+ const source = join(from, name);
172
+ if (!existsSync(source))
173
+ continue;
174
+ if (!created) {
175
+ mkdirSync(to, { recursive: true });
176
+ created = true;
177
+ }
178
+ try {
179
+ /**
180
+ * 报告粒度按**这一样家当是不是一个集合**来分:
181
+ *
182
+ * - `models/` 是集合,而「目标里已经有别的模型」正是最容易出问题的情况,
183
+ * 所以要报**哪几个**搬了(`models/WeMM-Embedding-2B-Quantized`);
184
+ * - `embedding-venv` / `knowledge-bases.json` 是单件,报一次就够。
185
+ *
186
+ * 这里原来写的是「按 `move()` 返回的条目逐个 push 类别名」,于是 venv 有几个
187
+ * 子目录就报几次 `embedding-venv` —— 实测报出 8 项,而真正搬的是 3 项。
188
+ */
189
+ const items = move(source, target);
190
+ if (name === 'models')
191
+ for (const item of items)
192
+ moved.push(`${name}/${item}`);
193
+ else if (items.length > 0)
194
+ moved.push(name);
195
+ }
196
+ catch (cause) {
197
+ // 跨卷:**不复制**。2.7G 的静默复制不是迁移该做的事。
198
+ if (cause?.code === 'EXDEV') {
199
+ return { status: 'failed', from, to, moved, reason: `${name} 与根路径不在同一个卷上,需要你手动搬(不自动复制,因为可能有几个 GB)` };
200
+ }
201
+ throw cause;
202
+ }
203
+ // 搬空了的旧目录不留着:它只会让人以为家当还在那儿。
204
+ try {
205
+ rmdirSync(source);
206
+ }
207
+ catch { /* 还有别的东西在里面,保留 */ }
208
+ }
209
+ }
210
+ catch (cause) {
211
+ return { status: 'failed', from, to, moved, reason: cause instanceof Error ? cause.message : String(cause) };
212
+ }
213
+ if (moved.length === 0)
214
+ return { status: 'skipped', reason: '家当已经在新位置,或旧位置没有可搬的', from, to };
215
+ return { status: 'moved', from, to, moved, reason: `已搬迁 ${moved.length} 项家当` };
216
+ }
217
+ /**
218
+ * 0032:把记忆段从知识树里搬出来 —— `<知识库根>/04_memory` → `<agentRoot>/memory/<库 id>`。
219
+ *
220
+ * ## 为什么搬
221
+ *
222
+ * 记忆装的是版本快照、反馈与访问审计:它们是**关于这个 Agent 的动作留痕**,不是
223
+ * 关于知识的断言。留在知识树里有三个说不通的地方:备份知识树被迫连审计流水一起
224
+ * 备份;「知识树有哪几段」这个问题里混进了一个横切层;多知识库时每棵树各存一份
225
+ * 同构的流水。搬出来之后知识树只剩知识,记忆与它平级、同样按库分叉。
226
+ *
227
+ * ## 纪律
228
+ *
229
+ * 与家当迁移同源,但**这里允许合并**:目标里已经有同名条目时跳过(用户可能已经
230
+ * 在新位置写过记忆),其余照搬。跨卷时退化成复制 + 删除 —— 记忆是**数据**,不是
231
+ * 可以重新下载的模型,所以这里不像家当迁移那样「不自动复制」:丢掉版本历史比
232
+ * 复制几百 MB 严重得多。
233
+ *
234
+ * @param input.agentRoot - 新的 Tita Agent 根路径。
235
+ * @param input.kbRoot - 这个知识库的根(`<agentRoot>/domain_knowledge/<id>`)。
236
+ * @param input.kbId - 知识库 id,决定记忆落在 `memory/` 下的哪一格。
237
+ * @returns 迁移结论。**不抛异常** —— 迁移失败不该让插件起不来。
238
+ */
239
+ export function migrateLegacyMemory(input) {
240
+ const from = join(resolve(input.kbRoot), '04_memory');
241
+ const to = memoryRoot(input.agentRoot, input.kbId);
242
+ if (resolve(from) === resolve(to))
243
+ return skipped('记忆段与目标位置相同', from, to);
244
+ if (!existsSync(from))
245
+ return skipped('这个知识库里没有旧的记忆段', from, to);
246
+ const moved = [];
247
+ try {
248
+ for (const name of readdirSync(from)) {
249
+ const source = join(from, name);
250
+ const target = join(to, name);
251
+ if (existsSync(target))
252
+ continue;
253
+ mkdirSync(to, { recursive: true });
254
+ try {
255
+ renameSync(source, target);
256
+ }
257
+ catch (cause) {
258
+ if (cause?.code !== 'EXDEV')
259
+ throw cause;
260
+ // 跨卷:记忆是数据,**复制 + 删除**,与家当迁移的「不自动复制」不同。
261
+ cpSync(source, target, { recursive: true });
262
+ rmSync(source, { recursive: true, force: true });
263
+ }
264
+ moved.push(name);
265
+ }
266
+ }
267
+ catch (cause) {
268
+ return { status: 'failed', from, to, moved, reason: cause instanceof Error ? cause.message : String(cause) };
269
+ }
270
+ // 搬空了的旧段删掉:留着它会让人以为记忆还在知识树里(而且它会出现在「知识树
271
+ // 有哪几段」的扫描里)。还有东西没搬走就保留。
272
+ try {
273
+ rmdirSync(from);
274
+ }
275
+ catch { /* 还有别的东西在里面 */ }
276
+ if (moved.length === 0)
277
+ return skipped('记忆已经在新位置', from, to);
278
+ return { status: 'moved', from, to, moved, reason: `已把记忆搬到 ${to}(${moved.length} 项)` };
279
+ }
280
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * 召回链路的**纯函数**部分(0031):融合、boost、去冗余、证据抽取。
3
+ *
4
+ * 与 `graph/layout.ts`、`problem-domains.ts` 同一个理由:把不依赖 runtime、不碰磁盘的
5
+ * 那部分单独放,于是它们可以在 `node:test` 里被直接断言。这里的每个函数都对应 0031
6
+ * 的一个设计决定,注释写的是**为什么**,不是做了什么。
7
+ *
8
+ * @module
9
+ */
10
+ import type { RecallEvidence, RecallRoute } from './types.js';
11
+ /** 一路的排序结果(已过阈值、已按分数降序)。 */
12
+ export interface RouteRanking {
13
+ unitId: string;
14
+ /** 该路自己的分数,只用于阈值与展示 —— 融合不读它。 */
15
+ score: number;
16
+ }
17
+ export interface FusedHit {
18
+ unitId: string;
19
+ score: number;
20
+ /** 每一路的名次(1 起)。缺失 = 那一路没有召回它。 */
21
+ ranks: Partial<Record<RecallRoute, number>>;
22
+ }
23
+ export interface RrfOptions {
24
+ /** RRF 的平滑常数;越大越平(削弱第一名)。WeKnora 默认 60。 */
25
+ k: number;
26
+ weights: Partial<Record<RecallRoute, number>>;
27
+ }
28
+ /**
29
+ * 名次级融合(Reciprocal Rank Fusion)。
30
+ *
31
+ * **为什么不用分数加权和**:三路的分数是三个不同的量纲 —— 关键词是归一化 BM25、
32
+ * 向量是余弦、图谱是命中分/最大命中分。把它们乘权重相加,等于假设「0.5 的关键词分」
33
+ * 与「0.5 的余弦」一样好,而这个假设没有任何依据。0030 的实际后果就是:向量路输出
34
+ * 常数时,hybrid 的 55% 权重全是噪声,排序退化成 `unitId` 字典序(实测 4 条命中
35
+ * 分数完全相同:`0.2753 = 0.5 × 0.55`)。
36
+ *
37
+ * RRF 只吃**名次**,所以量纲问题从根上消失,而权重变成「我更信哪一路的排序」——
38
+ * 这是一个可以校准、也可以被解释的量。
39
+ */
40
+ export declare function rrfFuse(rankings: Partial<Record<RecallRoute, RouteRanking[]>>, options: RrfOptions): FusedHit[];
41
+ /**
42
+ * 图谱作为**boost**,不是第三路。
43
+ *
44
+ * 0009/0014 都把知识图谱定位为**构建产物**(wiki→图谱),没有把它当作召回路线;
45
+ * 而 0030 把它做成第三路时,匹配逻辑与关键词路同源(词面匹配 title / id / 关系词),
46
+ * 等于把关键词路的弱点复制一遍,还多贡献了一份不可比的分数。
47
+ *
48
+ * 现在的语义是:图谱命中的实体及其 1 跳邻居,**只给已经在候选池里的条目**加一个
49
+ * RRF 项。它因此不能凭自己制造候选(那是「路」的权力),只能重排(那是「boost」的
50
+ * 职责)—— 于是它既保留了「命中实体 → 带出邻居」的价值,又不会污染融合。
51
+ */
52
+ export declare function graphBoost(fused: FusedHit[], graphRanking: RouteRanking[], options: RrfOptions): {
53
+ hits: FusedHit[];
54
+ applied: number;
55
+ };
56
+ /**
57
+ * 按阈值裁剪一路的候选,并给出这一路的诊断。
58
+ *
59
+ * 关键词路的分是**相对**归一的(见 `fts.ts` 的量纲说明),所以这里的阈值挡得住
60
+ * 「弱命中」、挡不住「整批都弱」;向量路的分是原始余弦,是绝对的。两者都要如实
61
+ * 写进诊断,不能让人以为「过了阈值」等于「相关」。
62
+ */
63
+ export declare function applyThreshold(ranking: RouteRanking[], threshold: number): {
64
+ kept: RouteRanking[];
65
+ dropped: number;
66
+ topScore: number;
67
+ };
68
+ /**
69
+ * 从原文里挑出与查询最相关的若干段,作为**证据片段**。
70
+ *
71
+ * 为什么要有这一步:`context` 原来只带 wiki 卡片,模型要核对原文还得再调一次工具。
72
+ * 把证据放进上下文,「每一个数字都能指回它的口径定义与原始文档」才在上下文层面
73
+ * 成立,而不是靠模型自觉去查。
74
+ *
75
+ * 段落按空行切(Markdown 的自然段),逐段算**查询词覆盖率**,取最高的几段。
76
+ * 覆盖率是绝对的,所以「找不到相关段落」会如实返回空数组,而不是硬塞一段无关文字。
77
+ */
78
+ export declare function evidenceExcerpts(sourceId: string, title: string | undefined, text: string, queryTerms: string[], options?: {
79
+ maxExcerpts?: number;
80
+ maxChars?: number;
81
+ minCoverage?: number;
82
+ }): RecallEvidence[];
83
+ /**
84
+ * 一条 note 进关键词索引的**完整文本**。
85
+ *
86
+ * 它包含三部分:标题、正文、以及**溯源身份**(它引用的 sourceId 与那些来源的标题)。
87
+ * 溯源身份不是锦上添花:图谱降为 boost 之后,「只提到某份来源、没提到任何卡片正文」
88
+ * 的查询再也没有第二条路可走,所以「这份台账派生出了哪些结论」必须由关键词路回答。
89
+ *
90
+ * 这个函数被**两处**共用 —— 建索引时写进去的文本,与召回时算查询词覆盖率的文本。
91
+ * 两处各写一份的话,覆盖率会对着不同的文本算,好命中会被静默丢掉(实测:查 `ledger`
92
+ * 时索引命中了、覆盖率却是 0)。
93
+ */
94
+ export declare function noteIndexText(note: {
95
+ title: string;
96
+ content: string;
97
+ sourceRefs: string[];
98
+ }, titleOf: (sourceId: string) => string | undefined): string;
99
+ /** 一段文本的词集合,用于 MMR 的冗余度(Jaccard)。 */
100
+ export declare function tokenSet(text: string): Set<string>;
101
+ export interface MmrOptions<T> {
102
+ /** 相关性(通常就是融合分)。 */
103
+ relevance: (item: T) => number;
104
+ /** 该条目的词集合。 */
105
+ tokens: (item: T) => Set<string>;
106
+ /** 该条目属于哪张 wiki —— 用于「每张卡最多几条」的硬约束。 */
107
+ wikiKey: (item: T) => string;
108
+ /** 相关性 vs 多样性的权衡;0.7 = 偏相关性(与 WeKnora 的 grep_chunks 一致)。 */
109
+ lambda?: number;
110
+ /** 每张 wiki 最多入选几条。 */
111
+ perWikiCap?: number;
112
+ /** 总共要几条。 */
113
+ limit: number;
114
+ }
115
+ /**
116
+ * 选上下文条目:**每张 wiki 封顶 + MMR 去冗余**。
117
+ *
118
+ * 为什么必须有:0030 的图谱路刻意给同一张 wiki 的分节 note 0.8 的权重,于是 5 条上下文
119
+ * 可以全部来自同一张卡 —— 一屏塞满、信息量为 1。这是「召回质量差」里最容易被忽略的一半:
120
+ * 前 5 条不是「5 条相关」,而是「1 条相关的 5 个片段」。
121
+ *
122
+ * 冗余度用**词集合的 Jaccard**,不用向量:它对编码器是否可用不敏感,因此去冗余在
123
+ * 向量路降级时依然生效 —— 依赖一个可能坏掉的组件的功能,等于把它的可靠性绑在那个组件上。
124
+ */
125
+ export declare function selectContext<T>(items: T[], options: MmrOptions<T>): T[];
126
+ /** `match` 字段由名次推导:两路及以上命中 = hybrid。 */
127
+ export declare function matchOf(ranks: Partial<Record<RecallRoute, number>>): 'fts' | 'vector' | 'graph' | 'hybrid';
128
+ /** 展示用的概率:`rerankScore` 是 logit 的 sigmoid。 */
129
+ export declare function sigmoidLogit(logit: number): number;
130
+ export interface RerankOutcome<T> {
131
+ /** 过阈值的条目,按 logit 降序;`rerankScore` 是 logit 的 sigmoid。 */
132
+ kept: Array<T & {
133
+ rerankScore: number;
134
+ }>;
135
+ /** 被阈值丢掉的条数。 */
136
+ dropped: number;
137
+ /** 候选池里最高的 logit —— 跨查询可比的「这一批到底有多相关」。 */
138
+ topLogit: number;
139
+ }
140
+ /**
141
+ * Stage 4:**在 logit 刻度上**过阈值,展示值才做一次 sigmoid。
142
+ *
143
+ * 刻度必须只有一个。cross-encoder 的价值就在于此:它的分是**跨查询可比**的,
144
+ * 所以「低于 0.2 就不要」是一个绝对判据,而关键词/向量的阈值做不到这一点。
145
+ * 0031 落地时这里错了两层:
146
+ *
147
+ * 1. worker 用 `CrossEncoder.predict` 的默认行为,拿到的是 **sigmoid 之后**的值
148
+ * ((0,1)),却按 logit 阈值 0.2 去比 —— 于是 `dropped` 恒为 0,绝对闸门从未生效。
149
+ * 2. Host 又 sigmoid 了一次做展示,把无关文档(logit −10.2)显示成 `0.500`
150
+ * —— 一个「看起来刚好在门槛上」的分数。
151
+ *
152
+ * 现在 worker 返回 logit(`predict_raw`),阈值与排序都在 logit 上,展示只 sigmoid 一次。
153
+ * 这个函数是纯的,所以刻度这件事可以在 `node:test` 里被钉住。
154
+ */
155
+ export declare function applyRerank<T extends {
156
+ unitId: string;
157
+ }>(scores: number[], items: T[], threshold: number): RerankOutcome<T>;
158
+ //# sourceMappingURL=recall-rank.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall-rank.d.ts","sourceRoot":"","sources":["../../src/recall-rank.ts"],"names":[],"mappings":"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"}