agentworkshop 0.8.5 → 0.8.7

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 (1999) hide show
  1. package/.AgentWorkShop/prompts/host-tools.en.json +196 -68
  2. package/.AgentWorkShop/prompts/host-tools.json +16 -6
  3. package/.output/.AgentWorkShop/aml-python/train-example.py +92 -92
  4. package/.output/.AgentWorkShop/prompts/host-tools.en.json +196 -68
  5. package/.output/.AgentWorkShop/prompts/host-tools.json +16 -6
  6. package/.output/nitro.json +1 -1
  7. package/.output/public/_nuxt/9Kt-rxrm.js +1 -0
  8. package/.output/public/_nuxt/ATAvN55g.js +1 -0
  9. package/.output/public/_nuxt/B3GEA4IW.js +1 -0
  10. package/.output/public/_nuxt/B9qIhT7k2.js +1 -0
  11. package/.output/public/_nuxt/BBTI9r9T2.js +1 -0
  12. package/.output/public/_nuxt/BE9oKpOt.js +1 -0
  13. package/.output/public/_nuxt/BHOjkDAJ.js +21 -0
  14. package/.output/public/_nuxt/BTaGYNZF2.js +1 -0
  15. package/.output/public/_nuxt/BXUDD9fv.js +1 -0
  16. package/.output/public/_nuxt/BXbZ_hei.js +1 -0
  17. package/.output/public/_nuxt/BaGy_jAI2.js +1 -0
  18. package/.output/public/_nuxt/BdfAuX81.js +1 -0
  19. package/.output/public/_nuxt/BoXKUOiN2.js +1 -0
  20. package/.output/public/_nuxt/Buj_DMJ-.js +1 -0
  21. package/.output/public/_nuxt/Bv7dyPx4.js +1 -0
  22. package/.output/public/_nuxt/BvjY-Xks.js +1 -0
  23. package/.output/public/_nuxt/BxC9PAu-2.js +1 -0
  24. package/.output/public/_nuxt/Bzfzp9-f.js +1 -0
  25. package/.output/public/_nuxt/CT4bi_Y4.js +1 -0
  26. package/.output/public/_nuxt/CTGJHZ8X2.js +1 -0
  27. package/.output/public/_nuxt/CWcaJnFp.js +1 -0
  28. package/.output/public/_nuxt/CYLe9LKr.js +1 -0
  29. package/.output/public/_nuxt/CeCSjB9O2.js +1 -0
  30. package/.output/public/_nuxt/CnoJJb7B.js +1 -0
  31. package/.output/public/_nuxt/Crf8_Ad02.js +1 -0
  32. package/.output/public/_nuxt/CtMTOx_-2.js +1 -0
  33. package/.output/public/_nuxt/Cv9OcYm3.js +1 -0
  34. package/.output/public/_nuxt/CxIF09Zj2.js +1 -0
  35. package/.output/public/_nuxt/CxR0TyUA.js +1 -0
  36. package/.output/public/_nuxt/D9tNM-1a.js +9 -0
  37. package/.output/public/_nuxt/DL8QM0x5.js +1 -0
  38. package/.output/public/_nuxt/DO9Y3eoU.js +20 -0
  39. package/.output/public/_nuxt/DQLBGo6O.js +1 -0
  40. package/.output/public/_nuxt/DSqQKrMK2.js +1 -0
  41. package/.output/public/_nuxt/DXc4yISs.js +47 -0
  42. package/.output/public/_nuxt/DXmEuVFQ2.js +1 -0
  43. package/.output/public/_nuxt/DeXAMdSa2.js +1 -0
  44. package/.output/public/_nuxt/DjjOAXrj2.js +1 -0
  45. package/.output/public/_nuxt/DkRozlDP2.js +1 -0
  46. package/.output/public/_nuxt/DoprKJ5a2.js +1 -0
  47. package/.output/public/_nuxt/DvI5fMX12.js +1 -0
  48. package/.output/public/_nuxt/DzWyfYJ12.js +2 -0
  49. package/.output/public/_nuxt/EXs4hr_w2.js +2 -0
  50. package/.output/public/_nuxt/K5Xen0wZ2.js +1 -0
  51. package/.output/public/_nuxt/LS9Wa05P.js +1 -0
  52. package/.output/public/_nuxt/MmlCf-EZ.js +1 -0
  53. package/.output/public/_nuxt/OmpTerminalPanel.DMWgGwDs.css +1 -0
  54. package/.output/public/_nuxt/PluginSlot.BqBzLD4T.css +1 -0
  55. package/.output/public/_nuxt/TownView.DQaU1HuK.css +1 -0
  56. package/.output/public/_nuxt/TugRY_4O.js +1 -0
  57. package/.output/public/_nuxt/UgCvr7b2.js +1 -0
  58. package/.output/public/_nuxt/WCG1-KXf2.js +16 -0
  59. package/.output/public/_nuxt/WybiLTow2.js +8 -0
  60. package/.output/public/_nuxt/YWsTLN5m.js +1 -0
  61. package/.output/public/_nuxt/Zn0BZpf0.js +3 -0
  62. package/.output/public/_nuxt/ZzOyoXex2.js +1 -0
  63. package/.output/public/_nuxt/_id_.Be5JaH-P.css +1 -0
  64. package/.output/public/_nuxt/_wsId_.DSOfdfx2.css +1 -0
  65. package/.output/public/_nuxt/agents.CRomddYR.css +1 -0
  66. package/.output/public/_nuxt/aml.DgOMpDpv.css +1 -0
  67. package/.output/public/_nuxt/builds/latest.json +1 -1
  68. package/.output/public/_nuxt/builds/meta/02ba4bc7-f353-4183-a619-716921b5f0dc.json +1 -0
  69. package/.output/public/_nuxt/default.CpAx70gC.css +1 -0
  70. package/.output/public/_nuxt/eNEgl-ZF.js +1 -0
  71. package/.output/public/_nuxt/entry.Buc3k7Ha.css +1 -0
  72. package/.output/public/_nuxt/fJv3DH8b.js +1 -0
  73. package/.output/public/_nuxt/hyLdZsOd2.js +1 -0
  74. package/.output/public/_nuxt/logs.6VGjPS34.css +1 -0
  75. package/.output/public/_nuxt/monitor.OoNTwfMJ.css +1 -0
  76. package/.output/public/_nuxt/o8sYG6xx2.js +1 -0
  77. package/.output/public/_nuxt/ontology.D4P756Tc.css +1 -0
  78. package/.output/public/_nuxt/operations.C48ggFa5.css +1 -0
  79. package/.output/public/_nuxt/pages.Dpa28tJW.css +1 -0
  80. package/.output/public/_nuxt/permissions.CrV-4t-6.css +1 -0
  81. package/.output/public/_nuxt/px0VQ09m.js +2 -0
  82. package/.output/public/_nuxt/schedules.DYWOjGHm.css +1 -0
  83. package/.output/public/_nuxt/teams.DEJoJ4QV.css +1 -0
  84. package/.output/public/_nuxt/tokens.DKZWCP5v.css +1 -0
  85. package/.output/public/_nuxt/tools.DP-nsTli.css +1 -0
  86. package/.output/public/_nuxt/workshop.PT1xhP8C.css +1 -0
  87. package/.output/public/favicon.svg +14 -14
  88. package/.output/public/robots.txt +3 -3
  89. package/.output/server/chunks/_/AuthGate-G74Wr5IV.mjs +716 -0
  90. package/.output/server/chunks/_/AuthGate-G74Wr5IV.mjs.map +1 -0
  91. package/.output/server/chunks/_/FormItemContext-DmuQqaeJ.mjs +72 -0
  92. package/.output/server/chunks/_/FormItemContext-DmuQqaeJ.mjs.map +1 -0
  93. package/.output/server/chunks/_/LeftOutlined.mjs.map +1 -1
  94. package/.output/server/chunks/_/OmpTerminalPanel-CVn7GF98.mjs +942 -0
  95. package/.output/server/chunks/_/OmpTerminalPanel-CVn7GF98.mjs.map +1 -0
  96. package/.output/server/chunks/_/PluginSlot-CZlGlRoR.mjs +141 -0
  97. package/.output/server/chunks/_/PluginSlot-CZlGlRoR.mjs.map +1 -0
  98. package/.output/server/chunks/_/RightOutlined.mjs.map +1 -1
  99. package/.output/server/chunks/_/SearchOutlined.mjs +13 -13
  100. package/.output/server/chunks/_/SearchOutlined.mjs.map +1 -1
  101. package/.output/server/chunks/_/TownView-CaxNtCrZ.mjs +6496 -0
  102. package/.output/server/chunks/_/TownView-CaxNtCrZ.mjs.map +1 -0
  103. package/.output/server/chunks/_/_id_-CvCH8aqA.mjs +2045 -0
  104. package/.output/server/chunks/_/_id_-CvCH8aqA.mjs.map +1 -0
  105. package/.output/server/chunks/_/_id_-X_k47fyM.mjs +392 -0
  106. package/.output/server/chunks/_/_id_-X_k47fyM.mjs.map +1 -0
  107. package/.output/server/chunks/_/_wsId_-CIXvt220.mjs +14589 -0
  108. package/.output/server/chunks/_/_wsId_-CIXvt220.mjs.map +1 -0
  109. package/.output/server/chunks/_/access.mjs +1 -1
  110. package/.output/server/chunks/_/agent-dto.mjs +26 -0
  111. package/.output/server/chunks/_/agent-dto.mjs.map +1 -0
  112. package/.output/server/chunks/_/agents-Bipi0xxl.mjs +1078 -0
  113. package/.output/server/chunks/_/agents-Bipi0xxl.mjs.map +1 -0
  114. package/.output/server/chunks/_/alert-CNGhs--Y.mjs +263 -0
  115. package/.output/server/chunks/_/alert-CNGhs--Y.mjs.map +1 -0
  116. package/.output/server/chunks/_/aml-gCTIxLoE.mjs +814 -0
  117. package/.output/server/chunks/_/aml-gCTIxLoE.mjs.map +1 -0
  118. package/.output/server/chunks/_/analysis-BrSFajFi.mjs +533 -0
  119. package/.output/server/chunks/_/analysis-BrSFajFi.mjs.map +1 -0
  120. package/.output/server/chunks/_/api--f4L9O86.mjs +64 -0
  121. package/.output/server/chunks/_/api--f4L9O86.mjs.map +1 -0
  122. package/.output/server/chunks/_/api-CRGCw6io.mjs +53 -0
  123. package/.output/server/chunks/_/api-CRGCw6io.mjs.map +1 -0
  124. package/.output/server/chunks/_/api-DKutH26K.mjs +72 -0
  125. package/.output/server/chunks/_/api-DKutH26K.mjs.map +1 -0
  126. package/.output/server/chunks/_/api-error-BrL8jXVC.mjs +47 -0
  127. package/.output/server/chunks/_/api-error-BrL8jXVC.mjs.map +1 -0
  128. package/.output/server/chunks/_/apiClient-DrCvj3Zb.mjs +81 -0
  129. package/.output/server/chunks/_/apiClient-DrCvj3Zb.mjs.map +1 -0
  130. package/.output/server/chunks/_/binding-authz.mjs +4 -1
  131. package/.output/server/chunks/_/binding-authz.mjs.map +1 -1
  132. package/.output/server/chunks/_/board-DB55AvRS.mjs +189 -0
  133. package/.output/server/chunks/_/board-DB55AvRS.mjs.map +1 -0
  134. package/.output/server/chunks/_/builtin-catalog-edpDcgfL.mjs.map +1 -0
  135. package/.output/server/chunks/_/card-BECE6y_G.mjs +953 -0
  136. package/.output/server/chunks/_/card-BECE6y_G.mjs.map +1 -0
  137. package/.output/server/chunks/_/channel-templates-C0Njk-Ir.mjs +942 -0
  138. package/.output/server/chunks/_/channel-templates-C0Njk-Ir.mjs.map +1 -0
  139. package/.output/server/chunks/_/chart-pipeline-BpoWYMK_.mjs.map +1 -0
  140. package/.output/server/chunks/_/chart-trend-BWeZh5Lv.mjs.map +1 -0
  141. package/.output/server/chunks/_/checkbox-C6xY5uc6.mjs +439 -0
  142. package/.output/server/chunks/_/checkbox-C6xY5uc6.mjs.map +1 -0
  143. package/.output/server/chunks/_/client-only-DQ6Q0w4J.mjs +43 -0
  144. package/.output/server/chunks/_/client-only-DQ6Q0w4J.mjs.map +1 -0
  145. package/.output/server/chunks/_/constants-HPHJvjne.mjs +142 -0
  146. package/.output/server/chunks/_/constants-HPHJvjne.mjs.map +1 -0
  147. package/.output/server/chunks/_/core-CRlsQhzd.mjs +294 -0
  148. package/.output/server/chunks/_/core-CRlsQhzd.mjs.map +1 -0
  149. package/.output/server/chunks/_/daq-VLM0Ud2Y.mjs +1266 -0
  150. package/.output/server/chunks/_/daq-VLM0Ud2Y.mjs.map +1 -0
  151. package/.output/server/chunks/_/data-Bgx_w04W.mjs +481 -0
  152. package/.output/server/chunks/_/data-Bgx_w04W.mjs.map +1 -0
  153. package/.output/server/chunks/_/data-export.mjs +6 -6
  154. package/.output/server/chunks/_/data-query.mjs +3 -3
  155. package/.output/server/chunks/_/dcw-BstEJzQ4.mjs +505 -0
  156. package/.output/server/chunks/_/dcw-BstEJzQ4.mjs.map +1 -0
  157. package/.output/server/chunks/_/dcw-driver-badge-Df5wL_ZA.mjs.map +1 -0
  158. package/.output/server/chunks/_/default-Dmo-rt5V.mjs +2353 -0
  159. package/.output/server/chunks/_/default-Dmo-rt5V.mjs.map +1 -0
  160. package/.output/server/chunks/_/descriptions-B3uhDesi.mjs +406 -0
  161. package/.output/server/chunks/_/descriptions-B3uhDesi.mjs.map +1 -0
  162. package/.output/server/chunks/_/drawer-DwXxapMg.mjs +834 -0
  163. package/.output/server/chunks/_/drawer-DwXxapMg.mjs.map +1 -0
  164. package/.output/server/chunks/_/dropdown-DLrGy-Fs.mjs +14 -0
  165. package/.output/server/chunks/_/dropdown-DLrGy-Fs.mjs.map +1 -0
  166. package/.output/server/chunks/_/dropdown-nsGv8Gqx.mjs +540 -0
  167. package/.output/server/chunks/_/dropdown-nsGv8Gqx.mjs.map +1 -0
  168. package/.output/server/chunks/_/eda-run.repo.mjs +2 -2
  169. package/.output/server/chunks/_/entity.mjs +1 -1
  170. package/.output/server/chunks/_/error-500.mjs.map +1 -1
  171. package/.output/server/chunks/_/es-DXSEkmAm.mjs +43 -0
  172. package/.output/server/chunks/_/es-DXSEkmAm.mjs.map +1 -0
  173. package/.output/server/chunks/_/features.mjs +5 -5
  174. package/.output/server/chunks/_/firstNotUndefined-laiThpLD.mjs +2448 -0
  175. package/.output/server/chunks/_/firstNotUndefined-laiThpLD.mjs.map +1 -0
  176. package/.output/server/chunks/_/form-Cw2Ex9w5.mjs +4712 -0
  177. package/.output/server/chunks/_/form-Cw2Ex9w5.mjs.map +1 -0
  178. package/.output/server/chunks/_/golden.mjs +3 -3
  179. package/.output/server/chunks/_/harness-spawn-policy.mjs +77 -0
  180. package/.output/server/chunks/_/harness-spawn-policy.mjs.map +1 -0
  181. package/.output/server/chunks/_/hasIn-RYRGomyg.mjs +553 -0
  182. package/.output/server/chunks/_/hasIn-RYRGomyg.mjs.map +1 -0
  183. package/.output/server/chunks/_/hitl-CQowkJ6s.mjs +132 -0
  184. package/.output/server/chunks/_/hitl-CQowkJ6s.mjs.map +1 -0
  185. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  186. package/.output/server/chunks/_/index.mjs +1 -1
  187. package/.output/server/chunks/_/input-CJgB-RL6.mjs +2181 -0
  188. package/.output/server/chunks/_/input-CJgB-RL6.mjs.map +1 -0
  189. package/.output/server/chunks/_/input-number-CQKL42p_.mjs +1120 -0
  190. package/.output/server/chunks/_/input-number-CQKL42p_.mjs.map +1 -0
  191. package/.output/server/chunks/_/interval-CfceaI3F.mjs +9 -0
  192. package/.output/server/chunks/_/interval-CfceaI3F.mjs.map +1 -0
  193. package/.output/server/chunks/_/isNumeric-DQiJ-b15.mjs +7 -0
  194. package/.output/server/chunks/_/isNumeric-DQiJ-b15.mjs.map +1 -0
  195. package/.output/server/chunks/_/line-scope.mjs +32 -0
  196. package/.output/server/chunks/_/line-scope.mjs.map +1 -0
  197. package/.output/server/chunks/_/logs-Dt4ejjjU.mjs +492 -0
  198. package/.output/server/chunks/_/logs-Dt4ejjjU.mjs.map +1 -0
  199. package/.output/server/chunks/_/menu-xO8ocVtL.mjs +1952 -0
  200. package/.output/server/chunks/_/menu-xO8ocVtL.mjs.map +1 -0
  201. package/.output/server/chunks/_/mes-console.mjs +1 -1
  202. package/.output/server/chunks/_/monitor-vqmGVVN5.mjs +2253 -0
  203. package/.output/server/chunks/_/monitor-vqmGVVN5.mjs.map +1 -0
  204. package/.output/server/chunks/_/narrow-fetch-CcG-BPxc.mjs.map +1 -0
  205. package/.output/server/chunks/_/nitro.mjs +4416 -3477
  206. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  207. package/.output/server/chunks/_/ocap.mjs +1 -1
  208. package/.output/server/chunks/_/ontology-ih0HgPpL.mjs +1406 -0
  209. package/.output/server/chunks/_/ontology-ih0HgPpL.mjs.map +1 -0
  210. package/.output/server/chunks/_/operations-BHmdVOUk.mjs +311 -0
  211. package/.output/server/chunks/_/operations-BHmdVOUk.mjs.map +1 -0
  212. package/.output/server/chunks/_/optimizer-DyvIYE4A.mjs +202 -0
  213. package/.output/server/chunks/_/optimizer-DyvIYE4A.mjs.map +1 -0
  214. package/.output/server/chunks/_/pages-C2KTn0U1.mjs +542 -0
  215. package/.output/server/chunks/_/pages-C2KTn0U1.mjs.map +1 -0
  216. package/.output/server/chunks/_/pagination-BTzq7dD5.mjs +1346 -0
  217. package/.output/server/chunks/_/pagination-BTzq7dD5.mjs.map +1 -0
  218. package/.output/server/chunks/_/permissions-BbTI02WI.mjs +637 -0
  219. package/.output/server/chunks/_/permissions-BbTI02WI.mjs.map +1 -0
  220. package/.output/server/chunks/_/pipeline-BgNjQ4J3.mjs +212 -0
  221. package/.output/server/chunks/_/pipeline-BgNjQ4J3.mjs.map +1 -0
  222. package/.output/server/chunks/_/plugins-CplEv3mY.mjs +272 -0
  223. package/.output/server/chunks/_/plugins-CplEv3mY.mjs.map +1 -0
  224. package/.output/server/chunks/_/popconfirm-DuGF7ty-.mjs +340 -0
  225. package/.output/server/chunks/_/popconfirm-DuGF7ty-.mjs.map +1 -0
  226. package/.output/server/chunks/_/responsiveObserve-CzRpNXkr.mjs +78 -0
  227. package/.output/server/chunks/_/responsiveObserve-CzRpNXkr.mjs.map +1 -0
  228. package/.output/server/chunks/_/rest-auth.mjs +1 -1
  229. package/.output/server/chunks/_/schedules-BN4t_4PG.mjs +7172 -0
  230. package/.output/server/chunks/_/schedules-BN4t_4PG.mjs.map +1 -0
  231. package/.output/server/chunks/_/segmented-29uEKZ3D.mjs +341 -0
  232. package/.output/server/chunks/_/segmented-29uEKZ3D.mjs.map +1 -0
  233. package/.output/server/chunks/_/select-CJb2XrQf.mjs +3923 -0
  234. package/.output/server/chunks/_/select-CJb2XrQf.mjs.map +1 -0
  235. package/.output/server/chunks/_/settings-BQaAoT4q.mjs +1014 -0
  236. package/.output/server/chunks/_/settings-BQaAoT4q.mjs.map +1 -0
  237. package/.output/server/chunks/_/space-BByD-mFE.mjs +110 -0
  238. package/.output/server/chunks/_/space-BByD-mFE.mjs.map +1 -0
  239. package/.output/server/chunks/_/spc.mjs +1 -1
  240. package/.output/server/chunks/_/spin-XhbgGeLP.mjs +357 -0
  241. package/.output/server/chunks/_/spin-XhbgGeLP.mjs.map +1 -0
  242. package/.output/server/chunks/_/studio-D5r5Rzaq.mjs +336 -0
  243. package/.output/server/chunks/_/studio-D5r5Rzaq.mjs.map +1 -0
  244. package/.output/server/chunks/_/switch-DWcwVFxW.mjs +377 -0
  245. package/.output/server/chunks/_/switch-DWcwVFxW.mjs.map +1 -0
  246. package/.output/server/chunks/_/table-Zhuo7Fq-.mjs +7546 -0
  247. package/.output/server/chunks/_/table-Zhuo7Fq-.mjs.map +1 -0
  248. package/.output/server/chunks/_/tabs-BCwBXjNt.mjs +1924 -0
  249. package/.output/server/chunks/_/tabs-BCwBXjNt.mjs.map +1 -0
  250. package/.output/server/chunks/_/tag-CRW-anwy.mjs +1156 -0
  251. package/.output/server/chunks/_/tag-CRW-anwy.mjs.map +1 -0
  252. package/.output/server/chunks/_/teams-BUtsNTet.mjs +1203 -0
  253. package/.output/server/chunks/_/teams-BUtsNTet.mjs.map +1 -0
  254. package/.output/server/chunks/_/tokens-o8lT3x-p.mjs +1062 -0
  255. package/.output/server/chunks/_/tokens-o8lT3x-p.mjs.map +1 -0
  256. package/.output/server/chunks/_/tools-DRb5HTtU.mjs +487 -0
  257. package/.output/server/chunks/_/tools-DRb5HTtU.mjs.map +1 -0
  258. package/.output/server/chunks/_/tooltip-GlMrUZzx.mjs +920 -0
  259. package/.output/server/chunks/_/tooltip-GlMrUZzx.mjs.map +1 -0
  260. package/.output/server/chunks/_/town-BPA3G6yX.mjs +133 -0
  261. package/.output/server/chunks/_/town-BPA3G6yX.mjs.map +1 -0
  262. package/.output/server/chunks/_/town-BV-hbwb5.mjs +75 -0
  263. package/.output/server/chunks/_/town-BV-hbwb5.mjs.map +1 -0
  264. package/.output/server/chunks/_/types-D6J7slEa.mjs +5565 -0
  265. package/.output/server/chunks/_/types-D6J7slEa.mjs.map +1 -0
  266. package/.output/server/chunks/_/types-DWqIeMRP.mjs +76 -0
  267. package/.output/server/chunks/_/types-DWqIeMRP.mjs.map +1 -0
  268. package/.output/server/chunks/_/useAgentHarnessOptions-dDHiEoK2.mjs +124 -0
  269. package/.output/server/chunks/_/useAgentHarnessOptions-dDHiEoK2.mjs.map +1 -0
  270. package/.output/server/chunks/_/useAgentTemplateActions-S3dtH5UW.mjs +77 -0
  271. package/.output/server/chunks/_/useAgentTemplateActions-S3dtH5UW.mjs.map +1 -0
  272. package/.output/server/chunks/_/useAgentTemplateDialogState-CZzpu5og.mjs +67 -0
  273. package/.output/server/chunks/_/useAgentTemplateDialogState-CZzpu5og.mjs.map +1 -0
  274. package/.output/server/chunks/_/useAgentTemplateForm-D8gneIvd.mjs +117 -0
  275. package/.output/server/chunks/_/useAgentTemplateForm-D8gneIvd.mjs.map +1 -0
  276. package/.output/server/chunks/_/useAgentTemplatesCatalog-DHUpubKM.mjs +133 -0
  277. package/.output/server/chunks/_/useAgentTemplatesCatalog-DHUpubKM.mjs.map +1 -0
  278. package/.output/server/chunks/_/useAmlDatasets-CDg3Qbpv.mjs +92 -0
  279. package/.output/server/chunks/_/useAmlDatasets-CDg3Qbpv.mjs.map +1 -0
  280. package/.output/server/chunks/_/useAmlEntities-Bcaput4Y.mjs +86 -0
  281. package/.output/server/chunks/_/useAmlEntities-Bcaput4Y.mjs.map +1 -0
  282. package/.output/server/chunks/_/useAmlEnv-Dga_Nq6z.mjs +194 -0
  283. package/.output/server/chunks/_/useAmlEnv-Dga_Nq6z.mjs.map +1 -0
  284. package/.output/server/chunks/_/useAmlExperiments-CFngqLM3.mjs +89 -0
  285. package/.output/server/chunks/_/useAmlExperiments-CFngqLM3.mjs.map +1 -0
  286. package/.output/server/chunks/_/useAmlFormat-C2sl3MGB.mjs +82 -0
  287. package/.output/server/chunks/_/useAmlFormat-C2sl3MGB.mjs.map +1 -0
  288. package/.output/server/chunks/_/useAmlJobs-C7onZkcR.mjs +267 -0
  289. package/.output/server/chunks/_/useAmlJobs-C7onZkcR.mjs.map +1 -0
  290. package/.output/server/chunks/_/useAmlModels-B2b3mx4d.mjs +93 -0
  291. package/.output/server/chunks/_/useAmlModels-B2b3mx4d.mjs.map +1 -0
  292. package/.output/server/chunks/_/useAmlNotes-6gZX7tbx.mjs +86 -0
  293. package/.output/server/chunks/_/useAmlNotes-6gZX7tbx.mjs.map +1 -0
  294. package/.output/server/chunks/_/useAmlPredict-DwOmM2ke.mjs +130 -0
  295. package/.output/server/chunks/_/useAmlPredict-DwOmM2ke.mjs.map +1 -0
  296. package/.output/server/chunks/_/useAnalysisFeed-CpPsKh_I.mjs +129 -0
  297. package/.output/server/chunks/_/useAnalysisFeed-CpPsKh_I.mjs.map +1 -0
  298. package/.output/server/chunks/_/useDaqAddNode-QtJja03_.mjs +142 -0
  299. package/.output/server/chunks/_/useDaqAddNode-QtJja03_.mjs.map +1 -0
  300. package/.output/server/chunks/_/useDaqDetailBinding-Dd5c4bep.mjs +70 -0
  301. package/.output/server/chunks/_/useDaqDetailBinding-Dd5c4bep.mjs.map +1 -0
  302. package/.output/server/chunks/_/useDaqDetailFrames-C2gvrOr6.mjs +79 -0
  303. package/.output/server/chunks/_/useDaqDetailFrames-C2gvrOr6.mjs.map +1 -0
  304. package/.output/server/chunks/_/useDaqDetailHistory-Bhht_iFw.mjs +176 -0
  305. package/.output/server/chunks/_/useDaqDetailHistory-Bhht_iFw.mjs.map +1 -0
  306. package/.output/server/chunks/_/useDaqDetailNode-BayXtr5W.mjs +99 -0
  307. package/.output/server/chunks/_/useDaqDetailNode-BayXtr5W.mjs.map +1 -0
  308. package/.output/server/chunks/_/useDaqDetailParams-D8d1l3_R.mjs +159 -0
  309. package/.output/server/chunks/_/useDaqDetailParams-D8d1l3_R.mjs.map +1 -0
  310. package/.output/server/chunks/_/useDaqFilters-TYucwywj.mjs +222 -0
  311. package/.output/server/chunks/_/useDaqFilters-TYucwywj.mjs.map +1 -0
  312. package/.output/server/chunks/_/useDaqNodeWindow-1DWj2H5G.mjs +90 -0
  313. package/.output/server/chunks/_/useDaqNodeWindow-1DWj2H5G.mjs.map +1 -0
  314. package/.output/server/chunks/_/useDaqOptimizations-o5hubsm8.mjs +136 -0
  315. package/.output/server/chunks/_/useDaqOptimizations-o5hubsm8.mjs.map +1 -0
  316. package/.output/server/chunks/_/useDaqStream-BCTOU87S.mjs +395 -0
  317. package/.output/server/chunks/_/useDaqStream-BCTOU87S.mjs.map +1 -0
  318. package/.output/server/chunks/_/useDaqTemplates-Fj64LHfn.mjs +187 -0
  319. package/.output/server/chunks/_/useDaqTemplates-Fj64LHfn.mjs.map +1 -0
  320. package/.output/server/chunks/_/useDashboardCharts-D45083s_.mjs +354 -0
  321. package/.output/server/chunks/_/useDashboardCharts-D45083s_.mjs.map +1 -0
  322. package/.output/server/chunks/_/useDashboardData-Cm_-daeI.mjs +153 -0
  323. package/.output/server/chunks/_/useDashboardData-Cm_-daeI.mjs.map +1 -0
  324. package/.output/server/chunks/_/useDcwAddNode-DaqIQSXN.mjs +219 -0
  325. package/.output/server/chunks/_/useDcwAddNode-DaqIQSXN.mjs.map +1 -0
  326. package/.output/server/chunks/_/useDcwCards-OhzgHbAI.mjs +67 -0
  327. package/.output/server/chunks/_/useDcwCards-OhzgHbAI.mjs.map +1 -0
  328. package/.output/server/chunks/_/useDcwDetailScope-CaWcaiBg.mjs +184 -0
  329. package/.output/server/chunks/_/useDcwDetailScope-CaWcaiBg.mjs.map +1 -0
  330. package/.output/server/chunks/_/useDcwDetailTemplates-CrOgqQMX.mjs +148 -0
  331. package/.output/server/chunks/_/useDcwDetailTemplates-CrOgqQMX.mjs.map +1 -0
  332. package/.output/server/chunks/_/useDcwFilter-RH511Ra2.mjs +71 -0
  333. package/.output/server/chunks/_/useDcwFilter-RH511Ra2.mjs.map +1 -0
  334. package/.output/server/chunks/_/useDcwLedger-Dg61GD1J.mjs +79 -0
  335. package/.output/server/chunks/_/useDcwLedger-Dg61GD1J.mjs.map +1 -0
  336. package/.output/server/chunks/_/useDcwLineMutations-CiurWUFF.mjs +137 -0
  337. package/.output/server/chunks/_/useDcwLineMutations-CiurWUFF.mjs.map +1 -0
  338. package/.output/server/chunks/_/useDcwLineRun-DTSemEZb.mjs +104 -0
  339. package/.output/server/chunks/_/useDcwLineRun-DTSemEZb.mjs.map +1 -0
  340. package/.output/server/chunks/_/useDcwParamApprovals-DpnD-yw0.mjs +121 -0
  341. package/.output/server/chunks/_/useDcwParamApprovals-DpnD-yw0.mjs.map +1 -0
  342. package/.output/server/chunks/_/useDcwProducts-CRAl59cn.mjs +93 -0
  343. package/.output/server/chunks/_/useDcwProducts-CRAl59cn.mjs.map +1 -0
  344. package/.output/server/chunks/_/useDcwQuery-Cyh_iGa9.mjs +98 -0
  345. package/.output/server/chunks/_/useDcwQuery-Cyh_iGa9.mjs.map +1 -0
  346. package/.output/server/chunks/_/useDcwQuickActions-BW5-5HFn.mjs +88 -0
  347. package/.output/server/chunks/_/useDcwQuickActions-BW5-5HFn.mjs.map +1 -0
  348. package/.output/server/chunks/_/useDcwRecipes-Ct9bWJwP.mjs +258 -0
  349. package/.output/server/chunks/_/useDcwRecipes-Ct9bWJwP.mjs.map +1 -0
  350. package/.output/server/chunks/_/useDcwStream-BerzMqxo.mjs +455 -0
  351. package/.output/server/chunks/_/useDcwStream-BerzMqxo.mjs.map +1 -0
  352. package/.output/server/chunks/_/useDcwTemplates-PMVeSLNP.mjs +91 -0
  353. package/.output/server/chunks/_/useDcwTemplates-PMVeSLNP.mjs.map +1 -0
  354. package/.output/server/chunks/_/useDcwWrites-CND_sZdb.mjs +140 -0
  355. package/.output/server/chunks/_/useDcwWrites-CND_sZdb.mjs.map +1 -0
  356. package/.output/server/chunks/_/useDeviceTwins-FB6rTm-6.mjs +128 -0
  357. package/.output/server/chunks/_/useDeviceTwins-FB6rTm-6.mjs.map +1 -0
  358. package/.output/server/chunks/_/useExpConfirmations-b0bE75Yq.mjs +107 -0
  359. package/.output/server/chunks/_/useExpConfirmations-b0bE75Yq.mjs.map +1 -0
  360. package/.output/server/chunks/_/useLocalTime-BJ_4vg1E.mjs +55 -0
  361. package/.output/server/chunks/_/useLocalTime-BJ_4vg1E.mjs.map +1 -0
  362. package/.output/server/chunks/_/useLogsFormat-B-o4MHy7.mjs +77 -0
  363. package/.output/server/chunks/_/useLogsFormat-B-o4MHy7.mjs.map +1 -0
  364. package/.output/server/chunks/_/useLogsManual-Cxka55hz.mjs +89 -0
  365. package/.output/server/chunks/_/useLogsManual-Cxka55hz.mjs.map +1 -0
  366. package/.output/server/chunks/_/useLogsQuery-DxMHc7M4.mjs +150 -0
  367. package/.output/server/chunks/_/useLogsQuery-DxMHc7M4.mjs.map +1 -0
  368. package/.output/server/chunks/_/useLogsScope-HuOiW-OR.mjs +83 -0
  369. package/.output/server/chunks/_/useLogsScope-HuOiW-OR.mjs.map +1 -0
  370. package/.output/server/chunks/_/useMonitorColumns-vVnt3r5Q.mjs +217 -0
  371. package/.output/server/chunks/_/useMonitorColumns-vVnt3r5Q.mjs.map +1 -0
  372. package/.output/server/chunks/_/useMonitorData-Bf3w2khj.mjs +135 -0
  373. package/.output/server/chunks/_/useMonitorData-Bf3w2khj.mjs.map +1 -0
  374. package/.output/server/chunks/_/useMonitorFormat-DsiVqWoa.mjs +91 -0
  375. package/.output/server/chunks/_/useMonitorFormat-DsiVqWoa.mjs.map +1 -0
  376. package/.output/server/chunks/_/useMonitorTerminal-Dj4QwRNW.mjs +71 -0
  377. package/.output/server/chunks/_/useMonitorTerminal-Dj4QwRNW.mjs.map +1 -0
  378. package/.output/server/chunks/_/useOperationsFeed-Bg35fcgt.mjs +195 -0
  379. package/.output/server/chunks/_/useOperationsFeed-Bg35fcgt.mjs.map +1 -0
  380. package/.output/server/chunks/_/useOpsLog-BEzBrMf4.mjs +149 -0
  381. package/.output/server/chunks/_/useOpsLog-BEzBrMf4.mjs.map +1 -0
  382. package/.output/server/chunks/_/useRecipeDispatchApprovals-CZfcMRYk.mjs +156 -0
  383. package/.output/server/chunks/_/useRecipeDispatchApprovals-CZfcMRYk.mjs.map +1 -0
  384. package/.output/server/chunks/_/useResponsive-BKDMGTHs.mjs.map +1 -0
  385. package/.output/server/chunks/_/useTeamActions-CmiuiQiG.mjs +79 -0
  386. package/.output/server/chunks/_/useTeamActions-CmiuiQiG.mjs.map +1 -0
  387. package/.output/server/chunks/_/useTeamAddMemberDialog-CMpzf0jO.mjs +84 -0
  388. package/.output/server/chunks/_/useTeamAddMemberDialog-CMpzf0jO.mjs.map +1 -0
  389. package/.output/server/chunks/_/useTeamCreateDialog-BnvjXWso.mjs +97 -0
  390. package/.output/server/chunks/_/useTeamCreateDialog-BnvjXWso.mjs.map +1 -0
  391. package/.output/server/chunks/_/useTeamDeployDialog-C0FOUYep.mjs +80 -0
  392. package/.output/server/chunks/_/useTeamDeployDialog-C0FOUYep.mjs.map +1 -0
  393. package/.output/server/chunks/_/useTeamDialogState-CFRUQxAf.mjs +82 -0
  394. package/.output/server/chunks/_/useTeamDialogState-CFRUQxAf.mjs.map +1 -0
  395. package/.output/server/chunks/_/useTeamPluginDialog-Do-07a47.mjs +103 -0
  396. package/.output/server/chunks/_/useTeamPluginDialog-Do-07a47.mjs.map +1 -0
  397. package/.output/server/chunks/_/useTeamsCatalog-ClG_gBI8.mjs +123 -0
  398. package/.output/server/chunks/_/useTeamsCatalog-ClG_gBI8.mjs.map +1 -0
  399. package/.output/server/chunks/_/useTokenClipboard-CwQpoFeP.mjs +72 -0
  400. package/.output/server/chunks/_/useTokenClipboard-CwQpoFeP.mjs.map +1 -0
  401. package/.output/server/chunks/_/useTokenCreate-C4g5eKd3.mjs +115 -0
  402. package/.output/server/chunks/_/useTokenCreate-C4g5eKd3.mjs.map +1 -0
  403. package/.output/server/chunks/_/useTokenRename-ClWrxpNk.mjs +87 -0
  404. package/.output/server/chunks/_/useTokenRename-ClWrxpNk.mjs.map +1 -0
  405. package/.output/server/chunks/_/useTokenReveal-C8n1Vt9t.mjs +118 -0
  406. package/.output/server/chunks/_/useTokenReveal-C8n1Vt9t.mjs.map +1 -0
  407. package/.output/server/chunks/_/useTokensList-CgiH2W1C.mjs +92 -0
  408. package/.output/server/chunks/_/useTokensList-CgiH2W1C.mjs.map +1 -0
  409. package/.output/server/chunks/_/useTownBus-D9SoIsAN.mjs.map +1 -0
  410. package/.output/server/chunks/_/useWorkbenchAuth-DSstfK5Z.mjs +141 -0
  411. package/.output/server/chunks/_/useWorkbenchAuth-DSstfK5Z.mjs.map +1 -0
  412. package/.output/server/chunks/_/useWorkbenchWorkspaces-l_0SUOzn.mjs +138 -0
  413. package/.output/server/chunks/_/useWorkbenchWorkspaces-l_0SUOzn.mjs.map +1 -0
  414. package/.output/server/chunks/_/useWorkshopApi-Bqe2FlsB.mjs +127 -0
  415. package/.output/server/chunks/_/useWorkshopApi-Bqe2FlsB.mjs.map +1 -0
  416. package/.output/server/chunks/_/useWorkshopWs-DP4MbZsb.mjs +1659 -0
  417. package/.output/server/chunks/_/useWorkshopWs-DP4MbZsb.mjs.map +1 -0
  418. package/.output/server/chunks/_/useWorkspaceAuth-CzDigJGl.mjs +60 -0
  419. package/.output/server/chunks/_/useWorkspaceAuth-CzDigJGl.mjs.map +1 -0
  420. package/.output/server/chunks/_/useWorkspaceChannels-BLtsS6-m.mjs +92 -0
  421. package/.output/server/chunks/_/useWorkspaceChannels-BLtsS6-m.mjs.map +1 -0
  422. package/.output/server/chunks/_/useWorkspacePanels-CTwREmq0.mjs +78 -0
  423. package/.output/server/chunks/_/useWorkspacePanels-CTwREmq0.mjs.map +1 -0
  424. package/.output/server/chunks/_/useWorkspaceShell-rQHWNNWJ.mjs +168 -0
  425. package/.output/server/chunks/_/useWorkspaceShell-rQHWNNWJ.mjs.map +1 -0
  426. package/.output/server/chunks/_/users-BM1ZzxPp.mjs +569 -0
  427. package/.output/server/chunks/_/users-BM1ZzxPp.mjs.map +1 -0
  428. package/.output/server/chunks/_/workshop-CUXCV3RH.mjs +546 -0
  429. package/.output/server/chunks/_/workshop-CUXCV3RH.mjs.map +1 -0
  430. package/.output/server/chunks/_/workspaces-CmW0cpOt.mjs.map +1 -0
  431. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  432. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  433. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  434. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/grant.post.mjs +1 -1
  435. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/revoke.post.mjs +1 -1
  436. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  437. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
  438. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +36 -9
  439. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  440. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  441. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +1 -1
  442. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +1 -1
  443. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +3 -0
  444. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs.map +1 -1
  445. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +1 -1
  446. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +1 -1
  447. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +1 -1
  448. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +1 -1
  449. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +1 -1
  450. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +1 -1
  451. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +1 -1
  452. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +1 -1
  453. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +1 -1
  454. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +1 -1
  455. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +1 -1
  456. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +1 -1
  457. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +1 -1
  458. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +1 -1
  459. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +1 -1
  460. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +1 -1
  461. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +1 -1
  462. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +1 -1
  463. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +1 -1
  464. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +1 -1
  465. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +1 -1
  466. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +1 -1
  467. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +1 -1
  468. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +1 -1
  469. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +1 -1
  470. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +1 -1
  471. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +1 -1
  472. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +1 -1
  473. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +1 -1
  474. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +1 -1
  475. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +1 -1
  476. package/.output/server/chunks/routes/api/workshop/analysis/_id_.patch.mjs +1 -1
  477. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  478. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +6 -0
  479. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs.map +1 -1
  480. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +5 -0
  481. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  482. package/.output/server/chunks/routes/api/workshop/channels/_id/execution-mode.patch.mjs +1 -1
  483. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +5 -2
  484. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  485. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +7 -1
  486. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs.map +1 -1
  487. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  488. package/.output/server/chunks/routes/api/workshop/channels/_id/members/join.post.mjs +1 -1
  489. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  490. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +3 -1
  491. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  492. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +8 -6
  493. package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
  494. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -1
  495. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
  496. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -1
  497. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -1
  498. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs +29 -49
  499. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs.map +1 -1
  500. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  501. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
  502. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
  503. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +6 -1
  504. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  505. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -1
  506. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +4 -2
  507. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  508. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
  509. package/.output/server/chunks/routes/api/workshop/daq/index2.post.mjs +1 -1
  510. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +14 -5
  511. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  512. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  513. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  514. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  515. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +7 -4
  516. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  517. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  518. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  519. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +6 -2
  520. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  521. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +6 -2
  522. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
  523. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  524. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  525. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  526. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +6 -1
  527. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  528. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  529. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +7 -4
  530. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  531. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  532. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  533. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  534. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +6 -2
  535. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  536. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  537. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +7 -4
  538. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  539. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  540. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  541. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  542. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +7 -3
  543. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -1
  544. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  545. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  546. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  547. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  548. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  549. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  550. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +6 -2
  551. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs.map +1 -1
  552. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  553. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  554. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  555. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  556. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +6 -2
  557. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  558. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +4 -2
  559. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  560. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +5 -2
  561. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -1
  562. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  563. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  564. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  565. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  566. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  567. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  568. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  569. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +1 -1
  570. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  571. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +7 -3
  572. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
  573. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +8 -1
  574. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  575. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +1 -1
  576. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +6 -2
  577. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  578. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  579. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  580. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  581. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  582. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +7 -4
  583. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  584. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  585. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  586. package/.output/server/chunks/routes/api/workshop/eda/commonality.get.mjs +1 -1
  587. package/.output/server/chunks/routes/api/workshop/eda/index6.get.mjs +1 -1
  588. package/.output/server/chunks/routes/api/workshop/eda/index6.post.mjs +1 -1
  589. package/.output/server/chunks/routes/api/workshop/eda/vm/predict.post.mjs +1 -1
  590. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  591. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  592. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  593. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  594. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  595. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  596. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  597. package/.output/server/chunks/routes/api/workshop/index.mjs +1 -1
  598. package/.output/server/chunks/routes/api/workshop/index.post.mjs +2 -0
  599. package/.output/server/chunks/routes/api/workshop/index.post.mjs.map +1 -1
  600. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  601. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  602. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  603. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  604. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +8 -3
  605. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  606. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  607. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  608. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  609. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
  610. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  611. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +18 -6
  612. package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
  613. package/.output/server/chunks/routes/api/workshop/mes/datasets.get.mjs +1 -1
  614. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs +1 -1
  615. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs +1 -1
  616. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs +1 -1
  617. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs +1 -1
  618. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs +1 -1
  619. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs +1 -1
  620. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs +1 -1
  621. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs +1 -1
  622. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs +1 -1
  623. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs +1 -1
  624. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs +1 -1
  625. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs +1 -1
  626. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs +1 -1
  627. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs +1 -1
  628. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs +1 -1
  629. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs +1 -1
  630. package/.output/server/chunks/routes/api/workshop/optimization/capabilities.get.mjs +1 -1
  631. package/.output/server/chunks/routes/api/workshop/optimization/index.get.mjs +1 -1
  632. package/.output/server/chunks/routes/api/workshop/optimization/index.mjs +1 -1
  633. package/.output/server/chunks/routes/api/workshop/optimization/index2.mjs +1 -1
  634. package/.output/server/chunks/routes/api/workshop/optimization/profiles/_id/publish.post.mjs +1 -1
  635. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/crosscheck.post.mjs +1 -1
  636. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/dispatch.post.mjs +1 -1
  637. package/.output/server/chunks/routes/api/workshop/optimization/solve.post.mjs +1 -1
  638. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  639. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  640. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  641. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  642. package/.output/server/chunks/routes/api/workshop/process-model/experiments.mjs +1 -1
  643. package/.output/server/chunks/routes/api/workshop/process-model/index.mjs +1 -1
  644. package/.output/server/chunks/routes/api/workshop/process-model/specs/_id/publish.post.mjs +1 -1
  645. package/.output/server/chunks/routes/api/workshop/process-model/train.post.mjs +1 -1
  646. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  647. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  648. package/.output/server/chunks/routes/api/workshop/tools/sync.post.mjs +1 -1
  649. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  650. package/.output/server/chunks/routes/renderer.mjs +2 -2
  651. package/.output/server/chunks/routes/renderer.mjs.map +1 -1
  652. package/.output/server/chunks/virtual/entry.mjs +395 -377
  653. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  654. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  655. package/.output/server/chunks/virtual/precomputed.mjs.map +1 -1
  656. package/.output/server/index.mjs +1 -1
  657. package/.output/server/package.json +1 -1
  658. package/README-zh.md +5 -2
  659. package/README.md +14 -2
  660. package/app/components/AwLogo.vue +75 -75
  661. package/app/components/aml/AmlDatasetFormModal.vue +279 -279
  662. package/app/components/aml/AmlDatasetTable.vue +319 -319
  663. package/app/components/aml/AmlExperimentsTable.vue +142 -142
  664. package/app/components/aml/AmlInfraBanner.vue +23 -23
  665. package/app/components/aml/AmlJobsTable.vue +248 -248
  666. package/app/components/aml/AmlOverviewBar.vue +62 -62
  667. package/app/components/aml/AmlPageHeader.vue +47 -47
  668. package/app/components/aml/AmlPredictConsole.vue +201 -201
  669. package/app/components/app-header/HitlBell.vue +423 -423
  670. package/app/components/daq/DaqAddNodeModal.vue +209 -209
  671. package/app/components/daq/DaqAlarmBar.vue +46 -46
  672. package/app/components/daq/DaqControlCard.vue +159 -159
  673. package/app/components/daq/DaqInfraBanner.vue +31 -31
  674. package/app/components/daq/DaqLineBanner.vue +47 -47
  675. package/app/components/daq/DaqNodePanel.vue +396 -396
  676. package/app/components/daq/DaqOptPanel.vue +197 -197
  677. package/app/components/daq/DaqTemplateModal.vue +246 -246
  678. package/app/components/dashboard/DashboardGaugeBand.vue +78 -78
  679. package/app/components/dashboard/DashboardHero.vue +209 -209
  680. package/app/components/dashboard/DashboardLineStatePanel.vue +78 -78
  681. package/app/components/dashboard/DashboardNodeStatePanel.vue +46 -46
  682. package/app/components/dashboard/DashboardPipelinePanel.vue +46 -46
  683. package/app/components/dashboard/DashboardTrendPanel.vue +83 -83
  684. package/app/components/dashboard/DashboardWritePanel.vue +52 -52
  685. package/app/components/dcw/DcwCreateLineModal.vue +105 -105
  686. package/app/components/dcw/DcwDeleteLineModal.vue +73 -73
  687. package/app/components/dcw/DcwDetailTemplateModal.vue +238 -238
  688. package/app/components/dcw/DcwLedgerCard.vue +160 -160
  689. package/app/components/dcw/DcwMesArtifacts.vue +140 -140
  690. package/app/components/dcw/DcwProductCreateModal.vue +113 -113
  691. package/app/components/dcw/DcwRecipeDispatchHistoryModal.vue +244 -244
  692. package/app/components/dcw/DcwRecipeEditModal.vue +399 -399
  693. package/app/components/dcw/DcwRecipeHistoryModal.vue +165 -165
  694. package/app/components/dcw/DcwRunDataModal.vue +191 -191
  695. package/app/components/dcw/DcwTemplateModal.vue +227 -227
  696. package/app/components/dcw/DcwWriteHistoryCard.vue +96 -96
  697. package/app/components/dcw/ExpConfirmCard.vue +103 -103
  698. package/app/components/dcw/RecipeDispatchApprovalCard.vue +330 -330
  699. package/app/components/logs/LogsEventTable.vue +36 -3
  700. package/app/components/logs/LogsManualModal.vue +23 -1
  701. package/app/components/logs/LogsPageHead.vue +122 -71
  702. package/app/components/monitor/MonitorAgentTable.vue +143 -143
  703. package/app/components/monitor/MonitorChannelTable.vue +80 -80
  704. package/app/components/monitor/MonitorLoginGate.vue +24 -24
  705. package/app/components/monitor/MonitorPageHead.vue +92 -92
  706. package/app/components/monitor/MonitorProcessTable.vue +159 -159
  707. package/app/components/ontology/OntologyGraph.vue +356 -356
  708. package/app/components/operations/OperationsFilterCard.vue +164 -164
  709. package/app/components/operations/OperationsPageHead.vue +47 -47
  710. package/app/components/tokens/TokenCreateModal.vue +42 -42
  711. package/app/components/tokens/TokenOnceModal.vue +164 -164
  712. package/app/components/tokens/TokenRenameModal.vue +40 -40
  713. package/app/components/tokens/TokensPageHead.vue +76 -76
  714. package/app/components/workshop/A2aRpcDebugger.vue +237 -237
  715. package/app/components/workshop/AgentInspectorDrawer.vue +424 -424
  716. package/app/components/workshop/AgentLanesView.vue +278 -278
  717. package/app/components/workshop/ArtifactCard.vue +120 -120
  718. package/app/components/workshop/AssetLibrary.vue +452 -452
  719. package/app/components/workshop/ChatMemberPanel.vue +556 -556
  720. package/app/components/workshop/CommandPalette.vue +270 -270
  721. package/app/components/workshop/Composer.vue +540 -540
  722. package/app/components/workshop/DaqTemplateIcon.vue +33 -33
  723. package/app/components/workshop/DeviceTwinPanel.vue +167 -167
  724. package/app/components/workshop/FileSelectorModal.vue +188 -188
  725. package/app/components/workshop/InspectorPanel.vue +301 -301
  726. package/app/components/workshop/PluginSlot.vue +120 -120
  727. package/app/components/workshop/TranscriptTimeline.vue +223 -223
  728. package/app/components/workshop/agents/AgentTemplateEditModal.vue +139 -139
  729. package/app/components/workshop/blocks/ClusterArtifact.vue +61 -61
  730. package/app/components/workshop/blocks/ClusterError.vue +85 -85
  731. package/app/components/workshop/blocks/ClusterLife.vue +87 -87
  732. package/app/components/workshop/blocks/ClusterMember.vue +95 -95
  733. package/app/components/workshop/blocks/ClusterMemory.vue +84 -84
  734. package/app/components/workshop/blocks/ClusterOther.vue +67 -67
  735. package/app/components/workshop/blocks/ClusterStatus.vue +149 -149
  736. package/app/components/workshop/blocks/ClusterTool.vue +176 -176
  737. package/app/components/workshop/blocks/EventBlockAvatar.vue +114 -114
  738. package/app/components/workshop/blocks/EventBlockHead.vue +232 -232
  739. package/app/components/workshop/composer/ComposerToolbar.vue +278 -278
  740. package/app/components/workshop/composer/MentionMenu.vue +135 -135
  741. package/app/components/workshop/composer/ReplyChip.vue +65 -65
  742. package/app/components/workshop/composer/StatusChip.vue +171 -171
  743. package/app/components/workshop/console/Dock.vue +71 -71
  744. package/app/components/workshop/console/LeftPane.vue +84 -84
  745. package/app/components/workshop/device-twin/DeviceTwinCard.vue +265 -265
  746. package/app/components/workshop/device-twin/DeviceTwinDcwSection.vue +203 -203
  747. package/app/components/workshop/lanes/AddMemberModal.vue +270 -270
  748. package/app/components/workshop/lanes/EditMemberModal.vue +106 -106
  749. package/app/components/workshop/lanes/LanesToolbar.vue +97 -97
  750. package/app/components/workshop/session-list/MountChannelModal.vue +124 -124
  751. package/app/components/workshop/session-list/SaveTemplateModal.vue +93 -93
  752. package/app/components/workshop/task-board/Card.vue +172 -172
  753. package/app/components/workshop/task-board/Column.vue +151 -151
  754. package/app/components/workshop/task-board/List.vue +157 -157
  755. package/app/components/workshop/task-board/StatusMenu.vue +88 -88
  756. package/app/components/workshop/teams/TeamAddMemberModal.vue +53 -53
  757. package/app/components/workshop/teams/TeamCreateModal.vue +94 -94
  758. package/app/components/workshop/teams/TeamDeployModal.vue +40 -40
  759. package/app/components/workshop/teams/TeamPluginModal.vue +119 -119
  760. package/app/components/workshop/terminal/OmpTerminalPanel.vue +270 -270
  761. package/app/components/workshop/terminal/TerminalHitlCard.vue +170 -170
  762. package/app/components/workshop/town/TownScene.ts +466 -466
  763. package/app/components/workshop/town/TownView.vue +561 -561
  764. package/app/components/workshop/town/components/AutoModeConfirmModal.vue +94 -94
  765. package/app/components/workshop/town/components/TownAgentBindings.vue +417 -405
  766. package/app/components/workshop/town/components/TownAgentInspector.vue +554 -554
  767. package/app/components/workshop/town/components/TownAlarmList.vue +147 -147
  768. package/app/components/workshop/town/components/TownBoundaryPanel.vue +350 -350
  769. package/app/components/workshop/town/components/TownCalloutLayer.vue +147 -147
  770. package/app/components/workshop/town/components/TownChannelDock.vue +116 -116
  771. package/app/components/workshop/town/components/TownControlDock.vue +405 -405
  772. package/app/components/workshop/town/components/TownDaqNodeInspector.vue +345 -345
  773. package/app/components/workshop/town/components/TownDaqTree.vue +366 -366
  774. package/app/components/workshop/town/components/TownDcwBindSection.vue +473 -473
  775. package/app/components/workshop/town/components/TownDcwNodeInspector.vue +185 -185
  776. package/app/components/workshop/town/components/TownDcwTree.vue +280 -280
  777. package/app/components/workshop/town/components/TownDeviceBindings.vue +394 -394
  778. package/app/components/workshop/town/components/TownDeviceTransform.vue +248 -248
  779. package/app/components/workshop/town/components/TownEventList.vue +120 -120
  780. package/app/components/workshop/town/components/TownHealthBody.vue +100 -100
  781. package/app/components/workshop/town/components/TownKpiStrip.vue +207 -207
  782. package/app/components/workshop/town/components/TownLeftRail.vue +308 -308
  783. package/app/components/workshop/town/components/TownLoadingMask.vue +61 -61
  784. package/app/components/workshop/town/components/TownNavMap.vue +154 -154
  785. package/app/components/workshop/town/components/TownRightRail.vue +543 -543
  786. package/app/components/workshop/town/components/TownStage.vue +281 -281
  787. package/app/components/workshop/town/components/TownStageTop.vue +238 -238
  788. package/app/components/workshop/town/components/TownStatusBar.vue +108 -108
  789. package/app/components/workshop/town/components/TownTopNav.vue +367 -367
  790. package/app/components/workshop/town/components/TownTrendDock.vue +178 -178
  791. package/app/components/workshop/town/scene/town-scene-agents.ts +254 -254
  792. package/app/components/workshop/town/scene/town-scene-behavior.ts +194 -194
  793. package/app/components/workshop/town/scene/town-scene-bubbles.ts +96 -96
  794. package/app/components/workshop/town/scene/town-scene-core.ts +158 -158
  795. package/app/components/workshop/town/scene/town-scene-models.ts +109 -109
  796. package/app/components/workshop/town/scene/town-scene-visuals.ts +279 -279
  797. package/app/components/workshop/town/scene/town-scene3d-agents.ts +308 -308
  798. package/app/components/workshop/town/scene/town-scene3d-blocks.ts +297 -297
  799. package/app/components/workshop/town/scene/town-scene3d-bubbles.ts +281 -281
  800. package/app/components/workshop/town/scene/town-scene3d-camera.ts +282 -282
  801. package/app/components/workshop/town/scene/town-scene3d-devices.ts +433 -433
  802. package/app/components/workshop/town/scene/town-scene3d-editing.ts +490 -490
  803. package/app/components/workshop/town/scene/town-scene3d-events.ts +173 -173
  804. package/app/components/workshop/town/scene/town-scene3d-factory.ts +412 -412
  805. package/app/components/workshop/town/scene/town-scene3d-hud.ts +110 -110
  806. package/app/components/workshop/town/scene/town-scene3d-lifecycle.ts +144 -144
  807. package/app/components/workshop/town/scene/town-scene3d-links.ts +141 -141
  808. package/app/components/workshop/town/scene/town-scene3d-loop.ts +286 -286
  809. package/app/components/workshop/town/scene/town-scene3d-models.ts +154 -154
  810. package/app/components/workshop/town/scene/town-scene3d-nodes.ts +562 -562
  811. package/app/components/workshop/town/scene/town-scene3d-ranges.ts +273 -273
  812. package/app/components/workshop/town/scene/town-scene3d-renderer.ts +320 -320
  813. package/app/components/workshop/town/scene/town-scene3d-selection.ts +257 -257
  814. package/app/components/workshop/town/scene/town-scene3d-types.ts +264 -264
  815. package/app/components/workshop/transcript/TranscriptBlockList.vue +68 -68
  816. package/app/components/workshop/transcript/TranscriptEarlierPager.vue +81 -81
  817. package/app/components/workshop/transcript/TranscriptFilterBar.vue +126 -126
  818. package/app/components/workshop/workbench/CreateWorkspaceModal.vue +36 -36
  819. package/app/components/workshop/workbench/WorkspaceEmpty.vue +56 -56
  820. package/app/composables/useResponsive.ts +88 -88
  821. package/app/composables/workshop/device-twin-types.ts +29 -29
  822. package/app/composables/workshop/event-blocks/attention.ts +58 -58
  823. package/app/composables/workshop/event-blocks/classify.ts +44 -44
  824. package/app/composables/workshop/event-blocks/clusterer.ts +231 -231
  825. package/app/composables/workshop/event-blocks/fold-stream.ts +45 -45
  826. package/app/composables/workshop/event-blocks/markdown.ts +81 -81
  827. package/app/composables/workshop/event-blocks/mentions.ts +49 -49
  828. package/app/composables/workshop/event-blocks/text-utils.ts +100 -100
  829. package/app/composables/workshop/event-blocks/types.ts +40 -40
  830. package/app/composables/workshop/town/town-relay-props.ts +231 -231
  831. package/app/composables/workshop/town/town-view-types.ts +145 -145
  832. package/app/composables/workshop/town/useTownAgentBindings.ts +183 -182
  833. package/app/composables/workshop/town/useTownAgentChat.ts +203 -203
  834. package/app/composables/workshop/town/useTownAlarms.ts +36 -36
  835. package/app/composables/workshop/town/useTownCallouts.ts +174 -174
  836. package/app/composables/workshop/town/useTownChannels.ts +220 -220
  837. package/app/composables/workshop/town/useTownHealth.ts +66 -66
  838. package/app/composables/workshop/town/useTownHudTickers.ts +77 -77
  839. package/app/composables/workshop/town/useTownLayout.ts +277 -277
  840. package/app/composables/workshop/town/useTownNavMap.ts +301 -301
  841. package/app/composables/workshop/town/useTownNodeBindings.ts +345 -345
  842. package/app/composables/workshop/town/useTownPanelDrag.ts +91 -91
  843. package/app/composables/workshop/town/useTownRailData.ts +421 -421
  844. package/app/composables/workshop/town/useTownSceneControl.ts +92 -92
  845. package/app/composables/workshop/town/useTownSceneInput.ts +275 -275
  846. package/app/composables/workshop/town/useTownSceneRuntime.ts +390 -390
  847. package/app/composables/workshop/town/useTownSheets.ts +41 -41
  848. package/app/composables/workshop/town/useTownTrends.ts +93 -93
  849. package/app/composables/workshop/useChannelList.ts +88 -88
  850. package/app/composables/workshop/useChannelTerminals.ts +65 -65
  851. package/app/composables/workshop/useComposerMentions.ts +130 -130
  852. package/app/composables/workshop/useDcwStream.ts +377 -374
  853. package/app/composables/workshop/useDeviceTwinDcwWrite.ts +77 -77
  854. package/app/composables/workshop/useDeviceTwinPanel.ts +56 -56
  855. package/app/composables/workshop/useEscClose.ts +44 -44
  856. package/app/composables/workshop/useEventBlockView.ts +159 -159
  857. package/app/composables/workshop/useEventBlocks.ts +33 -33
  858. package/app/composables/workshop/useHitlAnswer.ts +184 -184
  859. package/app/composables/workshop/useLaneWidths.ts +27 -27
  860. package/app/composables/workshop/useOmpTerminalSession.ts +424 -424
  861. package/app/composables/workshop/useOpsLog.ts +1 -1
  862. package/app/composables/workshop/usePluginAdmin.ts +152 -152
  863. package/app/composables/workshop/usePluginPanels.ts +72 -72
  864. package/app/composables/workshop/useRuntimeConfigDraft.ts +118 -118
  865. package/app/composables/workshop/useSettingsGroups.ts +243 -243
  866. package/app/composables/workshop/useTaskBoardColumns.ts +47 -47
  867. package/app/composables/workshop/useTerminalRenderer.ts +308 -308
  868. package/app/composables/workshop/useTranscriptEnterStage.ts +48 -48
  869. package/app/composables/workshop/useTranscriptHistory.ts +52 -52
  870. package/app/composables/workshop/useTranscriptScroll.ts +113 -113
  871. package/app/composables/workshop/useVisibleInterval.ts +42 -42
  872. package/app/composables/workshop/useWorkshopWs.ts +265 -265
  873. package/app/config/index.ts +1 -1
  874. package/app/middleware/locale-cookie.global.ts +22 -22
  875. package/app/pages/aml/api.ts +6 -6
  876. package/app/pages/aml/composables/useAmlDatasets.ts +38 -38
  877. package/app/pages/aml/composables/useAmlEntities.ts +57 -57
  878. package/app/pages/aml/composables/useAmlEnv.ts +191 -191
  879. package/app/pages/aml/composables/useAmlExperiments.ts +45 -45
  880. package/app/pages/aml/composables/useAmlFormat.ts +44 -44
  881. package/app/pages/aml/composables/useAmlJobs.ts +131 -131
  882. package/app/pages/aml/composables/useAmlModels.ts +56 -56
  883. package/app/pages/aml/composables/useAmlNotes.ts +47 -47
  884. package/app/pages/aml/composables/useAmlPredict.ts +93 -93
  885. package/app/pages/aml/constants.ts +63 -63
  886. package/app/pages/aml/index.vue +236 -236
  887. package/app/pages/composables/useDashboardCharts.ts +192 -192
  888. package/app/pages/composables/useDashboardData.ts +144 -144
  889. package/app/pages/daq/composables/useDaqAddNode.ts +126 -126
  890. package/app/pages/daq/composables/useDaqDetailBinding.ts +29 -29
  891. package/app/pages/daq/composables/useDaqDetailFrames.ts +42 -42
  892. package/app/pages/daq/composables/useDaqDetailNode.ts +53 -53
  893. package/app/pages/daq/composables/useDaqDetailParams.ts +138 -138
  894. package/app/pages/daq/composables/useDaqFilters.ts +187 -187
  895. package/app/pages/daq/composables/useDaqNodeWindow.ts +86 -86
  896. package/app/pages/daq/composables/useDaqOptimizations.ts +99 -99
  897. package/app/pages/daq/composables/useDaqTemplates.ts +152 -152
  898. package/app/pages/daq/index.vue +260 -260
  899. package/app/pages/dcw/composables/useDcwCards.ts +27 -27
  900. package/app/pages/dcw/composables/useDcwDetailScope.ts +145 -145
  901. package/app/pages/dcw/composables/useDcwDetailTemplates.ts +94 -94
  902. package/app/pages/dcw/composables/useDcwFilter.ts +29 -29
  903. package/app/pages/dcw/composables/useDcwLedger.ts +34 -34
  904. package/app/pages/dcw/composables/useDcwLineMutations.ts +115 -115
  905. package/app/pages/dcw/composables/useDcwLineRun.ts +60 -60
  906. package/app/pages/dcw/composables/useDcwProducts.ts +54 -54
  907. package/app/pages/dcw/composables/useDcwQuery.ts +68 -68
  908. package/app/pages/dcw/composables/useDcwQuickActions.ts +47 -47
  909. package/app/pages/dcw/composables/useDcwRecipes.ts +256 -256
  910. package/app/pages/dcw/composables/useDcwTemplates.ts +50 -50
  911. package/app/pages/dcw/index.vue +195 -195
  912. package/app/pages/dcw/types.ts +9 -9
  913. package/app/pages/index.vue +126 -126
  914. package/app/pages/logs/composables/useLogsFormat.ts +43 -43
  915. package/app/pages/logs/composables/useLogsManual.ts +3 -0
  916. package/app/pages/logs/composables/useLogsScope.ts +39 -39
  917. package/app/pages/logs/index.vue +34 -1
  918. package/app/pages/monitor/types.ts +61 -61
  919. package/app/pages/operations.vue +61 -61
  920. package/app/pages/permissions/index.vue +369 -369
  921. package/app/pages/tokens/composables/useTokenClipboard.ts +33 -33
  922. package/app/pages/tokens/composables/useTokenCreate.ts +93 -93
  923. package/app/pages/tokens/composables/useTokenRename.ts +54 -54
  924. package/app/pages/tokens/composables/useTokenReveal.ts +84 -84
  925. package/app/pages/tokens/composables/useTokensList.ts +60 -60
  926. package/app/pages/tokens.vue +111 -111
  927. package/app/pages/tools/index.vue +98 -98
  928. package/app/pages/workshop/agents.vue +130 -130
  929. package/app/pages/workshop/composables/useAgentHarnessOptions.ts +59 -59
  930. package/app/pages/workshop/composables/useAgentTemplateActions.ts +42 -42
  931. package/app/pages/workshop/composables/useAgentTemplateDialogState.ts +24 -24
  932. package/app/pages/workshop/composables/useAgentTemplateForm.ts +88 -88
  933. package/app/pages/workshop/composables/useAgentTemplatesCatalog.ts +92 -92
  934. package/app/pages/workshop/composables/useTeamActions.ts +44 -44
  935. package/app/pages/workshop/composables/useTeamAddMemberDialog.ts +49 -49
  936. package/app/pages/workshop/composables/useTeamCreateDialog.ts +67 -67
  937. package/app/pages/workshop/composables/useTeamDeployDialog.ts +49 -49
  938. package/app/pages/workshop/composables/useTeamDialogState.ts +46 -46
  939. package/app/pages/workshop/composables/useTeamPluginDialog.ts +72 -72
  940. package/app/pages/workshop/composables/useTeamsCatalog.ts +100 -100
  941. package/app/pages/workshop/composables/useWorkbenchWorkspaces.ts +123 -123
  942. package/app/pages/workshop/composables/useWorkspaceAuth.ts +31 -31
  943. package/app/pages/workshop/composables/useWorkspaceChannels.ts +62 -62
  944. package/app/pages/workshop/composables/useWorkspaceShell.ts +136 -136
  945. package/app/pages/workshop/schedules.vue +553 -553
  946. package/app/pages/workshop/w/[wsId].vue +221 -221
  947. package/app/plugins/aw-plugins.client.ts +213 -213
  948. package/app/plugins/esc-close.client.ts +31 -31
  949. package/app/stores/workshop/hitl.ts +183 -183
  950. package/app/stores/workshop/narrow-fetch.ts +23 -23
  951. package/app/utils/api-error.ts +75 -75
  952. package/app/utils/builtin-catalog.ts +104 -104
  953. package/app/utils/chart-trend.ts +97 -97
  954. package/app/utils/dcw-driver-badge.ts +16 -16
  955. package/app/utils/dcw-recipe-form.ts +26 -26
  956. package/cli/commands/tui.mjs +28 -28
  957. package/cli/commands/update.mjs +124 -124
  958. package/cli/core/child-lifecycle.mjs +136 -136
  959. package/cli/core/meta.mjs +38 -38
  960. package/cli/core/post-build.mjs +96 -96
  961. package/config.yml +1 -1
  962. package/docker-compose.yml +4 -2
  963. package/docs/cli.en.md +2 -2
  964. package/docs/cli.md +2 -2
  965. package/docs/mcp.en.md +27 -27
  966. package/docs/multi-harness-architecture.md +248 -248
  967. package/docs/plugins.en.md +1 -1
  968. package/docs/plugins.md +1 -1
  969. package/docs/sdk.en.md +1 -1
  970. package/docs/sdk.md +1 -1
  971. package/docs/tui.md +43 -43
  972. package/i18n/dicts/_en.json +1551 -1551
  973. package/i18n/dicts/_en2.json +300 -300
  974. package/i18n/dicts/_en4.json +114 -114
  975. package/i18n/dicts/agentLanesView.json +61 -61
  976. package/i18n/dicts/appHeader.json +17 -17
  977. package/i18n/dicts/channelSessionList.json +51 -51
  978. package/i18n/dicts/chat.json +79 -79
  979. package/i18n/dicts/clusterTool.json +4 -4
  980. package/i18n/dicts/composer.json +38 -38
  981. package/i18n/dicts/ctpl.json +37 -37
  982. package/i18n/dicts/dcwDetail.json +219 -219
  983. package/i18n/dicts/lineOps.json +14 -14
  984. package/i18n/dicts/multiChannelView.json +13 -13
  985. package/i18n/dicts/notifications.json +13 -13
  986. package/i18n/dicts/taskInspectorDrawer.json +25 -25
  987. package/i18n/dicts/teamPlugins.json +10 -10
  988. package/i18n/dicts/townView.json +211 -209
  989. package/i18n/locales/en.ts +9 -0
  990. package/i18n/locales/zh-CN.ts +9 -0
  991. package/mcp/discovery.mjs +227 -227
  992. package/package.json +3 -1
  993. package/public/favicon.svg +14 -14
  994. package/public/robots.txt +3 -3
  995. package/scripts/_audit/_live-mqtt-e2e-20261028.mjs +219 -0
  996. package/scripts/_audit/audit-harness-adapters.md +664 -664
  997. package/scripts/_audit/aw-mcp-live-e2e.mjs +293 -293
  998. package/scripts/_audit/bump-version.mjs +51 -51
  999. package/scripts/_audit/detached-instance.mjs +112 -112
  1000. package/scripts/_audit/detached-start.mjs +103 -103
  1001. package/scripts/_audit/eda-ui-fix-acceptance.mjs +212 -212
  1002. package/scripts/_audit/guard-upstream-liveness.mjs +104 -104
  1003. package/scripts/_audit/http-api-authz-audit.md +657 -657
  1004. package/scripts/_audit/kb-team-mock-e2e.mjs +146 -146
  1005. package/scripts/_audit/kb-team-omp-e2e.mjs +229 -229
  1006. package/scripts/_audit/prompt-injection-probe.mts +76 -0
  1007. package/scripts/_audit/run.mjs +21 -21
  1008. package/scripts/_audit/runtime-audit.md +716 -716
  1009. package/scripts/_audit/skills-guided-e2e.mjs +316 -316
  1010. package/scripts/_audit/stability-soak.mjs +252 -252
  1011. package/scripts/_audit/stubs/nuxt-imports.mjs +67 -67
  1012. package/scripts/_audit/ts-register-hook.mjs +12 -12
  1013. package/scripts/_audit/ts-resolve-hook.mjs +96 -96
  1014. package/scripts/_aw0746-stage12.mjs +94 -94
  1015. package/scripts/_aw0746-stage34.mjs +136 -136
  1016. package/scripts/_aw0746-stage6b-train-sweep.mjs +145 -145
  1017. package/scripts/_aw0746-stage6c-jobsmoke.mjs +69 -69
  1018. package/scripts/_dbg-configroot-audit.mjs +86 -86
  1019. package/scripts/_dbg-daq-intervals-func.mjs +115 -115
  1020. package/scripts/_dbg-perms-e2e.mjs +142 -142
  1021. package/scripts/_dbg-protocol-matrix.mjs +462 -462
  1022. package/scripts/_dbg-render-regression.mjs +193 -193
  1023. package/scripts/_dbg-schedule-e2e.mjs +262 -262
  1024. package/scripts/_e2e-ui-functional.mjs +371 -371
  1025. package/scripts/_lib-aml-python-run.mjs +17 -17
  1026. package/scripts/_plc-sim-detached.cjs +22 -22
  1027. package/scripts/_provision-injection-line.mjs +39 -39
  1028. package/scripts/_run-matrix.ps1 +53 -53
  1029. package/scripts/_sweep-button-contrast.mjs +87 -87
  1030. package/scripts/acceptance-aml-hybrid-e2e.ts +396 -396
  1031. package/scripts/acceptance-aml-hybrid-live.mjs +93 -93
  1032. package/scripts/acceptance-aml-model-identity.ts +137 -137
  1033. package/scripts/agent-daq-isolation-e2e.mjs +91 -91
  1034. package/scripts/api-contract-smoke.mjs +126 -126
  1035. package/scripts/api-live-e2e.mjs +9 -3
  1036. package/scripts/ask-hitl-e2e.mjs +96 -96
  1037. package/scripts/aw-expose.mjs +159 -159
  1038. package/scripts/channel-interaction-smoke.mjs +80 -80
  1039. package/scripts/data-studio-ui-e2e.mjs +163 -163
  1040. package/scripts/demo-group-chat-all-real.ts +279 -279
  1041. package/scripts/dev-modbus-simulator.mjs +55 -55
  1042. package/scripts/docs-shots.mjs +36 -36
  1043. package/scripts/e2e-agentteam-chat.mjs +473 -473
  1044. package/scripts/e2e-agentteam-real-triage.mjs +421 -421
  1045. package/scripts/e2e-aml-decoupled.mjs +162 -162
  1046. package/scripts/e2e-analysis-ledger.mjs +202 -0
  1047. package/scripts/e2e-aw-tui-global.mjs +277 -277
  1048. package/scripts/e2e-binding-modes-real.mjs +442 -0
  1049. package/scripts/e2e-business-loop-real.mjs +391 -0
  1050. package/scripts/e2e-closedloop/cleanup.mjs +27 -27
  1051. package/scripts/e2e-closedloop/lib.mjs +109 -109
  1052. package/scripts/e2e-closedloop/main.mjs +59 -59
  1053. package/scripts/e2e-closedloop/scenarios-accounts.mjs +210 -210
  1054. package/scripts/e2e-closedloop/scenarios-authz.mjs +196 -196
  1055. package/scripts/e2e-closedloop/scenarios-daq-dcw.mjs +222 -222
  1056. package/scripts/e2e-closedloop/scenarios-plugins.mjs +169 -169
  1057. package/scripts/e2e-closedloop/state.mjs +10 -10
  1058. package/scripts/e2e-config-groups.mjs +238 -238
  1059. package/scripts/e2e-core-bridges-matrix.mjs +303 -0
  1060. package/scripts/e2e-crash-cycle.mjs +108 -108
  1061. package/scripts/e2e-error-handling.mjs +190 -0
  1062. package/scripts/e2e-full-closedloop.mjs +16 -16
  1063. package/scripts/e2e-golive-matrix.mjs +515 -0
  1064. package/scripts/e2e-hil-multi-user.mjs +307 -307
  1065. package/scripts/e2e-hil-restart.mjs +339 -339
  1066. package/scripts/e2e-line-governance.mjs +352 -352
  1067. package/scripts/e2e-mes-mirror-real.mjs +418 -0
  1068. package/scripts/e2e-multiexpert-remediation-real.mjs +453 -0
  1069. package/scripts/e2e-node-binding-3mode-real.mjs +792 -0
  1070. package/scripts/e2e-node-binding-authz.mjs +372 -0
  1071. package/scripts/e2e-ontology.mjs +393 -393
  1072. package/scripts/e2e-optimizer-live.mjs +4 -0
  1073. package/scripts/e2e-physical-effect-real.mjs +570 -0
  1074. package/scripts/e2e-plc-plugin-closedloop.mjs +549 -549
  1075. package/scripts/full-stack-shots.mjs +145 -145
  1076. package/scripts/full-tool-injection-harness-e2e.mjs +214 -214
  1077. package/scripts/hitl-reject-e2e.mjs +131 -131
  1078. package/scripts/line-log-smoke.mjs +260 -260
  1079. package/scripts/live-aml-mockomp.mjs +304 -304
  1080. package/scripts/live-aml-optloop-resume.mjs +322 -322
  1081. package/scripts/live-aml-optloop.mjs +588 -588
  1082. package/scripts/live-aml-stage9.mjs +169 -169
  1083. package/scripts/live-aml-two-goals.mjs +315 -315
  1084. package/scripts/live-demo-seed.mjs +157 -0
  1085. package/scripts/live-optloop-two-modes.mjs +857 -857
  1086. package/scripts/mes-agent-integration-e2e.mjs +361 -361
  1087. package/scripts/ops-plugins-e2e.mjs +85 -85
  1088. package/scripts/scenario-suite-setup.mjs +337 -337
  1089. package/scripts/scenario-suite-stability.mjs +144 -144
  1090. package/scripts/security-acceptance.mjs +218 -0
  1091. package/scripts/team-coordination-e2e.mjs +96 -96
  1092. package/scripts/test-agentteam-workflow.ts +472 -472
  1093. package/scripts/test-aw-skills.mjs +102 -102
  1094. package/scripts/test-daq-frame-race.mjs +358 -358
  1095. package/scripts/test-data-root.mjs +208 -208
  1096. package/scripts/test-events-index.mjs +176 -176
  1097. package/scripts/test-group-chat-unit/lib.ts +186 -186
  1098. package/scripts/test-group-chat-unit/main.ts +45 -45
  1099. package/scripts/test-group-chat-unit.ts +35 -35
  1100. package/scripts/test-hitl-decision.ts +526 -526
  1101. package/scripts/test-hitl-registry.ts +112 -112
  1102. package/scripts/test-log-flooding.mjs +160 -160
  1103. package/scripts/test-lru.mjs +101 -101
  1104. package/scripts/test-plugin-hardening.mjs +90 -90
  1105. package/scripts/test-plugin-lifecycle.mjs +173 -173
  1106. package/scripts/test-rollback-index.mjs +137 -137
  1107. package/scripts/test-schedule-runtime.ts +309 -309
  1108. package/scripts/test-sdk-surface.mjs +158 -158
  1109. package/scripts/test-serial-bridge.mjs +418 -418
  1110. package/scripts/test-tui-commands.mjs +148 -148
  1111. package/scripts/test-tui-reducers.mjs +72 -72
  1112. package/scripts/three-system-e2e/lib.mjs +79 -79
  1113. package/scripts/three-system-e2e/main.mjs +40 -40
  1114. package/scripts/three-system-e2e/phases/phase-0-user-token.mjs +42 -42
  1115. package/scripts/three-system-e2e/phases/phase-0a2-line-autoselect.mjs +35 -35
  1116. package/scripts/three-system-e2e/phases/phase-0b-fixture-grants.mjs +39 -39
  1117. package/scripts/three-system-e2e/phases/phase-0c-plugin-outbound-auth.mjs +95 -95
  1118. package/scripts/three-system-e2e/phases/stage-1-health.mjs +47 -47
  1119. package/scripts/three-system-e2e/phases/stage-2-5-team-plugins.mjs +84 -84
  1120. package/scripts/three-system-e2e/phases/stage-2-teams-tools-hitl.mjs +184 -184
  1121. package/scripts/three-system-e2e/phases/stage-3-diag.mjs +73 -73
  1122. package/scripts/three-system-e2e/phases/stage-4-plugin-toggle.mjs +53 -53
  1123. package/scripts/three-system-e2e/state.mjs +87 -87
  1124. package/scripts/three-system-e2e.mjs +40 -40
  1125. package/scripts/tool-face-batch-identity-e2e.mjs +222 -222
  1126. package/scripts/tsconfig.json +14 -14
  1127. package/scripts/tui-smoke.mjs +100 -100
  1128. package/scripts/typecheck.mjs +75 -75
  1129. package/scripts/ui/md-lint.mjs +80 -80
  1130. package/scripts/ui/readme-assets.mjs +30 -30
  1131. package/scripts/ui/readme-shots.mjs +42 -42
  1132. package/scripts/ui/record-demo.mjs +557 -557
  1133. package/scripts/ui/record.mjs +225 -225
  1134. package/scripts/ui/seed-admin.mjs +68 -68
  1135. package/scripts/ui/seed-demo.mjs +83 -83
  1136. package/scripts/ui/seed-industrial-demo.mjs +171 -171
  1137. package/scripts/ui/shot-hero.mjs +25 -25
  1138. package/scripts/ui/shots.mjs +75 -75
  1139. package/scripts/ui/verify-nav.mjs +51 -51
  1140. package/scripts/ui/verify-responsive.mjs +285 -285
  1141. package/sdk/client.d.mts +110 -110
  1142. package/sdk/examples/line-sentinel/index.mjs +105 -105
  1143. package/sdk/examples/ops-notifier/index.mjs +34 -34
  1144. package/sdk/examples/sample-insight/index.mjs +39 -39
  1145. package/server/api/plugins/client/[name].get.ts +18 -18
  1146. package/server/api/plugins/i18n.get.ts +12 -12
  1147. package/server/api/plugins/manifest.get.ts +10 -10
  1148. package/server/api/system/backup/list.get.ts +32 -32
  1149. package/server/api/system/backup/run.post.ts +21 -21
  1150. package/server/api/system/config-groups/[id].delete.ts +21 -21
  1151. package/server/api/system/config-groups/[id].patch.ts +26 -26
  1152. package/server/api/system/config-groups/index.get.ts +21 -21
  1153. package/server/api/system/config-groups/index.post.ts +33 -33
  1154. package/server/api/system/timezone.get.ts +20 -20
  1155. package/server/api/users/tokens/[id]/token.get.ts +11 -11
  1156. package/server/api/workshop/[...path].ts +13 -13
  1157. package/server/api/workshop/agent-tools/approvals/index.get.ts +45 -43
  1158. package/server/api/workshop/agent-tools/bindings/[id].delete.ts +26 -26
  1159. package/server/api/workshop/agent-tools/bindings/grant.post.ts +45 -45
  1160. package/server/api/workshop/agent-tools/bindings/index.get.ts +41 -41
  1161. package/server/api/workshop/agent-tools/bindings/index.post.ts +58 -20
  1162. package/server/api/workshop/agent-tools/bindings/revoke.post.ts +42 -42
  1163. package/server/api/workshop/agents/[id].patch.ts +3 -0
  1164. package/server/api/workshop/agents/index.post.ts +3 -0
  1165. package/server/api/workshop/aml/datasets/[id]/preview.get.ts +68 -68
  1166. package/server/api/workshop/aml/datasets/[id].delete.ts +39 -39
  1167. package/server/api/workshop/aml/datasets/[id].get.ts +53 -53
  1168. package/server/api/workshop/aml/datasets/[id].patch.ts +30 -30
  1169. package/server/api/workshop/aml/datasets/index.get.ts +20 -20
  1170. package/server/api/workshop/aml/datasets/index.post.ts +27 -27
  1171. package/server/api/workshop/aml/entities/index.get.ts +13 -13
  1172. package/server/api/workshop/aml/entities/prune.post.ts +28 -28
  1173. package/server/api/workshop/aml/env/index.get.ts +13 -13
  1174. package/server/api/workshop/aml/env/recheck.post.ts +14 -14
  1175. package/server/api/workshop/aml/env/uv.post.ts +21 -21
  1176. package/server/api/workshop/aml/env/venv.post.ts +24 -24
  1177. package/server/api/workshop/aml/experiments/index.get.ts +35 -35
  1178. package/server/api/workshop/aml/index.get.ts +37 -37
  1179. package/server/api/workshop/aml/jobs/[id]/cancel.post.ts +21 -21
  1180. package/server/api/workshop/aml/jobs/[id]/logs.get.ts +23 -23
  1181. package/server/api/workshop/aml/jobs/[id]/retry.post.ts +20 -20
  1182. package/server/api/workshop/aml/jobs/[id].delete.ts +44 -44
  1183. package/server/api/workshop/aml/jobs/[id].get.ts +23 -23
  1184. package/server/api/workshop/aml/jobs/index.get.ts +26 -26
  1185. package/server/api/workshop/aml/models/[id]/predict.post.ts +24 -24
  1186. package/server/api/workshop/aml/models/[id]/promote.post.ts +30 -30
  1187. package/server/api/workshop/aml/models/index.get.ts +48 -48
  1188. package/server/api/workshop/aml/training-plans/[id]/train.post.ts +18 -18
  1189. package/server/api/workshop/aml/training-plans/[id].delete.ts +18 -18
  1190. package/server/api/workshop/aml/training-plans/[id].patch.ts +30 -30
  1191. package/server/api/workshop/aml/training-plans/index.get.ts +9 -9
  1192. package/server/api/workshop/aml/training-plans/index.post.ts +43 -43
  1193. package/server/api/workshop/analysis/index.post.ts +54 -54
  1194. package/server/api/workshop/approvals/[id]/decide.post.ts +30 -30
  1195. package/server/api/workshop/approvals/index.get.ts +22 -22
  1196. package/server/api/workshop/audit.get.ts +43 -43
  1197. package/server/api/workshop/channel-templates/[id].patch.ts +5 -0
  1198. package/server/api/workshop/channel-templates/index.post.ts +6 -0
  1199. package/server/api/workshop/channels/[id]/agents/[agentId].patch.ts +5 -0
  1200. package/server/api/workshop/channels/[id]/agents/index.get.ts +8 -2
  1201. package/server/api/workshop/channels/[id]/agents/index.post.ts +7 -0
  1202. package/server/api/workshop/channels/[id]/chat/messages/[messageId]/read.post.ts +22 -22
  1203. package/server/api/workshop/channels/[id]/chat/messages/index.get.ts +29 -29
  1204. package/server/api/workshop/channels/[id]/chat/messages/index.post.ts +51 -51
  1205. package/server/api/workshop/channels/[id]/chat/permissions.get.ts +35 -35
  1206. package/server/api/workshop/channels/[id]/index.get.ts +10 -4
  1207. package/server/api/workshop/channels/[id]/index.patch.ts +64 -64
  1208. package/server/api/workshop/channels/[id]/members/[userId]/approve.post.ts +20 -20
  1209. package/server/api/workshop/channels/[id]/members/[userId].delete.ts +21 -21
  1210. package/server/api/workshop/channels/[id]/members/index.get.ts +23 -23
  1211. package/server/api/workshop/channels/[id]/members/leave.post.ts +20 -20
  1212. package/server/api/workshop/channels/[id]/twin-profile.get.ts +45 -45
  1213. package/server/api/workshop/channels/[id]/twin-profile.patch.ts +72 -72
  1214. package/server/api/workshop/channels.post.ts +3 -0
  1215. package/server/api/workshop/daq/[id]/ingest.post.ts +26 -22
  1216. package/server/api/workshop/daq/[id]/test.post.ts +1 -1
  1217. package/server/api/workshop/daq/[id].patch.ts +8 -0
  1218. package/server/api/workshop/daq/alarms.get.ts +18 -16
  1219. package/server/api/workshop/daq/infra/reconnect.post.ts +21 -5
  1220. package/server/api/workshop/daq/test-driver.post.ts +10 -3
  1221. package/server/api/workshop/dcw/[id]/param-ledger.get.ts +7 -1
  1222. package/server/api/workshop/dcw/[id]/read.post.ts +6 -1
  1223. package/server/api/workshop/dcw/[id]/write.post.ts +4 -4
  1224. package/server/api/workshop/dcw/[id].delete.ts +41 -41
  1225. package/server/api/workshop/dcw/[id].patch.ts +49 -40
  1226. package/server/api/workshop/dcw/journal/index.get.ts +7 -3
  1227. package/server/api/workshop/dcw/mes-artifacts/file.get.ts +7 -1
  1228. package/server/api/workshop/dcw/mes-artifacts/index.get.ts +7 -1
  1229. package/server/api/workshop/dcw/mes-test-read.post.ts +24 -24
  1230. package/server/api/workshop/dcw/optimizations/[id]/series.get.ts +6 -1
  1231. package/server/api/workshop/dcw/optimizations/[id].get.ts +3 -1
  1232. package/server/api/workshop/dcw/optimizations/index.get.ts +6 -3
  1233. package/server/api/workshop/dcw/params/[id]/read.post.ts +22 -17
  1234. package/server/api/workshop/dcw/params/[id]/write.post.ts +21 -21
  1235. package/server/api/workshop/dcw/params/[id].delete.ts +19 -19
  1236. package/server/api/workshop/dcw/params/[id].patch.ts +23 -23
  1237. package/server/api/workshop/dcw/params/index.get.ts +27 -27
  1238. package/server/api/workshop/dcw/params/index.post.ts +25 -25
  1239. package/server/api/workshop/dcw/recipes/[id]/versions.get.ts +20 -14
  1240. package/server/api/workshop/dcw/recipes/[id].delete.ts +33 -25
  1241. package/server/api/workshop/dcw/recipes/index.get.ts +17 -12
  1242. package/server/api/workshop/dcw/runs/[id]/close.post.ts +21 -15
  1243. package/server/api/workshop/dcw/templates/[key].delete.ts +14 -14
  1244. package/server/api/workshop/dcw/templates/[key].patch.ts +16 -16
  1245. package/server/api/workshop/dcw/templates/index.post.ts +15 -15
  1246. package/server/api/workshop/dcw/test-driver.post.ts +21 -16
  1247. package/server/api/workshop/device-twins/[id].delete.ts +25 -25
  1248. package/server/api/workshop/eda/runs/[id]/labels.patch.ts +25 -25
  1249. package/server/api/workshop/eda/templates/[id].delete.ts +14 -14
  1250. package/server/api/workshop/eda/templates/[id].get.ts +15 -15
  1251. package/server/api/workshop/eda/templates/[id].patch.ts +20 -20
  1252. package/server/api/workshop/eda/templates/index.get.ts +11 -11
  1253. package/server/api/workshop/eda/templates/index.post.ts +20 -20
  1254. package/server/api/workshop/exp/confirmations/[id]/decide.post.ts +41 -41
  1255. package/server/api/workshop/exp/confirmations/index.get.ts +25 -25
  1256. package/server/api/workshop/harnesses/[id]/providers.get.ts +16 -16
  1257. package/server/api/workshop/hitl/respond.post.ts +94 -94
  1258. package/server/api/workshop/notifications/index.get.ts +60 -60
  1259. package/server/api/workshop/notifications/read.post.ts +31 -31
  1260. package/server/api/workshop/ontology/drafts/[draftId]/subgraph.ts +24 -24
  1261. package/server/api/workshop/ops-logs/index.post.ts +20 -2
  1262. package/server/api/workshop/plugins/[name]/disable.post.ts +21 -21
  1263. package/server/api/workshop/plugins/[name]/enable.post.ts +21 -21
  1264. package/server/api/workshop/plugins/[name]/index.get.ts +14 -14
  1265. package/server/api/workshop/schedules/[id]/run.post.ts +15 -15
  1266. package/server/api/workshop/schedules/[id]/runs.get.ts +15 -15
  1267. package/server/api/workshop/schedules/[id].delete.ts +14 -14
  1268. package/server/api/workshop/schedules/[id].get.ts +13 -13
  1269. package/server/api/workshop/schedules/[id].patch.ts +29 -29
  1270. package/server/api/workshop/schedules/index.get.ts +12 -12
  1271. package/server/api/workshop/schedules/index.post.ts +32 -32
  1272. package/server/api/workshop/tasks/[id]/reassign.post.ts +32 -32
  1273. package/server/api/workshop/tasks/[id]/update.post.ts +35 -35
  1274. package/server/api/workshop/teams/[id]/plugins/index.get.ts +36 -36
  1275. package/server/api/workshop/teams/[id]/plugins/index.put.ts +42 -42
  1276. package/server/api/workshop/ws/audience.ts +56 -56
  1277. package/server/api/workshop/ws/db-buffer.ts +68 -68
  1278. package/server/api/workshop/ws/event-mapping.ts +47 -47
  1279. package/server/api/workshop/ws/handlers.ts +132 -132
  1280. package/server/api/workshop/ws/hub.ts +134 -133
  1281. package/server/api/workshop/ws/index.ts +23 -23
  1282. package/server/api/workshop/ws/notification-uplink.ts +77 -77
  1283. package/server/api/workshop/ws/shared.ts +94 -94
  1284. package/server/api/workshop/ws/streams.ts +146 -146
  1285. package/server/middleware/00-security-headers.ts +38 -38
  1286. package/server/middleware/01-rate-guard.ts +101 -101
  1287. package/server/plugins/01-instance-guard.ts +82 -0
  1288. package/server/plugins/aml-twin-worker.ts +32 -32
  1289. package/server/plugins/aw-plugins.ts +4 -1
  1290. package/server/plugins/daq.ts +40 -8
  1291. package/server/plugins/dev-stability-guard.ts +46 -42
  1292. package/server/plugins/error-ledger.ts +21 -0
  1293. package/server/plugins/workshop.ts +12 -0
  1294. package/server/plugins-builtin/diag-bridge/host/constants.mjs +25 -25
  1295. package/server/plugins-builtin/diag-bridge/host/exports.mjs +104 -104
  1296. package/server/plugins-builtin/diag-bridge/host/index.mjs +15 -15
  1297. package/server/plugins-builtin/diag-bridge/host/intents.mjs +62 -62
  1298. package/server/plugins-builtin/diag-bridge/host/snapshot.mjs +93 -93
  1299. package/server/plugins-builtin/diag-bridge/index.mjs +9 -9
  1300. package/server/plugins-builtin/serial-bridge/client.mjs +211 -211
  1301. package/server/plugins-builtin/serial-bridge/drivers.mjs +409 -409
  1302. package/server/plugins-builtin/serial-bridge/i18n.json +62 -62
  1303. package/server/plugins-builtin/serial-bridge/index.mjs +247 -247
  1304. package/server/plugins-builtin/serial-bridge/lib.mjs +208 -208
  1305. package/server/plugins-builtin/serial-bridge/rtu.mjs +168 -168
  1306. package/server/services/system-config/contracts.ts +29 -29
  1307. package/server/services/system-config/dispose.ts +19 -19
  1308. package/server/services/system-config/facade.ts +26 -26
  1309. package/server/services/system-config/groups.ts +108 -108
  1310. package/server/services/system-config/index.ts +21 -21
  1311. package/server/services/system-config/init.ts +26 -26
  1312. package/server/services/system-config/mutate.ts +103 -103
  1313. package/server/services/system-config/plugins.ts +104 -104
  1314. package/server/services/system-config/snapshot.ts +59 -59
  1315. package/server/services/system-config/state.ts +79 -79
  1316. package/server/services/system-config/types.ts +58 -58
  1317. package/server/services/workshop/agents/adapters/line-spawn.ts +24 -1
  1318. package/server/services/workshop/agents/adapters/omp-rpc-client/api.ts +111 -111
  1319. package/server/services/workshop/agents/adapters/omp-rpc-client/contracts.ts +22 -22
  1320. package/server/services/workshop/agents/adapters/omp-rpc-client/facade.ts +7 -7
  1321. package/server/services/workshop/agents/adapters/omp-rpc-client/helpers.ts +38 -38
  1322. package/server/services/workshop/agents/adapters/omp-rpc-client/index.ts +25 -25
  1323. package/server/services/workshop/agents/adapters/omp-rpc-client/start.ts +70 -70
  1324. package/server/services/workshop/agents/adapters/omp-rpc-client/state.ts +65 -65
  1325. package/server/services/workshop/agents/adapters/omp-rpc-client/stdout.ts +92 -92
  1326. package/server/services/workshop/agents/adapters/omp-rpc-client/usage.ts +47 -47
  1327. package/server/services/workshop/agents/agent-badge.ts +38 -38
  1328. package/server/services/workshop/agents/agent-dto.ts +54 -0
  1329. package/server/services/workshop/agents/binding-authz.ts +66 -60
  1330. package/server/services/workshop/agents/binding-mode.ts +51 -51
  1331. package/server/services/workshop/agents/codex-agent/client.ts +170 -170
  1332. package/server/services/workshop/agents/codex-agent/core.ts +119 -119
  1333. package/server/services/workshop/agents/codex-agent/facade.ts +8 -8
  1334. package/server/services/workshop/agents/codex-agent/helpers.ts +13 -13
  1335. package/server/services/workshop/agents/codex-agent/hitl.ts +138 -138
  1336. package/server/services/workshop/agents/codex-agent/index.ts +14 -14
  1337. package/server/services/workshop/agents/codex-agent/turn.ts +367 -367
  1338. package/server/services/workshop/agents/codex-agent/types.ts +42 -42
  1339. package/server/services/workshop/agents/harness-process.ts +3 -3
  1340. package/server/services/workshop/agents/harness-spawn-policy.ts +114 -0
  1341. package/server/services/workshop/agents/harness-terminal/api.ts +197 -197
  1342. package/server/services/workshop/agents/harness-terminal/index.ts +17 -17
  1343. package/server/services/workshop/agents/harness-terminal/io.ts +120 -120
  1344. package/server/services/workshop/agents/harness-terminal/park.ts +55 -55
  1345. package/server/services/workshop/agents/harness-terminal/sanitize.ts +98 -98
  1346. package/server/services/workshop/agents/harness-terminal/session.ts +124 -124
  1347. package/server/services/workshop/agents/harness-terminal/shared.ts +74 -74
  1348. package/server/services/workshop/agents/hitl-capabilities.ts +312 -312
  1349. package/server/services/workshop/agents/hitl-decision/answers.ts +32 -32
  1350. package/server/services/workshop/agents/hitl-decision/decide.ts +268 -268
  1351. package/server/services/workshop/agents/hitl-decision/payload.ts +45 -45
  1352. package/server/services/workshop/agents/hitl-decision/shared.ts +108 -108
  1353. package/server/services/workshop/agents/hitl-decision/visibility.ts +94 -94
  1354. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +22 -0
  1355. package/server/services/workshop/agents/host-tool-bridge/index.ts +1 -1
  1356. package/server/services/workshop/agents/host-tool-bridge/per-agent.ts +31 -3
  1357. package/server/services/workshop/agents/host-tool-bridge/tools/progress.ts +84 -84
  1358. package/server/services/workshop/agents/host-tool-bridge/tools/tasks.ts +1 -1
  1359. package/server/services/workshop/agents/host-tool-bridge/tools/team-delegation.ts +109 -104
  1360. package/server/services/workshop/agents/host-tool-bridge/tools/team.ts +70 -70
  1361. package/server/services/workshop/agents/industrial/aml-activity.ts +131 -131
  1362. package/server/services/workshop/agents/industrial/audit-query.ts +66 -66
  1363. package/server/services/workshop/agents/industrial/dcw-tools.ts +17 -3
  1364. package/server/services/workshop/agents/industrial/exp-tools.ts +104 -104
  1365. package/server/services/workshop/agents/industrial/ops-tools.ts +62 -14
  1366. package/server/services/workshop/agents/industrial/param-tools.ts +69 -69
  1367. package/server/services/workshop/agents/industrial/recipe-gate.ts +103 -22
  1368. package/server/services/workshop/agents/industrial/recipe-propose-tools.ts +2 -1
  1369. package/server/services/workshop/agents/industrial/tool-verify-legacy-specs.ts +2 -2
  1370. package/server/services/workshop/agents/industrial/tool-verify.ts +51 -2
  1371. package/server/services/workshop/agents/node-bindings.repo.ts +210 -207
  1372. package/server/services/workshop/agents/node-delegation.ts +204 -159
  1373. package/server/services/workshop/agents/omp-agent/core.ts +146 -146
  1374. package/server/services/workshop/agents/omp-agent/facade.ts +8 -8
  1375. package/server/services/workshop/agents/omp-agent/helpers.ts +37 -37
  1376. package/server/services/workshop/agents/omp-agent/index.ts +16 -16
  1377. package/server/services/workshop/agents/omp-agent/types.ts +45 -45
  1378. package/server/services/workshop/agents/opencode-agent/core.ts +77 -77
  1379. package/server/services/workshop/agents/opencode-agent/facade.ts +8 -8
  1380. package/server/services/workshop/agents/opencode-agent/helpers.ts +29 -29
  1381. package/server/services/workshop/agents/opencode-agent/hitl.ts +113 -113
  1382. package/server/services/workshop/agents/opencode-agent/index.ts +16 -16
  1383. package/server/services/workshop/agents/opencode-agent/lifecycle.ts +44 -44
  1384. package/server/services/workshop/agents/opencode-agent/server.ts +244 -244
  1385. package/server/services/workshop/agents/opencode-agent/turn.ts +278 -278
  1386. package/server/services/workshop/agents/opencode-agent/types.ts +54 -54
  1387. package/server/services/workshop/agents/tool-approvals.ts +25 -0
  1388. package/server/services/workshop/agents/tool-classes.ts +44 -44
  1389. package/server/services/workshop/agents/tool-reference-spec.ts +3 -0
  1390. package/server/services/workshop/aml/clean.ts +120 -120
  1391. package/server/services/workshop/aml/entity.ts +367 -367
  1392. package/server/services/workshop/aml/job-orchestrator/broadcast.ts +37 -37
  1393. package/server/services/workshop/aml/job-orchestrator/control.ts +94 -94
  1394. package/server/services/workshop/aml/job-orchestrator/failure.ts +96 -96
  1395. package/server/services/workshop/aml/job-orchestrator/index.ts +22 -22
  1396. package/server/services/workshop/aml/job-orchestrator/process.ts +101 -101
  1397. package/server/services/workshop/aml/job-orchestrator/shared.ts +53 -53
  1398. package/server/services/workshop/aml/job-orchestrator/status.ts +20 -20
  1399. package/server/services/workshop/aml/job-orchestrator/tick.ts +37 -37
  1400. package/server/services/workshop/aml/python/train-example.py +92 -92
  1401. package/server/services/workshop/aml/runtime.ts +137 -137
  1402. package/server/services/workshop/aml/stats.ts +140 -140
  1403. package/server/services/workshop/aml/twin/calibration-worker.ts +150 -150
  1404. package/server/services/workshop/aml/twin/model-backed-provider.ts +332 -332
  1405. package/server/services/workshop/aml/twin/physics-spec-draft.ts +185 -185
  1406. package/server/services/workshop/aml/twin/prompt-composer.ts +143 -143
  1407. package/server/services/workshop/aml/twin/training-plans.ts +260 -260
  1408. package/server/services/workshop/aml/twin/write-guard.ts +19 -19
  1409. package/server/services/workshop/assets/character-asset.repo.ts +1 -1
  1410. package/server/services/workshop/assets/device-twin.repo.ts +1 -1
  1411. package/server/services/workshop/daq/bus/mqtt.adapter.ts +12 -0
  1412. package/server/services/workshop/daq/daq-controller/contracts.ts +39 -39
  1413. package/server/services/workshop/daq/daq-controller/crud.ts +5 -3
  1414. package/server/services/workshop/daq/daq-controller/facade.ts +28 -28
  1415. package/server/services/workshop/daq/daq-controller/frames.ts +137 -137
  1416. package/server/services/workshop/daq/daq-controller/helpers.ts +52 -52
  1417. package/server/services/workshop/daq/daq-controller/index.ts +22 -22
  1418. package/server/services/workshop/daq/daq-controller/ingest.ts +23 -0
  1419. package/server/services/workshop/daq/daq-controller/push.ts +24 -3
  1420. package/server/services/workshop/daq/daq-controller/runtime-control.ts +6 -0
  1421. package/server/services/workshop/daq/daq-controller/sweep-alarms.ts +3 -1
  1422. package/server/services/workshop/daq/daq-controller/tsdb-twin.ts +21 -1
  1423. package/server/services/workshop/daq/daq-node.repo.ts +10 -7
  1424. package/server/services/workshop/daq/daq-node.ts +2 -0
  1425. package/server/services/workshop/daq/daq-runtime.ts +10 -2
  1426. package/server/services/workshop/daq/drivers/mock.ts +130 -130
  1427. package/server/services/workshop/daq/drivers/modbus-rtu.ts +67 -67
  1428. package/server/services/workshop/daq/drivers/modbus-tcp.ts +310 -307
  1429. package/server/services/workshop/daq/drivers/opcua.ts +227 -227
  1430. package/server/services/workshop/daq/drivers/registry.ts +5 -4
  1431. package/server/services/workshop/daq/drivers/s7-stub.ts +29 -29
  1432. package/server/services/workshop/daq/host-bindings.ts +71 -71
  1433. package/server/services/workshop/daq/host-ports.ts +65 -65
  1434. package/server/services/workshop/daq/infra.ts +13 -0
  1435. package/server/services/workshop/daq/ingest-policy.ts +24 -1
  1436. package/server/services/workshop/daq/storage/timescale.adapter.ts +42 -3
  1437. package/server/services/workshop/db/aml-team-seeds.ts +118 -118
  1438. package/server/services/workshop/db/backup-registry.ts +33 -33
  1439. package/server/services/workshop/db/channel-member.repo.ts +122 -122
  1440. package/server/services/workshop/db/channel.repo.ts +203 -203
  1441. package/server/services/workshop/db/chat-message.repo.ts +233 -233
  1442. package/server/services/workshop/db/database/index.ts +18 -18
  1443. package/server/services/workshop/db/database/json.ts +14 -14
  1444. package/server/services/workshop/db/database/migrations.ts +83 -68
  1445. package/server/services/workshop/db/database/seed-data.ts +60 -60
  1446. package/server/services/workshop/db/hitl-request.repo.ts +221 -221
  1447. package/server/services/workshop/db/notification.repo.ts +199 -199
  1448. package/server/services/workshop/db/readonly.ts +30 -30
  1449. package/server/services/workshop/db/scheduled-task.repo.ts +235 -235
  1450. package/server/services/workshop/db/transaction.ts +72 -72
  1451. package/server/services/workshop/dcw/dcw-controller/contracts.ts +16 -16
  1452. package/server/services/workshop/dcw/dcw-controller/control.ts +78 -78
  1453. package/server/services/workshop/dcw/dcw-controller/crud.ts +27 -2
  1454. package/server/services/workshop/dcw/dcw-controller/facade.ts +19 -19
  1455. package/server/services/workshop/dcw/dcw-controller/index.ts +22 -22
  1456. package/server/services/workshop/dcw/dcw-controller/lines.ts +14 -3
  1457. package/server/services/workshop/dcw/dcw-controller/params.ts +97 -97
  1458. package/server/services/workshop/dcw/dcw-controller/products.ts +103 -103
  1459. package/server/services/workshop/dcw/dcw-controller/recipes.ts +63 -5
  1460. package/server/services/workshop/dcw/dcw-controller/write.ts +12 -0
  1461. package/server/services/workshop/dcw/dcw-node.ts +13 -1
  1462. package/server/services/workshop/dcw/dcw-recipe.repo.ts +10 -1
  1463. package/server/services/workshop/dcw/dcw-runtime.ts +39 -15
  1464. package/server/services/workshop/dcw/dcw-templates.ts +136 -136
  1465. package/server/services/workshop/dcw/drivers/shared.ts +62 -6
  1466. package/server/services/workshop/dcw/param-conversion.ts +78 -78
  1467. package/server/services/workshop/dcw/param-map.repo.ts +349 -349
  1468. package/server/services/workshop/dcw/plugin-bridge.ts +45 -45
  1469. package/server/services/workshop/dcw/recipe-op-anchor.ts +28 -0
  1470. package/server/services/workshop/dcw/recipe-rollback-manager/contracts.ts +26 -26
  1471. package/server/services/workshop/dcw/recipe-rollback-manager/facade.ts +13 -13
  1472. package/server/services/workshop/dcw/recipe-rollback-manager/helpers.ts +30 -30
  1473. package/server/services/workshop/dcw/recipe-rollback-manager/index.ts +17 -17
  1474. package/server/services/workshop/dcw/recipe-rollback-manager/internal.ts +33 -33
  1475. package/server/services/workshop/dcw/recipe-rollback-manager/judge.ts +52 -52
  1476. package/server/services/workshop/dcw/recipe-rollback-manager/lock.ts +137 -137
  1477. package/server/services/workshop/dcw/recipe-rollback-manager/rollback.ts +204 -190
  1478. package/server/services/workshop/dcw/recipe-rollback-manager/state.ts +21 -21
  1479. package/server/services/workshop/dcw/recipe-rollback-manager/sweep.ts +97 -77
  1480. package/server/services/workshop/dcw/recipe-rollback-manager/types.ts +3 -3
  1481. package/server/services/workshop/dcw/recipe-rollback-manager/views.ts +214 -214
  1482. package/server/services/workshop/eda/template-repo.ts +101 -101
  1483. package/server/services/workshop/exp/exp-collector.ts +275 -275
  1484. package/server/services/workshop/exp/exp-state.repo.ts +339 -339
  1485. package/server/services/workshop/line-scope.ts +80 -0
  1486. package/server/services/workshop/mes/mes-controller.ts +1164 -1155
  1487. package/server/services/workshop/mes/mes-hook.ts +567 -567
  1488. package/server/services/workshop/ontology/subgraph.core.ts +300 -300
  1489. package/server/services/workshop/ontology/subgraph.service.ts +113 -113
  1490. package/server/services/workshop/ops/error-ledger.ts +209 -0
  1491. package/server/services/workshop/optimization/dispatch.service.ts +18 -2
  1492. package/server/services/workshop/permissions.ts +2 -0
  1493. package/server/services/workshop/plugins/host/api.mjs +90 -90
  1494. package/server/services/workshop/plugins/host/config.mjs +135 -135
  1495. package/server/services/workshop/plugins/host/index.mjs +23 -23
  1496. package/server/services/workshop/plugins/host/init.mjs +109 -109
  1497. package/server/services/workshop/plugins/host/rollback.mjs +72 -72
  1498. package/server/services/workshop/plugins/host/state.mjs +54 -54
  1499. package/server/services/workshop/plugins/host/toggle.mjs +64 -64
  1500. package/server/services/workshop/plugins/host.mjs +9 -9
  1501. package/server/services/workshop/runtime/agent-runtime/facade.ts +7 -7
  1502. package/server/services/workshop/runtime/agent-runtime/helpers.ts +18 -18
  1503. package/server/services/workshop/runtime/agent-runtime/index.ts +19 -19
  1504. package/server/services/workshop/runtime/agent-runtime/lifecycle.ts +137 -137
  1505. package/server/services/workshop/runtime/agent-runtime/message.ts +17 -0
  1506. package/server/services/workshop/runtime/agent-runtime/state.ts +9 -3
  1507. package/server/services/workshop/runtime/agent-runtime/types.ts +2 -1
  1508. package/server/services/workshop/runtime/channel-runtime.ts +3 -1
  1509. package/server/services/workshop/runtime/chat-mention.ts +164 -164
  1510. package/server/services/workshop/runtime/chat-projection.ts +246 -246
  1511. package/server/services/workshop/runtime/mailbox.ts +6 -3
  1512. package/server/services/workshop/runtime/manager/a2a.ts +4 -2
  1513. package/server/services/workshop/runtime/manager/admin-agents.ts +268 -268
  1514. package/server/services/workshop/runtime/manager/admin-channel.ts +1 -1
  1515. package/server/services/workshop/runtime/manager/bus.ts +182 -182
  1516. package/server/services/workshop/runtime/manager/channel-template-constants.ts +20 -20
  1517. package/server/services/workshop/runtime/manager/chat-reply.ts +181 -181
  1518. package/server/services/workshop/runtime/manager/chat.ts +386 -384
  1519. package/server/services/workshop/runtime/manager/facade.ts +24 -24
  1520. package/server/services/workshop/runtime/manager/helpers.ts +119 -119
  1521. package/server/services/workshop/runtime/manager/host-tools.ts +1 -1
  1522. package/server/services/workshop/runtime/manager/index.ts +42 -42
  1523. package/server/services/workshop/runtime/manager/internal.ts +73 -73
  1524. package/server/services/workshop/runtime/manager/notifications.ts +108 -108
  1525. package/server/services/workshop/runtime/manager/runtime-wiring.ts +31 -19
  1526. package/server/services/workshop/runtime/manager/state.ts +43 -1
  1527. package/server/services/workshop/runtime/manager/teams.ts +148 -148
  1528. package/server/services/workshop/runtime/memory/contracts.ts +18 -18
  1529. package/server/services/workshop/runtime/memory/facade.ts +10 -10
  1530. package/server/services/workshop/runtime/memory/helpers.ts +196 -196
  1531. package/server/services/workshop/runtime/memory/index.ts +27 -27
  1532. package/server/services/workshop/runtime/memory/score.ts +33 -33
  1533. package/server/services/workshop/runtime/memory/state.ts +40 -40
  1534. package/server/services/workshop/runtime/monitor.ts +3 -3
  1535. package/server/services/workshop/runtime/permission-scope.ts +21 -0
  1536. package/server/services/workshop/runtime/platform-notice.ts +113 -113
  1537. package/server/services/workshop/runtime/schedule-runtime.ts +347 -347
  1538. package/server/services/workshop/runtime/scheduler-loop/contracts.ts +29 -29
  1539. package/server/services/workshop/runtime/scheduler-loop/facade.ts +7 -7
  1540. package/server/services/workshop/runtime/scheduler-loop/helpers.ts +14 -14
  1541. package/server/services/workshop/runtime/scheduler-loop/index.ts +16 -16
  1542. package/server/services/workshop/runtime/scheduler-loop/tick.ts +16 -4
  1543. package/server/services/workshop/runtime/task-engine/facade.ts +7 -7
  1544. package/server/services/workshop/runtime/task-engine/index.ts +15 -15
  1545. package/server/services/workshop/runtime/task-engine/types.ts +3 -3
  1546. package/server/services/workshop/runtime/user-notification-hub.ts +192 -192
  1547. package/server/services/workshop/scene-events.ts +19 -0
  1548. package/server/types/pg.d.ts +49 -49
  1549. package/server/utils/approval-gate.ts +67 -67
  1550. package/server/utils/mojibake-guard.ts +29 -29
  1551. package/server/utils/stability-severity.ts +77 -77
  1552. package/shared/config/groups.mjs +241 -241
  1553. package/shared/daq-protocol.ts +24 -5
  1554. package/shared/dcw-protocol/catalog.ts +4 -4
  1555. package/shared/dcw-protocol/line.ts +4 -1
  1556. package/shared/lru.mjs +97 -97
  1557. package/tui/README.md +74 -74
  1558. package/tui/aw-tui.mjs +445 -445
  1559. package/tui/commands/index.mjs +287 -287
  1560. package/tui/components/chat-log.mjs +42 -42
  1561. package/tui/components/monitor-pane.mjs +39 -39
  1562. package/tui/components/root.mjs +53 -53
  1563. package/tui/components/status-bar.mjs +33 -33
  1564. package/tui/lib/api.mjs +82 -82
  1565. package/tui/lib/pickers.mjs +121 -121
  1566. package/tui/lib/reducers.mjs +218 -218
  1567. package/tui/lib/state.mjs +86 -86
  1568. package/tui/lib/virtual-terminal.mjs +48 -48
  1569. package/tui/lib/ws.mjs +125 -125
  1570. package/tui/theme.mjs +38 -38
  1571. package/.output/.AgentWorkShop/aml-python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  1572. package/.output/.AgentWorkShop/aml-python/__pycache__/amlkit.cpython-312.pyc +0 -0
  1573. package/.output/.AgentWorkShop/aml-python/__pycache__/train-example.cpython-312.pyc +0 -0
  1574. package/.output/.AgentWorkShop/aml-python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  1575. package/.output/public/_nuxt/-gy9k_TE2.js +0 -1
  1576. package/.output/public/_nuxt/26OL4Ao82.js +0 -1
  1577. package/.output/public/_nuxt/7OZQiw002.js +0 -1
  1578. package/.output/public/_nuxt/8b9CKi6F.js +0 -1
  1579. package/.output/public/_nuxt/B0UUODeh.js +0 -1
  1580. package/.output/public/_nuxt/B4GOTVfN.js +0 -1
  1581. package/.output/public/_nuxt/BBhroEeN.js +0 -1
  1582. package/.output/public/_nuxt/BHxG41IQ2.js +0 -1
  1583. package/.output/public/_nuxt/BPUQZ9Lq2.js +0 -8
  1584. package/.output/public/_nuxt/BVg2R2VB2.js +0 -1
  1585. package/.output/public/_nuxt/BZg_MIK42.js +0 -1
  1586. package/.output/public/_nuxt/BaYDgyaR.js +0 -3
  1587. package/.output/public/_nuxt/BfvuWqSa.js +0 -1
  1588. package/.output/public/_nuxt/BkEokGX5.js +0 -1
  1589. package/.output/public/_nuxt/BkO5WdX5.js +0 -1
  1590. package/.output/public/_nuxt/BqBTlfiz.js +0 -1
  1591. package/.output/public/_nuxt/BtZKe9ZV2.js +0 -1
  1592. package/.output/public/_nuxt/BwOko01T.js +0 -47
  1593. package/.output/public/_nuxt/BzBBEE-o2.js +0 -1
  1594. package/.output/public/_nuxt/C3vxePED.js +0 -21
  1595. package/.output/public/_nuxt/C4tXwpSt.js +0 -1
  1596. package/.output/public/_nuxt/CBkXv24C2.js +0 -1
  1597. package/.output/public/_nuxt/CCI-fwcS2.js +0 -1
  1598. package/.output/public/_nuxt/CGf9neEK2.js +0 -1
  1599. package/.output/public/_nuxt/CGviZq4E.js +0 -1
  1600. package/.output/public/_nuxt/CNrRZmSx2.js +0 -1
  1601. package/.output/public/_nuxt/CQ31GiJU2.js +0 -1
  1602. package/.output/public/_nuxt/CY_7u1ST2.js +0 -2
  1603. package/.output/public/_nuxt/CZJ5cw6r2.js +0 -1
  1604. package/.output/public/_nuxt/ChF6qLpY2.js +0 -1
  1605. package/.output/public/_nuxt/CjdxNYpU2.js +0 -1
  1606. package/.output/public/_nuxt/CmuGMxDP.js +0 -1
  1607. package/.output/public/_nuxt/Cr2xJ_CY.js +0 -1
  1608. package/.output/public/_nuxt/Cy_HDgSl.js +0 -20
  1609. package/.output/public/_nuxt/D1thFC3z.js +0 -1
  1610. package/.output/public/_nuxt/D8AvmPUH.js +0 -1
  1611. package/.output/public/_nuxt/D9GoOkyP2.js +0 -1
  1612. package/.output/public/_nuxt/D9ppMCbw.js +0 -1
  1613. package/.output/public/_nuxt/DGmFHb7m.js +0 -1
  1614. package/.output/public/_nuxt/DJaGVY4v2.js +0 -1
  1615. package/.output/public/_nuxt/DOUuGOQR2.js +0 -2
  1616. package/.output/public/_nuxt/DZqVVvR0.js +0 -1
  1617. package/.output/public/_nuxt/DZzbCFY2.js +0 -1
  1618. package/.output/public/_nuxt/DnuJ66Jy.js +0 -1
  1619. package/.output/public/_nuxt/DuUc4bbY2.js +0 -1
  1620. package/.output/public/_nuxt/EJkmXP432.js +0 -1
  1621. package/.output/public/_nuxt/EMbqTHfT.js +0 -1
  1622. package/.output/public/_nuxt/OmpTerminalPanel.ComMDrA8.css +0 -1
  1623. package/.output/public/_nuxt/PbzVdCTA2.js +0 -1
  1624. package/.output/public/_nuxt/PluginSlot.CGH0vb95.css +0 -1
  1625. package/.output/public/_nuxt/SgsmmrsZ.js +0 -1
  1626. package/.output/public/_nuxt/TownView.CC3t-Dte.css +0 -1
  1627. package/.output/public/_nuxt/U_n8pryv2.js +0 -1
  1628. package/.output/public/_nuxt/W0sNnJQh.js +0 -1
  1629. package/.output/public/_nuxt/_id_.BQRWK7J2.css +0 -1
  1630. package/.output/public/_nuxt/_wsId_.CQMH8t8j.css +0 -1
  1631. package/.output/public/_nuxt/ae2-5ZPt.js +0 -1
  1632. package/.output/public/_nuxt/agents.D-JPovTZ.css +0 -1
  1633. package/.output/public/_nuxt/aml.PalMp-5n.css +0 -1
  1634. package/.output/public/_nuxt/builds/meta/5cd11284-05bf-4fcd-9a69-56a01c9f56dd.json +0 -1
  1635. package/.output/public/_nuxt/byZYInPk2.js +0 -1
  1636. package/.output/public/_nuxt/dHwWyr6b.js +0 -1
  1637. package/.output/public/_nuxt/default.BEXGWZFQ.css +0 -1
  1638. package/.output/public/_nuxt/entry.D6nBdXet.css +0 -1
  1639. package/.output/public/_nuxt/gUYi1hLJ2.js +0 -16
  1640. package/.output/public/_nuxt/iqxZGXsY.js +0 -1
  1641. package/.output/public/_nuxt/logs.BkJPbR_K.css +0 -1
  1642. package/.output/public/_nuxt/monitor.D3yEqqrv.css +0 -1
  1643. package/.output/public/_nuxt/ontology.CkuUThtY.css +0 -1
  1644. package/.output/public/_nuxt/operations.-l6u44Ar.css +0 -1
  1645. package/.output/public/_nuxt/pages.Cdpm_B-G.css +0 -1
  1646. package/.output/public/_nuxt/permissions.DxuOOIqQ.css +0 -1
  1647. package/.output/public/_nuxt/rDvMijKA.js +0 -9
  1648. package/.output/public/_nuxt/schedules.BXNJ9q_I.css +0 -1
  1649. package/.output/public/_nuxt/teams.CLQaXno5.css +0 -1
  1650. package/.output/public/_nuxt/tokens.BDSUWF-L.css +0 -1
  1651. package/.output/public/_nuxt/tools.BwXFAb-X.css +0 -1
  1652. package/.output/public/_nuxt/workshop.BBiFhXuM.css +0 -1
  1653. package/.output/public/_nuxt/zWZ26UWi.js +0 -1
  1654. package/.output/server/chunks/build/AuthGate-nF1evO4v.mjs +0 -716
  1655. package/.output/server/chunks/build/AuthGate-nF1evO4v.mjs.map +0 -1
  1656. package/.output/server/chunks/build/FormItemContext-BlyzocS0.mjs +0 -72
  1657. package/.output/server/chunks/build/FormItemContext-BlyzocS0.mjs.map +0 -1
  1658. package/.output/server/chunks/build/OmpTerminalPanel-BhvhQ1gG.mjs +0 -942
  1659. package/.output/server/chunks/build/OmpTerminalPanel-BhvhQ1gG.mjs.map +0 -1
  1660. package/.output/server/chunks/build/PluginSlot-BUKXwV2X.mjs +0 -141
  1661. package/.output/server/chunks/build/PluginSlot-BUKXwV2X.mjs.map +0 -1
  1662. package/.output/server/chunks/build/TownView-BWMDbosY.mjs +0 -6489
  1663. package/.output/server/chunks/build/TownView-BWMDbosY.mjs.map +0 -1
  1664. package/.output/server/chunks/build/_id_-BK-t8nRG.mjs +0 -392
  1665. package/.output/server/chunks/build/_id_-BK-t8nRG.mjs.map +0 -1
  1666. package/.output/server/chunks/build/_id_-CZPlPDm4.mjs +0 -2045
  1667. package/.output/server/chunks/build/_id_-CZPlPDm4.mjs.map +0 -1
  1668. package/.output/server/chunks/build/_wsId_-C871SDPN.mjs +0 -14589
  1669. package/.output/server/chunks/build/_wsId_-C871SDPN.mjs.map +0 -1
  1670. package/.output/server/chunks/build/agents-D7CdEUTv.mjs +0 -1078
  1671. package/.output/server/chunks/build/agents-D7CdEUTv.mjs.map +0 -1
  1672. package/.output/server/chunks/build/alert-D0ivtTGy.mjs +0 -263
  1673. package/.output/server/chunks/build/alert-D0ivtTGy.mjs.map +0 -1
  1674. package/.output/server/chunks/build/aml-DRAFRcGU.mjs +0 -814
  1675. package/.output/server/chunks/build/aml-DRAFRcGU.mjs.map +0 -1
  1676. package/.output/server/chunks/build/analysis-p-dBkjoK.mjs +0 -533
  1677. package/.output/server/chunks/build/analysis-p-dBkjoK.mjs.map +0 -1
  1678. package/.output/server/chunks/build/api-B4Om0mEc.mjs +0 -53
  1679. package/.output/server/chunks/build/api-B4Om0mEc.mjs.map +0 -1
  1680. package/.output/server/chunks/build/api-BEW_ebY_.mjs +0 -64
  1681. package/.output/server/chunks/build/api-BEW_ebY_.mjs.map +0 -1
  1682. package/.output/server/chunks/build/api-BsAgXWxi.mjs +0 -72
  1683. package/.output/server/chunks/build/api-BsAgXWxi.mjs.map +0 -1
  1684. package/.output/server/chunks/build/api-error-BwAQLw44.mjs +0 -47
  1685. package/.output/server/chunks/build/api-error-BwAQLw44.mjs.map +0 -1
  1686. package/.output/server/chunks/build/apiClient-BvXtNzC8.mjs +0 -81
  1687. package/.output/server/chunks/build/apiClient-BvXtNzC8.mjs.map +0 -1
  1688. package/.output/server/chunks/build/board-CJUc032b.mjs +0 -189
  1689. package/.output/server/chunks/build/board-CJUc032b.mjs.map +0 -1
  1690. package/.output/server/chunks/build/builtin-catalog-edpDcgfL.mjs.map +0 -1
  1691. package/.output/server/chunks/build/card-Cqk0Ur-L.mjs +0 -953
  1692. package/.output/server/chunks/build/card-Cqk0Ur-L.mjs.map +0 -1
  1693. package/.output/server/chunks/build/channel-templates-ggsBacZF.mjs +0 -942
  1694. package/.output/server/chunks/build/channel-templates-ggsBacZF.mjs.map +0 -1
  1695. package/.output/server/chunks/build/chart-pipeline-BpoWYMK_.mjs.map +0 -1
  1696. package/.output/server/chunks/build/chart-trend-BWeZh5Lv.mjs.map +0 -1
  1697. package/.output/server/chunks/build/checkbox-CrT4cnfu.mjs +0 -439
  1698. package/.output/server/chunks/build/checkbox-CrT4cnfu.mjs.map +0 -1
  1699. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs +0 -43
  1700. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs.map +0 -1
  1701. package/.output/server/chunks/build/constants-HPHJvjne.mjs +0 -142
  1702. package/.output/server/chunks/build/constants-HPHJvjne.mjs.map +0 -1
  1703. package/.output/server/chunks/build/core-CgTOPS4t.mjs +0 -294
  1704. package/.output/server/chunks/build/core-CgTOPS4t.mjs.map +0 -1
  1705. package/.output/server/chunks/build/daq-CdxcfY_G.mjs +0 -1266
  1706. package/.output/server/chunks/build/daq-CdxcfY_G.mjs.map +0 -1
  1707. package/.output/server/chunks/build/data-D8uX1dnm.mjs +0 -481
  1708. package/.output/server/chunks/build/data-D8uX1dnm.mjs.map +0 -1
  1709. package/.output/server/chunks/build/dcw-BlDQtS4q.mjs +0 -505
  1710. package/.output/server/chunks/build/dcw-BlDQtS4q.mjs.map +0 -1
  1711. package/.output/server/chunks/build/dcw-driver-badge-Df5wL_ZA.mjs.map +0 -1
  1712. package/.output/server/chunks/build/default-CNWS6NUw.mjs +0 -2353
  1713. package/.output/server/chunks/build/default-CNWS6NUw.mjs.map +0 -1
  1714. package/.output/server/chunks/build/descriptions-BNlfKG9y.mjs +0 -406
  1715. package/.output/server/chunks/build/descriptions-BNlfKG9y.mjs.map +0 -1
  1716. package/.output/server/chunks/build/drawer-Caji0PLs.mjs +0 -834
  1717. package/.output/server/chunks/build/drawer-Caji0PLs.mjs.map +0 -1
  1718. package/.output/server/chunks/build/dropdown-BNwTVGde.mjs +0 -14
  1719. package/.output/server/chunks/build/dropdown-BNwTVGde.mjs.map +0 -1
  1720. package/.output/server/chunks/build/dropdown-Cd-xPhR6.mjs +0 -540
  1721. package/.output/server/chunks/build/dropdown-Cd-xPhR6.mjs.map +0 -1
  1722. package/.output/server/chunks/build/es-Bxu10NJ2.mjs +0 -43
  1723. package/.output/server/chunks/build/es-Bxu10NJ2.mjs.map +0 -1
  1724. package/.output/server/chunks/build/firstNotUndefined-8H5_qHUu.mjs +0 -2448
  1725. package/.output/server/chunks/build/firstNotUndefined-8H5_qHUu.mjs.map +0 -1
  1726. package/.output/server/chunks/build/form-D_UpWPN4.mjs +0 -4712
  1727. package/.output/server/chunks/build/form-D_UpWPN4.mjs.map +0 -1
  1728. package/.output/server/chunks/build/hasIn-DBdElbjM.mjs +0 -553
  1729. package/.output/server/chunks/build/hasIn-DBdElbjM.mjs.map +0 -1
  1730. package/.output/server/chunks/build/hitl-Bd30yr1J.mjs +0 -132
  1731. package/.output/server/chunks/build/hitl-Bd30yr1J.mjs.map +0 -1
  1732. package/.output/server/chunks/build/input-GtPuSEgt.mjs +0 -2181
  1733. package/.output/server/chunks/build/input-GtPuSEgt.mjs.map +0 -1
  1734. package/.output/server/chunks/build/input-number-BNlNDK7H.mjs +0 -1120
  1735. package/.output/server/chunks/build/input-number-BNlNDK7H.mjs.map +0 -1
  1736. package/.output/server/chunks/build/interval-DvHBIIZh.mjs +0 -9
  1737. package/.output/server/chunks/build/interval-DvHBIIZh.mjs.map +0 -1
  1738. package/.output/server/chunks/build/isNumeric-CP7q_yhz.mjs +0 -7
  1739. package/.output/server/chunks/build/isNumeric-CP7q_yhz.mjs.map +0 -1
  1740. package/.output/server/chunks/build/logs-pRb-TMWa.mjs +0 -427
  1741. package/.output/server/chunks/build/logs-pRb-TMWa.mjs.map +0 -1
  1742. package/.output/server/chunks/build/menu-BXt-X0dt.mjs +0 -1952
  1743. package/.output/server/chunks/build/menu-BXt-X0dt.mjs.map +0 -1
  1744. package/.output/server/chunks/build/monitor-Cq6hRFeQ.mjs +0 -2253
  1745. package/.output/server/chunks/build/monitor-Cq6hRFeQ.mjs.map +0 -1
  1746. package/.output/server/chunks/build/narrow-fetch-CcG-BPxc.mjs.map +0 -1
  1747. package/.output/server/chunks/build/ontology-ohICfVVb.mjs +0 -1406
  1748. package/.output/server/chunks/build/ontology-ohICfVVb.mjs.map +0 -1
  1749. package/.output/server/chunks/build/operations-SMQrRAcr.mjs +0 -311
  1750. package/.output/server/chunks/build/operations-SMQrRAcr.mjs.map +0 -1
  1751. package/.output/server/chunks/build/optimizer-BlWTsM-W.mjs +0 -202
  1752. package/.output/server/chunks/build/optimizer-BlWTsM-W.mjs.map +0 -1
  1753. package/.output/server/chunks/build/pages-DsMKUw7i.mjs +0 -542
  1754. package/.output/server/chunks/build/pages-DsMKUw7i.mjs.map +0 -1
  1755. package/.output/server/chunks/build/pagination-DTAconUo.mjs +0 -1346
  1756. package/.output/server/chunks/build/pagination-DTAconUo.mjs.map +0 -1
  1757. package/.output/server/chunks/build/permissions-DgXQZSyx.mjs +0 -637
  1758. package/.output/server/chunks/build/permissions-DgXQZSyx.mjs.map +0 -1
  1759. package/.output/server/chunks/build/pipeline-CkavMBhk.mjs +0 -212
  1760. package/.output/server/chunks/build/pipeline-CkavMBhk.mjs.map +0 -1
  1761. package/.output/server/chunks/build/plugins-LRjaSEZy.mjs +0 -272
  1762. package/.output/server/chunks/build/plugins-LRjaSEZy.mjs.map +0 -1
  1763. package/.output/server/chunks/build/popconfirm-DxYPGRgS.mjs +0 -340
  1764. package/.output/server/chunks/build/popconfirm-DxYPGRgS.mjs.map +0 -1
  1765. package/.output/server/chunks/build/responsiveObserve-DM3hpzhU.mjs +0 -78
  1766. package/.output/server/chunks/build/responsiveObserve-DM3hpzhU.mjs.map +0 -1
  1767. package/.output/server/chunks/build/schedules-Hz2DJUE2.mjs +0 -7172
  1768. package/.output/server/chunks/build/schedules-Hz2DJUE2.mjs.map +0 -1
  1769. package/.output/server/chunks/build/segmented-D3HWtHPw.mjs +0 -341
  1770. package/.output/server/chunks/build/segmented-D3HWtHPw.mjs.map +0 -1
  1771. package/.output/server/chunks/build/select-B3Dsb9yq.mjs +0 -3923
  1772. package/.output/server/chunks/build/select-B3Dsb9yq.mjs.map +0 -1
  1773. package/.output/server/chunks/build/settings-DXLJPq7d.mjs +0 -1014
  1774. package/.output/server/chunks/build/settings-DXLJPq7d.mjs.map +0 -1
  1775. package/.output/server/chunks/build/space-Dwu2Skt8.mjs +0 -110
  1776. package/.output/server/chunks/build/space-Dwu2Skt8.mjs.map +0 -1
  1777. package/.output/server/chunks/build/spin-C2cuvGth.mjs +0 -357
  1778. package/.output/server/chunks/build/spin-C2cuvGth.mjs.map +0 -1
  1779. package/.output/server/chunks/build/studio-hSqH9TYS.mjs +0 -336
  1780. package/.output/server/chunks/build/studio-hSqH9TYS.mjs.map +0 -1
  1781. package/.output/server/chunks/build/switch-CyR-H6Fb.mjs +0 -377
  1782. package/.output/server/chunks/build/switch-CyR-H6Fb.mjs.map +0 -1
  1783. package/.output/server/chunks/build/table-CmVD-cA9.mjs +0 -7546
  1784. package/.output/server/chunks/build/table-CmVD-cA9.mjs.map +0 -1
  1785. package/.output/server/chunks/build/tabs-Vg0e7cZE.mjs +0 -1924
  1786. package/.output/server/chunks/build/tabs-Vg0e7cZE.mjs.map +0 -1
  1787. package/.output/server/chunks/build/tag-y0sn-xv9.mjs +0 -1156
  1788. package/.output/server/chunks/build/tag-y0sn-xv9.mjs.map +0 -1
  1789. package/.output/server/chunks/build/teams-BbwYJyzv.mjs +0 -1203
  1790. package/.output/server/chunks/build/teams-BbwYJyzv.mjs.map +0 -1
  1791. package/.output/server/chunks/build/tokens-GYaGJ35Z.mjs +0 -1062
  1792. package/.output/server/chunks/build/tokens-GYaGJ35Z.mjs.map +0 -1
  1793. package/.output/server/chunks/build/tools-CnYi9cou.mjs +0 -487
  1794. package/.output/server/chunks/build/tools-CnYi9cou.mjs.map +0 -1
  1795. package/.output/server/chunks/build/tooltip-C2n2nNiQ.mjs +0 -920
  1796. package/.output/server/chunks/build/tooltip-C2n2nNiQ.mjs.map +0 -1
  1797. package/.output/server/chunks/build/town-B5aoiG98.mjs +0 -133
  1798. package/.output/server/chunks/build/town-B5aoiG98.mjs.map +0 -1
  1799. package/.output/server/chunks/build/town-BV-hbwb5.mjs +0 -75
  1800. package/.output/server/chunks/build/town-BV-hbwb5.mjs.map +0 -1
  1801. package/.output/server/chunks/build/types-D6J7slEa.mjs +0 -5565
  1802. package/.output/server/chunks/build/types-D6J7slEa.mjs.map +0 -1
  1803. package/.output/server/chunks/build/types-DWqIeMRP.mjs +0 -76
  1804. package/.output/server/chunks/build/types-DWqIeMRP.mjs.map +0 -1
  1805. package/.output/server/chunks/build/useAgentHarnessOptions-Dq0l0Z6d.mjs +0 -124
  1806. package/.output/server/chunks/build/useAgentHarnessOptions-Dq0l0Z6d.mjs.map +0 -1
  1807. package/.output/server/chunks/build/useAgentTemplateActions-BFOHb5-L.mjs +0 -77
  1808. package/.output/server/chunks/build/useAgentTemplateActions-BFOHb5-L.mjs.map +0 -1
  1809. package/.output/server/chunks/build/useAgentTemplateDialogState-CZzpu5og.mjs +0 -67
  1810. package/.output/server/chunks/build/useAgentTemplateDialogState-CZzpu5og.mjs.map +0 -1
  1811. package/.output/server/chunks/build/useAgentTemplateForm-CuJPOPcK.mjs +0 -117
  1812. package/.output/server/chunks/build/useAgentTemplateForm-CuJPOPcK.mjs.map +0 -1
  1813. package/.output/server/chunks/build/useAgentTemplatesCatalog-B2bIhZLA.mjs +0 -133
  1814. package/.output/server/chunks/build/useAgentTemplatesCatalog-B2bIhZLA.mjs.map +0 -1
  1815. package/.output/server/chunks/build/useAmlDatasets-DeoE1idn.mjs +0 -92
  1816. package/.output/server/chunks/build/useAmlDatasets-DeoE1idn.mjs.map +0 -1
  1817. package/.output/server/chunks/build/useAmlEntities-BJhvdqHJ.mjs +0 -86
  1818. package/.output/server/chunks/build/useAmlEntities-BJhvdqHJ.mjs.map +0 -1
  1819. package/.output/server/chunks/build/useAmlEnv-CDIZ6xTe.mjs +0 -194
  1820. package/.output/server/chunks/build/useAmlEnv-CDIZ6xTe.mjs.map +0 -1
  1821. package/.output/server/chunks/build/useAmlExperiments-Dloi834i.mjs +0 -89
  1822. package/.output/server/chunks/build/useAmlExperiments-Dloi834i.mjs.map +0 -1
  1823. package/.output/server/chunks/build/useAmlFormat-C2sl3MGB.mjs +0 -82
  1824. package/.output/server/chunks/build/useAmlFormat-C2sl3MGB.mjs.map +0 -1
  1825. package/.output/server/chunks/build/useAmlJobs-BF9LpwXz.mjs +0 -267
  1826. package/.output/server/chunks/build/useAmlJobs-BF9LpwXz.mjs.map +0 -1
  1827. package/.output/server/chunks/build/useAmlModels-_bweOr3R.mjs +0 -93
  1828. package/.output/server/chunks/build/useAmlModels-_bweOr3R.mjs.map +0 -1
  1829. package/.output/server/chunks/build/useAmlNotes-DQj980iX.mjs +0 -86
  1830. package/.output/server/chunks/build/useAmlNotes-DQj980iX.mjs.map +0 -1
  1831. package/.output/server/chunks/build/useAmlPredict-DHNgDSJn.mjs +0 -130
  1832. package/.output/server/chunks/build/useAmlPredict-DHNgDSJn.mjs.map +0 -1
  1833. package/.output/server/chunks/build/useAnalysisFeed-BrEGV_9x.mjs +0 -129
  1834. package/.output/server/chunks/build/useAnalysisFeed-BrEGV_9x.mjs.map +0 -1
  1835. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs +0 -142
  1836. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs.map +0 -1
  1837. package/.output/server/chunks/build/useDaqDetailBinding-DCWaLKXT.mjs +0 -70
  1838. package/.output/server/chunks/build/useDaqDetailBinding-DCWaLKXT.mjs.map +0 -1
  1839. package/.output/server/chunks/build/useDaqDetailFrames-BOIcOJRB.mjs +0 -79
  1840. package/.output/server/chunks/build/useDaqDetailFrames-BOIcOJRB.mjs.map +0 -1
  1841. package/.output/server/chunks/build/useDaqDetailHistory-D6WulPVs.mjs +0 -176
  1842. package/.output/server/chunks/build/useDaqDetailHistory-D6WulPVs.mjs.map +0 -1
  1843. package/.output/server/chunks/build/useDaqDetailNode-DeOsDxK5.mjs +0 -99
  1844. package/.output/server/chunks/build/useDaqDetailNode-DeOsDxK5.mjs.map +0 -1
  1845. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs +0 -159
  1846. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs.map +0 -1
  1847. package/.output/server/chunks/build/useDaqFilters-CctmO03p.mjs +0 -222
  1848. package/.output/server/chunks/build/useDaqFilters-CctmO03p.mjs.map +0 -1
  1849. package/.output/server/chunks/build/useDaqNodeWindow-1DWj2H5G.mjs +0 -90
  1850. package/.output/server/chunks/build/useDaqNodeWindow-1DWj2H5G.mjs.map +0 -1
  1851. package/.output/server/chunks/build/useDaqOptimizations-CmX_dpBc.mjs +0 -136
  1852. package/.output/server/chunks/build/useDaqOptimizations-CmX_dpBc.mjs.map +0 -1
  1853. package/.output/server/chunks/build/useDaqStream-B9ZBVQrI.mjs +0 -395
  1854. package/.output/server/chunks/build/useDaqStream-B9ZBVQrI.mjs.map +0 -1
  1855. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs +0 -187
  1856. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs.map +0 -1
  1857. package/.output/server/chunks/build/useDashboardCharts-D45083s_.mjs +0 -354
  1858. package/.output/server/chunks/build/useDashboardCharts-D45083s_.mjs.map +0 -1
  1859. package/.output/server/chunks/build/useDashboardData-NJ7rKxhx.mjs +0 -153
  1860. package/.output/server/chunks/build/useDashboardData-NJ7rKxhx.mjs.map +0 -1
  1861. package/.output/server/chunks/build/useDcwAddNode-DACVcEHs.mjs +0 -219
  1862. package/.output/server/chunks/build/useDcwAddNode-DACVcEHs.mjs.map +0 -1
  1863. package/.output/server/chunks/build/useDcwCards-SaiImIYQ.mjs +0 -67
  1864. package/.output/server/chunks/build/useDcwCards-SaiImIYQ.mjs.map +0 -1
  1865. package/.output/server/chunks/build/useDcwDetailScope-DLOklSMO.mjs +0 -184
  1866. package/.output/server/chunks/build/useDcwDetailScope-DLOklSMO.mjs.map +0 -1
  1867. package/.output/server/chunks/build/useDcwDetailTemplates-ClmIdZ40.mjs +0 -148
  1868. package/.output/server/chunks/build/useDcwDetailTemplates-ClmIdZ40.mjs.map +0 -1
  1869. package/.output/server/chunks/build/useDcwFilter-CPMyCltx.mjs +0 -71
  1870. package/.output/server/chunks/build/useDcwFilter-CPMyCltx.mjs.map +0 -1
  1871. package/.output/server/chunks/build/useDcwLedger-0ie-0WTc.mjs +0 -79
  1872. package/.output/server/chunks/build/useDcwLedger-0ie-0WTc.mjs.map +0 -1
  1873. package/.output/server/chunks/build/useDcwLineMutations-DNxo66yM.mjs +0 -137
  1874. package/.output/server/chunks/build/useDcwLineMutations-DNxo66yM.mjs.map +0 -1
  1875. package/.output/server/chunks/build/useDcwLineRun-CHskwscT.mjs +0 -104
  1876. package/.output/server/chunks/build/useDcwLineRun-CHskwscT.mjs.map +0 -1
  1877. package/.output/server/chunks/build/useDcwParamApprovals-DtScUc-W.mjs +0 -121
  1878. package/.output/server/chunks/build/useDcwParamApprovals-DtScUc-W.mjs.map +0 -1
  1879. package/.output/server/chunks/build/useDcwProducts-BMaxzLu6.mjs +0 -93
  1880. package/.output/server/chunks/build/useDcwProducts-BMaxzLu6.mjs.map +0 -1
  1881. package/.output/server/chunks/build/useDcwQuery-TVU3Eo0M.mjs +0 -98
  1882. package/.output/server/chunks/build/useDcwQuery-TVU3Eo0M.mjs.map +0 -1
  1883. package/.output/server/chunks/build/useDcwQuickActions-BREFmR9T.mjs +0 -88
  1884. package/.output/server/chunks/build/useDcwQuickActions-BREFmR9T.mjs.map +0 -1
  1885. package/.output/server/chunks/build/useDcwRecipes-Bc9urA1N.mjs +0 -258
  1886. package/.output/server/chunks/build/useDcwRecipes-Bc9urA1N.mjs.map +0 -1
  1887. package/.output/server/chunks/build/useDcwStream-Dir5ufAU.mjs +0 -452
  1888. package/.output/server/chunks/build/useDcwStream-Dir5ufAU.mjs.map +0 -1
  1889. package/.output/server/chunks/build/useDcwTemplates-BzagZztS.mjs +0 -91
  1890. package/.output/server/chunks/build/useDcwTemplates-BzagZztS.mjs.map +0 -1
  1891. package/.output/server/chunks/build/useDcwWrites-BROwTLCn.mjs +0 -140
  1892. package/.output/server/chunks/build/useDcwWrites-BROwTLCn.mjs.map +0 -1
  1893. package/.output/server/chunks/build/useDeviceTwins-BqwVJaZg.mjs +0 -128
  1894. package/.output/server/chunks/build/useDeviceTwins-BqwVJaZg.mjs.map +0 -1
  1895. package/.output/server/chunks/build/useExpConfirmations-BM626N4p.mjs +0 -107
  1896. package/.output/server/chunks/build/useExpConfirmations-BM626N4p.mjs.map +0 -1
  1897. package/.output/server/chunks/build/useLocalTime-uVSM44Um.mjs +0 -55
  1898. package/.output/server/chunks/build/useLocalTime-uVSM44Um.mjs.map +0 -1
  1899. package/.output/server/chunks/build/useLogsFormat-B-o4MHy7.mjs +0 -77
  1900. package/.output/server/chunks/build/useLogsFormat-B-o4MHy7.mjs.map +0 -1
  1901. package/.output/server/chunks/build/useLogsManual-cVBZQ_Mt.mjs +0 -88
  1902. package/.output/server/chunks/build/useLogsManual-cVBZQ_Mt.mjs.map +0 -1
  1903. package/.output/server/chunks/build/useLogsQuery-D7hrJ3yn.mjs +0 -150
  1904. package/.output/server/chunks/build/useLogsQuery-D7hrJ3yn.mjs.map +0 -1
  1905. package/.output/server/chunks/build/useLogsScope-aaPQeTRm.mjs +0 -83
  1906. package/.output/server/chunks/build/useLogsScope-aaPQeTRm.mjs.map +0 -1
  1907. package/.output/server/chunks/build/useMonitorColumns-vVnt3r5Q.mjs +0 -217
  1908. package/.output/server/chunks/build/useMonitorColumns-vVnt3r5Q.mjs.map +0 -1
  1909. package/.output/server/chunks/build/useMonitorData-DIkiLr_h.mjs +0 -135
  1910. package/.output/server/chunks/build/useMonitorData-DIkiLr_h.mjs.map +0 -1
  1911. package/.output/server/chunks/build/useMonitorFormat-CyURtH8N.mjs +0 -91
  1912. package/.output/server/chunks/build/useMonitorFormat-CyURtH8N.mjs.map +0 -1
  1913. package/.output/server/chunks/build/useMonitorTerminal-Dj4QwRNW.mjs +0 -71
  1914. package/.output/server/chunks/build/useMonitorTerminal-Dj4QwRNW.mjs.map +0 -1
  1915. package/.output/server/chunks/build/useOperationsFeed-Ci4mZAn_.mjs +0 -195
  1916. package/.output/server/chunks/build/useOperationsFeed-Ci4mZAn_.mjs.map +0 -1
  1917. package/.output/server/chunks/build/useOpsLog-C-M6Eace.mjs +0 -149
  1918. package/.output/server/chunks/build/useOpsLog-C-M6Eace.mjs.map +0 -1
  1919. package/.output/server/chunks/build/useRecipeDispatchApprovals-BYtiqfeb.mjs +0 -156
  1920. package/.output/server/chunks/build/useRecipeDispatchApprovals-BYtiqfeb.mjs.map +0 -1
  1921. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +0 -1
  1922. package/.output/server/chunks/build/useTeamActions-BDjU06LP.mjs +0 -79
  1923. package/.output/server/chunks/build/useTeamActions-BDjU06LP.mjs.map +0 -1
  1924. package/.output/server/chunks/build/useTeamAddMemberDialog-J3oFn3FI.mjs +0 -84
  1925. package/.output/server/chunks/build/useTeamAddMemberDialog-J3oFn3FI.mjs.map +0 -1
  1926. package/.output/server/chunks/build/useTeamCreateDialog-fbn4ixYu.mjs +0 -97
  1927. package/.output/server/chunks/build/useTeamCreateDialog-fbn4ixYu.mjs.map +0 -1
  1928. package/.output/server/chunks/build/useTeamDeployDialog-BNezMD2k.mjs +0 -80
  1929. package/.output/server/chunks/build/useTeamDeployDialog-BNezMD2k.mjs.map +0 -1
  1930. package/.output/server/chunks/build/useTeamDialogState-CFRUQxAf.mjs +0 -82
  1931. package/.output/server/chunks/build/useTeamDialogState-CFRUQxAf.mjs.map +0 -1
  1932. package/.output/server/chunks/build/useTeamPluginDialog-BZznrOVe.mjs +0 -103
  1933. package/.output/server/chunks/build/useTeamPluginDialog-BZznrOVe.mjs.map +0 -1
  1934. package/.output/server/chunks/build/useTeamsCatalog-DuZFP3oG.mjs +0 -123
  1935. package/.output/server/chunks/build/useTeamsCatalog-DuZFP3oG.mjs.map +0 -1
  1936. package/.output/server/chunks/build/useTokenClipboard-CwQpoFeP.mjs +0 -72
  1937. package/.output/server/chunks/build/useTokenClipboard-CwQpoFeP.mjs.map +0 -1
  1938. package/.output/server/chunks/build/useTokenCreate-Ctl0YGhL.mjs +0 -115
  1939. package/.output/server/chunks/build/useTokenCreate-Ctl0YGhL.mjs.map +0 -1
  1940. package/.output/server/chunks/build/useTokenRename-Cm3ypSfN.mjs +0 -87
  1941. package/.output/server/chunks/build/useTokenRename-Cm3ypSfN.mjs.map +0 -1
  1942. package/.output/server/chunks/build/useTokenReveal-CeoWL5Mt.mjs +0 -118
  1943. package/.output/server/chunks/build/useTokenReveal-CeoWL5Mt.mjs.map +0 -1
  1944. package/.output/server/chunks/build/useTokensList-CNIzON3u.mjs +0 -92
  1945. package/.output/server/chunks/build/useTokensList-CNIzON3u.mjs.map +0 -1
  1946. package/.output/server/chunks/build/useTownBus-D9SoIsAN.mjs.map +0 -1
  1947. package/.output/server/chunks/build/useWorkbenchAuth-CY-bVFMu.mjs +0 -141
  1948. package/.output/server/chunks/build/useWorkbenchAuth-CY-bVFMu.mjs.map +0 -1
  1949. package/.output/server/chunks/build/useWorkbenchWorkspaces-DhZQFss9.mjs +0 -138
  1950. package/.output/server/chunks/build/useWorkbenchWorkspaces-DhZQFss9.mjs.map +0 -1
  1951. package/.output/server/chunks/build/useWorkshopApi-BxHn-4iR.mjs +0 -127
  1952. package/.output/server/chunks/build/useWorkshopApi-BxHn-4iR.mjs.map +0 -1
  1953. package/.output/server/chunks/build/useWorkshopWs-YQ5URrbt.mjs +0 -1659
  1954. package/.output/server/chunks/build/useWorkshopWs-YQ5URrbt.mjs.map +0 -1
  1955. package/.output/server/chunks/build/useWorkspaceAuth-Dlvj9csD.mjs +0 -60
  1956. package/.output/server/chunks/build/useWorkspaceAuth-Dlvj9csD.mjs.map +0 -1
  1957. package/.output/server/chunks/build/useWorkspaceChannels-CPFepxTN.mjs +0 -92
  1958. package/.output/server/chunks/build/useWorkspaceChannels-CPFepxTN.mjs.map +0 -1
  1959. package/.output/server/chunks/build/useWorkspacePanels-CTwREmq0.mjs +0 -78
  1960. package/.output/server/chunks/build/useWorkspacePanels-CTwREmq0.mjs.map +0 -1
  1961. package/.output/server/chunks/build/useWorkspaceShell-BCypjjjE.mjs +0 -168
  1962. package/.output/server/chunks/build/useWorkspaceShell-BCypjjjE.mjs.map +0 -1
  1963. package/.output/server/chunks/build/users-DjiVC_tS.mjs +0 -569
  1964. package/.output/server/chunks/build/users-DjiVC_tS.mjs.map +0 -1
  1965. package/.output/server/chunks/build/workshop-1gKeDASV.mjs +0 -546
  1966. package/.output/server/chunks/build/workshop-1gKeDASV.mjs.map +0 -1
  1967. package/.output/server/chunks/build/workspaces-CmW0cpOt.mjs.map +0 -1
  1968. package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.json +0 -1
  1969. package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/1459e6269990a5d229b9228c8b2f62ffaa7d350068380ae8b875fee0db45cca6.source +0 -180
  1970. package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/c2991e909c70c5c12b90a407c7adcf63384c51668a2b334e6e047fa675c268fe.source +0 -305
  1971. package/app/.mimosa/hook-state/sess_05189059-e42d-4188-8911-4f7baabe009b.mtg0vz68-49792-75b0709555.baseline/e09129039d1e27e3fac24becc9bdafd2d1a7c8049bff24173df007be865f0165.source +0 -264
  1972. package/app/.mimosa/hook-status/sess_05189059-e42d-4188-8911-4f7baabe009b-28ef7c75ea.json +0 -14
  1973. package/server/.mimosa/hook-state/sess_869e5bfd-07f4-4b6e-a991-6221fcf6b7d2.json +0 -1
  1974. package/server/.mimosa/hook-state/sess_869e5bfd-07f4-4b6e-a991-6221fcf6b7d2.mvhn1irp-99488-e3fdc1cbfc.baseline/942d2679b87b96c612b4f2a425c3ccc5b6f3234f0cf589a8441602f866fbe277.source +0 -41
  1975. package/server/.mimosa/hook-state/sess_869e5bfd-07f4-4b6e-a991-6221fcf6b7d2.mvhn1irp-99488-e3fdc1cbfc.baseline/dd617a82339d2c61e49e28e416aabeb2fc100fb3cb1beca18d02dfb833214af6.source +0 -51
  1976. package/server/.mimosa/hook-status/sess_869e5bfd-07f4-4b6e-a991-6221fcf6b7d2-e67b6b91bf.json +0 -14
  1977. package/server/services/workshop/.mimosa/hook-state/sess_fed429fb-c8b7-4a50-bbd6-45afc580893f.json +0 -1
  1978. package/server/services/workshop/.mimosa/hook-status/sess_fed429fb-c8b7-4a50-bbd6-45afc580893f-e6b75bbfe6.json +0 -14
  1979. package/server/services/workshop/aml/python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  1980. package/server/services/workshop/aml/python/__pycache__/amlkit.cpython-312.pyc +0 -0
  1981. package/server/services/workshop/aml/python/__pycache__/train-example.cpython-312.pyc +0 -0
  1982. package/server/services/workshop/aml/python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  1983. package/server/services/workshop/optimization/python/.mimosa/hook-state/session_187ec97f45d4bd02369bbe94da527cf1.json +0 -1
  1984. package/server/services/workshop/optimization/python/.mimosa/hook-state/session_187ec97f45d4bd02369bbe94da527cf1.mvjqkcs6-68688-fb7131a89c.baseline/190a6772a4e43801737b4ba6072eb9d53d3099b5d8a9e6f57bc5e8592a26a6c4.source +0 -274
  1985. package/server/services/workshop/optimization/python/.mimosa/hook-status/session_187ec97f45d4bd02369bbe94da527cf1-01ed7f04fa.json +0 -14
  1986. package/server/services/workshop/optimization/python/__pycache__/problems.cpython-312.pyc +0 -0
  1987. /package/.output/public/_nuxt/{6P4ZAzxa2.js → 6P4ZAzxa.js} +0 -0
  1988. /package/.output/public/_nuxt/{9j2J4k4w.js → 9j2J4k4w2.js} +0 -0
  1989. /package/.output/public/_nuxt/{DgrK8UCQ.js → BvRk9kiK2.js} +0 -0
  1990. /package/.output/public/_nuxt/{dVw8IHY62.js → dVw8IHY6.js} +0 -0
  1991. /package/.output/public/_nuxt/{k9b520K-.js → k9b520K-2.js} +0 -0
  1992. /package/.output/server/chunks/{build → _}/builtin-catalog-edpDcgfL.mjs +0 -0
  1993. /package/.output/server/chunks/{build → _}/chart-pipeline-BpoWYMK_.mjs +0 -0
  1994. /package/.output/server/chunks/{build → _}/chart-trend-BWeZh5Lv.mjs +0 -0
  1995. /package/.output/server/chunks/{build → _}/dcw-driver-badge-Df5wL_ZA.mjs +0 -0
  1996. /package/.output/server/chunks/{build → _}/narrow-fetch-CcG-BPxc.mjs +0 -0
  1997. /package/.output/server/chunks/{build → _}/useResponsive-BKDMGTHs.mjs +0 -0
  1998. /package/.output/server/chunks/{build → _}/useTownBus-D9SoIsAN.mjs +0 -0
  1999. /package/.output/server/chunks/{build → _}/workspaces-CmW0cpOt.mjs +0 -0
