dsh-data-domain-knowledge 0.1.0-alpha.9 → 0.1.1-alpha.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.
Files changed (438) hide show
  1. package/README.md +118 -567
  2. package/cordis.patch.yml +5 -418
  3. package/eval/README.md +19 -8
  4. package/eval/benchmark-extraction-format.mjs +20 -0
  5. package/eval/evaluate-retrieval.mjs +17 -8
  6. package/eval/queries.example.jsonl +1 -0
  7. package/lib/client.js +4181 -3239
  8. package/lib/contract-envelope.d.ts +91 -0
  9. package/lib/contract-envelope.js +106 -0
  10. package/lib/contract-layout.d.ts +130 -0
  11. package/lib/contract-layout.js +138 -0
  12. package/lib/contract-refs.d.ts +39 -0
  13. package/lib/contract-refs.js +9 -0
  14. package/lib/contract-version.d.ts +311 -0
  15. package/lib/contract-version.js +270 -0
  16. package/lib/contract-wire.d.ts +147 -0
  17. package/lib/contract-wire.js +99 -0
  18. package/lib/contracts.d.ts +12 -0
  19. package/lib/contracts.js +12 -0
  20. package/lib/doc-page.js +2 -2
  21. package/lib/pages.js +3329 -1296
  22. package/lib/types/agent-behavior-rules.d.ts +10 -0
  23. package/lib/types/agent-behavior-rules.d.ts.map +1 -0
  24. package/lib/types/agent-behavior-rules.js +28 -0
  25. package/lib/types/agent-behavior-rules.js.map +1 -0
  26. package/lib/types/axis-registry.d.ts +37 -5
  27. package/lib/types/axis-registry.d.ts.map +1 -1
  28. package/lib/types/axis-registry.js +234 -26
  29. package/lib/types/axis-registry.js.map +1 -1
  30. package/lib/types/card-organize.d.ts +27 -12
  31. package/lib/types/card-organize.d.ts.map +1 -1
  32. package/lib/types/card-organize.js +58 -73
  33. package/lib/types/card-organize.js.map +1 -1
  34. package/lib/types/compiler/embedding-identity.d.ts +3 -0
  35. package/lib/types/compiler/embedding-identity.d.ts.map +1 -0
  36. package/lib/types/compiler/embedding-identity.js +24 -0
  37. package/lib/types/compiler/embedding-identity.js.map +1 -0
  38. package/lib/types/compiler/snapshot.d.ts +16 -0
  39. package/lib/types/compiler/snapshot.d.ts.map +1 -0
  40. package/lib/types/compiler/snapshot.js +2 -0
  41. package/lib/types/compiler/snapshot.js.map +1 -0
  42. package/lib/types/config-schema.d.ts +6 -3
  43. package/lib/types/config-schema.d.ts.map +1 -1
  44. package/lib/types/config-schema.js +6 -2
  45. package/lib/types/config-schema.js.map +1 -1
  46. package/lib/types/convert/host.d.ts +6 -5
  47. package/lib/types/convert/host.d.ts.map +1 -1
  48. package/lib/types/convert/host.js +58 -18
  49. package/lib/types/convert/host.js.map +1 -1
  50. package/lib/types/convert/ingest.d.ts +10 -1
  51. package/lib/types/convert/ingest.d.ts.map +1 -1
  52. package/lib/types/convert/ingest.js +68 -9
  53. package/lib/types/convert/ingest.js.map +1 -1
  54. package/lib/types/derive-contract.d.ts +3 -0
  55. package/lib/types/derive-contract.d.ts.map +1 -0
  56. package/lib/types/derive-contract.js +15 -0
  57. package/lib/types/derive-contract.js.map +1 -0
  58. package/lib/types/diagnosis/cards.d.ts +7 -3
  59. package/lib/types/diagnosis/cards.d.ts.map +1 -1
  60. package/lib/types/diagnosis/cards.js +13 -8
  61. package/lib/types/diagnosis/cards.js.map +1 -1
  62. package/lib/types/diagnosis/run.d.ts +4 -13
  63. package/lib/types/diagnosis/run.d.ts.map +1 -1
  64. package/lib/types/diagnosis/run.js +26 -16
  65. package/lib/types/diagnosis/run.js.map +1 -1
  66. package/lib/types/diagnosis/schema.js +2 -2
  67. package/lib/types/diagnosis/schema.js.map +1 -1
  68. package/lib/types/diagnosis/seed-source.d.ts +1 -1
  69. package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
  70. package/lib/types/diagnosis/seed-source.js +5 -4
  71. package/lib/types/diagnosis/seed-source.js.map +1 -1
  72. package/lib/types/diagnosis/seed.d.ts +4 -4
  73. package/lib/types/diagnosis/seed.d.ts.map +1 -1
  74. package/lib/types/diagnosis/seed.js +6 -8
  75. package/lib/types/diagnosis/seed.js.map +1 -1
  76. package/lib/types/diagnosis/store.d.ts +24 -18
  77. package/lib/types/diagnosis/store.d.ts.map +1 -1
  78. package/lib/types/diagnosis/store.js +130 -65
  79. package/lib/types/diagnosis/store.js.map +1 -1
  80. package/lib/types/diagnosis/types.d.ts +47 -15
  81. package/lib/types/diagnosis/types.d.ts.map +1 -1
  82. package/lib/types/diagnosis/types.js.map +1 -1
  83. package/lib/types/environment/dsh-python.d.ts +77 -0
  84. package/lib/types/environment/dsh-python.d.ts.map +1 -0
  85. package/lib/types/environment/dsh-python.js +139 -0
  86. package/lib/types/environment/dsh-python.js.map +1 -0
  87. package/lib/types/environment/install.d.ts +15 -0
  88. package/lib/types/environment/install.d.ts.map +1 -0
  89. package/lib/types/environment/install.js +297 -0
  90. package/lib/types/environment/install.js.map +1 -0
  91. package/lib/types/environment/manifest.d.ts +208 -0
  92. package/lib/types/environment/manifest.d.ts.map +1 -0
  93. package/lib/types/environment/manifest.js +26 -0
  94. package/lib/types/environment/manifest.js.map +1 -0
  95. package/lib/types/environment/model-catalog.d.ts +223 -0
  96. package/lib/types/environment/model-catalog.d.ts.map +1 -0
  97. package/lib/types/environment/model-catalog.js +129 -0
  98. package/lib/types/environment/model-catalog.js.map +1 -0
  99. package/lib/types/environment/process.d.ts +10 -0
  100. package/lib/types/environment/process.d.ts.map +1 -0
  101. package/lib/types/environment/process.js +54 -0
  102. package/lib/types/environment/process.js.map +1 -0
  103. package/lib/types/environment/selection.d.ts +9 -0
  104. package/lib/types/environment/selection.d.ts.map +1 -0
  105. package/lib/types/environment/selection.js +29 -0
  106. package/lib/types/environment/selection.js.map +1 -0
  107. package/lib/types/environment/service.d.ts +64 -0
  108. package/lib/types/environment/service.d.ts.map +1 -0
  109. package/lib/types/environment/service.js +424 -0
  110. package/lib/types/environment/service.js.map +1 -0
  111. package/lib/types/environment/types.d.ts +56 -0
  112. package/lib/types/environment/types.d.ts.map +1 -0
  113. package/lib/types/environment/types.js +2 -0
  114. package/lib/types/environment/types.js.map +1 -0
  115. package/lib/types/events.d.ts +76 -0
  116. package/lib/types/events.d.ts.map +1 -0
  117. package/lib/types/events.js +52 -0
  118. package/lib/types/events.js.map +1 -0
  119. package/lib/types/extract-contract.d.ts +3 -0
  120. package/lib/types/extract-contract.d.ts.map +1 -0
  121. package/lib/types/extract-contract.js +41 -0
  122. package/lib/types/extract-contract.js.map +1 -0
  123. package/lib/types/extract-model.d.ts +5 -0
  124. package/lib/types/extract-model.d.ts.map +1 -1
  125. package/lib/types/extract-model.js.map +1 -1
  126. package/lib/types/extract-table-contract.d.ts +3 -0
  127. package/lib/types/extract-table-contract.d.ts.map +1 -0
  128. package/lib/types/extract-table-contract.js +27 -0
  129. package/lib/types/extract-table-contract.js.map +1 -0
  130. package/lib/types/extract-table.d.ts +8 -0
  131. package/lib/types/extract-table.d.ts.map +1 -0
  132. package/lib/types/extract-table.js +158 -0
  133. package/lib/types/extract-table.js.map +1 -0
  134. package/lib/types/extraction-runs.d.ts +30 -6
  135. package/lib/types/extraction-runs.d.ts.map +1 -1
  136. package/lib/types/extraction-runs.js +69 -8
  137. package/lib/types/extraction-runs.js.map +1 -1
  138. package/lib/types/fs-atomic.d.ts +0 -7
  139. package/lib/types/fs-atomic.d.ts.map +1 -1
  140. package/lib/types/fs-atomic.js +17 -2
  141. package/lib/types/fs-atomic.js.map +1 -1
  142. package/lib/types/images.d.ts +26 -0
  143. package/lib/types/images.d.ts.map +1 -0
  144. package/lib/types/images.js +196 -0
  145. package/lib/types/images.js.map +1 -0
  146. package/lib/types/index.d.ts +2 -2
  147. package/lib/types/index.d.ts.map +1 -1
  148. package/lib/types/index.js +598 -209
  149. package/lib/types/index.js.map +1 -1
  150. package/lib/types/intent/engine.d.ts +12 -4
  151. package/lib/types/intent/engine.d.ts.map +1 -1
  152. package/lib/types/intent/engine.js +43 -5
  153. package/lib/types/intent/engine.js.map +1 -1
  154. package/lib/types/intent/host.d.ts +5 -8
  155. package/lib/types/intent/host.d.ts.map +1 -1
  156. package/lib/types/intent/host.js +56 -11
  157. package/lib/types/intent/host.js.map +1 -1
  158. package/lib/types/intent/scope.d.ts +25 -0
  159. package/lib/types/intent/scope.d.ts.map +1 -0
  160. package/lib/types/intent/scope.js +116 -0
  161. package/lib/types/intent/scope.js.map +1 -0
  162. package/lib/types/intent/tools.d.ts +24 -20
  163. package/lib/types/intent/tools.d.ts.map +1 -1
  164. package/lib/types/intent/tools.js +65 -23
  165. package/lib/types/intent/tools.js.map +1 -1
  166. package/lib/types/intent/types.d.ts +11 -4
  167. package/lib/types/intent/types.d.ts.map +1 -1
  168. package/lib/types/knowledge-bases.d.ts +11 -5
  169. package/lib/types/knowledge-bases.d.ts.map +1 -1
  170. package/lib/types/knowledge-bases.js +52 -20
  171. package/lib/types/knowledge-bases.js.map +1 -1
  172. package/lib/types/knowledge-contract.d.ts +32 -0
  173. package/lib/types/knowledge-contract.d.ts.map +1 -0
  174. package/lib/types/knowledge-contract.js +116 -0
  175. package/lib/types/knowledge-contract.js.map +1 -0
  176. package/lib/types/knowledge.d.ts +31 -9
  177. package/lib/types/knowledge.d.ts.map +1 -1
  178. package/lib/types/knowledge.js +137 -60
  179. package/lib/types/knowledge.js.map +1 -1
  180. package/lib/types/layout.d.ts +10 -29
  181. package/lib/types/layout.d.ts.map +1 -1
  182. package/lib/types/layout.js +17 -36
  183. package/lib/types/layout.js.map +1 -1
  184. package/lib/types/materialize-snapshot.d.ts +49 -0
  185. package/lib/types/materialize-snapshot.d.ts.map +1 -0
  186. package/lib/types/materialize-snapshot.js +2 -0
  187. package/lib/types/materialize-snapshot.js.map +1 -0
  188. package/lib/types/migrate.d.ts +11 -0
  189. package/lib/types/migrate.d.ts.map +1 -1
  190. package/lib/types/migrate.js +83 -2
  191. package/lib/types/migrate.js.map +1 -1
  192. package/lib/types/model-text.d.ts +58 -1
  193. package/lib/types/model-text.d.ts.map +1 -1
  194. package/lib/types/model-text.js +85 -30
  195. package/lib/types/model-text.js.map +1 -1
  196. package/lib/types/oplog.d.ts.map +1 -1
  197. package/lib/types/oplog.js +7 -0
  198. package/lib/types/oplog.js.map +1 -1
  199. package/lib/types/organize-contract.d.ts +18 -0
  200. package/lib/types/organize-contract.d.ts.map +1 -0
  201. package/lib/types/organize-contract.js +82 -0
  202. package/lib/types/organize-contract.js.map +1 -0
  203. package/lib/types/pipeline/engine.d.ts +66 -0
  204. package/lib/types/pipeline/engine.d.ts.map +1 -0
  205. package/lib/types/pipeline/engine.js +352 -0
  206. package/lib/types/pipeline/engine.js.map +1 -0
  207. package/lib/types/pipeline/store.d.ts +73 -0
  208. package/lib/types/pipeline/store.d.ts.map +1 -0
  209. package/lib/types/pipeline/store.js +143 -0
  210. package/lib/types/pipeline/store.js.map +1 -0
  211. package/lib/types/pipeline/types.d.ts +102 -0
  212. package/lib/types/pipeline/types.d.ts.map +1 -0
  213. package/lib/types/pipeline/types.js +5 -0
  214. package/lib/types/pipeline/types.js.map +1 -0
  215. package/lib/types/present.d.ts +2 -0
  216. package/lib/types/present.d.ts.map +1 -1
  217. package/lib/types/present.js +9 -4
  218. package/lib/types/present.js.map +1 -1
  219. package/lib/types/preset-ids.d.ts +4 -0
  220. package/lib/types/preset-ids.d.ts.map +1 -0
  221. package/lib/types/preset-ids.js +6 -0
  222. package/lib/types/preset-ids.js.map +1 -0
  223. package/lib/types/query-analysis.d.ts +13 -1
  224. package/lib/types/query-analysis.d.ts.map +1 -1
  225. package/lib/types/query-analysis.js +62 -6
  226. package/lib/types/query-analysis.js.map +1 -1
  227. package/lib/types/recall-rank.d.ts +3 -3
  228. package/lib/types/recall-rank.d.ts.map +1 -1
  229. package/lib/types/recall-rank.js +4 -4
  230. package/lib/types/recall-rank.js.map +1 -1
  231. package/lib/types/retention.d.ts +39 -0
  232. package/lib/types/retention.d.ts.map +1 -0
  233. package/lib/types/retention.js +42 -0
  234. package/lib/types/retention.js.map +1 -0
  235. package/lib/types/retrieval/vector-index.d.ts +32 -0
  236. package/lib/types/retrieval/vector-index.d.ts.map +1 -0
  237. package/lib/types/retrieval/vector-index.js +15 -0
  238. package/lib/types/retrieval/vector-index.js.map +1 -0
  239. package/lib/types/retrieval/visibility.d.ts +6 -0
  240. package/lib/types/retrieval/visibility.d.ts.map +1 -0
  241. package/lib/types/retrieval/visibility.js +11 -0
  242. package/lib/types/retrieval/visibility.js.map +1 -0
  243. package/lib/types/runtime.d.ts +272 -27
  244. package/lib/types/runtime.d.ts.map +1 -1
  245. package/lib/types/runtime.js +2751 -537
  246. package/lib/types/runtime.js.map +1 -1
  247. package/lib/types/settings-schema.d.ts +17 -15
  248. package/lib/types/settings-schema.d.ts.map +1 -1
  249. package/lib/types/settings-schema.js +50 -47
  250. package/lib/types/settings-schema.js.map +1 -1
  251. package/lib/types/settings-volatile.d.ts +4 -4
  252. package/lib/types/settings-volatile.js +4 -4
  253. package/lib/types/source-evidence.d.ts +14 -0
  254. package/lib/types/source-evidence.d.ts.map +1 -0
  255. package/lib/types/source-evidence.js +36 -0
  256. package/lib/types/source-evidence.js.map +1 -0
  257. package/lib/types/store/axis-references.d.ts +5 -0
  258. package/lib/types/store/axis-references.d.ts.map +1 -0
  259. package/lib/types/store/axis-references.js +106 -0
  260. package/lib/types/store/axis-references.js.map +1 -0
  261. package/lib/types/store/derived.d.ts +12 -1
  262. package/lib/types/store/derived.d.ts.map +1 -1
  263. package/lib/types/store/derived.js +71 -12
  264. package/lib/types/store/derived.js.map +1 -1
  265. package/lib/types/store/knowledge-db.d.ts +31 -1
  266. package/lib/types/store/knowledge-db.d.ts.map +1 -1
  267. package/lib/types/store/knowledge-db.js +252 -18
  268. package/lib/types/store/knowledge-db.js.map +1 -1
  269. package/lib/types/store/migrate.d.ts.map +1 -1
  270. package/lib/types/store/migrate.js +17 -6
  271. package/lib/types/store/migrate.js.map +1 -1
  272. package/lib/types/trajectory-types.d.ts +172 -0
  273. package/lib/types/trajectory-types.d.ts.map +1 -0
  274. package/lib/types/trajectory-types.js +36 -0
  275. package/lib/types/trajectory-types.js.map +1 -0
  276. package/lib/types/types.d.ts +59 -27
  277. package/lib/types/types.d.ts.map +1 -1
  278. package/lib/types/types.js +6 -15
  279. package/lib/types/types.js.map +1 -1
  280. package/lib/types/wiki-finalize.d.ts +16 -0
  281. package/lib/types/wiki-finalize.d.ts.map +1 -1
  282. package/lib/types/wiki-finalize.js +26 -0
  283. package/lib/types/wiki-finalize.js.map +1 -1
  284. package/lib/types/wiki-materialize.d.ts +4 -0
  285. package/lib/types/wiki-materialize.d.ts.map +1 -1
  286. package/lib/types/wiki-materialize.js +21 -7
  287. package/lib/types/wiki-materialize.js.map +1 -1
  288. package/lib/types/wiki-trial-types.d.ts +87 -0
  289. package/lib/types/wiki-trial-types.d.ts.map +1 -1
  290. package/lib/types/wiki-trial-types.js +0 -16
  291. package/lib/types/wiki-trial-types.js.map +1 -1
  292. package/lib/types/wiki-trial.d.ts +40 -16
  293. package/lib/types/wiki-trial.d.ts.map +1 -1
  294. package/lib/types/wiki-trial.js +337 -224
  295. package/lib/types/wiki-trial.js.map +1 -1
  296. package/package.json +29 -20
  297. package/python/prepare-models.py +19 -0
  298. package/python/requirements.txt +8 -6
  299. package/scripts/doctor.mjs +13 -19
  300. package/scripts/environment.mjs +29 -0
  301. package/scripts/setup-embedding.sh +15 -5
  302. package/src/agent-behavior-rules.ts +37 -0
  303. package/src/axis-registry.ts +234 -27
  304. package/src/card-organize.ts +69 -75
  305. package/src/client/AgentBehaviorRulesCard.tsx +65 -0
  306. package/src/client/AttributionEventGuide.tsx +41 -39
  307. package/src/client/AxisRegistrySection.tsx +204 -164
  308. package/src/client/CompileDialogs.tsx +44 -29
  309. package/src/client/DeleteDocumentDialog.tsx +36 -5
  310. package/src/client/DirectoryPicker.tsx +0 -10
  311. package/src/client/EnvironmentSetup.tsx +243 -0
  312. package/src/client/ExpansionGraph.tsx +13 -7
  313. package/src/client/ExtractionTasksPage.tsx +578 -0
  314. package/src/client/GuideArchitectureCanvas.tsx +470 -0
  315. package/src/client/ImportFilesDialog.tsx +2 -13
  316. package/src/client/IntentLogic.tsx +2 -2
  317. package/src/client/IntentTab.tsx +118 -47
  318. package/src/client/KnowledgeBaseTab.tsx +277 -197
  319. package/src/client/KnowledgeLayerSection.tsx +24 -6
  320. package/src/client/KnowledgePanel.tsx +58 -93
  321. package/src/client/KnowledgeSettingsDrawer.tsx +90 -0
  322. package/src/client/ListPager.tsx +15 -5
  323. package/src/client/MaterializeTrajectoryView.tsx +124 -0
  324. package/src/client/NodeSettings.tsx +210 -89
  325. package/src/client/NormalizeTrajectoryView.tsx +136 -0
  326. package/src/client/PipelineNotice.tsx +26 -0
  327. package/src/client/PreviewSections.tsx +118 -51
  328. package/src/client/RecallPanel.tsx +89 -85
  329. package/src/client/TabGuide.tsx +159 -184
  330. package/src/client/TrialReportView.tsx +391 -214
  331. package/src/client/TypeDefinitionDrawer.tsx +150 -23
  332. package/src/client/WikiCardPreview.tsx +62 -16
  333. package/src/client/WikiFlowPanel.tsx +4 -4
  334. package/src/client/arch/NodeLogicPanel.tsx +3 -4
  335. package/src/client/arch/model.ts +6 -9
  336. package/src/client/architecture.tsx +23 -33
  337. package/src/client/attribution/AttributionGraph.tsx +10 -6
  338. package/src/client/attribution/AttributionTab.tsx +136 -84
  339. package/src/client/attribution/CaseView.tsx +3 -1
  340. package/src/client/attribution/EventView.tsx +108 -0
  341. package/src/client/attribution/RunView.tsx +2 -2
  342. package/src/client/attribution/StageChrome.tsx +34 -3
  343. package/src/client/attribution/ViewSwitch.tsx +20 -5
  344. package/src/client/attribution/graph-options.ts +47 -39
  345. package/src/client/attribution/model.ts +17 -10
  346. package/src/client/config-scope.ts +3 -3
  347. package/src/client/graph/palette.ts +165 -0
  348. package/src/client/index.ts +49 -42
  349. package/src/client/pages.css +459 -135
  350. package/src/client/pages.tsx +37 -9
  351. package/src/client/problem-domains.ts +1 -1
  352. package/src/client/session-remote.ts +9 -0
  353. package/src/client/styles.css +205 -62
  354. package/src/client/wiki-trial.ts +44 -3
  355. package/src/compiler/embedding-identity.ts +21 -0
  356. package/src/compiler/snapshot.ts +17 -0
  357. package/src/config-schema.ts +8 -3
  358. package/src/convert/host.ts +56 -21
  359. package/src/convert/ingest.ts +74 -10
  360. package/src/derive-contract.ts +14 -0
  361. package/src/diagnosis/cards.ts +13 -8
  362. package/src/diagnosis/run.ts +27 -17
  363. package/src/diagnosis/schema.ts +2 -2
  364. package/src/diagnosis/seed-source.ts +5 -4
  365. package/src/diagnosis/seed.ts +6 -8
  366. package/src/diagnosis/store.ts +138 -69
  367. package/src/diagnosis/types.ts +34 -15
  368. package/src/environment/dsh-python.ts +156 -0
  369. package/src/environment/install.ts +244 -0
  370. package/src/environment/manifest.ts +28 -0
  371. package/src/environment/model-catalog.ts +147 -0
  372. package/src/environment/process.ts +54 -0
  373. package/src/environment/selection.ts +29 -0
  374. package/src/environment/service.ts +348 -0
  375. package/src/environment/types.ts +45 -0
  376. package/src/events.ts +108 -0
  377. package/src/extract-contract.ts +42 -0
  378. package/src/extract-model.ts +10 -1
  379. package/src/extract-table-contract.ts +26 -0
  380. package/src/extract-table.ts +132 -0
  381. package/src/extraction-runs.ts +70 -11
  382. package/src/fs-atomic.ts +19 -2
  383. package/src/images.ts +203 -0
  384. package/src/index.ts +553 -205
  385. package/src/intent/README.md +8 -6
  386. package/src/intent/engine.ts +44 -6
  387. package/src/intent/host.ts +59 -18
  388. package/src/intent/scope.ts +125 -0
  389. package/src/intent/tools.ts +70 -28
  390. package/src/intent/types.ts +11 -4
  391. package/src/knowledge-bases.ts +56 -20
  392. package/src/knowledge-contract.ts +114 -0
  393. package/src/knowledge.ts +138 -69
  394. package/src/layout.ts +17 -37
  395. package/src/materialize-snapshot.ts +46 -0
  396. package/src/migrate.ts +75 -2
  397. package/src/model-text.ts +109 -4
  398. package/src/oplog.ts +7 -0
  399. package/src/organize-contract.ts +83 -0
  400. package/src/pipeline/engine.ts +323 -0
  401. package/src/pipeline/store.ts +147 -0
  402. package/src/pipeline/types.ts +93 -0
  403. package/src/present.ts +10 -4
  404. package/src/preset-ids.ts +6 -0
  405. package/src/python/embedding_worker.py +66 -2
  406. package/src/query-analysis.ts +68 -8
  407. package/src/recall-rank.ts +5 -5
  408. package/src/retention.ts +76 -0
  409. package/src/retrieval/vector-index.ts +45 -0
  410. package/src/retrieval/visibility.ts +14 -0
  411. package/src/runtime.ts +2708 -567
  412. package/src/settings-schema.ts +11 -8
  413. package/src/settings-volatile.ts +4 -4
  414. package/src/source-evidence.ts +37 -0
  415. package/src/store/axis-references.ts +96 -0
  416. package/src/store/derived.ts +70 -12
  417. package/src/store/knowledge-db.ts +248 -17
  418. package/src/store/migrate.ts +16 -6
  419. package/src/trajectory-types.ts +142 -0
  420. package/src/types.ts +61 -35
  421. package/src/wiki-finalize.ts +28 -0
  422. package/src/wiki-materialize.ts +25 -6
  423. package/src/wiki-trial-types.ts +83 -1
  424. package/src/wiki-trial.ts +357 -185
  425. package/lib/types/intent/preset-tools.d.ts +0 -37
  426. package/lib/types/intent/preset-tools.d.ts.map +0 -1
  427. package/lib/types/intent/preset-tools.js +0 -45
  428. package/lib/types/intent/preset-tools.js.map +0 -1
  429. package/preset/tita-data-agent/agent.cordis.yml +0 -394
  430. package/preset/tita-data-agent/preset.yml +0 -3
  431. package/scripts/install-agent-preset.mjs +0 -92
  432. package/scripts/sync-agent-preset.mjs +0 -188
  433. package/src/client/AgentPresetCard.tsx +0 -247
  434. package/src/client/agent-preset.ts +0 -121
  435. package/src/client/convert/ConvertPanel.tsx +0 -583
  436. package/src/client/convert/styles.css +0 -138
  437. package/src/client/convert/styles.ts +0 -49
  438. package/src/intent/preset-tools.ts +0 -48
