dsh-data-domain-knowledge 0.1.0-alpha.9 → 0.1.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/README.md +118 -567
  2. package/cordis.patch.yml +5 -418
  3. package/eval/README.md +19 -8
  4. package/eval/benchmark-extraction-format.mjs +20 -0
  5. package/eval/evaluate-retrieval.mjs +17 -8
  6. package/eval/queries.example.jsonl +1 -0
  7. package/lib/client.js +4181 -3239
  8. package/lib/contract-envelope.d.ts +91 -0
  9. package/lib/contract-envelope.js +106 -0
  10. package/lib/contract-layout.d.ts +130 -0
  11. package/lib/contract-layout.js +138 -0
  12. package/lib/contract-refs.d.ts +39 -0
  13. package/lib/contract-refs.js +9 -0
  14. package/lib/contract-version.d.ts +311 -0
  15. package/lib/contract-version.js +270 -0
  16. package/lib/contract-wire.d.ts +147 -0
  17. package/lib/contract-wire.js +99 -0
  18. package/lib/contracts.d.ts +12 -0
  19. package/lib/contracts.js +12 -0
  20. package/lib/doc-page.js +2 -2
  21. package/lib/pages.js +3329 -1296
  22. package/lib/types/agent-behavior-rules.d.ts +10 -0
  23. package/lib/types/agent-behavior-rules.d.ts.map +1 -0
  24. package/lib/types/agent-behavior-rules.js +28 -0
  25. package/lib/types/agent-behavior-rules.js.map +1 -0
  26. package/lib/types/axis-registry.d.ts +37 -5
  27. package/lib/types/axis-registry.d.ts.map +1 -1
  28. package/lib/types/axis-registry.js +234 -26
  29. package/lib/types/axis-registry.js.map +1 -1
  30. package/lib/types/card-organize.d.ts +27 -12
  31. package/lib/types/card-organize.d.ts.map +1 -1
  32. package/lib/types/card-organize.js +58 -73
  33. package/lib/types/card-organize.js.map +1 -1
  34. package/lib/types/compiler/embedding-identity.d.ts +3 -0
  35. package/lib/types/compiler/embedding-identity.d.ts.map +1 -0
  36. package/lib/types/compiler/embedding-identity.js +24 -0
  37. package/lib/types/compiler/embedding-identity.js.map +1 -0
  38. package/lib/types/compiler/snapshot.d.ts +16 -0
  39. package/lib/types/compiler/snapshot.d.ts.map +1 -0
  40. package/lib/types/compiler/snapshot.js +2 -0
  41. package/lib/types/compiler/snapshot.js.map +1 -0
  42. package/lib/types/config-schema.d.ts +6 -3
  43. package/lib/types/config-schema.d.ts.map +1 -1
  44. package/lib/types/config-schema.js +6 -2
  45. package/lib/types/config-schema.js.map +1 -1
  46. package/lib/types/convert/host.d.ts +6 -5
  47. package/lib/types/convert/host.d.ts.map +1 -1
  48. package/lib/types/convert/host.js +58 -18
  49. package/lib/types/convert/host.js.map +1 -1
  50. package/lib/types/convert/ingest.d.ts +10 -1
  51. package/lib/types/convert/ingest.d.ts.map +1 -1
  52. package/lib/types/convert/ingest.js +68 -9
  53. package/lib/types/convert/ingest.js.map +1 -1
  54. package/lib/types/derive-contract.d.ts +3 -0
  55. package/lib/types/derive-contract.d.ts.map +1 -0
  56. package/lib/types/derive-contract.js +15 -0
  57. package/lib/types/derive-contract.js.map +1 -0
  58. package/lib/types/diagnosis/cards.d.ts +7 -3
  59. package/lib/types/diagnosis/cards.d.ts.map +1 -1
  60. package/lib/types/diagnosis/cards.js +13 -8
  61. package/lib/types/diagnosis/cards.js.map +1 -1
  62. package/lib/types/diagnosis/run.d.ts +4 -13
  63. package/lib/types/diagnosis/run.d.ts.map +1 -1
  64. package/lib/types/diagnosis/run.js +26 -16
  65. package/lib/types/diagnosis/run.js.map +1 -1
  66. package/lib/types/diagnosis/schema.js +2 -2
  67. package/lib/types/diagnosis/schema.js.map +1 -1
  68. package/lib/types/diagnosis/seed-source.d.ts +1 -1
  69. package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
  70. package/lib/types/diagnosis/seed-source.js +5 -4
  71. package/lib/types/diagnosis/seed-source.js.map +1 -1
  72. package/lib/types/diagnosis/seed.d.ts +4 -4
  73. package/lib/types/diagnosis/seed.d.ts.map +1 -1
  74. package/lib/types/diagnosis/seed.js +6 -8
  75. package/lib/types/diagnosis/seed.js.map +1 -1
  76. package/lib/types/diagnosis/store.d.ts +24 -18
  77. package/lib/types/diagnosis/store.d.ts.map +1 -1
  78. package/lib/types/diagnosis/store.js +130 -65
  79. package/lib/types/diagnosis/store.js.map +1 -1
  80. package/lib/types/diagnosis/types.d.ts +47 -15
  81. package/lib/types/diagnosis/types.d.ts.map +1 -1
  82. package/lib/types/diagnosis/types.js.map +1 -1
  83. package/lib/types/environment/dsh-python.d.ts +77 -0
  84. package/lib/types/environment/dsh-python.d.ts.map +1 -0
  85. package/lib/types/environment/dsh-python.js +139 -0
  86. package/lib/types/environment/dsh-python.js.map +1 -0
  87. package/lib/types/environment/install.d.ts +15 -0
  88. package/lib/types/environment/install.d.ts.map +1 -0
  89. package/lib/types/environment/install.js +297 -0
  90. package/lib/types/environment/install.js.map +1 -0
  91. package/lib/types/environment/manifest.d.ts +208 -0
  92. package/lib/types/environment/manifest.d.ts.map +1 -0
  93. package/lib/types/environment/manifest.js +26 -0
  94. package/lib/types/environment/manifest.js.map +1 -0
  95. package/lib/types/environment/model-catalog.d.ts +223 -0
  96. package/lib/types/environment/model-catalog.d.ts.map +1 -0
  97. package/lib/types/environment/model-catalog.js +129 -0
  98. package/lib/types/environment/model-catalog.js.map +1 -0
  99. package/lib/types/environment/process.d.ts +10 -0
  100. package/lib/types/environment/process.d.ts.map +1 -0
  101. package/lib/types/environment/process.js +54 -0
  102. package/lib/types/environment/process.js.map +1 -0
  103. package/lib/types/environment/selection.d.ts +9 -0
  104. package/lib/types/environment/selection.d.ts.map +1 -0
  105. package/lib/types/environment/selection.js +29 -0
  106. package/lib/types/environment/selection.js.map +1 -0
  107. package/lib/types/environment/service.d.ts +64 -0
  108. package/lib/types/environment/service.d.ts.map +1 -0
  109. package/lib/types/environment/service.js +424 -0
  110. package/lib/types/environment/service.js.map +1 -0
  111. package/lib/types/environment/types.d.ts +56 -0
  112. package/lib/types/environment/types.d.ts.map +1 -0
  113. package/lib/types/environment/types.js +2 -0
  114. package/lib/types/environment/types.js.map +1 -0
  115. package/lib/types/events.d.ts +76 -0
  116. package/lib/types/events.d.ts.map +1 -0
  117. package/lib/types/events.js +52 -0
  118. package/lib/types/events.js.map +1 -0
  119. package/lib/types/extract-contract.d.ts +3 -0
  120. package/lib/types/extract-contract.d.ts.map +1 -0
  121. package/lib/types/extract-contract.js +41 -0
  122. package/lib/types/extract-contract.js.map +1 -0
  123. package/lib/types/extract-model.d.ts +5 -0
  124. package/lib/types/extract-model.d.ts.map +1 -1
  125. package/lib/types/extract-model.js.map +1 -1
  126. package/lib/types/extract-table-contract.d.ts +3 -0
  127. package/lib/types/extract-table-contract.d.ts.map +1 -0
  128. package/lib/types/extract-table-contract.js +27 -0
  129. package/lib/types/extract-table-contract.js.map +1 -0
  130. package/lib/types/extract-table.d.ts +8 -0
  131. package/lib/types/extract-table.d.ts.map +1 -0
  132. package/lib/types/extract-table.js +158 -0
  133. package/lib/types/extract-table.js.map +1 -0
  134. package/lib/types/extraction-runs.d.ts +30 -6
  135. package/lib/types/extraction-runs.d.ts.map +1 -1
  136. package/lib/types/extraction-runs.js +69 -8
  137. package/lib/types/extraction-runs.js.map +1 -1
  138. package/lib/types/fs-atomic.d.ts +0 -7
  139. package/lib/types/fs-atomic.d.ts.map +1 -1
  140. package/lib/types/fs-atomic.js +17 -2
  141. package/lib/types/fs-atomic.js.map +1 -1
  142. package/lib/types/images.d.ts +26 -0
  143. package/lib/types/images.d.ts.map +1 -0
  144. package/lib/types/images.js +196 -0
  145. package/lib/types/images.js.map +1 -0
  146. package/lib/types/index.d.ts +2 -2
  147. package/lib/types/index.d.ts.map +1 -1
  148. package/lib/types/index.js +598 -209
  149. package/lib/types/index.js.map +1 -1
  150. package/lib/types/intent/engine.d.ts +12 -4
  151. package/lib/types/intent/engine.d.ts.map +1 -1
  152. package/lib/types/intent/engine.js +43 -5
  153. package/lib/types/intent/engine.js.map +1 -1
  154. package/lib/types/intent/host.d.ts +5 -8
  155. package/lib/types/intent/host.d.ts.map +1 -1
  156. package/lib/types/intent/host.js +56 -11
  157. package/lib/types/intent/host.js.map +1 -1
  158. package/lib/types/intent/scope.d.ts +25 -0
  159. package/lib/types/intent/scope.d.ts.map +1 -0
  160. package/lib/types/intent/scope.js +116 -0
  161. package/lib/types/intent/scope.js.map +1 -0
  162. package/lib/types/intent/tools.d.ts +24 -20
  163. package/lib/types/intent/tools.d.ts.map +1 -1
  164. package/lib/types/intent/tools.js +65 -23
  165. package/lib/types/intent/tools.js.map +1 -1
  166. package/lib/types/intent/types.d.ts +11 -4
  167. package/lib/types/intent/types.d.ts.map +1 -1
  168. package/lib/types/knowledge-bases.d.ts +11 -5
  169. package/lib/types/knowledge-bases.d.ts.map +1 -1
  170. package/lib/types/knowledge-bases.js +52 -20
  171. package/lib/types/knowledge-bases.js.map +1 -1
  172. package/lib/types/knowledge-contract.d.ts +32 -0
  173. package/lib/types/knowledge-contract.d.ts.map +1 -0
  174. package/lib/types/knowledge-contract.js +116 -0
  175. package/lib/types/knowledge-contract.js.map +1 -0
  176. package/lib/types/knowledge.d.ts +31 -9
  177. package/lib/types/knowledge.d.ts.map +1 -1
  178. package/lib/types/knowledge.js +137 -60
  179. package/lib/types/knowledge.js.map +1 -1
  180. package/lib/types/layout.d.ts +10 -29
  181. package/lib/types/layout.d.ts.map +1 -1
  182. package/lib/types/layout.js +17 -36
  183. package/lib/types/layout.js.map +1 -1
  184. package/lib/types/materialize-snapshot.d.ts +49 -0
  185. package/lib/types/materialize-snapshot.d.ts.map +1 -0
  186. package/lib/types/materialize-snapshot.js +2 -0
  187. package/lib/types/materialize-snapshot.js.map +1 -0
  188. package/lib/types/migrate.d.ts +11 -0
  189. package/lib/types/migrate.d.ts.map +1 -1
  190. package/lib/types/migrate.js +83 -2
  191. package/lib/types/migrate.js.map +1 -1
  192. package/lib/types/model-text.d.ts +58 -1
  193. package/lib/types/model-text.d.ts.map +1 -1
  194. package/lib/types/model-text.js +85 -30
  195. package/lib/types/model-text.js.map +1 -1
  196. package/lib/types/oplog.d.ts.map +1 -1
  197. package/lib/types/oplog.js +7 -0
  198. package/lib/types/oplog.js.map +1 -1
  199. package/lib/types/organize-contract.d.ts +18 -0
  200. package/lib/types/organize-contract.d.ts.map +1 -0
  201. package/lib/types/organize-contract.js +82 -0
  202. package/lib/types/organize-contract.js.map +1 -0
  203. package/lib/types/pipeline/engine.d.ts +66 -0
  204. package/lib/types/pipeline/engine.d.ts.map +1 -0
  205. package/lib/types/pipeline/engine.js +352 -0
  206. package/lib/types/pipeline/engine.js.map +1 -0
  207. package/lib/types/pipeline/store.d.ts +73 -0
  208. package/lib/types/pipeline/store.d.ts.map +1 -0
  209. package/lib/types/pipeline/store.js +143 -0
  210. package/lib/types/pipeline/store.js.map +1 -0
  211. package/lib/types/pipeline/types.d.ts +102 -0
  212. package/lib/types/pipeline/types.d.ts.map +1 -0
  213. package/lib/types/pipeline/types.js +5 -0
  214. package/lib/types/pipeline/types.js.map +1 -0
  215. package/lib/types/present.d.ts +2 -0
  216. package/lib/types/present.d.ts.map +1 -1
  217. package/lib/types/present.js +9 -4
  218. package/lib/types/present.js.map +1 -1
  219. package/lib/types/preset-ids.d.ts +4 -0
  220. package/lib/types/preset-ids.d.ts.map +1 -0
  221. package/lib/types/preset-ids.js +6 -0
  222. package/lib/types/preset-ids.js.map +1 -0
  223. package/lib/types/query-analysis.d.ts +13 -1
  224. package/lib/types/query-analysis.d.ts.map +1 -1
  225. package/lib/types/query-analysis.js +62 -6
  226. package/lib/types/query-analysis.js.map +1 -1
  227. package/lib/types/recall-rank.d.ts +3 -3
  228. package/lib/types/recall-rank.d.ts.map +1 -1
  229. package/lib/types/recall-rank.js +4 -4
  230. package/lib/types/recall-rank.js.map +1 -1
  231. package/lib/types/retention.d.ts +39 -0
  232. package/lib/types/retention.d.ts.map +1 -0
  233. package/lib/types/retention.js +42 -0
  234. package/lib/types/retention.js.map +1 -0
  235. package/lib/types/retrieval/vector-index.d.ts +32 -0
  236. package/lib/types/retrieval/vector-index.d.ts.map +1 -0
  237. package/lib/types/retrieval/vector-index.js +15 -0
  238. package/lib/types/retrieval/vector-index.js.map +1 -0
  239. package/lib/types/retrieval/visibility.d.ts +6 -0
  240. package/lib/types/retrieval/visibility.d.ts.map +1 -0
  241. package/lib/types/retrieval/visibility.js +11 -0
  242. package/lib/types/retrieval/visibility.js.map +1 -0
  243. package/lib/types/runtime.d.ts +272 -27
  244. package/lib/types/runtime.d.ts.map +1 -1
  245. package/lib/types/runtime.js +2751 -537
  246. package/lib/types/runtime.js.map +1 -1
  247. package/lib/types/settings-schema.d.ts +17 -15
  248. package/lib/types/settings-schema.d.ts.map +1 -1
  249. package/lib/types/settings-schema.js +50 -47
  250. package/lib/types/settings-schema.js.map +1 -1
  251. package/lib/types/settings-volatile.d.ts +4 -4
  252. package/lib/types/settings-volatile.js +4 -4
  253. package/lib/types/source-evidence.d.ts +14 -0
  254. package/lib/types/source-evidence.d.ts.map +1 -0
  255. package/lib/types/source-evidence.js +36 -0
  256. package/lib/types/source-evidence.js.map +1 -0
  257. package/lib/types/store/axis-references.d.ts +5 -0
  258. package/lib/types/store/axis-references.d.ts.map +1 -0
  259. package/lib/types/store/axis-references.js +106 -0
  260. package/lib/types/store/axis-references.js.map +1 -0
  261. package/lib/types/store/derived.d.ts +12 -1
  262. package/lib/types/store/derived.d.ts.map +1 -1
  263. package/lib/types/store/derived.js +71 -12
  264. package/lib/types/store/derived.js.map +1 -1
  265. package/lib/types/store/knowledge-db.d.ts +31 -1
  266. package/lib/types/store/knowledge-db.d.ts.map +1 -1
  267. package/lib/types/store/knowledge-db.js +252 -18
  268. package/lib/types/store/knowledge-db.js.map +1 -1
  269. package/lib/types/store/migrate.d.ts.map +1 -1
  270. package/lib/types/store/migrate.js +17 -6
  271. package/lib/types/store/migrate.js.map +1 -1
  272. package/lib/types/trajectory-types.d.ts +172 -0
  273. package/lib/types/trajectory-types.d.ts.map +1 -0
  274. package/lib/types/trajectory-types.js +36 -0
  275. package/lib/types/trajectory-types.js.map +1 -0
  276. package/lib/types/types.d.ts +59 -27
  277. package/lib/types/types.d.ts.map +1 -1
  278. package/lib/types/types.js +6 -15
  279. package/lib/types/types.js.map +1 -1
  280. package/lib/types/wiki-finalize.d.ts +16 -0
  281. package/lib/types/wiki-finalize.d.ts.map +1 -1
  282. package/lib/types/wiki-finalize.js +26 -0
  283. package/lib/types/wiki-finalize.js.map +1 -1
  284. package/lib/types/wiki-materialize.d.ts +4 -0
  285. package/lib/types/wiki-materialize.d.ts.map +1 -1
  286. package/lib/types/wiki-materialize.js +21 -7
  287. package/lib/types/wiki-materialize.js.map +1 -1
  288. package/lib/types/wiki-trial-types.d.ts +87 -0
  289. package/lib/types/wiki-trial-types.d.ts.map +1 -1
  290. package/lib/types/wiki-trial-types.js +0 -16
  291. package/lib/types/wiki-trial-types.js.map +1 -1
  292. package/lib/types/wiki-trial.d.ts +40 -16
  293. package/lib/types/wiki-trial.d.ts.map +1 -1
  294. package/lib/types/wiki-trial.js +337 -224
  295. package/lib/types/wiki-trial.js.map +1 -1
  296. package/package.json +29 -20
  297. package/python/prepare-models.py +19 -0
  298. package/python/requirements.txt +8 -6
  299. package/scripts/doctor.mjs +13 -19
  300. package/scripts/environment.mjs +29 -0
  301. package/scripts/setup-embedding.sh +15 -5
  302. package/src/agent-behavior-rules.ts +37 -0
  303. package/src/axis-registry.ts +234 -27
  304. package/src/card-organize.ts +69 -75
  305. package/src/client/AgentBehaviorRulesCard.tsx +65 -0
  306. package/src/client/AttributionEventGuide.tsx +41 -39
  307. package/src/client/AxisRegistrySection.tsx +204 -164
  308. package/src/client/CompileDialogs.tsx +44 -29
  309. package/src/client/DeleteDocumentDialog.tsx +36 -5
  310. package/src/client/DirectoryPicker.tsx +0 -10
  311. package/src/client/EnvironmentSetup.tsx +243 -0
  312. package/src/client/ExpansionGraph.tsx +13 -7
  313. package/src/client/ExtractionTasksPage.tsx +578 -0
  314. package/src/client/GuideArchitectureCanvas.tsx +470 -0
  315. package/src/client/ImportFilesDialog.tsx +2 -13
  316. package/src/client/IntentLogic.tsx +2 -2
  317. package/src/client/IntentTab.tsx +118 -47
  318. package/src/client/KnowledgeBaseTab.tsx +277 -197
  319. package/src/client/KnowledgeLayerSection.tsx +24 -6
  320. package/src/client/KnowledgePanel.tsx +58 -93
  321. package/src/client/KnowledgeSettingsDrawer.tsx +90 -0
  322. package/src/client/ListPager.tsx +15 -5
  323. package/src/client/MaterializeTrajectoryView.tsx +124 -0
  324. package/src/client/NodeSettings.tsx +210 -89
  325. package/src/client/NormalizeTrajectoryView.tsx +136 -0
  326. package/src/client/PipelineNotice.tsx +26 -0
  327. package/src/client/PreviewSections.tsx +118 -51
  328. package/src/client/RecallPanel.tsx +89 -85
  329. package/src/client/TabGuide.tsx +159 -184
  330. package/src/client/TrialReportView.tsx +391 -214
  331. package/src/client/TypeDefinitionDrawer.tsx +150 -23
  332. package/src/client/WikiCardPreview.tsx +62 -16
  333. package/src/client/WikiFlowPanel.tsx +4 -4
  334. package/src/client/arch/NodeLogicPanel.tsx +3 -4
  335. package/src/client/arch/model.ts +6 -9
  336. package/src/client/architecture.tsx +23 -33
  337. package/src/client/attribution/AttributionGraph.tsx +10 -6
  338. package/src/client/attribution/AttributionTab.tsx +136 -84
  339. package/src/client/attribution/CaseView.tsx +3 -1
  340. package/src/client/attribution/EventView.tsx +108 -0
  341. package/src/client/attribution/RunView.tsx +2 -2
  342. package/src/client/attribution/StageChrome.tsx +34 -3
  343. package/src/client/attribution/ViewSwitch.tsx +20 -5
  344. package/src/client/attribution/graph-options.ts +47 -39
  345. package/src/client/attribution/model.ts +17 -10
  346. package/src/client/config-scope.ts +3 -3
  347. package/src/client/graph/palette.ts +165 -0
  348. package/src/client/index.ts +49 -42
  349. package/src/client/pages.css +459 -135
  350. package/src/client/pages.tsx +37 -9
  351. package/src/client/problem-domains.ts +1 -1
  352. package/src/client/session-remote.ts +9 -0
  353. package/src/client/styles.css +205 -62
  354. package/src/client/wiki-trial.ts +44 -3
  355. package/src/compiler/embedding-identity.ts +21 -0
  356. package/src/compiler/snapshot.ts +17 -0
  357. package/src/config-schema.ts +8 -3
  358. package/src/convert/host.ts +56 -21
  359. package/src/convert/ingest.ts +74 -10
  360. package/src/derive-contract.ts +14 -0
  361. package/src/diagnosis/cards.ts +13 -8
  362. package/src/diagnosis/run.ts +27 -17
  363. package/src/diagnosis/schema.ts +2 -2
  364. package/src/diagnosis/seed-source.ts +5 -4
  365. package/src/diagnosis/seed.ts +6 -8
  366. package/src/diagnosis/store.ts +138 -69
  367. package/src/diagnosis/types.ts +34 -15
  368. package/src/environment/dsh-python.ts +156 -0
  369. package/src/environment/install.ts +244 -0
  370. package/src/environment/manifest.ts +28 -0
  371. package/src/environment/model-catalog.ts +147 -0
  372. package/src/environment/process.ts +54 -0
  373. package/src/environment/selection.ts +29 -0
  374. package/src/environment/service.ts +348 -0
  375. package/src/environment/types.ts +45 -0
  376. package/src/events.ts +108 -0
  377. package/src/extract-contract.ts +42 -0
  378. package/src/extract-model.ts +10 -1
  379. package/src/extract-table-contract.ts +26 -0
  380. package/src/extract-table.ts +132 -0
  381. package/src/extraction-runs.ts +70 -11
  382. package/src/fs-atomic.ts +19 -2
  383. package/src/images.ts +203 -0
  384. package/src/index.ts +553 -205
  385. package/src/intent/README.md +8 -6
  386. package/src/intent/engine.ts +44 -6
  387. package/src/intent/host.ts +59 -18
  388. package/src/intent/scope.ts +125 -0
  389. package/src/intent/tools.ts +70 -28
  390. package/src/intent/types.ts +11 -4
  391. package/src/knowledge-bases.ts +56 -20
  392. package/src/knowledge-contract.ts +114 -0
  393. package/src/knowledge.ts +138 -69
  394. package/src/layout.ts +17 -37
  395. package/src/materialize-snapshot.ts +46 -0
  396. package/src/migrate.ts +75 -2
  397. package/src/model-text.ts +109 -4
  398. package/src/oplog.ts +7 -0
  399. package/src/organize-contract.ts +83 -0
  400. package/src/pipeline/engine.ts +323 -0
  401. package/src/pipeline/store.ts +147 -0
  402. package/src/pipeline/types.ts +93 -0
  403. package/src/present.ts +10 -4
  404. package/src/preset-ids.ts +6 -0
  405. package/src/python/embedding_worker.py +66 -2
  406. package/src/query-analysis.ts +68 -8
  407. package/src/recall-rank.ts +5 -5
  408. package/src/retention.ts +76 -0
  409. package/src/retrieval/vector-index.ts +45 -0
  410. package/src/retrieval/visibility.ts +14 -0
  411. package/src/runtime.ts +2708 -567
  412. package/src/settings-schema.ts +11 -8
  413. package/src/settings-volatile.ts +4 -4
  414. package/src/source-evidence.ts +37 -0
  415. package/src/store/axis-references.ts +96 -0
  416. package/src/store/derived.ts +70 -12
  417. package/src/store/knowledge-db.ts +248 -17
  418. package/src/store/migrate.ts +16 -6
  419. package/src/trajectory-types.ts +142 -0
  420. package/src/types.ts +61 -35
  421. package/src/wiki-finalize.ts +28 -0
  422. package/src/wiki-materialize.ts +25 -6
  423. package/src/wiki-trial-types.ts +83 -1
  424. package/src/wiki-trial.ts +357 -185
  425. package/lib/types/intent/preset-tools.d.ts +0 -37
  426. package/lib/types/intent/preset-tools.d.ts.map +0 -1
  427. package/lib/types/intent/preset-tools.js +0 -45
  428. package/lib/types/intent/preset-tools.js.map +0 -1
  429. package/preset/tita-data-agent/agent.cordis.yml +0 -394
  430. package/preset/tita-data-agent/preset.yml +0 -3
  431. package/scripts/install-agent-preset.mjs +0 -92
  432. package/scripts/sync-agent-preset.mjs +0 -188
  433. package/src/client/AgentPresetCard.tsx +0 -247
  434. package/src/client/agent-preset.ts +0 -121
  435. package/src/client/convert/ConvertPanel.tsx +0 -583
  436. package/src/client/convert/styles.css +0 -138
  437. package/src/client/convert/styles.ts +0 -49
  438. package/src/intent/preset-tools.ts +0 -48
