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
package/src/knowledge.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Knowledge(0063 §2):**事实真源**。一条可独立检索、可由来源验证的原子语义单元。
3
3
  *
4
- * ## 只有 `text` 是内容
4
+ * ## `text` 与结构化内容共同构成知识
5
5
  *
6
- * `object` / `action` / `scene` 是三个轴实体的引用,`sources` 是出处 —— 它们都是索引。
6
+ * `text` 保存可读内容,`data` 保存条件及 Procedure 的方法、检查与限制。
7
+ * `object` / `action` / `scene` 是轴实体引用,`sources` 是出处。
7
8
  * 把索引当知识,是这套模型最常见的误解。
8
9
  *
9
10
  * ## 判重与冲突(§5.2.2)
@@ -21,22 +22,22 @@
21
22
  * 还把两个来源都抹了。**也不许删掉任何一条** —— 删了就没有「冲突」这件事了,
22
23
  * 而冲突本身是要给人看的信号。
23
24
  *
24
- * ## 身份就是判重键
25
+ * ## 稳定身份与判重键
25
26
  *
26
- * `id = k_<归一化文本的哈希>`。同一个事实无论来自哪份文档都得到同一个 id,于是
27
- * 「多来源支持」是**往同一行追加 sources**,而不是靠一条知识挂多个坐标。
28
- * 文本改了就是一个新 id —— 旧的那条**留着**(不许删),两条之间可以记一条 redirect。
27
+ * 新行使用 `k_<归一化文本的 SHA-256>`,存量 ID 保留。判重先比较归一化文本,
28
+ * 不把哈希相同当作事实相同。「多来源支持」往同一行追加版本证据。
29
+ * 人工编辑正文保留 ID 并增加内容版本;重新抽出不同文本则保留为另一条知识。
29
30
  *
30
31
  * ## 为什么存在记忆段
31
32
  *
32
33
  * Knowledge 不可重建:它是抽取产物 + 人的裁决。重跑一次抽取不会得到同样的结果,
33
- * 而人的裁决根本没有第二次。所以它和轴注册表同一个库(`<memoryDir>/knowledge.sqlite`)。
34
+ * 而人的裁决根本没有第二次。所以它与轴注册表共享经过属主、版本校验的 `knowledge.db`。
34
35
  */
35
36
 
36
- import { mkdir } from 'node:fs/promises'
37
- import { dirname } from 'node:path'
38
37
  import { createHash } from 'node:crypto'
39
38
  import { loadSqlite, type SqliteDatabase } from './fts.js'
39
+ import { KnowledgeDb } from './store/knowledge-db.js'
40
+ import type { KnowledgeKind, KnowledgeContent } from './knowledge-contract.js'
40
41
 
41
42
  /**
42
43
  * 一条 Knowledge 的**真值状态**。
@@ -93,15 +94,20 @@ export interface KnowledgeSource {
93
94
  * 「这条知识依据的是第 3 版,而那版已经被人改过了」。
94
95
  */
95
96
  toVersion?: number
97
+ /** Evidence changes do not change the truth state of the Knowledge. */
98
+ currentVersion?: number
99
+ evidenceStatus?: 'current' | 'historical' | 'unversioned' | 'missing' | 'human'
100
+ quoteInCurrentVersion?: boolean
101
+ /** A completed newer extraction withdrew this document contribution. */
102
+ withdrawn?: boolean
96
103
  createdAt: string
97
104
  }
98
105
 