@@ -0,0 +1,10 @@
1
+ export interface AgentBehaviorRuleSet {
2
+ id: string;
3
+ label: string;
4
+ rules: readonly string[];
5
+ }
6
+ export declare const AGENT_BEHAVIOR_RULE_SETS: readonly AgentBehaviorRuleSet[];
7
+ /** Return the exact prompt fragment for Standard mode; other presets get no additions. */
8
+ export declare function behaviorRulesForPreset(presetId: unknown): string;
9
+ export declare function behaviorPromptForPreset(presetId: unknown, enabled?: boolean): string;
10
+ //# sourceMappingURL=agent-behavior-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-behavior-rules.d.ts","sourceRoot":"","sources":["../../src/agent-behavior-rules.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED,eAAO,MAAM,wBAAwB,EAAE,SAAS,oBAAoB,EAEnE,CAAA;AAED,0FAA0F;AAC1F,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAIhE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,UAAO,GAAG,MAAM,CAEjF"}
@@ -0,0 +1,28 @@
1
+ import { STANDARD_PRESET_ID } from './preset-ids.js';
2
+ /** Rules added to DSH Standard mode. Keep this list as the UI and prompt source of truth. */
3
+ const STANDARD_RULES = [
4
+ '数据或知识任务开始时调用 `intent_record`;寒暄、闲聊、纯写作、代码和一般运维任务不记录。',
5
+ '组织内部的定义、指标口径、规则、流程和历史优先查内部知识;用户提供的材料直接读取。来源冲突或需要原文时查源文档。',
6
+ '不要编造事实或数字。结论使用可追溯且仍适用的工具结果或用户材料;关键指标说明计算口径,影响结论的不确定性必须说明。数据过期、范围改变或证据不足时,先补查再下结论。',
7
+ '复用已确认的 ID;目标或 ID 未知时先查目录或数据字典。优先用工具查明知识和数据;只有目标、选择或授权确实无法查明时才向用户确认。只调用与当前任务有关的工具。',
8
+ '报告、表格、图表等交付文件放在当前会话工作区的 `output/<YYYY-MM-DD>/`,日期取本地日期;给出实际路径。代码仓库源文件留在仓库原位置。',
9
+ '交付文件使用有含义的中文名,名称部分不超过 25 字;只保留汉字、字母、数字和 `-_.`,其他字符替换成 `-`。文件名不重复写日期,不覆盖已有文件,重名时追加 `-2`、`-3`。',
10
+ '确认操作成功后再报告完成;后台任务已提交不代表已完成。',
11
+ '使用用户的语言,默认中文;先说结论,再给必要依据和来源。用常见词和短句,解释必要术语,删掉套话和重复。只在有助理解时使用标题、列表或表格。',
12
+ '知识库只通过知识工具读写,且只执行用户已要求或已授权的写入。转换、入库和编译是独立步骤;默认导入只保存来源,编译需明确要求。',
13
+ 'Wiki Fact 与 Wiki Way 由编译器维护;先明确当前子问题,再检索可用 Procedure。命中章节用于定位,采用时读取完整 Wiki 的条件与边界。历史 Case 只证明当时的过程和结果,不能直接作为当前根因;审核由人完成。',
14
+ ];
15
+ export const AGENT_BEHAVIOR_RULE_SETS = [
16
+ { id: STANDARD_PRESET_ID, label: '标准模式', rules: STANDARD_RULES },
17
+ ];
18
+ /** Return the exact prompt fragment for Standard mode; other presets get no additions. */
19
+ export function behaviorRulesForPreset(presetId) {
20
+ const ruleSet = AGENT_BEHAVIOR_RULE_SETS.find(item => item.id === presetId);
21
+ if (!ruleSet)
22
+ return '';
23
+ return [`## 数据与知识任务规则(${ruleSet.label})`, ...ruleSet.rules.map(rule => `- ${rule}`)].join('\n');
24
+ }
25
+ export function behaviorPromptForPreset(presetId, enabled = true) {
26
+ return enabled ? behaviorRulesForPreset(presetId) : '';
27
+ }
28
+ //# sourceMappingURL=agent-behavior-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-behavior-rules.js","sourceRoot":"","sources":["../../src/agent-behavior-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD,6FAA6F;AAC7F,MAAM,cAAc,GAAG;IACrB,sDAAsD;IACtD,0DAA0D;IAC1D,mFAAmF;IACnF,mFAAmF;IACnF,+EAA+E;IAC/E,8FAA8F;IAC9F,6BAA6B;IAC7B,uEAAuE;IACvE,gEAAgE;IAChE,0HAA0H;CAClH,CAAA;AAQV,MAAM,CAAC,MAAM,wBAAwB,GAAoC;IACvE,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE;CACjE,CAAA;AAED,0FAA0F;AAC1F,MAAM,UAAU,sBAAsB,CAAC,QAAiB;IACtD,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAA;IAC3E,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IACvB,OAAO,CAAC,gBAAgB,OAAO,CAAC,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAiB,EAAE,OAAO,GAAG,IAAI;IACvE,OAAO,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACxD,CAAC"}
@@ -34,11 +34,24 @@
34
34
  * ## 为什么存在记忆段