@@ -0,0 +1,470 @@
1
+ /**
2
+ * 架构说明页的画布:**一条链路 = 画布上的一条工序带**。
3
+ *
4
+ * ## 它和 Agent 概览为什么不是同一个渲染层
5
+ *
6
+ * 两者画的是同一份数据(`architecture.tsx` 的 `NODE_META` + `arch/model.ts` 的坐标与连边),
7
+ * 但回答的问题不同:
8
+ *
9
+ * - **概览**是「现在跑到哪一步」—— 十七张卡要同时在场,卡片挂实时计数,
10
+ * 所以坐标固定、内容由数据喂(G6 HTML 节点 + `updateNodeData`)。
11
+ * - **这一页**是「这条链路有哪些环节、每一步做什么」—— 一次只读一条链路,
12
+ * 卡片要排三层信息(标题 / 步骤表 / 状态)。这是**排版**问题,不是画布问题。
13
+ *
14
+ * G6 的 canvas 文本只有一种字号与字重,装不下三层;换成 HTML 节点之后它又算不出内容
15
+ * 包围盒,`fitView` / `zoomTo` 实测失效(见 `useFitScale.ts` 的头注释)。所以这里
16
+ * **SVG 画带与连线、卡片是普通 DOM、缩放由整块板的 `transform` 承担**。
17
+ *
18
+ * ## 三条构图纪律(第一版在这里翻过车)
19
+ *
20
+ * 1. **三条链路始终在场。** 这是完整架构图,切换 Tab 只改变高亮,不改变节点位置。
21
+ * 2. **节点点击只选中一个节点。** 只有左上角显式选择链路时,才整体高亮这条链路。
22
+ * 3. **侧边详情不挤压画布。** Inspector 浮在画布右侧,节点仍使用完整设计宽度。
23
+ *
24
+ * 坐标仍然只有一个来源:`arch/model.ts`。位置、顺序、走线都不在这里重算。
25
+ */
26
+
27
+ import { useEffect, useId, useLayoutEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react'
28
+ import { Button, Tabs, TabsList, TabsTrigger, cn } from '@tita-agent/ui/components'
29
+ import { X } from '@tita-agent/ui/icons'
30
+ import {
31
+ NODE_LANES, NODE_META, NODE_ORDER, NODE_STATUS_LABEL,
32
+ type NodeId, type NodeStep,
33
+ } from './architecture.tsx'
34
+ import {
35
+ ARCH_EDGES, BAND_H, BOTTOM, CANVAS_WIDTH, EDGE_STYLE,
36
+ GUTTER, LANE_HEAD_H, LANE_HEAD_W, LANE_PALETTE,
37
+ boxOf, columnGapX, laneCenter, laneGapY, laneTop,
38
+ type ArchEdge,
39
+ } from './arch/model.ts'
40
+
41
+ /** 说明页能选中的对象:架构图上的真实节点,外加四个产品概念入口。 */
42
+ export type GuideNodeId = NodeId | 'knowledge' | 'attribution' | 'memory' | 'eval'
43
+
44
+ /**
45
+ * 链路筛选。`all` 不是「第五条链路」,是**不筛选** —— 它是这张图的初始读法,
46
+ * 也是唯一能看到三条链路怎么咬合的那一档。
47
+ */
48
+ export type GuideChainId = 'all' | 'compile' | 'recall' | 'memory'
49
+
50
+ export interface GuideChainTab {
51
+ id: GuideChainId
52
+ label: string
53
+ /** 一句链路走向,写在 Tab 的 `title` 上。 */
54
+ note: string
55
+ /** 切到这条链路时右侧默认展开哪个环节。`all` 不动当前选择。 */
56
+ entry: GuideNodeId | null
57
+ /** 这条链路点亮哪些节点。 */
58
+ nodes: readonly NodeId[]
59
+ }
60
+
61
+ /**
62
+ * 四档筛选。**每一档点亮的集合是设计结论,不是包含关系**:
63
+ *
64
+ * - 编译只点亮写入侧(SourceRaw → 编译 → 构建)。把「召回」也算进来会让人以为
65
+ * 编译链路要等召回跑完,而它们是同一条 B 带的两端。
66
+ * - 记忆链路把 `source-raw` 一起点亮:确认后的记忆**汇成一份来源**再回到编译入口,
67
+ * 这是闭环的落点;不点亮它,链路的最后一段就没有去处。
68
+ */
69
+ export const GUIDE_CHAIN_TABS: readonly GuideChainTab[] = [
70
+ { id: 'all', label: '全部链路', note: '三条链路:看清跨链路怎么咬合', entry: null, nodes: NODE_ORDER },
71
+ { id: 'compile', label: '知识编译', note: 'SourceRaw → 编译 → 构建', entry: 'compile', nodes: ['source-raw', 'compile', 'build'] },
72
+ { id: 'recall', label: '知识召回', note: '对话 → 意图 → 召回 → 重排 → Runtime → 回答', entry: 'recall', nodes: ['conversation', 'intent', 'recall', 'context', 'runtime', 'answer'] },
73
+ { id: 'memory', label: '记忆构建', note: '交互 → 记忆 → 质量门 → 每日更新 → SourceRaw', entry: 'interaction', nodes: ['interaction', 'episodic-memory', 'procedural-memory', 'memory-quality', 'daily-update', 'source-raw'] },
74
+ ]
75
+
76
+ const TAB_BY_ID = new Map(GUIDE_CHAIN_TABS.map(tab => [tab.id, tab]))
77
+
78
+ /** 这条链路点亮哪些节点(`all` 是全部)。 */
79
+ export function activeNodesOf(chain: GuideChainId): readonly NodeId[] {
80
+ return TAB_BY_ID.get(chain)?.nodes ?? NODE_ORDER
81
+ }
82
+
83
+ /**
84
+ * 这个环节属于哪条链路,供深链初始化和链路入口定位使用;点击节点时不自动切 Tab。
85
+ *
86
+ * 四个产品概念入口没有自己的链路,映射到它**内容上属于**的那条:
87
+ * 知识库 → 编译、记忆 → 记忆构建。智能归因与评测是产品概念入口,
88
+ * 不属于某一条运行链路,所以不切(保持当前筛选)。
89
+ */
90
+ export function chainOfNode(id: GuideNodeId): GuideChainId | null {
91
+ for (const tab of GUIDE_CHAIN_TABS) {
92
+ if (tab.id !== 'all' && (tab.nodes as readonly string[]).includes(id)) return tab.id
93
+ }
94
+ if (id === 'knowledge') return 'compile'
95
+ if (id === 'memory') return 'memory'
96
+ return null
97
+ }
98
+
99
+ export function isGuideChainId(value: string | undefined): value is GuideChainId {
100
+ return value !== undefined && TAB_BY_ID.has(value as GuideChainId)
101
+ }
102
+
103
+ // ------------------------------------------------------------------ 连边
104
+
105
+ /**
106
+ * 一条边的折线。**从 `arch/model.ts` 的几何推导,坐标不在这里另立一份**。
107
+ *
108
+ * 四条跨链路边里只有 `x3` 需要手工绕行(见 `arch/model.ts` 的 `CROSS_ROUTES` 那段:
109
+ * 它的最短路径会横穿两张卡片)。其余三条实测走在空处,这里给它们的正交折线
110
+ * 与那个「最短路径」的结论一致。
111
+ */
112
+ function edgePath(edge: ArchEdge): string {
113
+ const source = boxOf(edge.source)
114
+ const target = boxOf(edge.target)
115
+ const rightward = target.x >= source.x
116
+ const start: [number, number] = [source.x + (rightward ? source.width / 2 : -source.width / 2), source.y]
117
+ const end: [number, number] = [target.x + (rightward ? -target.width / 2 : target.width / 2), target.y]
118
+
119
+ if (edge.id === 'x1') return `M ${start[0]} ${start[1]} H ${CANVAS_WIDTH - 25} V ${end[1]} H ${end[0]}`
120
+ if (edge.id === 'x2') return `M ${start[0]} ${start[1]} H ${GUTTER - 25} V ${end[1]} H ${end[0]}`
121
+ if (edge.id === 'x3') {
122
+ const gap = columnGapX(1)
123
+ const channel = laneGapY(0)
124
+ return `M ${start[0]} ${start[1]} H ${gap} V ${channel} H ${target.x} V ${end[1]} H ${end[0]}`
125
+ }
126
+ if (edge.id === 'x4') {
127
+ const gap = columnGapX(2)
128
+ const channel = laneGapY(0)
129
+ return `M ${start[0]} ${start[1]} H ${gap} V ${channel} H ${target.x} V ${end[1]} H ${end[0]}`
130
+ }
131
+ if (Math.abs(source.y - target.y) < 1) return `M ${start[0]} ${start[1]} H ${end[0]}`
132
+ const trunk = (start[0] + end[0]) / 2
133
+ return `M ${start[0]} ${start[1]} H ${trunk} V ${end[1]} H ${end[0]}`
134
+ }
135
+
136
+ /**
137
+ * 跨链路边标签的落点。**不能交给「弧长中点」**:那四条线的中点常常正好压在一张卡片上,
138
+ * 而标签带白底 —— 压上去就是把一张卡糊掉一块。所以四条各自给坐标(拱在通道里)。
139
+ */
140
+ const EDGE_LABEL_POSITIONS: Record<string, { x: number; y: number }> = {
141
+ x1: { x: CANVAS_WIDTH - 96, y: laneCenter(2) },
142
+ x2: { x: GUTTER - 20, y: laneGapY(1) + 4 },
143
+ x3: { x: columnGapX(1) + 44, y: laneGapY(0) - 9 },
144
+ x4: { x: columnGapX(2) + 44, y: laneGapY(0) + 17 },
145
+ }
146
+
147
+ const EDGE_MARKER: Record<string, 'flow' | 'cross'> = { flow: 'flow', branch: 'flow', inject: 'cross', collect: 'cross', feedback: 'cross' }
148
+
149
+ // ------------------------------------------------------------------ 视口
150
+
151
+ /**
152
+ * 量视口的**宽与高**。
153
+ *
154
+ * 两个都要:宽决定「适应」能放多大(整图设计宽 1172),高决定它能缩到多小。
155
+ * 视口高度是 CSS 给的固定值,不随缩放变化 —— 见下面的「固定边框」。
156
+ */
157
+ function useBoxSize(ref: { current: HTMLElement | null }): { width: number; height: number } {
158
+ const [size, setSize] = useState({ width: 0, height: 0 })
159
+ useEffect(() => {
160
+ const el = ref.current
161
+ if (!el) return undefined
162
+ const update = (): void => setSize(previous => {
163
+ const next = { width: el.offsetWidth, height: el.offsetHeight }
164
+ return previous.width === next.width && previous.height === next.height ? previous : next
165
+ })
166
+ update()
167
+ if (typeof ResizeObserver === 'undefined') return undefined
168
+ const observer = new ResizeObserver(update)
169
+ observer.observe(el)
170
+ return () => observer.disconnect()
171
+ }, [ref])
172
+ return size
173
+ }
174
+
175
+ /** 说明页画布高度按三条运行链路计算。 */
176
+ const GUIDE_CANVAS_HEIGHT = laneTop(NODE_LANES.length - 1) + BAND_H + BOTTOM
177
+
178
+ export interface GuideArchitectureCanvasProps {
179
+ chain: GuideChainId
180
+ onChainChange: (chain: GuideChainId) => void
181
+ selected: GuideNodeId | null
182
+ onSelect: (id: GuideNodeId) => void
183
+ inspector?: ReactNode
184
+ onCloseInspector?: () => void
185
+ }
186
+
187
+ const ZOOM_MIN = 0.35
188
+ const ZOOM_MAX = 2.4
189
+ /**
190
+ * Inspector 在右侧占掉多少像素(宽度上限 380 + 右边距 12)。
191
+ * **写成常量而不是量出来**:量出来要等一帧,而「图往左让还是居中」是一帧都不许抖的排版决定。
192
+ */
193
+ const INSPECTOR_WIDTH = 392
194
+ /**
195
+ * 「适应」档的比例上限。取 0.96 而不是 1,是为了让 1172px 宽的整图和 380px 的 Inspector
196
+ * 在常见的 1440–1920 屏上**同时站得下** —— 顶到 1 就会让 Inspector 压住最右一列。
197
+ */
198
+ const MAX_FIT_SCALE = 0.96
199
+ /**
200
+ * 窄于这个宽度时,Inspector 不再是「右边的一栏」,而是**落到画布下面**(见 pages.css 的同名
201
+ * 容器查询)。两个数字必须相同:JS 用它决定要不要预留右栏,CSS 用它决定 Inspector 摆在哪里 ——
202
+ * 差一点就会出现「预留了但没东西占位」或者「没预留却被盖住」。
203
+ */
204
+ const BESIDE_MIN_WIDTH = 1100
205
+ /** 图与边框之间留的呼吸位。 */
206
+ const FIT_MARGIN = 24
207
+
208
+ export function GuideArchitectureCanvas({ chain, onChainChange, selected, onSelect, inspector, onCloseInspector }: GuideArchitectureCanvasProps): ReactNode {
209
+ const markerId = useId().replace(/[^a-zA-Z0-9_-]/g, '')
210
+ const viewport = useRef<HTMLDivElement>(null)
211
+ const box = useBoxSize(viewport)
212
+ /** `null` = 「适应」(整图缩进边框);数字 = 用户自己捏出来/按出来的比例。Tab 切换不动它。 */
213
+ const [manualScale, setManualScale] = useState<number | null>(null)
214
+ const [isPanning, setIsPanning] = useState(false)
215
+ const panRef = useRef<{ pointerId: number; clientX: number; clientY: number; scrollLeft: number; scrollTop: number } | null>(null)
216
+ const zoomAnchorRef = useRef<{ screenX: number; screenY: number; worldX: number; worldY: number } | null>(null)
217
+
218
+ const active = new Set<string>(activeNodesOf(chain))
219
+ /** 有被点亮环节的那几条带。**带头也要跟着调淡**,否则空带的标题比它的内容还响。 */
220
+ const activeLanes = new Set(NODE_LANES.filter(lane => activeNodesOf(chain).some(id => NODE_META[id].lane === lane.id)).map(lane => lane.id))
221
+ /** `all` 不筛选;切换链路时,非当前链路的卡片降为次级。 */
222
+ const filtered = chain !== 'all'
223
+
224
+ const available = box.width > 0 ? box.width - 2 : CANVAS_WIDTH
225
+ const availableHeight = box.height > 0 ? box.height - 2 : GUIDE_CANVAS_HEIGHT
226
+ /**
227
+ * 「适应」= 整图缩进边框,**并且给 Inspector 留出它那一栏**。
228
+ *
229
+ * 留这一栏是「不遮挡」的唯一可靠做法:整图 1172px 宽,右列 380px,
230
+ * 两者在窄屏上本来就放不下;不留就一定会压住最右一列(召回 / 重排、用户交互),
231
+ * 而它们正是要对照着读的环节。
232
+ *
233
+ * 实测这不会造成开合 Inspector 时图「跳一下」:常见窗口高度下这一档本来就被高度卡住
234
+ * (≈0.88),留不留这一栏算出来是同一个数。
235
+ */
236
+ const besideInspector = inspector !== undefined && box.width >= BESIDE_MIN_WIDTH
237
+ const reserve = besideInspector ? INSPECTOR_WIDTH + 28 : FIT_MARGIN
238
+ const fitScale = Math.max(ZOOM_MIN, Math.min(
239
+ MAX_FIT_SCALE,
240
+ (available - reserve) / CANVAS_WIDTH,
241
+ (availableHeight - FIT_MARGIN) / GUIDE_CANVAS_HEIGHT,
242
+ ))
243
+ const scale = manualScale ?? fitScale
244
+
245
+ const boardWidth = CANVAS_WIDTH * scale
246
+ const boardHeight = GUIDE_CANVAS_HEIGHT * scale
247
+ /** Inspector 在右边时图靠左站(它那一栏已经预留出来了);否则居中,放不下就贴左边。 */
248
+ const offsetX = besideInspector ? 14 : Math.max(0, (available - boardWidth) / 2)
249
+ const offsetY = Math.max(0, (availableHeight - boardHeight) / 2)
250
+
251
+ /** 捏合要按指针锚定,锚点计算读的是「这一帧」的比例与位移 —— 存一份给原生监听用。 */
252
+ const viewRef = useRef({ scale, offsetX, offsetY })
253
+ viewRef.current = { scale, offsetX, offsetY }
254
+ const pannable = boardWidth > available + 1 || boardHeight > availableHeight + 1
255
+
256
+ /**
257
+ * 触控板捏合缩放。**必须是原生的非被动监听**:React 的 `onWheel` 挂在根容器上、
258
+ * 而且是 passive 的 —— 在那里 `preventDefault()` 不生效,浏览器会顺手把整页也缩放掉,
259
+ * 表现就是「一捏,页面和画布一起变大」。
260
+ *
261
+ * 触控板捏合在浏览器里的约定是「带 `ctrlKey` 的 wheel 事件」,所以这里只接管那一种;
262
+ * **普通两指滚动一概不碰**,交给容器自己滚(滚到头会继续滚页面)。
263
+ */
264
+ useEffect(() => {
265
+ const el = viewport.current
266
+ if (!el) return undefined
267
+ const onWheel = (event: WheelEvent): void => {
268
+ if (!event.ctrlKey && !event.metaKey) return
269
+ event.preventDefault()
270
+ const current = viewRef.current
271
+ const rect = el.getBoundingClientRect()
272
+ const screenX = event.clientX - rect.left
273
+ const screenY = event.clientY - rect.top
274
+ const worldX = (screenX + el.scrollLeft - current.offsetX) / current.scale
275
+ const worldY = (screenY + el.scrollTop - current.offsetY) / current.scale
276
+ // 单次最多放 1.38 倍:捏合会连发事件,一次跳太多会晕。
277
+ const delta = Math.max(-40, Math.min(40, event.deltaY))
278
+ const next = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, current.scale * Math.exp(-delta * 0.008)))
279
+ if (Math.abs(next - current.scale) < 0.0005) return
280
+ zoomAnchorRef.current = { screenX, screenY, worldX, worldY }
281
+ setManualScale(next)
282
+ }
283
+ el.addEventListener('wheel', onWheel, { passive: false })
284
+ return () => el.removeEventListener('wheel', onWheel)
285
+ }, [])
286
+
287
+ /** 缩放以后,把锚点下的画布坐标移回原来的屏幕位置 —— 不然放大时图会从指针底下跑掉。 */
288
+ useLayoutEffect(() => {
289
+ const el = viewport.current
290
+ const anchor = zoomAnchorRef.current
291
+ if (!el || !anchor) return
292
+ const nextOffsetX = besideInspector ? 14 : Math.max(0, (available - CANVAS_WIDTH * scale) / 2)
293
+ const nextOffsetY = Math.max(0, (availableHeight - GUIDE_CANVAS_HEIGHT * scale) / 2)
294
+ const nextScrollLeft = nextOffsetX + anchor.worldX * scale - anchor.screenX
295
+ const nextScrollTop = nextOffsetY + anchor.worldY * scale - anchor.screenY
296
+ const maxScrollLeft = Math.max(0, el.scrollWidth - el.clientWidth)
297
+ const maxScrollTop = Math.max(0, el.scrollHeight - el.clientHeight)
298
+ el.scrollLeft = Math.max(0, Math.min(maxScrollLeft, nextScrollLeft))
299
+ el.scrollTop = Math.max(0, Math.min(maxScrollTop, nextScrollTop))
300
+ zoomAnchorRef.current = null
301
+ }, [available, availableHeight, besideInspector, scale])
302
+
303
+ const beginPan = (event: ReactPointerEvent<HTMLDivElement>): void => {
304
+ // **左键在空白处拖就平移**,中键同理;落点在卡片上时不抢 —— 那一下是「选中这个环节」。
305
+ // 不占用空格键:那是整页翻页的键,画布没有资格把它拿走。
306
+ const onCard = event.target instanceof Element && event.target.closest('.tabGuideCard') !== null
307
+ const allowed = event.button === 1 || (event.button === 0 && !onCard)
308
+ if (!allowed) return
309
+ const el = event.currentTarget
310
+ event.preventDefault()
311
+ el.setPointerCapture(event.pointerId)
312
+ panRef.current = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY, scrollLeft: el.scrollLeft, scrollTop: el.scrollTop }
313
+ setIsPanning(true)
314
+ }
315
+
316
+ const movePan = (event: ReactPointerEvent<HTMLDivElement>): void => {
317
+ const el = event.currentTarget
318
+ const pan = panRef.current
319
+ if (!pan || pan.pointerId !== event.pointerId) return
320
+ event.preventDefault()
321
+ el.scrollLeft = pan.scrollLeft - (event.clientX - pan.clientX)
322
+ el.scrollTop = pan.scrollTop - (event.clientY - pan.clientY)
323
+ }
324
+
325
+ const endPan = (event: ReactPointerEvent<HTMLDivElement>): void => {
326
+ const pan = panRef.current
327
+ if (!pan || pan.pointerId !== event.pointerId) return
328
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId)
329
+ panRef.current = null
330
+ setIsPanning(false)
331
+ }
332
+
333
+ return <section className="tabGuideCanvas" aria-label="TitaAgent 完整架构图">
334
+ {/* 画布上只有一个浮层:左上角的链路 Tab。**右上角不再放任何控件** ——
335
+ 缩放是一条触控板手势,全屏交给浏览器自己的键;两个按钮只是把画布切掉一角。 */}
336
+ <div className="tabGuideCanvasOverlay">
337
+ <Tabs className="tabGuideChainTabs" value={chain} onValueChange={value => {
338
+ if (isGuideChainId(value)) onChainChange(value)
339
+ }}>
340
+ <TabsList aria-label="按链路筛选架构图">
341
+ {GUIDE_CHAIN_TABS.map(tab => <TabsTrigger key={tab.id} value={tab.id} title={tab.note}>{tab.label}</TabsTrigger>)}
342
+ </TabsList>
343
+ </Tabs>
344
+ </div>
345
+
346
+ {/* **固定边框**:高度由 CSS 给,不跟缩放走 —— 缩放只动框里的内容。
347
+ 滚轮捏合由原生监听接管(见上),所以这里没有 onWheel。 */}
348
+ <div className={cn('tabGuideCanvasViewport', isPanning && 'tabGuideCanvasViewportPanning')}
349
+ data-pannable={pannable ? 'true' : undefined} ref={viewport}
350
+ onPointerDown={beginPan} onPointerMove={movePan} onPointerUp={endPan} onPointerCancel={endPan}>
351
+ <div className="tabGuideCanvasFrame" style={{ width: boardWidth, height: boardHeight, left: offsetX, top: offsetY }}>
352
+ <div className="tabGuideCanvasBoard" style={{ width: CANVAS_WIDTH, height: GUIDE_CANVAS_HEIGHT, transform: `scale(${scale})` }}>
353
+ <svg className="tabGuideBoardEdges" width={CANVAS_WIDTH} height={GUIDE_CANVAS_HEIGHT}
354
+ viewBox={`0 0 ${CANVAS_WIDTH} ${GUIDE_CANVAS_HEIGHT}`} aria-hidden="true">
355
+ <defs>
356
+ <marker id={`${markerId}-flow`} markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
357
+ <path d="M0 0 L8 4 L0 8 Z" fill={EDGE_STYLE.flow.stroke} />
358
+ </marker>
359
+ <marker id={`${markerId}-cross`} markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
360
+ <path d="M0 0 L8 4 L0 8 Z" fill={EDGE_STYLE.inject.stroke} />
361
+ </marker>
362
+ </defs>
363
+
364
+ {NODE_LANES.map((lane, index) => {
365
+ const on = !filtered || activeLanes.has(lane.id)
366
+ return <g key={lane.id}>
367
+ <rect className="tabGuideBoardBand" x="14" y={laneTop(index)} width={CANVAS_WIDTH - 28} height={BAND_H} rx="10" />
368
+ <g className="tabGuideBoardLaneHead" style={{ opacity: on ? 1 : 0.32 }}>
369
+ <rect className={cn('tabGuideBoardLaneBadge', `tabGuideBoardLaneBadge-${lane.id}`)}
370
+ x={GUTTER} y={laneTop(index) + 7} width={LANE_HEAD_W} height={LANE_HEAD_H - 12} rx="5" />
371
+ <text className="tabGuideBoardLaneLabel" x={GUTTER + 10} y={laneTop(index) + 20}>{`${lane.index} · ${lane.title}`}</text>
372
+ {/* 走向与逐带计数跟在带名后面,**不放到画布右边缘**:窄链路裁到三列时,
373
+ 右边缘在视野之外,那里的字一行都看不见。
374
+ 计数用 `tspan` 顺排,不靠估算字宽 —— 中英混排的字宽估不准,
375
+ 估错的后果是两段字压在一起(第一版就是这样)。 */}
376
+ <text className="tabGuideBoardLaneNote" x={GUTTER + LANE_HEAD_W + 14} y={laneTop(index) + 20}>{lane.note}</text>
377
+ </g>
378
+ </g>
379
+ })}
380
+
381
+ {ARCH_EDGES.map(edge => {
382
+ const style = EDGE_STYLE[edge.kind]
383
+ const on = !filtered || (active.has(edge.source) && active.has(edge.target))
384
+ return <path key={edge.id} className="tabGuideBoardEdge" d={edgePath(edge)}
385
+ style={{ stroke: style.stroke, strokeWidth: style.lineWidth, strokeDasharray: style.lineDash?.join(' '), opacity: on ? 0.9 : 0.1 }}
386
+ markerEnd={`url(#${markerId}-${EDGE_MARKER[edge.kind]})`} />
387
+ })}
388
+ {ARCH_EDGES.map(edge => {
389
+ const at = EDGE_LABEL_POSITIONS[edge.id]
390
+ if (!edge.label || !at) return null
391
+ const on = !filtered || (active.has(edge.source) && active.has(edge.target))
392
+ return <text key={`${edge.id}-label`} className="tabGuideBoardEdgeLabel" x={at.x} y={at.y} style={{ opacity: on ? 1 : 0.14 }}>{edge.label}</text>
393
+ })}
394
+ </svg>
395
+
396
+ {NODE_ORDER.map(id => <NodeCard key={id} id={id}
397
+ selected={selected === id} active={!filtered || active.has(id)} showSteps={filtered && active.has(id)}
398
+ onSelect={onSelect} />)}
399
+
400
+ </div>
401
+ </div>
402
+ </div>
403
+ {inspector && <aside className="tabGuideInspector" aria-label="节点详细信息">
404
+ <div className="tabGuideInspectorHeader">
405
+ <div className="tabGuideInspectorHeaderCopy">
406
+ <span>当前选中</span>
407
+ <strong>节点详细信息</strong>
408
+ </div>
409
+ {onCloseInspector && <Button variant="ghost" size="icon" aria-label="关闭节点详细信息" title="关闭"
410
+ onClick={onCloseInspector}><X size={14} aria-hidden="true" /></Button>}
411
+ </div>
412
+ <div className="tabGuideInspectorBody">{inspector}</div>
413
+ </aside>}
414
+ </section>
415
+ }
416
+
417
+ /** 步骤的三档状态:一枚小方块,颜色与右侧详情里的图标同源。 */
418
+ const STEP_TONE: Record<string, string> = { done: 'done', partial: 'partial', todo: 'todo' }
419
+
420
+ /**
421
+ * 一张环节卡片:**标题行 + 编号步骤表**。
422
+ *
423
+ * 步骤是这张卡的全部理由 —— 用户切到一条链路,要的就是「它分几步做」。
424
+ * 所以步骤**编号**而不是打点:编号说明顺序,而顺序正是链路的意思。
425
+ *
426
+ * 行数由**卡片自己的高度**决定(坐标是 `arch/model.ts` 给的,有 96 / 80 / 52 三档),
427
+ * 而不是写死一个数字 —— 换掉任一条高度常量,这里的正文会跟着变。
428
+ */
429
+ function NodeCard({ id, selected, active, showSteps, onSelect }: {
430
+ id: NodeId
431
+ selected: boolean
432
+ active: boolean
433
+ showSteps: boolean
434
+ onSelect: (id: GuideNodeId) => void
435
+ }): ReactNode {
436
+ const meta = NODE_META[id]
437
+ const box = boxOf(id)
438
+ const lane = LANE_PALETTE[meta.lane]
439
+ const lineHeight = 13.5
440
+ /**
441
+ * 能排下几行步骤。**收尾那一行要占一行**:装不下时先让出「还有 N 步」的位置,
442
+ * 而不是先把步骤排满、再让收尾那行溢出卡片底边(第一版只差 1px 就压到边上)。
443
+ */
444
+ const capacity = Math.max(1, Math.floor((box.height - 19 - 17 - 5) / lineHeight))
445
+ const truncated = showSteps && meta.steps.length > capacity
446
+ const shown: NodeStep[] = showSteps ? meta.steps.slice(0, truncated ? capacity - 1 : capacity) : []
447
+ const rest = showSteps ? meta.steps.length - shown.length : 0
448
+
449
+ return <button
450
+ type="button"
451
+ className={cn('tabGuideCard', selected && 'tabGuideCardSelected', !active && 'tabGuideCardDim')}
452
+ style={{ left: box.x - box.width / 2, top: box.y - box.height / 2, width: box.width, height: box.height }}
453
+ aria-pressed={selected}
454
+ title={`${meta.title}(${NODE_STATUS_LABEL[meta.status]})—— ${meta.statusNote}`}
455
+ onClick={() => onSelect(id)}
456
+ >
457
+ <span className="tabGuideCardHead">
458
+ <i className="tabGuideCardDot" style={{ background: lane.accent }} aria-hidden="true" />
459
+ <strong className="tabGuideCardTitle">{meta.shortTitle ?? meta.title}</strong>
460
+ </span>
461
+ {showSteps
462
+ ? <span className="tabGuideCardSteps">
463
+ {shown.map((step, index) => <span key={step.label} className="tabGuideCardStep" data-state={STEP_TONE[step.state ?? 'done']}>
464
+ <i aria-hidden="true">{index + 1}</i>{step.label}
465
+ </span>)}
466
+ {rest > 0 && <span className="tabGuideCardStep tabGuideCardStepRest">还有 {rest} 步在右侧</span>}
467
+ </span>
468
+ : <span className="tabGuideCardSub" style={{ WebkitLineClamp: Math.max(1, Math.floor((box.height - 19 - 17 - 5) / 15)) }}>{meta.subtitle}</span>}
469
+ </button>
470
+ }
@@ -31,7 +31,7 @@ import { AlertCircle, Check, FileText, RefreshCw, Trash2, Upload, X } from '@tit
31
31
  import { Button, cn } from '@tita-agent/ui/components'