99
106
  export interface Knowledge {
100
- /*
101
- * 当前不把 Fact / Rule / Procedure / Constraint 做成 Knowledge 的列。它们只有在产生
102
- * 不同召回、验证或执行策略时才值得结构化;现阶段由抽取/Card metadata 承载扩展信息。
103
- */
104
107
  id: string
108
+ kind?: KnowledgeKind
109
+ data?: KnowledgeContent
110
+ /** Fact / Procedure 的结构化内容参与版本与判重;Case 使用共享库内的独立存储。 */
105
111
  text: string
106
112
  /** 三个轴实体的 id。空串 = 那个分量为空 —— 坐标可以是空的(§九)。 */
107
113
  objectId: string
@@ -112,7 +118,7 @@ export interface Knowledge {
112
118
  runId: string
113
119
  /** 被并进了哪一条。空串 = 它自己就是保留的那条。 */
114
120
  mergedInto: string
115
- /** 当前正文版本。只有 `text` 的内容 hash 变化时才递增。 */
121
+ /** 当前内容版本。正文、类型或结构化条件变化时递增。 */
116
122
  version: number
117
123
  createdAt: string
118
124
  updatedAt: string
@@ -147,9 +153,12 @@ export interface KnowledgeCardRef {
147
153
  */
148
154
  export function normalizeKnowledge(text: string): string {
149
155
  return text
156
+ .normalize('NFKC')
150
157
  .toLowerCase()
151
158
  .replace(/\s+/g, '')
152
- .replace(/[,。、;:?!,.;:?!"'“”‘’()()【】\[\]《》<>—\-_/\\]/g, '')
159
+ // Operators, decimal points, signs and identifier separators carry meaning.
160
+ .replace(/[,。、;:?!,;:?!“”‘’]/g, '')
161
+ .replace(/\.$/g, '')
153
162
  }
154
163
 
155
164
  /** FNV-1a(32 位):只用来生成稳定短 id,不用于任何安全目的。 */
@@ -172,10 +181,15 @@ function fnv1a(value: string): number {
172
181
  * 如果未来一个库混合多个 Scope 或有效期,必须先把 Scope/有效性纳入判重策略,再改变 id。
173
182
  */
174
183
  export function knowledgeId(text: string): string {
175
- return `k_${fnv1a(normalizeKnowledge(text)).toString(36)}`
184
+ return `k_${createHash('sha256').update(normalizeKnowledge(text), 'utf8').digest('hex')}`
176
185
  }
177
186
 
178
187
  export interface KnowledgeIngest {
188
+ /** v2 records deduplicate only inside the same semantic coordinate; legacy IDs remain readable. */
189
+ scopeIdentity?: boolean
190
+ id?: string
191
+ kind?: KnowledgeKind
192
+ data?: KnowledgeContent
179
193
  text: string
180
194
  objectId?: string
181
195
  actionId?: string
@@ -221,6 +235,8 @@ export interface KnowledgeVersion {
221
235
  * 「`object_id` 这个参数不在」与「`object_id=` 空值」。
222
236
  */
223
237
  export interface KnowledgeQuery {
238
+ kind?: KnowledgeKind
239
+ excludeWithdrawn?: boolean
224
240
  objectId?: string
225
241
  actionId?: string
226
242
  sceneId?: string
@@ -375,6 +391,8 @@ CREATE TABLE IF NOT EXISTS knowledge (
375
391
  id TEXT PRIMARY KEY,
376
392
  text TEXT NOT NULL,
377
393
  normalized TEXT NOT NULL,
394
+ kind TEXT NOT NULL DEFAULT 'fact',
395
+ payload TEXT NOT NULL DEFAULT '{}',
378
396
  object_id TEXT NOT NULL DEFAULT '',
379
397
  action_id TEXT NOT NULL DEFAULT '',
380
398
  scene_id TEXT NOT NULL DEFAULT '',
@@ -458,8 +476,9 @@ CREATE INDEX IF NOT EXISTS revision_blob_idx ON revision(blob_hash);
458
476
  */
459
477
  export class KnowledgeStore {
460
478
  private db: SqliteDatabase | null = null
479
+ private owner: KnowledgeDb | null = null
461
480
 
462
- constructor(private readonly file: string) {}
481
+ constructor(private readonly file: string, private readonly shared?: SqliteDatabase) {}
463
482
 
464
483
  /**
465
484
  * 这个文件里有没有某张表。
@@ -481,14 +500,25 @@ export class KnowledgeStore {
481
500
  const sqlite = await loadSqlite()
482
501
  if (sqlite === null) return false
483
502
  try {
484
- await mkdir(dirname(this.file), { recursive: true })
485
- this.db = new sqlite.DatabaseSync(this.file)
503
+ if (this.shared) this.db = this.shared
504
+ else {
505
+ const opened = await KnowledgeDb.open(this.file, sqlite.DatabaseSync)
506
+ if (!opened.ok) return false
507
+ this.owner = opened.db
508
+ this.db = opened.db.connection()
509
+ }
486
510
  this.db.exec(SCHEMA)
511
+ if (!hasColumn(this.db, 'knowledge', 'kind')) this.db.exec("ALTER TABLE knowledge ADD COLUMN kind TEXT NOT NULL DEFAULT 'fact'")
512
+ if (!hasColumn(this.db, 'knowledge', 'payload')) this.db.exec("ALTER TABLE knowledge ADD COLUMN payload TEXT NOT NULL DEFAULT '{}'")
513
+ // The retired source_type table can predate revision-bound evidence too.
514
+ if (!hasColumn(this.db, 'knowledge_sources', 'to_version')) {
515
+ this.db.exec('ALTER TABLE knowledge_sources ADD COLUMN to_version INTEGER')
516
+ }
487
517
  /*
488
518
  * 旧库的 `knowledge_sources` 带有已经撤掉的 `source_type NOT NULL` 列。
489
519
  * `CREATE TABLE IF NOT EXISTS` 不会改变旧表;如果直接继续,新的出处写入会因
490
520
  * 没有给这个列赋值而全部失败,表现成「抽取报告有知识,但 Knowledge 为 0」。
491
- * 只重建这一张可派生关系表,保留正文与出处数据,并让迁移具备事务性。
521
+ * 只重建这一张出处表,保留原始证据数据,并让迁移具备事务性。
492
522
  */
493
523
  if (hasColumn(this.db, 'knowledge_sources', 'source_type')) {
494
524
  this.db.exec('BEGIN IMMEDIATE')
@@ -521,26 +551,27 @@ export class KnowledgeStore {
521
551
  throw cause
522
552
  }
523
553
  }
524
- /*
525
- * 0062 v2 补的列。老库(`CREATE TABLE IF NOT EXISTS` 对已存在的表是空操作)不会
526
- * 自己长出它来,所以要显式 ALTER —— 与知识库文件「版本不符走迁移、不重建」同一政策。
527
- */
528
- if (!hasColumn(this.db, 'knowledge_sources', 'to_version')) {
529
- this.db.exec('ALTER TABLE knowledge_sources ADD COLUMN to_version INTEGER')
530
- }
554
+ if (!hasColumn(this.db, 'knowledge_sources', 'withdrawn')) this.db.exec('ALTER TABLE knowledge_sources ADD COLUMN withdrawn INTEGER NOT NULL DEFAULT 0')
531
555
  if (!hasColumn(this.db, 'knowledge', 'head_version')) {
532
556
  this.db.exec("ALTER TABLE knowledge ADD COLUMN head_version INTEGER NOT NULL DEFAULT 0")
533
557
  }
558
+ // Keep legacy IDs and references; replace only the lossy comparison key.
559
+ const reindex = this.db.prepare('UPDATE knowledge SET normalized = ? WHERE id = ?')
560
+ for (const row of this.db.prepare('SELECT id, text, normalized FROM knowledge').all() as Array<{ id: string; text: string; normalized: string }>) {
561
+ const normalized = normalizeKnowledge(row.text)
562
+ if (normalized !== row.normalized) reindex.run(normalized, row.id)
563
+ }
534
564
  this.backfillContentVersions()
535
565
  return true
536
566
  } catch {
567
+ this.owner?.close()
568
+ this.owner = null
537
569
  this.db = null
538
570
  return false
539
571
  }
540
572
  }
541
573
 
542
- available(): boolean { return this.db !== null
543
- }
574
+ available(): boolean { return this.db !== null }
544
575
 
545
576
  /**
546
577
  * 为旧 Knowledge 行补首版。
@@ -612,13 +643,23 @@ export class KnowledgeStore {
612
643
  if (this.db === null) throw new Error('KNOWLEDGE_STORE_UNAVAILABLE')
613
644
  const text = input.text.trim()
614
645
  if (!text) throw new Error('KNOWLEDGE_TEXT_REQUIRED')
646
+ const kind = input.kind ?? 'fact'
647
+ if (kind === 'case') throw new Error('CASE_STORE_REQUIRED: Case 通过统一 Case 存储保存,不写入 Fact/Procedure 表')
648
+ const data = input.data ?? {}
649
+ const payload = JSON.stringify(data)
615
650
  const normalized = normalizeKnowledge(text)
616
- const id = knowledgeId(text)
651
+ // Edited and migrated facts keep their identity. A hash is not proof of equality.
652
+ const coordinate = [(input.objectId ?? '').trim(), (input.actionId ?? '').trim(), (input.sceneId ?? '').trim()]
653
+ const match = input.scopeIdentity
654
+ ? this.db.prepare("SELECT id FROM knowledge WHERE normalized=? AND kind=? AND payload=? AND object_id=? AND action_id=? AND scene_id=? AND merged_into='' ORDER BY created_at,id LIMIT 1").get(normalized, kind, payload, ...coordinate) as { id: string } | undefined
655
+ : this.db.prepare("SELECT id FROM knowledge WHERE normalized=? AND kind=? AND payload=? AND merged_into='' ORDER BY created_at,id LIMIT 1").get(normalized, kind, payload) as { id: string } | undefined
656
+ const id = input.id ?? match?.id ?? (!input.scopeIdentity && kind === 'fact' && payload === '{}' ? knowledgeId(text) : `k_${createHash('sha256').update(JSON.stringify([kind, normalized, data, ...(input.scopeIdentity ? coordinate : [])])).digest('hex')}`)
617
657
  const now = new Date().toISOString()
618
- const existing = await this.get(id)
658
+ const existing = this.read(id)
659
+ if (existing !== null && !input.id && (normalizeKnowledge(existing.text) !== normalized || (existing.kind ?? 'fact') !== kind)) throw new Error('KNOWLEDGE_ID_COLLISION')
619
660
 
620
661
  if (existing === null) {
621
- this.db.exec('BEGIN')
662
+ this.db.exec('SAVEPOINT knowledge_ingest')
622
663
  try {
623
664
  this.db.prepare(
624
665
  'INSERT INTO knowledge (id, text, normalized, object_id, action_id, scene_id, status, run_id, merged_into, head_version, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
@@ -627,18 +668,19 @@ export class KnowledgeStore {
627
668
  (input.objectId ?? '').trim(), (input.actionId ?? '').trim(), (input.sceneId ?? '').trim(),
628
669
  input.status ?? 'candidate', (input.runId ?? '').trim(), '', 0, now, now,
629
670
  )
630
- const added = await this.appendSources(id, input.sources ?? [])
631
- this.appendContentVersion(id, text, {
671
+ this.db.prepare('UPDATE knowledge SET kind = ?, payload = ? WHERE id = ?').run(kind, payload, id)
672
+ const added = this.appendSources(id, input.sources ?? [])
673
+ this.appendContentVersion(id, kind === 'fact' && payload === '{}' ? text : JSON.stringify({ text, kind, data }), {
632
674
  actor: input.actor ?? 'compiler',
633
675
  kind: input.revisionKind ?? 'auto',
634
676
  summary: input.revisionSummary ?? '写入 Knowledge',
635
677
  at: now,
636
678
  })
637
679
  this.db.prepare('UPDATE knowledge SET head_version = 1 WHERE id = ?').run(id)
638
- this.db.exec('COMMIT')
639
- return { knowledge: (await this.get(id))!, merged: false, addedSources: added }
680
+ this.db.exec('RELEASE knowledge_ingest')
681
+ return { knowledge: this.read(id)!, merged: false, addedSources: added }
640
682
  } catch (cause) {
641
- this.db.exec('ROLLBACK')
683
+ this.db.exec('ROLLBACK TO knowledge_ingest; RELEASE knowledge_ingest')
642
684
  throw cause
643
685
  }
644
686
  }
@@ -652,23 +694,33 @@ export class KnowledgeStore {
652
694
  * 所以只允许「旧坐标三项全空 → 本次坐标非空」这一种补齐;已有任意坐标的行仍走显式
653
695
  * `setCoordinate`,不会被合并流程覆盖。
654
696
  */
655
- const incomingCoordinate = {
656
- objectId: (input.objectId ?? '').trim(),
657
- actionId: (input.actionId ?? '').trim(),
658
- sceneId: (input.sceneId ?? '').trim(),
659
- }
660
- const existingHasCoordinate = existing.objectId !== '' || existing.actionId !== '' || existing.sceneId !== ''
661
- const incomingHasCoordinate = incomingCoordinate.objectId !== '' || incomingCoordinate.actionId !== '' || incomingCoordinate.sceneId !== ''
662
- if (!existingHasCoordinate && incomingHasCoordinate) {
663
- this.db.prepare('UPDATE knowledge SET object_id = ?, action_id = ?, scene_id = ?, updated_at = ? WHERE id = ?').run(
664
- incomingCoordinate.objectId, incomingCoordinate.actionId, incomingCoordinate.sceneId, now, id,
665
- )
666
- }
667
- const added = await this.appendSources(id, input.sources ?? [])
668
- if (existingHasCoordinate || !incomingHasCoordinate) {
669
- this.db.prepare('UPDATE knowledge SET updated_at = ? WHERE id = ?').run(now, id)
670
- }
671
- return { knowledge: (await this.get(id))!, merged: true, addedSources: added }
697
+ this.db.exec('SAVEPOINT knowledge_update')
698
+ try {
699
+ if (input.id && (existing.text !== text || (existing.kind ?? 'fact') !== kind || JSON.stringify(existing.data ?? {}) !== payload)) {
700
+ this.db.prepare('UPDATE knowledge SET text = ?, normalized = ?, kind = ?, payload = ?, updated_at = ? WHERE id = ?').run(text, normalized, kind, payload, now, id)
701
+ const version = this.appendContentVersion(id, kind === 'fact' && payload === '{}' ? text : JSON.stringify({ text, kind, data }), { actor: input.actor ?? 'compiler', kind: 'auto', summary: '更新 Knowledge 内容与条件', at: now })
702
+ this.db.prepare('UPDATE knowledge SET head_version = ? WHERE id = ?').run(version, id)
703
+ }
704
+ const incomingCoordinate = {
705
+ objectId: (input.objectId ?? '').trim(),
706
+ actionId: (input.actionId ?? '').trim(),
707
+ sceneId: (input.sceneId ?? '').trim(),
708
+ }
709
+ const existingHasCoordinate = existing.objectId !== '' || existing.actionId !== '' || existing.sceneId !== ''
710
+ const incomingHasCoordinate = incomingCoordinate.objectId !== '' || incomingCoordinate.actionId !== '' || incomingCoordinate.sceneId !== ''
711
+ if (!existingHasCoordinate && incomingHasCoordinate) {
712
+ this.db.prepare('UPDATE knowledge SET object_id = ?, action_id = ?, scene_id = ?, updated_at = ? WHERE id = ?').run(
713
+ incomingCoordinate.objectId, incomingCoordinate.actionId, incomingCoordinate.sceneId, now, id,
714
+ )
715
+ }
716
+ const added = this.appendSources(id, input.sources ?? [])
717
+ if (existingHasCoordinate || !incomingHasCoordinate) {
718
+ this.db.prepare('UPDATE knowledge SET updated_at = ? WHERE id = ?').run(now, id)
719
+ }
720
+ const result = { knowledge: (await this.get(id))!, merged: true, addedSources: added }
721
+ this.db.exec('RELEASE knowledge_update')
722
+ return result
723
+ } catch (cause) { this.db.exec('ROLLBACK TO knowledge_update; RELEASE knowledge_update'); throw cause }
672
724
  }
673
725
 
674
726
  /**
@@ -692,6 +744,7 @@ export class KnowledgeStore {
692
744
  if (!text) throw new Error('KNOWLEDGE_TEXT_REQUIRED')
693
745
  const current = await this.get(id)
694
746
  if (current === null) return null
747
+ if (current.kind === 'procedure') throw new Error('PROCEDURE_STRUCTURED_EDIT_REQUIRED: 请同时修改 Procedure 的问题、方法、条件与验证字段,不能只改展示正文')
695
748
  const now = new Date().toISOString()
696
749
  this.db.exec('BEGIN')
697
750
  try {
@@ -713,24 +766,21 @@ export class KnowledgeStore {
713
766
  }
714
767
 
715
768
  /** 追加来源。返回这次真正加进去几条(去重之后)。 */
716
- private async appendSources(id: string, sources: Array<Partial<KnowledgeSource>>): Promise<number> {
769
+ private appendSources(id: string, sources: Array<Partial<KnowledgeSource>>): number {
717
770
  if (sources.length === 0) return 0
718
- const current = await this.get(id)
771
+ const current = this.read(id)
719
772
  const existingByKey = new Map((current?.sources ?? []).map(source => [sourceKey(source), source]))
720
773
  const seen = new Set(existingByKey.keys())
721
- let ordinal = current?.sources.length ?? 0
774
+ let ordinal = Number((this.db!.prepare('SELECT COALESCE(MAX(ordinal), -1) + 1 AS n FROM knowledge_sources WHERE knowledge_id = ?').get(id) as { n: number }).n)
722
775
  let added = 0
723
776
  const now = new Date().toISOString()
724
777
  for (const source of sources) {
725
778
  const row = normalizeSource(source, now)
726
779
  const key = sourceKey(row)
727
780
  if (seen.has(key)) {
728
- // 同一出处的来源版本是血缘元数据,不是新的 Knowledge 内容版本。
729
- const previous = existingByKey.get(key)
730
- if (row.toVersion !== undefined && previous?.toVersion !== row.toVersion) {
731
- this.db!.prepare(
732
- 'UPDATE knowledge_sources SET to_version = ? WHERE knowledge_id = ? AND document_id = ? AND quote = ? AND author = ? AND statement = ?',
733
- ).run(row.toVersion, id, row.documentId, row.quote, row.author, row.statement)
781
+ if (existingByKey.get(key)?.withdrawn) {
782
+ this.db!.prepare('UPDATE knowledge_sources SET withdrawn=0 WHERE knowledge_id=? AND document_id=? AND quote=? AND COALESCE(to_version,-1)=?')
783
+ .run(id, row.documentId, row.quote, row.toVersion ?? -1)
734
784
  }
735
785
  continue
736
786
  }
@@ -748,7 +798,10 @@ export class KnowledgeStore {
748
798
  return added
749
799
  }
750
800
 
751
- async get(id: string): Promise<Knowledge | null> { if (this.db === null) throw new Error('KNOWLEDGE_STORE_UNAVAILABLE')
801
+ async get(id: string): Promise<Knowledge | null> { return this.read(id) }
802
+
803
+ private read(id: string): Knowledge | null {
804
+ if (this.db === null) throw new Error('KNOWLEDGE_STORE_UNAVAILABLE')
752
805
  const row = this.db.prepare('SELECT * FROM knowledge WHERE id = ?').get(id) as Record<string, unknown> | undefined
753
806
  if (row === undefined) return null
754
807
  const sources = this.db.prepare(
@@ -773,7 +826,7 @@ export class KnowledgeStore {
773
826
  version: Number(row.version),
774
827
  contentHash: String(row.blob_hash ?? ''),
775
828
  bytes: Number(row.bytes ?? Buffer.byteLength(String(row.body ?? ''), 'utf8')),
776
- text: String(row.body ?? ''),
829
+ text: (() => { const body = String(row.body ?? ''); try { const value = JSON.parse(body); return typeof value?.text === 'string' && value?.kind ? value.text : body } catch { return body } })(),
777
830
  actor: String(row.actor ?? 'system'),
778
831
  kind: String(row.kind ?? 'auto'),
779
832
  summary: String(row.summary ?? ''),
@@ -948,6 +1001,8 @@ export class KnowledgeStore {
948
1001
  } {
949
1002
  const where: string[] = [query.includeMerged === true ? '1 = 1' : "merged_into = ''"]
950
1003
  const params: Record<string, unknown> = {}
1004
+ if (query.kind !== undefined) { where.push('kind = :knowledgeKind'); params.knowledgeKind = query.kind }
1005
+ if (query.excludeWithdrawn) where.push('EXISTS (SELECT 1 FROM knowledge_sources active_source WHERE active_source.knowledge_id = knowledge.id AND active_source.withdrawn = 0)')
951
1006
  if (query.ids !== undefined) {
952
1007
  // 空数组是一个**取值**(筛出空集),不能退化成「不过滤」—— 那会让一次失败的落位
953
1008
  // 查询变成「把整库的知识塞进这次召回」。
@@ -961,7 +1016,17 @@ export class KnowledgeStore {
961
1016
  if (!skip.has('status') && query.status !== undefined) { where.push('status = :status'); params.status = query.status }
962
1017
  if (query.runId !== undefined) { where.push('run_id = :runId'); params.runId = query.runId }
963
1018
  if (query.noCoordinate === true) where.push("object_id = '' AND action_id = '' AND scene_id = ''")
964
- if (query.text) { where.push('normalized LIKE :text'); params.text = `%${normalizeKnowledge(query.text)}%` }
1019
+ if (query.text) {
1020
+ /**
1021
+ * LIKE 的元字符必须转义(0070)。
1022
+ *
1023
+ * `normalizeKnowledge` 会保留 `%` 与 `_`,而 `?q=` 是用户能直接传的:查询 `%`
1024
+ * 会拼成 `%%%`,命中整库并虚报 total;`a_b` 还会顺带匹配 `axb`。反斜杠自己也要
1025
+ * 先转义 —— 否则用户输入的一个 `\` 会把后面的字符变成转义序列。
1026
+ */
1027
+ where.push("normalized LIKE :text ESCAPE '\\'")
1028
+ params.text = `%${normalizeKnowledge(query.text).replace(/[\\%_]/g, char => `\\${char}`)}%`
1029
+ }
965
1030
  if (query.cardId !== undefined) {
966
1031
  /*
967
1032
  * `card_knowledge` 归**另一个模块**所有(`store/knowledge-db.ts`),而两个模块
@@ -1015,7 +1080,7 @@ export class KnowledgeStore {
1015
1080
  *
1016
1081
  * 联动只走一个方向:**矩阵 → 列表**。点一格筛列表,列表的筛选不动矩阵。
1017
1082
  */
1018
- const forMatrix = this.where({})
1083
+ const forMatrix = this.where({ kind: query.kind })
1019
1084
  const rows = this.db.prepare(
1020
1085
  `SELECT object_id, action_id, scene_id, COUNT(*) AS n FROM knowledge ${forMatrix.clause}
1021
1086
  GROUP BY object_id, action_id, scene_id`,
@@ -1341,7 +1406,8 @@ export class KnowledgeStore {
1341
1406
  }
1342
1407
 
1343
1408
  close(): void {
1344
- this.db?.close()
1409
+ this.owner?.close()
1410
+ this.owner = null
1345
1411
  this.db = null
1346
1412
  }
1347
1413
  }
@@ -1447,7 +1513,7 @@ function hasColumn(db: { prepare: (sql: string) => { all: (...params: unknown[])
1447
1513
 
1448
1514
  function sourceKey(source: KnowledgeSource): string {
1449
1515
  return source.documentId
1450
- ? `d\u0001${source.documentId}\u0001${source.quote}`
1516
+ ? `d\u0001${source.documentId}\u0001${source.toVersion ?? ''}\u0001${source.quote}`
1451
1517
  : `h\u0001${source.author}\u0001${source.statement}`
1452
1518
  }
1453
1519
 
@@ -1482,6 +1548,8 @@ function knowledgeSnapshot(row: Record<string, unknown>): Record<string, unknown
1482
1548
  function rowToKnowledge(row: Record<string, unknown>, sourceRows: Array<Record<string, unknown>>): Knowledge {
1483
1549
  return {
1484
1550
  id: String(row.id),
1551
+ kind: (String(row.kind ?? 'fact')) as KnowledgeKind,
1552
+ ...(row.payload && row.payload !== '{}' ? { data: JSON.parse(String(row.payload)) as KnowledgeContent } : {}),
1485
1553
  text: String(row.text),
1486
1554
  objectId: String(row.object_id ?? ''),
1487
1555
  actionId: String(row.action_id ?? ''),
@@ -1500,6 +1568,7 @@ function rowToKnowledge(row: Record<string, unknown>, sourceRows: Array<Record<s
1500
1568
  author: String(source.author ?? ''),
1501
1569
  statement: String(source.statement ?? ''),
1502
1570
  ...(source.to_version === null || source.to_version === undefined ? {} : { toVersion: Number(source.to_version) }),
1571
+ ...(Number(source.withdrawn) === 1 ? { withdrawn: true } : {}),
1503
1572
  createdAt: String(source.created_at),
1504
1573
  })),
1505
1574
  }
package/src/layout.ts CHANGED
@@ -115,7 +115,6 @@
115
115
  import { existsSync, mkdirSync } from 'node:fs'
116
116
  import { homedir } from 'node:os'
117
117
  import { basename, dirname, join, resolve } from 'node:path'
118
- import { fileURLToPath } from 'node:url'
119
118
 
120
119
  /**
121
120
  * 根路径下固定存在的段。顺序即它们在文档与界面里出现的顺序。
@@ -129,7 +128,7 @@ import { fileURLToPath } from 'node:url'
129
128
  * **`output` 不在这里。** 交付物是**某个工作项目的产物**,不是这个 Agent 的固有状态:
130
129
  * 「分析华东区渠道压货」产出的那几张图属于那个项目,换一个项目打开就不该再看见它。
131
130
  * 所以它落在**当前工作区**的 `output/<日期>/` 下,而不是跟着 Agent 的家走。
132
- * 约定写在 preset 的人格提示词里(`preset/tita-data-agent/agent.cordis.yml` 的工作规则)。
131
+ * 约定写在知识插件追加到标准模式系统提示词的行为规则里。
133
132
  */
134
133
  export const AGENT_DIRS = ['domain_knowledge', 'memory', 'intent', 'tmp', 'resource'] as const
135
134
  export type AgentDirName = typeof AGENT_DIRS[number]
@@ -173,22 +172,26 @@ export const MEMORY_DIR = 'memory'
173
172
  export const INTENT_DIR = 'intent'
174
173
 
175
174
  /**
176
- * 默认根路径:`~/Desktop/titaagent`。
175
+ * 默认根路径:`~/.dsh/tita-agent`。
177
176
  *
178
- * 落在**桌面**是刻意的:这四段目录是用户自己的东西,放在一个他们看得见、能直接
179
- * 打开、能自己备份的位置,比藏进 `~/.tita-data-agent` 更诚实。这也正是 0029 之前
180
- * 默认知识树的位置(`~/Desktop/titaagent/domain_knowledge`),所以对没改过设置的
181
- * 用户来说,知识树**原地不动**。
177
+ * `.dsh` 是 DSH 的用户级数据根;`tita-agent` 是本插件的专属目录。知识、记忆、意图、
178
+ * 临时态与运行所需家当都收在这里,用户不需要再管理一条插件自己的路径。
182
179
  */
183
180
  export function defaultAgentRoot(): string {
184
- return resolve(process.env.DSH_AGENT_ROOT || join(homedir(), 'Desktop', 'titaagent'))
181
+ const dshHome = process.env.DSH_HOME?.trim() || join(homedir(), '.dsh')
182
+ return resolve(join(dshHome, 'tita-agent'))
183
+ }
184
+
185
+ /** 旧版本默认的 Agent 根,只用于一次性迁移。 */
186
+ export function legacyDefaultAgentRoot(): string {
187
+ return resolve(join(homedir(), 'Desktop', 'titaagent'))
185
188
  }
186
189
 
187
190
  /** 0029 之前的知识树根:用户显式设过的 `rootDir`,或旧默认位置。只用于迁移。 */
188
191
  export function legacyKnowledgeRoot(): string {
189
192
  const inRepo = join(process.cwd(), 'domain_knowledge')
190
193
  return resolve(process.env.DSH_KNOWLEDGE_ROOT
191
- || (existsSync(inRepo) ? inRepo : join(defaultAgentRoot(), DOMAIN_KNOWLEDGE_DIR)))
194
+ || (existsSync(inRepo) ? inRepo : join(legacyDefaultAgentRoot(), DOMAIN_KNOWLEDGE_DIR)))
192
195
  }
193
196
 
194
197
  /**
@@ -199,7 +202,7 @@ export function legacyKnowledgeRoot(): string {
199
202
  * 按 cwd 决定搬谁太危险 —— 一个恰好放了对拍夹具的目录会被搬去桌面。
200
203
  */
201
204
  export function legacyDefaultKnowledgeRoot(): string {
202
- return resolve(process.env.DSH_KNOWLEDGE_ROOT || join(defaultAgentRoot(), DOMAIN_KNOWLEDGE_DIR))
205
+ return resolve(process.env.DSH_KNOWLEDGE_ROOT || join(legacyDefaultAgentRoot(), DOMAIN_KNOWLEDGE_DIR))
203
206
  }
204
207
 
205
208
  /** `<agentRoot>/domain_knowledge`。 */
@@ -225,8 +228,8 @@ export function knowledgeBaseRoot(agentRoot: string, kbId: string): string {
225
228
  *
226
229
  * 二级目录按日期分桶(`output/<YYYY-MM-DD>/`),由转换内核的 `bucketByDay` 打开;
227
230
  * 再下一级是**文档的中文名**(`dsh-convert-core` 的 `deliveryDirName(label)`:取标题,
228
- * 没有标题取文件名,≤25 字,同名让路 `-2`)。Agent 自己写文件时的命名约定见 preset
229
- * 的人格提示词 —— 同一个规则有两处措辞(提示词约束 Agent、代码约束内核),改请一起改。
231
+ * 没有标题取文件名,≤25 字,同名让路 `-2`)。Agent 自己写文件时的命名约定见
232
+ * `agent-behavior-rules.ts` —— 提示词约束 Agent,代码约束内核,改动时一起更新。
230
233
  *
231
234
  * @param workspace - 当前工作项目的绝对路径。
232
235
  */
@@ -239,31 +242,6 @@ export function tmpRoot(agentRoot: string): string {
239
242
  return join(resolve(agentRoot), TMP_DIR)
240
243
  }
241
244
 
242
- /**
243
- * 随插件分发的 preset **真源目录**:`<包根>/preset/tita-data-agent/`。
244
- *
245
- * ## 它和「DSH 装好的 preset」不是一回事
246
- *
247
- * 0.1.7 起 DSH 那边 preset 不再是一个目录,而是 profile 组合里的一条声明行
248
- * (见 docs/current/06-Agent-preset的注入形态.md)。但**写提示词的人需要一个能编辑的地方**,那个地方就是这里:
249
- * `agent.cordis.yml` 的 `persona` 行是提示词的唯一真源,改完跑 `pnpm sync:preset`
250
- * 把它编译进 `cordis.patch.yml`。所以「打开 preset 目录」打开的是这个目录 ——
251
- * 不是 DSH 内部某个装好的副本(那种副本不存在,存在也会被下次编译覆盖)。
252
- *
253
- * 从 `lib/types/index.js` 回退两级就是包根,所以这个路径在源码仓库里跑和从
254
- * npm 安装后跑都成立。路径不存在时调用方应当如实说明,而不是弹一个空目录。
255
- */
256
- export function presetSourceDir(): string {
257
- return resolve(dirname(fileURLToPath(import.meta.url)), '../../preset', TITA_PRESET_ID)
258
- }
259
-
260
- /**
261
- * 这个 preset 的 id。与 `src/client/agent-preset.ts` 的 `TITA_PRESET_ID`、
262
- * `scripts/install-agent-preset.mjs` 的 `PRESET_ID` 是同一个值 —— 三处各留一份
263
- * 是因为它们分属三个编译单元(宿主 / 浏览器 / 脚本),测试会钉住它们一致。
264
- */
265
- export const TITA_PRESET_ID = 'tita-data-agent'
266
-
267
245
  /** `<agentRoot>/resource`。 */
268
246
  export function resourceRoot(agentRoot: string): string {
269
247
  return join(resolve(agentRoot), RESOURCE_DIR)
@@ -377,6 +355,8 @@ export function intentRoot(agentRoot: string): string {
377
355
  export const KNOWLEDGE_DB_FILE = 'knowledge.db'
378
356
  export const DERIVED_DB_FILE = 'derived.db'
379
357
  export const ASSETS_DIR = 'assets'
358
+ /** Hidden marker: standalone published images must survive source/card orphan sweeps. */
359
+ export const PUBLISHED_IMAGE_MARKER = '.dsh-published-image'
380
360
  /**
381
361
  * 原始输入的落点(0067)。与 {@link ASSETS_DIR} **并列且同构**:一个装内容里提取出来的
382
362
  * 图,一个装用户送进来的原件 —— 两者都是「从这个知识库里能直接拿到手的东西」,
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 物化阶段的语料快照(0070)—— **只有服务端看得见**。
3
+ *
4
+ * 它刻意不放在 `pipeline/types.ts` 里:那个模块被客户端 import(`PIPELINE_ACTIVE_STATES`
5
+ * 这类值),而本文件的字段类型来自 `knowledge.ts` / `events.ts` / `source-images.ts` /
6
+ * `card-organize.ts`,它们全都 `import 'node:…'`。把服务端模块拉进客户端的类型程序,
7
+ * 浏览器与 Node 的类型边界就没了(这条规矩写在 `wiki-trial-types.ts` 里)。
8
+ * 引擎只把这个对象原样传回去,所以它在引擎那边是 `unknown`。
9
+ *
10
+ * ## 为什么是「一次阶段运行算一份」
11
+ *
12
+ * 物化是逐组的,而每一组都要用到全库的东西:别组的正文(图片分发)、全部卡片(相关推荐)、
13
+ * 全部事件、全部知识。每组现算一遍就是 O(组数 × 语料) —— 几百张卡时单线程跑不完。
14
+ *
15
+ * ## 快照的边界
16
+ *
17
+ * 语料在**同一条串行队列里**是不变的(归一排在物化后面)。但别的写入者(另一个进程、
18
+ * 同一个库的另一条路径)不受这条队列约束,所以写回之前仍然要**单独复查这一组**的
19
+ * 事实(`freshGroupFingerprint`);而**人工裁决**从来不被快照 —— 卡片状态在每次写之前
20
+ * 重读并与旧值比对(见 `materializePipelineGroup`)。
21
+ */
22
+ import type { OrganizeRelatedCandidate } from './card-organize.js'
23
+ import type { EventEntity } from './events.js'
24
+ import type { Knowledge } from './knowledge.js'
25
+ import type { MaterializationGroup } from './pipeline/types.js'
26
+ import type { SourceImage } from './source-images.js'
27
+
28
+ export interface MaterializationSnapshot {
29
+ groups: MaterializationGroup[]
30
+ /** 坐标仍有歧义 + 等待归一,两部分的合计(分开的两个字段见下)。 */
31
+ blocked: number
32
+ /** 坐标仍有歧义的 Knowledge 条数。这些行不属于任何分组。 */
33
+ blockedAmbiguous: number
34
+ /** 来源已变化 / 新抽取尚未归一的 Knowledge 条数。 */
35
+ blockedAwaitingNormalize: number
36
+ /** key → 这一组参与成卡的知识。 */
37
+ knowledge: Map<string, Knowledge[]>
38
+ /** key → 这一组的 Event。 */
39
+ events: Map<string, EventEntity[]>
40
+ /** 图片分发:全部来源正文,阶段内只读一次。 */
41
+ sources: Array<{ sourceId: string; content: string }>
42
+ /** 图片分发计划:整库算一次,按组取。 */
43
+ images: Map<string, SourceImage[]>
44
+ /** 相关推荐计划:整库算一次,按组取(键是分组键,不是卡片身份)。 */
45
+ related: Map<string, OrganizeRelatedCandidate[]>
46
+ }