35
35
  *
36
36
  * 注册表**不可重建**:它是人确认过的命名决定(改 canonical name、并两个实体、加一个别名),
37
- * 重跑一次抽取不会得到同样的结果。所以它和操作日志、抽取轨迹一样落在
38
- * `<memoryDir>/knowledge.sqlite`,不在 `03_compiled/`。
37
+ * 重跑一次抽取不会得到同样的结果。所以它与 Knowledge 共享 `knowledge.db`,
38
+ * 经过同一个属主与 schema 版本入口校验。
39
39
  */
40
+ import { type SqliteDatabase } from './fts.js';
40
41
  /** 三个轴。三者地位相同(§3.1)—— 没有哪个更特殊。 */
41
42
  export type AxisKind = 'object' | 'action' | 'scene';
43
+ /** 当前参与关系扩展召回的轴关系。它连接相关对象,不表示父子层级。 */
44
+ export declare const AXIS_RELATION_TYPES: readonly ["related_to"];
45
+ export type AxisRelationType = typeof AXIS_RELATION_TYPES[number];
46
+ export interface AxisRelation {
47
+ id: string;
48
+ fromId: string;
49
+ toId: string;
50
+ relationType: AxisRelationType;
51
+ evidence: string;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ }
42
55
  /**
43
56
  * 一个轴实体的状态。
44
57
  *
@@ -139,9 +152,19 @@ export declare function axisId(kind: AxisKind, name: string): string;
139
152
  */