32
32
  import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@tita-agent/ui/overlays'
33
33
  import { styles } from './styles.ts'
34
- import { COMPILE_STEP_TITLE, type CompileProgressView } from './CompileDialogs.tsx'
34
+ import { COMPILE_STEP_TITLE, compileRatio, type CompileProgressView } from './CompileDialogs.tsx'
35
35
  import type { ImportSummaryView } from './KnowledgeBaseTab.tsx'
36
36
 
37
37
  /** 一个文件在这一趟里走到哪了。**两段**(转 → 入库),编译那一段是整批共用的。 */
@@ -168,7 +168,7 @@ export function ImportFilesDialog({
168
168
 
169
169
  {compileProgress !== null && <>
170
170
  <div className={cn(styles.compileBar, styles.importBar)}>
171
- <span style={{ inlineSize: `${ratioOf(compileProgress)}%` }} />
171
+ <span style={{ inlineSize: `${Math.round(compileRatio(compileProgress) * 100)}%` }} />
172
172
  </div>
173
173
  {/* 五段与编译弹窗、SourceRaw 抽取轨迹共用同一套名称和状态。
174
174
  这里回答的是「整批到哪了」,但不能再画成另一套不对应的步骤。 */}
@@ -318,14 +318,3 @@ function CompileStage({ title, note, children }: { title: string; note: string;
318
318
  <p className={styles.importStageBody}>{children}</p>
319
319
  </div>
320
320
  }
321
-
322
- /** 与编译对话框同一条算法:按阶段均分,正在跑的那一段再按文档数细分。 */
323
- function ratioOf(progress: CompileProgressView): number {
324
- if (progress.finishedAt !== undefined) return 100
325
- const total = progress.steps.length || 1
326
- const done = progress.steps.filter(step => step.state === 'done').length
327
- const running = progress.steps.find(step => step.state === 'running')
328
- if (running === undefined) return Math.round((done / total) * 100)
329
- const inner = running.id === 'knowledge' && progress.sourcesTotal > 0 ? progress.sourcesDone / progress.sourcesTotal : 0.5
330
- return Math.min(99, Math.round(((done + inner) / total) * 100))
331
- }
@@ -35,7 +35,7 @@ const RECORD_FIELDS: FieldDoc[] = [
35
35
  { name: 'refs', required: false, meaning: '引用了哪些对象(表、文档、指标),形如 { id, kind, label }。', where: '模型抽取' },
36
36
  { name: 'relation', required: true, meaning: '这轮与已有任务的关系:new_task(开新任务)/ subtask_of(续已有任务)/ unknown。', where: '模型判断,Host 校验 task 是否存在' },
37
37
  { name: 'lineage', required: true, meaning: 'intentId / taskId / subtaskId / runId 四个 id 的链路,下游工具与产物靠它回溯。', where: 'Host 分配,模型可显式续接' },
38
- { name: 'source', required: true, meaning: 'model = 模型记录;fallback = 轮次结束模型没记,Host 补的一条 unknown。', where: 'Host 标记' },
38
+ { name: 'source', required: true, meaning: 'model = 模型记录;fallback = 数据轮次结束模型没记,Host 补的一条 unknown。', where: 'Host 标记' },
39
39
  ]
40
40
 
41
41
  interface Paper {
@@ -110,7 +110,7 @@ export function IntentLogic(): ReactNode {
110
110
  <ul className={styles.intentDocList}>
111
111
  <li><b>判断完全交给大模型。</b>`intent_record` 只把模型给出的结论落成一条记录,不做关键词匹配、不做状态机、不反问、不阻断当前请求,也不会因为分类错了就让请求失败。</li>
112
112
  <li><b>记录不驱动控制流。</b>它服务三件事:事后回溯(这轮到底想干什么)、链路串联(下游工具与产物继承 taskId / subtaskId)、质量观测(哪些轮次低置信度、哪些落到了 unknown)。</li>
113
- <li><b>模型漏了也不丢。</b>轮次结束时如果没有任何记录,Host 补一条 <code>source: fallback</code> 的 unknown,保证"每轮一条"这个不变式成立。</li>
113
+ <li><b>数据轮次漏了也不丢。</b>只有进入数据 / 知识域的轮次才需要记录;如果模型漏记,Host 补一条 <code>source: fallback</code> 的 unknown。普通 Agent 和闲聊不会生成意图记录。</li>
114
114
  </ul>
115
115
  </Section>
116
116