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
@@ -1,26 +1,5 @@
1
- /**
2
- * 「轴实体」配置区块(0063 §3)——**这张界面就是 Resolve 那一步的词汇表**。
3
- *
4
- * ## 它是什么
5
- *
6
- * Object / Action / Scene 三个轴的 canonical 身份。抽取阶段拿到的是 **mention**
7
- * (原文里怎么称呼它),Resolve 把它变成实体 —— 而实体要有一个能查、能改的地方。
8
- * 就是这里。
9
- *
10
- * ## 为什么「候选」是一等状态
11
- *
12
- * 抽取先建 `candidate`,人后确认 —— 与卡片「入库在前、review 在后」同一条纪律。
13
- * 「先确认才准建」会让一份新文档里的每个新名字都变成「未解析」,而人根本看不到它们;
14
- * 建了候选,至少「库里现在有哪些实体、哪些还没人看过」有答案。
15
- *
16
- * ## 三个动作都可逆
17
- *
18
- * 确认能撤销(停用 / 退回候选)、改名留旧名做别名、并了能再改。
19
- * 与卡片 review 一样,**它们都不是准入凭证**。
20
- */
21
-
22
1
  import { useCallback, useEffect, useState, type ChangeEvent, type ReactNode } from 'react'
23
- import { Check, Pencil, Plus, X } from '@tita-agent/ui/icons'
2
+ import { Check, ChevronDown, ChevronUp, Pencil, Plus, Search, X } from '@tita-agent/ui/icons'
24
3
  import { Badge, Button, Field, Input, SelectMenu, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, cn } from '@tita-agent/ui/components'