140
153
  export declare class AxisRegistry {
141
154
  private readonly file;
155
+ private readonly shared?;
142
156
  private db;
143
- constructor(file: string);
157
+ private owner;
158
+ constructor(file: string, shared?: SqliteDatabase | undefined);
144
159
  open(): Promise<boolean>;
160
+ inputRevision(): number;
161
+ /** Resolve against an isolated copy; commit only if the live registry still matches. */
162
+ draft(): Promise<{
163
+ registry: AxisRegistry;
164
+ commit: () => void;
165
+ close: () => void;
166
+ }>;
167
+ private changedInput;
145
168
  available(): boolean;
146
169
  /**
147
170
  * 把一个 mention 解析成 canonical 实体。
@@ -187,6 +210,12 @@ export declare class AxisRegistry {
187
210
  list(kind?: AxisKind, status?: AxisStatus): Promise<Array<AxisEntity & {
188
211
  aliases: string[];
189
212
  }>>;
213
+ /** 列出对象关系;传实体 id 时只返回它的邻接关系。 */
214
+ listRelations(entityId?: string): Promise<AxisRelation[]>;
215
+ /** 建立无方向的 related_to 边;同一个对象不能关联自己。 */
216
+ addRelation(fromId: string, toId: string, evidence?: string): Promise<AxisRelation | null>;
217
+ /** 移除一条对象关系。 */
218
+ removeRelation(id: string): Promise<boolean>;
190
219
  /** 每个轴各有多少个实体、其中几个待人确认。类型定义那一屏的计数读它。 */
191
220
  stats(): Promise<Record<AxisKind, {
192
221
  total: number;
@@ -212,7 +241,9 @@ export declare class AxisRegistry {
212
241
  * 它转成 `merged`,`scopeId` 改存目标 id —— 复用这一列而不是新加一列,因为
213
242
  * 「它现在归谁」与「它在谁的下面」对解析来说问的是同一件事。
214
243
  */
215
- merge(fromId: string, intoId: string): Promise<boolean>;
244
+ merge(fromId: string, intoId: string, redirect?: (kind: AxisKind) => void): Promise<boolean>;
245
+ /** 合并轴实体时转移相关关系,并折叠重复边与自环。 */
246
+ private redirectRelations;
216
247
  /**
217
248
  * 人改定义。**写了就是决定**:`description_source` 落成 `human`,模型从此不许覆盖。
218
249
  */
@@ -277,7 +308,8 @@ export declare class AxisRegistry {
277
308
  }>;
278
309
  close(): void;
279
310
  private findCanonical;
280
- private findAlias;
311
+ /** 作用域内的别名命中。**可能不止一条** —— 调用方必须自己判唯一性。 */
312
+ private findAliases;
281
313
  /** 全局 canonical 名精确命中。它可能不止一个 —— 两个实体同名时就是歧义。 */
282
314
  private findCanonicalGlobal;
283
315
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"axis-registry.d.ts","sourceRoot":"","sources":["../../src/axis-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"axis-registry.d.ts","sourceRoot":"","sources":["../../src/axis-registry.ts"],"names":[],"mappings":"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"}
@@ -34,12 +34,14 @@
34
34
  * ## 为什么存在记忆段
35
35
  *
36
36
  * 注册表**不可重建**:它是人确认过的命名决定(改 canonical name、并两个实体、加一个别名),
37
- * 重跑一次抽取不会得到同样的结果。所以它和操作日志、抽取轨迹一样落在
38
- * `<memoryDir>/knowledge.sqlite`,不在 `03_compiled/`。
37
+ * 重跑一次抽取不会得到同样的结果。所以它与 Knowledge 共享 `knowledge.db`,
38
+ * 经过同一个属主与 schema 版本入口校验。
39
39
  */
40
- import { mkdir } from 'node:fs/promises';
41
- import { dirname } from 'node:path';
40
+ import { createHash } from 'node:crypto';
42
41
  import { loadSqlite } from './fts.js';
42
+ import { KnowledgeDb } from './store/knowledge-db.js';
43
+ /** 当前参与关系扩展召回的轴关系。它连接相关对象,不表示父子层级。 */
44
+ export const AXIS_RELATION_TYPES = ['related_to'];
43
45
  export const AXIS_GUIDANCE_KINDS = ['prefer_name', 'do_not_merge', 'scope_rule', 'definition', 'extraction_hint'];
44
46
  /**
45
47
  * 轴名归一:全半角、大小写、空格、连接符。
@@ -119,6 +121,18 @@ CREATE TABLE IF NOT EXISTS entity_guidance (
119
121
  created_at TEXT NOT NULL
120
122
  );
121
123
  CREATE INDEX IF NOT EXISTS idx_axis_guidance_entity ON entity_guidance(entity_id);
124
+ CREATE TABLE IF NOT EXISTS axis_relations (
125
+ id TEXT PRIMARY KEY,
126
+ from_id TEXT NOT NULL,
127
+ to_id TEXT NOT NULL,
128
+ relation_type TEXT NOT NULL,
129
+ evidence TEXT NOT NULL DEFAULT '',
130
+ created_at TEXT NOT NULL,
131
+ updated_at TEXT NOT NULL,
132
+ UNIQUE(from_id, to_id, relation_type)
133
+ );
134
+ CREATE INDEX IF NOT EXISTS idx_axis_relation_from ON axis_relations(from_id, relation_type);
135
+ CREATE INDEX IF NOT EXISTS idx_axis_relation_to ON axis_relations(to_id, relation_type);
122
136
  `;
123
137
  /**
124
138
  * 三个轴共用一个注册表。
@@ -128,9 +142,12 @@ CREATE INDEX IF NOT EXISTS idx_axis_guidance_entity ON entity_guidance(entity_id
128
142
  */
129
143
  export class AxisRegistry {
130
144
  file;
145
+ shared;
131
146
  db = null;
132
- constructor(file) {
147
+ owner = null;
148
+ constructor(file, shared) {
133
149
  this.file = file;
150
+ this.shared = shared;
134
151
  }
135
152
  async open() {
136
153
  if (this.db !== null)
@@ -139,12 +156,20 @@ export class AxisRegistry {
139
156
  if (sqlite === null)
140
157
  return false;
141
158
  try {
142
- await mkdir(dirname(this.file), { recursive: true });
143
- this.db = new sqlite.DatabaseSync(this.file);
159
+ if (this.shared)
160
+ this.db = this.shared;
161
+ else {
162
+ const opened = await KnowledgeDb.open(this.file, sqlite.DatabaseSync);
163
+ if (!opened.ok)
164
+ return false;
165
+ this.owner = opened.db;
166
+ this.db = opened.db.connection();
167
+ }
144
168
  this.db.exec(SCHEMA);
169
+ this.db.exec('CREATE TABLE IF NOT EXISTS axis_input_revision (id INTEGER PRIMARY KEY CHECK(id = 1), revision INTEGER NOT NULL); INSERT OR IGNORE INTO axis_input_revision VALUES (1, 0)');
145
170
  /*
146
- * 补列。这个库**没有 `user_version` 那一套**(它是记忆段里的一张注册表,不是知识本体),
147
- * 所以判据落在列上:缺就补,补齐之后什么都不做。`CREATE TABLE IF NOT EXISTS` 对
171
+ * 主库已通过 `user_version` 校验,再幂等补齐存量注册表的扩展列。缺就补。
172
+ * `CREATE TABLE IF NOT EXISTS` 对
148
173
  * 已经存在的表一个字都不改 —— 少了这一段,0068 之前建的库会永远没有这两列,
149
174
  * 而症状是「定义存进去了,下次打开又没了」。
150
175
  */
@@ -157,10 +182,61 @@ export class AxisRegistry {
157
182
  return true;
158
183
  }
159
184
  catch {
185
+ this.owner?.close();
186
+ this.owner = null;
160
187
  this.db = null;
161
188
  return false;
162
189
  }
163
190
  }
191
+ inputRevision() {
192
+ return Number(this.db?.prepare('SELECT revision FROM axis_input_revision WHERE id = 1').get()?.revision ?? 0);
193
+ }
194
+ /** Resolve against an isolated copy; commit only if the live registry still matches. */
195
+ async draft() {
196
+ const sqlite = await loadSqlite();
197
+ if (!sqlite || !this.db)
198
+ throw new Error('AXIS_REGISTRY_UNAVAILABLE');
199
+ const live = this.db;
200
+ const tables = ['axis_entities', 'axis_aliases', 'entity_guidance', 'axis_relations', 'axis_input_revision'];
201
+ const read = (db) => tables.map(table => db.prepare(`SELECT * FROM ${table} ORDER BY rowid`).all());
202
+ const before = read(live);
203
+ const copy = new sqlite.DatabaseSync(':memory:');
204
+ const registry = new AxisRegistry(':memory:', copy);
205
+ try {
206
+ if (!await registry.open())
207
+ throw new Error('AXIS_DRAFT_UNAVAILABLE');
208
+ tables.forEach((table, index) => {
209
+ copy.exec(`DELETE FROM ${table}`);
210
+ for (const row of before[index]) {
211
+ const columns = Object.keys(row);
212
+ copy.prepare(`INSERT INTO ${table} (${columns.join(',')}) VALUES (${columns.map(() => '?').join(',')})`).run(...Object.values(row));
213
+ }
214
+ });
215
+ return {
216
+ registry,
217
+ commit: () => {
218
+ if (JSON.stringify(read(live)) !== JSON.stringify(before))
219
+ throw new Error('归一期间实体注册表已变化,请重试归一');
220
+ // Resolution only adds entities/aliases and fills model definitions.
221
+ for (const table of ['axis_entities', 'axis_aliases']) {
222
+ for (const row of copy.prepare(`SELECT * FROM ${table}`).all()) {
223
+ const columns = Object.keys(row);
224
+ const keys = table === 'axis_entities' ? ['id'] : ['entity_id', 'normalized', 'scope_id'];
225
+ const updates = columns.filter(column => !keys.includes(column)).map(column => `${column}=excluded.${column}`);
226
+ live.prepare(`INSERT INTO ${table} (${columns.join(',')}) VALUES (${columns.map(() => '?').join(',')}) ON CONFLICT (${keys.join(',')}) DO UPDATE SET ${updates.join(',')}`).run(...Object.values(row));
227
+ }
228
+ }
229
+ },
230
+ close: () => { registry.close(); copy.close(); },
231
+ };
232
+ }
233
+ catch (cause) {
234
+ registry.close();
235
+ copy.close();
236
+ throw cause;
237
+ }
238
+ }
239
+ changedInput() { this.db?.prepare('UPDATE axis_input_revision SET revision = revision + 1 WHERE id = 1').run(); }
164
240
  available() {
165
241
  return this.db !== null;
166
242
  }
@@ -203,10 +279,19 @@ export class AxisRegistry {
203
279
  }
204
280
  // 2 · 作用域内 alias
205
281
  if (parentId) {
206
- const aliased = this.findAlias(normalized, parentId);
207
- if (aliased) {
208
- this.learn(aliased, mention, normalized, parentId, input.description);
209
- return { mention, normalized, outcome: 'matched', entity: aliased, how: 'scoped-alias' };
282
+ const aliased = this.findAliases(input.kind, normalized, parentId);
283
+ if (aliased.length === 1) {
284
+ this.learn(aliased[0], mention, normalized, parentId, input.description);
285
+ return { mention, normalized, outcome: 'matched', entity: aliased[0], how: 'scoped-alias' };
286
+ }
287
+ /**
288
+ * 同一作用域里两个实体可以合法地共有同一条别名(`axis_aliases` 的主键是
289
+ * `(entity_id, normalized, scope_id)`,不是 `(normalized, scope_id)`)。这时候
290
+ * **不能取第一个** —— 本文件的规矩是「不唯一就不猜」,猜错的代价是把一条知识挂到
291
+ * 错误的对象上并一路传到卡名。全局那条路(下面)一直是这么做的,只有这里漏了。
292
+ */
293
+ if (aliased.length > 1) {
294
+ return { mention, normalized, outcome: 'ambiguous', candidates: aliased.slice().sort((left, right) => left.name.localeCompare(right.name)) };
210
295
  }
211
296
  }
212
297
  /**
@@ -332,6 +417,64 @@ export class AxisRegistry {
332
417
  return { ...entity, aliases: aliases.map(item => String(item.alias)) };
333
418
  });
334
419
  }
420
+ /** 列出对象关系;传实体 id 时只返回它的邻接关系。 */
421
+ async listRelations(entityId) {
422
+ if (this.db === null)
423
+ throw new Error('AXIS_REGISTRY_UNAVAILABLE');
424
+ const params = {};
425
+ const filter = entityId === undefined ? '' : 'AND (r.from_id = :entityId OR r.to_id = :entityId)';
426
+ if (entityId !== undefined)
427
+ params.entityId = entityId;
428
+ const rows = this.db.prepare(`
429
+ SELECT r.* FROM axis_relations r
430
+ JOIN axis_entities a ON a.id = r.from_id
431
+ JOIN axis_entities b ON b.id = r.to_id
432
+ WHERE r.relation_type = 'related_to'
433
+ AND a.kind = 'object' AND b.kind = 'object'
434
+ AND a.status <> 'merged' AND b.status <> 'merged'
435
+ ${filter}
436
+ ORDER BY r.from_id, r.to_id
437
+ `).all(params);
438
+ return rows.map(rowToRelation);
439
+ }
440
+ /** 建立无方向的 related_to 边;同一个对象不能关联自己。 */
441
+ async addRelation(fromId, toId, evidence = '') {
442
+ if (this.db === null)
443
+ throw new Error('AXIS_REGISTRY_UNAVAILABLE');
444
+ if (!fromId || !toId || fromId === toId)
445
+ return null;
446
+ const [from, to] = await Promise.all([this.get(fromId), this.get(toId)]);
447
+ if (from === null || to === null || from.kind !== 'object' || to.kind !== 'object' || from.status === 'merged' || to.status === 'merged')
448
+ return null;
449
+ const [left, right] = [fromId, toId].sort((a, b) => a.localeCompare(b));
450
+ const now = new Date().toISOString();
451
+ const relation = {
452
+ id: axisRelationId(left, right, 'related_to'),
453
+ fromId: left,
454
+ toId: right,
455
+ relationType: 'related_to',
456
+ evidence: evidence.trim(),
457
+ createdAt: now,
458
+ updatedAt: now,
459
+ };
460
+ this.db.prepare(`
461
+ INSERT INTO axis_relations (id, from_id, to_id, relation_type, evidence, created_at, updated_at)
462
+ VALUES (?, ?, ?, ?, ?, ?, ?)
463
+ ON CONFLICT(from_id, to_id, relation_type) DO UPDATE SET
464
+ evidence = CASE WHEN excluded.evidence <> '' THEN excluded.evidence ELSE axis_relations.evidence END,
465
+ updated_at = excluded.updated_at
466
+ `).run(relation.id, relation.fromId, relation.toId, relation.relationType, relation.evidence, relation.createdAt, relation.updatedAt);
467
+ const row = this.db.prepare('SELECT * FROM axis_relations WHERE from_id = ? AND to_id = ? AND relation_type = ?')
468
+ .get(left, right, 'related_to');
469
+ return row === undefined ? null : rowToRelation(row);
470
+ }
471
+ /** 移除一条对象关系。 */
472
+ async removeRelation(id) {
473
+ if (this.db === null)
474
+ throw new Error('AXIS_REGISTRY_UNAVAILABLE');
475
+ const result = this.db.prepare('DELETE FROM axis_relations WHERE id = ?').run(id);
476
+ return Number(result.changes) > 0;
477
+ }
335
478
  /** 每个轴各有多少个实体、其中几个待人确认。类型定义那一屏的计数读它。 */
336
479
  async stats() {
337
480
  const empty = { total: 0, candidate: 0 };
@@ -363,6 +506,7 @@ export class AxisRegistry {
363
506
  const now = new Date().toISOString();
364
507
  this.db.prepare('UPDATE axis_entities SET name = ?, updated_at = ? WHERE id = ?').run(next, now, id);
365
508
  this.insertAlias(id, current.name, normalizeAxisName(current.name), current.scopeId, now);
509
+ this.changedInput();
366
510
  return this.get(id);
367
511
  }
368
512
  /**
@@ -379,6 +523,7 @@ export class AxisRegistry {
379
523
  if (!normalized)
380
524
  return false;
381
525
  this.insertAlias(id, alias.trim(), normalized, scopeId.trim(), new Date().toISOString());
526
+ this.changedInput();
382
527
  return true;
383
528
  }
384
529
  /** 确认一个候选实体。人看过之后调它 —— 与卡片 review 同一条纪律:入库在前、确认在后。 */
@@ -389,6 +534,7 @@ export class AxisRegistry {
389
534
  if (this.db === null)
390
535
  throw new Error('AXIS_REGISTRY_UNAVAILABLE');
391
536
  this.db.prepare('UPDATE axis_entities SET status = ?, updated_at = ? WHERE id = ?').run(status, new Date().toISOString(), id);
537
+ this.changedInput();
392
538
  return this.get(id);
393
539
  }
394
540
  /**
@@ -398,22 +544,65 @@ export class AxisRegistry {
398
544
  * 它转成 `merged`,`scopeId` 改存目标 id —— 复用这一列而不是新加一列,因为
399
545
  * 「它现在归谁」与「它在谁的下面」对解析来说问的是同一件事。
400
546
  */
401
- async merge(fromId, intoId) {
547
+ async merge(fromId, intoId, redirect) {
402
548
  if (this.db === null)
403
549
  throw new Error('AXIS_REGISTRY_UNAVAILABLE');
404
550
  if (fromId === intoId)
405
551
  return false;
406
552
  const [from, into] = [await this.get(fromId), await this.get(intoId)];
407
- if (from === null || into === null || from.kind !== into.kind)
553
+ if (from === null || into === null || from.kind !== into.kind || from.status === 'merged' || into.status === 'merged')
408
554
  return false;
409
555
  const now = new Date().toISOString();
410
- this.db.prepare('UPDATE axis_entities SET status = ?, scope_id = ?, updated_at = ? WHERE id = ?').run('merged', intoId, now, fromId);
411
- // 被并者的别名与名字一起搬过去:按旧名、旧别名都要搜得到。
412
- this.insertAlias(intoId, from.name, normalizeAxisName(from.name), into.scopeId, now);
413
- const aliases = this.db.prepare('SELECT alias, scope_id FROM axis_aliases WHERE entity_id = ?').all(fromId);
414
- for (const row of aliases)
415
- this.insertAlias(intoId, String(row.alias), normalizeAxisName(String(row.alias)), String(row.scope_id ?? ''), now);
416
- return true;
556
+ this.db.exec('SAVEPOINT axis_merge');
557
+ try {
558
+ this.db.prepare('UPDATE axis_entities SET status = ?, scope_id = ?, updated_at = ? WHERE id = ?').run('merged', intoId, now, fromId);
559
+ // 被并者的别名与名字一起搬过去:按旧名、旧别名都要搜得到。
560
+ this.insertAlias(intoId, from.name, normalizeAxisName(from.name), into.scopeId, now);
561
+ const aliases = this.db.prepare('SELECT alias, scope_id FROM axis_aliases WHERE entity_id = ?').all(fromId);
562
+ for (const row of aliases)
563
+ this.insertAlias(intoId, String(row.alias), normalizeAxisName(String(row.alias)), String(row.scope_id ?? ''), now);
564
+ this.redirectRelations(fromId, intoId, now);
565
+ redirect?.(from.kind);
566
+ // Scope references on both canonical names and aliases move together.
567
+ this.db.prepare("UPDATE axis_entities SET scope_id = ? WHERE scope_id = ? AND status <> 'merged'").run(intoId, fromId);
568
+ this.db.prepare(`INSERT OR IGNORE INTO axis_aliases (entity_id, alias, normalized, scope_id, created_at)
569
+ SELECT entity_id, alias, normalized, ?, created_at FROM axis_aliases WHERE scope_id = ?`).run(intoId, fromId);
570
+ this.db.prepare('DELETE FROM axis_aliases WHERE scope_id = ?').run(fromId);
571
+ this.db.prepare('UPDATE entity_guidance SET entity_id = ? WHERE entity_id = ?').run(intoId, fromId);
572
+ this.changedInput();
573
+ this.db.exec('RELEASE axis_merge');
574
+ return true;
575
+ }
576
+ catch (cause) {
577
+ this.db.exec('ROLLBACK TO axis_merge; RELEASE axis_merge');
578
+ throw cause;
579
+ }
580
+ }
581
+ /** 合并轴实体时转移相关关系,并折叠重复边与自环。 */
582
+ redirectRelations(fromId, intoId, now) {
583
+ if (this.db === null)
584
+ return;
585
+ const rows = this.db.prepare('SELECT * FROM axis_relations WHERE from_id = ? OR to_id = ?').all(fromId, fromId);
586
+ if (rows.length === 0)
587
+ return;
588
+ this.db.prepare('DELETE FROM axis_relations WHERE from_id = ? OR to_id = ?').run(fromId, fromId);
589
+ const insert = this.db.prepare(`
590
+ INSERT INTO axis_relations (id, from_id, to_id, relation_type, evidence, created_at, updated_at)
591
+ VALUES (?, ?, ?, ?, ?, ?, ?)
592
+ ON CONFLICT(from_id, to_id, relation_type) DO UPDATE SET
593
+ evidence = CASE WHEN excluded.evidence <> '' THEN excluded.evidence ELSE axis_relations.evidence END,
594
+ updated_at = excluded.updated_at
595
+ `);
596
+ for (const row of rows) {
597
+ const oldFrom = String(row.from_id);
598
+ const oldTo = String(row.to_id);
599
+ const pair = [oldFrom === fromId ? intoId : oldFrom, oldTo === fromId ? intoId : oldTo];
600
+ if (pair[0] === pair[1])
601
+ continue;
602
+ const [left, right] = pair.sort((a, b) => a.localeCompare(b));
603
+ const type = String(row.relation_type);
604
+ insert.run(axisRelationId(left, right, type), left, right, type, String(row.evidence ?? ''), String(row.created_at ?? now), now);
605
+ }
417
606
  }
418
607
  /* ─────────────────────────────────────────── 定义(0068) ── */
419
608
  /**
@@ -425,6 +614,7 @@ export class AxisRegistry {
425
614
  const next = text.trim();
426
615
  this.db.prepare('UPDATE axis_entities SET description = ?, description_source = ?, updated_at = ? WHERE id = ?')
427
616
  .run(next, next ? 'human' : '', new Date().toISOString(), id);
617
+ this.changedInput();
428
618
  return this.get(id);
429
619
  }
430
620
  /**
@@ -521,6 +711,7 @@ export class AxisRegistry {
521
711
  };
522
712
  this.db.prepare('INSERT INTO entity_guidance (id, entity_id, kind, text, author, created_at) VALUES (?, ?, ?, ?, ?, ?)')
523
713
  .run(guidance.id, guidance.entityId, guidance.kind, guidance.text, guidance.author, guidance.createdAt);
714
+ this.changedInput();
524
715
  return guidance;
525
716
  }
526
717
  /** 撤一条指导。**人写的东西要能撤** —— 不然一条写错的指引会永远跟着每次抽取。 */
@@ -531,6 +722,7 @@ export class AxisRegistry {
531
722
  if (before === undefined)
532
723
  return false;
533
724
  this.db.prepare('DELETE FROM entity_guidance WHERE id = ?').run(id);
725
+ this.changedInput();
534
726
  return true;
535
727
  }
536
728
  /**
@@ -614,7 +806,8 @@ export class AxisRegistry {
614
806
  return { entries, totals, truncated, selection };
615
807
  }
616
808
  close() {
617
- this.db?.close();
809
+ this.owner?.close();
810
+ this.owner = null;
618
811
  this.db = null;
619
812
  }
620
813
  // ------------------------------------------------------------ 内部查询
@@ -623,9 +816,10 @@ export class AxisRegistry {
623
816
  const hit = rows.find(row => normalizeAxisName(String(row.name)) === normalized);
624
817
  return hit === undefined ? undefined : rowToEntity(hit);
625
818
  }
626
- findAlias(normalized, scopeId) {
627
- const row = this.db.prepare("SELECT e.* FROM axis_aliases a JOIN axis_entities e ON e.id = a.entity_id WHERE a.normalized = ? AND a.scope_id = ? AND e.status <> 'merged' LIMIT 1").get(normalized, scopeId);
628
- return row === undefined ? undefined : rowToEntity(row);
819
+ /** 作用域内的别名命中。**可能不止一条** —— 调用方必须自己判唯一性。 */
820
+ findAliases(kind, normalized, scopeId) {
821
+ const rows = this.db.prepare("SELECT e.* FROM axis_aliases a JOIN axis_entities e ON e.id = a.entity_id WHERE a.normalized = ? AND a.scope_id = ? AND e.kind = ? AND e.status <> 'merged' ORDER BY e.id").all(normalized, scopeId, kind);
822
+ return rows.map(rowToEntity);
629
823
  }
630
824
  /** 全局 canonical 名精确命中。它可能不止一个 —— 两个实体同名时就是歧义。 */
631
825
  findCanonicalGlobal(kind, normalized) {
@@ -726,6 +920,20 @@ function rowToEntity(row) {
726
920
  updatedAt: String(row.updated_at),
727
921
  };
728
922
  }
923
+ function axisRelationId(fromId, toId, relationType) {
924
+ return `axis_rel_${createHash('sha256').update(`${relationType}:${fromId}:${toId}`).digest('hex').slice(0, 14)}`;
925
+ }
926
+ function rowToRelation(row) {
927
+ return {
928
+ id: String(row.id),
929
+ fromId: String(row.from_id),
930
+ toId: String(row.to_id),
931
+ relationType: String(row.relation_type),
932
+ evidence: String(row.evidence ?? ''),
933
+ createdAt: String(row.created_at),
934
+ updatedAt: String(row.updated_at),
935
+ };
936
+ }
729
937
  function rowToGuidance(row) {
730
938
  return {
731
939
  id: String(row.id),