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
@@ -11,24 +11,26 @@ Host 提供两个工具:
11
11
  - `intent_record`:把模型对当前轮次的判断写成一条审计记录。
12
12
  - `intent_store_view`:查看当前会话的最近记录与任务链路。
13
13
 
14
- 工具只在 Tita preset 的 agent 平面注册。HTTP 只读接口是 `/intent/overview` 与
14
+ 工具在 Host 层注册,供标准模式使用。意图写入与读取只接受 `standard` 会话。
15
+ HTTP 只读接口是 `/intent/overview` 与
15
16
  `/intent/store`,服务名仍为 `titaDataAgentIntent`。
16
17
 
17
18
  ## 固定审计契约
18
19
 
19
20
  分类、act 与 predicate 的内置词表由代码固定提供,不属于知识库配置,也没有编辑入口。
20
- `intent_record` 的工具描述携带这份固定规则;记录器只校验并保留模型结论,不做关键词
21
- 匹配、不反问、不阻断请求。模型漏调时,Host 在 `turn/end` 补一条
22
- `source: 'fallback'` 的 `unknown` 记录。
21
+ `intent_record` 的工具描述携带这份固定规则;记录器只校验并保留模型结论,不做完整的
22
+ 意图分类、不反问、不阻断请求。门控只负责判断是否进入数据域:其他 preset 和普通聊天
23
+ 不创建意图记录;标准模式在数据工具、数据域请求或数据分类被激活后,模型漏调时,
24
+ Host 才在 `turn/end` 补一条 `source: 'fallback'` 的 `unknown` 记录。
23
25
 
24
26
  ## 记录与 ID
25
27
 
26
- - 按 `session + turn` upsert:同一轮重复调用只保留一条记录。
28
+ - 按 `session + data turn` upsert:同一数据轮次重复调用只保留一条记录,普通轮次不落记录。
27
29
  - Host 在 `turn/start` 为当前轮次预分配 `subtaskId`;模型用 `relation` 表示新任务
28
30
  (`new_task`)或已有任务的子任务(`subtask_of`)。
29
31
  - 记录写入 `<agentRoot>/intent/intent.db`。`intent_records` 保存每轮当前版本,
30
32
  `intent_record_history` 追加保存每次变更。内存工作集仍按 TTL(默认 600 秒)管理,
31
- SQLite 用于重启后的审计留痕与面板读取。旧的 `records.ndjson` 只做一次性迁移。
33
+ SQLite 用于重启后的审计留痕与面板读取。
32
34
 
33
35
  ## 与知识库召回的边界
34
36
 
@@ -15,8 +15,8 @@ import {
15
15
  type IntentTaskSummary,
16
16
  type IntentTurnState,
17
17
  } from './types.js'
18
- import { envelopeSuccess } from 'dsh-data-contracts/envelope'
19
- import type { LineageContext } from 'dsh-data-contracts/refs'
18
+ import { envelopeSuccess } from '#contracts'
19
+ import type { LineageContext } from '#contracts'
20
20
 
