agentworkshop 0.7.49 → 0.7.50

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 (883) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +409 -6
  2. package/.output/.AgentWorkShop/aml-python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  3. package/.output/.AgentWorkShop/aml-python/__pycache__/amlkit.cpython-312.pyc +0 -0
  4. package/.output/.AgentWorkShop/aml-python/__pycache__/train-example.cpython-312.pyc +0 -0
  5. package/.output/.AgentWorkShop/aml-python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  6. package/.output/.AgentWorkShop/aml-python/aml_eval.py +39 -6
  7. package/.output/.AgentWorkShop/aml-python/amlkit.py +222 -3
  8. package/.output/.AgentWorkShop/aml-python/train-hybrid-example.py +278 -32
  9. package/.output/.AgentWorkShop/prompts/host-tools.json +409 -6
  10. package/.output/.AgentWorkShop/schema.json +135 -133
  11. package/.output/nitro.json +1 -1
  12. package/.output/public/_nuxt/2_DkYoqD2.js +1 -0
  13. package/.output/public/_nuxt/8FXd9As6.js +1 -0
  14. package/.output/public/_nuxt/{d-w5jR8R.js → B3zB6K6m.js} +1 -1
  15. package/.output/public/_nuxt/{OXtV_ukR.js → B4ujjkUI.js} +1 -1
  16. package/.output/public/_nuxt/B9BmiUil.js +2 -0
  17. package/.output/public/_nuxt/B9QzrmgE.js +1 -0
  18. package/.output/public/_nuxt/BE7BrEw6.js +1 -0
  19. package/.output/public/_nuxt/{Cu8c3oMN2.js → BFZIll912.js} +1 -1
  20. package/.output/public/_nuxt/{ChtjzEpK2.js → BGAaKBeo2.js} +1 -1
  21. package/.output/public/_nuxt/BOmDHp5L.js +14 -0
  22. package/.output/public/_nuxt/BPou3U7b.js +1 -0
  23. package/.output/public/_nuxt/{CiTQY_n32.js → BXx9AxdF2.js} +1 -1
  24. package/.output/public/_nuxt/Bfe2qOYs.js +1 -0
  25. package/.output/public/_nuxt/BgEDwFMf.js +1 -0
  26. package/.output/public/_nuxt/BgnhB8r5.js +1 -0
  27. package/.output/public/_nuxt/Bhe953zV2.js +1 -0
  28. package/.output/public/_nuxt/{BITZvQBK.js → Bpkm4W5P.js} +1 -1
  29. package/.output/public/_nuxt/C4lagVdN2.js +1 -0
  30. package/.output/public/_nuxt/C5cf3T4d.js +1 -0
  31. package/.output/public/_nuxt/CBIoheY42.js +1 -0
  32. package/.output/public/_nuxt/{CN1CDAwe.js → CFQSjB1h.js} +1 -1
  33. package/.output/public/_nuxt/CFQyYMEn2.js +1 -0
  34. package/.output/public/_nuxt/CHrErv1E.js +1 -0
  35. package/.output/public/_nuxt/{fxWyOzyp2.js → CI2yXRr42.js} +1 -1
  36. package/.output/public/_nuxt/CIduggmC.js +1 -0
  37. package/.output/public/_nuxt/CU-mhG0-.js +1 -0
  38. package/.output/public/_nuxt/CXzfXC5M.js +1 -0
  39. package/.output/public/_nuxt/{H6pPjo0l.js → C_sjV3Ee.js} +1 -1
  40. package/.output/public/_nuxt/Ccps4cxo.js +1 -0
  41. package/.output/public/_nuxt/{CPmNRTBk2.js → CdIsmU5a2.js} +10 -10
  42. package/.output/public/_nuxt/{BS9P_Ies2.js → ChGuLxwW2.js} +1 -1
  43. package/.output/public/_nuxt/{Ck5oMvUk.js → Cn6ihm8j.js} +1 -1
  44. package/.output/public/_nuxt/{CWzp2R6G.js → D-Xyb3DA.js} +1 -1
  45. package/.output/public/_nuxt/D0SNhlnt.js +1 -0
  46. package/.output/public/_nuxt/D0ldVwl-.js +1 -0
  47. package/.output/public/_nuxt/DClNt1uS.js +1 -0
  48. package/.output/public/_nuxt/{CTVfcnjU.js → DQMbdg4t.js} +2 -2
  49. package/.output/public/_nuxt/{DHSDk8Bq2.js → DTxfFIvL2.js} +1 -1
  50. package/.output/public/_nuxt/DVKXGuMz2.js +1 -0
  51. package/.output/public/_nuxt/{CLySL7mW.js → Da0h_6VA.js} +1 -1
  52. package/.output/public/_nuxt/{PixDfCSm.js → DefDtlKK.js} +1 -1
  53. package/.output/public/_nuxt/DjefmmJu.js +1 -0
  54. package/.output/public/_nuxt/DnH9SRMW2.js +1 -0
  55. package/.output/public/_nuxt/{BmiMC_BC.js → DppqsiPC.js} +1 -1
  56. package/.output/public/_nuxt/Drq9iy6V.js +1 -0
  57. package/.output/public/_nuxt/DsGf2IV82.js +1 -0
  58. package/.output/public/_nuxt/{DoKpLEqc.js → DzfVS8N72.js} +1 -1
  59. package/.output/public/_nuxt/{DRpFsrno.js → I1cI6sPJ2.js} +1 -1
  60. package/.output/public/_nuxt/IU-UGkCJ2.js +1 -0
  61. package/.output/public/_nuxt/KXjvpIk2.js +1 -0
  62. package/.output/public/_nuxt/NJn94js_.js +1 -0
  63. package/.output/public/_nuxt/ON2x-t6n.js +1 -0
  64. package/.output/public/_nuxt/S799kNo8.js +1 -0
  65. package/.output/public/_nuxt/{uI9Ki_XZ.js → S9rLP7_v.js} +1 -1
  66. package/.output/public/_nuxt/UN3nSFjj2.js +1 -0
  67. package/.output/public/_nuxt/WVTVkqef.js +1 -0
  68. package/.output/public/_nuxt/{C_VAXV7I2.js → Yv9YItEX2.js} +1 -1
  69. package/.output/public/_nuxt/_id_.DamiFT0Q.css +1 -0
  70. package/.output/public/_nuxt/{_id_.BTrFUIHX.css → _id_.DpRe1PRh.css} +1 -1
  71. package/.output/public/_nuxt/_wsId_.DkrQkT6r.css +1 -0
  72. package/.output/public/_nuxt/aml.-czpKIs8.css +1 -0
  73. package/.output/public/_nuxt/asmJ99nX2.js +47 -0
  74. package/.output/public/_nuxt/builds/latest.json +1 -1
  75. package/.output/public/_nuxt/builds/meta/08ba670b-7512-426b-a0ae-b10cbeb1c985.json +1 -0
  76. package/.output/public/_nuxt/{default.uao9U50c.css → default.CXb_zoN6.css} +1 -1
  77. package/.output/public/_nuxt/{entry.6DEjPWvR.css → entry.JdEG3KJg.css} +1 -1
  78. package/.output/public/_nuxt/jRTz0hjN2.js +1 -0
  79. package/.output/public/_nuxt/{DLPuRMeG.js → k5K6Jj6g.js} +1 -1
  80. package/.output/public/_nuxt/operations.B8X9uWK6.css +1 -0
  81. package/.output/public/_nuxt/{settings.Bo5EYkLI.css → settings.O26Dw1iT.css} +1 -1
  82. package/.output/public/_nuxt/{BACBBVdw.js → tKxYgsf-.js} +1 -1
  83. package/.output/public/_nuxt/{Cm_PTn9t2.js → vXrNItas2.js} +1 -1
  84. package/.output/public/_nuxt/{Cr518Gh02.js → zsRclU9w2.js} +1 -1
  85. package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
  86. package/.output/server/chunks/_/SearchOutlined.mjs +1 -1
  87. package/.output/server/chunks/_/binding-authz.mjs +1 -1
  88. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  89. package/.output/server/chunks/_/entity.mjs +1 -1
  90. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  91. package/.output/server/chunks/_/nitro.mjs +26134 -21024
  92. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  93. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  94. package/.output/server/chunks/build/Checkbox-4EdGAAl_.mjs +1 -1
  95. package/.output/server/chunks/build/FormItemContext-4ORSzhWv.mjs +1 -1
  96. package/.output/server/chunks/build/{OmpTerminalPanel-EQHrOJbw.mjs → OmpTerminalPanel-mk31gVzA.mjs} +3 -3
  97. package/.output/server/chunks/build/{OmpTerminalPanel-EQHrOJbw.mjs.map → OmpTerminalPanel-mk31gVzA.mjs.map} +1 -1
  98. package/.output/server/chunks/build/{PluginSlot-BP_qedpQ.mjs → PluginSlot-D2WUZgbp.mjs} +2 -2
  99. package/.output/server/chunks/build/{PluginSlot-BP_qedpQ.mjs.map → PluginSlot-D2WUZgbp.mjs.map} +1 -1
  100. package/.output/server/chunks/build/{TownView-BAR8CPIZ.mjs → TownView-fP9BiALv.mjs} +6 -6
  101. package/.output/server/chunks/build/{TownView-BAR8CPIZ.mjs.map → TownView-fP9BiALv.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{_id_-DgMpjM3_.mjs → _id_-BUpQSlzo.mjs} +142 -106
  103. package/.output/server/chunks/build/_id_-BUpQSlzo.mjs.map +1 -0
  104. package/.output/server/chunks/build/{_id_-Dv3BQbYV.mjs → _id_-CDlur81q.mjs} +25 -24
  105. package/.output/server/chunks/build/_id_-CDlur81q.mjs.map +1 -0
  106. package/.output/server/chunks/build/{_wsId_-BKJvFmyf.mjs → _wsId_-DPy2BXRd.mjs} +547 -158
  107. package/.output/server/chunks/build/_wsId_-DPy2BXRd.mjs.map +1 -0
  108. package/.output/server/chunks/build/{agents-B2GLPmn2.mjs → agents-CDLcboCv.mjs} +12 -12
  109. package/.output/server/chunks/build/{agents-B2GLPmn2.mjs.map → agents-CDLcboCv.mjs.map} +1 -1
  110. package/.output/server/chunks/build/{aml-DdWicH3t.mjs → aml-DsgtDLWF.mjs} +28 -27
  111. package/.output/server/chunks/build/aml-DsgtDLWF.mjs.map +1 -0
  112. package/.output/server/chunks/build/api-BY6ji7RC.mjs +6 -6
  113. package/.output/server/chunks/build/card-CUSocE9p.mjs +1 -1
  114. package/.output/server/chunks/build/{channel-templates-RPOtkgRf.mjs → channel-templates-DjEsj0_v.mjs} +8 -8
  115. package/.output/server/chunks/build/{channel-templates-RPOtkgRf.mjs.map → channel-templates-DjEsj0_v.mjs.map} +1 -1
  116. package/.output/server/chunks/build/checkbox-C4AKj81e.mjs +1 -1
  117. package/.output/server/chunks/build/constants-HPHJvjne.mjs +6 -6
  118. package/.output/server/chunks/build/{daq-CPtsh0e7.mjs → daq-N69AOtgw.mjs} +12 -11
  119. package/.output/server/chunks/build/daq-N69AOtgw.mjs.map +1 -0
  120. package/.output/server/chunks/build/{dcw-ry5Gyw6Y.mjs → dcw-CN9d3Rs7.mjs} +10 -10
  121. package/.output/server/chunks/build/{dcw-ry5Gyw6Y.mjs.map → dcw-CN9d3Rs7.mjs.map} +1 -1
  122. package/.output/server/chunks/build/{default-DxOE1eB0.mjs → default-DCf9tn1i.mjs} +38 -30
  123. package/.output/server/chunks/build/{default-DxOE1eB0.mjs.map → default-DCf9tn1i.mjs.map} +1 -1
  124. package/.output/server/chunks/build/descriptions-CFaUq4y4.mjs +1 -1
  125. package/.output/server/chunks/build/drawer-Cfh9_zft.mjs +1 -1
  126. package/.output/server/chunks/build/dropdown-KdKWCS5K.mjs +1 -1
  127. package/.output/server/chunks/build/form-uSlNqIAV.mjs +1 -1
  128. package/.output/server/chunks/build/input-Cr_KFj4T.mjs +1 -1
  129. package/.output/server/chunks/build/input-number-BRVnxeiA.mjs +1 -1
  130. package/.output/server/chunks/build/{logs-CeaiO3y9.mjs → logs-BcAjU1Ps.mjs} +12 -11
  131. package/.output/server/chunks/build/logs-BcAjU1Ps.mjs.map +1 -0
  132. package/.output/server/chunks/build/menu-BgkRSSx7.mjs +1 -1
  133. package/.output/server/chunks/build/{monitor-DnuXEIi5.mjs → monitor-DX_K0WMq.mjs} +13 -13
  134. package/.output/server/chunks/build/{monitor-DnuXEIi5.mjs.map → monitor-DX_K0WMq.mjs.map} +1 -1
  135. package/.output/server/chunks/build/operations-OFHYXwh4.mjs +282 -0
  136. package/.output/server/chunks/build/operations-OFHYXwh4.mjs.map +1 -0
  137. package/.output/server/chunks/build/{pages-Bn90ijKD.mjs → pages-rZKH72eC.mjs} +10 -11
  138. package/.output/server/chunks/build/pages-rZKH72eC.mjs.map +1 -0
  139. package/.output/server/chunks/build/{permissions-DL70W1YD.mjs → permissions-BvmodvsO.mjs} +8 -8
  140. package/.output/server/chunks/build/{permissions-DL70W1YD.mjs.map → permissions-BvmodvsO.mjs.map} +1 -1
  141. package/.output/server/chunks/build/{plugins-DrsZo--K.mjs → plugins-DSka7-vS.mjs} +9 -9
  142. package/.output/server/chunks/build/{plugins-DrsZo--K.mjs.map → plugins-DSka7-vS.mjs.map} +1 -1
  143. package/.output/server/chunks/build/popconfirm-Ox-_2V8A.mjs +1 -1
  144. package/.output/server/chunks/build/{schedules-VLzNcjnW.mjs → schedules-lo4bfgVt.mjs} +8 -8
  145. package/.output/server/chunks/build/{schedules-VLzNcjnW.mjs.map → schedules-lo4bfgVt.mjs.map} +1 -1
  146. package/.output/server/chunks/build/segmented-C61yLHvo.mjs +1 -1
  147. package/.output/server/chunks/build/select-rdBWytVK.mjs +1 -1
  148. package/.output/server/chunks/build/{settings-DVAUVMsX.mjs → settings-CAJWvul5.mjs} +32 -13
  149. package/.output/server/chunks/build/settings-CAJWvul5.mjs.map +1 -0
  150. package/.output/server/chunks/build/space-B2uhHJG8.mjs +1 -1
  151. package/.output/server/chunks/build/spin-C2cuvGth.mjs +1 -1
  152. package/.output/server/chunks/build/switch-DZAUIbIN.mjs +1 -1
  153. package/.output/server/chunks/build/table-DOFAvY-v.mjs +1 -1
  154. package/.output/server/chunks/build/tabs-DTeIuZeP.mjs +1 -1
  155. package/.output/server/chunks/build/tag-CHLGvNM6.mjs +1 -1
  156. package/.output/server/chunks/build/{teams-Mc07PYO8.mjs → teams-DBBvIToa.mjs} +14 -14
  157. package/.output/server/chunks/build/{teams-Mc07PYO8.mjs.map → teams-DBBvIToa.mjs.map} +1 -1
  158. package/.output/server/chunks/build/{tokens-DiwD5qni.mjs → tokens-CloWk4x_.mjs} +12 -12
  159. package/.output/server/chunks/build/{tokens-DiwD5qni.mjs.map → tokens-CloWk4x_.mjs.map} +1 -1
  160. package/.output/server/chunks/build/{town-D8VmTCmN.mjs → town-BMlctE4m.mjs} +12 -12
  161. package/.output/server/chunks/build/{town-D8VmTCmN.mjs.map → town-BMlctE4m.mjs.map} +1 -1
  162. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  163. package/.output/server/chunks/build/{useAgentHarnessOptions-CPn5dzKe.mjs → useAgentHarnessOptions-D6SJ_uUr.mjs} +7 -7
  164. package/.output/server/chunks/build/{useAgentHarnessOptions-CPn5dzKe.mjs.map → useAgentHarnessOptions-D6SJ_uUr.mjs.map} +1 -1
  165. package/.output/server/chunks/build/{useAgentTemplateActions-DQWzVnZ0.mjs → useAgentTemplateActions-CdG4g_PF.mjs} +7 -7
  166. package/.output/server/chunks/build/{useAgentTemplateActions-DQWzVnZ0.mjs.map → useAgentTemplateActions-CdG4g_PF.mjs.map} +1 -1
  167. package/.output/server/chunks/build/useAgentTemplateDialogState-CZzpu5og.mjs +6 -6
  168. package/.output/server/chunks/build/{useAgentTemplateForm-vqyiRPtt.mjs → useAgentTemplateForm-a5y-N5sB.mjs} +7 -7
  169. package/.output/server/chunks/build/{useAgentTemplateForm-vqyiRPtt.mjs.map → useAgentTemplateForm-a5y-N5sB.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{useAgentTemplatesCatalog-DcQbsOik.mjs → useAgentTemplatesCatalog-pBVcUuN3.mjs} +7 -7
  171. package/.output/server/chunks/build/{useAgentTemplatesCatalog-DcQbsOik.mjs.map → useAgentTemplatesCatalog-pBVcUuN3.mjs.map} +1 -1
  172. package/.output/server/chunks/build/useAmlDatasets-BM0lZu40.mjs +6 -6
  173. package/.output/server/chunks/build/{useAmlEntities-BjXWvFd_.mjs → useAmlEntities-BDQ8TmLL.mjs} +7 -7
  174. package/.output/server/chunks/build/{useAmlEntities-BjXWvFd_.mjs.map → useAmlEntities-BDQ8TmLL.mjs.map} +1 -1
  175. package/.output/server/chunks/build/{useAmlEnv-BB7p6x_w.mjs → useAmlEnv-DgTVwpqi.mjs} +7 -7
  176. package/.output/server/chunks/build/{useAmlEnv-BB7p6x_w.mjs.map → useAmlEnv-DgTVwpqi.mjs.map} +1 -1
  177. package/.output/server/chunks/build/useAmlExperiments-BtyW32PO.mjs +6 -6
  178. package/.output/server/chunks/build/{useAmlFormat-WrKuRfw2.mjs → useAmlFormat-C2sl3MGB.mjs} +7 -7
  179. package/.output/server/chunks/build/{useAmlFormat-WrKuRfw2.mjs.map → useAmlFormat-C2sl3MGB.mjs.map} +1 -1
  180. package/.output/server/chunks/build/{useAmlJobs-DBuLvWMF.mjs → useAmlJobs-fk-H5Rp5.mjs} +10 -9
  181. package/.output/server/chunks/build/useAmlJobs-fk-H5Rp5.mjs.map +1 -0
  182. package/.output/server/chunks/build/{useAmlModels-VurmkBYe.mjs → useAmlModels-hgyVHoAq.mjs} +7 -7
  183. package/.output/server/chunks/build/{useAmlModels-VurmkBYe.mjs.map → useAmlModels-hgyVHoAq.mjs.map} +1 -1
  184. package/.output/server/chunks/build/{useAmlNotes-BUdj3X6Y.mjs → useAmlNotes-BjbYNADm.mjs} +7 -7
  185. package/.output/server/chunks/build/{useAmlNotes-BUdj3X6Y.mjs.map → useAmlNotes-BjbYNADm.mjs.map} +1 -1
  186. package/.output/server/chunks/build/{useAmlPredict-DFy-Do10.mjs → useAmlPredict-U24-SZNA.mjs} +7 -7
  187. package/.output/server/chunks/build/{useAmlPredict-DFy-Do10.mjs.map → useAmlPredict-U24-SZNA.mjs.map} +1 -1
  188. package/.output/server/chunks/build/useDaqAddNode-kW7uTSMQ.mjs +7 -7
  189. package/.output/server/chunks/build/useDaqDetailBinding-cpBz4hSL.mjs +6 -6
  190. package/.output/server/chunks/build/useDaqDetailFrames-BZGtKKXW.mjs +6 -6
  191. package/.output/server/chunks/build/{useDaqDetailHistory-C4_hVeqZ.mjs → useDaqDetailHistory-DtSTfyMi.mjs} +7 -7
  192. package/.output/server/chunks/build/{useDaqDetailHistory-C4_hVeqZ.mjs.map → useDaqDetailHistory-DtSTfyMi.mjs.map} +1 -1
  193. package/.output/server/chunks/build/{useDaqDetailNode-Bwid_iA8.mjs → useDaqDetailNode-D_vhG0jF.mjs} +8 -8
  194. package/.output/server/chunks/build/{useDaqDetailNode-Bwid_iA8.mjs.map → useDaqDetailNode-D_vhG0jF.mjs.map} +1 -1
  195. package/.output/server/chunks/build/useDaqDetailParams-JfqHvTxr.mjs +7 -7
  196. package/.output/server/chunks/build/{useDaqFilters-C13836p-.mjs → useDaqFilters-BUQtZ82a.mjs} +8 -8
  197. package/.output/server/chunks/build/{useDaqFilters-C13836p-.mjs.map → useDaqFilters-BUQtZ82a.mjs.map} +1 -1
  198. package/.output/server/chunks/build/useDaqNodeWindow-1DWj2H5G.mjs +6 -6
  199. package/.output/server/chunks/build/useDaqOptimizations-Ct-TSXxy.mjs +6 -6
  200. package/.output/server/chunks/build/useDaqStream-wOxZcMDA.mjs +1 -1
  201. package/.output/server/chunks/build/useDaqTemplates-BqQRdrIm.mjs +7 -7
  202. package/.output/server/chunks/build/{useDashboardCharts-DZysNDUX.mjs → useDashboardCharts-D45083s_.mjs} +7 -7
  203. package/.output/server/chunks/build/{useDashboardCharts-DZysNDUX.mjs.map → useDashboardCharts-D45083s_.mjs.map} +1 -1
  204. package/.output/server/chunks/build/{useDashboardData-Ny_wtbo6.mjs → useDashboardData-Do_Vsepa.mjs} +8 -8
  205. package/.output/server/chunks/build/{useDashboardData-Ny_wtbo6.mjs.map → useDashboardData-Do_Vsepa.mjs.map} +1 -1
  206. package/.output/server/chunks/build/{useDcwAddNode-C8nE7geh.mjs → useDcwAddNode-C1HDP3yG.mjs} +12 -9
  207. package/.output/server/chunks/build/useDcwAddNode-C1HDP3yG.mjs.map +1 -0
  208. package/.output/server/chunks/build/useDcwCards-ETEsHvVy.mjs +6 -6
  209. package/.output/server/chunks/build/{useDcwDetailScope-BNrpDzbO.mjs → useDcwDetailScope-QTr1G6Oe.mjs} +7 -7
  210. package/.output/server/chunks/build/{useDcwDetailScope-BNrpDzbO.mjs.map → useDcwDetailScope-QTr1G6Oe.mjs.map} +1 -1
  211. package/.output/server/chunks/build/{useDcwDetailTemplates-IcKAJ37Y.mjs → useDcwDetailTemplates-Djt-0Vse.mjs} +7 -7
  212. package/.output/server/chunks/build/{useDcwDetailTemplates-IcKAJ37Y.mjs.map → useDcwDetailTemplates-Djt-0Vse.mjs.map} +1 -1
  213. package/.output/server/chunks/build/useDcwFilter-FfVlDdyS.mjs +6 -6
  214. package/.output/server/chunks/build/useDcwLedger-BLoMmcu1.mjs +6 -6
  215. package/.output/server/chunks/build/useDcwLineMutations-BMC5BTWU.mjs +6 -6
  216. package/.output/server/chunks/build/{useDcwLineRun-Bpxk4mse.mjs → useDcwLineRun-74gN_s6T.mjs} +7 -7
  217. package/.output/server/chunks/build/{useDcwLineRun-Bpxk4mse.mjs.map → useDcwLineRun-74gN_s6T.mjs.map} +1 -1
  218. package/.output/server/chunks/build/useDcwProducts-D-zrMaeV.mjs +6 -6
  219. package/.output/server/chunks/build/{useDcwQuery-1lYHOaU6.mjs → useDcwQuery-7tX4QYmv.mjs} +7 -7
  220. package/.output/server/chunks/build/{useDcwQuery-1lYHOaU6.mjs.map → useDcwQuery-7tX4QYmv.mjs.map} +1 -1
  221. package/.output/server/chunks/build/useDcwQuickActions-C-tgcXIr.mjs +6 -6
  222. package/.output/server/chunks/build/{useDcwRecipes-BzGOymqz.mjs → useDcwRecipes-FVk5gDLV.mjs} +23 -15
  223. package/.output/server/chunks/build/useDcwRecipes-FVk5gDLV.mjs.map +1 -0
  224. package/.output/server/chunks/build/useDcwStream-D04kCV3J.mjs +1 -1
  225. package/.output/server/chunks/build/{useDcwTemplates-Dsjw9u6U.mjs → useDcwTemplates-LDZffy4u.mjs} +7 -7
  226. package/.output/server/chunks/build/{useDcwTemplates-Dsjw9u6U.mjs.map → useDcwTemplates-LDZffy4u.mjs.map} +1 -1
  227. package/.output/server/chunks/build/{useDcwWrites-3RxwN36I.mjs → useDcwWrites-B22mwliK.mjs} +25 -8
  228. package/.output/server/chunks/build/useDcwWrites-B22mwliK.mjs.map +1 -0
  229. package/.output/server/chunks/build/useLocalTime-DZ2RAtVs.mjs +49 -0
  230. package/.output/server/chunks/build/useLocalTime-DZ2RAtVs.mjs.map +1 -0
  231. package/.output/server/chunks/build/{useLogsFormat-BlwLpyzy.mjs → useLogsFormat-B-o4MHy7.mjs} +7 -7
  232. package/.output/server/chunks/build/{useLogsFormat-BlwLpyzy.mjs.map → useLogsFormat-B-o4MHy7.mjs.map} +1 -1
  233. package/.output/server/chunks/build/{useLogsManual-Deev2Cjk.mjs → useLogsManual-COfCyUtj.mjs} +7 -7
  234. package/.output/server/chunks/build/{useLogsManual-Deev2Cjk.mjs.map → useLogsManual-COfCyUtj.mjs.map} +1 -1
  235. package/.output/server/chunks/build/useLogsQuery-CRAm2hmS.mjs +6 -6
  236. package/.output/server/chunks/build/useLogsScope-ClNijVj4.mjs +6 -6
  237. package/.output/server/chunks/build/{useMonitorColumns-ylxrUNTK.mjs → useMonitorColumns-DhYvkLDq.mjs} +7 -7
  238. package/.output/server/chunks/build/{useMonitorColumns-ylxrUNTK.mjs.map → useMonitorColumns-DhYvkLDq.mjs.map} +1 -1
  239. package/.output/server/chunks/build/{useMonitorData-CEpKXoD4.mjs → useMonitorData-guVjMDtR.mjs} +9 -8
  240. package/.output/server/chunks/build/useMonitorData-guVjMDtR.mjs.map +1 -0
  241. package/.output/server/chunks/build/{useMonitorFormat-_7zLapf3.mjs → useMonitorFormat-C7lhZe4g.mjs} +13 -12
  242. package/.output/server/chunks/build/useMonitorFormat-C7lhZe4g.mjs.map +1 -0
  243. package/.output/server/chunks/build/useMonitorTerminal-Dj4QwRNW.mjs +6 -6
  244. package/.output/server/chunks/build/useOperationsFeed-CeXeHqUK.mjs +191 -0
  245. package/.output/server/chunks/build/useOperationsFeed-CeXeHqUK.mjs.map +1 -0
  246. package/.output/server/chunks/build/{useTeamActions-D6sxdpkP.mjs → useTeamActions-C4n-taBk.mjs} +7 -7
  247. package/.output/server/chunks/build/{useTeamActions-D6sxdpkP.mjs.map → useTeamActions-C4n-taBk.mjs.map} +1 -1
  248. package/.output/server/chunks/build/{useTeamAddMemberDialog-Q-ntQ6Vo.mjs → useTeamAddMemberDialog-Cp_z3nMa.mjs} +7 -7
  249. package/.output/server/chunks/build/{useTeamAddMemberDialog-Q-ntQ6Vo.mjs.map → useTeamAddMemberDialog-Cp_z3nMa.mjs.map} +1 -1
  250. package/.output/server/chunks/build/{useTeamCreateDialog-D7OMfDTM.mjs → useTeamCreateDialog-C8LKUoe2.mjs} +7 -7
  251. package/.output/server/chunks/build/{useTeamCreateDialog-D7OMfDTM.mjs.map → useTeamCreateDialog-C8LKUoe2.mjs.map} +1 -1
  252. package/.output/server/chunks/build/{useTeamDeployDialog-vBRqjiut.mjs → useTeamDeployDialog-wdBVsNWY.mjs} +7 -7
  253. package/.output/server/chunks/build/{useTeamDeployDialog-vBRqjiut.mjs.map → useTeamDeployDialog-wdBVsNWY.mjs.map} +1 -1
  254. package/.output/server/chunks/build/useTeamDialogState-CFRUQxAf.mjs +6 -6
  255. package/.output/server/chunks/build/{useTeamPluginDialog-B8kxewpZ.mjs → useTeamPluginDialog-CIk8G8nI.mjs} +7 -7
  256. package/.output/server/chunks/build/{useTeamPluginDialog-B8kxewpZ.mjs.map → useTeamPluginDialog-CIk8G8nI.mjs.map} +1 -1
  257. package/.output/server/chunks/build/{useTeamsCatalog-xRhk7ezA.mjs → useTeamsCatalog-D6TULzmS.mjs} +7 -7
  258. package/.output/server/chunks/build/{useTeamsCatalog-xRhk7ezA.mjs.map → useTeamsCatalog-D6TULzmS.mjs.map} +1 -1
  259. package/.output/server/chunks/build/useTokenClipboard-CwQpoFeP.mjs +6 -6
  260. package/.output/server/chunks/build/{useTokenCreate-DpDcF1Vx.mjs → useTokenCreate-DkYvEQUD.mjs} +7 -7
  261. package/.output/server/chunks/build/{useTokenCreate-DpDcF1Vx.mjs.map → useTokenCreate-DkYvEQUD.mjs.map} +1 -1
  262. package/.output/server/chunks/build/{useTokenRename-BRejFrtc.mjs → useTokenRename-DOCP4aeI.mjs} +7 -7
  263. package/.output/server/chunks/build/{useTokenRename-BRejFrtc.mjs.map → useTokenRename-DOCP4aeI.mjs.map} +1 -1
  264. package/.output/server/chunks/build/{useTokenReveal-DER2afAS.mjs → useTokenReveal-CybwwflV.mjs} +7 -7
  265. package/.output/server/chunks/build/{useTokenReveal-DER2afAS.mjs.map → useTokenReveal-CybwwflV.mjs.map} +1 -1
  266. package/.output/server/chunks/build/{useTokensList-DHt65IOY.mjs → useTokensList-BLiMvrc4.mjs} +7 -7
  267. package/.output/server/chunks/build/{useTokensList-DHt65IOY.mjs.map → useTokensList-BLiMvrc4.mjs.map} +1 -1
  268. package/.output/server/chunks/build/{useWorkbenchAuth-B2j-zILO.mjs → useWorkbenchAuth-DqjBX-6w.mjs} +7 -7
  269. package/.output/server/chunks/build/{useWorkbenchAuth-B2j-zILO.mjs.map → useWorkbenchAuth-DqjBX-6w.mjs.map} +1 -1
  270. package/.output/server/chunks/build/{useWorkbenchWorkspaces-B_2mOxN6.mjs → useWorkbenchWorkspaces-DgiSCzsX.mjs} +10 -9
  271. package/.output/server/chunks/build/useWorkbenchWorkspaces-DgiSCzsX.mjs.map +1 -0
  272. package/.output/server/chunks/build/{useWorkshopWs-B-Es2Xg3.mjs → useWorkshopWs-Bm80bLn7.mjs} +8 -7
  273. package/.output/server/chunks/build/useWorkshopWs-Bm80bLn7.mjs.map +1 -0
  274. package/.output/server/chunks/build/{useWorkspaceAuth-tQ1ORWXo.mjs → useWorkspaceAuth-Dlvj9csD.mjs} +8 -8
  275. package/.output/server/chunks/build/{useWorkspaceAuth-tQ1ORWXo.mjs.map → useWorkspaceAuth-Dlvj9csD.mjs.map} +1 -1
  276. package/.output/server/chunks/build/{useWorkspaceChannels-BwB6TAWY.mjs → useWorkspaceChannels-D61Al2dr.mjs} +11 -10
  277. package/.output/server/chunks/build/useWorkspaceChannels-D61Al2dr.mjs.map +1 -0
  278. package/.output/server/chunks/build/{useWorkspacePanels-CuAmDpT5.mjs → useWorkspacePanels-CTwREmq0.mjs} +8 -8
  279. package/.output/server/chunks/build/{useWorkspacePanels-CuAmDpT5.mjs.map → useWorkspacePanels-CTwREmq0.mjs.map} +1 -1
  280. package/.output/server/chunks/build/{useWorkspaceShell-CcQ4JlqO.mjs → useWorkspaceShell-BCypjjjE.mjs} +7 -7
  281. package/.output/server/chunks/build/{useWorkspaceShell-CcQ4JlqO.mjs.map → useWorkspaceShell-BCypjjjE.mjs.map} +1 -1
  282. package/.output/server/chunks/build/{users-De2HygNt.mjs → users-CCf5PgRs.mjs} +8 -8
  283. package/.output/server/chunks/build/{users-De2HygNt.mjs.map → users-CCf5PgRs.mjs.map} +1 -1
  284. package/.output/server/chunks/build/{workshop-CmgpTwyf.mjs → workshop-FQ4YzooB.mjs} +13 -12
  285. package/.output/server/chunks/build/workshop-FQ4YzooB.mjs.map +1 -0
  286. package/.output/server/chunks/build/{workspaces-DVIEk1Bl.mjs → workspaces-CmW0cpOt.mjs} +1 -1
  287. package/.output/server/chunks/build/{workspaces-DVIEk1Bl.mjs.map → workspaces-CmW0cpOt.mjs.map} +1 -1
  288. package/.output/server/chunks/routes/api/health.get.mjs +6 -6
  289. package/.output/server/chunks/routes/api/index.get.mjs +7 -7
  290. package/.output/server/chunks/routes/api/index.post.mjs +7 -7
  291. package/.output/server/chunks/routes/api/mcp/workshop.mjs +6 -6
  292. package/.output/server/chunks/routes/api/metrics.mjs +6 -6
  293. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +6 -6
  294. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +6 -6
  295. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +6 -6
  296. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +6 -6
  297. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +6 -6
  298. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +6 -6
  299. package/.output/server/chunks/routes/api/system/config.get.mjs +6 -6
  300. package/.output/server/chunks/routes/api/system/index.get.mjs +6 -6
  301. package/.output/server/chunks/routes/api/system/index.patch.mjs +6 -6
  302. package/.output/server/chunks/routes/api/system/index.post.mjs +6 -6
  303. package/.output/server/chunks/routes/api/system/index2.get.mjs +6 -6
  304. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +6 -6
  305. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +6 -6
  306. package/.output/server/chunks/routes/api/system/monitor.get.mjs +6 -6
  307. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +6 -6
  308. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +6 -6
  309. package/.output/server/chunks/routes/api/system/timezone.get.mjs +36 -0
  310. package/.output/server/chunks/routes/api/system/timezone.get.mjs.map +1 -0
  311. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +7 -7
  312. package/.output/server/chunks/routes/api/users/_id_.get.mjs +7 -7
  313. package/.output/server/chunks/routes/api/users/_id_.put.mjs +7 -7
  314. package/.output/server/chunks/routes/api/users/index.get.mjs +7 -7
  315. package/.output/server/chunks/routes/api/users/index.post.mjs +7 -7
  316. package/.output/server/chunks/routes/api/users/login.post.mjs +7 -7
  317. package/.output/server/chunks/routes/api/users/logout.post.mjs +7 -7
  318. package/.output/server/chunks/routes/api/users/me.get.mjs +7 -7
  319. package/.output/server/chunks/routes/api/users/register.post.mjs +7 -7
  320. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +7 -7
  321. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +7 -7
  322. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +7 -7
  323. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +7 -7
  324. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +6 -6
  325. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +7 -7
  326. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +5 -5
  327. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +6 -6
  328. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +7 -7
  329. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +7 -7
  330. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +10 -7
  331. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
  332. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +7 -7
  333. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +7 -7
  334. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +7 -7
  335. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +7 -7
  336. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +7 -7
  337. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +6 -6
  338. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +6 -6
  339. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +6 -6
  340. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +6 -6
  341. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +6 -6
  342. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +7 -7
  343. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +7 -7
  344. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +7 -7
  345. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs +7 -7
  346. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +7 -8
  347. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +7 -8
  349. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +7 -8
  351. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +7 -7
  353. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +7 -7
  354. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +6 -6
  355. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +20 -7
  356. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -1
  357. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +7 -8
  358. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -1
  359. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +49 -0
  360. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs.map +1 -0
  361. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +7 -7
  362. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +7 -7
  363. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +7 -7
  364. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +28 -0
  365. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs.map +1 -0
  366. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +7 -7
  367. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +7 -7
  368. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +7 -7
  369. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +7 -7
  370. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +7 -7
  371. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +7 -7
  372. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +7 -7
  373. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +7 -7
  374. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +7 -7
  375. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +35 -0
  376. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs.map +1 -0
  377. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +35 -0
  378. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs.map +1 -0
  379. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +44 -0
  380. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs.map +1 -0
  381. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +46 -0
  382. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs.map +1 -0
  383. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +7 -7
  384. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +5 -5
  385. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +5 -5
  386. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +6 -6
  387. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +6 -6
  388. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +5 -5
  389. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +6 -6
  390. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +6 -6
  391. package/.output/server/chunks/routes/api/workshop/caller.mjs +7 -7
  392. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +16 -10
  393. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs.map +1 -1
  394. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +6 -6
  395. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +6 -6
  396. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +6 -6
  397. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +6 -6
  398. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +7 -7
  399. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +6 -6
  400. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +6 -6
  401. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +6 -6
  402. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +6 -6
  403. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +6 -6
  404. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +6 -6
  405. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +6 -6
  406. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +6 -6
  407. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +6 -6
  408. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +6 -6
  409. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.get.mjs +6 -6
  410. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +6 -6
  411. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/messages/_messageId/read.post.mjs +6 -6
  412. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/permissions.get.mjs +6 -6
  413. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +6 -6
  414. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +6 -6
  415. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +6 -6
  416. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +7 -7
  417. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +6 -6
  418. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +6 -6
  419. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +6 -6
  420. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +6 -6
  421. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +6 -6
  422. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +6 -6
  423. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +7 -7
  424. package/.output/server/chunks/routes/api/workshop/channels/_id/index6.get.mjs +6 -6
  425. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId/approve.post.mjs +6 -6
  426. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId_.delete.mjs +6 -6
  427. package/.output/server/chunks/routes/api/workshop/channels/_id/members/join.post.mjs +6 -6
  428. package/.output/server/chunks/routes/api/workshop/channels/_id/members/leave.post.mjs +6 -6
  429. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +6 -6
  430. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +6 -6
  431. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +7 -7
  432. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +51 -0
  433. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs.map +1 -0
  434. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +71 -0
  435. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs.map +1 -0
  436. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +6 -6
  437. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +7 -7
  438. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +6 -6
  439. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +6 -6
  440. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +9 -9
  441. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +7 -7
  442. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +7 -7
  443. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +7 -7
  444. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +7 -7
  445. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +7 -7
  446. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +7 -7
  447. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +7 -7
  448. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +7 -7
  449. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +7 -7
  450. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +7 -7
  451. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +7 -7
  452. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +7 -7
  453. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +7 -7
  454. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +7 -7
  455. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +7 -7
  456. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +7 -7
  457. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +7 -7
  458. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +7 -7
  459. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +7 -7
  460. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +7 -7
  461. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +7 -7
  462. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +7 -7
  463. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +7 -7
  464. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +7 -7
  465. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +7 -7
  466. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +7 -7
  467. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +7 -7
  468. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +7 -7
  469. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +7 -7
  470. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +7 -7
  471. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +7 -7
  472. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +7 -7
  473. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +7 -7
  474. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +7 -7
  475. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +7 -7
  476. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +7 -7
  477. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +7 -7
  478. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +7 -7
  479. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +7 -7
  480. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +7 -7
  481. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +7 -7
  482. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +7 -7
  483. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +7 -7
  484. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +7 -7
  485. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +7 -7
  486. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +7 -7
  487. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +7 -7
  488. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +7 -7
  489. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +7 -7
  490. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +7 -7
  491. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +7 -7
  492. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +7 -7
  493. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +7 -7
  494. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +7 -7
  495. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +7 -7
  496. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +7 -7
  497. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +7 -7
  498. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +7 -7
  499. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +7 -7
  500. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +7 -7
  501. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +7 -7
  502. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +7 -7
  503. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +7 -7
  504. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +7 -7
  505. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +7 -7
  506. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +7 -7
  507. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +7 -7
  508. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +7 -7
  509. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +7 -7
  510. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +7 -7
  511. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +5 -5
  512. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +7 -7
  513. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +7 -7
  514. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +7 -7
  515. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +7 -7
  516. package/.output/server/chunks/routes/api/workshop/index.get.mjs +6 -6
  517. package/.output/server/chunks/routes/api/workshop/index.post.mjs +6 -6
  518. package/.output/server/chunks/routes/api/workshop/index.put.mjs +7 -7
  519. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +7 -7
  520. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +6 -6
  521. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +6 -6
  522. package/.output/server/chunks/routes/api/workshop/index13.get.mjs +6 -6
  523. package/.output/server/chunks/routes/api/workshop/index14.get.mjs +6 -6
  524. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +7 -8
  525. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  526. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +6 -6
  527. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +6 -6
  528. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +7 -7
  529. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +6 -6
  530. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +7 -7
  531. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +7 -7
  532. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +7 -7
  533. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +7 -7
  534. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +7 -7
  535. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +7 -7
  536. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +6 -6
  537. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +6 -6
  538. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +6 -6
  539. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +6 -6
  540. package/.output/server/chunks/routes/api/workshop/index9.post.mjs +6 -6
  541. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +6 -6
  542. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +6 -6
  543. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +6 -6
  544. package/.output/server/chunks/routes/api/workshop/notifications/read.post.mjs +6 -6
  545. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +7 -7
  546. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +7 -7
  547. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +6 -6
  548. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +6 -6
  549. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +7 -7
  550. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +7 -7
  551. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +6 -6
  552. package/.output/server/chunks/routes/api/workshop/schedules/_id/run.post.mjs +6 -6
  553. package/.output/server/chunks/routes/api/workshop/schedules/_id/runs.get.mjs +6 -6
  554. package/.output/server/chunks/routes/api/workshop/schedules/_id_.delete.mjs +6 -6
  555. package/.output/server/chunks/routes/api/workshop/schedules/_id_.get.mjs +6 -6
  556. package/.output/server/chunks/routes/api/workshop/schedules/_id_.patch.mjs +6 -6
  557. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +6 -6
  558. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +6 -6
  559. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +6 -6
  560. package/.output/server/chunks/routes/api/workshop/tasks/_id/reassign.post.mjs +6 -6
  561. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +6 -6
  562. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +6 -6
  563. package/.output/server/chunks/routes/api/workshop/tasks/_id/update.post.mjs +6 -6
  564. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +6 -6
  565. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +6 -6
  566. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +6 -6
  567. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +6 -6
  568. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +6 -6
  569. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +7 -7
  570. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +7 -7
  571. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +6 -6
  572. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +6 -6
  573. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +6 -6
  574. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +6 -6
  575. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +6 -6
  576. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +6 -6
  577. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +7 -7
  578. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +6 -6
  579. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +6 -6
  580. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +6 -6
  581. package/.output/server/chunks/routes/renderer.mjs +2 -2
  582. package/.output/server/chunks/virtual/entry.mjs +645 -525
  583. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  584. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  585. package/.output/server/index.mjs +6 -6
  586. package/.output/server/package.json +1 -1
  587. package/README-zh.md +33 -17
  588. package/README.md +32 -16
  589. package/app/components/AppSidebar.vue +1 -0
  590. package/app/components/aml/AmlModelsTable.vue +180 -173
  591. package/app/components/daq/DaqDetailFramesTile.vue +140 -139
  592. package/app/components/daq/DaqDetailHistoryCard.vue +129 -128
  593. package/app/components/dcw/DcwAddNodeModal.vue +342 -328
  594. package/app/components/dcw/DcwNodesTable.vue +290 -253
  595. package/app/components/dcw/DcwQueryCard.vue +252 -251
  596. package/app/components/dcw/DcwRecipeEditModal.vue +297 -285
  597. package/app/components/dcw/DcwRecipePanel.vue +371 -367
  598. package/app/components/operations/OperationsFilterCard.vue +164 -0
  599. package/app/components/operations/OperationsPageHead.vue +47 -0
  600. package/app/components/operations/OperationsTimeline.vue +215 -0
  601. package/app/components/settings/RuntimeFieldRow.vue +207 -189
  602. package/app/components/workshop/ChatTimeline.vue +596 -569
  603. package/app/components/workshop/EventBlock.vue +224 -214
  604. package/app/components/workshop/blocks/ClusterTool.vue +20 -2
  605. package/app/components/workshop/console/LineOperationsPanel.vue +179 -0
  606. package/app/components/workshop/console/RightPane.vue +6 -0
  607. package/app/composables/workshop/event-blocks/constants.ts +48 -2
  608. package/app/composables/workshop/operation-events.ts +151 -0
  609. package/app/composables/workshop/useAmlStream.ts +137 -136
  610. package/app/composables/workshop/useLocalTime.ts +81 -37
  611. package/app/config/schema.ts +3 -0
  612. package/app/pages/aml/styles.css +422 -420
  613. package/app/pages/aml/types.ts +195 -189
  614. package/app/pages/dcw/[id].vue +300 -297
  615. package/app/pages/dcw/composables/useDcwAddNode.ts +124 -121
  616. package/app/pages/dcw/composables/useDcwRecipes.ts +242 -239
  617. package/app/pages/dcw/composables/useDcwWrites.ts +100 -81
  618. package/app/pages/monitor/composables/useMonitorData.ts +125 -124
  619. package/app/pages/monitor/composables/useMonitorFormat.ts +41 -39
  620. package/app/pages/operations/composables/useOperationsFeed.ts +137 -0
  621. package/app/pages/operations.vue +61 -0
  622. package/app/stores/runtime-config.ts +1 -1
  623. package/app/stores/workshop/chat.ts +434 -434
  624. package/app/stores/workshop/notifications.ts +288 -288
  625. package/app/utils/dcw-recipe-form.ts +26 -0
  626. package/cli/aw.mjs +3 -2
  627. package/cli/commands/mcp.mjs +154 -0
  628. package/cli/core/context.mjs +5 -0
  629. package/config.yml +180 -176
  630. package/docs/aml.md +112 -111
  631. package/docs/cli.en.md +13 -11
  632. package/docs/cli.md +12 -10
  633. package/docs/plugins.en.md +621 -567
  634. package/docs/plugins.md +610 -560
  635. package/docs/sdk.en.md +964 -922
  636. package/docs/sdk.md +900 -861
  637. package/i18n/dicts/aml.json +207 -205
  638. package/i18n/locales/en.ts +37 -0
  639. package/i18n/locales/zh-CN.ts +37 -0
  640. package/nuxt.config.ts +2 -0
  641. package/package.json +178 -172
  642. package/scripts/.chk-tok +1 -0
  643. package/scripts/.retrain-body.json +1 -0
  644. package/scripts/.retrain3-body.json +1 -0
  645. package/scripts/.rt-tok +1 -0
  646. package/scripts/.rt3-tok +1 -0
  647. package/scripts/_audit/.tmp/audit-data/dcw-params.json +15 -0
  648. package/scripts/_audit/.tmp/audit-data/dcws.json +30 -0
  649. package/scripts/_audit/aw-mcp-live-e2e.mjs +293 -0
  650. package/scripts/_audit/dcw-controller-e2e.ts +25 -18
  651. package/scripts/_audit/dcw-rollback-ledger.ts +4 -1
  652. package/scripts/_audit/feature-audit-e2e.mjs +339 -0
  653. package/scripts/_audit/full-e2e-adopt.mjs +238 -0
  654. package/scripts/_audit/full-e2e-close-loop.mjs +134 -0
  655. package/scripts/_audit/full-e2e-retrain.mjs +320 -0
  656. package/scripts/_audit/full-e2e-supplement.mjs +192 -0
  657. package/scripts/_audit/full-e2e-ui-final.mjs +111 -0
  658. package/scripts/_audit/full-e2e-ui-mount.mjs +111 -0
  659. package/scripts/_audit/full-feature-e2e-20260927.mjs +627 -0
  660. package/scripts/_audit/kb-diag-complete.mjs +261 -0
  661. package/scripts/_audit/kb-diag-complete2.mjs +271 -0
  662. package/scripts/_audit/kb-diag-loop-e2e.mjs +357 -0
  663. package/scripts/_audit/kb-diag-loop-mock.mjs +416 -0
  664. package/scripts/_audit/kb-diag-loop-v2.mjs +314 -0
  665. package/scripts/_audit/recipe-save-e2e.mjs +365 -0
  666. package/scripts/_audit/run.mjs +21 -0
  667. package/scripts/_audit/runtime-dir-e2e.mjs +393 -0
  668. package/scripts/_audit/skills-guided-e2e.mjs +316 -0
  669. package/scripts/_audit/stability-soak.mjs +252 -0
  670. package/scripts/_aw0748-failclosed-probe.mjs +1 -1
  671. package/scripts/_aw0748-mock-closedloop.mjs +12 -0
  672. package/scripts/_aw0748-mock-dispatch-diag.mjs +66 -0
  673. package/scripts/_dbg-configroot-audit.mjs +86 -84
  674. package/scripts/_dbg-daq-intervals-func.mjs +115 -94
  675. package/scripts/_dbg-optloop-ui-shots.mjs +52 -0
  676. package/scripts/_dbg-param-map-e2e.ts +7 -1
  677. package/scripts/_dbg-perms-e2e.mjs +11 -1
  678. package/scripts/_dbg-protocol-matrix.mjs +3 -1
  679. package/scripts/_dbg-render-regression.mjs +67 -25
  680. package/scripts/_lib-aml-python-run.mjs +17 -0
  681. package/scripts/_lint-reflow.mjs +105 -0
  682. package/scripts/_probe-model-channel-link.cjs +25 -0
  683. package/scripts/acceptance-aml-hybrid-e2e.ts +396 -0
  684. package/scripts/acceptance-aml-hybrid-twin.ts +3 -3
  685. package/scripts/acceptance-aml-model-identity.ts +137 -0
  686. package/scripts/dev-guard.mjs +4 -2
  687. package/scripts/dev-protocol-simulators.mjs +3 -2
  688. package/scripts/e2e-aml-decoupled.mjs +162 -0
  689. package/scripts/e2e-closedloop/scenarios-accounts.mjs +2 -0
  690. package/scripts/e2e-closedloop/scenarios-authz.mjs +12 -6
  691. package/scripts/e2e-closedloop/scenarios-daq-dcw.mjs +4 -1
  692. package/scripts/e2e-timezone-settings.mjs +57 -0
  693. package/scripts/live-aml-mockomp.mjs +304 -0
  694. package/scripts/live-aml-optloop-resume.mjs +322 -0
  695. package/scripts/live-aml-optloop.mjs +545 -0
  696. package/scripts/live-aml-stage9.mjs +169 -0
  697. package/scripts/live-aml-two-goals.mjs +315 -0
  698. package/scripts/live-optloop-two-modes.mjs +857 -0
  699. package/scripts/start.mjs +3 -1
  700. package/scripts/test-aw-skills.mjs +102 -0
  701. package/scripts/test-twin-plugin-sdk.mjs +30 -0
  702. package/sdk/context.mjs +305 -0
  703. package/sdk/index.d.mts +149 -0
  704. package/sdk/index.mjs +5 -2
  705. package/server/api/system/timezone.get.ts +20 -0
  706. package/server/api/workshop/agent-tools/bindings/[id].patch.ts +28 -23
  707. package/server/api/workshop/aml/jobs/index.post.ts +74 -44
  708. package/server/api/workshop/aml/training-plans/[id]/train.post.ts +18 -0
  709. package/server/api/workshop/aml/training-plans/[id].delete.ts +18 -0
  710. package/server/api/workshop/aml/training-plans/[id].patch.ts +30 -0
  711. package/server/api/workshop/aml/training-plans/index.get.ts +9 -0
  712. package/server/api/workshop/aml/training-plans/index.post.ts +43 -0
  713. package/server/api/workshop/aml/twin/providers.get.ts +33 -0
  714. package/server/api/workshop/channel-templates/[id]/instantiate.post.ts +8 -2
  715. package/server/api/workshop/channels/[id]/twin-profile.get.ts +45 -0
  716. package/server/api/workshop/channels/[id]/twin-profile.patch.ts +72 -0
  717. package/server/plugins/00-local-time.ts +13 -10
  718. package/server/plugins/aml-twin-worker.ts +32 -0
  719. package/server/plugins/aw-plugins.ts +16 -0
  720. package/server/plugins/workshop.ts +21 -0
  721. package/server/plugins-builtin/twin-injection-default/index.mjs +23 -0
  722. package/server/services/system-config/helpers.ts +42 -41
  723. package/server/services/system-config/recompute.ts +68 -66
  724. package/server/services/workshop/agents/host-tool-bridge/catalog.ts +50 -18
  725. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +51 -5
  726. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +19 -6
  727. package/server/services/workshop/agents/industrial/aml-dataset-tools.ts +276 -276
  728. package/server/services/workshop/agents/industrial/aml-job-tools.ts +549 -363
  729. package/server/services/workshop/agents/industrial/audit-query.ts +30 -0
  730. package/server/services/workshop/agents/industrial/dcw-judge-tools.ts +9 -13
  731. package/server/services/workshop/agents/industrial/dcw-tools.ts +208 -213
  732. package/server/services/workshop/agents/industrial/index.ts +3 -2
  733. package/server/services/workshop/agents/industrial/manual-approval.ts +45 -0
  734. package/server/services/workshop/agents/industrial/ops-tools.ts +370 -382
  735. package/server/services/workshop/agents/industrial/optimization-tools.ts +148 -0
  736. package/server/services/workshop/agents/industrial/param-tools.ts +169 -172
  737. package/server/services/workshop/agents/industrial/twin-tools.ts +618 -61
  738. package/server/services/workshop/agents/industrial-context.ts +4 -2
  739. package/server/services/workshop/agents/node-bindings.repo.ts +35 -2
  740. package/server/services/workshop/agents/tool-classes.ts +28 -0
  741. package/server/services/workshop/aml/aml.repo.ts +412 -386
  742. package/server/services/workshop/aml/job-orchestrator/stages.ts +108 -96
  743. package/server/services/workshop/aml/job-orchestrator/start-job.ts +29 -5
  744. package/server/services/workshop/aml/job-orchestrator/submit.ts +36 -1
  745. package/server/services/workshop/aml/model-registry.ts +265 -175
  746. package/server/services/workshop/aml/predictor.ts +336 -262
  747. package/server/services/workshop/aml/python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  748. package/server/services/workshop/aml/python/__pycache__/amlkit.cpython-312.pyc +0 -0
  749. package/server/services/workshop/aml/python/__pycache__/train-example.cpython-312.pyc +0 -0
  750. package/server/services/workshop/aml/python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  751. package/server/services/workshop/aml/python/aml_eval.py +39 -6
  752. package/server/services/workshop/aml/python/amlkit.py +222 -3
  753. package/server/services/workshop/aml/python/train-hybrid-example.py +278 -32
  754. package/server/services/workshop/aml/runtime.ts +4 -3
  755. package/server/services/workshop/aml/twin/acceptance.ts +26 -0
  756. package/server/services/workshop/aml/twin/binding-snapshot.ts +603 -0
  757. package/server/services/workshop/aml/twin/calibration-worker.ts +150 -0
  758. package/server/services/workshop/aml/twin/channel-profile.ts +80 -7
  759. package/server/services/workshop/aml/twin/contracts.ts +3 -0
  760. package/server/services/workshop/aml/twin/declarative-provider.ts +108 -0
  761. package/server/services/workshop/aml/twin/feature-flags.ts +63 -0
  762. package/server/services/workshop/aml/twin/hybrid-provider.ts +86 -0
  763. package/server/services/workshop/aml/twin/model-backed-provider.ts +332 -0
  764. package/server/services/workshop/aml/twin/physics-spec-draft.ts +185 -0
  765. package/server/services/workshop/aml/twin/physics-spec.ts +338 -0
  766. package/server/services/workshop/aml/twin/prompt-composer.ts +143 -0
  767. package/server/services/workshop/aml/twin/provider-contracts.ts +98 -34
  768. package/server/services/workshop/aml/twin/provider-health.ts +69 -8
  769. package/server/services/workshop/aml/twin/provider-loader.ts +76 -45
  770. package/server/services/workshop/aml/twin/provider-registry.ts +670 -49
  771. package/server/services/workshop/aml/twin/repo.ts +63 -4
  772. package/server/services/workshop/aml/twin/scene-builder.ts +118 -0
  773. package/server/services/workshop/aml/twin/scene-lifecycle.ts +60 -0
  774. package/server/services/workshop/aml/twin/snapshot-service.ts +395 -22
  775. package/server/services/workshop/aml/twin/training-plans.ts +260 -0
  776. package/server/services/workshop/aml/twin/trial-service.ts +97 -13
  777. package/server/services/workshop/aml/twin/write-guard.ts +20 -0
  778. package/server/services/workshop/daq/daq-controller/state.ts +8 -5
  779. package/server/services/workshop/daq/drivers/registry.ts +116 -144
  780. package/server/services/workshop/db/database/migrations.ts +40 -0
  781. package/server/services/workshop/db/database/open.ts +4 -1
  782. package/server/services/workshop/db/database/schema.ts +68 -1
  783. package/server/services/workshop/db/database/seed.ts +22 -0
  784. package/server/services/workshop/db/readonly.ts +30 -0
  785. package/server/services/workshop/dcw/dcw-controller/crud.ts +162 -152
  786. package/server/services/workshop/dcw/dcw-controller/helpers.ts +61 -57
  787. package/server/services/workshop/dcw/dcw-controller/types.ts +61 -57
  788. package/server/services/workshop/dcw/dcw-controller/write-audit.ts +49 -0
  789. package/server/services/workshop/dcw/dcw-controller/write.ts +137 -147
  790. package/server/services/workshop/dcw/dcw-node.ts +18 -2
  791. package/server/services/workshop/dcw/dcw-recipe.repo.ts +5 -0
  792. package/server/services/workshop/dcw/dcw-runtime.ts +9 -3
  793. package/server/services/workshop/dcw/drivers/index.ts +2 -1
  794. package/server/services/workshop/dcw/drivers/modbus-rtu.ts +85 -93
  795. package/server/services/workshop/dcw/drivers/modbus.ts +131 -139
  796. package/server/services/workshop/dcw/drivers/opcua.ts +103 -110
  797. package/server/services/workshop/dcw/drivers/registry.ts +25 -45
  798. package/server/services/workshop/dcw/drivers/shared.ts +24 -6
  799. package/server/services/workshop/dcw/param-limits.ts +193 -142
  800. package/server/services/workshop/dcw/param-map.repo.ts +318 -305
  801. package/server/services/workshop/plugin-driver-registry.ts +108 -0
  802. package/server/services/workshop/runtime/manager/admin-channel.ts +13 -0
  803. package/server/services/workshop/runtime/manager/channel-templates.ts +29 -2
  804. package/server/services/workshop/runtime/manager/runtime-wiring.ts +8 -0
  805. package/server/services/workshop/runtime/permission-scope.ts +79 -81
  806. package/server/services/workshop/runtime/schedule-runtime.ts +33 -6
  807. package/server/utils/errors.ts +8 -0
  808. package/shared/config/engine.mjs +5 -0
  809. package/shared/config/home.mjs +15 -20
  810. package/shared/config/schema.json +135 -133
  811. package/shared/dcw-protocol/line.ts +133 -131
  812. package/shared/dcw-protocol/recipe.ts +311 -301
  813. package/shared/local-time.mjs +116 -36
  814. package/.output/public/_nuxt/-hB4kEmt.js +0 -1
  815. package/.output/public/_nuxt/74x7BOWv2.js +0 -1
  816. package/.output/public/_nuxt/9c5GOgbu.js +0 -1
  817. package/.output/public/_nuxt/BHwG4yNs.js +0 -1
  818. package/.output/public/_nuxt/BIOq3xqe2.js +0 -1
  819. package/.output/public/_nuxt/BL_dbd2v2.js +0 -1
  820. package/.output/public/_nuxt/BNnnYEYh2.js +0 -1
  821. package/.output/public/_nuxt/BxYTM0hb.js +0 -1
  822. package/.output/public/_nuxt/C3twEwTh2.js +0 -1
  823. package/.output/public/_nuxt/CGZVhYJ4.js +0 -1
  824. package/.output/public/_nuxt/CJRDL4EG.js +0 -1
  825. package/.output/public/_nuxt/CKQPwwZa2.js +0 -1
  826. package/.output/public/_nuxt/CeWnOF3O.js +0 -1
  827. package/.output/public/_nuxt/ChoLwR-s.js +0 -1
  828. package/.output/public/_nuxt/DGw8juu_.js +0 -2
  829. package/.output/public/_nuxt/DJdDFnjG2.js +0 -1
  830. package/.output/public/_nuxt/DXIaadqv.js +0 -1
  831. package/.output/public/_nuxt/D_7AzAWe.js +0 -1
  832. package/.output/public/_nuxt/DdvQ7LRI.js +0 -14
  833. package/.output/public/_nuxt/DeYsUzhr.js +0 -1
  834. package/.output/public/_nuxt/DkLCjrCk2.js +0 -47
  835. package/.output/public/_nuxt/DpqA8D8_.js +0 -1
  836. package/.output/public/_nuxt/DqtgGFEc.js +0 -1
  837. package/.output/public/_nuxt/Dy3oXKdn2.js +0 -1
  838. package/.output/public/_nuxt/PLGqdko0.js +0 -1
  839. package/.output/public/_nuxt/U8oQxruK.js +0 -1
  840. package/.output/public/_nuxt/WleoCtUX.js +0 -1
  841. package/.output/public/_nuxt/ZvXovq7N2.js +0 -1
  842. package/.output/public/_nuxt/_id_.Bossmhv1.css +0 -1
  843. package/.output/public/_nuxt/_wsId_.D-u-dbP9.css +0 -1
  844. package/.output/public/_nuxt/aml.Bi5X6_oi.css +0 -1
  845. package/.output/public/_nuxt/builds/meta/0530cee1-fff5-4025-a6f4-5708b6534608.json +0 -1
  846. package/.output/public/_nuxt/cDcDztgb2.js +0 -1
  847. package/.output/public/_nuxt/e7BBCLxr.js +0 -1
  848. package/.output/public/_nuxt/hkMGMTqt.js +0 -1
  849. package/.output/public/_nuxt/ikAUnxx3.js +0 -1
  850. package/.output/public/_nuxt/y9kob70X.js +0 -1
  851. package/.output/server/chunks/_/env-manager.mjs +0 -162
  852. package/.output/server/chunks/_/env-manager.mjs.map +0 -1
  853. package/.output/server/chunks/build/_id_-DgMpjM3_.mjs.map +0 -1
  854. package/.output/server/chunks/build/_id_-Dv3BQbYV.mjs.map +0 -1
  855. package/.output/server/chunks/build/_wsId_-BKJvFmyf.mjs.map +0 -1
  856. package/.output/server/chunks/build/aml-DdWicH3t.mjs.map +0 -1
  857. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs +0 -43
  858. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs.map +0 -1
  859. package/.output/server/chunks/build/daq-CPtsh0e7.mjs.map +0 -1
  860. package/.output/server/chunks/build/logs-CeaiO3y9.mjs.map +0 -1
  861. package/.output/server/chunks/build/pages-Bn90ijKD.mjs.map +0 -1
  862. package/.output/server/chunks/build/settings-DVAUVMsX.mjs.map +0 -1
  863. package/.output/server/chunks/build/useAmlJobs-DBuLvWMF.mjs.map +0 -1
  864. package/.output/server/chunks/build/useDcwAddNode-C8nE7geh.mjs.map +0 -1
  865. package/.output/server/chunks/build/useDcwRecipes-BzGOymqz.mjs.map +0 -1
  866. package/.output/server/chunks/build/useDcwWrites-3RxwN36I.mjs.map +0 -1
  867. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs +0 -35
  868. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs.map +0 -1
  869. package/.output/server/chunks/build/useMonitorData-CEpKXoD4.mjs.map +0 -1
  870. package/.output/server/chunks/build/useMonitorFormat-_7zLapf3.mjs.map +0 -1
  871. package/.output/server/chunks/build/useWorkbenchWorkspaces-B_2mOxN6.mjs.map +0 -1
  872. package/.output/server/chunks/build/useWorkshopWs-B-Es2Xg3.mjs.map +0 -1
  873. package/.output/server/chunks/build/useWorkspaceChannels-BwB6TAWY.mjs.map +0 -1
  874. package/.output/server/chunks/build/workshop-CmgpTwyf.mjs.map +0 -1
  875. /package/.output/public/_nuxt/{B2x8SKRO.js → B2x8SKRO2.js} +0 -0
  876. /package/.output/public/_nuxt/{BzvHUfRR2.js → BzvHUfRR.js} +0 -0
  877. /package/.output/public/_nuxt/{DPUXbTg92.js → DPUXbTg9.js} +0 -0
  878. /package/.output/public/_nuxt/{DdNujZN5.js → DdNujZN52.js} +0 -0
  879. /package/.output/public/_nuxt/{DlUQa0wn2.js → DlUQa0wn.js} +0 -0
  880. /package/.output/public/_nuxt/{Du9v6qGB.js → Du9v6qGB2.js} +0 -0
  881. /package/.output/public/_nuxt/{TOWR4WpO.js → TOWR4WpO2.js} +0 -0
  882. /package/.output/public/_nuxt/{cBI0JqsV2.js → cBI0JqsV.js} +0 -0
  883. /package/.output/public/_nuxt/{zh-S_7rN.js → zh-S_7rN2.js} +0 -0
@@ -1,363 +1,549 @@
1
- /**
2
- * AML 作业与模型(aml_job_* / aml_leaderboard / aml_model_*)
3
- * (由 server/services/workshop/agents/industrial-tools.ts 按职责拆出;内容逐行原文搬运)
4
- */
5
- import { AML_AUDIT_KIND, amlErr, amlJobCard, amlNodeName, amlNodeUnit, fmtAmlNum } from './aml-dataset-tools'
6
- import { agentBadgeLabel } from '../agent-badge'
7
- import { alignToGrid } from '../../aml/clean'
8
- import { cancelJob, jobLogsTail, runtimeStatus, submitJob } from '../../aml/job-orchestrator'
9
- import { getActiveLineRun } from '../../dcw/line-run'
10
- import { getAgentNodeBindingRepo } from '../node-bindings.repo'
11
- import { getAmlRuntime } from '../../aml/runtime'
12
- import { getDaqNodeRepo } from '../../daq/daq-node.repo'
13
- import { getDcwProductRepo } from '../../dcw/dcw-product.repo'
14
- import { getDcwRecipeRepo } from '../../dcw/dcw-recipe.repo'
15
- import { getToolApprovals } from '../tool-approvals'
16
- import { predictProduction, readIoSpecFor } from '../../aml/predictor'
17
- import { recordOps } from '../../ops/ops'
18
- import { transitionModel } from '../../aml/model-registry'
19
-
20
- /** 工具:aml_job_submit —— 提交训练作业(train.py 全文内联;归因 agentId;队列 FIFO) */
21
- export async function toolAmlJobSubmit(agentId: string, args: {
22
- dataset_id?: string
23
- code?: string
24
- change_note?: string
25
- params?: Record<string, unknown>
26
- seed?: number | string
27
- purpose?: string
28
- parent_experiment_id?: string
29
- scene_id?: string
30
- scene_version?: string
31
- objective_id?: string
32
- job_kind?: 'supervised' | 'physics_calibration' | 'hybrid_residual' | 'uncertainty_calibration'
33
- physics_manifest?: Record<string, unknown>
34
- twin_snapshot?: Record<string, unknown>
35
- objective_profile?: Record<string, unknown>
36
- }): Promise<{ text: string, isError?: boolean }> {
37
- const datasetId = String(args.dataset_id ?? '').trim()
38
- const code = typeof args.code === 'string' ? args.code : ''
39
- if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
40
- if (!code.trim()) return amlErr('code 必填:train.py 全文(单文件;契约见工具说明)。')
41
- if (code.length > 512_000) return amlErr(`code 过大(${Math.round(code.length / 1024)}KB),上限 500KB;精简训练代码(模型定义/训练循环拆薄)后重试。`)
42
- if (!/\bimport\s+amlkit\b/.test(code)) {
43
- return amlErr('code 必须 import amlkit(平台数据/进度/导出契约):amlkit.load_bundle(datasetPath) 取数、amlkit.report_progress(pct, note) 报进度、amlkit.export_torch_onnx(model, manifest) 导出。缺契约的作业必然失败。')
44
- }
45
- const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : args.purpose === 'mpc_surrogate' ? 'mpc_surrogate' : undefined
46
- const changeNote = String(args.change_note ?? '').trim()
47
- if (!changeNote) return amlErr('change_note 必填:单组件改动纪律 —— 每次实验只改一个组件(网络结构/特征/超参之一),写清改了什么与预期,实验谱系靠它归因。')
48
- try {
49
- const job = submitJob({
50
- datasetId,
51
- purpose,
52
- changeNote,
53
- params: args.params && typeof args.params === 'object' && !Array.isArray(args.params) ? args.params : undefined,
54
- seed: Number.isInteger(Number(args.seed)) ? Number(args.seed) : undefined,
55
- parentExperimentId: String(args.parent_experiment_id ?? '').trim() || undefined,
56
- code,
57
- sceneId: String(args.scene_id ?? '').trim() || undefined,
58
- sceneVersion: String(args.scene_version ?? '').trim() || undefined,
59
- objectiveId: String(args.objective_id ?? '').trim() || undefined,
60
- jobKind: args.job_kind,
61
- physicsManifest: args.physics_manifest,
62
- twinSnapshot: args.twin_snapshot,
63
- objectiveProfile: args.objective_profile,
64
- agent: { id: agentId },
65
- })
66
- const st = await runtimeStatus()
67
- return {
68
- text: [
69
- `训练作业已提交:`,
70
- ` job_id: ${job.id}`,
71
- ` dataset: ${job.datasetId} | purpose=${job.purpose} | seed=${fmtAmlNum(Number(job.budget.seed ?? 42), 0)} | change_note: ${changeNote}`,
72
- ` 队列: 排队 ${st.queued} 个(含本作业)/ 在跑 ${st.running} 个 | python ${st.python.ok ? (st.python.version ?? 'ok') : `不可用(${st.python.reason ?? '?'};作业会失败,请联系用户修复环境)`}`,
73
- `\n用 aml_job_status { job_id: "${job.id}" } 看状态/阶段/门禁,aml_job_logs { job_id: "${job.id}" } 看日志尾;训练完成后 aml_leaderboard 看谱系与门禁。`,
74
- ].join('\n'),
75
- }
76
- }
77
- catch (err) {
78
- return { text: `提交失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
79
- }
80
- }
81
-
82
- /** 工具:aml_job_status —— 作业状态(单作业详情 / 缺省列最近 10 个) */
83
- export async function toolAmlJobStatus(_agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
84
- const rt = getAmlRuntime()
85
- const jobId = String(args.job_id ?? '').trim()
86
- if (jobId) {
87
- const job = rt.repo.job.get(jobId)
88
- if (!job) return amlErr(`作业 ${jobId} 不存在(aml_job_status 不带参数可列出最近 10 个)。`)
89
- return { text: `${amlJobCard(job)}\n\n轮询建议:training 阶段 30~60s 查一次;终态(done/failed)后看门禁与错误,失败原因可 in aml_job_logs 定位。` }
90
- }
91
- const jobs = rt.repo.job.list({ limit: 10 })
92
- if (jobs.length === 0) {
93
- return { text: '尚无训练作业。路径:aml_node_catalog 确认节点 → aml_dataset_build 组数据集 → aml_job_submit 提交训练。' }
94
- }
95
- const rows = jobs.map(j => `- ${j.id} [${j.status}] ${j.stage || '-'} ${j.progress}% dataset=${j.datasetId}${j.error ? ` | 错误: ${j.error.slice(0, 100)}` : ''}`)
96
- return { text: `最近 ${jobs.length} 个作业(新→旧):\n${rows.join('\n')}\n\n传 job_id 查看单作业详情(指标/门禁逐项/错误)。` }
97
- }
98
-
99
- /** 工具:aml_job_logs —— 作业日志尾随(平台 ##AML 协议行 + 训练输出) */
100
- export async function toolAmlJobLogs(_agentId: string, args: { job_id?: string, lines?: number | string }): Promise<{ text: string, isError?: boolean }> {
101
- const jobId = String(args.job_id ?? '').trim()
102
- if (!jobId) return amlErr('job_id 必填(aml_job_status 不带参数可列出最近作业)。')
103
- const job = getAmlRuntime().repo.job.get(jobId)
104
- if (!job) return amlErr(`作业 ${jobId} 不存在。`)
105
- const n = Math.min(Math.max(Number(args.lines) || 80, 5), 400)
106
- const rows = jobLogsTail(jobId, n)
107
- if (rows.length === 0) {
108
- return { text: `作业 ${jobId} 暂无日志(${job.status === 'queued' ? '仍在排队,开跑后产生日志' : '日志未落盘或已被清理'});稍后重试或用 aml_job_status 看状态。` }
109
- }
110
- return { text: `作业 ${jobId} 日志尾(最近 ${rows.length} 行,时间正序;##AML 前缀行 = 平台协议事件):\n${rows.join('\n')}` }
111
- }
112
-
113
- /** 工具:aml_job_cancel —— 取消排队/运行中的作业(归因入册) */
114
- export async function toolAmlJobCancel(agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
115
- const jobId = String(args.job_id ?? '').trim()
116
- if (!jobId) return amlErr('job_id 必填。')
117
- const rt = getAmlRuntime()
118
- const job = rt.repo.job.get(jobId)
119
- if (!job) return amlErr(`作业 ${jobId} 不存在。`)
120
- if (['done', 'failed', 'cancelled', 'timeout'].includes(job.status)) {
121
- return amlErr(`作业 ${jobId} 已是终态(${job.status}),无需取消;aml_job_status 复核。`)
122
- }
123
- const ok = cancelJob(jobId, { id: agentId, kind: 'agent' })
124
- if (!ok) return amlErr(`取消失败:作业 ${jobId} 不在排队/运行中(可能恰好结束);aml_job_status 复核。`)
125
- const dataset = rt.repo.dataset.get(job.datasetId)
126
- recordOps({
127
- actor: agentId,
128
- actorName: agentBadgeLabel(agentId),
129
- actorKind: 'agent',
130
- action: 'aml.job.cancel',
131
- kind: AML_AUDIT_KIND,
132
- summary: `取消训练作业 ${jobId}(原状态 ${job.status})`,
133
- targetKind: 'aml_job',
134
- targetId: jobId,
135
- lineId: dataset?.lineId,
136
- productId: dataset?.productId,
137
- recipeId: dataset?.recipeId,
138
- })
139
- return { text: `作业 ${jobId} 已取消(运行中的会终止进程树)。数据集 ${job.datasetId} 仍可复用;需要重训直接 aml_job_submit。` }
140
- }
141
-
142
- /** 工具:aml_leaderboard —— 数据集的实验谱系与门禁对照(标当前最优) */
143
- export async function toolAmlLeaderboard(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
144
- const datasetId = String(args.dataset_id ?? '').trim()
145
- if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
146
- const rt = getAmlRuntime()
147
- const dataset = rt.repo.dataset.get(datasetId)
148
- if (!dataset) return amlErr(`数据集 ${datasetId} 不存在。`)
149
- const exps = rt.repo.experiment.listByDataset(datasetId, 50)
150
- if (exps.length === 0) {
151
- return { text: `数据集 ${datasetId}(${dataset.rowCount} 行)尚无实验:aml_job_submit 提交训练后,此处给出谱系与门禁对照。` }
152
- }
153
- const parsed = exps.map((e) => {
154
- let metrics: { oneStepTest?: { nrmse?: number }, rolloutTest?: { nrmse?: number } } = {}
155
- let gates: { passed?: boolean } = {}
156
- try {
157
- metrics = JSON.parse(e.metricsJson)
158
- }
159
- catch { /* 无指标 */ }
160
- try {
161
- gates = JSON.parse(e.gatesJson)
162
- }
163
- catch { /* 无门禁 */ }
164
- return { e, g1: metrics.oneStepTest?.nrmse ?? null, g2: metrics.rolloutTest?.nrmse ?? null, passed: gates.passed === true || e.status === 'gates_passed' }
165
- })
166
- const passers = parsed.filter(p => p.passed && p.g1 != null)
167
- const bestId = passers.length > 0 ? passers.reduce((a, b) => ((a.g1 ?? Infinity) <= (b.g1 ?? Infinity) ? a : b)).e.id : null
168
- const rows = parsed.map(p =>
169
- `- ${p.e.id} [${p.e.status}] ${p.e.changeNote ? `「${p.e.changeNote.slice(0, 60)}」` : '(无备注)'}${p.e.parentExperimentId ? ` ← 父 ${p.e.parentExperimentId}` : ''} | G1=${fmtAmlNum(p.g1)}${p.g2 != null ? ` G2=${fmtAmlNum(p.g2)}` : ''} | 门禁 ${p.passed ? '通过' : '未通过'}${p.e.id === bestId ? ' ★当前最优' : ''}`)
170
- const models = rt.repo.model.list({ limit: 100 }).filter(m => m.datasetId === datasetId)
171
- const modelLines = models.map(m => `- ${m.id} [${m.stage}] purpose=${m.purpose}(实验 ${m.experimentId})`)
172
- return {
173
- text: [
174
- `实验谱系(数据集 ${datasetId} · ${dataset.productId}/${dataset.recipeId} · ${exps.length} 条,新→旧):`,
175
- ...rows,
176
- modelLines.length > 0 ? `\n已登记模型(晋升对象;aml_leaderboard 最优 = 门禁通过且 G1 最小):` : null,
177
- ...modelLines,
178
- `\nG1=单步测试 NRMSE,G2=多步滚动 NRMSE(越小越好)。优化纪律:每次只改一个组件,change_note 写明;把最优模型推上生产用 aml_model_promote(lead 专属,需人工审批)。`,
179
- ].filter(x => x !== null).join('\n'),
180
- }
181
- }
182
-
183
- /** 工具:aml_model_promote —— 模型晋升 shadow/production(lead 专属;HITL 人工审批;流转入册由 transitionModel 内部完成) */
184
- export async function toolAmlModelPromote(agentId: string, args: { model_id?: string, to_stage?: string }): Promise<{ text: string, isError?: boolean }> {
185
- // 治理硬守卫:晋升仅限 lead 实例(注入层过滤 + 分发层双重校验,HTTP 直调不可绕过)
186
- const roleRow = getAmlRuntime().db.prepare('SELECT role FROM channel_agents WHERE id = ? AND enabled = 1').get(agentId) as { role?: string } | undefined
187
- if (roleRow?.role !== 'lead') {
188
- return amlErr(`aml_model_promote 为 lead 专属工具:实例 ${agentId}(role=${roleRow?.role ?? '未知'})无权晋升模型。请由团队 lead 发起,晋升需人工 HITL 批准。`)
189
- }
190
- const modelId = String(args.model_id ?? '').trim()
191
- const toStage = String(args.to_stage ?? '').trim()
192
- if (!modelId) return amlErr('model_id 必填(aml_leaderboard 的「已登记模型」段可查)。')
193
- if (toStage !== 'shadow' && toStage !== 'production') return amlErr('to_stage 必须为 \'shadow\'(影子观测)或 \'production\'(生产生效)。')
194
- const rt = getAmlRuntime()
195
- const model = rt.repo.model.get(modelId)
196
- if (!model) return amlErr(`模型 ${modelId} 不存在。`)
197
- if (model.stage === toStage) return amlErr(`模型 ${modelId} 已是 ${toStage},无需流转。`)
198
- // production 预检:同组 (product, recipe, purpose) 旧生产将被退役
199
- let oldProdId: string | undefined
200
- if (toStage === 'production') {
201
- oldProdId = rt.repo.model
202
- .list({ stage: 'production', productId: model.productId, recipeId: model.recipeId, limit: 50 })
203
- .find(m => m.id !== modelId && m.purpose === model.purpose)?.id
204
- }
205
- // 同模型挂起审批去重(防审批面板堆积,与 dcw_control 同纪律)
206
- const approvals = getToolApprovals()
207
- if (approvals.hasPendingFor(agentId, modelId)) {
208
- return amlErr(`模型 ${modelId} 已有一条待审批的晋升请求,请等待用户处理后再发起新请求。`)
209
- }
210
- const detail = `AML 模型晋升:${modelId} ${model.stage} → ${toStage}(产品 ${model.productId} / 配方 ${model.recipeId} / purpose=${model.purpose}${oldProdId ? `;批准后原生产模型 ${oldProdId} 将自动退役` : ''})`
211
- const ap = await approvals.request(agentId, modelId, 'dcw', detail, { title: 'AML 模型晋升审批' })
212
- if (!ap.approved) {
213
- return { text: `人工未批准:模型 ${modelId} 保持 ${model.stage} 阶段。用户备注:${ap.comment || '(无)'}。可回炉重训(aml_job_submit)或换候选模型后再申请。` }
214
- }
215
- try {
216
- const r = transitionModel(modelId, toStage, agentBadgeLabel(agentId), 'agent')
217
- // 归属审计已由 transitionModel 内部 recordOps(aml.model.promote)完成,此处不重复记录
218
- return {
219
- text: `晋升完成:${modelId} ${r.from} → ${toStage}。${r.retiredId ? `原生产模型 ${r.retiredId} 已自动退役。` : ''}${toStage === 'shadow'
220
- ? '影子阶段:用 aml_model_reference 观测其预测与实际偏差,积累证据后再申请 production。'
221
- : '该模型已作为生产模型生效:aml_model_reference 的影子参考即来自它;调控 Agent 调参前请先查它。'}`,
222
- }
223
- }
224
- catch (err) {
225
- return { text: `晋升失败:${err instanceof Error ? err.message : String(err)}(审批已通过;若为并发竞态可刷新状态重试)。`, isError: true }
226
- }
227
- }
228
-
229
- /** 工具:aml_model_reference —— 生产模型影子参考:拉最近历史组装模型输入 → 预测未来目标轨迹(调参前先问影子模型) */
230
- export async function toolAmlModelReference(agentId: string, args: {
231
- line_id?: string
232
- product_id?: string
233
- recipe_id?: string
234
- purpose?: string
235
- controls?: Record<string, number | string>
236
- steps?: number | string
237
- }): Promise<{ text: string, isError?: boolean }> {
238
- // 0. 绑定面:至少一个 daq 绑定;line_id 只缩不放
239
- const repo = getAgentNodeBindingRepo()
240
- const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
241
- if (daqBindings.length === 0) {
242
- return amlErr('你尚未绑定任何数采节点,无法组装影子参考所需的历史输入;请先绑定数采节点。')
243
- }
244
- const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
245
- const scopeLines = [...new Set(daqBindings.map(b => lineOf(b.nodeId)).filter(Boolean))]
246
- const lineFilter = String(args.line_id ?? '').trim()
247
- if (lineFilter && !scopeLines.includes(lineFilter)) {
248
- return amlErr(`产线 ${lineFilter} 不在你的负责范围(你绑定节点覆盖:${scopeLines.join(', ') || '无'};绑定只缩不放)。`)
249
- }
250
- const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
251
-
252
- // 1. 解析 (productId, recipeId):参数给全用参数;缺省回退到候选产线的唯一活动批次
253
- let productId = String(args.product_id ?? '').trim()
254
- let recipeId = String(args.recipe_id ?? '').trim()
255
- let resolveHow = '参数指定'
256
- if (!productId || !recipeId) {
257
- const candidateLines = lineFilter ? [lineFilter] : scopeLines
258
- const runs = candidateLines
259
- .map(lid => getActiveLineRun(lid))
260
- .filter((r): r is NonNullable<ReturnType<typeof getActiveLineRun>> => !!r && !!r.productId && !!r.recipeId)
261
- if (runs.length === 1) {
262
- const run = runs[0]!
263
- if (!productId) productId = run.productId
264
- if (!recipeId) recipeId = run.recipeId
265
- resolveHow = `产线 ${run.lineId} 唯一活动批次 ${run.runId.slice(0, 8)}(产品「${run.productName}」/配方「${run.recipeName}」)`
266
- }
267
- else if (runs.length === 0) {
268
- return { text: `无法确定产品/配方:${candidateLines.length > 0 ? `产线 ${candidateLines.join(', ')}` : '你绑定节点所属产线'}当前无活动批次,且 product_id/recipe_id 未给全。请开跑后重试,或显式传 product_id 与 recipe_id(line_context 可查)。`, isError: true }
269
- }
270
- else {
271
- return { text: `无法确定产品/配方:候选产线存在多个活动批次(${runs.map(r => `${r.lineId} → ${r.productName}/${r.recipeName}`).join('; ')})。请传 line_id 缩小范围,或显式传 product_id 与 recipe_id。`, isError: true }
272
- }
273
- }
274
-
275
- // 2. 生产模型(无则指引建模范式)
276
- const rt = getAmlRuntime()
277
- const model = rt.repo.model.productionOf(productId, recipeId, purpose)
278
- if (!model) {
279
- const cands = rt.repo.model.list({ productId, recipeId, limit: 20 })
280
- return { text: `尚无生产模型:(${productId}, ${recipeId}, ${purpose}) 下没有 stage=production 的模型。${cands.length > 0 ? `现有候选:${cands.map(m => `${m.id}(${m.stage})`).join(', ')} —— 请 lead 用 aml_model_promote 晋升(需人工审批)。` : '该三元组下还没有任何模型:aml_dataset_build → aml_job_submit 训练,门禁通过后申请晋升。在此之前调参请依据 dcw_journal 历史经验与 daq_query 证据。'}` }
281
- }
282
- // 3. 产线归属鉴权(绑定只缩不放;模型归属线经数据集追溯)
283
- const ds = rt.repo.dataset.get(model.datasetId)
284
- const modelLine = ds?.lineId ?? ''
285
- if (modelLine && !scopeLines.includes(modelLine)) {
286
- return amlErr(`模型 ${model.id} 归属产线 ${modelLine},不在你绑定节点覆盖的产线(${scopeLines.join(', ')})内;绑定只缩不放。`)
287
- }
288
-
289
- // 4. io 契约 → 拉最近历史 → 网格对齐 → 组 [H][nAll](原始物理量,顺序 = allNodes)
290
- const io = readIoSpecFor(model.id)
291
- const H = io.historySteps
292
- const beatMs = io.beatMs
293
- const now = Date.now()
294
- const fromMs = now - H * beatMs - 5 * beatMs
295
- const { getTsdb, tsdbReady } = await import('../../daq/storage')
296
- await tsdbReady
297
- const tsdb = getTsdb()
298
- const columns = new Map<string, number[]>()
299
- const shortage: string[] = []
300
- for (const nodeId of io.allNodes) {
301
- try {
302
- const pts = await tsdb.query(nodeId, { fromMs, toMs: now, limit: Math.min(Math.max(H * 10, 600), 5000) })
303
- const { grid } = alignToGrid(
304
- pts.map(p => ({ at: p.at, value: p.value ?? p.avg ?? 0 })).filter(p => Number.isFinite(p.value)),
305
- { beatMs, maxInterpMs: beatMs * 2 },
306
- )
307
- const tail = grid.slice(-H).map(g => g.value)
308
- if (tail.length < H) {
309
- shortage.push(`${amlNodeName(nodeId)}(${nodeId})仅 ${tail.length}/${H} 格点`)
310
- continue
311
- }
312
- columns.set(nodeId, tail)
313
- }
314
- catch (err) {
315
- shortage.push(`${amlNodeName(nodeId)}(${nodeId})查询失败:${err instanceof Error ? err.message : String(err)}`)
316
- }
317
- }
318
- if (shortage.length > 0) {
319
- return { text: `历史数据不足,无法组装模型输入:${shortage.join(';')}。需要从 ${new Date(fromMs).toISOString().slice(0, 16)} 起连续约 ${(H * beatMs / 60_000).toFixed(0)} 分钟的运行数据(产线须在跑);等数据积累后重试,或缩短 steps/换更短 history 的模型。`, isError: true }
320
- }
321
- const history: number[][] = []
322
- for (let i = 0; i < H; i++) history.push(io.allNodes.map(n => columns.get(n)![i]!))
323
-
324
- // 5. 控制轨迹:controls 映射(节点 id → 值,常数外推 steps 行);缺省行持最后观测
325
- const steps = Math.max(1, Math.min(Number(args.steps) || io.horizonSteps, io.horizonSteps))
326
- const lastRow = history[history.length - 1]!
327
- const unknownKeys = args.controls ? Object.keys(args.controls).filter(k => !io.controlNodes.includes(k)) : []
328
- const controlRow = io.controlNodes.map((c) => {
329
- const provided = args.controls?.[c]
330
- const v = provided != null ? Number(provided) : Number.NaN
331
- return Number.isFinite(v) ? v : lastRow[io.allNodes.indexOf(c)]!
332
- })
333
- const controls: number[][] = Array.from({ length: steps }, () => [...controlRow])
334
-
335
- // 6. 预测 + 人话报告
336
- try {
337
- const r = await predictProduction(productId, recipeId, purpose, { history, controls, steps })
338
- const header = `步 | ${r.targetNodes.map(t => `${amlNodeName(t)}(${amlNodeUnit(t)})`).join(' | ')}`
339
- const forecastLines = r.forecast.map((row, i) =>
340
- ` ${i + 1}(+${fmtAmlNum(((i + 1) * r.beatMs) / 1000, 0)}s) | ${row.map(v => fmtAmlNum(v, 3)).join(' | ')}`)
341
- const ctrlTxt = io.controlNodes.length > 0
342
- ? io.controlNodes.map((c) => {
343
- const provided = args.controls?.[c]
344
- return `${amlNodeName(c)}=${Number.isFinite(Number(provided)) ? Number(provided) : `${fmtAmlNum(lastRow[io.allNodes.indexOf(c)], 3)}(持最后观测)`}${amlNodeUnit(c)}`
345
- }).join(', ')
346
- : '无控制节点'
347
- return {
348
- text: [
349
- `影子模型参考(调参前先问影子模型;预测≠承诺,真实下发仍走 dcw_control 安全联锁):`,
350
- ` 模型 ${r.modelId}(stage=${r.stage},purpose=${purpose})| 三元组:产品 ${getDcwProductRepo().byId(productId)?.name ?? productId} / 配方 ${getDcwRecipeRepo().byId(recipeId)?.name ?? recipeId}(解析:${resolveHow})`,
351
- ` 输入:最近 ${H} 拍 × ${io.allNodes.length} 节点(beat=${beatMs}ms),截至 ${new Date(now).toISOString().slice(11, 19)};控制轨迹(共 ${steps} 步):${ctrlTxt}${unknownKeys.length > 0 ? `(已忽略非控制节点的键:${unknownKeys.join(', ')})` : ''}`,
352
- ` 预测(steps=${steps},每拍 ${beatMs / 1000}s):`,
353
- ` ${header}`,
354
- ...forecastLines,
355
- ` 假设: ${r.assumptions}`,
356
- `\n用法:把候选设定值作为 controls 传入(键 = 控制节点 id)对比不同方案的预测轨迹;选定后 dcw_control 下发并 daq_query 复测。`,
357
- ].join('\n'),
358
- }
359
- }
360
- catch (err) {
361
- return { text: `预测失败:${err instanceof Error ? err.message : String(err)}(模型 ${model.id};若为工件缺失可重训同规格数据集)。`, isError: true }
362
- }
363
- }
1
+ /**
2
+ * AML 作业与模型(aml_job_* / aml_leaderboard / aml_model_*)
3
+ * (由 server/services/workshop/agents/industrial-tools.ts 按职责拆出;内容逐行原文搬运)
4
+ */
5
+ import { AML_AUDIT_KIND, amlErr, amlJobCard, amlNodeName, amlNodeUnit, fmtAmlNum } from './aml-dataset-tools'
6
+ import { agentBadgeLabel } from '../agent-badge'
7
+ import { alignToGrid } from '../../aml/clean'
8
+ import { cancelJob, jobLogsTail, runtimeStatus, submitJob } from '../../aml/job-orchestrator'
9
+ import { getActiveLineRun } from '../../dcw/line-run'
10
+ import { getAgentNodeBindingRepo } from '../node-bindings.repo'
11
+ import { getAmlRuntime } from '../../aml/runtime'
12
+ import { getDaqNodeRepo } from '../../daq/daq-node.repo'
13
+ import { createTrainingPlan, listTrainingPlans, runPlanTraining } from '../../aml/twin/training-plans'
14
+ import { getDcwProductRepo } from '../../dcw/dcw-product.repo'
15
+ import { getDcwRecipeRepo } from '../../dcw/dcw-recipe.repo'
16
+ import { getToolApprovals } from '../tool-approvals'
17
+ import { predictProduction, readIoSpecFor } from '../../aml/predictor'
18
+ import { recordOps } from '../../ops/ops'
19
+ import { transitionModel } from '../../aml/model-registry'
20
+
21
+ /** 工具:aml_job_submit —— 提交训练作业(train.py 全文内联;归因 agentId;队列 FIFO) */
22
+ export async function toolAmlJobSubmit(agentId: string, args: {
23
+ dataset_id?: string
24
+ code?: string
25
+ change_note?: string
26
+ params?: Record<string, unknown>
27
+ seed?: number | string
28
+ purpose?: string
29
+ parent_experiment_id?: string
30
+ scene_id?: string
31
+ scene_version?: string
32
+ objective_id?: string
33
+ job_kind?: 'supervised' | 'physics_calibration' | 'hybrid_residual' | 'uncertainty_calibration'
34
+ physics_manifest?: Record<string, unknown>
35
+ physics_spec?: Record<string, unknown>
36
+ twin_snapshot?: Record<string, unknown>
37
+ objective_profile?: Record<string, unknown>
38
+ provider_id?: string
39
+ provider_version?: string
40
+ provider_hash?: string
41
+ provider_generation?: number | string
42
+ model_name?: string
43
+ model_description?: string
44
+ }): Promise<{ text: string, isError?: boolean }> {
45
+ const datasetId = String(args.dataset_id ?? '').trim()
46
+ const code = typeof args.code === 'string' ? args.code : ''
47
+ if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
48
+ const templateFallback = args.job_kind === 'hybrid_residual' && !code.trim()
49
+ if (!templateFallback && !code.trim()) return amlErr('code 必填:train.py 全文(单文件;契约见工具说明)。例外:job_kind=hybrid_residual 可省略 code,平台用内置参考训练器(物理参数校准→残差集成→UQ)。')
50
+ if (code.length > 512_000) return amlErr(`code 过大(${Math.round(code.length / 1024)}KB),上限 500KB;精简训练代码(模型定义/训练循环拆薄)后重试。`)
51
+ if (!templateFallback && !/\bimport\s+amlkit\b/.test(code)) {
52
+ return amlErr('code 必须 import amlkit(平台数据/进度/导出契约):amlkit.load_bundle(datasetPath) 取数、amlkit.report_progress(pct, note) 报进度、amlkit.export_torch_onnx(model, manifest) 导出。缺契约的作业必然失败。')
53
+ }
54
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : args.purpose === 'mpc_surrogate' ? 'mpc_surrogate' : undefined
55
+ const changeNote = String(args.change_note ?? '').trim()
56
+ if (!changeNote) return amlErr('change_note 必填:单组件改动纪律 —— 每次实验只改一个组件(网络结构/特征/超参之一),写清改了什么与预期,实验谱系靠它归因。')
57
+ try {
58
+ const job = submitJob({
59
+ datasetId,
60
+ purpose,
61
+ changeNote,
62
+ params: args.params && typeof args.params === 'object' && !Array.isArray(args.params) ? args.params : undefined,
63
+ seed: Number.isInteger(Number(args.seed)) ? Number(args.seed) : undefined,
64
+ parentExperimentId: String(args.parent_experiment_id ?? '').trim() || undefined,
65
+ code,
66
+ sceneId: String(args.scene_id ?? '').trim() || undefined,
67
+ sceneVersion: String(args.scene_version ?? '').trim() || undefined,
68
+ objectiveId: String(args.objective_id ?? '').trim() || undefined,
69
+ jobKind: args.job_kind,
70
+ physicsManifest: args.physics_manifest,
71
+ physicsSpec: args.physics_spec,
72
+ twinSnapshot: args.twin_snapshot,
73
+ objectiveProfile: args.objective_profile,
74
+ providerId: String(args.provider_id ?? '').trim() || undefined,
75
+ providerVersion: String(args.provider_version ?? '').trim() || undefined,
76
+ providerHash: String(args.provider_hash ?? '').trim() || undefined,
77
+ providerGeneration: Number.isInteger(Number(args.provider_generation)) ? Number(args.provider_generation) : undefined,
78
+ modelName: String(args.model_name ?? '').trim() || undefined,
79
+ modelDescription: String(args.model_description ?? '').trim() || undefined,
80
+ agent: { id: agentId },
81
+ })
82
+ const st = await runtimeStatus()
83
+ return {
84
+ text: [
85
+ `训练作业已提交:`,
86
+ ` job_id: ${job.id}`,
87
+ ` dataset: ${job.datasetId} | purpose=${job.purpose} | seed=${fmtAmlNum(Number(job.budget.seed ?? 42), 0)} | change_note: ${changeNote}`,
88
+ args.model_name || args.model_description ? ` 模型标识: name=${String(args.model_name ?? '(缺省派生)')} | description=${String(args.model_description ?? '(缺省派生)').slice(0, 80) || '(缺省派生)'}` : ` 模型标识: 注册时自动派生「产线·配方·优化目标」label(可传 model_name/model_description 自拟)`,
89
+ ` 队列: 排队 ${st.queued} 个(含本作业)/ 在跑 ${st.running} 个 | python ${st.python.ok ? (st.python.version ?? 'ok') : `不可用(${st.python.reason ?? '?'};作业会失败,请联系用户修复环境)`}`,
90
+ `\n用 aml_job_status { job_id: "${job.id}" } 看状态/阶段/门禁,aml_job_logs { job_id: "${job.id}" } 看日志尾;训练完成后 aml_leaderboard 看谱系与门禁。`,
91
+ ].join('\n'),
92
+ }
93
+ }
94
+ catch (err) {
95
+ return { text: `提交失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
96
+ }
97
+ }
98
+
99
+ /** 工具:aml_job_status —— 作业状态(单作业详情 / 缺省列最近 10 个) */
100
+ export async function toolAmlJobStatus(_agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
101
+ const rt = getAmlRuntime()
102
+ const jobId = String(args.job_id ?? '').trim()
103
+ if (jobId) {
104
+ const job = rt.repo.job.get(jobId)
105
+ if (!job) return amlErr(`作业 ${jobId} 不存在(aml_job_status 不带参数可列出最近 10 个)。`)
106
+ return { text: `${amlJobCard(job)}\n\n轮询建议:training 阶段 30~60s 查一次;终态(done/failed)后看门禁与错误,失败原因可 in aml_job_logs 定位。` }
107
+ }
108
+ const jobs = rt.repo.job.list({ limit: 10 })
109
+ if (jobs.length === 0) {
110
+ return { text: '尚无训练作业。路径:aml_node_catalog 确认节点 → aml_dataset_build 组数据集 → aml_job_submit 提交训练。' }
111
+ }
112
+ const rows = jobs.map(j => `- ${j.id} [${j.status}] ${j.stage || '-'} ${j.progress}% dataset=${j.datasetId}${j.error ? ` | 错误: ${j.error.slice(0, 100)}` : ''}`)
113
+ return { text: `最近 ${jobs.length} 个作业(新→旧):\n${rows.join('\n')}\n\n传 job_id 查看单作业详情(指标/门禁逐项/错误)。` }
114
+ }
115
+
116
+ /** 工具:aml_job_logs —— 作业日志尾随(平台 ##AML 协议行 + 训练输出) */
117
+ export async function toolAmlJobLogs(_agentId: string, args: { job_id?: string, lines?: number | string }): Promise<{ text: string, isError?: boolean }> {
118
+ const jobId = String(args.job_id ?? '').trim()
119
+ if (!jobId) return amlErr('job_id 必填(aml_job_status 不带参数可列出最近作业)。')
120
+ const job = getAmlRuntime().repo.job.get(jobId)
121
+ if (!job) return amlErr(`作业 ${jobId} 不存在。`)
122
+ const n = Math.min(Math.max(Number(args.lines) || 80, 5), 400)
123
+ const rows = jobLogsTail(jobId, n)
124
+ if (rows.length === 0) {
125
+ return { text: `作业 ${jobId} 暂无日志(${job.status === 'queued' ? '仍在排队,开跑后产生日志' : '日志未落盘或已被清理'});稍后重试或用 aml_job_status 看状态。` }
126
+ }
127
+ return { text: `作业 ${jobId} 日志尾(最近 ${rows.length} 行,时间正序;##AML 前缀行 = 平台协议事件):\n${rows.join('\n')}` }
128
+ }
129
+
130
+ /** 工具:aml_job_cancel —— 取消排队/运行中的作业(归因入册) */
131
+ export async function toolAmlJobCancel(agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
132
+ const jobId = String(args.job_id ?? '').trim()
133
+ if (!jobId) return amlErr('job_id 必填。')
134
+ const rt = getAmlRuntime()
135
+ const job = rt.repo.job.get(jobId)
136
+ if (!job) return amlErr(`作业 ${jobId} 不存在。`)
137
+ if (['done', 'failed', 'cancelled', 'timeout'].includes(job.status)) {
138
+ return amlErr(`作业 ${jobId} 已是终态(${job.status}),无需取消;aml_job_status 复核。`)
139
+ }
140
+ const ok = cancelJob(jobId, { id: agentId, kind: 'agent' })
141
+ if (!ok) return amlErr(`取消失败:作业 ${jobId} 不在排队/运行中(可能恰好结束);aml_job_status 复核。`)
142
+ const dataset = rt.repo.dataset.get(job.datasetId)
143
+ recordOps({
144
+ actor: agentId,
145
+ actorName: agentBadgeLabel(agentId),
146
+ actorKind: 'agent',
147
+ action: 'aml.job.cancel',
148
+ kind: AML_AUDIT_KIND,
149
+ summary: `取消训练作业 ${jobId}(原状态 ${job.status})`,
150
+ targetKind: 'aml_job',
151
+ targetId: jobId,
152
+ lineId: dataset?.lineId,
153
+ productId: dataset?.productId,
154
+ recipeId: dataset?.recipeId,
155
+ })
156
+ return { text: `作业 ${jobId} 已取消(运行中的会终止进程树)。数据集 ${job.datasetId} 仍可复用;需要重训直接 aml_job_submit。` }
157
+ }
158
+
159
+ /** 工具:aml_leaderboard —— 数据集的实验谱系与门禁对照(标当前最优) */
160
+ export async function toolAmlLeaderboard(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
161
+ const datasetId = String(args.dataset_id ?? '').trim()
162
+ if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
163
+ const rt = getAmlRuntime()
164
+ const dataset = rt.repo.dataset.get(datasetId)
165
+ if (!dataset) return amlErr(`数据集 ${datasetId} 不存在。`)
166
+ const exps = rt.repo.experiment.listByDataset(datasetId, 50)
167
+ if (exps.length === 0) {
168
+ return { text: `数据集 ${datasetId}(${dataset.rowCount} 行)尚无实验:aml_job_submit 提交训练后,此处给出谱系与门禁对照。` }
169
+ }
170
+ const parsed = exps.map((e) => {
171
+ let metrics: { oneStepTest?: { nrmse?: number }, rolloutTest?: { nrmse?: number } } = {}
172
+ let gates: { passed?: boolean } = {}
173
+ try {
174
+ metrics = JSON.parse(e.metricsJson)
175
+ }
176
+ catch { /* 无指标 */ }
177
+ try {
178
+ gates = JSON.parse(e.gatesJson)
179
+ }
180
+ catch { /* 无门禁 */ }
181
+ return { e, g1: metrics.oneStepTest?.nrmse ?? null, g2: metrics.rolloutTest?.nrmse ?? null, passed: gates.passed === true || e.status === 'gates_passed' }
182
+ })
183
+ const passers = parsed.filter(p => p.passed && p.g1 != null)
184
+ const bestId = passers.length > 0 ? passers.reduce((a, b) => ((a.g1 ?? Infinity) <= (b.g1 ?? Infinity) ? a : b)).e.id : null
185
+ const rows = parsed.map(p =>
186
+ `- ${p.e.id} [${p.e.status}] ${p.e.changeNote ? `「${p.e.changeNote.slice(0, 60)}」` : '(无备注)'}${p.e.parentExperimentId ? ` ← 父 ${p.e.parentExperimentId}` : ''} | G1=${fmtAmlNum(p.g1)}${p.g2 != null ? ` G2=${fmtAmlNum(p.g2)}` : ''} | 门禁 ${p.passed ? '通过' : '未通过'}${p.e.id === bestId ? ' ★当前最优' : ''}`)
187
+ const models = rt.repo.model.list({ limit: 100 }).filter(m => m.datasetId === datasetId)
188
+ const modelLines = models.map(m => `- ${m.id} [${m.stage}] 「${m.label || '(未打标)'}」 purpose=${m.purpose}${m.objectiveId ? ` objective=${m.objectiveId}` : ''}(实验 ${m.experimentId})`)
189
+ return {
190
+ text: [
191
+ `实验谱系(数据集 ${datasetId} · ${dataset.productId}/${dataset.recipeId} · ${exps.length} 条,新→旧):`,
192
+ ...rows,
193
+ modelLines.length > 0 ? `\n已登记模型(晋升对象;aml_leaderboard 最优 = 门禁通过且 G1 最小):` : null,
194
+ ...modelLines,
195
+ `\nG1=单步测试 NRMSE,G2=多步滚动 NRMSE(越小越好)。优化纪律:每次只改一个组件,change_note 写明;把最优模型推上生产用 aml_model_promote(lead 专属,需人工审批)。`,
196
+ ].filter(x => x !== null).join('\n'),
197
+ }
198
+ }
199
+
200
+ /** 工具:aml_model_promote —— 模型晋升 shadow/production(lead 专属;HITL 人工审批;流转入册由 transitionModel 内部完成) */
201
+ export async function toolAmlModelPromote(agentId: string, args: { model_id?: string, to_stage?: string }): Promise<{ text: string, isError?: boolean }> {
202
+ // 治理硬守卫:晋升仅限 lead 实例(注入层过滤 + 分发层双重校验,HTTP 直调不可绕过)
203
+ const roleRow = getAmlRuntime().db.prepare('SELECT role FROM channel_agents WHERE id = ? AND enabled = 1').get(agentId) as { role?: string } | undefined
204
+ if (roleRow?.role !== 'lead') {
205
+ return amlErr(`aml_model_promote 为 lead 专属工具:实例 ${agentId}(role=${roleRow?.role ?? '未知'})无权晋升模型。请由团队 lead 发起,晋升需人工 HITL 批准。`)
206
+ }
207
+ const modelId = String(args.model_id ?? '').trim()
208
+ const toStage = String(args.to_stage ?? '').trim()
209
+ if (!modelId) return amlErr('model_id 必填(aml_leaderboard 的「已登记模型」段可查)。')
210
+ if (toStage !== 'shadow' && toStage !== 'production') return amlErr('to_stage 必须为 \'shadow\'(影子观测)或 \'production\'(生产生效)。')
211
+ const rt = getAmlRuntime()
212
+ const model = rt.repo.model.get(modelId)
213
+ if (!model) return amlErr(`模型 ${modelId} 不存在。`)
214
+ if (model.stage === toStage) return amlErr(`模型 ${modelId} 已是 ${toStage},无需流转。`)
215
+ // production 预检:同组 (product, recipe, purpose) 旧生产将被退役
216
+ let oldProdId: string | undefined
217
+ if (toStage === 'production') {
218
+ oldProdId = rt.repo.model
219
+ .list({ stage: 'production', productId: model.productId, recipeId: model.recipeId, limit: 50 })
220
+ .find(m => m.id !== modelId && m.purpose === model.purpose)?.id
221
+ }
222
+ // 同模型挂起审批去重(防审批面板堆积,与 dcw_control 同纪律)
223
+ const approvals = getToolApprovals()
224
+ if (approvals.hasPendingFor(agentId, modelId)) {
225
+ return amlErr(`模型 ${modelId} 已有一条待审批的晋升请求,请等待用户处理后再发起新请求。`)
226
+ }
227
+ const detail = `AML 模型晋升:${modelId} ${model.stage} → ${toStage}「${model.label || '(未打标)'}」(产线 ${model.lineId || rt.repo.dataset.get(model.datasetId)?.lineId || '?'} / 产品 ${model.productId} / 配方 ${model.recipeId} / purpose=${model.purpose}${model.objectiveId ? ` / objective=${model.objectiveId}` : ''}${oldProdId ? `;批准后原生产模型 ${oldProdId} 将自动退役` : ''})`
228
+ const ap = await approvals.request(agentId, modelId, 'dcw', detail, { title: 'AML 模型晋升审批' })
229
+ if (!ap.approved) {
230
+ return { text: `人工未批准:模型 ${modelId} 保持 ${model.stage} 阶段。用户备注:${ap.comment || '(无)'}。可回炉重训(aml_job_submit)或换候选模型后再申请。` }
231
+ }
232
+ try {
233
+ const r = transitionModel(modelId, toStage, agentBadgeLabel(agentId), 'agent')
234
+ // 归属审计已由 transitionModel 内部 recordOps(aml.model.promote)完成,此处不重复记录
235
+ return {
236
+ text: `晋升完成:${modelId} ${r.from} → ${toStage}。${r.retiredId ? `原生产模型 ${r.retiredId} 已自动退役。` : ''}${toStage === 'shadow'
237
+ ? '影子阶段:用 aml_model_reference 观测其预测与实际偏差,积累证据后再申请 production。'
238
+ : '该模型已作为生产模型生效:aml_model_reference 的影子参考即来自它;调控 Agent 调参前请先查它。'}`,
239
+ }
240
+ }
241
+ catch (err) {
242
+ return { text: `晋升失败:${err instanceof Error ? err.message : String(err)}(审批已通过;若为并发竞态可刷新状态重试)。`, isError: true }
243
+ }
244
+ }
245
+
246
+ /** 工具:aml_model_find —— 模型发现与选型(按产线/产品/配方/目标/阶段过滤;复用 vs 新建决策指引) */
247
+ export async function toolAmlModelFind(agentId: string, args: {
248
+ line_id?: string
249
+ product_id?: string
250
+ recipe_id?: string
251
+ purpose?: string
252
+ objective_id?: string
253
+ stage?: string
254
+ }): Promise<{ text: string, isError?: boolean }> {
255
+ // 0. 绑定面:与 aml_model_reference 同纪律 —— 至少一个 daq 绑定;line_id 只缩不放
256
+ const repo = getAgentNodeBindingRepo()
257
+ const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
258
+ if (daqBindings.length === 0) {
259
+ return amlErr('你尚未绑定任何数采节点,无法确定可查的产线范围;请先绑定数采节点。')
260
+ }
261
+ const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
262
+ const scopeLines = [...new Set(daqBindings.map(b => lineOf(b.nodeId)).filter(Boolean))]
263
+ const lineFilter = String(args.line_id ?? '').trim()
264
+ if (lineFilter && !scopeLines.includes(lineFilter)) {
265
+ return amlErr(`产线 ${lineFilter} 不在你的负责范围(你绑定节点覆盖:${scopeLines.join(', ') || '无'};绑定只缩不放)。`)
266
+ }
267
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : args.purpose === 'mpc_surrogate' ? 'mpc_surrogate' : undefined
268
+ const stage = ['candidate', 'shadow', 'production', 'retired'].includes(String(args.stage ?? '')) ? String(args.stage) : undefined
269
+ const productFilter = String(args.product_id ?? '').trim() || undefined
270
+ const recipeFilter = String(args.recipe_id ?? '').trim() || undefined
271
+ const objectiveFilter = String(args.objective_id ?? '').trim() || undefined
272
+
273
+ // 1. 拉全量后在代码层过滤(模型行 line_id 对历史行为空,经数据集回补;绑定只缩不放)
274
+ const rt = getAmlRuntime()
275
+ const models = rt.repo.model.list({ stage, purpose, limit: 200 }).filter((m) => {
276
+ const ds = rt.repo.dataset.get(m.datasetId)
277
+ const modelLine = m.lineId || ds?.lineId || ''
278
+ if (lineFilter ? modelLine !== lineFilter : (modelLine && !scopeLines.includes(modelLine))) return false
279
+ if (productFilter && m.productId !== productFilter) return false
280
+ if (recipeFilter && m.recipeId !== recipeFilter) return false
281
+ if (objectiveFilter && m.objectiveId !== objectiveFilter) return false
282
+ return true
283
+ })
284
+ if (models.length === 0) {
285
+ return {
286
+ text: [
287
+ `过滤条件下(${[lineFilter || `产线∈{${scopeLines.join(', ')}}`, productFilter, recipeFilter, purpose, objectiveFilter && `objective=${objectiveFilter}`, stage].filter(Boolean).join(', ')})没有匹配模型。`,
288
+ `新建路径:aml_node_catalog → aml_dataset_build(绑定产线的配方批次组数据集)→ aml_job_submit 提交训练(建议带 model_name/model_description 打标)。`,
289
+ `注意:模型按 (产品, 配方, purpose) 隔离 —— 换配方必须为该配方另建模型,不可跨配方复用。`,
290
+ ].join('\n'),
291
+ }
292
+ }
293
+
294
+ // 2. 分组呈现:production 置顶(可直接复用)→ shadow/candidate(晋升对象)→ retired 计数
295
+ const fmtG = (metricsJson: string): string => {
296
+ try {
297
+ const m = JSON.parse(metricsJson) as { oneStepTest?: { nrmse?: number }, rolloutTest?: { nrmse?: number } }
298
+ return `G1=${fmtAmlNum(m.oneStepTest?.nrmse ?? null)}${m.rolloutTest?.nrmse != null ? ` G2=${fmtAmlNum(m.rolloutTest.nrmse)}` : ''}`
299
+ }
300
+ catch { return 'G1=- G2=-' }
301
+ }
302
+ const prods = models.filter(m => m.stage === 'production')
303
+ const cands = models.filter(m => m.stage === 'shadow' || m.stage === 'candidate')
304
+ const retiredCount = models.filter(m => m.stage === 'retired').length
305
+ const rowOf = (m: typeof models[number]): string => {
306
+ const lineId = m.lineId || rt.repo.dataset.get(m.datasetId)?.lineId || '?'
307
+ const desc = m.description ? ` | ${m.description.slice(0, 120)}` : ''
308
+ return `- ${m.id} [${m.stage}] 「${m.label || '(未打标)'}」 purpose=${m.purpose}${m.objectiveId ? ` objective=${m.objectiveId}` : ''} | 产线 ${lineId} | ${fmtG(m.metricsJson)}${desc}`
309
+ }
310
+ const sections: string[] = []
311
+ sections.push(`匹配 ${models.length} 个模型(过滤:${[lineFilter || `产线∈{${scopeLines.join(', ')}}`, productFilter, recipeFilter, purpose, objectiveFilter && `objective=${objectiveFilter}`, stage].filter(Boolean).join(', ')})`)
312
+ if (prods.length > 0) {
313
+ sections.push(`\n生产模型(可直接复用):`)
314
+ sections.push(...prods.map(rowOf))
315
+ }
316
+ if (cands.length > 0) {
317
+ sections.push(`\n候选/影子(晋升对象;aml_model_promote 为 lead 专属,需人工审批):`)
318
+ sections.push(...cands.map(rowOf))
319
+ }
320
+ if (retiredCount > 0) sections.push(`\n另有 ${retiredCount} 个已退役模型(stage 过滤可查)。`)
321
+
322
+ // 3. 决策指引:按本次优化目标给出 复用 / 晋升 / 新建 三分支
323
+ const tips: string[] = []
324
+ if (prods.some(m => (!productFilter || m.productId === productFilter) && (!recipeFilter || m.recipeId === recipeFilter) && (!purpose || m.purpose === purpose))) {
325
+ tips.push(`已有匹配生产模型 → 调参前先 aml_model_reference 问影子参考;预测与实际偏差大再考虑重训(换配方/换目标才需要新模型)。`)
326
+ }
327
+ else if (cands.length > 0) {
328
+ tips.push(`无生产模型但有候选 → 评估候选指标后由 lead 走 aml_model_promote(shadow 先行,production 需人工审批)。`)
329
+ }
330
+ else {
331
+ tips.push(`无可用模型 → 走新建:aml_dataset_build 组该配方数据集 → aml_job_submit(带 model_name/model_description)→ 门禁通过后晋升。`)
332
+ }
333
+ tips.push(`模型身份规则:每个模型的 label/description 强制携带 产线·配方·优化目标(注册时平台派生,aml_job_submit 可用 model_name/model_description 补充);不同 recipe 的模型互不通用,选型先对齐配方与目标。`)
334
+ return { text: [...sections, `\n选型指引:`, ...tips.map(t => `- ${t}`)].join('\n') }
335
+ }
336
+
337
+ /** 工具:aml_model_reference —— 生产模型影子参考:拉最近历史组装模型输入 → 预测未来目标轨迹(调参前先问影子模型) */
338
+ export async function toolAmlModelReference(agentId: string, args: {
339
+ line_id?: string
340
+ product_id?: string
341
+ recipe_id?: string
342
+ purpose?: string
343
+ controls?: Record<string, number | string>
344
+ steps?: number | string
345
+ }): Promise<{ text: string, isError?: boolean }> {
346
+ // 0. 绑定面:至少一个 daq 绑定;line_id 只缩不放
347
+ const repo = getAgentNodeBindingRepo()
348
+ const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
349
+ if (daqBindings.length === 0) {
350
+ return amlErr('你尚未绑定任何数采节点,无法组装影子参考所需的历史输入;请先绑定数采节点。')
351
+ }
352
+ const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
353
+ const scopeLines = [...new Set(daqBindings.map(b => lineOf(b.nodeId)).filter(Boolean))]
354
+ const lineFilter = String(args.line_id ?? '').trim()
355
+ if (lineFilter && !scopeLines.includes(lineFilter)) {
356
+ return amlErr(`产线 ${lineFilter} 不在你的负责范围(你绑定节点覆盖:${scopeLines.join(', ') || '无'};绑定只缩不放)。`)
357
+ }
358
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
359
+
360
+ // 1. 解析 (productId, recipeId):参数给全用参数;缺省回退到候选产线的唯一活动批次
361
+ let productId = String(args.product_id ?? '').trim()
362
+ let recipeId = String(args.recipe_id ?? '').trim()
363
+ let resolveHow = '参数指定'
364
+ if (!productId || !recipeId) {
365
+ const candidateLines = lineFilter ? [lineFilter] : scopeLines
366
+ const runs = candidateLines
367
+ .map(lid => getActiveLineRun(lid))
368
+ .filter((r): r is NonNullable<ReturnType<typeof getActiveLineRun>> => !!r && !!r.productId && !!r.recipeId)
369
+ if (runs.length === 1) {
370
+ const run = runs[0]!
371
+ if (!productId) productId = run.productId
372
+ if (!recipeId) recipeId = run.recipeId
373
+ resolveHow = `产线 ${run.lineId} 唯一活动批次 ${run.runId.slice(0, 8)}(产品「${run.productName}」/配方「${run.recipeName}」)`
374
+ }
375
+ else if (runs.length === 0) {
376
+ return { text: `无法确定产品/配方:${candidateLines.length > 0 ? `产线 ${candidateLines.join(', ')}` : '你绑定节点所属产线'}当前无活动批次,且 product_id/recipe_id 未给全。请开跑后重试,或显式传 product_id 与 recipe_id(line_context 可查)。`, isError: true }
377
+ }
378
+ else {
379
+ return { text: `无法确定产品/配方:候选产线存在多个活动批次(${runs.map(r => `${r.lineId} → ${r.productName}/${r.recipeName}`).join('; ')})。请传 line_id 缩小范围,或显式传 product_id 与 recipe_id。`, isError: true }
380
+ }
381
+ }
382
+
383
+ // 2. 生产模型(无则指引建模范式)
384
+ const rt = getAmlRuntime()
385
+ const model = rt.repo.model.productionOf(productId, recipeId, purpose)
386
+ if (!model) {
387
+ const cands = rt.repo.model.list({ productId, recipeId, limit: 20 })
388
+ return { text: `尚无生产模型:(${productId}, ${recipeId}, ${purpose}) 下没有 stage=production 的模型。${cands.length > 0 ? `现有候选:${cands.map(m => `${m.id}「${m.label || '(未打标)'}」(${m.stage})`).join(', ')} —— 请 lead 用 aml_model_promote 晋升(需人工审批)。` : '该三元组下还没有任何模型:aml_dataset_build → aml_job_submit 训练,门禁通过后申请晋升。在此之前调参请依据 dcw_journal 历史经验与 daq_query 证据。'}` }
389
+ }
390
+ // 3. 产线归属鉴权(绑定只缩不放;模型归属线经数据集追溯)
391
+ const ds = rt.repo.dataset.get(model.datasetId)
392
+ const modelLine = ds?.lineId ?? ''
393
+ if (modelLine && !scopeLines.includes(modelLine)) {
394
+ return amlErr(`模型 ${model.id} 归属产线 ${modelLine},不在你绑定节点覆盖的产线(${scopeLines.join(', ')})内;绑定只缩不放。`)
395
+ }
396
+
397
+ // 4. io 契约 → 拉最近历史 → 网格对齐 → 组 [H][nAll](原始物理量,顺序 = allNodes)
398
+ const io = readIoSpecFor(model.id)
399
+ const H = io.historySteps
400
+ const beatMs = io.beatMs
401
+ const now = Date.now()
402
+ const fromMs = now - H * beatMs - 5 * beatMs
403
+ const { getTsdb, tsdbReady } = await import('../../daq/storage')
404
+ await tsdbReady
405
+ const tsdb = getTsdb()
406
+ const columns = new Map<string, number[]>()
407
+ const shortage: string[] = []
408
+ for (const nodeId of io.allNodes) {
409
+ try {
410
+ const pts = await tsdb.query(nodeId, { fromMs, toMs: now, limit: Math.min(Math.max(H * 10, 600), 5000) })
411
+ const { grid } = alignToGrid(
412
+ pts.map(p => ({ at: p.at, value: p.value ?? p.avg ?? 0 })).filter(p => Number.isFinite(p.value)),
413
+ { beatMs, maxInterpMs: beatMs * 2 },
414
+ )
415
+ const tail = grid.slice(-H).map(g => g.value)
416
+ if (tail.length < H) {
417
+ shortage.push(`${amlNodeName(nodeId)}(${nodeId})仅 ${tail.length}/${H} 格点`)
418
+ continue
419
+ }
420
+ columns.set(nodeId, tail)
421
+ }
422
+ catch (err) {
423
+ shortage.push(`${amlNodeName(nodeId)}(${nodeId})查询失败:${err instanceof Error ? err.message : String(err)}`)
424
+ }
425
+ }
426
+ if (shortage.length > 0) {
427
+ return { text: `历史数据不足,无法组装模型输入:${shortage.join(';')}。需要从 ${new Date(fromMs).toISOString().slice(0, 16)} 起连续约 ${(H * beatMs / 60_000).toFixed(0)} 分钟的运行数据(产线须在跑);等数据积累后重试,或缩短 steps/换更短 history 的模型。`, isError: true }
428
+ }
429
+ const history: number[][] = []
430
+ for (let i = 0; i < H; i++) history.push(io.allNodes.map(n => columns.get(n)![i]!))
431
+
432
+ // 5. 控制轨迹:controls 映射(节点 id → 值,常数外推 steps 行);缺省行持最后观测
433
+ const steps = Math.max(1, Math.min(Number(args.steps) || io.horizonSteps, io.horizonSteps))
434
+ const lastRow = history[history.length - 1]!
435
+ const unknownKeys = args.controls ? Object.keys(args.controls).filter(k => !io.controlNodes.includes(k)) : []
436
+ const controlRow = io.controlNodes.map((c) => {
437
+ const provided = args.controls?.[c]
438
+ const v = provided != null ? Number(provided) : Number.NaN
439
+ return Number.isFinite(v) ? v : lastRow[io.allNodes.indexOf(c)]!
440
+ })
441
+ const controls: number[][] = Array.from({ length: steps }, () => [...controlRow])
442
+
443
+ // 6. 预测 + 人话报告
444
+ try {
445
+ const r = await predictProduction(productId, recipeId, purpose, { history, controls, steps })
446
+ const header = `步 | ${r.targetNodes.map(t => `${amlNodeName(t)}(${amlNodeUnit(t)})`).join(' | ')}`
447
+ const forecastLines = r.forecast.map((row, i) =>
448
+ ` ${i + 1}(+${fmtAmlNum(((i + 1) * r.beatMs) / 1000, 0)}s) | ${row.map(v => fmtAmlNum(v, 3)).join(' | ')}`)
449
+ const ctrlTxt = io.controlNodes.length > 0
450
+ ? io.controlNodes.map((c) => {
451
+ const provided = args.controls?.[c]
452
+ return `${amlNodeName(c)}=${Number.isFinite(Number(provided)) ? Number(provided) : `${fmtAmlNum(lastRow[io.allNodes.indexOf(c)], 3)}(持最后观测)`}${amlNodeUnit(c)}`
453
+ }).join(', ')
454
+ : '无控制节点'
455
+ return {
456
+ text: [
457
+ `影子模型参考(调参前先问影子模型;预测≠承诺,真实下发仍走 dcw_control 安全联锁):`,
458
+ ` 模型 ${r.modelId}「${model.label || '(未打标)'}」(stage=${r.stage},purpose=${purpose}${model.objectiveId ? `,objective=${model.objectiveId}` : ''})| 三元组:产品 ${getDcwProductRepo().byId(productId)?.name ?? productId} / 配方 ${getDcwRecipeRepo().byId(recipeId)?.name ?? recipeId}(解析:${resolveHow})`,
459
+ model.description ? ` 模型说明: ${model.description}` : null,
460
+ ` 输入:最近 ${H} 拍 × ${io.allNodes.length} 节点(beat=${beatMs}ms),截至 ${new Date(now).toISOString().slice(11, 19)};控制轨迹(共 ${steps} 步):${ctrlTxt}${unknownKeys.length > 0 ? `(已忽略非控制节点的键:${unknownKeys.join(', ')})` : ''}`,
461
+ ` 预测(steps=${steps},每拍 ${beatMs / 1000}s):`,
462
+ ` ${header}`,
463
+ ...forecastLines,
464
+ ` 假设: ${r.assumptions}`,
465
+ `\n用法:把候选设定值作为 controls 传入(键 = 控制节点 id)对比不同方案的预测轨迹;选定后 dcw_control 下发并 daq_query 复测。`,
466
+ ].filter(x => x !== null).join('\n'),
467
+ }
468
+ }
469
+ catch (err) {
470
+ return { text: `预测失败:${err instanceof Error ? err.message : String(err)}(模型 ${model.id};若为工件缺失可重训同规格数据集)。`, isError: true }
471
+ }
472
+ }
473
+
474
+ /* ═══ 建模任务(aml_training_plan_*;2026-09-26 解耦计划:训练 Channel 的编排入口) ═══ */
475
+
476
+ /** 工具:aml_training_plan_list —— 建模任务清单(状态/最新模型/新批次检测基数) */
477
+ export async function toolAmlTrainingPlanList(_agentId: string, _args: Record<string, unknown>): Promise<{ text: string, isError?: boolean }> {
478
+ const plans = listTrainingPlans()
479
+ if (plans.length === 0) {
480
+ return { text: '尚无建模任务。创建路径:AML 界面「建模任务」表单,或 aml_training_plan_create(绑定产线/产品/配方 + 数据集 IO 契约);auto 策略的任务在新批次数据到达时自动修正训练。' }
481
+ }
482
+ const lines = plans.map((p) => {
483
+ const specFixed = p.trainingSpecJson ? 'spec已固化' : 'spec未固化(需先完成 draft 流程后 PATCH 固化)'
484
+ return `- ${p.id}「${p.name}」[${p.enabled ? '启用' : '停用'}/${p.strategy}] 产线 ${p.lineId}·配方 ${p.recipeId}${p.objectiveId ? `·目标 ${p.objectiveId}` : ''} | 状态 ${p.lastStatus}${p.lastModelId ? ` → 模型 ${p.lastModelId}` : ''}${p.lastJobId ? `(作业 ${p.lastJobId})` : ''} | ${specFixed} | 批次基数 ${p.lastRunCount}`
485
+ })
486
+ return { text: ['建模任务清单:', ...lines].join('\n') }
487
+ }
488
+
489
+ /** 工具:aml_training_plan_train —— 立即触发一次修正训练(重建数据集含新批次 → 平台训练器) */
490
+ export async function toolAmlTrainingPlanTrain(agentId: string, args: { plan_id?: string }): Promise<{ text: string, isError?: boolean }> {
491
+ const planId = String(args.plan_id ?? '').trim()
492
+ if (!planId) {
493
+ const plans = listTrainingPlans()
494
+ if (plans.length === 0) return amlErr('尚无建模任务可触发。')
495
+ return amlErr(`plan_id 必填。可选:${plans.map(p => `${p.id}「${p.name}」`).join('; ')}`)
496
+ }
497
+ try {
498
+ const r = await runPlanTraining(planId, { id: agentId, kind: 'agent' })
499
+ return { text: `建模任务 ${planId} 修正训练已提交:\n 作业: ${r.jobId}\n 数据集: ${r.datasetId}(${r.rowCount} 行,含历史+新批次)\n用 aml_job_status 轮询;完成后模型自动入册,plan 状态回写,可在 AML 界面绑定到工艺优化 Channel。` }
500
+ }
501
+ catch (err) {
502
+ return amlErr(`触发失败:${err instanceof Error ? err.message : String(err)}`)
503
+ }
504
+ }
505
+
506
+ /** 工具:aml_training_plan_create —— 创建建模任务(绑定 recipe + 数据集 IO 契约 + 固化训练 spec) */
507
+ export async function toolAmlTrainingPlanCreate(agentId: string, args: {
508
+ name?: string
509
+ line_id?: string
510
+ product_id?: string
511
+ recipe_id?: string
512
+ scene_id?: string
513
+ scene_version?: string
514
+ objective_id?: string
515
+ strategy?: string
516
+ dataset_spec?: Record<string, unknown>
517
+ training_spec?: Record<string, unknown>
518
+ model_name_prefix?: string
519
+ params?: Record<string, unknown>
520
+ seed?: number | string
521
+ min_interval_sec?: number | string
522
+ }): Promise<{ text: string, isError?: boolean }> {
523
+ const lineId = String(args.line_id ?? '').trim()
524
+ const productId = String(args.product_id ?? '').trim()
525
+ const recipeId = String(args.recipe_id ?? '').trim()
526
+ if (!lineId || !productId || !recipeId) return amlErr('line_id/product_id/recipe_id 必填(隔离三元组;防配方串味)。')
527
+ if (!args.dataset_spec || typeof args.dataset_spec !== 'object') return amlErr('dataset_spec 必填(AmlDatasetSpec:nodes 角色 control=DCW 输入,target=DAQ 输出;window/beatMs/split)。')
528
+ try {
529
+ const plan = createTrainingPlan({
530
+ name: String(args.name ?? '').trim() || `建模任务-${Date.now().toString(36)}`,
531
+ lineId, productId, recipeId,
532
+ sceneId: String(args.scene_id ?? '').trim() || undefined,
533
+ sceneVersion: String(args.scene_version ?? '').trim() || undefined,
534
+ objectiveId: String(args.objective_id ?? '').trim() || undefined,
535
+ strategy: args.strategy === 'manual' ? 'manual' : 'auto',
536
+ datasetSpec: args.dataset_spec as never,
537
+ trainingSpec: args.training_spec as never,
538
+ modelNamePrefix: String(args.model_name_prefix ?? '').trim() || undefined,
539
+ params: args.params,
540
+ seed: Number.isFinite(Number(args.seed)) ? Number(args.seed) : undefined,
541
+ minIntervalSec: Number.isFinite(Number(args.min_interval_sec)) ? Number(args.min_interval_sec) : undefined,
542
+ createdBy: agentId,
543
+ })
544
+ return { text: `建模任务已创建:\n id: ${plan.id}\n 名称: ${plan.name}(${plan.strategy})\n 谱系: 产线 ${plan.lineId}/产品 ${plan.productId}/配方 ${plan.recipeId}\n 训练: ${plan.trainingSpecJson ? 'spec 已固化,新批次到达将自动修正训练' : 'spec 未固化 —— 先完成 twin_physics_spec_draft/compile 流程后固化(REST PATCH training_spec);再 aml_training_plan_train 触发'}\n立即触发:aml_training_plan_train { plan_id: "${plan.id}" }。` }
545
+ }
546
+ catch (err) {
547
+ return amlErr(`创建失败:${err instanceof Error ? err.message : String(err)}`)
548
+ }
549
+ }