@@ -1,1155 +1,1164 @@
1
- /**
2
- * MES 取数控制器(Agent 工具后端)—— mes-rest 点位目录 + 历史取数编排。
3
- *
4
- * 护栏全部**代码级**(不是提示词):绑线授权过滤、时间窗 ≤7 天、maxRows ≤5000、
5
- * 每 agent 每 60s ≤6 次 fetch;数据原文不进 prompt —— 文本只给 stats + ≤3 行采样,
6
- * 行级原文只落 CSV 数据集(mes-datasets)。
7
- *
8
- * 取数三模式:
9
- * 无 from/to → 当前值快照(driver.read 内联直读);
10
- * from/to 且 maxRows ≤ 2000 → 同步 fetchHistory 内联返回(缓冲截断保护);
11
- * 其余(maxRows > 2000) → createFetchJob 异步落 CSV,回 job_id/dataset_id。
12
- */
13
- import { randomUUID } from 'node:crypto'
14
- import { closeSync, mkdirSync, openSync, readFileSync, writeFileSync, writeSync } from 'node:fs'
15
- import { join, resolve, sep } from 'node:path'
16
- import { ensureDataDir } from '@/shared/config/home.mjs'
17
- import { getActiveLineRun } from '../dcw/line-run'
18
- import { resolveDcwDriver } from '../dcw/drivers'
19
- import type { DcwFieldDef, DcwHistoryFormat as MesHistoryFormat } from '../dcw/drivers/shared'
20
- import { historyFormatOf, normalizeMesDictionary } from '../dcw/drivers/mes-rest'
21
- import type { MesHistoryDriver, MesDatasetStatsView, MesDatasetStore } from './mes-datasets'
22
- import { getMesDatasets } from './mes-datasets'
23
- import { mesDataHookCode, mesRequestHookCode, runMesDataHook, runMesRequestHook, saveMesImageArtifact } from './mes-hook'
24
- import type { MesHookArtifact, MesHookData } from './mes-hook'
25
-
26
- /** mes-rest 驱动 kind(并行工作流收编进 DcwDriverKind 联合;此处按字符串经注册表解析,不 import 驱动实现) */
27
- export const MES_REST_DRIVER_KIND = 'mes-rest'
28
-
29
- // ============================================================
30
- // 护栏常量(单一事实源;测试直接引用)
31
- // ============================================================
32
-
33
- /** 历史窗口上限:7 天 */
34
- export const MES_WINDOW_MAX_MS = 7 * 24 * 3_600_000
35
- /** 单次取数行数硬上限 */
36
- export const MES_MAX_ROWS_CAP = 5000
37
- /** 同步内联返回的行数上限(超过走异步数据集) */
38
- export const MES_SYNC_INLINE_MAX_ROWS = 2000
39
- /** 频次限流:窗口与次数(每 agent) */
40
- export const MES_RATE_WINDOW_MS = 60_000
41
- export const MES_RATE_MAX_CALLS = 6
42
- /** max_rows 缺省值 */
43
- export const MES_DEFAULT_MAX_ROWS = 500
44
- /** 离线导出单次行数上限(CSV/JSONL 流式写盘;比在线取数宽,仍防磁盘失控) */
45
- export const MES_EXPORT_MAX_ROWS = 200_000
46
- /** 离线导出图像帧上限(单次) */
47
- export const MES_EXPORT_MAX_FRAMES = 500
48
-
49
- // ============================================================
50
- // 频次限流(进程内内存计数;Map<agentId, 时间戳[]>)
51
- // ============================================================
52
-
53
- const fetchCallStamps = new Map<string, number[]>()
54
-
55
- /** 记一次 fetch 并判定是否放行(滑动 60s 窗 ≤6 次;超限不记账) */
56
- export function mesFetchRateCheck(agentId: string, nowMs = Date.now()): boolean {
57
- const stamps = (fetchCallStamps.get(agentId) ?? []).filter(t => nowMs - t < MES_RATE_WINDOW_MS)
58
- if (stamps.length >= MES_RATE_MAX_CALLS) {
59
- fetchCallStamps.set(agentId, stamps)
60
- return false
61
- }
62
- stamps.push(nowMs)
63
- fetchCallStamps.set(agentId, stamps)
64
- return true
65
- }
66
-
67
- /** 清空限流账(测试用) */
68
- export function mesFetchRateReset(): void {
69
- fetchCallStamps.clear()
70
- }
71
-
72
- // ============================================================
73
- // 节点/依赖(结构化注入;缺省接真实服务,测试注入假件不联网)
74
- // ============================================================
75
-
76
- export interface MesNodeLike {
77
- id: string
78
- name: string
79
- driver: string
80
- lineId: string
81
- unit: string
82
- min: number
83
- max: number
84
- enabled: boolean
85
- driverConfig: Record<string, string | number | boolean>
86
- }
87
-
88
- export interface MesControllerDeps {
89
- /** 数据集服务(异步取数账本;缺省 getMesDatasets()) */
90
- store: Pick<MesDatasetStore, 'createFetchJob'>
91
- /** 全量 dcw 节点(缺省 dcw-node.repo) */
92
- nodes: () => MesNodeLike[] | Promise<MesNodeLike[]>
93
- /** 调用者可见节点(绑线过滤:dcw 绑定集;缺省 node-bindings.repo) */
94
- boundNodeIds: (agentId: string) => Set<string> | Promise<Set<string>>
95
- /** 驱动解析(缺省 dcw 注册表) */
96
- resolveDriver: (kind: string) => MesHistoryDriver
97
- nowMs: () => number
98
- }
99
-
100
- /** 缺省依赖:重模块(dcw 仓储/绑线仓储)经动态 import 引入,保持本模块可被 tsx 测试轻量直跑 */
101
- function defaultDeps(): MesControllerDeps {
102
- return {
103
- store: new Proxy({} as Pick<MesDatasetStore, 'createFetchJob'>, {
104
- get: (_t, prop) => {
105
- const store = getMesDatasets() as unknown as Record<string | symbol, unknown>
106
- const v = store[prop]
107
- return typeof v === 'function' ? (v as (...a: unknown[]) => unknown).bind(store) : v
108
- },
109
- }),
110
- nodes: async () => {
111
- const { getDcwNodeRepo } = await import('../dcw/dcw-node.repo')
112
- return getDcwNodeRepo().all()
113
- },
114
- boundNodeIds: async (agentId) => {
115
- // 权限模型 v2:dcw 绑定(存量)∪ 绑定配方内的参数节点(kind='recipe' 的配方可见节点)
116
- const { getAgentNodeBindingRepo } = await import('../agents/node-bindings.repo')
117
- const { getDcwController } = await import('../dcw/dcw-controller')
118
- const bindings = getAgentNodeBindingRepo().byAgent(agentId)
119
- const ids = new Set(bindings.filter(b => b.kind === 'dcw').map(b => b.nodeId))
120
- const recipeIds = new Set(bindings.filter(b => b.kind === 'recipe').map(b => b.nodeId))
121
- if (recipeIds.size > 0) {
122
- for (const r of getDcwController().listRecipes()) {
123
- if (!recipeIds.has(r.id)) continue
124
- for (const p of r.params) ids.add(p.nodeId)
125
- }
126
- }
127
- return ids
128
- },
129
- resolveDriver: kind => resolveDcwDriver(kind as Parameters<typeof resolveDcwDriver>[0]),
130
- nowMs: () => Date.now(),
131
- }
132
- }
133
-
134
- export type MesCatalogEntry = {
135
- id: string
136
- name: string
137
- lineId: string
138
- unit: string
139
- min: number
140
- max: number
141
- desc: string
142
- readable: boolean
143
- writable: boolean
144
- historyable: boolean
145
- /** 历史格式(scalar/vector/image/table/event;historyMap 未配置时 scalar) */
146
- format: MesHistoryFormat
147
- /** 已配置数据下沉 hook(dataHook) */
148
- hooked: boolean
149
- enabled: boolean
150
- /** 字段级数据字典(响应缓存 ∪ 节点静态配置;无则空数组) */
151
- fields: DcwFieldDef[]
152
- }
153
-
154
- // ============================================================
155
- // 字段字典缓存(响应返回 → 后续 catalog/导出复用)
156
- // ============================================================
157
-
158
- const dictionaryCache = new Map<string, DcwFieldDef[]>()
159
- const DICTIONARY_CACHE_MAX = 200
160
-
161
- function cacheDictionary(nodeId: string, fields: DcwFieldDef[] | undefined): void {
162
- if (!fields || fields.length === 0) return
163
- dictionaryCache.delete(nodeId)
164
- dictionaryCache.set(nodeId, fields)
165
- while (dictionaryCache.size > DICTIONARY_CACHE_MAX) {
166
- const oldest = dictionaryCache.keys().next().value
167
- if (oldest === undefined) break
168
- dictionaryCache.delete(oldest)
169
- }
170
- }
171
-
172
- /** 节点静态字典(driverConfig.dictionary / fieldDictionary 的 JSON 文本) */
173
- function configuredDictionary(cfg: Record<string, unknown>): DcwFieldDef[] {
174
- for (const key of ['dictionary', 'fieldDictionary', 'fields']) {
175
- const raw = cfg[key]
176
- if (raw === undefined || raw === null || String(raw).trim() === '') continue
177
- try {
178
- const parsed = typeof raw === 'string' ? JSON.parse(raw) as unknown : raw
179
- const fields = normalizeMesDictionary(parsed)
180
- if (fields.length > 0) return fields
181
- }
182
- catch { /* 坏配置不击穿目录;由驱动测试报错 */ }
183
- }
184
- return []
185
- }
186
-
187
- /** 节点有效字典:响应缓存优先(实时真相),否则静态配置 */
188
- export function mesDictionaryOfNode(nodeId: string, cfg: Record<string, unknown>): DcwFieldDef[] {
189
- return dictionaryCache.get(nodeId) ?? configuredDictionary(cfg)
190
- }
191
-
192
- /** 字典一行摘要(字段名(标签,单位;量程;点数)) */
193
- export function fieldSummaryOf(fields: DcwFieldDef[]): string {
194
- return fields.slice(0, 8).map((f) => {
195
- const bits = [f.label, f.unit, f.min != null || f.max != null ? `${f.min ?? '-∞'}~${f.max ?? '+∞'}` : '', f.points?.length ? `${f.points.length} 点` : '']
196
- .filter(Boolean)
197
- return bits.length > 0 ? `${f.field}(${bits.join(',')})` : f.field
198
- }).join('; ')
199
- }
200
-
201
- /** 字段字典 → 多行可读文本(Agent 直接引用;含单位/量程/物理意义/逐点语义) */
202
- export function formatDictionary(fields: DcwFieldDef[], indent = ' '): string {
203
- if (fields.length === 0) return ''
204
- const pointLine = (f: DcwFieldDef): string => {
205
- const pts = f.points ?? []
206
- if (pts.length === 0) return ''
207
- const head = pts.slice(0, 6).map(p => `${p.index ?? '?'}=${p.label ?? p.field}${p.unit ? `(${p.unit})` : ''}`).join(', ')
208
- return `; 点位 ${pts.length} 个: ${head}${pts.length > 6 ? ', …' : ''}`
209
- }
210
- const lines = fields.slice(0, 24).map((f) => {
211
- const meta = [
212
- f.label && f.label !== f.field ? `标签 ${f.label}` : '',
213
- f.unit ? `单位 ${f.unit}` : '',
214
- f.min != null || f.max != null ? `量程 ${f.min ?? '-∞'}~${f.max ?? '+∞'}` : '',
215
- f.kind ? `形态 ${f.kind}` : '',
216
- ].filter(Boolean).join(' | ')
217
- const desc = f.description ? ` — ${f.description.slice(0, 160)}` : ''
218
- return `${indent}- ${f.field}${meta ? ` [${meta}]` : ''}${desc}${pointLine(f)}`
219
- })
220
- return `字段字典(${fields.length} 个字段,来自 MES 响应/节点配置):\n${lines.join('\n')}${fields.length > 24 ? `\n${indent}(仅显示前 24 个字段)` : ''}`
221
- }
222
-
223
- /** 目录条目合成:desc/readMap/writeMap/historyMap 均来自 driverConfig(数据驱动,零硬编码) */
224
- export function mesCatalogEntryOf(n: MesNodeLike): MesCatalogEntry {
225
- const cfg = n.driverConfig ?? {}
226
- return {
227
- id: n.id,
228
- name: n.name,
229
- lineId: n.lineId ?? '',
230
- unit: n.unit ?? '',
231
- min: n.min,
232
- max: n.max,
233
- desc: String(cfg.desc ?? ''),
234
- readable: Boolean(cfg.readMap),
235
- writable: Boolean(cfg.writeMap),
236
- historyable: Boolean(cfg.historyMap),
237
- format: historyFormatOf(cfg as Record<string, unknown>),
238
- hooked: Boolean(cfg.dataHook),
239
- enabled: Boolean(n.enabled),
240
- fields: mesDictionaryOfNode(n.id, cfg as Record<string, unknown>),
241
- }
242
- }
243
-
244
- // ============================================================
245
- // 控制器
246
- // ============================================================
247
-
248
- export type MesToolResult = { text: string, isError?: boolean }
249
-
250
- export type MesFetchOutcome = MesToolResult & {
251
- mode?: 'snapshot' | 'inline' | 'async'
252
- data?: {
253
- job_ids?: string[]
254
- dataset_ids?: string[]
255
- stats?: Array<{ nodeId: string, stats: MesDatasetStatsView, truncated: boolean }>
256
- }
257
- }
258
-
259
- export interface MesFetchArgs {
260
- ids?: unknown
261
- from?: string
262
- to?: string
263
- max_rows?: number | string
264
- /** 透传给 requestHook/dataHook 的参数对象(Agent 只传 param,其余交给配置) */
265
- param?: unknown
266
- /** 内联/快照回包是否附带采样行的实际数组/数值内容(默认 false=只给统计与均值) */
267
- include_data?: boolean | string
268
- }
269
-
270
- export interface MesCatalogArgs {
271
- q?: string
272
- line_id?: string
273
- /** 按产品 id 收窄到该产品产线(可选;与 line_id 冲突时拒绝) */
274
- product_id?: string
275
- /** 按配方 id 收窄到该配方产线(可选;与 line_id 冲突时拒绝) */
276
- recipe_id?: string
277
- limit?: number | string
278
- /** 调用者可读产线集(绑线授权口径);提供时严格过滤(孤儿/越线点位不可见,空集=空目录 fail-closed) */
279
- scope_line_ids?: string[]
280
- }
281
-
282
- export interface MesExportArgs {
283
- ids?: unknown
284
- from?: string
285
- to?: string
286
- max_rows?: number | string
287
- /** 透传给 requestHook 的调用参数 */
288
- param?: unknown
289
- /** 导出子目录(相对 <数据根>/mes-exports;绝对路径须落在 AW_MES_EXPORT_ROOT 内) */
290
- folder?: string
291
- title?: string
292
- note?: string
293
- /** 标量节点是否生成按时间对齐的 merged.csv(缺省 true) */
294
- merge?: boolean | string
295
- }
296
-
297
- export function createMesController(deps: Partial<MesControllerDeps> = {}) {
298
- const d: MesControllerDeps = { ...defaultDeps(), ...deps }
299
-
300
- // ---------- 目录 ----------
301
-
302
- /** mes-rest 点位目录(q 对 name/desc 子串过滤;line_id 精确过滤;limit 缺省 20;
303
- * scope_line_ids 提供时按调用者可读产线严格过滤——跨产线点位与孤儿(未分配)点位不可见) */
304
- async function catalog(args: MesCatalogArgs = {}): Promise<MesToolResult & { entries: MesCatalogEntry[], total: number }> {
305
- const all = await d.nodes()
306
- let mes = all.filter(n => n.driver === MES_REST_DRIVER_KIND).map(mesCatalogEntryOf)
307
- if (Array.isArray(args.scope_line_ids)) {
308
- const scope = new Set(args.scope_line_ids)
309
- mes = mes.filter(e => e.lineId !== '' && scope.has(e.lineId))
310
- }
311
- const total = mes.length
312
- let lineId = String(args.line_id ?? '').trim()
313
- const productId = String(args.product_id ?? '').trim()
314
- if (productId) {
315
- const { getDcwProductRepo } = await import('../dcw/dcw-product.repo')
316
- const product = getDcwProductRepo().byId(productId)
317
- if (!product) return { text: `产品 ${productId} 不存在。`, isError: true, entries: [], total: 0 }
318
- if (lineId && product.lineId !== lineId) return { text: `产品 ${productId} 归属产线 ${product.lineId},与 line_id=${lineId} 不一致。`, isError: true, entries: [], total: 0 }
319
- lineId = product.lineId
320
- }
321
- const recipeId = String(args.recipe_id ?? '').trim()
322
- if (recipeId) {
323
- const { getDcwController } = await import('../dcw/dcw-controller')
324
- const recipe = getDcwController().listRecipes().find(r => r.id === recipeId)
325
- if (!recipe) return { text: `配方 ${recipeId} 不存在。`, isError: true, entries: [], total: 0 }
326
- if (lineId && recipe.lineId !== lineId) return { text: `配方 ${recipeId} 归属产线 ${recipe.lineId},与 line_id=${lineId} 不一致。`, isError: true, entries: [], total: 0 }
327
- lineId = recipe.lineId
328
- }
329
- if (lineId) mes = mes.filter(e => e.lineId === lineId)
330
- const q = String(args.q ?? '').trim().toLowerCase()
331
- if (q) mes = mes.filter(e => e.name.toLowerCase().includes(q) || e.desc.toLowerCase().includes(q))
332
- const limit = Math.min(Math.max(Math.round(Number(args.limit)) || 20, 1), 100)
333
- const shown = mes.slice(0, limit)
334
-
335
- const cap = (e: MesCatalogEntry): string => {
336
- const hist = e.historyable ? (e.format !== 'scalar' ? `史·${e.format}` : '史') : null
337
- const ab = [e.readable ? '读' : null, e.writable ? '写' : null, hist, e.hooked ? '钩子' : null].filter(Boolean)
338
- return ab.length > 0 ? ab.join('/') : '无能力位'
339
- }
340
- const body = shown.map((e) => {
341
- const fields = e.fields.length > 0 ? ` | 字段: ${fieldSummaryOf(e.fields)}` : ''
342
- return `- ${e.name}(id=${e.id}) | 产线 ${e.lineId || '未分配'} | 单位 ${e.unit || '-'} | 量程 ${e.min}~${e.max} | 能力 ${cap(e)}${e.enabled ? '' : ' [停用]'}${e.desc ? ` | ${e.desc.slice(0, 80)}` : ''}${fields}`
343
- })
344
- const more = mes.length - shown.length
345
- const text = `MES REST 点位目录(共 ${total} 个${lineId ? `,产线 ${lineId}` : ''}${q ? `,关键字「${args.q}」` : ''};显示 ${shown.length} 条):\n${body.join('\n') || '(无匹配点位)'}${more > 0 ? `\n(另有 ${more} 条未显示,可收紧 q/line_id 或调大 limit≤100)` : ''}\n\n说明:能力 读=可读当前值,写=可写设定值,史=可取历史(史·vector=每时间点检测向量,史·image=图像帧,史·table/event=记录流),钩子=已配 dataHook(取数后自动做下沉处理并回传摘要与产物)。字段级语义来自 MES 响应 dictionaryPath 或节点 driverConfig.dictionary;首次 mes_fetch 后缓存,后续目录可直接看到字段标签/单位/点位。历史取数用 mes_fetch(ids=[点位id], from, to, max_rows, param?);需要落盘到目录做离线分析用 mes_export。`
346
- return { text, entries: shown, total }
347
- }
348
-
349
- // ---------- 取数 ----------
350
-
351
- /** 归一 ids + 授权过滤(绑线路径:仅调用者 dcw 绑定的 mes-rest 节点) */
352
- async function resolveVisibleIds(agentId: string, rawIds: unknown): Promise<{ ok: true, nodes: MesNodeLike[] } | { ok: false, text: string, isError: true }> {
353
- const ids = Array.isArray(rawIds) ? [...new Set(rawIds.map(x => String(x ?? '').trim()).filter(Boolean))] : []
354
- if (ids.length === 0) return { ok: false, text: 'ids 必填:目标 mes-rest 点位 id 数组(catalog 输出的 id;至少 1 个)。', isError: true }
355
- const all = await d.nodes()
356
- const bound = await d.boundNodeIds(agentId)
357
- const mesById = new Map(all.filter(n => n.driver === MES_REST_DRIVER_KIND).map(n => [n.id, n]))
358
- const picked: MesNodeLike[] = []
359
- const missing: string[] = []
360
- const notAllowed: string[] = []
361
- for (const id of ids) {
362
- const n = mesById.get(id)
363
- if (!n) {
364
- missing.push(id)
365
- continue
366
- }
367
- if (!bound.has(id)) {
368
- notAllowed.push(id)
369
- continue
370
- }
371
- picked.push(n)
372
- }
373
- if (missing.length > 0 || notAllowed.length > 0) {
374
- const allowed = [...bound]
375
- .map(id => mesById.get(id))
376
- .filter((n): n is MesNodeLike => !!n && n.driver === MES_REST_DRIVER_KIND)
377
- const parts: string[] = []
378
- if (missing.length > 0) parts.push(`不存在或不是 mes-rest 点位:${missing.join(', ')}`)
379
- if (notAllowed.length > 0) parts.push(`无权访问(须为你绑定的数控节点):${notAllowed.join(', ')}`)
380
- return {
381
- ok: false,
382
- text: `取数被拒:${parts.join(';')}。你有权取数的 mes-rest 点位:${allowed.map(n => `${n.name}(${n.id})`).join(', ') || '(无)'}。`,
383
- isError: true,
384
- }
385
- }
386
- return { ok: true, nodes: picked }
387
- }
388
-
389
- /** 时间窗/行数护栏归一(代码级;返回错误文本或归一值) */
390
- function normalizeWindow(args: MesFetchArgs): { ok: true, from?: string, to?: string, maxRows: number } | { ok: false, text: string, isError?: true } {
391
- const from = String(args.from ?? '').trim()
392
- const to = String(args.to ?? '').trim()
393
- if ((from && !to) || (!from && to)) {
394
- return { ok: false, text: 'from/to 必须成对提供(历史取数),或都不传(当前值快照模式)。' }
395
- }
396
- if (from && to) {
397
- const fromMs = Date.parse(from)
398
- const toMs = Date.parse(to)
399
- if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return { ok: false, text: 'from/to 必须是合法 ISO 时间戳。' }
400
- if (fromMs >= toMs) return { ok: false, text: `时间窗无效:from(${from}) 必须早于 to(${to})。` }
401
- if (toMs - fromMs > MES_WINDOW_MAX_MS) {
402
- return { ok: false, text: `时间窗被拒:窗口 ${(toMs - fromMs) / 3_600_000 / 24} 天超过上限 7 天。请拆成 ≤7 天的分段分批取数。`, isError: true }
403
- }
404
- }
405
- const maxRows = args.max_rows == null || args.max_rows === '' ? MES_DEFAULT_MAX_ROWS : Math.round(Number(args.max_rows))
406
- if (!Number.isFinite(maxRows) || maxRows < 1) return { ok: false, text: 'max_rows 必须为 ≥1 的整数。' }
407
- if (maxRows > MES_MAX_ROWS_CAP) {
408
- return { ok: false, text: `max_rows=${maxRows} 被拒:单次取数上限 ${MES_MAX_ROWS_CAP} 行。请缩小时间窗或分批取数。`, isError: true }
409
- }
410
- return { ok: true, from: from || undefined, to: to || undefined, maxRows }
411
- }
412
-
413
- /** 统计摘要(数值列;均值/采样标准差) */
414
- function statsOf(values: number[], firstTs: string | null, lastTs: string | null): MesDatasetStatsView {
415
- const n = values.length
416
- if (n === 0) return { count: 0, min: null, max: null, mean: null, stddev: null, firstTs: null, lastTs: null }
417
- const min = Math.min(...values)
418
- const max = Math.max(...values)
419
- const mean = values.reduce((a, b) => a + b, 0) / n
420
- const stddev = n > 1 ? Math.sqrt(values.reduce((a, b) => a + (b - mean) ** 2, 0) / (n - 1)) : 0
421
- return { count: n, min, max, mean, stddev, firstTs, lastTs }
422
- }
423
-
424
- const fmtN = (v: number | null | undefined, digits = 3): string =>
425
- v == null || !Number.isFinite(v) ? '-' : String(Number(v.toFixed(digits)))
426
- const shortTs = (iso: string | null): string => iso && iso.length >= 19 ? iso.slice(5, 19).replace('T', ' ') : (iso ?? '-')
427
- const clip = (v: unknown, max: number): string => {
428
- const s = typeof v === 'string' ? v : JSON.stringify(v) ?? String(v)
429
- return s.length > max ? `${s.slice(0, max)}…` : s
430
- }
431
-
432
- // -------- 格式感知取数(行形态全谱;内存硬顶防大payload 拖垮进程) --------
433
-
434
- /** 泛化历史行缓冲的硬顶 */
435
- const VECTOR_ELEMENT_CAP = 2_000_000
436
- const IMAGE_BASE64_CAP = 16_000_000
437
- const RECORD_JSON_CAP = 8_000_000
438
- /** image 格式自动落盘帧数上限(其余帧不落盘,回包注明) */
439
- const IMAGE_AUTOSAVE_MAX = 20
440
-
441
- interface GenRow { ts: string, value?: number, values?: number[], data?: string, mime?: string, record?: unknown }
442
-
443
- interface GenStats extends MesDatasetStatsView {
444
- /** vector:维度(首行长度)与维度不齐行数 */
445
- dim?: number
446
- dimMismatch?: number
447
- /** vector:全体元素均值(比行均值更细) */
448
- elementMean?: number
449
- }
450
-
451
- /** requestHook 覆盖合并:克隆 driverConfig,把 {path,query,headers} 合入 historyMap JSON */
452
- async function configWithRequestHook(node: MesNodeLike, param: unknown): Promise<Record<string, unknown>> {
453
- const cfg = { ...(node.driverConfig as Record<string, unknown>) }
454
- const hookCode = mesRequestHookCode(cfg as Record<string, unknown>)
455
- if (!hookCode) return cfg
456
- const overrides = await runMesRequestHook(hookCode, param, { nodeId: node.id })
457
- if (overrides.path === undefined && overrides.query === undefined && overrides.headers === undefined) return cfg
458
- try {
459
- const map = JSON.parse(String(cfg.historyMap ?? '{}')) as Record<string, unknown>
460
- if (overrides.path !== undefined) map.path = overrides.path
461
- const baseQuery = (map.query !== null && typeof map.query === 'object' && !Array.isArray(map.query) ? map.query : {}) as Record<string, unknown>
462
- map.query = { ...baseQuery, ...(overrides.query ?? {}) }
463
- const baseHeaders = (map.headers !== null && typeof map.headers === 'object' && !Array.isArray(map.headers) ? map.headers : {}) as Record<string, unknown>
464
- if (overrides.headers !== undefined) map.headers = { ...baseHeaders, ...overrides.headers }
465
- cfg.historyMap = JSON.stringify(map)
466
- }
467
- catch (err) {
468
- throw new AppError(422, 'MES_HOOK_FAILED', `requestHook 覆盖合并失败(historyMap 非法 JSON):${err instanceof Error ? err.message : String(err)}`)
469
- }
470
- return cfg
471
- }
472
-
473
- /** 向量行统计摘要(行均值序列 stats + 维度 + 全体元素均值) */
474
- function vectorStats(rows: GenRow[]): GenStats {
475
- const rowMeans = rows.map((r) => {
476
- const vs = r.values ?? []
477
- return vs.length > 0 ? vs.reduce((a, b) => a + b, 0) / vs.length : NaN
478
- }).filter(v => Number.isFinite(v))
479
- const all: number[] = []
480
- for (const r of rows) if (Array.isArray(r.values)) all.push(...r.values)
481
- const base = statsOf(rowMeans, rows[0]?.ts ?? null, rows[rows.length - 1]?.ts ?? null) as GenStats
482
- base.dim = Array.isArray(rows[0]?.values) ? rows[0]!.values!.length : undefined
483
- base.dimMismatch = base.dim === undefined ? undefined : rows.filter(r => Array.isArray(r.values) && r.values!.length !== base.dim).length
484
- base.elementMean = all.length > 0 ? all.reduce((a, b) => a + b, 0) / all.length : undefined
485
- return base
486
- }
487
-
488
- /** 同步取单节点历史(格式感知:统计+采样+图像落盘+dataHook 下沉处理;原文不回传) */
489
- async function inlineFetchNode(node: MesNodeLike, from: string, to: string, maxRows: number, param: unknown, includeData = false): Promise<{
490
- text: string
491
- stats: MesDatasetStatsView
492
- truncated: boolean
493
- sample: string[]
494
- hookText?: string
495
- artifacts: MesHookArtifact[]
496
- }> {
497
- const cfg = node.driverConfig as Record<string, unknown>
498
- const format = historyFormatOf(cfg)
499
- const driver = d.resolveDriver(node.driver)
500
- if (typeof driver.fetchHistory !== 'function') {
501
- return { text: `驱动 ${node.driver} 未提供历史原语(fetchHistory)`, stats: statsOf([], null, null), truncated: true, sample: [], artifacts: [] }
502
- }
503
- const effCfg = await configWithRequestHook(node, param)
504
- const buf: GenRow[] = []
505
- let truncated = false
506
- let vecElems = 0
507
- let imgChars = 0
508
- let recChars = 0
509
- let memoryHit = ''
510
- let dictionary: DcwFieldDef[]
511
- const result = await driver.fetchHistory({
512
- driverConfig: effCfg,
513
- fromIso: from,
514
- toIso: to,
515
- maxRows,
516
- onRows: (batch) => {
517
- for (const r of batch ?? []) {
518
- if (buf.length >= maxRows) {
519
- truncated = true
520
- break
521
- }
522
- const row: GenRow = { ts: String(r?.ts ?? '') }
523
- if (typeof r?.value === 'number') row.value = r.value
524
- if (Array.isArray(r?.values)) {
525
- vecElems += r.values.length
526
- if (vecElems > VECTOR_ELEMENT_CAP) {
527
- memoryHit = `向量元素总量超过 ${VECTOR_ELEMENT_CAP} 上限`
528
- truncated = true
529
- break
530
- }
531
- row.values = r.values as number[]
532
- }
533
- if (typeof r?.data === 'string') {
534
- imgChars += r.data.length
535
- if (imgChars > IMAGE_BASE64_CAP) {
536
- memoryHit = `图像载荷总量超过 ${Math.round(IMAGE_BASE64_CAP / 1024 / 1024)}MB 上限`
537
- truncated = true
538
- break
539
- }
540
- row.data = r.data
541
- row.mime = typeof r?.mime === 'string' ? r.mime : 'image/png'
542
- }
543
- if (r?.record !== undefined && r.record !== null) {
544
- let json: string
545
- try {
546
- json = JSON.stringify(r.record)
547
- }
548
- catch {
549
- continue
550
- }
551
- recChars += json.length
552
- if (recChars > RECORD_JSON_CAP) {
553
- memoryHit = `记录载荷总量超过 ${Math.round(RECORD_JSON_CAP / 1024 / 1024)}MB 上限`
554
- truncated = true
555
- break
556
- }
557
- row.record = r.record
558
- }
559
- buf.push(row)
560
- }
561
- },
562
- })
563
- if (result?.dictionary && result.dictionary.length > 0) {
564
- dictionary = result.dictionary
565
- cacheDictionary(node.id, dictionary)
566
- }
567
- else {
568
- dictionary = mesDictionaryOfNode(node.id, cfg)
569
- }
570
- if (result && result.complete === false) truncated = true
571
- if (!truncated && memoryHit) truncated = true
572
-
573
- // 统计与采样(按格式)
574
- let stats: GenStats
575
- let autosaved: MesHookArtifact[] = []
576
- const sample: string[] = []
577
- let tableFieldStats = ''
578
- if (format === 'vector') {
579
- stats = vectorStats(buf)
580
- // 空窗口不得生成采样下标(否则 buf[0] undefined → 取数崩溃)
581
- const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
582
- const vecField = dictionary.find(f => f.kind === 'vector' || (f.points?.length ?? 0) > 0)
583
- const pointLabel = (i: number): string => {
584
- const p = vecField?.points?.[i]
585
- return p?.label ?? p?.field ?? `v${i}`
586
- }
587
- for (const i of idx) {
588
- const r = buf[i]!
589
- const vs = r.values ?? []
590
- const m = vs.length > 0 ? vs.reduce((a, b) => a + b, 0) / vs.length : NaN
591
- const valuesTxt = includeData && vs.length > 0
592
- ? `,values=[${vs.slice(0, 64).map((v, j) => `${pointLabel(j)}=${Number(v.toFixed(4))}`).join(',')}${vs.length > 64 ? ',…' : ''}]`
593
- : ''
594
- sample.push(`${shortTs(r.ts)},dim=${vs.length},mean=${fmtN(m)},min=${fmtN(vs.length ? Math.min(...vs) : NaN)},max=${fmtN(vs.length ? Math.max(...vs) : NaN)}${valuesTxt}`)
595
- }
596
- }
597
- else if (format === 'image') {
598
- stats = { count: buf.length, min: null, max: null, mean: null, stddev: null, firstTs: buf[0]?.ts ?? null, lastTs: buf[buf.length - 1]?.ts ?? null }
599
- // 图像 base64 永不进 prompt:自动落盘(≤20 帧),采样给文件名
600
- const saved: MesHookArtifact[] = []
601
- for (const [i, r] of buf.entries()) {
602
- if (typeof r.data !== 'string') continue
603
- if (saved.length >= IMAGE_AUTOSAVE_MAX) break
604
- const a = saveMesImageArtifact(node.id, `frame-${String(i).padStart(4, '0')}`, r.data, r.mime ?? 'image/png')
605
- if (a) saved.push(a)
606
- }
607
- const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
608
- for (const i of idx) {
609
- const r = buf[i]!
610
- const kb = r.data ? Math.round(r.data.length * 3 / 4 / 1024) : 0
611
- const f = saved.find(x => x.name.includes(`frame-${String(i).padStart(4, '0')}`))
612
- sample.push(`${shortTs(r.ts)},${r.mime ?? 'image/png'},~${kb}KB${f ? ` → ${f.name}` : ''}`)
613
- }
614
- autosaved = saved
615
- }
616
- else if (format === 'table' || format === 'event') {
617
- stats = { count: buf.length, min: null, max: null, mean: null, stddev: null, firstTs: buf[0]?.ts ?? null, lastTs: buf[buf.length - 1]?.ts ?? null }
618
- const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
619
- for (const i of idx) {
620
- const r = buf[i]!
621
- let body: string
622
- try {
623
- body = JSON.stringify(r.record)
624
- }
625
- catch {
626
- body = '(不可序列化)'
627
- }
628
- sample.push(`${shortTs(r.ts)},${clip(body ?? '', 120)}`)
629
- }
630
- // map/多参数行:逐数值字段统计(最多 12 个字段),让 Agent 不必只看 3 行采样
631
- const cols = new Map<string, number[]>()
632
- for (const r of buf) {
633
- if (r.record === null || typeof r.record !== 'object' || Array.isArray(r.record)) continue
634
- for (const [k, v] of Object.entries(r.record as Record<string, unknown>)) {
635
- if (v === null || v === '' || typeof v === 'boolean') continue
636
- const n = Number(v)
637
- if (!Number.isFinite(n)) continue
638
- const arr = cols.get(k) ?? []
639
- arr.push(n)
640
- cols.set(k, arr)
641
- }
642
- }
643
- const fieldLines = [...cols.entries()].slice(0, 12).map(([k, vs]) => {
644
- const mean = vs.reduce((a, b) => a + b, 0) / vs.length
645
- const def = dictionary.find(f => f.field === k)
646
- const label = def?.label ? `${def.label}(${k})` : k
647
- const unit = def?.unit ? ` ${def.unit}` : ''
648
- return `${label}: n=${vs.length} min=${fmtN(Math.min(...vs))} max=${fmtN(Math.max(...vs))} mean=${fmtN(mean)}${unit}`
649
- })
650
- if (fieldLines.length > 0) {
651
- tableFieldStats = ` 数值字段统计(${cols.size} 个字段${cols.size > 12 ? ',显示前12' : ''}): ${fieldLines.join(' | ')}`
652
- }
653
- }
654
- else {
655
- const values = buf.map(r => r.value).filter((v): v is number => Number.isFinite(v))
656
- stats = statsOf(values, buf[0]?.ts ?? null, buf[buf.length - 1]?.ts ?? null)
657
- const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
658
- for (const i of idx) sample.push(`${shortTs(buf[i]!.ts)},${fmtN(buf[i]!.value ?? NaN)}${includeData ? ` (value=${buf[i]!.value ?? '-'})` : ''}`)
659
- }
660
-
661
- const fmtLabel = format === 'scalar' ? `标量` : format === 'vector' ? `向量(dim=${stats.dim ?? '?'})` : format === 'image' ? `图像(${(buf[0]?.mime as string) ?? 'image/png'})` : format === 'table' ? `表格记录` : `事件记录`
662
- const statLine = format === 'scalar'
663
- ? ` 统计:min ${fmtN(stats.min)} / max ${fmtN(stats.max)} / mean ${fmtN(stats.mean)} / stddev ${fmtN(stats.stddev)} ${node.unit}`
664
- : format === 'vector'
665
- ? ` 统计(按行均值):min ${fmtN(stats.min)} / max ${fmtN(stats.max)} / mean ${fmtN(stats.mean)} / stddev ${fmtN(stats.stddev)} ${node.unit};全体元素均值 ${fmtN(stats.elementMean ?? NaN)}${stats.dimMismatch ? `;维度漂移 ${stats.dimMismatch} 行` : ''}`
666
- : ` 统计:${stats.count} 条记录(非数值格式不做均值)`
667
- const dictText = formatDictionary(dictionary)
668
- const text = [
669
- `■ ${node.name}(id=${node.id})[格式 ${fmtLabel};节点单位 ${node.unit || '-'};量程 ${node.min}~${node.max}]`,
670
- ` 行数 ${stats.count}${truncated ? `(截断:${memoryHit || '达到 maxRows 上限'})` : '(完整)'} | 首 ${shortTs(stats.firstTs)} ~ 末 ${shortTs(stats.lastTs)}`,
671
- statLine,
672
- sample.length > 0 ? ` 采样(≤3 行): ${sample.join(' | ')}` : ' 采样:无有效行',
673
- ...(tableFieldStats ? [tableFieldStats] : []),
674
- ...(dictText ? [dictText] : []),
675
- ].join('\n')
676
-
677
- // dataHook 下沉处理(用户配置的 (param, data, ctx) => {...})
678
- let hookText: string | undefined
679
- const artifacts: MesHookArtifact[] = [...(autosaved as MesHookArtifact[])]
680
- const hookCode = mesDataHookCode(cfg)
681
- if (hookCode) {
682
- const hookData: MesHookData = {
683
- node: { id: node.id, name: node.name, lineId: node.lineId, unit: node.unit },
684
- format,
685
- rows: buf,
686
- window: { from, to },
687
- }
688
- try {
689
- const outcome = await runMesDataHook(hookCode, param, hookData, { nodeId: node.id })
690
- if (outcome.ok) {
691
- artifacts.push(...outcome.artifacts)
692
- const parts = [` 钩子(dataHook):已执行,产物 ${outcome.artifacts.length} 个`]
693
- if (outcome.summary) parts.push(` 处理摘要: ${outcome.summary}`)
694
- if (outcome.context) parts.push(` 处理说明: ${outcome.context}`)
695
- if (outcome.logs.length > 0) parts.push(` hook 日志(≤3): ${outcome.logs.slice(0, 3).join(' / ')}`)
696
- hookText = parts.join('\n')
697
- }
698
- else {
699
- hookText = ` 钩子(dataHook)执行失败:${outcome.error ?? '未知原因'}(统计仍基于原始数据)`
700
- }
701
- }
702
- catch (err) {
703
- hookText = ` 钩子(dataHook)执行失败:${err instanceof Error ? err.message : String(err)}`
704
- }
705
- }
706
-
707
- // 产物行(hook 之外含自动落盘图像)
708
- if (artifacts.length > 0) {
709
- const shown = artifacts.slice(0, 8).map(a => `${a.name}(${Math.max(1, Math.round(a.bytes / 1024))}KB)`)
710
- hookText = `${hookText ?? ''}\n 产物(${artifacts.length}${artifacts.length > 8 ? ',显示前8' : ''}): ${shown.join(' | ')}`
711
- }
712
- return { text, stats, truncated, sample, hookText, artifacts }
713
- }
714
-
715
- /**
716
- * 取数编排(护栏全代码级):
717
- * 授权过滤 → 窗口/行数归一 → 频次限流 → 快照 / 内联 / 异步三模式。
718
- */
719
- async function fetch(agentId: string, args: MesFetchArgs): Promise<MesFetchOutcome> {
720
- // ① 授权:ids 必须是调用者可见(绑线)的 mes-rest 节点
721
- const vis = await resolveVisibleIds(agentId, args.ids)
722
- if (!vis.ok) return { text: vis.text, isError: true }
723
- // ② 窗口/行数护栏
724
- const win = normalizeWindow(args)
725
- if (!win.ok) return { text: win.text, isError: true }
726
- // ③ 频次限流(每 agent 每 60s ≤6 次)
727
- if (!mesFetchRateCheck(agentId, d.nowMs())) {
728
- return { text: `取数过于频繁:每 60 秒最多 ${MES_RATE_MAX_CALLS} 次。请先消化已有结果,稍后再取。`, isError: true }
729
- }
730
- // ④ 格式门控:image/table/event 的原文(帧/记录)不进 prompt 也不落 CSV 数据集,
731
- // 只支持内联行数(≤MES_SYNC_INLINE_MAX_ROWS);大窗口请拆小分批
732
- if (win.maxRows > MES_SYNC_INLINE_MAX_ROWS) {
733
- const INLINE_ONLY = new Set(['image', 'table', 'event'])
734
- const hits = vis.nodes.filter(n => INLINE_ONLY.has(historyFormatOf(n.driverConfig as Record<string, unknown>)))
735
- if (hits.length > 0) {
736
- return {
737
- text: `行数上限冲突:${hits.map(n => `${n.name}(${n.id})`).join(', ')} 是 图像/表格/事件 格式点位,只在 max_rows ≤ ${MES_SYNC_INLINE_MAX_ROWS} 的内联模式支持(原文不落 CSV 数据集)。请缩小时间窗或调低 max_rows 后重取。`,
738
- isError: true,
739
- }
740
- }
741
- }
742
-
743
- // 模式一:当前值快照(无 from/to)
744
- if (!win.from || !win.to) {
745
- const lines: string[] = []
746
- for (const node of vis.nodes) {
747
- const driver = d.resolveDriver(node.driver)
748
- try {
749
- if (typeof driver.read !== 'function') {
750
- lines.push(`- ${node.name}(${node.id}):驱动 ${node.driver} 不支持读取`)
751
- continue
752
- }
753
- const r = await driver.read({ domain: { min: node.min, max: node.max }, driverConfig: node.driverConfig })
754
- const at = new Date(d.nowMs()).toISOString()
755
- if (r.dictionary && r.dictionary.length > 0) cacheDictionary(node.id, r.dictionary)
756
- const dict = r.dictionary && r.dictionary.length > 0 ? r.dictionary : mesDictionaryOfNode(node.id, node.driverConfig as Record<string, unknown>)
757
- lines.push(r.ok && r.eng != null
758
- ? `- ${node.name}(${node.id}):${fmtN(r.eng)}${node.unit} @ ${shortTs(at)}${dict.length > 0 ? `\n${formatDictionary(dict, ' ')}` : ''}`
759
- : `- ${node.name}(${node.id}):读取失败(${r.message.slice(0, 80)})`)
760
- }
761
- catch (err) {
762
- lines.push(`- ${node.name}(${node.id}):读取异常(${(err instanceof Error ? err.message : String(err)).slice(0, 80)})`)
763
- }
764
- }
765
- return {
766
- mode: 'snapshot',
767
- text: `MES 当前值快照(${vis.nodes.length} 个点位,内联直读):\n${lines.join('\n')}\n\n说明:当前值为直读快照;历史窗口用 mes_fetch 带 from/to(≤7 天,max_rows≤${MES_MAX_ROWS_CAP})。`,
768
- }
769
- }
770
-
771
- // 模式二:同步内联(行数 ≤ MES_SYNC_INLINE_MAX_ROWS;格式感知+dataHook 下沉)
772
- if (win.maxRows <= MES_SYNC_INLINE_MAX_ROWS) {
773
- const sections: string[] = []
774
- const statsOut: NonNullable<MesFetchOutcome['data']>['stats'] = []
775
- for (const node of vis.nodes) {
776
- try {
777
- const one = await inlineFetchNode(node, win.from, win.to, win.maxRows, args.param, args.include_data === true || args.include_data === 'true')
778
- sections.push(one.hookText ? `${one.text}\n${one.hookText}` : one.text)
779
- statsOut.push({ nodeId: node.id, stats: one.stats, truncated: one.truncated })
780
- }
781
- catch (err) {
782
- sections.push(`■ ${node.name}(id=${node.id})\n 取数失败:${err instanceof Error ? err.message : String(err)}`)
783
- }
784
- }
785
- return {
786
- mode: 'inline',
787
- text: `MES 历史取数(内联同步,${vis.nodes.length} 个点位,窗口 ${shortTs(win.from)} ~ ${shortTs(win.to)}):\n${sections.join('\n')}\n\n说明:以上为统计摘要与 ≤3 行采样;MES 原文不进入对话。向量/图像/记录点位按各自格式呈现,已配置数据钩子(dataHook)的点位会附处理摘要与产物清单(文件落 <数据根>/mes-artifacts/<点位id>/)。需要标量/向量全量行请用更大 max_rows(> ${MES_SYNC_INLINE_MAX_ROWS})走异步数据集,再用 mes_dataset_read 读。`,
788
- data: { stats: statsOut },
789
- }
790
- }
791
-
792
- // 模式三:异步数据集(行数 > MES_SYNC_INLINE_MAX_ROWS;进程内异步,绝不进调度循环;
793
- // requestHook 覆盖在此同样生效——合并进作业用的 driverConfig)
794
- const jobIds: string[] = []
795
- const datasetIds: string[] = []
796
- const lines: string[] = []
797
- for (const node of vis.nodes) {
798
- let effCfg: Record<string, unknown>
799
- try {
800
- effCfg = await configWithRequestHook(node, args.param)
801
- }
802
- catch (err) {
803
- lines.push(`- ${node.name}(${node.id}):requestHook 失败,作业未创建(${err instanceof Error ? err.message : String(err)})`)
804
- continue
805
- }
806
- const run = node.lineId ? getActiveLineRun(node.lineId) : null
807
- const { jobId, datasetId } = d.store.createFetchJob({
808
- nodeId: node.id,
809
- fromIso: win.from,
810
- toIso: win.to,
811
- maxRows: win.maxRows,
812
- agentId,
813
- lineId: node.lineId,
814
- nodeName: node.name,
815
- driverConfig: effCfg,
816
- dictionary: mesDictionaryOfNode(node.id, node.driverConfig as Record<string, unknown>),
817
- nodeMeta: {
818
- unit: node.unit,
819
- min: node.min,
820
- max: node.max,
821
- description: String(node.driverConfig.desc ?? ''),
822
- semantics: String(node.driverConfig.semantics ?? ''),
823
- format: historyFormatOf(node.driverConfig as Record<string, unknown>),
824
- },
825
- context: run
826
- ? { lineId: run.lineId, productId: run.productId, recipeId: run.recipeId, runId: run.runId }
827
- : { lineId: node.lineId },
828
- })
829
- jobIds.push(jobId)
830
- datasetIds.push(datasetId)
831
- lines.push(`- ${node.name}(${node.id}):job_id=${jobId} dataset_id=${datasetId} status=running`)
832
- }
833
- return {
834
- mode: 'async',
835
- text: `已创建 ${lines.length} 个异步取数作业(窗口 ${shortTs(win.from)} ~ ${shortTs(win.to)},max_rows=${win.maxRows}):\n${lines.join('\n')}\n\n勿轮询;未完成先做别的,用 mes_datasets 查状态,完成后 mes_dataset_read(dataset_id, mode=stats/rows) 读内容。`,
836
- data: { job_ids: jobIds, dataset_ids: datasetIds },
837
- }
838
- }
839
-
840
- // ---------- 离线导出(指定目录 + manifest/README 语义清单) ----------
841
-
842
- /** 安全子路径:只允许落在 root 内(拒绝 ../、绝对路径逃逸、盘符切换) */
843
- function resolveUnderRoot(root: string, folder: string, fallback: string): { ok: true, dir: string } | { ok: false, text: string } {
844
- const base = resolve(root)
845
- const raw = String(folder ?? '').trim()
846
- if (!raw) return { ok: true, dir: join(base, fallback) }
847
- const target = resolve(base, raw)
848
- if (target !== base && !target.startsWith(`${base}${sep}`)) {
849
- return {
850
- ok: false,
851
- text: `导出目录被拒:folder=${raw} 越出允许根目录 ${base}(只接受相对路径;如需自定义根目录,请由管理员设置环境变量 AW_MES_EXPORT_ROOT)。`,
852
- }
853
- }
854
- return { ok: true, dir: target }
855
- }
856
-
857
- function safeSeg(value: string): string {
858
- return value.replace(/[^A-Za-z0-9._-]/g, '_').slice(0, 80) || 'node'
859
- }
860
-
861
- function writeChunk(fd: number, text: string): void {
862
- const buf = Buffer.from(text, 'utf8')
863
- let off = 0
864
- while (off < buf.length) off += writeSync(fd, buf, off, buf.length - off)
865
- }
866
-
867
- /**
868
- * 把可见 MES 点位的历史原样导出到目录(流式写盘):
869
- * scalar → data.csv(ts,value)
870
- * vector → data.csv(宽表 ts,v0..vN)+ manifest 里的逐点语义
871
- * image → frames.jsonl(元数据)+ frames/*.png
872
- * table/event → records.jsonl
873
- * 每个导出目录都写 manifest.json + README.md(字段含义/单位/量程/产线批次上下文),
874
- * Agent 与离线分析器都能直接读懂,不需要回读平台。
875
- */
876
- async function exportData(agentId: string, args: MesExportArgs): Promise<MesToolResult & { dir?: string, manifestPath?: string, rows?: number }> {
877
- const vis = await resolveVisibleIds(agentId, args.ids)
878
- if (!vis.ok) return { text: vis.text, isError: true }
879
- const from = String(args.from ?? '').trim()
880
- const to = String(args.to ?? '').trim()
881
- if (!from || !to) return { text: 'mes_export 需要 from/to(ISO)历史窗口;当前值快照请用 mes_fetch。', isError: true }
882
- const fromMs = Date.parse(from)
883
- const toMs = Date.parse(to)
884
- if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return { text: 'from/to 必须是合法 ISO 时间戳。', isError: true }
885
- if (fromMs >= toMs) return { text: `时间窗无效:from(${from}) 必须早于 to(${to})。`, isError: true }
886
- if (toMs - fromMs > MES_WINDOW_MAX_MS) {
887
- return { text: `时间窗被拒:超过 7 天上限。请拆成 ≤7 天的分段导出。`, isError: true }
888
- }
889
- const rawMax = args.max_rows == null || args.max_rows === '' ? MES_MAX_ROWS_CAP : Math.round(Number(args.max_rows))
890
- if (!Number.isFinite(rawMax) || rawMax < 1) return { text: 'max_rows 必须为 ≥1 的整数。', isError: true }
891
- const maxRows = Math.min(rawMax, MES_EXPORT_MAX_ROWS)
892
- if (!mesFetchRateCheck(agentId, d.nowMs())) {
893
- return { text: `导出过于频繁:每 60 秒最多 ${MES_RATE_MAX_CALLS} 次。请稍后再试。`, isError: true }
894
- }
895
-
896
- const root = process.env.AW_MES_EXPORT_ROOT
897
- ? resolve(process.env.AW_MES_EXPORT_ROOT)
898
- : join(ensureDataDir(), 'mes-exports')
899
- const exportId = `mesexp-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}-${randomUUID().slice(0, 6)}`
900
- const where = resolveUnderRoot(root, String(args.folder ?? ''), exportId)
901
- if (!where.ok) return { text: where.text, isError: true }
902
- const dir = where.dir
903
- mkdirSync(dir, { recursive: true })
904
-
905
- const title = String(args.title ?? '').trim() || `MES 数据导出 ${exportId}`
906
- const note = String(args.note ?? '').trim()
907
- const manifestNodes: Array<Record<string, unknown>> = []
908
- const failures: string[] = []
909
- const scalarFiles: Array<{ nodeName: string, nodeId: string, file: string }> = []
910
- let totalRows = 0
911
-
912
- for (const node of vis.nodes) {
913
- const cfg = node.driverConfig as Record<string, unknown>
914
- const format = historyFormatOf(cfg)
915
- const nodeDir = join(dir, safeSeg(node.id))
916
- try {
917
- mkdirSync(nodeDir, { recursive: true })
918
- const driver = d.resolveDriver(node.driver)
919
- if (typeof driver.fetchHistory !== 'function') {
920
- failures.push(`${node.name}(${node.id}):驱动 ${node.driver} 无历史原语`)
921
- continue
922
- }
923
- const effCfg = await configWithRequestHook(node, args.param)
924
- const run = node.lineId ? getActiveLineRun(node.lineId) : null
925
- let dictionary = mesDictionaryOfNode(node.id, cfg)
926
- let rows = 0
927
- let truncated = false
928
- let dim = 0
929
- let dimDrift = 0
930
- let skipped = 0
931
- let frameSaved = 0
932
- let frameSkipped = 0
933
- let fd: number | null = null
934
- let headerWritten = false
935
- let columns: string[] = []
936
- let fileRel = ''
937
- const jsonl: string[] = []
938
-
939
- if (format === 'image') {
940
- mkdirSync(join(nodeDir, 'frames'), { recursive: true })
941
- }
942
- else {
943
- fd = openSync(join(nodeDir, format === 'table' || format === 'event' ? 'records.jsonl' : 'data.csv'), 'w')
944
- }
945
-
946
- const result = await driver.fetchHistory({
947
- driverConfig: effCfg,
948
- fromIso: from,
949
- toIso: to,
950
- maxRows,
951
- onRows: (batch) => {
952
- if (!Array.isArray(batch)) return
953
- for (const r of batch) {
954
- if (rows >= maxRows) {
955
- truncated = true
956
- break
957
- }
958
- const ts = String(r?.ts ?? '')
959
- if (format === 'vector') {
960
- if (!Array.isArray(r?.values) || r.values.length === 0) {
961
- skipped++
962
- continue
963
- }
964
- if (!headerWritten) {
965
- dim = r.values.length
966
- columns = ['ts', ...Array.from({ length: dim }, (_, i) => `v${i}`)]
967
- writeChunk(fd!, `${columns.join(',')}\r\n`)
968
- headerWritten = true
969
- }
970
- if (r.values.length !== dim) dimDrift++
971
- const cells = [ts]
972
- for (let i = 0; i < dim; i++) {
973
- const v = r.values[i]
974
- cells.push(Number.isFinite(v) ? String(v) : '')
975
- }
976
- writeChunk(fd!, `${cells.join(',')}\r\n`)
977
- rows++
978
- continue
979
- }
980
- if (format === 'image') {
981
- if (typeof r?.data !== 'string' || r.data.trim() === '') {
982
- skipped++
983
- continue
984
- }
985
- if (frameSaved >= MES_EXPORT_MAX_FRAMES) {
986
- frameSkipped++
987
- truncated = true
988
- continue
989
- }
990
- const mime = typeof r.mime === 'string' && r.mime.includes('/') ? r.mime : 'image/png'
991
- const ext = mime.includes('jpeg') ? 'jpg' : mime.includes('webp') ? 'webp' : 'png'
992
- const name = `frames/${String(frameSaved).padStart(5, '0')}-${ts.replace(/[:.]/g, '-')}.${ext}`
993
- try {
994
- writeFileSync(join(nodeDir, name), Buffer.from(r.data, 'base64'))
995
- jsonl.push(JSON.stringify({ ts, mime, file: name, ...(r.record !== null && typeof r.record === 'object' ? { record: r.record } : {}) }))
996
- frameSaved++
997
- rows++
998
- }
999
- catch (imgErr) {
1000
- skipped++
1001
- jsonl.push(JSON.stringify({ ts, mime, error: imgErr instanceof Error ? imgErr.message : String(imgErr) }))
1002
- }
1003
- continue
1004
- }
1005
- if (format === 'table' || format === 'event') {
1006
- if (r?.record === null || r?.record === undefined) {
1007
- skipped++
1008
- continue
1009
- }
1010
- jsonl.push(JSON.stringify({ ts, record: r.record }))
1011
- rows++
1012
- continue
1013
- }
1014
- if (typeof r?.value !== 'number' || !Number.isFinite(r.value)) {
1015
- skipped++
1016
- continue
1017
- }
1018
- if (!headerWritten) {
1019
- columns = ['ts', 'value']
1020
- writeChunk(fd!, `${columns.join(',')}\r\n`)
1021
- headerWritten = true
1022
- }
1023
- writeChunk(fd!, `${ts},${r.value}\r\n`)
1024
- rows++
1025
- }
1026
- },
1027
- })
1028
- if (result?.dictionary && result.dictionary.length > 0) {
1029
- dictionary = result.dictionary
1030
- cacheDictionary(node.id, dictionary)
1031
- }
1032
- if (result && result.complete === false) truncated = true
1033
- if (format === 'image' || format === 'table' || format === 'event') {
1034
- writeFileSync(join(nodeDir, 'records.jsonl'), `${jsonl.join('\n')}${jsonl.length > 0 ? '\n' : ''}`, 'utf8')
1035
- fileRel = `${safeSeg(node.id)}/records.jsonl`
1036
- }
1037
- else {
1038
- if (!headerWritten) {
1039
- columns = format === 'vector' ? ['ts'] : ['ts', 'value']
1040
- writeChunk(fd!, `${columns.join(',')}\r\n`)
1041
- headerWritten = true
1042
- }
1043
- fileRel = `${safeSeg(node.id)}/data.csv`
1044
- }
1045
- if (fd != null) {
1046
- closeSync(fd)
1047
- fd = null
1048
- }
1049
- if (format === 'scalar') scalarFiles.push({ nodeName: node.name, nodeId: node.id, file: fileRel })
1050
- totalRows += rows
1051
- manifestNodes.push({
1052
- id: node.id,
1053
- name: node.name,
1054
- line_id: node.lineId,
1055
- format,
1056
- unit: node.unit,
1057
- range: { min: node.min, max: node.max },
1058
- description: String(cfg.desc ?? ''),
1059
- semantics: String(cfg.semantics ?? ''),
1060
- file: fileRel,
1061
- columns,
1062
- rows,
1063
- ...(format === 'vector' ? { vector: { dim, dimension_drift_rows: dimDrift } } : {}),
1064
- ...(format === 'image' ? { frames: { saved: frameSaved, skipped: frameSkipped } } : {}),
1065
- skipped_rows: skipped,
1066
- truncated,
1067
- fields: dictionary,
1068
- context: run ? { line_id: run.lineId, product_id: run.productId, recipe_id: run.recipeId, run_id: run.runId } : { line_id: node.lineId },
1069
- })
1070
- }
1071
- catch (err) {
1072
- failures.push(`${node.name}(${node.id}):${err instanceof Error ? err.message : String(err)}`)
1073
- }
1074
- }
1075
-
1076
- // 多标量节点按时间对齐的宽表(默认生成;纯时间戳交集,不做插值)
1077
- let mergedFile: string | null = null
1078
- const mergeEnabled = !(args.merge === false || args.merge === 'false')
1079
- if (mergeEnabled && scalarFiles.length > 1) {
1080
- try {
1081
- const series = scalarFiles.map((s) => {
1082
- const map = new Map<string, number>()
1083
- const raw = readFileSync(join(dir, s.file), 'utf8')
1084
- for (const line of raw.split(/\r?\n/).slice(1)) {
1085
- const [ts, v] = line.split(',')
1086
- if (ts && v !== undefined && Number.isFinite(Number(v))) map.set(ts, Number(v))
1087
- }
1088
- return { ...s, map }
1089
- })
1090
- const times = [...new Set(series.flatMap(s => [...s.map.keys()]))].sort()
1091
- const header = ['time', ...series.map(s => `${s.nodeName}(${s.nodeId})`)]
1092
- const lines = [header.join(',')]
1093
- for (const ts of times) lines.push([ts, ...series.map(s => s.map.get(ts) ?? '')].join(','))
1094
- writeFileSync(join(dir, 'merged.csv'), `${lines.join('\n')}\n`, 'utf8')
1095
- mergedFile = join(dir, 'merged.csv')
1096
- }
1097
- catch { /* merge 失败不影响单节点导出 */ }
1098
- }
1099
-
1100
- const manifest = {
1101
- schema: 'aw.mes-export/1',
1102
- export_id: exportId,
1103
- created_at: new Date().toISOString(),
1104
- title,
1105
- note,
1106
- window: { from, to, from_ms: fromMs, to_ms: toMs },
1107
- directory: dir,
1108
- nodes: manifestNodes,
1109
- merged_file: mergedFile,
1110
- totals: { nodes: manifestNodes.length, rows: totalRows, failed_nodes: failures.length },
1111
- usage: 'data.csv 首行为列名(ts=时间,v0..vN=向量点位);records.jsonl 每行一条记录;image 格式的像素在 frames/ 下,records.jsonl 是对应元数据。字段含义/单位/量程见 nodes[].fields(向量逐点语义在 fields[].points);批次归属见 nodes[].context。',
1112
- }
1113
- const manifestPath = join(dir, 'manifest.json')
1114
- writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8')
1115
-
1116
- const readme: string[] = [
1117
- `# ${title}`,
1118
- '',
1119
- `- 导出时间: ${new Date().toISOString()}`,
1120
- `- 时间窗: ${from} ~ ${to}`,
1121
- `- 导出目录: ${dir}`,
1122
- `- 说明: ${note || '(无)'}`,
1123
- '',
1124
- '## 文件与字段',
1125
- '',
1126
- ]
1127
- for (const n of manifestNodes) {
1128
- readme.push(`### ${String(n.name)} (${String(n.id)})`)
1129
- readme.push(`- 格式: ${String(n.format)};文件: ${String(n.file)};行数: ${String(n.rows)}`)
1130
- readme.push(`- 单位: ${String(n.unit || '-')};量程: ${JSON.stringify(n.range)}`)
1131
- if (n.semantics) readme.push(`- 物理意义: ${String(n.semantics)}`)
1132
- const fields = Array.isArray(n.fields) ? n.fields as DcwFieldDef[] : []
1133
- const dict = formatDictionary(fields, ' ')
1134
- if (dict) readme.push(dict)
1135
- readme.push('')
1136
- }
1137
- if (mergedFile) readme.push(`多参数对齐宽表: ${mergedFile}(列名=节点名(节点id);仅对齐相同时间戳,不插值)`, '')
1138
- if (failures.length > 0) readme.push('## 失败节点', '', ...failures.map(f => `- ${f}`), '')
1139
- writeFileSync(join(dir, 'README.md'), `${readme.join('\n')}\n`, 'utf8')
1140
-
1141
- const lines = manifestNodes.map(n => `- ${String(n.name)}(${String(n.id)}) [${String(n.format)}] ${String(n.rows)} 行 → ${String(n.file)}`)
1142
- const failText = failures.length > 0 ? `\n失败节点(${failures.length}):\n${failures.map(f => ` - ${f}`).join('\n')}` : ''
1143
- return {
1144
- isError: failures.length > 0,
1145
- dir,
1146
- manifestPath,
1147
- rows: totalRows,
1148
- text: `MES 数据已导出(${manifestNodes.length}/${vis.nodes.length} 个点位,共 ${totalRows} 行):\n${lines.join('\n')}${mergedFile ? `\n- 多参数宽表: ${mergedFile}` : ''}${failText}\n\n目录: ${dir}\n语义清单: ${manifestPath}\n说明: README.md\n\n离线分析请直接读取上述文件;在线继续取数用 mes_fetch/mes_dataset_read。`,
1149
- }
1150
- }
1151
-
1152
- return { catalog, fetch, exportData }
1153
- }
1154
-
1155
- export type MesController = ReturnType<typeof createMesController>
1
+ /**
2
+ * MES 取数控制器(Agent 工具后端)—— mes-rest 点位目录 + 历史取数编排。
3
+ *
4
+ * 护栏全部**代码级**(不是提示词):绑线授权过滤、时间窗 ≤7 天、maxRows ≤5000、
5
+ * 每 agent 每 60s ≤6 次 fetch;数据原文不进 prompt —— 文本只给 stats + ≤3 行采样,
6
+ * 行级原文只落 CSV 数据集(mes-datasets)。
7
+ *
8
+ * 取数三模式:
9
+ * 无 from/to → 当前值快照(driver.read 内联直读);
10
+ * from/to 且 maxRows ≤ 2000 → 同步 fetchHistory 内联返回(缓冲截断保护);
11
+ * 其余(maxRows > 2000) → createFetchJob 异步落 CSV,回 job_id/dataset_id。
12
+ */
13
+ import { randomUUID } from 'node:crypto'
14
+ import { closeSync, mkdirSync, openSync, readFileSync, writeFileSync, writeSync } from 'node:fs'
15
+ import { join, resolve, sep } from 'node:path'
16
+ import { ensureDataDir } from '@/shared/config/home.mjs'
17
+ import { getActiveLineRun } from '../dcw/line-run'
18
+ import { resolveDcwDriver } from '../dcw/drivers'
19
+ import type { DcwFieldDef, DcwHistoryFormat as MesHistoryFormat } from '../dcw/drivers/shared'
20
+ import { historyFormatOf, normalizeMesDictionary } from '../dcw/drivers/mes-rest'
21
+ import type { MesHistoryDriver, MesDatasetStatsView, MesDatasetStore } from './mes-datasets'
22
+ import { getMesDatasets } from './mes-datasets'
23
+ import { mesDataHookCode, mesRequestHookCode, runMesDataHook, runMesRequestHook, saveMesImageArtifact } from './mes-hook'
24
+ import type { MesHookArtifact, MesHookData } from './mes-hook'
25
+
26
+ /** mes-rest 驱动 kind(并行工作流收编进 DcwDriverKind 联合;此处按字符串经注册表解析,不 import 驱动实现) */
27
+ export const MES_REST_DRIVER_KIND = 'mes-rest'
28
+
29
+ // ============================================================
30
+ // 护栏常量(单一事实源;测试直接引用)
31
+ // ============================================================
32
+
33
+ /** 历史窗口上限:7 天 */
34
+ export const MES_WINDOW_MAX_MS = 7 * 24 * 3_600_000
35
+ /** 单次取数行数硬上限 */
36
+ export const MES_MAX_ROWS_CAP = 5000
37
+ /** 同步内联返回的行数上限(超过走异步数据集) */
38
+ export const MES_SYNC_INLINE_MAX_ROWS = 2000
39
+ /** 频次限流:窗口与次数(每 agent) */
40
+ export const MES_RATE_WINDOW_MS = 60_000
41
+ export const MES_RATE_MAX_CALLS = 6
42
+ /** max_rows 缺省值 */
43
+ export const MES_DEFAULT_MAX_ROWS = 500
44
+ /** 离线导出单次行数上限(CSV/JSONL 流式写盘;比在线取数宽,仍防磁盘失控) */
45
+ export const MES_EXPORT_MAX_ROWS = 200_000
46
+ /** 离线导出图像帧上限(单次) */
47
+ export const MES_EXPORT_MAX_FRAMES = 500
48
+
49
+ // ============================================================
50
+ // 频次限流(进程内内存计数;Map<agentId, 时间戳[]>)
51
+ // ============================================================
52
+
53
+ const fetchCallStamps = new Map<string, number[]>()
54
+
55
+ /** 记一次 fetch 并判定是否放行(滑动 60s 窗 ≤6 次;超限不记账) */
56
+ export function mesFetchRateCheck(agentId: string, nowMs = Date.now()): boolean {
57
+ const stamps = (fetchCallStamps.get(agentId) ?? []).filter(t => nowMs - t < MES_RATE_WINDOW_MS)
58
+ if (stamps.length >= MES_RATE_MAX_CALLS) {
59
+ fetchCallStamps.set(agentId, stamps)
60
+ return false
61
+ }
62
+ stamps.push(nowMs)
63
+ fetchCallStamps.set(agentId, stamps)
64
+ return true
65
+ }
66
+
67
+ /** 清空限流账(测试用) */
68
+ export function mesFetchRateReset(): void {
69
+ fetchCallStamps.clear()
70
+ }
71
+
72
+ // ============================================================
73
+ // 节点/依赖(结构化注入;缺省接真实服务,测试注入假件不联网)
74
+ // ============================================================
75
+
76
+ export interface MesNodeLike {
77
+ id: string
78
+ name: string
79
+ driver: string
80
+ lineId: string
81
+ unit: string
82
+ min: number
83
+ max: number
84
+ enabled: boolean
85
+ driverConfig: Record<string, string | number | boolean>
86
+ }
87
+
88
+ export interface MesControllerDeps {
89
+ /** 数据集服务(异步取数账本;缺省 getMesDatasets()) */
90
+ store: Pick<MesDatasetStore, 'createFetchJob'>
91
+ /** 全量 dcw 节点(缺省 dcw-node.repo) */
92
+ nodes: () => MesNodeLike[] | Promise<MesNodeLike[]>
93
+ /** 调用者可见节点(绑线过滤:dcw 绑定集;缺省 node-bindings.repo) */
94
+ boundNodeIds: (agentId: string) => Set<string> | Promise<Set<string>>
95
+ /** 驱动解析(缺省 dcw 注册表) */
96
+ resolveDriver: (kind: string) => MesHistoryDriver
97
+ nowMs: () => number
98
+ }
99
+
100
+ /** 缺省依赖:重模块(dcw 仓储/绑线仓储)经动态 import 引入,保持本模块可被 tsx 测试轻量直跑 */
101
+ function defaultDeps(): MesControllerDeps {
102
+ return {
103
+ store: new Proxy({} as Pick<MesDatasetStore, 'createFetchJob'>, {
104
+ get: (_t, prop) => {
105
+ const store = getMesDatasets() as unknown as Record<string | symbol, unknown>
106
+ const v = store[prop]
107
+ return typeof v === 'function' ? (v as (...a: unknown[]) => unknown).bind(store) : v
108
+ },
109
+ }),
110
+ nodes: async () => {
111
+ const { getDcwNodeRepo } = await import('../dcw/dcw-node.repo')
112
+ return getDcwNodeRepo().all()
113
+ },
114
+ boundNodeIds: async (agentId) => {
115
+ // 权限模型 v2:dcw 绑定(存量)∪ 绑定配方内的参数节点(kind='recipe' 的配方可见节点)
116
+ const { getAgentNodeBindingRepo } = await import('../agents/node-bindings.repo')
117
+ const { getDcwController } = await import('../dcw/dcw-controller')
118
+ const bindings = getAgentNodeBindingRepo().byAgent(agentId)
119
+ const ids = new Set(bindings.filter(b => b.kind === 'dcw').map(b => b.nodeId))
120
+ const recipeIds = new Set(bindings.filter(b => b.kind === 'recipe').map(b => b.nodeId))
121
+ if (recipeIds.size > 0) {
122
+ for (const r of getDcwController().listRecipes()) {
123
+ if (!recipeIds.has(r.id)) continue
124
+ for (const p of r.params) ids.add(p.nodeId)
125
+ }
126
+ }
127
+ return ids
128
+ },
129
+ resolveDriver: kind => resolveDcwDriver(kind as Parameters<typeof resolveDcwDriver>[0]),
130
+ nowMs: () => Date.now(),
131
+ }
132
+ }
133
+
134
+ export type MesCatalogEntry = {
135
+ id: string
136
+ name: string
137
+ lineId: string
138
+ unit: string
139
+ min: number
140
+ max: number
141
+ desc: string
142
+ readable: boolean
143
+ writable: boolean
144
+ historyable: boolean
145
+ /** 历史格式(scalar/vector/image/table/event;historyMap 未配置时 scalar) */
146
+ format: MesHistoryFormat
147
+ /** 已配置数据下沉 hook(dataHook) */
148
+ hooked: boolean
149
+ enabled: boolean
150
+ /** 字段级数据字典(响应缓存 ∪ 节点静态配置;无则空数组) */
151
+ fields: DcwFieldDef[]
152
+ }
153
+
154
+ // ============================================================
155
+ // 字段字典缓存(响应返回 → 后续 catalog/导出复用)
156
+ // ============================================================
157
+
158
+ const dictionaryCache = new Map<string, DcwFieldDef[]>()
159
+ const DICTIONARY_CACHE_MAX = 200
160
+
161
+ function cacheDictionary(nodeId: string, fields: DcwFieldDef[] | undefined): void {
162
+ if (!fields || fields.length === 0) return
163
+ dictionaryCache.delete(nodeId)
164
+ dictionaryCache.set(nodeId, fields)
165
+ while (dictionaryCache.size > DICTIONARY_CACHE_MAX) {
166
+ const oldest = dictionaryCache.keys().next().value
167
+ if (oldest === undefined) break
168
+ dictionaryCache.delete(oldest)
169
+ }
170
+ }
171
+
172
+ /** 节点静态字典(driverConfig.dictionary / fieldDictionary 的 JSON 文本) */
173
+ function configuredDictionary(cfg: Record<string, unknown>): DcwFieldDef[] {
174
+ for (const key of ['dictionary', 'fieldDictionary', 'fields']) {
175
+ const raw = cfg[key]
176
+ if (raw === undefined || raw === null || String(raw).trim() === '') continue
177
+ try {
178
+ const parsed = typeof raw === 'string' ? JSON.parse(raw) as unknown : raw
179
+ const fields = normalizeMesDictionary(parsed)
180
+ if (fields.length > 0) return fields
181
+ }
182
+ catch { /* 坏配置不击穿目录;由驱动测试报错 */ }
183
+ }
184
+ return []
185
+ }
186
+
187
+ /** 节点有效字典:响应缓存优先(实时真相),否则静态配置 */
188
+ export function mesDictionaryOfNode(nodeId: string, cfg: Record<string, unknown>): DcwFieldDef[] {
189
+ return dictionaryCache.get(nodeId) ?? configuredDictionary(cfg)
190
+ }
191
+
192
+ /** 字典一行摘要(字段名(标签,单位;量程;点数)) */
193
+ export function fieldSummaryOf(fields: DcwFieldDef[]): string {
194
+ return fields.slice(0, 8).map((f) => {
195
+ const bits = [f.label, f.unit, f.min != null || f.max != null ? `${f.min ?? '-∞'}~${f.max ?? '+∞'}` : '', f.points?.length ? `${f.points.length} 点` : '']
196
+ .filter(Boolean)
197
+ return bits.length > 0 ? `${f.field}(${bits.join(',')})` : f.field
198
+ }).join('; ')
199
+ }
200
+
201
+ /** 字段字典 → 多行可读文本(Agent 直接引用;含单位/量程/物理意义/逐点语义) */
202
+ export function formatDictionary(fields: DcwFieldDef[], indent = ' '): string {
203
+ if (fields.length === 0) return ''
204
+ const pointLine = (f: DcwFieldDef): string => {
205
+ const pts = f.points ?? []
206
+ if (pts.length === 0) return ''
207
+ const head = pts.slice(0, 6).map(p => `${p.index ?? '?'}=${p.label ?? p.field}${p.unit ? `(${p.unit})` : ''}`).join(', ')
208
+ return `; 点位 ${pts.length} 个: ${head}${pts.length > 6 ? ', …' : ''}`
209
+ }
210
+ const lines = fields.slice(0, 24).map((f) => {
211
+ const meta = [
212
+ f.label && f.label !== f.field ? `标签 ${f.label}` : '',
213
+ f.unit ? `单位 ${f.unit}` : '',
214
+ f.min != null || f.max != null ? `量程 ${f.min ?? '-∞'}~${f.max ?? '+∞'}` : '',
215
+ f.kind ? `形态 ${f.kind}` : '',
216
+ ].filter(Boolean).join(' | ')
217
+ const desc = f.description ? ` — ${f.description.slice(0, 160)}` : ''
218
+ return `${indent}- ${f.field}${meta ? ` [${meta}]` : ''}${desc}${pointLine(f)}`
219
+ })
220
+ return `字段字典(${fields.length} 个字段,来自 MES 响应/节点配置):\n${lines.join('\n')}${fields.length > 24 ? `\n${indent}(仅显示前 24 个字段)` : ''}`
221
+ }
222
+
223
+ /** 目录条目合成:desc/readMap/writeMap/historyMap 均来自 driverConfig(数据驱动,零硬编码) */
224
+ export function mesCatalogEntryOf(n: MesNodeLike): MesCatalogEntry {
225
+ const cfg = n.driverConfig ?? {}
226
+ return {
227
+ id: n.id,
228
+ name: n.name,
229
+ lineId: n.lineId ?? '',
230
+ unit: n.unit ?? '',
231
+ min: n.min,
232
+ max: n.max,
233
+ desc: String(cfg.desc ?? ''),
234
+ readable: Boolean(cfg.readMap),
235
+ writable: Boolean(cfg.writeMap),
236
+ historyable: Boolean(cfg.historyMap),
237
+ format: historyFormatOf(cfg as Record<string, unknown>),
238
+ hooked: Boolean(cfg.dataHook),
239
+ enabled: Boolean(n.enabled),
240
+ fields: mesDictionaryOfNode(n.id, cfg as Record<string, unknown>),
241
+ }
242
+ }
243
+
244
+ // ============================================================
245
+ // 控制器
246
+ // ============================================================
247
+
248
+ export type MesToolResult = { text: string, isError?: boolean }
249
+
250
+ export type MesFetchOutcome = MesToolResult & {
251
+ mode?: 'snapshot' | 'inline' | 'async'
252
+ data?: {
253
+ job_ids?: string[]
254
+ dataset_ids?: string[]
255
+ stats?: Array<{ nodeId: string, stats: MesDatasetStatsView, truncated: boolean }>
256
+ }
257
+ }
258
+
259
+ export interface MesFetchArgs {
260
+ ids?: unknown
261
+ from?: string
262
+ to?: string
263
+ max_rows?: number | string
264
+ /** 透传给 requestHook/dataHook 的参数对象(Agent 只传 param,其余交给配置) */
265
+ param?: unknown
266
+ /** 内联/快照回包是否附带采样行的实际数组/数值内容(默认 false=只给统计与均值) */
267
+ include_data?: boolean | string
268
+ }
269
+
270
+ export interface MesCatalogArgs {
271
+ q?: string
272
+ line_id?: string
273
+ /** 按产品 id 收窄到该产品产线(可选;与 line_id 冲突时拒绝) */
274
+ product_id?: string
275
+ /** 按配方 id 收窄到该配方产线(可选;与 line_id 冲突时拒绝) */
276
+ recipe_id?: string
277
+ limit?: number | string
278
+ /** 调用者可读产线集(绑线授权口径);提供时严格过滤(孤儿/越线点位不可见,空集=空目录 fail-closed) */
279
+ scope_line_ids?: string[]
280
+ }
281
+
282
+ export interface MesExportArgs {
283
+ ids?: unknown
284
+ from?: string
285
+ to?: string
286
+ max_rows?: number | string
287
+ /** 透传给 requestHook 的调用参数 */
288
+ param?: unknown
289
+ /** 导出子目录(相对 <数据根>/mes-exports;绝对路径须落在 AW_MES_EXPORT_ROOT 内) */
290
+ folder?: string
291
+ title?: string
292
+ note?: string
293
+ /** 标量节点是否生成按时间对齐的 merged.csv(缺省 true) */
294
+ merge?: boolean | string
295
+ }
296
+
297
+ export function createMesController(deps: Partial<MesControllerDeps> = {}) {
298
+ const d: MesControllerDeps = { ...defaultDeps(), ...deps }
299
+
300
+ // ---------- 目录 ----------
301
+
302
+ /** mes-rest 点位目录(q 对 name/desc 子串过滤;line_id 精确过滤;limit 缺省 20;
303
+ * scope_line_ids 提供时按调用者可读产线严格过滤——跨产线点位与孤儿(未分配)点位不可见) */
304
+ async function catalog(args: MesCatalogArgs = {}): Promise<MesToolResult & { entries: MesCatalogEntry[], total: number }> {
305
+ const all = await d.nodes()
306
+ let mes = all.filter(n => n.driver === MES_REST_DRIVER_KIND).map(mesCatalogEntryOf)
307
+ if (Array.isArray(args.scope_line_ids)) {
308
+ const scope = new Set(args.scope_line_ids)
309
+ mes = mes.filter(e => e.lineId !== '' && scope.has(e.lineId))
310
+ }
311
+ const total = mes.length
312
+ let lineId = String(args.line_id ?? '').trim()
313
+ const productId = String(args.product_id ?? '').trim()
314
+ if (productId) {
315
+ const { getDcwProductRepo } = await import('../dcw/dcw-product.repo')
316
+ const product = getDcwProductRepo().byId(productId)
317
+ if (!product) return { text: `产品 ${productId} 不存在。`, isError: true, entries: [], total: 0 }
318
+ if (lineId && product.lineId !== lineId) return { text: `产品 ${productId} 归属产线 ${product.lineId},与 line_id=${lineId} 不一致。`, isError: true, entries: [], total: 0 }
319
+ lineId = product.lineId
320
+ }
321
+ const recipeId = String(args.recipe_id ?? '').trim()
322
+ if (recipeId) {
323
+ const { getDcwController } = await import('../dcw/dcw-controller')
324
+ const recipe = getDcwController().listRecipes().find(r => r.id === recipeId)
325
+ if (!recipe) return { text: `配方 ${recipeId} 不存在。`, isError: true, entries: [], total: 0 }
326
+ if (lineId && recipe.lineId !== lineId) return { text: `配方 ${recipeId} 归属产线 ${recipe.lineId},与 line_id=${lineId} 不一致。`, isError: true, entries: [], total: 0 }
327
+ lineId = recipe.lineId
328
+ }
329
+ if (lineId) mes = mes.filter(e => e.lineId === lineId)
330
+ const q = String(args.q ?? '').trim().toLowerCase()
331
+ if (q) mes = mes.filter(e => e.name.toLowerCase().includes(q) || e.desc.toLowerCase().includes(q))
332
+ const limit = Math.min(Math.max(Math.round(Number(args.limit)) || 20, 1), 100)
333
+ const shown = mes.slice(0, limit)
334
+
335
+ const cap = (e: MesCatalogEntry): string => {
336
+ const hist = e.historyable ? (e.format !== 'scalar' ? `史·${e.format}` : '史') : null
337
+ const ab = [e.readable ? '读' : null, e.writable ? '写' : null, hist, e.hooked ? '钩子' : null].filter(Boolean)
338
+ return ab.length > 0 ? ab.join('/') : '无能力位'
339
+ }
340
+ const body = shown.map((e) => {
341
+ const fields = e.fields.length > 0 ? ` | 字段: ${fieldSummaryOf(e.fields)}` : ''
342
+ return `- ${e.name}(id=${e.id}) | 产线 ${e.lineId || '未分配'} | 单位 ${e.unit || '-'} | 量程 ${e.min}~${e.max} | 能力 ${cap(e)}${e.enabled ? '' : ' [停用]'}${e.desc ? ` | ${e.desc.slice(0, 80)}` : ''}${fields}`
343
+ })
344
+ const more = mes.length - shown.length
345
+ const text = `MES REST 点位目录(共 ${total} 个${lineId ? `,产线 ${lineId}` : ''}${q ? `,关键字「${args.q}」` : ''};显示 ${shown.length} 条):\n${body.join('\n') || '(无匹配点位)'}${more > 0 ? `\n(另有 ${more} 条未显示,可收紧 q/line_id 或调大 limit≤100)` : ''}\n\n说明:能力 读=可读当前值,写=可写设定值,史=可取历史(史·vector=每时间点检测向量,史·image=图像帧,史·table/event=记录流),钩子=已配 dataHook(取数后自动做下沉处理并回传摘要与产物)。字段级语义来自 MES 响应 dictionaryPath 或节点 driverConfig.dictionary;首次 mes_fetch 后缓存,后续目录可直接看到字段标签/单位/点位。历史取数用 mes_fetch(ids=[点位id], from, to, max_rows, param?);需要落盘到目录做离线分析用 mes_export。`
346
+ return { text, entries: shown, total }
347
+ }
348
+
349
+ // ---------- 取数 ----------
350
+
351
+ /** 归一 ids + 授权过滤(绑线路径:仅调用者 dcw 绑定的 mes-rest 节点) */
352
+ async function resolveVisibleIds(agentId: string, rawIds: unknown): Promise<{ ok: true, nodes: MesNodeLike[] } | { ok: false, text: string, isError: true }> {
353
+ const ids = Array.isArray(rawIds) ? [...new Set(rawIds.map(x => String(x ?? '').trim()).filter(Boolean))] : []
354
+ if (ids.length === 0) return { ok: false, text: 'ids 必填:目标 mes-rest 点位 id 数组(catalog 输出的 id;至少 1 个)。', isError: true }
355
+ const all = await d.nodes()
356
+ const bound = await d.boundNodeIds(agentId)
357
+ const mesById = new Map(all.filter(n => n.driver === MES_REST_DRIVER_KIND).map(n => [n.id, n]))
358
+ const picked: MesNodeLike[] = []
359
+ const missing: string[] = []
360
+ const notAllowed: string[] = []
361
+ for (const id of ids) {
362
+ const n = mesById.get(id)
363
+ if (!n) {
364
+ missing.push(id)
365
+ continue
366
+ }
367
+ if (!bound.has(id)) {
368
+ notAllowed.push(id)
369
+ continue
370
+ }
371
+ picked.push(n)
372
+ }
373
+ if (missing.length > 0 || notAllowed.length > 0) {
374
+ const allowed = [...bound]
375
+ .map(id => mesById.get(id))
376
+ .filter((n): n is MesNodeLike => !!n && n.driver === MES_REST_DRIVER_KIND)
377
+ const parts: string[] = []
378
+ if (missing.length > 0) parts.push(`不存在或不是 mes-rest 点位:${missing.join(', ')}`)
379
+ if (notAllowed.length > 0) parts.push(`无权访问(须为你绑定的数控节点):${notAllowed.join(', ')}`)
380
+ return {
381
+ ok: false,
382
+ text: `取数被拒:${parts.join(';')}。你有权取数的 mes-rest 点位:${allowed.map(n => `${n.name}(${n.id})`).join(', ') || '(无)'}。`,
383
+ isError: true,
384
+ }
385
+ }
386
+ return { ok: true, nodes: picked }
387
+ }
388
+
389
+ /** 时间窗/行数护栏归一(代码级;返回错误文本或归一值) */
390
+ function normalizeWindow(args: MesFetchArgs): { ok: true, from?: string, to?: string, maxRows: number } | { ok: false, text: string, isError?: true } {
391
+ const from = String(args.from ?? '').trim()
392
+ const to = String(args.to ?? '').trim()
393
+ if ((from && !to) || (!from && to)) {
394
+ return { ok: false, text: 'from/to 必须成对提供(历史取数),或都不传(当前值快照模式)。' }
395
+ }
396
+ if (from && to) {
397
+ const fromMs = Date.parse(from)
398
+ const toMs = Date.parse(to)
399
+ if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return { ok: false, text: 'from/to 必须是合法 ISO 时间戳。' }
400
+ if (fromMs >= toMs) return { ok: false, text: `时间窗无效:from(${from}) 必须早于 to(${to})。` }
401
+ if (toMs - fromMs > MES_WINDOW_MAX_MS) {
402
+ return { ok: false, text: `时间窗被拒:窗口 ${(toMs - fromMs) / 3_600_000 / 24} 天超过上限 7 天。请拆成 ≤7 天的分段分批取数。`, isError: true }
403
+ }
404
+ }
405
+ const maxRows = args.max_rows == null || args.max_rows === '' ? MES_DEFAULT_MAX_ROWS : Math.round(Number(args.max_rows))
406
+ if (!Number.isFinite(maxRows) || maxRows < 1) return { ok: false, text: 'max_rows 必须为 ≥1 的整数。' }
407
+ if (maxRows > MES_MAX_ROWS_CAP) {
408
+ return { ok: false, text: `max_rows=${maxRows} 被拒:单次取数上限 ${MES_MAX_ROWS_CAP} 行。请缩小时间窗或分批取数。`, isError: true }
409
+ }
410
+ return { ok: true, from: from || undefined, to: to || undefined, maxRows }
411
+ }
412
+
413
+ /** 统计摘要(数值列;均值/采样标准差) */
414
+ function statsOf(values: number[], firstTs: string | null, lastTs: string | null): MesDatasetStatsView {
415
+ const n = values.length
416
+ if (n === 0) return { count: 0, min: null, max: null, mean: null, stddev: null, firstTs: null, lastTs: null }
417
+ const min = Math.min(...values)
418
+ const max = Math.max(...values)
419
+ const mean = values.reduce((a, b) => a + b, 0) / n
420
+ const stddev = n > 1 ? Math.sqrt(values.reduce((a, b) => a + (b - mean) ** 2, 0) / (n - 1)) : 0
421
+ return { count: n, min, max, mean, stddev, firstTs, lastTs }
422
+ }
423
+
424
+ const fmtN = (v: number | null | undefined, digits = 3): string =>
425
+ v == null || !Number.isFinite(v) ? '-' : String(Number(v.toFixed(digits)))
426
+ const shortTs = (iso: string | null): string => iso && iso.length >= 19 ? iso.slice(5, 19).replace('T', ' ') : (iso ?? '-')
427
+ const clip = (v: unknown, max: number): string => {
428
+ const s = typeof v === 'string' ? v : JSON.stringify(v) ?? String(v)
429
+ return s.length > max ? `${s.slice(0, max)}…` : s
430
+ }
431
+
432
+ // -------- 格式感知取数(行形态全谱;内存硬顶防大payload 拖垮进程) --------
433
+
434
+ /** 泛化历史行缓冲的硬顶 */
435
+ const VECTOR_ELEMENT_CAP = 2_000_000
436
+ const IMAGE_BASE64_CAP = 16_000_000
437
+ const RECORD_JSON_CAP = 8_000_000
438
+ /** image 格式自动落盘帧数上限(其余帧不落盘,回包注明) */
439
+ const IMAGE_AUTOSAVE_MAX = 20
440
+
441
+ interface GenRow { ts: string, value?: number, values?: number[], data?: string, mime?: string, record?: unknown }
442
+
443
+ interface GenStats extends MesDatasetStatsView {
444
+ /** vector:维度(首行长度)与维度不齐行数 */
445
+ dim?: number
446
+ dimMismatch?: number
447
+ /** vector:全体元素均值(比行均值更细) */
448
+ elementMean?: number
449
+ }
450
+
451
+ /** requestHook 覆盖合并:克隆 driverConfig,把 {path,query,headers} 合入 historyMap JSON */
452
+ async function configWithRequestHook(node: MesNodeLike, param: unknown): Promise<Record<string, unknown>> {
453
+ const cfg = { ...(node.driverConfig as Record<string, unknown>) }
454
+ const hookCode = mesRequestHookCode(cfg as Record<string, unknown>)
455
+ if (!hookCode) return cfg
456
+ const overrides = await runMesRequestHook(hookCode, param, { nodeId: node.id })
457
+ if (overrides.path === undefined && overrides.query === undefined && overrides.headers === undefined) return cfg
458
+ try {
459
+ const map = JSON.parse(String(cfg.historyMap ?? '{}')) as Record<string, unknown>
460
+ if (overrides.path !== undefined) map.path = overrides.path
461
+ const baseQuery = (map.query !== null && typeof map.query === 'object' && !Array.isArray(map.query) ? map.query : {}) as Record<string, unknown>
462
+ map.query = { ...baseQuery, ...(overrides.query ?? {}) }
463
+ const baseHeaders = (map.headers !== null && typeof map.headers === 'object' && !Array.isArray(map.headers) ? map.headers : {}) as Record<string, unknown>
464
+ if (overrides.headers !== undefined) map.headers = { ...baseHeaders, ...overrides.headers }
465
+ cfg.historyMap = JSON.stringify(map)
466
+ }
467
+ catch (err) {
468
+ throw new AppError(422, 'MES_HOOK_FAILED', `requestHook 覆盖合并失败(historyMap 非法 JSON):${err instanceof Error ? err.message : String(err)}`)
469
+ }
470
+ return cfg
471
+ }
472
+
473
+ /** 向量行统计摘要(行均值序列 stats + 维度 + 全体元素均值) */
474
+ function vectorStats(rows: GenRow[]): GenStats {
475
+ const rowMeans = rows.map((r) => {
476
+ const vs = r.values ?? []
477
+ return vs.length > 0 ? vs.reduce((a, b) => a + b, 0) / vs.length : NaN
478
+ }).filter(v => Number.isFinite(v))
479
+ const all: number[] = []
480
+ for (const r of rows) if (Array.isArray(r.values)) all.push(...r.values)
481
+ const base = statsOf(rowMeans, rows[0]?.ts ?? null, rows[rows.length - 1]?.ts ?? null) as GenStats
482
+ base.dim = Array.isArray(rows[0]?.values) ? rows[0]!.values!.length : undefined
483
+ base.dimMismatch = base.dim === undefined ? undefined : rows.filter(r => Array.isArray(r.values) && r.values!.length !== base.dim).length
484
+ base.elementMean = all.length > 0 ? all.reduce((a, b) => a + b, 0) / all.length : undefined
485
+ return base
486
+ }
487
+
488
+ /** 同步取单节点历史(格式感知:统计+采样+图像落盘+dataHook 下沉处理;原文不回传) */
489
+ async function inlineFetchNode(node: MesNodeLike, from: string, to: string, maxRows: number, param: unknown, includeData = false): Promise<{
490
+ text: string
491
+ stats: MesDatasetStatsView
492
+ truncated: boolean
493
+ sample: string[]
494
+ hookText?: string
495
+ artifacts: MesHookArtifact[]
496
+ }> {
497
+ const cfg = node.driverConfig as Record<string, unknown>
498
+ const format = historyFormatOf(cfg)
499
+ const driver = d.resolveDriver(node.driver)
500
+ if (typeof driver.fetchHistory !== 'function') {
501
+ return { text: `驱动 ${node.driver} 未提供历史原语(fetchHistory)`, stats: statsOf([], null, null), truncated: true, sample: [], artifacts: [] }
502
+ }
503
+ const effCfg = await configWithRequestHook(node, param)
504
+ const buf: GenRow[] = []
505
+ let truncated = false
506
+ let vecElems = 0
507
+ let imgChars = 0
508
+ let recChars = 0
509
+ let memoryHit = ''
510
+ let dictionary: DcwFieldDef[]
511
+ const result = await driver.fetchHistory({
512
+ driverConfig: effCfg,
513
+ fromIso: from,
514
+ toIso: to,
515
+ maxRows,
516
+ onRows: (batch) => {
517
+ for (const r of batch ?? []) {
518
+ if (buf.length >= maxRows) {
519
+ truncated = true
520
+ break
521
+ }
522
+ const row: GenRow = { ts: String(r?.ts ?? '') }
523
+ if (typeof r?.value === 'number') row.value = r.value
524
+ if (Array.isArray(r?.values)) {
525
+ vecElems += r.values.length
526
+ if (vecElems > VECTOR_ELEMENT_CAP) {
527
+ memoryHit = `向量元素总量超过 ${VECTOR_ELEMENT_CAP} 上限`
528
+ truncated = true
529
+ break
530
+ }
531
+ row.values = r.values as number[]
532
+ }
533
+ if (typeof r?.data === 'string') {
534
+ imgChars += r.data.length
535
+ if (imgChars > IMAGE_BASE64_CAP) {
536
+ memoryHit = `图像载荷总量超过 ${Math.round(IMAGE_BASE64_CAP / 1024 / 1024)}MB 上限`
537
+ truncated = true
538
+ break
539
+ }
540
+ row.data = r.data
541
+ row.mime = typeof r?.mime === 'string' ? r.mime : 'image/png'
542
+ }
543
+ if (r?.record !== undefined && r.record !== null) {
544
+ let json: string
545
+ try {
546
+ json = JSON.stringify(r.record)
547
+ }
548
+ catch {
549
+ continue
550
+ }
551
+ recChars += json.length
552
+ if (recChars > RECORD_JSON_CAP) {
553
+ memoryHit = `记录载荷总量超过 ${Math.round(RECORD_JSON_CAP / 1024 / 1024)}MB 上限`
554
+ truncated = true
555
+ break
556
+ }
557
+ row.record = r.record
558
+ }
559
+ buf.push(row)
560
+ }
561
+ },
562
+ })
563
+ if (result?.dictionary && result.dictionary.length > 0) {
564
+ dictionary = result.dictionary
565
+ cacheDictionary(node.id, dictionary)
566
+ }
567
+ else {
568
+ dictionary = mesDictionaryOfNode(node.id, cfg)
569
+ }
570
+ if (result && result.complete === false) truncated = true
571
+ if (!truncated && memoryHit) truncated = true
572
+
573
+ // 统计与采样(按格式)
574
+ let stats: GenStats
575
+ let autosaved: MesHookArtifact[] = []
576
+ const sample: string[] = []
577
+ let tableFieldStats = ''
578
+ if (format === 'vector') {
579
+ stats = vectorStats(buf)
580
+ // 空窗口不得生成采样下标(否则 buf[0] undefined → 取数崩溃)
581
+ const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
582
+ const vecField = dictionary.find(f => f.kind === 'vector' || (f.points?.length ?? 0) > 0)
583
+ const pointLabel = (i: number): string => {
584
+ const p = vecField?.points?.[i]
585
+ return p?.label ?? p?.field ?? `v${i}`
586
+ }
587
+ for (const i of idx) {
588
+ const r = buf[i]!
589
+ const vs = r.values ?? []
590
+ const m = vs.length > 0 ? vs.reduce((a, b) => a + b, 0) / vs.length : NaN
591
+ const valuesTxt = includeData && vs.length > 0
592
+ ? `,values=[${vs.slice(0, 64).map((v, j) => `${pointLabel(j)}=${Number(v.toFixed(4))}`).join(',')}${vs.length > 64 ? ',…' : ''}]`
593
+ : ''
594
+ sample.push(`${shortTs(r.ts)},dim=${vs.length},mean=${fmtN(m)},min=${fmtN(vs.length ? Math.min(...vs) : NaN)},max=${fmtN(vs.length ? Math.max(...vs) : NaN)}${valuesTxt}`)
595
+ }
596
+ }
597
+ else if (format === 'image') {
598
+ stats = { count: buf.length, min: null, max: null, mean: null, stddev: null, firstTs: buf[0]?.ts ?? null, lastTs: buf[buf.length - 1]?.ts ?? null }
599
+ // 图像 base64 永不进 prompt:自动落盘(≤20 帧),采样给文件名
600
+ const saved: MesHookArtifact[] = []
601
+ for (const [i, r] of buf.entries()) {
602
+ if (typeof r.data !== 'string') continue
603
+ if (saved.length >= IMAGE_AUTOSAVE_MAX) break
604
+ const a = saveMesImageArtifact(node.id, `frame-${String(i).padStart(4, '0')}`, r.data, r.mime ?? 'image/png')
605
+ if (a) saved.push(a)
606
+ }
607
+ const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
608
+ for (const i of idx) {
609
+ const r = buf[i]!
610
+ const kb = r.data ? Math.round(r.data.length * 3 / 4 / 1024) : 0
611
+ const f = saved.find(x => x.name.includes(`frame-${String(i).padStart(4, '0')}`))
612
+ sample.push(`${shortTs(r.ts)},${r.mime ?? 'image/png'},~${kb}KB${f ? ` → ${f.name}` : ''}`)
613
+ }
614
+ autosaved = saved
615
+ }
616
+ else if (format === 'table' || format === 'event') {
617
+ stats = { count: buf.length, min: null, max: null, mean: null, stddev: null, firstTs: buf[0]?.ts ?? null, lastTs: buf[buf.length - 1]?.ts ?? null }
618
+ const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
619
+ for (const i of idx) {
620
+ const r = buf[i]!
621
+ let body: string
622
+ try {
623
+ body = JSON.stringify(r.record)
624
+ }
625
+ catch {
626
+ body = '(不可序列化)'
627
+ }
628
+ sample.push(`${shortTs(r.ts)},${clip(body ?? '', 120)}`)
629
+ }
630
+ // map/多参数行:逐数值字段统计(最多 12 个字段),让 Agent 不必只看 3 行采样
631
+ const cols = new Map<string, number[]>()
632
+ for (const r of buf) {
633
+ if (r.record === null || typeof r.record !== 'object' || Array.isArray(r.record)) continue
634
+ for (const [k, v] of Object.entries(r.record as Record<string, unknown>)) {
635
+ if (v === null || v === '' || typeof v === 'boolean') continue
636
+ const n = Number(v)
637
+ if (!Number.isFinite(n)) continue
638
+ const arr = cols.get(k) ?? []
639
+ arr.push(n)
640
+ cols.set(k, arr)
641
+ }
642
+ }
643
+ const fieldLines = [...cols.entries()].slice(0, 12).map(([k, vs]) => {
644
+ const mean = vs.reduce((a, b) => a + b, 0) / vs.length
645
+ const def = dictionary.find(f => f.field === k)
646
+ const label = def?.label ? `${def.label}(${k})` : k
647
+ const unit = def?.unit ? ` ${def.unit}` : ''
648
+ return `${label}: n=${vs.length} min=${fmtN(Math.min(...vs))} max=${fmtN(Math.max(...vs))} mean=${fmtN(mean)}${unit}`
649
+ })
650
+ if (fieldLines.length > 0) {
651
+ tableFieldStats = ` 数值字段统计(${cols.size} 个字段${cols.size > 12 ? ',显示前12' : ''}): ${fieldLines.join(' | ')}`
652
+ }
653
+ }
654
+ else {
655
+ const values = buf.map(r => r.value).filter((v): v is number => Number.isFinite(v))
656
+ stats = statsOf(values, buf[0]?.ts ?? null, buf[buf.length - 1]?.ts ?? null)
657
+ const idx = buf.length > 0 ? [...new Set([0, Math.floor((buf.length - 1) / 2), buf.length - 1])].slice(0, 3) : []
658
+ for (const i of idx) sample.push(`${shortTs(buf[i]!.ts)},${fmtN(buf[i]!.value ?? NaN)}${includeData ? ` (value=${buf[i]!.value ?? '-'})` : ''}`)
659
+ }
660
+
661
+ const fmtLabel = format === 'scalar' ? `标量` : format === 'vector' ? `向量(dim=${stats.dim ?? '?'})` : format === 'image' ? `图像(${(buf[0]?.mime as string) ?? 'image/png'})` : format === 'table' ? `表格记录` : `事件记录`
662
+ const statLine = format === 'scalar'
663
+ ? ` 统计:min ${fmtN(stats.min)} / max ${fmtN(stats.max)} / mean ${fmtN(stats.mean)} / stddev ${fmtN(stats.stddev)} ${node.unit}`
664
+ : format === 'vector'
665
+ ? ` 统计(按行均值):min ${fmtN(stats.min)} / max ${fmtN(stats.max)} / mean ${fmtN(stats.mean)} / stddev ${fmtN(stats.stddev)} ${node.unit};全体元素均值 ${fmtN(stats.elementMean ?? NaN)}${stats.dimMismatch ? `;维度漂移 ${stats.dimMismatch} 行` : ''}`
666
+ : ` 统计:${stats.count} 条记录(非数值格式不做均值)`
667
+ const dictText = formatDictionary(dictionary)
668
+ const text = [
669
+ `■ ${node.name}(id=${node.id})[格式 ${fmtLabel};节点单位 ${node.unit || '-'};量程 ${node.min}~${node.max}]`,
670
+ ` 行数 ${stats.count}${truncated ? `(截断:${memoryHit || '达到 maxRows 上限'})` : '(完整)'} | 首 ${shortTs(stats.firstTs)} ~ 末 ${shortTs(stats.lastTs)}`,
671
+ statLine,
672
+ sample.length > 0 ? ` 采样(≤3 行): ${sample.join(' | ')}` : ' 采样:无有效行',
673
+ ...(tableFieldStats ? [tableFieldStats] : []),
674
+ ...(dictText ? [dictText] : []),
675
+ ].join('\n')
676
+
677
+ // dataHook 下沉处理(用户配置的 (param, data, ctx) => {...})
678
+ let hookText: string | undefined
679
+ const artifacts: MesHookArtifact[] = [...(autosaved as MesHookArtifact[])]
680
+ const hookCode = mesDataHookCode(cfg)
681
+ if (hookCode) {
682
+ const hookData: MesHookData = {
683
+ node: { id: node.id, name: node.name, lineId: node.lineId, unit: node.unit },
684
+ format,
685
+ rows: buf,
686
+ window: { from, to },
687
+ }
688
+ try {
689
+ const outcome = await runMesDataHook(hookCode, param, hookData, { nodeId: node.id })
690
+ if (outcome.ok) {
691
+ artifacts.push(...outcome.artifacts)
692
+ const parts = [` 钩子(dataHook):已执行,产物 ${outcome.artifacts.length} 个`]
693
+ if (outcome.summary) parts.push(` 处理摘要: ${outcome.summary}`)
694
+ if (outcome.context) parts.push(` 处理说明: ${outcome.context}`)
695
+ if (outcome.logs.length > 0) parts.push(` hook 日志(≤3): ${outcome.logs.slice(0, 3).join(' / ')}`)
696
+ hookText = parts.join('\n')
697
+ }
698
+ else {
699
+ hookText = ` 钩子(dataHook)执行失败:${outcome.error ?? '未知原因'}(统计仍基于原始数据)`
700
+ }
701
+ }
702
+ catch (err) {
703
+ hookText = ` 钩子(dataHook)执行失败:${err instanceof Error ? err.message : String(err)}`
704
+ }
705
+ }
706
+
707
+ // 产物行(hook 之外含自动落盘图像)
708
+ if (artifacts.length > 0) {
709
+ const shown = artifacts.slice(0, 8).map(a => `${a.name}(${Math.max(1, Math.round(a.bytes / 1024))}KB)`)
710
+ hookText = `${hookText ?? ''}\n 产物(${artifacts.length}${artifacts.length > 8 ? ',显示前8' : ''}): ${shown.join(' | ')}`
711
+ }
712
+ return { text, stats, truncated, sample, hookText, artifacts }
713
+ }
714
+
715
+ /**
716
+ * 取数编排(护栏全代码级):
717
+ * 授权过滤 → 窗口/行数归一 → 频次限流 → 快照 / 内联 / 异步三模式。
718
+ */
719
+ async function fetch(agentId: string, args: MesFetchArgs): Promise<MesFetchOutcome> {
720
+ // ① 授权:ids 必须是调用者可见(绑线)的 mes-rest 节点
721
+ const vis = await resolveVisibleIds(agentId, args.ids)
722
+ if (!vis.ok) return { text: vis.text, isError: true }
723
+ // ② 窗口/行数护栏
724
+ const win = normalizeWindow(args)
725
+ if (!win.ok) return { text: win.text, isError: true }
726
+ // ③ 频次限流(每 agent 每 60s ≤6 次)
727
+ if (!mesFetchRateCheck(agentId, d.nowMs())) {
728
+ return { text: `取数过于频繁:每 60 秒最多 ${MES_RATE_MAX_CALLS} 次。请先消化已有结果,稍后再取。`, isError: true }
729
+ }
730
+ // ④ 格式门控:image/table/event 的原文(帧/记录)不进 prompt 也不落 CSV 数据集,
731
+ // 只支持内联行数(≤MES_SYNC_INLINE_MAX_ROWS);大窗口请拆小分批
732
+ if (win.maxRows > MES_SYNC_INLINE_MAX_ROWS) {
733
+ const INLINE_ONLY = new Set(['image', 'table', 'event'])
734
+ const hits = vis.nodes.filter(n => INLINE_ONLY.has(historyFormatOf(n.driverConfig as Record<string, unknown>)))
735
+ if (hits.length > 0) {
736
+ return {
737
+ text: `行数上限冲突:${hits.map(n => `${n.name}(${n.id})`).join(', ')} 是 图像/表格/事件 格式点位,只在 max_rows ≤ ${MES_SYNC_INLINE_MAX_ROWS} 的内联模式支持(原文不落 CSV 数据集)。请缩小时间窗或调低 max_rows 后重取。`,
738
+ isError: true,
739
+ }
740
+ }
741
+ }
742
+
743
+ // 模式一:当前值快照(无 from/to)
744
+ if (!win.from || !win.to) {
745
+ const lines: string[] = []
746
+ let failed = 0
747
+ for (const node of vis.nodes) {
748
+ const driver = d.resolveDriver(node.driver)
749
+ try {
750
+ if (typeof driver.read !== 'function') {
751
+ failed++
752
+ lines.push(`- ${node.name}(${node.id}):驱动 ${node.driver} 不支持读取`)
753
+ continue
754
+ }
755
+ const r = await driver.read({ domain: { min: node.min, max: node.max }, driverConfig: node.driverConfig })
756
+ const at = new Date(d.nowMs()).toISOString()
757
+ if (r.dictionary && r.dictionary.length > 0) cacheDictionary(node.id, r.dictionary)
758
+ const dict = r.dictionary && r.dictionary.length > 0 ? r.dictionary : mesDictionaryOfNode(node.id, node.driverConfig as Record<string, unknown>)
759
+ if (!(r.ok && r.eng != null)) failed++
760
+ lines.push(r.ok && r.eng != null
761
+ ? `- ${node.name}(${node.id}):${fmtN(r.eng)}${node.unit} @ ${shortTs(at)}${dict.length > 0 ? `\n${formatDictionary(dict, ' ')}` : ''}`
762
+ : `- ${node.name}(${node.id}):读取失败(${r.message.slice(0, 80)})`)
763
+ }
764
+ catch (err) {
765
+ failed++
766
+ lines.push(`- ${node.name}(${node.id}):读取异常(${(err instanceof Error ? err.message : String(err)).slice(0, 80)})`)
767
+ }
768
+ }
769
+ return {
770
+ mode: 'snapshot',
771
+ ...(failed === vis.nodes.length ? { isError: true } : {}),
772
+ text: `MES 当前值快照(${vis.nodes.length} 个点位,内联直读):\n${lines.join('\n')}\n\n说明:当前值为直读快照;历史窗口用 mes_fetch 带 from/to(≤7 天,max_rows≤${MES_MAX_ROWS_CAP})。`,
773
+ }
774
+ }
775
+
776
+ // 模式二:同步内联(行数 ≤ MES_SYNC_INLINE_MAX_ROWS;格式感知+dataHook 下沉)
777
+ if (win.maxRows <= MES_SYNC_INLINE_MAX_ROWS) {
778
+ const sections: string[] = []
779
+ const statsOut: NonNullable<MesFetchOutcome['data']>['stats'] = []
780
+ let failed = 0
781
+ for (const node of vis.nodes) {
782
+ try {
783
+ const one = await inlineFetchNode(node, win.from, win.to, win.maxRows, args.param, args.include_data === true || args.include_data === 'true')
784
+ sections.push(one.hookText ? `${one.text}\n${one.hookText}` : one.text)
785
+ statsOut.push({ nodeId: node.id, stats: one.stats, truncated: one.truncated })
786
+ }
787
+ catch (err) {
788
+ failed++
789
+ sections.push(`■ ${node.name}(id=${node.id})\n 取数失败:${err instanceof Error ? err.message : String(err)}`)
790
+ }
791
+ }
792
+ return {
793
+ mode: 'inline',
794
+ // 全部点位失败时如实置 isError(此前仅文本提示"取数失败",Agent 可能当成功继续)
795
+ ...(failed === vis.nodes.length ? { isError: true } : {}),
796
+ text: `MES 历史取数(内联同步,${vis.nodes.length} 个点位,窗口 ${shortTs(win.from)} ~ ${shortTs(win.to)}):\n${sections.join('\n')}\n\n说明:以上为统计摘要与 ≤3 行采样;MES 原文不进入对话。向量/图像/记录点位按各自格式呈现,已配置数据钩子(dataHook)的点位会附处理摘要与产物清单(文件落 <数据根>/mes-artifacts/<点位id>/)。需要标量/向量全量行请用更大 max_rows(> ${MES_SYNC_INLINE_MAX_ROWS})走异步数据集,再用 mes_dataset_read 读。`,
797
+ data: { stats: statsOut },
798
+ }
799
+ }
800
+
801
+ // 模式三:异步数据集(行数 > MES_SYNC_INLINE_MAX_ROWS;进程内异步,绝不进调度循环;
802
+ // requestHook 覆盖在此同样生效——合并进作业用的 driverConfig)
803
+ const jobIds: string[] = []
804
+ const datasetIds: string[] = []
805
+ const lines: string[] = []
806
+ for (const node of vis.nodes) {
807
+ let effCfg: Record<string, unknown>
808
+ try {
809
+ effCfg = await configWithRequestHook(node, args.param)
810
+ }
811
+ catch (err) {
812
+ lines.push(`- ${node.name}(${node.id}):requestHook 失败,作业未创建(${err instanceof Error ? err.message : String(err)})`)
813
+ continue
814
+ }
815
+ const run = node.lineId ? getActiveLineRun(node.lineId) : null
816
+ const { jobId, datasetId } = d.store.createFetchJob({
817
+ nodeId: node.id,
818
+ fromIso: win.from,
819
+ toIso: win.to,
820
+ maxRows: win.maxRows,
821
+ agentId,
822
+ lineId: node.lineId,
823
+ nodeName: node.name,
824
+ driverConfig: effCfg,
825
+ dictionary: mesDictionaryOfNode(node.id, node.driverConfig as Record<string, unknown>),
826
+ nodeMeta: {
827
+ unit: node.unit,
828
+ min: node.min,
829
+ max: node.max,
830
+ description: String(node.driverConfig.desc ?? ''),
831
+ semantics: String(node.driverConfig.semantics ?? ''),
832
+ format: historyFormatOf(node.driverConfig as Record<string, unknown>),
833
+ },
834
+ context: run
835
+ ? { lineId: run.lineId, productId: run.productId, recipeId: run.recipeId, runId: run.runId }
836
+ : { lineId: node.lineId },
837
+ })
838
+ jobIds.push(jobId)
839
+ datasetIds.push(datasetId)
840
+ lines.push(`- ${node.name}(${node.id}):job_id=${jobId} dataset_id=${datasetId} status=running`)
841
+ }
842
+ return {
843
+ mode: 'async',
844
+ text: `已创建 ${lines.length} 个异步取数作业(窗口 ${shortTs(win.from)} ~ ${shortTs(win.to)},max_rows=${win.maxRows}):\n${lines.join('\n')}\n\n勿轮询;未完成先做别的,用 mes_datasets 查状态,完成后 mes_dataset_read(dataset_id, mode=stats/rows) 读内容。`,
845
+ data: { job_ids: jobIds, dataset_ids: datasetIds },
846
+ }
847
+ }
848
+
849
+ // ---------- 离线导出(指定目录 + manifest/README 语义清单) ----------
850
+
851
+ /** 安全子路径:只允许落在 root 内(拒绝 ../、绝对路径逃逸、盘符切换) */
852
+ function resolveUnderRoot(root: string, folder: string, fallback: string): { ok: true, dir: string } | { ok: false, text: string } {
853
+ const base = resolve(root)
854
+ const raw = String(folder ?? '').trim()
855
+ if (!raw) return { ok: true, dir: join(base, fallback) }
856
+ const target = resolve(base, raw)
857
+ if (target !== base && !target.startsWith(`${base}${sep}`)) {
858
+ return {
859
+ ok: false,
860
+ text: `导出目录被拒:folder=${raw} 越出允许根目录 ${base}(只接受相对路径;如需自定义根目录,请由管理员设置环境变量 AW_MES_EXPORT_ROOT)。`,
861
+ }
862
+ }
863
+ return { ok: true, dir: target }
864
+ }
865
+
866
+ function safeSeg(value: string): string {
867
+ return value.replace(/[^A-Za-z0-9._-]/g, '_').slice(0, 80) || 'node'
868
+ }
869
+
870
+ function writeChunk(fd: number, text: string): void {
871
+ const buf = Buffer.from(text, 'utf8')
872
+ let off = 0
873
+ while (off < buf.length) off += writeSync(fd, buf, off, buf.length - off)
874
+ }
875
+
876
+ /**
877
+ * 把可见 MES 点位的历史原样导出到目录(流式写盘):
878
+ * scalar → data.csv(ts,value)
879
+ * vector → data.csv(宽表 ts,v0..vN)+ manifest 里的逐点语义
880
+ * image → frames.jsonl(元数据)+ frames/*.png
881
+ * table/event → records.jsonl
882
+ * 每个导出目录都写 manifest.json + README.md(字段含义/单位/量程/产线批次上下文),
883
+ * Agent 与离线分析器都能直接读懂,不需要回读平台。
884
+ */
885
+ async function exportData(agentId: string, args: MesExportArgs): Promise<MesToolResult & { dir?: string, manifestPath?: string, rows?: number }> {
886
+ const vis = await resolveVisibleIds(agentId, args.ids)
887
+ if (!vis.ok) return { text: vis.text, isError: true }
888
+ const from = String(args.from ?? '').trim()
889
+ const to = String(args.to ?? '').trim()
890
+ if (!from || !to) return { text: 'mes_export 需要 from/to(ISO)历史窗口;当前值快照请用 mes_fetch。', isError: true }
891
+ const fromMs = Date.parse(from)
892
+ const toMs = Date.parse(to)
893
+ if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return { text: 'from/to 必须是合法 ISO 时间戳。', isError: true }
894
+ if (fromMs >= toMs) return { text: `时间窗无效:from(${from}) 必须早于 to(${to})。`, isError: true }
895
+ if (toMs - fromMs > MES_WINDOW_MAX_MS) {
896
+ return { text: `时间窗被拒:超过 7 天上限。请拆成 ≤7 天的分段导出。`, isError: true }
897
+ }
898
+ const rawMax = args.max_rows == null || args.max_rows === '' ? MES_MAX_ROWS_CAP : Math.round(Number(args.max_rows))
899
+ if (!Number.isFinite(rawMax) || rawMax < 1) return { text: 'max_rows 必须为 ≥1 的整数。', isError: true }
900
+ const maxRows = Math.min(rawMax, MES_EXPORT_MAX_ROWS)
901
+ if (!mesFetchRateCheck(agentId, d.nowMs())) {
902
+ return { text: `导出过于频繁:每 60 秒最多 ${MES_RATE_MAX_CALLS} 次。请稍后再试。`, isError: true }
903
+ }
904
+
905
+ const root = process.env.AW_MES_EXPORT_ROOT
906
+ ? resolve(process.env.AW_MES_EXPORT_ROOT)
907
+ : join(ensureDataDir(), 'mes-exports')
908
+ const exportId = `mesexp-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}-${randomUUID().slice(0, 6)}`
909
+ const where = resolveUnderRoot(root, String(args.folder ?? ''), exportId)
910
+ if (!where.ok) return { text: where.text, isError: true }
911
+ const dir = where.dir
912
+ mkdirSync(dir, { recursive: true })
913
+
914
+ const title = String(args.title ?? '').trim() || `MES 数据导出 ${exportId}`
915
+ const note = String(args.note ?? '').trim()
916
+ const manifestNodes: Array<Record<string, unknown>> = []
917
+ const failures: string[] = []
918
+ const scalarFiles: Array<{ nodeName: string, nodeId: string, file: string }> = []
919
+ let totalRows = 0
920
+
921
+ for (const node of vis.nodes) {
922
+ const cfg = node.driverConfig as Record<string, unknown>
923
+ const format = historyFormatOf(cfg)
924
+ const nodeDir = join(dir, safeSeg(node.id))
925
+ try {
926
+ mkdirSync(nodeDir, { recursive: true })
927
+ const driver = d.resolveDriver(node.driver)
928
+ if (typeof driver.fetchHistory !== 'function') {
929
+ failures.push(`${node.name}(${node.id}):驱动 ${node.driver} 无历史原语`)
930
+ continue
931
+ }
932
+ const effCfg = await configWithRequestHook(node, args.param)
933
+ const run = node.lineId ? getActiveLineRun(node.lineId) : null
934
+ let dictionary = mesDictionaryOfNode(node.id, cfg)
935
+ let rows = 0
936
+ let truncated = false
937
+ let dim = 0
938
+ let dimDrift = 0
939
+ let skipped = 0
940
+ let frameSaved = 0
941
+ let frameSkipped = 0
942
+ let fd: number | null = null
943
+ let headerWritten = false
944
+ let columns: string[] = []
945
+ let fileRel = ''
946
+ const jsonl: string[] = []
947
+
948
+ if (format === 'image') {
949
+ mkdirSync(join(nodeDir, 'frames'), { recursive: true })
950
+ }
951
+ else {
952
+ fd = openSync(join(nodeDir, format === 'table' || format === 'event' ? 'records.jsonl' : 'data.csv'), 'w')
953
+ }
954
+
955
+ const result = await driver.fetchHistory({
956
+ driverConfig: effCfg,
957
+ fromIso: from,
958
+ toIso: to,
959
+ maxRows,
960
+ onRows: (batch) => {
961
+ if (!Array.isArray(batch)) return
962
+ for (const r of batch) {
963
+ if (rows >= maxRows) {
964
+ truncated = true
965
+ break
966
+ }
967
+ const ts = String(r?.ts ?? '')
968
+ if (format === 'vector') {
969
+ if (!Array.isArray(r?.values) || r.values.length === 0) {
970
+ skipped++
971
+ continue
972
+ }
973
+ if (!headerWritten) {
974
+ dim = r.values.length
975
+ columns = ['ts', ...Array.from({ length: dim }, (_, i) => `v${i}`)]
976
+ writeChunk(fd!, `${columns.join(',')}\r\n`)
977
+ headerWritten = true
978
+ }
979
+ if (r.values.length !== dim) dimDrift++
980
+ const cells = [ts]
981
+ for (let i = 0; i < dim; i++) {
982
+ const v = r.values[i]
983
+ cells.push(Number.isFinite(v) ? String(v) : '')
984
+ }
985
+ writeChunk(fd!, `${cells.join(',')}\r\n`)
986
+ rows++
987
+ continue
988
+ }
989
+ if (format === 'image') {
990
+ if (typeof r?.data !== 'string' || r.data.trim() === '') {
991
+ skipped++
992
+ continue
993
+ }
994
+ if (frameSaved >= MES_EXPORT_MAX_FRAMES) {
995
+ frameSkipped++
996
+ truncated = true
997
+ continue
998
+ }
999
+ const mime = typeof r.mime === 'string' && r.mime.includes('/') ? r.mime : 'image/png'
1000
+ const ext = mime.includes('jpeg') ? 'jpg' : mime.includes('webp') ? 'webp' : 'png'
1001
+ const name = `frames/${String(frameSaved).padStart(5, '0')}-${ts.replace(/[:.]/g, '-')}.${ext}`
1002
+ try {
1003
+ writeFileSync(join(nodeDir, name), Buffer.from(r.data, 'base64'))
1004
+ jsonl.push(JSON.stringify({ ts, mime, file: name, ...(r.record !== null && typeof r.record === 'object' ? { record: r.record } : {}) }))
1005
+ frameSaved++
1006
+ rows++
1007
+ }
1008
+ catch (imgErr) {
1009
+ skipped++
1010
+ jsonl.push(JSON.stringify({ ts, mime, error: imgErr instanceof Error ? imgErr.message : String(imgErr) }))
1011
+ }
1012
+ continue
1013
+ }
1014
+ if (format === 'table' || format === 'event') {
1015
+ if (r?.record === null || r?.record === undefined) {
1016
+ skipped++
1017
+ continue
1018
+ }
1019
+ jsonl.push(JSON.stringify({ ts, record: r.record }))
1020
+ rows++
1021
+ continue
1022
+ }
1023
+ if (typeof r?.value !== 'number' || !Number.isFinite(r.value)) {
1024
+ skipped++
1025
+ continue
1026
+ }
1027
+ if (!headerWritten) {
1028
+ columns = ['ts', 'value']
1029
+ writeChunk(fd!, `${columns.join(',')}\r\n`)
1030
+ headerWritten = true
1031
+ }
1032
+ writeChunk(fd!, `${ts},${r.value}\r\n`)
1033
+ rows++
1034
+ }
1035
+ },
1036
+ })
1037
+ if (result?.dictionary && result.dictionary.length > 0) {
1038
+ dictionary = result.dictionary
1039
+ cacheDictionary(node.id, dictionary)
1040
+ }
1041
+ if (result && result.complete === false) truncated = true
1042
+ if (format === 'image' || format === 'table' || format === 'event') {
1043
+ writeFileSync(join(nodeDir, 'records.jsonl'), `${jsonl.join('\n')}${jsonl.length > 0 ? '\n' : ''}`, 'utf8')
1044
+ fileRel = `${safeSeg(node.id)}/records.jsonl`
1045
+ }
1046
+ else {
1047
+ if (!headerWritten) {
1048
+ columns = format === 'vector' ? ['ts'] : ['ts', 'value']
1049
+ writeChunk(fd!, `${columns.join(',')}\r\n`)
1050
+ headerWritten = true
1051
+ }
1052
+ fileRel = `${safeSeg(node.id)}/data.csv`
1053
+ }
1054
+ if (fd != null) {
1055
+ closeSync(fd)
1056
+ fd = null
1057
+ }
1058
+ if (format === 'scalar') scalarFiles.push({ nodeName: node.name, nodeId: node.id, file: fileRel })
1059
+ totalRows += rows
1060
+ manifestNodes.push({
1061
+ id: node.id,
1062
+ name: node.name,
1063
+ line_id: node.lineId,
1064
+ format,
1065
+ unit: node.unit,
1066
+ range: { min: node.min, max: node.max },
1067
+ description: String(cfg.desc ?? ''),
1068
+ semantics: String(cfg.semantics ?? ''),
1069
+ file: fileRel,
1070
+ columns,
1071
+ rows,
1072
+ ...(format === 'vector' ? { vector: { dim, dimension_drift_rows: dimDrift } } : {}),
1073
+ ...(format === 'image' ? { frames: { saved: frameSaved, skipped: frameSkipped } } : {}),
1074
+ skipped_rows: skipped,
1075
+ truncated,
1076
+ fields: dictionary,
1077
+ context: run ? { line_id: run.lineId, product_id: run.productId, recipe_id: run.recipeId, run_id: run.runId } : { line_id: node.lineId },
1078
+ })
1079
+ }
1080
+ catch (err) {
1081
+ failures.push(`${node.name}(${node.id}):${err instanceof Error ? err.message : String(err)}`)
1082
+ }
1083
+ }
1084
+
1085
+ // 多标量节点按时间对齐的宽表(默认生成;纯时间戳交集,不做插值)
1086
+ let mergedFile: string | null = null
1087
+ const mergeEnabled = !(args.merge === false || args.merge === 'false')
1088
+ if (mergeEnabled && scalarFiles.length > 1) {
1089
+ try {
1090
+ const series = scalarFiles.map((s) => {
1091
+ const map = new Map<string, number>()
1092
+ const raw = readFileSync(join(dir, s.file), 'utf8')
1093
+ for (const line of raw.split(/\r?\n/).slice(1)) {
1094
+ const [ts, v] = line.split(',')
1095
+ if (ts && v !== undefined && Number.isFinite(Number(v))) map.set(ts, Number(v))
1096
+ }
1097
+ return { ...s, map }
1098
+ })
1099
+ const times = [...new Set(series.flatMap(s => [...s.map.keys()]))].sort()
1100
+ const header = ['time', ...series.map(s => `${s.nodeName}(${s.nodeId})`)]
1101
+ const lines = [header.join(',')]
1102
+ for (const ts of times) lines.push([ts, ...series.map(s => s.map.get(ts) ?? '')].join(','))
1103
+ writeFileSync(join(dir, 'merged.csv'), `${lines.join('\n')}\n`, 'utf8')
1104
+ mergedFile = join(dir, 'merged.csv')
1105
+ }
1106
+ catch { /* merge 失败不影响单节点导出 */ }
1107
+ }
1108
+
1109
+ const manifest = {
1110
+ schema: 'aw.mes-export/1',
1111
+ export_id: exportId,
1112
+ created_at: new Date().toISOString(),
1113
+ title,
1114
+ note,
1115
+ window: { from, to, from_ms: fromMs, to_ms: toMs },
1116
+ directory: dir,
1117
+ nodes: manifestNodes,
1118
+ merged_file: mergedFile,
1119
+ totals: { nodes: manifestNodes.length, rows: totalRows, failed_nodes: failures.length },
1120
+ usage: 'data.csv 首行为列名(ts=时间,v0..vN=向量点位);records.jsonl 每行一条记录;image 格式的像素在 frames/ 下,records.jsonl 是对应元数据。字段含义/单位/量程见 nodes[].fields(向量逐点语义在 fields[].points);批次归属见 nodes[].context。',
1121
+ }
1122
+ const manifestPath = join(dir, 'manifest.json')
1123
+ writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8')
1124
+
1125
+ const readme: string[] = [
1126
+ `# ${title}`,
1127
+ '',
1128
+ `- 导出时间: ${new Date().toISOString()}`,
1129
+ `- 时间窗: ${from} ~ ${to}`,
1130
+ `- 导出目录: ${dir}`,
1131
+ `- 说明: ${note || '(无)'}`,
1132
+ '',
1133
+ '## 文件与字段',
1134
+ '',
1135
+ ]
1136
+ for (const n of manifestNodes) {
1137
+ readme.push(`### ${String(n.name)} (${String(n.id)})`)
1138
+ readme.push(`- 格式: ${String(n.format)};文件: ${String(n.file)};行数: ${String(n.rows)}`)
1139
+ readme.push(`- 单位: ${String(n.unit || '-')};量程: ${JSON.stringify(n.range)}`)
1140
+ if (n.semantics) readme.push(`- 物理意义: ${String(n.semantics)}`)
1141
+ const fields = Array.isArray(n.fields) ? n.fields as DcwFieldDef[] : []
1142
+ const dict = formatDictionary(fields, ' ')
1143
+ if (dict) readme.push(dict)
1144
+ readme.push('')
1145
+ }
1146
+ if (mergedFile) readme.push(`多参数对齐宽表: ${mergedFile}(列名=节点名(节点id);仅对齐相同时间戳,不插值)`, '')
1147
+ if (failures.length > 0) readme.push('## 失败节点', '', ...failures.map(f => `- ${f}`), '')
1148
+ writeFileSync(join(dir, 'README.md'), `${readme.join('\n')}\n`, 'utf8')
1149
+
1150
+ const lines = manifestNodes.map(n => `- ${String(n.name)}(${String(n.id)}) [${String(n.format)}] ${String(n.rows)} 行 → ${String(n.file)}`)
1151
+ const failText = failures.length > 0 ? `\n失败节点(${failures.length}):\n${failures.map(f => ` - ${f}`).join('\n')}` : ''
1152
+ return {
1153
+ isError: failures.length > 0,
1154
+ dir,
1155
+ manifestPath,
1156
+ rows: totalRows,
1157
+ text: `MES 数据已导出(${manifestNodes.length}/${vis.nodes.length} 个点位,共 ${totalRows} 行):\n${lines.join('\n')}${mergedFile ? `\n- 多参数宽表: ${mergedFile}` : ''}${failText}\n\n目录: ${dir}\n语义清单: ${manifestPath}\n说明: README.md\n\n离线分析请直接读取上述文件;在线继续取数用 mes_fetch/mes_dataset_read。`,
1158
+ }
1159
+ }
1160
+
1161
+ return { catalog, fetch, exportData }
1162
+ }
1163
+
1164
+ export type MesController = ReturnType<typeof createMesController>