25
4
  import {
26
5
  Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle,
@@ -38,13 +17,12 @@ export interface AxisEntityView {
38
17
  scopeId: string
39
18
  status: AxisStatus
40
19
  aliases: string[]
41
- /** 一句话说清它指什么、边界在哪(0068)。空串 = 还没人写过。 */
20
+ /** 实体定义;空串表示尚未填写。 */
42
21
  description: string
43
- /** 这段定义是谁写的。`human` 之后模型不许覆盖它。 */
22
+ /** 人工修订后的定义不会被模型覆盖。 */
44
23
  descriptionSource: 'model' | 'human' | ''
45
24
  }
46
25
 
47
- /** 挂在轴实体上的人工指导(0063 §4.4,0068 落地)。 */
48
26
  export interface AxisGuidanceView {
49
27
  id: string
50
28
  kind: AxisGuidanceKind
@@ -53,9 +31,18 @@ export interface AxisGuidanceView {
53
31
  createdAt: string
54
32
  }
55
33
 
34
+ export interface AxisRelationView {
35
+ id: string
36
+ fromId: string
37
+ toId: string
38
+ relationType: 'related_to'
39
+ evidence: string
40
+ createdAt: string
41
+ updatedAt: string
42
+ }
43
+
56
44
  export type AxisGuidanceKind = 'prefer_name' | 'do_not_merge' | 'scope_rule' | 'definition' | 'extraction_hint'
57
45
 
58
- /** 五种指导的显示名。**说的是「模型拿到之后该怎么做」**,不是分类学。 */
59
46
  const GUIDANCE_LABEL: Record<AxisGuidanceKind, string> = {
60
47
  prefer_name: '优先用这个名',
61
48
  do_not_merge: '别并进来',
@@ -66,17 +53,15 @@ const GUIDANCE_LABEL: Record<AxisGuidanceKind, string> = {
66
53
 
67
54
  const GUIDANCE_KINDS = Object.keys(GUIDANCE_LABEL) as AxisGuidanceKind[]
68
55
 
69
- /** AI 生成的定义下一轮可以刷新;人工修改后变成稳定约束。 */
70
56
  const DESCRIPTION_SOURCE_LABEL: Record<'model' | 'human', string> = {
71
57
  model: 'AI 生成',
72
58
  human: '人工修订',
73
59
  }
74
60
 
75
- /** 三个轴的显示名与顺序。顺序就是坐标的读法:对象 × 动作 × 场景。 */
76
61
  const AXIS: Array<{ kind: AxisKind; label: string; hint: string }> = [
77
- { kind: 'object', label: '对象', hint: '正在处理什么?稳定、可引用、可操作或可观察的对象,例如指标、表、字段、产品或数据方案。' },
78
- { kind: 'action', label: '动作', hint: '正在做什么?围绕对象发生的操作或认知活动,例如查询、取数、分析、排查或修改。' },
79
- { kind: 'scene', label: '场景', hint: '在什么情况下?只有会改变知识边界、处理方式或判断标准的状态、环境和约束,才登记为场景。' },
62
+ { kind: 'object', label: '对象', hint: '知识涉及的对象。' },
63
+ { kind: 'action', label: '动作', hint: '对对象执行的操作。' },
64
+ { kind: 'scene', label: '场景', hint: '知识适用的场景与约束。' },
80
65
  ]
81
66
 
82
67
  const STATUS_LABEL: Record<AxisStatus, string> = {
@@ -90,13 +75,11 @@ interface Draft {
90
75
  name: string
91
76
  aliases: string
92
77
  mergeInto: string
93
- /** 定义(0068)。它与改名 / 别名一起在「保存」时提交 —— 它是一个字段,不是一个列表。 */
94
78
  description: string
95
79
  }
96
80
 
97
81
  const EMPTY_DRAFT: Draft = { open: false, id: '', kind: 'object', name: '', aliases: '', mergeInto: '', description: '' }
98
82
 
99
- /** 对话框里新加一条指导的草稿。它**立即生效**(列表项各有身份,不适合跟着「保存」一起提交)。 */
100
83
  interface GuidanceDraft {
101
84
  kind: AxisGuidanceKind
102
85
  text: string
@@ -115,24 +98,24 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
115
98
  const [loading, setLoading] = useState(false)
116
99
  const [draft, setDraft] = useState<Draft>(EMPTY_DRAFT)
117
100
  const [guidance, setGuidance] = useState<Record<string, AxisGuidanceView[]>>({})
101
+ const [relations, setRelations] = useState<AxisRelationView[]>([])
118
102
  const [guideDraft, setGuideDraft] = useState<GuidanceDraft>({ kind: 'prefer_name', text: '' })
119
- /**
120
- * 三个轴并排成 tab(2026-10-06)。
121
- *
122
- * 它们本来是**坐标的三个分量**(对象 × 动作 × 场景),竖着堆成三段会让人以为它们是三层
123
- * 或者有先后关系。并排之后一眼看到三类各有几个,切过去看内容 —— 与「知识」那一栏的
124
- * 矩阵是同一种读法。
125
- */
103
+ const [relationDraftId, setRelationDraftId] = useState('')
104
+ const [relationEvidence, setRelationEvidence] = useState('')
105
+ const [showEditorTools, setShowEditorTools] = useState(false)
126
106
  const [kindTab, setKindTab] = useState<AxisKind>('object')
107
+ const [searchQuery, setSearchQuery] = useState('')
108
+ const [statusFilter, setStatusFilter] = useState<'all' | AxisStatus>('all')
127
109
  const [error, setError] = useState('')
128
110
 
129
111
  const load = useCallback(async (): Promise<void> => {
130
112
  if (!kbId) return
131
113
  setLoading(true)
132
114
  try {
133
- const payload = await requestJson<{ entities: AxisEntityView[]; guidance: Record<string, AxisGuidanceView[]>; available: boolean }>(`/knowledge/axes?kb=${encodeURIComponent(kbId)}`)
115
+ const payload = await requestJson<{ entities: AxisEntityView[]; guidance: Record<string, AxisGuidanceView[]>; relations: AxisRelationView[]; available: boolean }>(`/knowledge/axes?kb=${encodeURIComponent(kbId)}`)
134
116
  setEntities(payload.data?.entities ?? [])
135
117
  setGuidance(payload.data?.guidance ?? {})
118
+ setRelations(payload.data?.relations ?? [])
136
119
  setAvailable(payload.data?.available ?? false)
137
120
  setError('')
138
121
  } catch (cause) {
@@ -143,11 +126,12 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
143
126
  }, [kbId])
144
127
 
145
128
  useEffect(() => { void load() }, [load])
129
+ useEffect(() => {
130
+ setKindTab('object')
131
+ setSearchQuery('')
132
+ setStatusFilter('all')
133
+ }, [kbId])
146
134
 
147
- /**
148
- * 一个写动作。四处调用共用它,所以「忙」与「报错」只有一套 ——
149
- * 三个动作各写一遍的话,迟早有一个忘了把错误显示出来。
150
- */
151
135
  const post = async (body: Record<string, unknown>, done?: () => void): Promise<void> => {
152
136
  if (!kbId) return
153
137
  onBusyChange?.(true)
@@ -176,17 +160,16 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
176
160
  description: entity.description,
177
161
  })
178
162
  setGuideDraft({ kind: 'prefer_name', text: '' })
163
+ setRelationDraftId('')
164
+ setRelationEvidence('')
165
+ setShowEditorTools(false)
179
166
  }
180
167
 
181
- /** 保存编辑:改名 + 补别名 + (可选)并进另一个实体。三件事一次提交,顺序固定。 */
182
168
  const saveEditor = async (): Promise<void> => {
183
169
  const editing = entities.find(item => item.id === draft.id)
184
170
  const name = draft.name.trim()
185
171
  if (editing && name && name !== editing.name) await post({ action: 'rename', id: draft.id, name })
186
- /*
187
- * 定义变了才写。**写了就是决定**(`description_source` 落成 human),模型从此不许覆盖 ——
188
- * 所以不能在打开对话框时无条件重写一遍,那会把「模型写的」也蹭成「人写的」。
189
- */
172
+ // A changed description becomes human-authored, so avoid rewriting an unchanged value.
190
173
  if (editing && draft.description.trim() !== editing.description) {
191
174
  await post({ action: 'describe', id: draft.id, description: draft.description.trim() })
192
175
  }
@@ -199,18 +182,36 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
199
182
  setDraft(EMPTY_DRAFT)
200
183
  }
201
184
 
202
- /** 弹窗正在编辑的那个实体。改名后 `entities` 会变,所以按 id 现查 —— 不缓存。 */
203
185
  const target = entities.find(item => item.id === draft.id) ?? null
186
+ const relatedFor = (entityId: string): AxisRelationView[] => relations.filter(item => item.fromId === entityId || item.toId === entityId)
187
+ const relatedEntityId = (relation: AxisRelationView, entityId: string): string => relation.fromId === entityId ? relation.toId : relation.fromId
188
+ const relatedEntities = entities.filter(item => item.kind === 'object' && item.status !== 'merged' && item.id !== draft.id
189
+ && !relatedFor(draft.id).some(relation => relatedEntityId(relation, draft.id) === item.id))
204
190
  const byKind = (kind: AxisKind): AxisEntityView[] => entities.filter(entity => entity.kind === kind)
191
+ const filteredByKind = (kind: AxisKind): AxisEntityView[] => {
192
+ const needle = searchQuery.trim().toLocaleLowerCase()
193
+ const statusOrder: Record<AxisStatus, number> = { candidate: 0, active: 1, deprecated: 2, merged: 3 }
194
+ return byKind(kind)
195
+ .filter(entity => statusFilter === 'all' || entity.status === statusFilter)
196
+ .filter(entity => needle === '' || [
197
+ entity.name,
198
+ entity.id,
199
+ entity.description,
200
+ ...entity.aliases,
201
+ ...(guidance[entity.id] ?? []).map(item => item.text),
202
+ ].some(value => value.toLocaleLowerCase().includes(needle)))
203
+ // 待确认项优先,其余按名称排。注册表变大后,待处理项不用再靠滚动寻找。
204
+ .sort((left, right) => statusOrder[left.status] - statusOrder[right.status] || left.name.localeCompare(right.name, 'zh-CN'))
205
+ }
205
206
  const candidates = entities.filter(entity => entity.status === 'candidate').length
206
207
 
207
208
  if (!available) {
208
209
  return <section className={styles.settingsSection}>
209
210
  <div className={styles.settingsSectionHeader}>
210
- <div><h3>知识矩阵实体注册表</h3></div>
211
+ <div><h3>坐标实体</h3></div>
211
212
  </div>
212
213
  <p className={styles.kbHint}>
213
- 当前环境还没有可用的坐标注册表。抽取试跑仍可运行,但无法核对库内已有的对象、动作和场景;报告会明确标记为“未查询注册表”。
214
+ 当前环境没有坐标注册表,试跑会跳过实体核对。
214
215
  </p>
215
216
  </section>
216
217
  }
@@ -218,34 +219,50 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
218
219
  return <section className={styles.settingsSection}>
219
220
  <div className={styles.settingsSectionHeader}>
220
221
  <div className={styles.settingsSectionHeaderTitle}>
221
- <h3>知识矩阵实体注册表</h3>
222
- <span className={styles.kbCount}>
223
- {entities.length} 个实体{candidates > 0 ? ` · ${candidates} 个待确认` : ''}
224
- </span>
222
+ <h3>坐标实体</h3>
223
+ {candidates > 0 && <span className={styles.kbCount}>{candidates} 个待确认</span>}
225
224
  </div>
226
225
  </div>
227
226
 
228
227
  {error && <p className={styles.trialError} role="alert">{error}</p>}
229
228
 
230
229
  {entities.length === 0 && !loading && <p className={styles.kbHint}>
231
- 还没有坐标实体。运行一次“编译”或“抽取试跑”,系统会把文档中识别出的对象、动作和场景登记到这里。
232
- 没有坐标的知识仍可检索,但不会进入坐标矩阵,也不会生成 Wiki Card。
230
+ 暂无坐标实体,运行编译后会自动登记。
233
231
  </p>}
234
232
 
235
233
  <Tabs value={kindTab} onValueChange={value => setKindTab(value as AxisKind)}>
236
234
  <TabsList className={cn(styles.tabsList, styles.kbViewTabs, styles.axisKindTabs)}>
237
235
  {AXIS.map(axis => <TabsTrigger key={axis.kind} value={axis.kind}>
238
236
  {axis.label}
239
- {/* 计数进 tab:切之前就要知道「这一类有几个」—— 空的那一类不该让人点进去才发现。 */}
240
237
  <span className={styles.axisKindCount}>{byKind(axis.kind).length}</span>
241
238
  </TabsTrigger>)}
242
239
  </TabsList>
240
+ {entities.length > 0 && <div className={styles.axisFilters}>
241
+ <div className={styles.axisSearchControl}>
242
+ <Search size={14} aria-hidden="true" />
243
+ <Input value={searchQuery} spellCheck={false} aria-label="搜索名称、别名、定义或 ID"
244
+ placeholder="搜索名称、别名、定义或 ID" onChange={event => setSearchQuery(event.target.value)} />
245
+ </div>
246
+ <SelectMenu value={statusFilter} aria-label="按状态筛选实体"
247
+ options={[
248
+ { value: 'all', label: '全部状态' },
249
+ { value: 'candidate', label: '待确认' },
250
+ { value: 'active', label: '已确认' },
251
+ { value: 'deprecated', label: '已停用' },
252
+ { value: 'merged', label: '已并入' },
253
+ ]}
254
+ onValueChange={value => setStatusFilter(value as 'all' | AxisStatus)} />
255
+ <span className={styles.axisFilterCount} aria-live="polite">
256
+ {filteredByKind(kindTab).length} / {byKind(kindTab).length}
257
+ </span>
258
+ </div>}
243
259
  {AXIS.map(axis => {
244
- const rows = byKind(axis.kind)
260
+ const allRows = byKind(axis.kind)
261
+ const rows = filteredByKind(axis.kind)
245
262
  return <TabsContent key={axis.kind} value={axis.kind}>
246
- {/* 这一类装什么,写在它自己的内容里 —— 三个提示并排挤在 tab 上会读成一句话。 */}
247
263
  <p className={styles.kbHint}>{axis.hint}</p>
248
- {rows.length === 0 && <p className={styles.kbHint}>这一类还没有实体。</p>}
264
+ {allRows.length === 0 && !loading && <p className={styles.kbHint}>这一类还没有实体。</p>}
265
+ {allRows.length > 0 && rows.length === 0 && <p className={styles.kbHint}>没有匹配的实体。</p>}
249
266
  <ul className={styles.axisList}>
250
267
  {rows.map(entity => <li key={entity.id} className={styles.axisRow}>
251
268
  <span className={styles.axisName}>
@@ -255,22 +272,17 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
255
272
  {STATUS_LABEL[entity.status]}
256
273
  </Badge>
257
274
  {entity.scopeId ? <span className={styles.axisScope} title={`作用域:${entity.scopeId}`}>有作用域</span> : null}
275
+ {entity.kind === 'object' && relatedFor(entity.id).length > 0 ? <span className={styles.axisScope}>相关 {relatedFor(entity.id).length}</span> : null}
258
276
  </span>
259
- <span className={styles.axisAliases}>
260
- 别名:{entity.aliases.filter(alias => alias !== entity.name).length > 0
261
- ? entity.aliases.filter(alias => alias !== entity.name).join('、')
262
- : '暂无(AI 还没有发现其他叫法)'}
263
- </span>
264
- {/*
265
- 定义与指导都在行上露出来(0068):它们是**下一次抽取的参考**,而参考的质量
266
- 决定了矩阵会不会裂成两半。藏在编辑弹窗里,人就不会去看它。
267
- */}
268
- <span className={styles.axisAliases}>
269
- 定义:{entity.description || '暂无(等待 AI 补充或人工填写)'}
277
+ {entity.aliases.filter(alias => alias !== entity.name).length > 0 && <span className={styles.axisAliases}>
278
+ 别名:{entity.aliases.filter(alias => alias !== entity.name).join('、')}
279
+ </span>}
280
+ {entity.description !== '' && <span className={styles.axisAliases}>
281
+ 定义:{entity.description}
270
282
  {entity.descriptionSource !== '' && <span className={styles.axisScope}>
271
283
  {' '}{DESCRIPTION_SOURCE_LABEL[entity.descriptionSource]}
272
284
  </span>}
273
- </span>
285
+ </span>}
274
286
  {(guidance[entity.id]?.length ?? 0) > 0 && <span className={styles.axisScope}>
275
287
  {(guidance[entity.id] ?? []).length} 条人工指导
276
288
  </span>}
@@ -292,101 +304,129 @@ export function AxisRegistrySection({ kbId, canEdit, onBusyChange }: AxisRegistr
292
304
  })}
293
305
  </Tabs>
294
306
 
295
- <Dialog open={draft.open} onOpenChange={next => { if (!next) setDraft(EMPTY_DRAFT) }}>
296
- <DialogContent>
297
- <DialogHeader><DialogTitle>编辑知识矩阵实体</DialogTitle></DialogHeader>
298
- <div className={styles.kbForm}>
299
- <Field label="标准名称">
300
- <Input value={draft.name} spellCheck={false} disabled={!canEdit}
301
- placeholder="例如:通天塔坑位click;要求脱离来源也能看懂"
302
- onChange={(event: ChangeEvent<HTMLInputElement>) => setDraft({ ...draft, name: event.target.value })} />
303
- </Field>
304
- <p className={styles.kbHint}>
305
- 改名后旧名会自动保留为别名,历史知识仍指向同一个实体。
306
- </p>
307
- <Field label="定义">
308
- <Textarea value={draft.description} spellCheck={false} disabled={!canEdit}
309
- placeholder="一句话说明它指什么、边界在哪里。例如:通天塔投放位上的一次点击上报,只在通天塔作用域内成立。"
310
- onChange={(event: ChangeEvent<HTMLTextAreaElement>) => setDraft({ ...draft, description: event.target.value })} />
311
- </Field>
312
- <p className={styles.kbHint}>
313
- 这段定义会进入下一次抽取提示词。AI 生成的定义可以被你修订;人工修订后,AI 不会覆盖它。
314
- {(draft.description !== '' && target !== null && target.descriptionSource !== '') && <>
315
- {' '}当前来源:<b>{DESCRIPTION_SOURCE_LABEL[target.descriptionSource]}</b>。
316
- </>}
317
- </p>
307
+ <Dialog open={draft.open} onOpenChange={next => {
308
+ if (!next) {
309
+ setDraft(EMPTY_DRAFT)
310
+ setShowEditorTools(false)
311
+ }
312
+ }}>
313
+ <DialogContent className={styles.axisEditorDialog}>
314
+ <DialogHeader>
315
+ <DialogTitle>编辑坐标实体</DialogTitle>
316
+ </DialogHeader>
317
+ <div className={styles.axisEditorBody}>
318
+ {error && <p className={styles.trialError} role="alert">{error}</p>}
319
+ <div className={styles.axisEditorCore}>
320
+ <Field label="标准名称">
321
+ <Input value={draft.name} spellCheck={false} disabled={!canEdit}
322
+ placeholder="输入标准名称"
323
+ onChange={(event: ChangeEvent<HTMLInputElement>) => setDraft({ ...draft, name: event.target.value })} />
324
+ </Field>
325
+ <Field label={<>定义 {target?.descriptionSource && <Badge tone="neutral">{DESCRIPTION_SOURCE_LABEL[target.descriptionSource]}</Badge>}</>}>
326
+ <Textarea value={draft.description} spellCheck={false} disabled={!canEdit}
327
+ placeholder="补充定义与边界(可选)"
328
+ onChange={(event: ChangeEvent<HTMLTextAreaElement>) => setDraft({ ...draft, description: event.target.value })} />
329
+ </Field>
330
+ <Field label="别名">
331
+ <Textarea value={draft.aliases} spellCheck={false} disabled={!canEdit}
332
+ placeholder="每行一个别名"
333
+ onChange={(event: ChangeEvent<HTMLTextAreaElement>) => setDraft({ ...draft, aliases: event.target.value })} />
334
+ </Field>
335
+ </div>
336
+
337
+ <Button className={styles.axisEditorToggle} variant="ghost" size="sm" type="button"
338
+ aria-expanded={showEditorTools} aria-controls="axis-editor-tools"
339
+ onClick={() => setShowEditorTools(value => !value)}>
340
+ {showEditorTools ? <ChevronUp size={13} /> : <ChevronDown size={13} />}
341
+ 更多操作
342
+ </Button>
343
+
344
+ <div className={styles.axisEditorTools} id="axis-editor-tools" hidden={!showEditorTools}>
345
+ {draft.kind === 'object' && <Field as="div" label="相关对象" hint="查询命中这个对象时,会沿相关关系召回对方的卡片。">
346
+ {relatedFor(draft.id).length > 0 && <ul className={cn(styles.axisList, styles.axisEditorRelationList)}>
347
+ {relatedFor(draft.id).map(relation => {
348
+ const otherId = relatedEntityId(relation, draft.id)
349
+ const other = entities.find(item => item.id === otherId)
350
+ return <li key={relation.id} className={styles.axisRow}>
351
+ <span className={styles.axisName}>
352
+ <Badge tone="neutral">相关</Badge>
353
+ <span className={styles.axisLabel}>{other?.name ?? otherId}</span>
354
+ {relation.evidence && <span className={styles.axisAliases}>{relation.evidence}</span>}
355
+ </span>
356
+ <span className={styles.axisActions}>
357
+ <Button variant="ghost" size="icon" title="移除对象关系" aria-label={`移除与 ${other?.name ?? otherId} 的关系`}
358
+ disabled={!canEdit} onClick={() => void post({ action: 'relation-remove', relation_id: relation.id })}>
359
+ <X size={12} />
360
+ </Button>
361
+ </span>
362
+ </li>
363
+ })}
364
+ </ul>}
365
+ {relatedEntities.length > 0
366
+ ? <div className={styles.axisEditorRelationComposer}>
367
+ <SelectMenu value={relationDraftId} disabled={!canEdit} aria-label="选择相关对象"
368
+ options={[{ value: '', label: '选择对象' }, ...relatedEntities.map(item => ({ value: item.id, label: item.name }))]}
369
+ onValueChange={setRelationDraftId} />
370
+ <Input value={relationEvidence} spellCheck={false} disabled={!canEdit}
371
+ placeholder="关系依据(可选)" aria-label="关系依据"
372
+ onChange={(event: ChangeEvent<HTMLInputElement>) => setRelationEvidence(event.target.value)} />
373
+ <Button variant="outline" size="sm" disabled={!canEdit || relationDraftId === ''}
374
+ onClick={() => void post({ action: 'relation-add', relation_type: 'related_to', from_id: draft.id, to_id: relationDraftId, evidence: relationEvidence }, () => {
375
+ setRelationDraftId('')
376
+ setRelationEvidence('')
377
+ })}>
378
+ <Plus size={12} />添加
379
+ </Button>
380
+ </div>
381
+ : <p className={styles.kbHint}>没有可关联的其他对象。</p>}
382
+ </Field>}
318
383
 
319
- <Field label="别名">
320
- <Textarea value={draft.aliases} spellCheck={false} disabled={!canEdit}
321
- placeholder={'每行一个。AI 发现的原文叫法通常会自动进入这里,例如:\n通天塔坑位click\n坑位click'}
322
- onChange={(event: ChangeEvent<HTMLTextAreaElement>) => setDraft({ ...draft, aliases: event.target.value })} />
323
- </Field>
324
- <p className={styles.kbHint}>
325
- 只添加同一实体的其他叫法;不要添加上位概念、组成部分或相关但不同的名称。
326
- </p>
327
- {/* 指导:一条件事,所以加/撤**立即生效**,不跟着下面那个「保存」走。 */}
328
- <Field as="div" label="人工指导">
329
- <span className={styles.kbHint}>{(guidance[draft.id] ?? []).length} 条</span>
330
- {(guidance[draft.id] ?? []).length === 0
331
- ? <p className={styles.kbHint}>
332
- 还没有。这里写的话会<b>逐字进下一次抽取的提示词</b> —— 名字该怎么理解、什么别并进来、
333
- 它属于哪个作用域。它是「人指挥模型怎么认坐标」的唯一入口。
334
- </p>
335
- : <ul className={styles.axisList}>
384
+ <Field as="div" label={<>人工指导 <Badge tone="neutral">立即生效</Badge></>}>
385
+ {(guidance[draft.id] ?? []).length > 0 && <ul className={cn(styles.axisList, styles.axisEditorGuidanceList)}>
336
386
  {(guidance[draft.id] ?? []).map(item => <li key={item.id} className={styles.axisRow}>
337
- <span className={styles.axisName}>
338
- <Badge tone="neutral">{GUIDANCE_LABEL[item.kind]}</Badge>
339
- <span className={styles.axisLabel}>{item.text}</span>
340
- {item.author !== '' && <span className={styles.axisScope}>{item.author}</span>}
341
- </span>
342
- <span className={styles.axisActions}>
343
- <Button variant="ghost" size="icon" title="撤掉这条指导" aria-label="撤掉这条指导"
344
- disabled={!canEdit} onClick={() => void post({ action: 'guide-remove', id: draft.id, guidance_id: item.id })}>
345
- <X size={12} />
346
- </Button>
347
- </span>
348
- </li>)}
387
+ <span className={styles.axisName}>
388
+ <Badge tone="neutral">{GUIDANCE_LABEL[item.kind]}</Badge>
389
+ <span className={styles.axisLabel}>{item.text}</span>
390
+ {item.author !== '' && <span className={styles.axisScope}>{item.author}</span>}
391
+ </span>
392
+ <span className={styles.axisActions}>
393
+ <Button variant="ghost" size="icon" title="移除指导" aria-label="移除指导"
394
+ disabled={!canEdit} onClick={() => void post({ action: 'guide-remove', id: draft.id, guidance_id: item.id })}>
395
+ <X size={12} />
396
+ </Button>
397
+ </span>
398
+ </li>)}
349
399
  </ul>}
350
- <SelectMenu
351
- value={guideDraft.kind}
352
- disabled={!canEdit}
353
- aria-label="指导类型"
354
- options={GUIDANCE_KINDS.map(kind => ({ value: kind, label: GUIDANCE_LABEL[kind] }))}
355
- onValueChange={value => setGuideDraft({ ...guideDraft, kind: value as AxisGuidanceKind })}
356
- />
357
- <Input value={guideDraft.text} spellCheck={false} disabled={!canEdit}
358
- placeholder="坑位click 在通天塔作用域内指通天塔坑位click,不是全局对象。"
359
- aria-label="指导内容"
360
- onChange={(event: ChangeEvent<HTMLInputElement>) => setGuideDraft({ ...guideDraft, text: event.target.value })} />
361
- <Button variant="outline" size="sm" disabled={!canEdit || guideDraft.text.trim() === ''}
362
- title="加上去立即生效:指导是一条条独立的东西,不跟着「保存」走"
363
- onClick={() => void post({ action: 'guide-add', id: draft.id, guidance_kind: guideDraft.kind, text: guideDraft.text }, () => setGuideDraft({ kind: guideDraft.kind, text: '' }))}>
364
- <Plus size={12} />加一条
365
- </Button>
366
- </Field>
400
+ <div className={styles.axisEditorGuidanceComposer}>
401
+ <SelectMenu value={guideDraft.kind} disabled={!canEdit} aria-label="指导类型"
402
+ options={GUIDANCE_KINDS.map(kind => ({ value: kind, label: GUIDANCE_LABEL[kind] }))}
403
+ onValueChange={value => setGuideDraft({ ...guideDraft, kind: value as AxisGuidanceKind })} />
404
+ <Input value={guideDraft.text} spellCheck={false} disabled={!canEdit}
405
+ placeholder="指导内容" aria-label="指导内容"
406
+ onChange={(event: ChangeEvent<HTMLInputElement>) => setGuideDraft({ ...guideDraft, text: event.target.value })} />
407
+ <Button variant="outline" size="sm" disabled={!canEdit || guideDraft.text.trim() === ''}
408
+ onClick={() => void post({ action: 'guide-add', id: draft.id, guidance_kind: guideDraft.kind, text: guideDraft.text }, () => setGuideDraft({ kind: guideDraft.kind, text: '' }))}>
409
+ <Plus size={12} />添加
410
+ </Button>
411
+ </div>
412
+ </Field>
367
413
 
368
- <Field as="div" label="并入实体">
369
- <SelectMenu
370
- value={draft.mergeInto}
371
- disabled={!canEdit}
372
- aria-label="并入另一个实体"
373
- options={[
374
- { value: '', label: '不并入其他实体' },
375
- ...entities
376
- .filter(item => item.id !== draft.id && item.kind === draft.kind && item.status !== 'merged')
377
- .map(item => ({ value: item.id, label: `${item.name}(${item.id})` })),
378
- ]}
379
- onValueChange={value => setDraft({ ...draft, mergeInto: value })}
380
- />
381
- </Field>
382
- <p className={styles.kbHint}>
383
- 并了之后<b>被并的那个不删</b>:历史知识指着它的 id,删了就成了悬空引用。
384
- 它转成「已并入」并指向目标,它的别名也一起搬过去。
385
- </p>
414
+ <Field as="div" label="合并到" hint="保存时执行;历史引用会保留。">
415
+ <SelectMenu value={draft.mergeInto} disabled={!canEdit} aria-label="并入另一个实体"
416
+ options={[
417
+ { value: '', label: '不合并' },
418
+ ...entities
419
+ .filter(item => item.id !== draft.id && item.kind === draft.kind && item.status !== 'merged')
420
+ .map(item => ({ value: item.id, label: `${item.name}(${item.id})` })),
421
+ ]}
422
+ onValueChange={value => setDraft({ ...draft, mergeInto: value })}
423
+ />
424
+ </Field>
425
+ </div>
386
426
  </div>
387
- <DialogFooter>
427
+ <DialogFooter className={styles.axisEditorFooter}>
388
428
  <Button variant="ghost" onClick={() => setDraft(EMPTY_DRAFT)}><X size={13} />取消</Button>
389
- <Button disabled={!canEdit} onClick={() => void saveEditor()}><Plus size={13} />保存</Button>
429
+ <Button disabled={!canEdit || draft.name.trim() === ''} onClick={() => void saveEditor()}><Check size={13} />保存</Button>
390
430
  </DialogFooter>
391
431
  </DialogContent>
392
432
  </Dialog>