21
21
  function id(prefix = 'intent'): string {
22
22
  return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`
@@ -226,12 +226,14 @@ export class IntentEngine {
226
226
  * Downstream calls dispatched in parallel with the record can already carry
227
227
  * an id; the record later commits the authoritative task binding.
228
228
  */
229
- beginTurn(sessionKey: string, turn: number, userInput: string): IntentTurnState {
229
+ beginTurn(sessionKey: string, turn: number, userInput: string, eligible = true): IntentTurnState {
230
230
  const state: IntentTurnState = {
231
231
  turn,
232
232
  userInput: userInput.slice(0, 2000),
233
233
  subtaskId: id('subtask'),
234
234
  taskId: this.store.last(sessionKey)?.lineage.taskId,
235
+ eligible,
236
+ dataToolUsed: false,
235
237
  committed: false,
236
238
  }
237
239
  this.turns.set(sessionKey, state)
@@ -252,11 +254,46 @@ export class IntentEngine {
252
254
  return true
253
255
  }
254
256
 
255
- /** Backfill one `unknown` record when a turn ends without a model record. */
257
+ /** Mark the current turn as a data turn without classifying it. */
258
+ markDataIntent(sessionKey: string, turn?: number): boolean {
259
+ const state = this.turns.get(sessionKey)
260
+ if (!state || state.committed || (turn !== undefined && state.turn !== turn)) return false
261
+ state.eligible = true
262
+ return true
263
+ }
264
+
265
+ /** Mark the current turn as a data turn based on actual data-tool use. */
266
+ markDataToolUse(sessionKey: string, turn?: number): boolean {
267
+ const state = this.turns.get(sessionKey)
268
+ if (!state || state.committed || (turn !== undefined && state.turn !== turn)) return false
269
+ state.eligible = true
270
+ state.dataToolUsed = true
271
+ return true
272
+ }
273
+
274
+ /** Clear a text-only gate when the model explicitly identifies a non-data turn. */
275
+ clearDataIntent(sessionKey: string, turn?: number): boolean {
276
+ const state = this.turns.get(sessionKey)
277
+ if (!state || state.committed || (turn !== undefined && state.turn !== turn)) return false
278
+ if (!state.dataToolUsed) state.eligible = false
279
+ return true
280
+ }
281
+
282
+ /** Whether the current turn is eligible for data intent recording. */
283
+ isDataIntentTurn(sessionKey: string, turn?: number): boolean {
284
+ const state = this.turns.get(sessionKey)
285
+ return Boolean(state && !state.committed && state.eligible && (turn === undefined || state.turn === turn))
286
+ }
287
+
288
+ /** Backfill one `unknown` record only when an eligible data turn has no model record. */
256
289
  fallbackWhenMissing(sessionKey: string, turn: number): IntentResult | undefined {
257
290
  if (!this.settings.fallbackEnabled) return undefined
258
291
  const state = this.turns.get(sessionKey)
259
292
  if (!state || state.turn !== turn || state.committed) return undefined
293
+ if (!state.eligible) {
294
+ this.turns.delete(sessionKey)
295
+ return undefined
296
+ }
260
297
  const result = this.record({
261
298
  userInput: state.userInput,
262
299
  act: 'unknown',
@@ -271,7 +308,7 @@ export class IntentEngine {
271
308
  return result
272
309
  }
273
310
 
274
- /** Record the model's intent judgement. Always stores a record. */
311
+ /** Record the model's intent judgement. The host applies scope before calling this method. */
275
312
  record(input: IntentRecordInput, source: IntentSource = 'model'): IntentResult {
276
313
  const sessionKey = input.sessionKey?.trim() || 'default'
277
314
  const timestamp = new Date(input.now ?? Date.now()).toISOString()
@@ -453,7 +490,8 @@ export class IntentEngine {
453
490
  })
454
491
  .join('\n')
455
492
  return [
456
- '记录本轮用户意图:先判断,再调用 intent_record 落一条审计记录,然后继续完成请求——记录不改变、不阻塞、也不需要用户确认。',
493
+ '本工具支持 standard preset 的顶层会话。先判断本轮是否属于数据 / 知识域;只有属于数据域时,才调用 intent_record 落一条数据意图审计;寒暄、闲聊、Agent 自身说明、纯写作、代码和一般运维请求不要调用,也不要补 unknown。记录不改变、不阻塞、也不需要用户确认。',
494
+ '如果当前请求会使用数据、知识库、表格、报告、SourceRaw、WikiCard、查询、分析、导入、编译或召回工具,它属于数据域;否则按普通对话处理。',
457
495
  '当前轮是新的任务用 relation=new_task;如果是在延续某个已有任务(追问、补充、纠正),用 relation=subtask_of 并带上该任务的 task_id;无法判断时省略 relation。',
458
496
  '',
459
497
  '分类判定分两步,必须先匹配预置、再自行判断:',
@@ -2,19 +2,20 @@ import type { IncomingMessage, ServerResponse } from 'node:http'
2
2
  import type { Context } from '@deepseek-ai/cordis'
3
3
  import type {} from '@deepseek-ai/dsh-settings'
4
4
  import type {} from '@deepseek-ai/dsh-system-prompt'
5
- import { envelopeSuccess } from 'dsh-data-contracts/envelope'
6
- import type { LineageContext } from 'dsh-data-contracts/refs'
5
+ import { envelopeFailure, envelopeSuccess } from '#contracts'
6
+ import type { LineageContext } from '#contracts'
7
7
  import { DEFAULT_INTENT_SETTINGS } from './types.js'
8
8
  import { IntentEngine } from './engine.js'
9
9
  import { appendIntentRecord, readIntentRecords } from './store.js'
10
10
  import type { IntentToolHost } from './tools.js'
11
11
  import { lineageOf, sessionKeyOf } from './tools.js'
12
+ import { isIntentAgentSession, isDataIntentCandidate, isDataIntentPayload, isDataToolName, isExplicitNonDataIntentPayload } from './scope.js'
12
13
 
13
14
  export * from './types.js'
14
15
  export * from './engine.js'
15
16
  export * from './tools.js'
16
17
 
17
- /** Read-only HTTP surface the 意图 panel reads: `/intent/overview` and `/intent/store`. */
18
+ /** Session intent audit endpoints. */
18
19
  export const INTENT_MOUNT_PATH = '/intent'
19
20
  /** Cordis service name consumers read to inherit the session's active task ids. */
20
21
  export const INTENT_SERVICE = 'titaDataAgentIntent'
@@ -24,10 +25,9 @@ export const INTENT_SERVICE = 'titaDataAgentIntent'
24
25
  *
25
26
  * 两类消费者,一个服务:
26
27
  * - `activeLineage` —— 其它插件(`data-table`)读本轮活动血缘。
27
- * - 其余成员 —— agent 平面的挂载行(`./preset-tools.ts`)按它注册 `intent_*` 工具。
28
+ * - 其余成员 —— Host 组合根按它注册 `intent_*` 工具。
28
29
  *
29
- * 0029 之前这两个工具由本模块直接全局注册;现在注册搬到了 agent 平面,这里只留
30
- * 「引擎能做什么」。引擎只有一份,工具定义也只有一份(`./tools.ts`)。
30
+ * 本模块只提供意图引擎。组合根在 Host 层注册工具;执行端只接受标准模式的会话。
31
31
  */
32
32
  export interface IntentService extends IntentToolHost {
33
33
  /**
@@ -68,9 +68,7 @@ function userText(message: unknown): string {
68
68
  * 它是 `KnowledgePanel` 五个视图之一「意图」的宿主实现。0029 起它**只负责引擎**:
69
69
  * 轮次记账、`/intent/**` 只读面,以及通过 `INTENT_SERVICE` 暴露操作面。
70
70
  *
71
- * 两个 `intent_*` 工具**不再在这里注册** —— 它们搬到了 agent 平面的
72
- * `./preset-tools.ts`,只被自定义 preset 的 `agent.cordis.yml` 挂载,于是只有跑
73
- * TitaAgent 那套组合的会话才看得到它们。理由见那个文件的模块注释。
71
+ * `intent_*` 工具由组合根在 Host 层注册;本模块只提供引擎和会话审计能力。
74
72
  *
75
73
  * 本模块由 `src/index.ts` 组合根调用,不自己导出 `name` / `inject`。
76
74
  * @module dsh-data-domain-knowledge/intent
@@ -134,6 +132,26 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
134
132
  */
135
133
  record: (args, exec) => {
136
134
  const lineage = lineageOf(args, exec)
135
+ const session = exec?.agent?.session
136
+ if (session && !isIntentAgentSession(session)) {
137
+ return envelopeSuccess({ skipped: true, skipReason: 'unsupported_preset' as const })
138
+ }
139
+ const sessionKey = sessionKeyOf(exec)
140
+ if (!sessionKey) {
141
+ return envelopeFailure({ skipped: false }, {
142
+ code: 'SESSION_CONTEXT_REQUIRED',
143
+ message: '意图记录只能在有活动 DSH 会话的上下文中写入。',
144
+ retryable: false,
145
+ })
146
+ }
147
+ if (isExplicitNonDataIntentPayload(args)) {
148
+ engine.clearDataIntent(sessionKey)
149
+ return envelopeSuccess({ skipped: true, skipReason: 'non_data_turn' as const })
150
+ }
151
+ if (!engine.isDataIntentTurn(sessionKey) && !isDataIntentPayload(args)) {
152
+ return envelopeSuccess({ skipped: true, skipReason: 'non_data_turn' as const })
153
+ }
154
+ engine.markDataIntent(sessionKey)
137
155
  return engine.record({
138
156
  userInput: typeof args.user_input === 'string' ? args.user_input : '',
139
157
  ...(typeof args.act === 'string' ? { act: args.act } : {}),
@@ -143,7 +161,7 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
143
161
  ...(typeof args.confidence === 'number' ? { confidence: args.confidence } : {}),
144
162
  ...(Array.isArray(args.refs) ? { refs: args.refs as Array<{ id: string }> } : {}),
145
163
  ...(args.relation === 'new_task' || args.relation === 'subtask_of' ? { relation: args.relation } : {}),
146
- sessionKey: sessionKeyOf(args, exec),
164
+ sessionKey,
147
165
  ...(lineage ? { lineage } : {}),
148
166
  })
149
167
  },
@@ -154,11 +172,15 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
154
172
  // 描述(见 `./tools.ts` 的 `registerIntentTools`)。两处都放会重复占用上下文,
155
173
  // 而且会漂移。
156
174
 
157
- // Turn bookkeeping: allocate provisional ids per turn and backfill one record
158
- // if the turn ends without one (issue 0012 decision B).
175
+ // Turn bookkeeping: allocate provisional ids for standard data turns and backfill
176
+ // one record only when a data turn ends without one (issue 0012 decision B).
159
177
  const pendingInput = new Map<string, string>()
160
178
  ctx.on('session/event', (session, event) => {
161
179
  const sessionKey = session.header.id as unknown as string
180
+ if (!isIntentAgentSession(session)) {
181
+ pendingInput.delete(sessionKey)
182
+ return
183
+ }
162
184
  if (event.type === 'user/message') {
163
185
  const text = userText(event.data)
164
186
  if (!text) return
@@ -166,10 +188,12 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
166
188
  // `turn/start` may have arrived before the user message. In that case update the
167
189
  // provisional state instead of leaving the record with an empty userInput.
168
190
  engine.updateTurnInput(sessionKey, text)
191
+ if (isDataIntentCandidate(text)) engine.markDataIntent(sessionKey)
169
192
  return
170
193
  }
171
194
  if (event.type === 'turn/start') {
172
- engine.beginTurn(sessionKey, event.data.turn, pendingInput.get(sessionKey) ?? '')
195
+ const input = pendingInput.get(sessionKey) ?? ''
196
+ engine.beginTurn(sessionKey, event.data.turn, input, isDataIntentCandidate(input))
173
197
  return
174
198
  }
175
199
  if (event.type === 'turn/end') {
@@ -178,9 +202,22 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
178
202
  }
179
203
  })
180
204
 
181
- // Read-only HTTP surface for the 意图 panel. The intent store is in-memory and
182
- // session-scoped, so the panel reads it over HTTP instead of duplicating the
183
- // engine in the browser.
205
+ /**
206
+ * 实际数据工具是比关键词更可靠的后置证据。
207
+ *
208
+ * 例如「帮我看看这个」本身没有明显关键词,但模型随后调用了
209
+ * `recall_knowledge`;这种轮次仍应在结束时补齐一条数据意图审计。
210
+ */
211
+ ctx.on('tools/pre-execute', (exec, next) => {
212
+ const session = exec?.agent?.session
213
+ if (isIntentAgentSession(session) && isDataToolName(exec?.name)) {
214
+ const sessionKey = session?.header?.id
215
+ if (typeof sessionKey === 'string') engine.markDataToolUse(sessionKey)
216
+ }
217
+ return next()
218
+ })
219
+
220
+ // Intent audit HTTP surface. It exposes stored intent data only.
184
221
  ctx.inject(['webServer'], webCtx => {
185
222
  const web = webCtx as unknown as {
186
223
  webServer: {
@@ -246,6 +283,10 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
246
283
  const url = new URL(req.url ?? '/', 'http://127.0.0.1')
247
284
  const sessionKey = url.searchParams.get('session_key')?.trim() || 'default'
248
285
  const includePrompt = url.searchParams.get('include_prompt') === 'true'
286
+ const requestedLimit = Number(url.searchParams.get('limit'))
287
+ const recentLimit = Number.isFinite(requestedLimit) && requestedLimit > 0
288
+ ? Math.min(500, Math.max(1, Math.round(requestedLimit)))
289
+ : 10
249
290
  const view = engine.view(sessionKey, includePrompt)
250
291
  const base = root()
251
292
  if (base) {
@@ -256,9 +297,9 @@ export function applyIntent(ctx: Context, deps: IntentHostDeps = {}): IntentHost
256
297
  * 「意图记录」会莫名其妙变空,而文件里明明一条不少。`tasks` /
257
298
  * `activeTaskId` 仍来自工作集 —— 那是**活的血缘**,不是历史。
258
299
  */
259
- const durable = await readIntentRecords(base, sessionKey, 50)
300
+ const durable = await readIntentRecords(base, sessionKey, recentLimit)
260
301
  const store = (view.data as { store?: { recent?: unknown[] } }).store
261
- if (store) store.recent = durable.slice(-10).reverse()
302
+ if (store) store.recent = durable.slice(-recentLimit).reverse()
262
303
  }
263
304
  send(res, 200, view)
264
305
  },
@@ -0,0 +1,125 @@
1
+ /**
2
+ * 会话意图的作用域门控。
3
+ *
4
+ * 意图记录只服务于 DSH 标准模式,不是宿主里每个 Agent 都要承担的全局开销。
5
+ * 这里的判断只回答「这一轮是否值得进入数据意图链路」,不负责替模型判断具体的
6
+ * act / category。具体分类仍由 `intent_record` 的固定提示词完成。
7
+ */
8
+
9
+ import { isIntentEnabledPreset } from '../preset-ids.js'
10
+
11
+ /** 数据域分类。其它分类(闲聊、运维、Agent 工程等)不应写入数据意图审计。 */
12
+ const DATA_CATEGORY_IDS = new Set([
13
+ 'data_analysis',
14
+ 'metadata_exploration',
15
+ 'data_validation',
16
+ 'knowledge_consultation',
17
+ 'knowledge_building',
18
+ 'document_research',
19
+ 'artifact_delivery',
20
+ ])
21
+
22
+ /** 模型明确标成普通对话 / Agent 运维时,不因原文碰到一个数据词就强行落记录。 */
23
+ const NON_DATA_CATEGORY_IDS = new Set([
24
+ 'conversation',
25
+ 'agent_engineering',
26
+ 'tooling_operations',
27
+ 'personal_assistant',
28
+ 'message_collaboration',
29
+ ])
30
+
31
+ const NON_DATA_ACT_IDS = new Set(['greet', 'chat'])
32
+
33
+ /** 直接表示数据 / 知识链路的 predicate。 */
34
+ const DATA_PREDICATE_IDS = new Set([
35
+ 'query_babel_data',
36
+ 'query_knowledge',
37
+ 'query_source_truth',
38
+ 'query_metadata',
39
+ 'query_graph',
40
+ 'add_source',
41
+ 'propose_wiki_cards',
42
+ 'rebuild_knowledge',
43
+ ])
44
+
45
+ /** 发生实际数据工作的工具。意图工具本身不在这里,避免自调用激活门控。 */
46
+ const DATA_TOOL_NAMES = new Set([
47
+ 'recall_knowledge',
48
+ 'get_knowledge_events',
49
+ 'get_knowledge_cases',
50
+ 'run_knowledge_pipeline',
51
+ 'get_knowledge_pipeline',
52
+ 'query_knowledge_graph',
53
+ 'query_source_truth',
54
+ 'list_knowledge_bases',
55
+ 'check_knowledge_embeddings',
56
+ 'add_source',
57
+ 'import_sources',
58
+ 'propose_wiki_cards',
59
+ 'annotate_wiki_card',
60
+ 'review_wiki_card',
61
+ 'set_knowledge_status',
62
+ 'record_feedback',
63
+ 'rebuild_knowledge',
64
+ 'convert_source',
65
+ 'convert_ingest',
66
+ 'convert_task',
67
+ ])
68
+
69
+ /**
70
+ * 这些词只做「是否进入数据域」的廉价门控,不做分类,也不替代模型判断。
71
+ * 列表刻意覆盖知识库、表格、查询、编译与召回;普通聊天不会因为一个泛化动词
72
+ * (例如「帮我写」)被误判成数据请求。
73
+ */
74
+ const DATA_DOMAIN_RE = /数据|指标|字段|数据库|知识库|知识卡|知识矩阵|召回|检索|向量|坐标|实体|source.?raw|wiki.?card|文档|资料|表格?|SQL|Excel|GMV|销售额|订单|报表|口径|编译|重建|导入|抽取|卡片/i
75
+ const DATA_ACTION_RE = /查|查询|统计|分析|计算|核对|校验|对比|召回|检索|读取|查看|导入|编译|重建|抽取|整理|生成|导出|写入|构建|解释|定义|口径/i
76
+ const DATA_QUESTION_RE = /(?:数据|指标|字段|数据库|知识库|文档|表格?|报表|口径)(?:里|中|有|是|怎么|如何|哪个|哪些|什么|相关)/i
77
+
78
+ /** 读取 DSH Session 的 preset 标识;结构读取以兼容测试替身和旧宿主。 */
79
+ export function sessionPresetOf(session: unknown): string | undefined {
80
+ const value = session as { header?: { agentPreset?: unknown } } | undefined
81
+ return typeof value?.header?.agentPreset === 'string' ? value.header.agentPreset : undefined
82
+ }
83
+
84
+ /** 标准模式参与数据 / 知识意图留痕。 */
85
+ export function isIntentAgentSession(session: unknown): boolean {
86
+ return isIntentEnabledPreset(sessionPresetOf(session))
87
+ }
88
+
89
+ /** 判断一个工具是否代表真实的数据 / 知识工作。 */
90
+ export function isDataToolName(name: unknown): boolean {
91
+ if (typeof name !== 'string') return false
92
+ return DATA_TOOL_NAMES.has(name) || /^workbook_/.test(name)
93
+ }
94
+
95
+ /**
96
+ * 判断用户原文是否明显进入数据域。
97
+ *
98
+ * 这是 gate,不是 NLU:宁可让模型通过 `category` 或实际数据工具调用补充一次,
99
+ * 也不在这里生成意图分类,避免第二套分类逻辑与 `intent_record` 漂移。
100
+ */
101
+ export function isDataIntentCandidate(value: unknown): boolean {
102
+ if (typeof value !== 'string') return false
103
+ const text = value.trim()
104
+ if (!text) return false
105
+ return (DATA_DOMAIN_RE.test(text) && DATA_ACTION_RE.test(text)) || DATA_QUESTION_RE.test(text)
106
+ }
107
+
108
+ /** 模型已经给出数据分类 / predicate 时,允许这一轮进入审计。 */
109
+ export function isDataIntentPayload(args: Record<string, unknown>): boolean {
110
+ const category = typeof args.category === 'string' ? args.category.trim() : ''
111
+ const predicate = typeof args.predicate === 'string' ? args.predicate.trim() : ''
112
+ const domain = typeof args.domain === 'string' ? args.domain.trim().toLowerCase() : ''
113
+ return DATA_CATEGORY_IDS.has(category)
114
+ || DATA_PREDICATE_IDS.has(predicate)
115
+ || domain === 'data'
116
+ || domain === 'knowledge'
117
+ || isDataIntentCandidate(args.user_input)
118
+ }
119
+
120
+ /** 模型已经明确表示这是普通对话时,覆盖廉价的文本 gate。 */
121
+ export function isExplicitNonDataIntentPayload(args: Record<string, unknown>): boolean {
122
+ const category = typeof args.category === 'string' ? args.category.trim() : ''
123
+ const act = typeof args.act === 'string' ? args.act.trim() : ''
124
+ return NON_DATA_CATEGORY_IDS.has(category) || NON_DATA_ACT_IDS.has(act)
125
+ }
@@ -3,35 +3,22 @@
3
3
  *
4
4
  * ## 为什么要单独一个文件
5
5
  *
6
- * 0029 之前这两个工具由宿主平面的 `applyIntent` 直接 `ctx.tools.register(...)`,
7
- * 于是它们是**全局工具**:任何 agent、任何 preset 的会话都会在提示词里看到
8
- * `intent_record`,也都能调它。而意图记录是这个方案自己的东西 —— 只有跑
9
- * TitaAgent 那套组合的会话才该有它,别的 agent 场景(别的 preset、临时会话)
10
- * 不该被塞一个用不上的工具。
11
- *
12
- * DSH 里「只有某个 preset 能用」的**唯一**支持形态是**注册作用域**:注册在哪个
13
- * 作用域,就只在哪个作用域可见(`dsh-tools` 的 `register` 是 scope-layered)。
14
- * `ctx.tools.restrict()` 只能做减法(从继承来的工具里减掉),宿主平面调它还会
15
- * 直接抛 —— 没有「只给某一个作用域」的正向开关。所以正确的做法是把注册搬到
16
- * **agent 平面**:一个只被自定义 preset 的 `agent.cordis.yml` 挂载的行
17
- * (`./preset-tools.ts`),它注册的工具只覆盖那个 preset 的会话。
18
- *
19
- * 注册逻辑本身与平面无关,所以它留在这里:宿主平面负责「引擎怎么跑」(轮次记账、
20
- * 轮次记账、HTTP 只读面),agent 平面负责「模型看到什么工具」。两边共用这一份,
21
- * 不各写一套工具定义。
6
+ * 工具由 Host 层注册,因此可以被标准模式调用。由于 Host 工具也可能出现在其他 preset
7
+ * 中,执行端会检查会话,只接受 `standard`。
22
8
  *
23
9
  * @module
24
10
  */
25
11
 
26
12
  import { defineTool, type ToolRunContext } from '@deepseek-ai/dsh-tools'
27
- import type { LineageContext } from 'dsh-data-contracts/refs'
13
+ import { envelopeFailure } from '#contracts'
14
+ import type { LineageContext } from '#contracts'
15
+ import { isIntentAgentSession } from './scope.js'
28
16
 
29
17
  /**
30
18
  * 注册这两个工具需要引擎提供的能力。
31
19
  *
32
20
  * 刻意是**结构化的最小面**而不是 `IntentEngine` 本身:宿主平面通过
33
- * `INTENT_SERVICE` 提供它,agent 平面的行只按这个形状取用。这样 preset 行不必
34
- * import 引擎、也不必知道引擎住在哪个模块里。
21
+ * `INTENT_SERVICE` 提供它,注册器只按这个形状使用引擎,不依赖其具体实现位置。
35
22
  */
36
23
  export interface IntentToolHost {
37
24
  /** `intent_record` 的**工具描述就是路由提示词**(0023)。 */
@@ -50,7 +37,6 @@ const INTENT_RECORD_PARAMS: Record<string, unknown> = {
50
37
  confidence: { type: 'number', description: '0-1,用于标注 lowConfidence' },
51
38
  refs: { type: 'array', description: '引用对象,例如 { id, kind, label }' },
52
39
  relation: { type: 'string', enum: ['new_task', 'subtask_of'], description: '本轮是新任务还是已有任务的子任务' },
53
- session_key: { type: 'string' },
54
40
  turn_id: { type: 'string', description: '当前对话轮次 id;不传则由 Host 生成' },
55
41
  task_id: { type: 'string', description: 'relation=subtask_of 时指向的已有业务任务 id;新任务不传' },
56
42
  subtask_id: { type: 'string', description: '已有子任务 id;新子任务不传,由 Host 生成' },
@@ -75,7 +61,8 @@ export function jsonTool(name: string, description: string, parameters: Record<s
75
61
 
76
62
  export function lineageOf(args: Record<string, unknown>, exec?: ToolRunContext): Partial<LineageContext> | undefined {
77
63
  const lineage: Partial<LineageContext> = {}
78
- const sessionId = typeof args.session_key === 'string' && args.session_key.trim() ? args.session_key.trim() : exec?.agent?.session.header.id
64
+ // Session identity is execution context, never model-controlled input.
65
+ const sessionId = exec?.agent?.session?.header?.id
79
66
  if (sessionId) lineage.sessionId = sessionId
80
67
  const fields: Array<[keyof LineageContext, string]> = [
81
68
  ['turnId', 'turn_id'], ['taskId', 'task_id'], ['subtaskId', 'subtask_id'],
@@ -85,9 +72,43 @@ export function lineageOf(args: Record<string, unknown>, exec?: ToolRunContext):
85
72
  return Object.keys(lineage).length > 0 ? lineage : undefined
86
73
  }
87
74
 
88
- export function sessionKeyOf(args: Record<string, unknown>, exec?: ToolRunContext): string {
89
- const explicit = typeof args.session_key === 'string' ? args.session_key.trim() : ''
90
- return explicit || exec?.agent?.session.header.id || 'default'
75
+ export function sessionKeyOf(exec?: ToolRunContext): string | undefined {
76
+ const sessionId = exec?.agent?.session?.header?.id
77
+ return typeof sessionId === 'string' && sessionId.trim() ? sessionId.trim() : undefined
78
+ }
79
+
80
+ /**
81
+ * 这个会话是不是**子代理**。
82
+ *
83
+ * 子代理会加入父会话的组合,所以它会继承到 `intent_*` 两个工具。而意图记录描述的是
84
+ * 「用户在跟 Agent 要什么」:子代理做的是被拆出来的一个片段,它记一条只会污染任务树。
85
+ *
86
+ * 这条规矩原来写在 preset 的 delegation 行上(`toolFilter: { deny: [...] }`)。DSH 0.1.8
87
+ * 起 `toolFilter`(与 `persona`)**不再被 `dsh-tool-subagent` 接受** —— 带上它的 preset
88
+ * 直接挂载失败,整个组合都不会生效。平台给的替代是「在 Agent Preset 里配好工具,再用
89
+ * `agentPreset` 选中它」,而那**只对 spawn provider 有效**:fork / codex / claude-code
90
+ * 的子会话按定义继承父会话的组合,没有选择余地(`inheritsParentContext` 直接拒绝)。
91
+ *
92
+ * 所以判据搬进工具本身:看会话头,与「谁把子会话拉起来的」无关。四个 provider 一视同仁,
93
+ * 也不会再出现「新增一个 delegation 行忘了 deny」这种漏法。
94
+ *
95
+ * 判据取两个字段:`origin === 'subagent'` 是产品分类,`delegationDepth > 0` 是递归深度
96
+ * (持久化过,重启后仍然成立)。任一条成立就算子会话。
97
+ */
98
+ export function isSubagentSession(exec?: ToolRunContext): boolean {
99
+ const header = exec?.agent?.session?.header
100
+ if (!header) return false
101
+ if (header.origin === 'subagent') return true
102
+ return typeof header.delegationDepth === 'number' && header.delegationDepth > 0
103
+ }
104
+
105
+ /** 子代理调这两个工具时统一回这一条:说清为什么,并给出该走的路。 */
106
+ function subagentRefusal(): unknown {
107
+ return envelopeFailure({ sessionKey: null }, {
108
+ code: 'SUBAGENT_NOT_RECORDED',
109
+ message: '子代理不记录意图:意图描述的是用户与主 Agent 的交互。把要记的内容写进返回结果,由主 Agent 记录。',
110
+ retryable: false,
111
+ })
91
112
  }
92
113
 
93
114
  /**
@@ -99,11 +120,32 @@ export function sessionKeyOf(args: Record<string, unknown>, exec?: ToolRunContex
99
120
  * 返回 disposer。
100
121
  */
101
122
  export function registerIntentTools(ctx: { tools: ToolRegistryLike }, host: IntentToolHost): () => void {
102
- const disposeRecord: unknown = ctx.tools.register(jsonTool('intent_record', host.routingPrompt(), INTENT_RECORD_PARAMS, (args, exec) => host.record(args, exec)))
123
+ const disposeRecord: unknown = ctx.tools.register(jsonTool('intent_record', host.routingPrompt(), INTENT_RECORD_PARAMS, (args, exec) => (
124
+ isSubagentSession(exec) ? subagentRefusal() : host.record(args, exec)
125
+ )))
103
126
  const disposeView: unknown = ctx.tools.register(jsonTool(
104
- 'intent_store_view', 'View recent intent records and the active task ids for the current session.',
105
- { session_key: { type: 'string' }, include_prompt: { type: 'boolean' } },
106
- (args: { session_key?: string; include_prompt?: boolean }, exec) => host.view(sessionKeyOf(args, exec), args.include_prompt),
127
+ 'intent_store_view', 'View recent intent records and active task ids for the current session. Only standard sessions can use this tool.',
128
+ { include_prompt: { type: 'boolean' } },
129
+ (args: { include_prompt?: boolean }, exec) => {
130
+ if (isSubagentSession(exec)) return subagentRefusal()
131
+ const session = exec?.agent?.session
132
+ if (session && !isIntentAgentSession(session)) {
133
+ return envelopeFailure({ sessionKey: null }, {
134
+ code: 'INTENT_PRESET_UNSUPPORTED',
135
+ message: '意图记录只支持标准模式。',
136
+ retryable: false,
137
+ })
138
+ }
139
+ const sessionKey = sessionKeyOf(exec)
140
+ if (!sessionKey) {
141
+ return envelopeFailure({ sessionKey: null }, {
142
+ code: 'SESSION_CONTEXT_REQUIRED',
143
+ message: '意图记录只能在有活动 DSH 会话的上下文中读取。',
144
+ retryable: false,
145
+ })
146
+ }
147
+ return host.view(sessionKey, args.include_prompt)
148
+ },
107
149
  ))
108
150
  return () => {
109
151
  if (typeof disposeRecord === 'function') (disposeRecord as () => void)()
@@ -1,5 +1,5 @@
1
- import type { ToolStatus } from 'dsh-data-contracts/envelope'
2
- import type { LineageContext } from 'dsh-data-contracts/refs'
1
+ import type { ToolStatus } from '#contracts'
2
+ import type { LineageContext } from '#contracts'
3
3
 
4
4
  export type { ToolStatus }
5
5
 
@@ -45,7 +45,7 @@ export type IntentAct = string
45
45
  /** How one turn relates to the session's existing tasks. */
46
46
  export type IntentRelation = 'new_task' | 'subtask_of' | 'unknown'
47
47
 
48
- /** `model` is a model-authored record; `fallback` is the Host's turn-end backfill. */
48
+ /** `model` is a model-authored record; `fallback` is the Host's data-turn backfill. */
49
49
  export type IntentSource = 'model' | 'fallback'
50
50
 
51
51
  export interface IntentSlotMap {
@@ -91,7 +91,7 @@ export interface IntentSettings {
91
91
  * 0023:路由提示词**没有开关**。它随 `intent_record` 的工具描述一起下发,
92
92
  * 分类规则必须始终在场——否则模型退化成每轮从零判断。
93
93
  */
94
- /** Backfill one `unknown` record when a turn ends without a model record. */
94
+ /** Backfill one `unknown` record when an eligible data turn ends without a model record. */
95
95
  fallbackEnabled: boolean
96
96
  }
97
97
 
@@ -203,6 +203,9 @@ export interface IntentResultData {
203
203
  activeTasks?: IntentTaskSummary[]
204
204
  store?: IntentStoreView
205
205
  prompt?: string
206
+ /** True when the scoped tool call was intentionally ignored as a non-data turn. */
207
+ skipped?: boolean
208
+ skipReason?: 'non_data_agent' | 'unsupported_preset' | 'non_data_turn'
206
209
  }
207
210
 
208
211
  export interface IntentResult {
@@ -218,5 +221,9 @@ export interface IntentTurnState {
218
221
  userInput: string
219
222
  subtaskId: string
220
223
  taskId?: string
224
+ /** The turn entered the data intent scope through text, payload or a data tool. */
225
+ eligible: boolean
226
+ /** A data tool ran during this turn; a later chat classification cannot revoke it. */
227
+ dataToolUsed: boolean
221
228
  committed: boolean
222
229
  }