agentworkshop 0.7.27 → 0.7.34

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 (1033) hide show
  1. package/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
  2. package/.AgentWorkShop/prompts/aml-playbook.md +49 -0
  3. package/.AgentWorkShop/prompts/host-tools.json +314 -0
  4. package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
  5. package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -0
  6. package/.output/.AgentWorkShop/prompts/host-tools.json +314 -0
  7. package/.output/.AgentWorkShop/schema.json +120 -0
  8. package/.output/nitro.json +1 -1
  9. package/.output/public/_nuxt/{BTLEvDxM.js → 4bHdIqEg.js} +8 -8
  10. package/.output/public/_nuxt/B9nXmjSB.js +19 -0
  11. package/.output/public/_nuxt/BASN8nZ0.js +1 -0
  12. package/.output/public/_nuxt/{DNQF_TXX.js → BBBtwOpo.js} +1 -1
  13. package/.output/public/_nuxt/{DoAlYsiF.js → BBwMH_hG.js} +1 -1
  14. package/.output/public/_nuxt/BWSE6hR6.js +1 -0
  15. package/.output/public/_nuxt/BZv4RFYN.js +1 -0
  16. package/.output/public/_nuxt/{BgCrZKv_2.js → Bc0AmjfT.js} +1 -1
  17. package/.output/public/_nuxt/BcmbLh2z2.js +1 -0
  18. package/.output/public/_nuxt/BgTB6h_q.js +2 -0
  19. package/.output/public/_nuxt/BkLJA9J5.js +1 -0
  20. package/.output/public/_nuxt/{XY2z78rj.js → BuCHayqN.js} +1 -1
  21. package/.output/public/_nuxt/{0jKrzLuM.js → BuvcLKh1.js} +1 -1
  22. package/.output/public/_nuxt/C-mDhyEd.js +1 -0
  23. package/.output/public/_nuxt/{DosOJEmZ2.js → C77oC8yC2.js} +1 -1
  24. package/.output/public/_nuxt/CQvmN-Mi.js +1 -0
  25. package/.output/public/_nuxt/CUDrOuW7.js +1 -0
  26. package/.output/public/_nuxt/{DjU9Dx5Y.js → CZcC-gpk.js} +1 -1
  27. package/.output/public/_nuxt/{Cz9gD2Yo.js → CbzsPO5H.js} +1 -1
  28. package/.output/public/_nuxt/CdSOrh2c.js +1 -0
  29. package/.output/public/_nuxt/Cgx818r-.js +1 -0
  30. package/.output/public/_nuxt/Cjm7VogC.js +1 -0
  31. package/.output/public/_nuxt/Cm5mDxzH.js +1 -0
  32. package/.output/public/_nuxt/Cp6z0RN7.js +1 -0
  33. package/.output/public/_nuxt/Ct-WOVr4.js +1 -0
  34. package/.output/public/_nuxt/CwqIxJGj.js +2 -0
  35. package/.output/public/_nuxt/{BGhOrgle.js → D0fhp-Ga.js} +2 -2
  36. package/.output/public/_nuxt/DIaTPH1M.js +1 -0
  37. package/.output/public/_nuxt/DLljr7g0.js +1 -0
  38. package/.output/public/_nuxt/DTYBfjRY.js +1 -0
  39. package/.output/public/_nuxt/DYKVPzN-.js +1 -0
  40. package/.output/public/_nuxt/DZzGarBE2.js +13 -0
  41. package/.output/public/_nuxt/DaMCzQhv.js +1 -0
  42. package/.output/public/_nuxt/DoMxCWN52.js +4 -0
  43. package/.output/public/_nuxt/{CucID8qg2.js → DoTdlVVe2.js} +1 -1
  44. package/.output/public/_nuxt/DsVcWfyR.js +1 -0
  45. package/.output/public/_nuxt/{BCJFMBQ6.js → DzuC31-i.js} +2 -2
  46. package/.output/public/_nuxt/FQri3dV3.js +1 -0
  47. package/.output/public/_nuxt/Lp7Ll94I.js +1 -0
  48. package/.output/public/_nuxt/PluginSlot.DmjNbrcX.css +1 -0
  49. package/.output/public/_nuxt/_id_.hRYo-EAB.css +1 -0
  50. package/.output/public/_nuxt/_wsId_.gXMEOYgX.css +1 -0
  51. package/.output/public/_nuxt/agents.BV70ioCv.css +1 -0
  52. package/.output/public/_nuxt/aml.WU_bh87J.css +1 -0
  53. package/.output/public/_nuxt/builds/latest.json +1 -1
  54. package/.output/public/_nuxt/builds/meta/adc365b6-f636-4a2b-9527-79819c1e874b.json +1 -0
  55. package/.output/public/_nuxt/daq.Bb6l44-O.css +1 -0
  56. package/.output/public/_nuxt/default.jNT73_hq.css +1 -0
  57. package/.output/public/_nuxt/ekuGmQ7R.js +1 -0
  58. package/.output/public/_nuxt/entry.jFrFAWuA.css +1 -0
  59. package/.output/public/_nuxt/pMoIO6rr.js +14 -0
  60. package/.output/public/_nuxt/pages.Cc8GX9T1.css +1 -0
  61. package/.output/public/_nuxt/plugins.wIPyfPn-.css +1 -0
  62. package/.output/public/_nuxt/settings.BCm4NZIc.css +1 -0
  63. package/.output/public/_nuxt/teams.BC75EGnR.css +1 -0
  64. package/.output/server/chunks/_/binding-authz.mjs +23 -0
  65. package/.output/server/chunks/_/binding-authz.mjs.map +1 -0
  66. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  67. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  68. package/.output/server/chunks/_/nitro.mjs +15929 -9198
  69. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  70. package/.output/server/chunks/_/scene-layout.repo.mjs +3 -3
  71. package/.output/server/chunks/_/scene-layout.repo.mjs.map +1 -1
  72. package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs +207 -0
  73. package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs.map +1 -0
  74. package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs → OmpTerminalPanel-Cu_s4i0A.mjs} +2 -2
  75. package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs.map → OmpTerminalPanel-Cu_s4i0A.mjs.map} +1 -1
  76. package/.output/server/chunks/build/{alert-qJnjyRcP.mjs → PluginSlot-CcR4Ys3T.mjs} +140 -4
  77. package/.output/server/chunks/build/PluginSlot-CcR4Ys3T.mjs.map +1 -0
  78. package/.output/server/chunks/build/{TownView-ftIylqiD.mjs → TownView-BdHnAilw.mjs} +5 -5
  79. package/.output/server/chunks/build/{TownView-ftIylqiD.mjs.map → TownView-BdHnAilw.mjs.map} +1 -1
  80. package/.output/server/chunks/build/{_id_-CahfkmEt.mjs → _id_-Cb845FHR.mjs} +7 -5
  81. package/.output/server/chunks/build/_id_-Cb845FHR.mjs.map +1 -0
  82. package/.output/server/chunks/build/{_id_-3Axz2-gV.mjs → _id_-fadFPl2i.mjs} +50 -35
  83. package/.output/server/chunks/build/_id_-fadFPl2i.mjs.map +1 -0
  84. package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs → _wsId_-CTZswnm5.mjs} +181 -22
  85. package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs.map → _wsId_-CTZswnm5.mjs.map} +1 -1
  86. package/.output/server/chunks/build/{agents-DuMiSWKp.mjs → agents-Bvin73QY.mjs} +82 -32
  87. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +1 -0
  88. package/.output/server/chunks/build/aml-uBNIppIf.mjs +508 -0
  89. package/.output/server/chunks/build/aml-uBNIppIf.mjs.map +1 -0
  90. package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs +81 -0
  91. package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs.map +1 -0
  92. package/.output/server/chunks/build/{channel-templates-BStqJ-of.mjs → channel-templates-BTq8570n.mjs} +6 -5
  93. package/.output/server/chunks/build/channel-templates-BTq8570n.mjs.map +1 -0
  94. package/.output/server/chunks/build/{checkbox-C1gABOca.mjs → checkbox-8fB-wI-T.mjs} +2 -2
  95. package/.output/server/chunks/build/{checkbox-C1gABOca.mjs.map → checkbox-8fB-wI-T.mjs.map} +1 -1
  96. package/.output/server/chunks/build/{daq-ChYCABz1.mjs → daq-BvihjQyW.mjs} +111 -109
  97. package/.output/server/chunks/build/daq-BvihjQyW.mjs.map +1 -0
  98. package/.output/server/chunks/build/{dcw-CcQNGggh.mjs → dcw-Ks2vJ4PF.mjs} +5 -3
  99. package/.output/server/chunks/build/dcw-Ks2vJ4PF.mjs.map +1 -0
  100. package/.output/server/chunks/build/{default-95-zOTPt.mjs → default-GgHt4O2R.mjs} +164 -101
  101. package/.output/server/chunks/build/{default-95-zOTPt.mjs.map → default-GgHt4O2R.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs → input-number-DzpyYB99.mjs} +2 -2
  103. package/.output/server/chunks/build/{input-number-Bd55elNN.mjs.map → input-number-DzpyYB99.mjs.map} +1 -1
  104. package/.output/server/chunks/build/{logs-D-2UyGtE.mjs → logs-CYBhkQwh.mjs} +5 -3
  105. package/.output/server/chunks/build/logs-CYBhkQwh.mjs.map +1 -0
  106. package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs → monitor-CyfDt4nR.mjs} +7 -6
  107. package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs.map → monitor-CyfDt4nR.mjs.map} +1 -1
  108. package/.output/server/chunks/build/{pages-Dfosfchr.mjs → pages-C-6BRtv8.mjs} +57 -47
  109. package/.output/server/chunks/build/pages-C-6BRtv8.mjs.map +1 -0
  110. package/.output/server/chunks/build/{permissions-B-hhZuzm.mjs → permissions-B52oOmaO.mjs} +6 -5
  111. package/.output/server/chunks/build/permissions-B52oOmaO.mjs.map +1 -0
  112. package/.output/server/chunks/build/{plugins-DZR0T4Mh.mjs → plugins-dZRegC7m.mjs} +22 -18
  113. package/.output/server/chunks/build/plugins-dZRegC7m.mjs.map +1 -0
  114. package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs → segmented-3TrWo0lS.mjs} +3 -3
  115. package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs.map → segmented-3TrWo0lS.mjs.map} +1 -1
  116. package/.output/server/chunks/build/{settings-BajN9TQW.mjs → settings-CgDLkP3s.mjs} +437 -62
  117. package/.output/server/chunks/build/settings-CgDLkP3s.mjs.map +1 -0
  118. package/.output/server/chunks/build/{table-Bf1r2JjE.mjs → table-BjSWwmic.mjs} +4 -4
  119. package/.output/server/chunks/build/{table-Bf1r2JjE.mjs.map → table-BjSWwmic.mjs.map} +1 -1
  120. package/.output/server/chunks/build/{tag-NO9jEqKy.mjs → tag-DNE9vXc0.mjs} +3 -131
  121. package/.output/server/chunks/build/tag-DNE9vXc0.mjs.map +1 -0
  122. package/.output/server/chunks/build/{teams-t2SkRlJP.mjs → teams-2kz3CusY.mjs} +31 -30
  123. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +1 -0
  124. package/.output/server/chunks/build/{tokens-DiCojbN8.mjs → tokens-BbWLqtVz.mjs} +6 -5
  125. package/.output/server/chunks/build/tokens-BbWLqtVz.mjs.map +1 -0
  126. package/.output/server/chunks/build/town-BUqRobze.mjs +1 -0
  127. package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
  128. package/.output/server/chunks/build/{town-C7QM8DYK.mjs → town-DJ-V5G9U.mjs} +7 -5
  129. package/.output/server/chunks/build/town-DJ-V5G9U.mjs.map +1 -0
  130. package/.output/server/chunks/build/{useDaqStream-BeA2X8KR.mjs → useDaqStream-CIBaiGAl.mjs} +4 -3
  131. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +1 -0
  132. package/.output/server/chunks/build/{useDcwStream-BJW_MitY.mjs → useDcwStream-CBbiYnWe.mjs} +4 -80
  133. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +1 -0
  134. package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs → useDeviceTwins-Yko6nNPF.mjs} +2 -2
  135. package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs.map → useDeviceTwins-Yko6nNPF.mjs.map} +1 -1
  136. package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs → useOpsLog-CO_VWh7t.mjs} +2 -2
  137. package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs.map → useOpsLog-CO_VWh7t.mjs.map} +1 -1
  138. package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs → useWorkshopApi-NyjL0L3j.mjs} +4 -2
  139. package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs.map → useWorkshopApi-NyjL0L3j.mjs.map} +1 -1
  140. package/.output/server/chunks/build/{users-B9SAdEtH.mjs → users-4nzxTjFT.mjs} +6 -5
  141. package/.output/server/chunks/build/users-4nzxTjFT.mjs.map +1 -0
  142. package/.output/server/chunks/build/workshop-81xhz368.mjs +1 -0
  143. package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/health.get.mjs +1 -0
  145. package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
  146. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  147. package/.output/server/chunks/routes/api/index.post.mjs +1 -1
  148. package/.output/server/chunks/routes/api/metrics.mjs +1 -0
  149. package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
  150. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -0
  151. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
  152. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -0
  153. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
  154. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +26 -0
  155. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs.map +1 -0
  156. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +2 -1
  157. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
  158. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +32 -0
  159. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs.map +1 -0
  160. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +36 -0
  161. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -0
  162. package/.output/server/chunks/routes/api/system/config.get.mjs +1 -0
  163. package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
  164. package/.output/server/chunks/routes/api/system/index.get.mjs +7 -2
  165. package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/system/index.patch.mjs +2 -1
  167. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/system/index.post.mjs +36 -0
  169. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -0
  170. package/.output/server/chunks/routes/api/system/index2.get.mjs +28 -0
  171. package/.output/server/chunks/routes/api/system/index2.get.mjs.map +1 -0
  172. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +2 -1
  173. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs.map +1 -1
  174. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +2 -1
  175. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
  176. package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -0
  177. package/.output/server/chunks/routes/api/system/monitor.get.mjs.map +1 -1
  178. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +8 -5
  179. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  180. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +2 -1
  181. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
  182. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +2 -1
  183. package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
  184. package/.output/server/chunks/routes/api/users/_id_.get.mjs +2 -1
  185. package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
  186. package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
  187. package/.output/server/chunks/routes/api/users/index.get.mjs +2 -1
  188. package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
  189. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
  191. package/.output/server/chunks/routes/api/users/logout.post.mjs +2 -1
  192. package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
  193. package/.output/server/chunks/routes/api/users/me.get.mjs +2 -1
  194. package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
  195. package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
  196. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +2 -1
  197. package/.output/server/chunks/routes/api/users/setup-status.get.mjs.map +1 -1
  198. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +2 -1
  199. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs.map +1 -1
  200. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +2 -1
  201. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs.map +1 -1
  202. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +2 -1
  204. package/.output/server/chunks/routes/api/workshop/_...path_.mjs.map +1 -1
  205. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +2 -1
  206. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs.map +1 -1
  207. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +2 -1
  210. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
  211. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +5 -2
  212. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs.map +1 -1
  213. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +9 -3
  214. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
  215. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +2 -1
  216. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
  217. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +2 -1
  218. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  219. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +23 -3
  220. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs.map +1 -1
  221. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +21 -3
  222. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  223. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +2 -1
  224. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs.map +1 -1
  225. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +2 -1
  226. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs.map +1 -1
  227. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +2 -1
  228. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs.map +1 -1
  229. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +75 -0
  232. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs.map +1 -0
  233. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +35 -0
  234. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -0
  235. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +35 -0
  236. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs.map +1 -0
  237. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +46 -0
  238. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs.map +1 -0
  239. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +47 -0
  240. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs.map +1 -0
  241. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +48 -0
  242. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -0
  243. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +41 -0
  244. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -0
  245. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +62 -0
  246. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs.map +1 -0
  247. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +35 -0
  248. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs.map +1 -0
  249. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +36 -0
  250. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs.map +1 -0
  251. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +34 -0
  252. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs.map +1 -0
  253. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +38 -0
  254. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs.map +1 -0
  255. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +37 -0
  256. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs.map +1 -0
  257. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +42 -0
  258. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs.map +1 -0
  259. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +2 -1
  260. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs.map +1 -1
  261. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +2 -1
  262. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs.map +1 -1
  263. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +2 -1
  264. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs.map +1 -1
  265. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +2 -1
  266. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs.map +1 -1
  267. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -1
  268. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs.map +1 -1
  269. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -0
  270. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs.map +1 -1
  271. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -1
  272. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs.map +1 -1
  273. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +2 -1
  274. package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/workshop/caller.mjs +2 -1
  276. package/.output/server/chunks/routes/api/workshop/caller.mjs.map +1 -1
  277. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  278. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +2 -1
  279. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs.map +1 -1
  280. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +2 -1
  281. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs.map +1 -1
  282. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -1
  285. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs.map +1 -1
  286. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +2 -1
  287. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs.map +1 -1
  288. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +2 -1
  290. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs.map +1 -1
  291. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +2 -1
  293. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs.map +1 -1
  294. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +2 -1
  295. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs.map +1 -1
  296. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +2 -1
  297. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs.map +1 -1
  298. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +2 -1
  299. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs.map +1 -1
  300. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +2 -1
  301. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs.map +1 -1
  302. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +2 -1
  303. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  304. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +2 -1
  306. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  307. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +2 -1
  309. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs.map +1 -1
  310. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +2 -1
  311. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs.map +1 -1
  312. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +2 -1
  316. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +1 -1
  317. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -0
  319. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs.map +1 -1
  320. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +2 -1
  321. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs.map +1 -1
  322. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +2 -1
  323. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs.map +1 -1
  324. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -1
  325. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs.map +1 -1
  326. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -0
  327. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs.map +1 -1
  328. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -1
  329. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  330. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -0
  332. package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
  333. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +4 -4
  334. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -1
  335. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
  336. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +2 -1
  337. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs.map +1 -1
  338. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +2 -1
  339. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
  340. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +2 -1
  341. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
  342. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +2 -1
  343. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
  344. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -1
  345. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs.map +1 -1
  346. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +3 -1
  347. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +2 -1
  349. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +2 -1
  351. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -1
  353. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  354. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +2 -1
  355. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
  356. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -1
  357. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  358. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -1
  359. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  360. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -1
  361. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs.map +1 -1
  362. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -1
  363. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  364. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +2 -1
  365. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  366. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -1
  367. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  368. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +2 -1
  369. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
  370. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +2 -1
  371. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs.map +1 -1
  372. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -1
  373. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  374. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -1
  375. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
  376. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +2 -1
  377. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
  378. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +2 -1
  379. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  380. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  381. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  382. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +7 -2
  383. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  384. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -1
  385. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs.map +1 -1
  386. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -1
  387. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  388. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +2 -1
  389. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
  390. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +2 -1
  391. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
  392. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +2 -1
  393. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  394. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -1
  395. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  396. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -1
  397. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  398. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +2 -1
  399. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  400. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +2 -1
  401. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  402. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +2 -1
  403. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  404. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -1
  405. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs.map +1 -1
  406. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +2 -1
  407. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
  408. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +2 -1
  409. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
  410. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +2 -1
  411. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
  412. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -1
  413. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs.map +1 -1
  414. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -1
  415. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  416. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -1
  417. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs.map +1 -1
  418. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -1
  419. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs.map +1 -1
  420. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -1
  421. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  422. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -1
  423. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  424. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -1
  425. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs.map +1 -1
  426. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -1
  427. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs.map +1 -1
  428. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -1
  429. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs.map +1 -1
  430. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -1
  431. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs.map +1 -1
  432. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +2 -1
  433. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs.map +1 -1
  434. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -1
  435. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs.map +1 -1
  436. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +2 -1
  437. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
  438. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -1
  439. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  440. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +2 -1
  441. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs.map +1 -1
  442. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -1
  443. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  444. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +2 -1
  445. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
  446. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -1
  447. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs.map +1 -1
  448. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -1
  449. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs.map +1 -1
  450. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -1
  451. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs.map +1 -1
  452. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -1
  453. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  454. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +2 -1
  455. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs.map +1 -1
  456. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +2 -1
  457. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs.map +1 -1
  458. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -1
  459. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs.map +1 -1
  460. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -1
  461. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs.map +1 -1
  462. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +2 -1
  463. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
  464. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +32 -1
  465. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs.map +1 -1
  466. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +2 -1
  467. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs.map +1 -1
  468. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +2 -1
  469. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -1
  470. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +3 -2
  471. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -1
  472. package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -0
  473. package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
  474. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  475. package/.output/server/chunks/routes/api/workshop/index.put.mjs +2 -1
  476. package/.output/server/chunks/routes/api/workshop/index.put.mjs.map +1 -1
  477. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +12 -6
  478. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  479. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +4 -2
  480. package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
  481. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +28 -0
  482. package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -0
  483. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +17 -11
  484. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  485. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  486. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +11 -4
  487. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  488. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -1
  489. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  490. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +5 -27
  491. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  492. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -1
  493. package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
  494. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +24 -18
  495. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  496. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -1
  497. package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
  498. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +23 -5
  499. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  500. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -1
  501. package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
  502. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +4 -17
  503. package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
  504. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +8 -3
  505. package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
  506. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +20 -21
  507. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  508. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  509. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +24 -11
  510. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  511. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -0
  512. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs.map +1 -1
  513. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -0
  514. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs.map +1 -1
  515. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +2 -1
  516. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs.map +1 -1
  517. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +2 -1
  518. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs.map +1 -1
  519. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +2 -1
  520. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs.map +1 -1
  521. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +2 -1
  522. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
  523. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -0
  524. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs.map +1 -1
  525. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +2 -1
  526. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs.map +1 -1
  527. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +2 -1
  528. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs.map +1 -1
  529. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -0
  530. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs.map +1 -1
  531. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  532. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  533. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +2 -1
  534. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs.map +1 -1
  535. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  536. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +2 -1
  537. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs.map +1 -1
  538. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +2 -1
  539. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
  540. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -0
  541. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs.map +1 -1
  542. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  543. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +2 -1
  544. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs.map +1 -1
  545. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  546. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +44 -0
  547. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs.map +1 -0
  548. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +47 -0
  549. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs.map +1 -0
  550. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +2 -1
  551. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs.map +1 -1
  552. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +2 -1
  553. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs.map +1 -1
  554. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +2 -1
  555. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs.map +1 -1
  556. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  557. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +2 -0
  558. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs.map +1 -1
  559. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
  560. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  561. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -0
  562. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs.map +1 -1
  563. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -0
  564. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs.map +1 -1
  565. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -0
  566. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
  567. package/.output/server/chunks/routes/renderer.mjs +2 -2
  568. package/.output/server/chunks/virtual/entry.mjs +601 -36
  569. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  570. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  571. package/.output/server/index.mjs +1 -0
  572. package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/package.json +84 -0
  573. package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +225 -0
  574. package/.output/server/package.json +2 -1
  575. package/README-zh.md +507 -478
  576. package/README.md +517 -486
  577. package/app/app.vue +17 -2
  578. package/app/assets/css/main.css +421 -30
  579. package/app/components/AppHeader.vue +17 -0
  580. package/app/components/AppSidebar.vue +162 -63
  581. package/app/components/AwChart.vue +57 -54
  582. package/app/components/workshop/ChannelSessionList.vue +802 -703
  583. package/app/components/workshop/DaqNodeRow.vue +156 -0
  584. package/app/components/workshop/PluginSlot.vue +120 -0
  585. package/app/composables/workshop/useAmlStream.ts +136 -0
  586. package/app/composables/workshop/useDaqStream.ts +8 -1
  587. package/app/composables/workshop/usePluginPanels.ts +72 -0
  588. package/app/composables/workshop/useWorkshopApi.ts +7 -0
  589. package/app/pages/aml/index.vue +1949 -0
  590. package/app/pages/daq/[id].vue +60 -2
  591. package/app/pages/daq/index.vue +7 -148
  592. package/app/pages/index.vue +235 -213
  593. package/app/pages/plugins/index.vue +280 -274
  594. package/app/pages/settings.vue +555 -78
  595. package/app/pages/workshop/agents.vue +23 -1
  596. package/app/pages/workshop/teams.vue +2 -2
  597. package/app/plugins/aw-plugins.client.ts +95 -6
  598. package/app/plugins/runtime-config.client.ts +4 -14
  599. package/app/plugins/theme.client.ts +13 -3
  600. package/app/stores/app.ts +9 -2
  601. package/app/stores/runtime-config.ts +113 -7
  602. package/cli/aw.mjs +16 -3
  603. package/cli/commands/build.mjs +8 -8
  604. package/cli/commands/dev.mjs +5 -13
  605. package/cli/commands/init.mjs +1 -1
  606. package/cli/commands/start.mjs +10 -17
  607. package/cli/core/args.mjs +85 -4
  608. package/cli/core/child-lifecycle.mjs +136 -0
  609. package/config.yml +24 -0
  610. package/docs/plugins.md +128 -220
  611. package/docs/sdk.md +1 -1
  612. package/i18n/dicts/_en.json +43 -2
  613. package/i18n/dicts/aml.json +163 -0
  614. package/i18n/dicts/channelSessionList.json +4 -1
  615. package/i18n/dicts/daqDetail.json +1 -0
  616. package/i18n/dicts/settings.json +33 -1
  617. package/i18n/dicts/teams.json +9 -1
  618. package/i18n/locales/en.ts +364 -132
  619. package/i18n/locales/zh-CN.ts +433 -201
  620. package/nuxt.config.ts +18 -3
  621. package/package.json +153 -149
  622. package/scripts/_audit/.tmp/audit-data/dcws.json +28 -0
  623. package/scripts/_audit/.tmp/dcw-writes.json +15650 -0
  624. package/scripts/_audit/.tmp/dcws.json +9033 -0
  625. package/scripts/_audit/.tmp/pollution-backup/dcw-rollback.polluted.json +470006 -0
  626. package/scripts/_audit/.tmp/pollution-backup/dcws.polluted.json +9085 -0
  627. package/scripts/_audit/.tmp/probe-cwd.txt +1 -0
  628. package/scripts/_audit/audit-harness-adapters.md +664 -0
  629. package/scripts/_audit/awhome/commands/README.md +3 -0
  630. package/scripts/_audit/awhome/commands/hello.mjs +12 -0
  631. package/scripts/_audit/dcw-controller-e2e.ts +99 -0
  632. package/scripts/_audit/dcw-flush-cost.ts +43 -0
  633. package/scripts/_audit/dcw-rollback-ledger.ts +153 -0
  634. package/scripts/_audit/dcw-unrecorded-write.ts +171 -0
  635. package/scripts/_audit/dcw-write-mutex.ts +157 -0
  636. package/scripts/_audit/diag-cwd.ts +20 -0
  637. package/scripts/_audit/diag-cwd2.ts +19 -0
  638. package/scripts/_audit/exp-cost-scaling.mjs +54 -0
  639. package/scripts/_audit/exp-envelope-and-png.mjs +77 -0
  640. package/scripts/_audit/exp-png-decode.mjs +67 -0
  641. package/scripts/_audit/exp-retention-plan.mjs +61 -0
  642. package/scripts/_audit/exp-retention-rescan.mjs +42 -0
  643. package/scripts/_audit/exp-sweep-fairness.mjs +48 -0
  644. package/scripts/_audit/hello.mjs +12 -0
  645. package/scripts/_audit/http-api-authz-audit.md +657 -0
  646. package/scripts/_audit/ndjson-partial-line-repro.mjs +77 -0
  647. package/scripts/_audit/opencode-await-ternary-repro.mjs +20 -0
  648. package/scripts/_audit/part-frag.txt +84 -0
  649. package/scripts/_audit/part-head.txt +45 -0
  650. package/scripts/_audit/probe-binding.mjs +103 -0
  651. package/scripts/_audit/probe-child.mjs +17 -0
  652. package/scripts/_audit/probe-envelope.mjs +49 -0
  653. package/scripts/_audit/probe-packlist.mjs +67 -0
  654. package/scripts/_audit/probe-routes.mjs +47 -0
  655. package/scripts/_audit/probe-routes2.mjs +38 -0
  656. package/scripts/_audit/probe.ts +9 -0
  657. package/scripts/_audit/probe2.ts +6 -0
  658. package/scripts/_audit/probe3.ts +3 -0
  659. package/scripts/_audit/probe4.ts +3 -0
  660. package/scripts/_audit/proj/.AgentWorkShop/commands/echoargs.mjs +13 -0
  661. package/scripts/_audit/proj/config.yml +1 -0
  662. package/scripts/_audit/run.mjs +30 -0
  663. package/scripts/_audit/runtime-audit.md +716 -0
  664. package/scripts/_audit/ts-resolve-hook.mjs +41 -0
  665. package/scripts/_audit/tsconfig.probe.json +24 -0
  666. package/scripts/_audit/typecheck-out.txt +466 -0
  667. package/scripts/_audit/verify-data-integrity.mjs +112 -0
  668. package/scripts/_dbg-agents-dropdown-shot.py +33 -0
  669. package/scripts/_dbg-anim-verify.mjs +1 -1
  670. package/scripts/_dbg-audit-all-pages.mjs +1 -1
  671. package/scripts/_dbg-availability-probe.ts +11 -0
  672. package/scripts/_dbg-bind-bidi-e2e.mjs +1 -1
  673. package/scripts/_dbg-cf-line-shot.mjs +18 -0
  674. package/scripts/_dbg-channel-plugin-ui.mjs +94 -0
  675. package/scripts/_dbg-configroot-audit.mjs +84 -0
  676. package/scripts/_dbg-crash-recovery.mjs +1 -1
  677. package/scripts/_dbg-crush-probe.sh +21 -0
  678. package/scripts/_dbg-crush-spawn-probe.ts +22 -0
  679. package/scripts/_dbg-daq-acc-probe.mjs +1 -1
  680. package/scripts/_dbg-daq-attrib.mjs +1 -1
  681. package/scripts/_dbg-daq-debug.mjs +1 -1
  682. package/scripts/_dbg-daq-diag.mjs +1 -1
  683. package/scripts/_dbg-daq-e2e.mjs +1 -1
  684. package/scripts/_dbg-daq-filter-e2e.mjs +1 -1
  685. package/scripts/_dbg-daq-filter-e2e2.mjs +1 -1
  686. package/scripts/_dbg-daq-final-regression.mjs +1 -1
  687. package/scripts/_dbg-daq-frame-alarm.mjs +1 -1
  688. package/scripts/_dbg-daq-frame-ui.mjs +1 -1
  689. package/scripts/_dbg-daq-frame-ws.mjs +1 -1
  690. package/scripts/_dbg-daq-frames-e2e.mjs +1 -1
  691. package/scripts/_dbg-daq-full-check.mjs +1 -1
  692. package/scripts/_dbg-daq-intervals-func.mjs +94 -0
  693. package/scripts/_dbg-daq-pages-shot.mjs +1 -1
  694. package/scripts/_dbg-daq-perf.mjs +1 -1
  695. package/scripts/_dbg-daq-probe.mjs +1 -1
  696. package/scripts/_dbg-daq-recipe-e2e.mjs +1 -1
  697. package/scripts/_dbg-daq-rows-probe.mjs +1 -1
  698. package/scripts/_dbg-daq-rowstate-e2e.mjs +1 -1
  699. package/scripts/_dbg-daq-rowstate-shot.mjs +1 -1
  700. package/scripts/_dbg-daq-rowstate-shot2.mjs +1 -1
  701. package/scripts/_dbg-daq-rowstyle-verify.mjs +112 -0
  702. package/scripts/_dbg-dash-console-check.mjs +1 -1
  703. package/scripts/_dbg-dash-deep-probe.mjs +1 -1
  704. package/scripts/_dbg-dash-hitpoint.mjs +1 -1
  705. package/scripts/_dbg-dcw-read-rest.mjs +1 -1
  706. package/scripts/_dbg-dcw-read-ui.mjs +1 -1
  707. package/scripts/_dbg-dcw-shot2.mjs +1 -1
  708. package/scripts/_dbg-diag-mock-loop.mjs +89 -0
  709. package/scripts/_dbg-diag-watch.mjs +95 -0
  710. package/scripts/_dbg-error-probe.mjs +2 -2
  711. package/scripts/_dbg-filter-light-verify.mjs +1 -1
  712. package/scripts/_dbg-final-acceptance-2.mjs +1 -1
  713. package/scripts/_dbg-final-acceptance.mjs +1 -1
  714. package/scripts/_dbg-final-full-e2e.mjs +1 -1
  715. package/scripts/_dbg-final-shots.mjs +32 -0
  716. package/scripts/_dbg-final-t6-hitl.mjs +1 -1
  717. package/scripts/_dbg-fix-unused-imports.py +41 -0
  718. package/scripts/_dbg-fresh-scene-e2e.mjs +1 -1
  719. package/scripts/_dbg-goose-probe.mjs +33 -0
  720. package/scripts/_dbg-goose-probe.sh +10 -0
  721. package/scripts/_dbg-groups-ui-verify.mjs +122 -0
  722. package/scripts/_dbg-harness-cancel-repro.mjs +81 -0
  723. package/scripts/_dbg-harness-ui-shot.py +109 -0
  724. package/scripts/_dbg-hidden-check.mjs +1 -1
  725. package/scripts/_dbg-home-repro.mjs +1 -1
  726. package/scripts/_dbg-home-stack.mjs +1 -1
  727. package/scripts/_dbg-hydration-detail.mjs +1 -1
  728. package/scripts/_dbg-infra-lifecycle.mjs +1 -1
  729. package/scripts/_dbg-line-live-e2e.mjs +1 -1
  730. package/scripts/_dbg-line-repo-test.ts +10 -0
  731. package/scripts/_dbg-login-debug.py +23 -0
  732. package/scripts/_dbg-modbus-latency.mjs +22 -0
  733. package/scripts/_dbg-mqtt-chain-e2e.mjs +1 -1
  734. package/scripts/_dbg-oneshot-impl-probe.ts +67 -0
  735. package/scripts/_dbg-opslog-agent-e2e.mjs +5 -2
  736. package/scripts/_dbg-opt-team-e2e.mjs +1 -1
  737. package/scripts/_dbg-panesplitter-fix-check.mjs +1 -1
  738. package/scripts/_dbg-phase-e3-monitor.mjs +1 -1
  739. package/scripts/_dbg-pi-spawn-probe.ts +33 -0
  740. package/scripts/_dbg-plc-e2e.mjs +1 -1
  741. package/scripts/_dbg-plugin-config-ui.mjs +111 -0
  742. package/scripts/_dbg-plugin-panels-ui.mjs +54 -0
  743. package/scripts/_dbg-plugin-sink-rest.mjs +1 -1
  744. package/scripts/_dbg-plugin-sink-ui.mjs +1 -1
  745. package/scripts/_dbg-plugin-ui-wizard.mjs +1 -1
  746. package/scripts/_dbg-plugin-verify-e2e.mjs +1 -1
  747. package/scripts/_dbg-pop-clamp-verify.mjs +1 -1
  748. package/scripts/_dbg-preview-console.mjs +1 -1
  749. package/scripts/_dbg-preview-minrepro.mjs +1 -1
  750. package/scripts/_dbg-preview-pixels.mjs +1 -1
  751. package/scripts/_dbg-quality-pages-e2e.mjs +1 -1
  752. package/scripts/_dbg-qwen-acp-probe.mjs +30 -0
  753. package/scripts/_dbg-qwen-capture.mjs +21 -0
  754. package/scripts/_dbg-rail-tree-e2e.mjs +1 -1
  755. package/scripts/_dbg-real-driver-e2e.mjs +1 -1
  756. package/scripts/_dbg-real-scenario-timeline.log +55 -123
  757. package/scripts/_dbg-redesign-shots.mjs +1 -1
  758. package/scripts/_dbg-release-smoke.mjs +1 -1
  759. package/scripts/_dbg-resolve-probe.ts +6 -0
  760. package/scripts/_dbg-restart-persist.mjs +1 -1
  761. package/scripts/_dbg-sc001-dispatch.mjs +1 -1
  762. package/scripts/_dbg-scenario-final-shot.mjs +1 -1
  763. package/scripts/_dbg-scenario-phase-e2.mjs +1 -1
  764. package/scripts/_dbg-scenario-phase-e3.mjs +1 -1
  765. package/scripts/_dbg-scenario-phase1.mjs +1 -1
  766. package/scripts/_dbg-scenario-phase2.mjs +1 -1
  767. package/scripts/_dbg-scenario-phase3-monitor.mjs +1 -1
  768. package/scripts/_dbg-scenario-phase3.mjs +1 -1
  769. package/scripts/_dbg-settings-draft-probe.mjs +39 -0
  770. package/scripts/_dbg-settings-probe.mjs +33 -0
  771. package/scripts/_dbg-task-cancel-probe.mjs +66 -0
  772. package/scripts/_dbg-town-alarm-e2e.mjs +1 -1
  773. package/scripts/_dbg-town-daq-shot.mjs +1 -1
  774. package/scripts/_dbg-town-full-e2e.mjs +1 -1
  775. package/scripts/_dbg-town-gate.mjs +1 -1
  776. package/scripts/_dbg-town-ins-probe.mjs +1 -1
  777. package/scripts/_dbg-town-perf.mjs +1 -1
  778. package/scripts/_dbg-town-realtime.mjs +1 -1
  779. package/scripts/_dbg-town-shot.py +25 -0
  780. package/scripts/_dbg-town-shot3.mjs +1 -1
  781. package/scripts/_dbg-town-smoke.mjs +54 -0
  782. package/scripts/_dbg-town-truth.mjs +1 -1
  783. package/scripts/_dbg-town-truth2.mjs +1 -1
  784. package/scripts/_dbg-trend-expand-test.mjs +1 -1
  785. package/scripts/_dbg-twindaq-focus.mjs +1 -1
  786. package/scripts/_dbg-ui-polish-shot.mjs +1 -1
  787. package/scripts/_dbg-ui-polish-verify1.mjs +1 -1
  788. package/scripts/_dbg-ui-polish-verify2.mjs +1 -1
  789. package/scripts/_dbg-ui-polish-verify3.mjs +1 -1
  790. package/scripts/_dbg-ui-polish-verify4.mjs +1 -1
  791. package/scripts/_dbg-unify-shot.mjs +1 -1
  792. package/scripts/_dbg-uplink-probe.mjs +1 -1
  793. package/scripts/_dbg-wizard-preview-shot.mjs +1 -1
  794. package/scripts/_dbg-wizard-ui-e2e.mjs +1 -1
  795. package/scripts/_dbg-ws-probe.mjs +1 -1
  796. package/scripts/_dbg-wsdot-sanity.mjs +1 -1
  797. package/scripts/_node-state-probe.mjs +1 -1
  798. package/scripts/_tmp-args-probe.mjs +20 -0
  799. package/scripts/_tmp-cyc-entry.mjs +8 -0
  800. package/scripts/_tmp-cyc-main.mjs +5 -0
  801. package/scripts/_tmp-cyc-mod.mjs +2 -0
  802. package/scripts/_tmp-cycle-a.mjs +6 -0
  803. package/scripts/_tmp-cycle-b.mjs +2 -0
  804. package/scripts/_tmp-cycle-probe.mjs +4 -0
  805. package/scripts/_tmp-entry-variant.mjs +2 -0
  806. package/scripts/_tmp-help-probe.mjs +19 -0
  807. package/scripts/_tmp-help-probe2.mjs +2 -0
  808. package/scripts/_tmp-trace-preload.mjs +1 -0
  809. package/scripts/aml-agent-bridge.ts +230 -0
  810. package/scripts/aml-industrial-loop.ts +232 -0
  811. package/scripts/aml-ui-smoke.mjs +67 -0
  812. package/scripts/aw-start-smoke.mjs +194 -0
  813. package/scripts/design-verify-templates.mjs +1 -1
  814. package/scripts/device-line-restore.mjs +1 -1
  815. package/scripts/e2e-aml.ts +259 -0
  816. package/scripts/e2e-config-groups.mjs +238 -0
  817. package/scripts/e2e-full-closedloop.mjs +911 -0
  818. package/scripts/e2e-full-scenario.ts +321 -0
  819. package/scripts/e2e-harness-consistency.ts +204 -0
  820. package/scripts/e2e-multi-harness.ts +233 -76
  821. package/scripts/e2e-plc-plugin-closedloop.mjs +518 -0
  822. package/scripts/e2e-real-scenario.mjs +466 -452
  823. package/scripts/e2e-template-isolation.mjs +2 -2
  824. package/scripts/experiment-castfilm-closedloop.mjs +423 -0
  825. package/scripts/experiment-castfilm-finish.mjs +194 -0
  826. package/scripts/experiment-castfilm-ui-shot.mjs +52 -0
  827. package/scripts/experiment-castfilm-viz.mjs +172 -0
  828. package/scripts/production-closed-loop-e2e.mjs +78 -29
  829. package/scripts/test-aml-integration.ts +159 -0
  830. package/scripts/test-aml-job.ts +174 -0
  831. package/scripts/test-aml-unit.ts +184 -0
  832. package/scripts/test-cli-exit.mjs +235 -0
  833. package/scripts/test-daq-frame-race.mjs +310 -0
  834. package/scripts/test-data-root.mjs +208 -0
  835. package/scripts/test-log-flooding.mjs +160 -0
  836. package/scripts/test-lru.mjs +78 -0
  837. package/scripts/test-memory-month-query.mjs +62 -0
  838. package/scripts/test-plugin-hardening.mjs +45 -0
  839. package/scripts/test-rollback-index.mjs +79 -0
  840. package/scripts/test-sdk-surface.mjs +155 -0
  841. package/scripts/three-system-e2e.mjs +662 -448
  842. package/scripts/town-scene-clear.mjs +1 -1
  843. package/sdk/client.d.mts +110 -0
  844. package/sdk/client.mjs +144 -124
  845. package/sdk/context.mjs +161 -1
  846. package/sdk/index.d.mts +37 -5
  847. package/sdk/index.mjs +44 -41
  848. package/sdk/lifecycle.mjs +4 -1
  849. package/server/api/plugins/i18n.get.ts +12 -0
  850. package/server/api/system/config-groups/[id].delete.ts +21 -0
  851. package/server/api/system/config-groups/[id].patch.ts +26 -0
  852. package/server/api/system/config-groups/index.get.ts +21 -0
  853. package/server/api/system/config-groups/index.post.ts +33 -0
  854. package/server/api/system/settings/events.get.ts +8 -4
  855. package/server/api/workshop/agent-tools/bindings/[id].delete.ts +6 -1
  856. package/server/api/workshop/agent-tools/bindings/[id].patch.ts +12 -3
  857. package/server/api/workshop/agent-tools/bindings/index.get.ts +29 -2
  858. package/server/api/workshop/agent-tools/invoke.post.ts +30 -5
  859. package/server/api/workshop/aml/datasets/[id]/preview.get.ts +68 -0
  860. package/server/api/workshop/aml/datasets/[id].get.ts +24 -0
  861. package/server/api/workshop/aml/datasets/index.get.ts +20 -0
  862. package/server/api/workshop/aml/datasets/index.post.ts +27 -0
  863. package/server/api/workshop/aml/experiments/index.get.ts +35 -0
  864. package/server/api/workshop/aml/index.get.ts +24 -0
  865. package/server/api/workshop/aml/jobs/[id]/cancel.post.ts +21 -0
  866. package/server/api/workshop/aml/jobs/[id]/logs.get.ts +23 -0
  867. package/server/api/workshop/aml/jobs/[id]/retry.post.ts +20 -0
  868. package/server/api/workshop/aml/jobs/[id].get.ts +23 -0
  869. package/server/api/workshop/aml/jobs/index.get.ts +26 -0
  870. package/server/api/workshop/aml/jobs/index.post.ts +44 -0
  871. package/server/api/workshop/aml/models/[id]/predict.post.ts +24 -0
  872. package/server/api/workshop/aml/models/[id]/promote.post.ts +30 -0
  873. package/server/api/workshop/aml/models/index.get.ts +48 -0
  874. package/server/api/workshop/daq/[id].delete.ts +6 -0
  875. package/server/api/workshop/dcw/[id].patch.ts +14 -2
  876. package/server/api/workshop/hitl/respond.post.ts +3 -1
  877. package/server/api/workshop/teams/[id]/plugins/index.get.ts +36 -0
  878. package/server/api/workshop/teams/[id]/plugins/index.put.ts +42 -0
  879. package/server/api/workshop/teams/index.post.ts +13 -0
  880. package/server/api/workshop/users/me.get.ts +5 -0
  881. package/server/api/workshop/ws.ts +14 -2
  882. package/server/data/daqs.json +1648 -123
  883. package/server/data/dcw-lines.json +301 -0
  884. package/server/data/dcw-products.json +140 -0
  885. package/server/data/dcw-recipes.json +890 -0
  886. package/server/data/dcw-rollback.json +11591 -5740
  887. package/server/data/dcw-runs.json +3745 -3559
  888. package/server/data/dcw-templates.json +120 -0
  889. package/server/data/dcw-writes.json +1800 -0
  890. package/server/data/dcws.json +1576 -287
  891. package/server/data/line-runs.json +137 -27
  892. package/server/harness/pi-aw-tools.mjs +51 -0
  893. package/server/plugins/dev-stability-guard.ts +63 -63
  894. package/server/plugins/system-config.ts +10 -11
  895. package/server/plugins/workshop.ts +10 -0
  896. package/server/plugins-builtin/diag-bridge/client.mjs +84 -0
  897. package/server/plugins-builtin/diag-bridge/i18n.json +72 -0
  898. package/server/plugins-builtin/diag-bridge/index.mjs +127 -22
  899. package/server/plugins-builtin/rag-bridge/client.mjs +108 -0
  900. package/server/plugins-builtin/rag-bridge/i18n.json +60 -0
  901. package/server/plugins-builtin/rag-bridge/index.mjs +67 -20
  902. package/server/services/system-config.ts +610 -396
  903. package/server/services/workshop/agents/adapters/line-spawn.ts +15 -6
  904. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +530 -0
  905. package/server/services/workshop/agents/base-agent.ts +219 -0
  906. package/server/services/workshop/agents/binding-authz.ts +57 -0
  907. package/server/services/workshop/agents/claude-agent.ts +546 -30
  908. package/server/services/workshop/agents/codex-agent.ts +40 -116
  909. package/server/services/workshop/agents/copilot-agent.ts +136 -0
  910. package/server/services/workshop/agents/crush-agent.ts +107 -0
  911. package/server/services/workshop/agents/cursor-agent.ts +102 -0
  912. package/server/services/workshop/agents/dsh-agent.ts +578 -670
  913. package/server/services/workshop/agents/gemini-agent.ts +121 -0
  914. package/server/services/workshop/agents/goose-agent.ts +98 -0
  915. package/server/services/workshop/agents/harness-models.ts +305 -270
  916. package/server/services/workshop/agents/hermes-agent.ts +528 -0
  917. package/server/services/workshop/agents/host-tool-bridge.ts +53 -2
  918. package/server/services/workshop/agents/industrial-tools.ts +659 -7
  919. package/server/services/workshop/agents/omp-agent.ts +74 -59
  920. package/server/services/workshop/agents/opencode-agent.ts +936 -987
  921. package/server/services/workshop/agents/pi-agent.ts +108 -0
  922. package/server/services/workshop/agents/qwen-agent.ts +540 -0
  923. package/server/services/workshop/agents/registry.ts +117 -5
  924. package/server/services/workshop/agents/tool-approvals.ts +3 -3
  925. package/server/services/workshop/aml/aml.repo.ts +368 -0
  926. package/server/services/workshop/aml/clean.ts +120 -0
  927. package/server/services/workshop/aml/dataset-builder.ts +491 -0
  928. package/server/services/workshop/aml/gates.ts +121 -0
  929. package/server/services/workshop/aml/job-orchestrator.ts +650 -0
  930. package/server/services/workshop/aml/model-registry.ts +169 -0
  931. package/server/services/workshop/aml/predictor.ts +262 -0
  932. package/server/services/workshop/aml/python/aml_eval.py +171 -0
  933. package/server/services/workshop/aml/python/amlkit.py +120 -0
  934. package/server/services/workshop/aml/python/requirements.txt +7 -0
  935. package/server/services/workshop/aml/python/train-example.py +92 -0
  936. package/server/services/workshop/aml/python-runtime.ts +217 -0
  937. package/server/services/workshop/aml/retention.ts +98 -0
  938. package/server/services/workshop/aml/runtime.ts +45 -0
  939. package/server/services/workshop/aml/spec.ts +63 -0
  940. package/server/services/workshop/aml/stats.ts +140 -0
  941. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -1
  942. package/server/services/workshop/daq/daq-controller.ts +147 -19
  943. package/server/services/workshop/daq/daq-node.repo.ts +13 -11
  944. package/server/services/workshop/daq/daq-runtime.ts +11 -0
  945. package/server/services/workshop/daq/drivers.ts +89 -8
  946. package/server/services/workshop/db/aml-team-seeds.ts +118 -0
  947. package/server/services/workshop/db/channel-plugins.repo.ts +27 -1
  948. package/server/services/workshop/db/database.ts +89 -1
  949. package/server/services/workshop/db/memory.repo.ts +31 -0
  950. package/server/services/workshop/db/user.repo.ts +9 -0
  951. package/server/services/workshop/dcw/dcw-controller.ts +33 -7
  952. package/server/services/workshop/dcw/dcw-line.repo.ts +5 -3
  953. package/server/services/workshop/dcw/dcw-node.repo.ts +4 -4
  954. package/server/services/workshop/dcw/dcw-product.repo.ts +8 -8
  955. package/server/services/workshop/dcw/dcw-recipe.repo.ts +6 -7
  956. package/server/services/workshop/dcw/dcw-runtime.ts +16 -2
  957. package/server/services/workshop/dcw/dcw-templates.ts +4 -4
  958. package/server/services/workshop/dcw/line-run.ts +5 -5
  959. package/server/services/workshop/dcw/recipe-rollback-manager.ts +3 -1
  960. package/server/services/workshop/dcw/recipe-rollback.repo.ts +155 -52
  961. package/server/services/workshop/logger.ts +145 -3
  962. package/server/services/workshop/plugins/host.mjs +854 -566
  963. package/server/services/workshop/prompts/loader.ts +32 -6
  964. package/server/services/workshop/runtime/agent-runtime.ts +32 -3
  965. package/server/services/workshop/runtime/manager.ts +53 -13
  966. package/server/services/workshop/runtime/scheduler-loop.ts +18 -1
  967. package/server/services/workshop/scene/scene-layout.repo.ts +5 -5
  968. package/server/services/workshop/settings.ts +64 -0
  969. package/shared/config/engine.mjs +5 -0
  970. package/shared/config/groups.mjs +220 -0
  971. package/shared/config/home.mjs +11 -2
  972. package/shared/config/schema.json +31 -6
  973. package/shared/daq-protocol.ts +6 -0
  974. package/shared/lru.mjs +94 -0
  975. package/shared/workshop-protocol.ts +2 -2
  976. package/.output/public/_nuxt/2jaJHWIJ.js +0 -1
  977. package/.output/public/_nuxt/B8kt898d.js +0 -1
  978. package/.output/public/_nuxt/BFGpEo8S.js +0 -1
  979. package/.output/public/_nuxt/BG4zduPf.js +0 -14
  980. package/.output/public/_nuxt/BHcpzI2n.js +0 -19
  981. package/.output/public/_nuxt/BWyR3awA.js +0 -1
  982. package/.output/public/_nuxt/Bc89zKq2.js +0 -1
  983. package/.output/public/_nuxt/BetmGSO4.js +0 -1
  984. package/.output/public/_nuxt/BowTbasd.js +0 -1
  985. package/.output/public/_nuxt/BvtknqSC2.js +0 -1
  986. package/.output/public/_nuxt/BytVi9VX2.js +0 -4
  987. package/.output/public/_nuxt/CJviSvm-.js +0 -1
  988. package/.output/public/_nuxt/CTfqWGdy.js +0 -1
  989. package/.output/public/_nuxt/Cb3SnTM8.js +0 -1
  990. package/.output/public/_nuxt/Chc5pfAA.js +0 -1
  991. package/.output/public/_nuxt/CobSUzQv.js +0 -2
  992. package/.output/public/_nuxt/D95h62Jn.js +0 -1
  993. package/.output/public/_nuxt/DGAOugLt.js +0 -1
  994. package/.output/public/_nuxt/DHbTyoAV.js +0 -1
  995. package/.output/public/_nuxt/DfLUN8kY.js +0 -1
  996. package/.output/public/_nuxt/DnziMlcX.js +0 -1
  997. package/.output/public/_nuxt/DvgKXPgu2.js +0 -13
  998. package/.output/public/_nuxt/Q_SJDSgx.js +0 -1
  999. package/.output/public/_nuxt/_id_.DdbYeLqn.css +0 -1
  1000. package/.output/public/_nuxt/_wsId_.BqWBlY7X.css +0 -1
  1001. package/.output/public/_nuxt/agents.CB9Ck7VQ.css +0 -1
  1002. package/.output/public/_nuxt/bFnZa2yd.js +0 -1
  1003. package/.output/public/_nuxt/builds/meta/f7a8e33d-5422-45ac-895d-27168f97e3ad.json +0 -1
  1004. package/.output/public/_nuxt/daq.DGV9QS8d.css +0 -1
  1005. package/.output/public/_nuxt/default.BbgdTDCk.css +0 -1
  1006. package/.output/public/_nuxt/entry.BN02X8iR.css +0 -1
  1007. package/.output/public/_nuxt/pages.CG8UJ2TK.css +0 -1
  1008. package/.output/public/_nuxt/plugins.DpCuwaJt.css +0 -1
  1009. package/.output/public/_nuxt/rkVgzg62.js +0 -1
  1010. package/.output/public/_nuxt/settings.W6qrYAui.css +0 -1
  1011. package/.output/public/_nuxt/teams.BBXVkyKq.css +0 -1
  1012. package/.output/server/chunks/build/_id_-3Axz2-gV.mjs.map +0 -1
  1013. package/.output/server/chunks/build/_id_-CahfkmEt.mjs.map +0 -1
  1014. package/.output/server/chunks/build/agents-DuMiSWKp.mjs.map +0 -1
  1015. package/.output/server/chunks/build/alert-qJnjyRcP.mjs.map +0 -1
  1016. package/.output/server/chunks/build/channel-templates-BStqJ-of.mjs.map +0 -1
  1017. package/.output/server/chunks/build/daq-ChYCABz1.mjs.map +0 -1
  1018. package/.output/server/chunks/build/dcw-CcQNGggh.mjs.map +0 -1
  1019. package/.output/server/chunks/build/logs-D-2UyGtE.mjs.map +0 -1
  1020. package/.output/server/chunks/build/pages-Dfosfchr.mjs.map +0 -1
  1021. package/.output/server/chunks/build/permissions-B-hhZuzm.mjs.map +0 -1
  1022. package/.output/server/chunks/build/plugins-DZR0T4Mh.mjs.map +0 -1
  1023. package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs +0 -78
  1024. package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs.map +0 -1
  1025. package/.output/server/chunks/build/settings-BajN9TQW.mjs.map +0 -1
  1026. package/.output/server/chunks/build/tag-NO9jEqKy.mjs.map +0 -1
  1027. package/.output/server/chunks/build/teams-t2SkRlJP.mjs.map +0 -1
  1028. package/.output/server/chunks/build/tokens-DiCojbN8.mjs.map +0 -1
  1029. package/.output/server/chunks/build/town-C7QM8DYK.mjs.map +0 -1
  1030. package/.output/server/chunks/build/useDaqStream-BeA2X8KR.mjs.map +0 -1
  1031. package/.output/server/chunks/build/useDcwStream-BJW_MitY.mjs.map +0 -1
  1032. package/.output/server/chunks/build/users-B9SAdEtH.mjs.map +0 -1
  1033. /package/.output/public/_nuxt/{ORt9oDIy.js → ORt9oDIy2.js} +0 -0
@@ -19,10 +19,20 @@ import { daqRuntimeSettings } from '../settings'
19
19
  import { getDaqNodeRepo } from '../daq/daq-node.repo'
20
20
  import { findDaqTemplate } from '../daq/daq-templates'
21
21
  import { getRecipeRollBackManager } from '../dcw/recipe-rollback-manager'
22
- import { getOps } from '../ops/ops'
22
+ import { getOps, recordOps } from '../ops/ops'
23
23
  import { getDcwLineRepo } from '../dcw/dcw-line.repo'
24
24
  import { getDcwProductRepo } from '../dcw/dcw-product.repo'
25
25
  import { getDcwRecipeRepo } from '../dcw/dcw-recipe.repo'
26
+ import { readFileSync } from 'node:fs'
27
+ import { join } from 'node:path'
28
+ import { getAmlRuntime } from '../aml/runtime'
29
+ import { parseDatasetSpec } from '../aml/spec'
30
+ import { buildDataset, type AmlDatasetReport } from '../aml/dataset-builder'
31
+ import { cancelJob, jobLogsTail, runtimeStatus, submitJob } from '../aml/job-orchestrator'
32
+ import { transitionModel } from '../aml/model-registry'
33
+ import { predictProduction, readIoSpecFor } from '../aml/predictor'
34
+ import { alignToGrid } from '../aml/clean'
35
+ import type { AmlDatasetRow, AmlJobRow } from '../aml/aml.repo'
26
36
 
27
37
  export async function toolMyIndustrialNodes(agentId: string): Promise<{ text: string }> {
28
38
  const repo = getAgentNodeBindingRepo()
@@ -352,8 +362,35 @@ export async function toolDaqQuery(agentId: string, args: {
352
362
  return { text: `数采数据查询结果(${targets.length} 个节点):\n\n${sections.join('\n\n')}${prov}\n\n数值均为经标定钩子处理后的真实物理量纲;调整工艺前请结合 my_industrial_nodes 的节点判读方法与操作守则。` }
353
363
  }
354
364
 
365
+ /**
366
+ * 写向工具的统一鉴权闸门(绑定必查)。
367
+ *
368
+ * 背景:dcw_control / dcw_read 各自抄了一份 `repo.find(agentId, nodeId, 'dcw')` 判定,
369
+ * 而 dcw_rollback / dcw_judge 的「接管孤儿记录」分支忘了这一步 —— 任何 agent(哪怕
370
+ * 零绑定)都能借 record_id 或超时接管,驱动真实 PLC 执行回退。这是权限模型里的
371
+ * **默认放行**,与 node-bindings.repo 自述的「未绑定节点一律拒绝」直接冲突。
372
+ * 收敛为单一入口后,新增写向工具不会再漏。
373
+ *
374
+ * @returns 命中返回绑定对象;未命中返回可直接回给模型的拒绝文本(isError)
375
+ */
376
+ function requireDcwBinding(agentId: string, nodeId: string, action: string): { binding: AgentNodeBinding } | { error: { text: string, isError: true } } {
377
+ const repo = getAgentNodeBindingRepo()
378
+ const binding = nodeId ? repo.find(agentId, nodeId, 'dcw') : undefined
379
+ if (binding) return { binding }
380
+ const mine = repo.byAgent(agentId).filter(b => b.kind === 'dcw')
381
+ return {
382
+ error: {
383
+ text: mine.length
384
+ ? `无权${action}节点 ${nodeId || '(空)'}。你有权控制的数控节点:${mine.map(b => b.nodeId).join(', ')}(可用 my_industrial_nodes 查看物理含义)。`
385
+ : `你尚未绑定任何数控节点,无权${action}。请在数字孪生界面绑定数控节点。`,
386
+ isError: true,
387
+ },
388
+ }
389
+ }
390
+
355
391
  /** 工具:dcw_judge —— 对自己的优化记录落判定(keep/rollback/uncertain)。
356
- * 判定与执行分离:rollback 判定只入册,执行必须再调 dcw_rollback。 */
392
+ * 判定与执行分离:rollback 判定只入册,执行必须再调 dcw_rollback。
393
+ * 鉴权:记录所属节点必须仍在你的 dcw 绑定内 —— 接管孤儿记录同样受此约束。 */
357
394
  export async function toolDcwJudge(agentId: string, args: { record_id?: string, verdict?: string, reason?: string }): Promise<{ text: string, isError?: boolean }> {
358
395
  const recordId = String(args.record_id ?? '').trim()
359
396
  const verdict = String(args.verdict ?? '').trim() as 'keep' | 'rollback' | 'uncertain'
@@ -371,6 +408,9 @@ export async function toolDcwJudge(agentId: string, args: { record_id?: string,
371
408
  const takeover = record.agentId !== agentId && rb.isStale(record)
372
409
  if (record.agentId !== agentId && !takeover)
373
410
  return { text: `记录 ${recordId} 不是你发起的优化(发起者:${record.agentId ?? '用户'}),Agent 仅可判定自己的记录;他人记录请请用户在界面判定。`, isError: true }
411
+ // 接管是「时间」判定,不是「权限」判定 —— 权限必须单独查绑定(早先漏了这一步)
412
+ const auth = requireDcwBinding(agentId, record.nodeId, '判定该记录')
413
+ if ('error' in auth) return auth.error
374
414
  try {
375
415
  const finalReason = takeover ? `[接管孤儿记录,原属主 ${record.agentId ?? '?'} 超时未判定] ${reason}` : reason
376
416
  const updated = rb.judge(recordId, verdict, finalReason, 'agent', agentId, { takeover, actorName: agentBadgeLabel(agentId) })
@@ -387,6 +427,8 @@ export async function toolDcwJudge(agentId: string, args: { record_id?: string,
387
427
  }
388
428
 
389
429
  /** 工具:dcw_rollback —— 执行回退(自己的记录直接执行;他人记录需用户在界面执行)。
430
+ * 鉴权:节点必须绑定给该 agent(record_id 路径先解析出 record.nodeId);
431
+ * manual 模式绑定与 dcw_control 同源 —— 回退也会改 PLC,必须推请用户确认。
390
432
  * args: record_id(回退该记录到其 from 值)或 node_id(单步撤销到最近稳定锚);to = 指定目标锚。 */
391
433
  export async function toolDcwRollback(agentId: string, args: { record_id?: string, node_id?: string, to?: string }): Promise<{ text: string, isError?: boolean }> {
392
434
  const rb = getRecipeRollBackManager()
@@ -396,17 +438,39 @@ export async function toolDcwRollback(agentId: string, args: { record_id?: strin
396
438
  if (!recordId && !nodeId)
397
439
  return { text: 'record_id 或 node_id 至少提供一个。', isError: true }
398
440
  try {
399
- if (recordId) {
400
- const record = rb.recordById(recordId)
401
- if (!record)
402
- return { text: `优化记录 ${recordId} 不存在。`, isError: true }
441
+ // 归属解析:record_id 路径的节点来自记录本身,node_id 路径直接用入参
442
+ const record = recordId ? rb.recordById(recordId) : undefined
443
+ if (recordId && !record)
444
+ return { text: `优化记录 ${recordId} 不存在。`, isError: true }
445
+ const targetNodeId = record?.nodeId ?? nodeId
446
+ if (record) {
403
447
  const takeover = record.agentId !== agentId && rb.isStale(record)
404
448
  if (record.agentId !== agentId && !takeover)
405
449
  return { text: `记录 ${recordId} 不是你发起的优化(发起者:${record.agentId ?? '用户'}),回退他人记录请请用户在数采中心/产线详情执行;若原属主已消失(超时未判定),可先 dcw_judge 接管后再回退。`, isError: true }
450
+ }
451
+ // 授权闸门(早先整段缺失 → 任意 agent 可回退任意节点)
452
+ const auth = requireDcwBinding(agentId, targetNodeId, '回退')
453
+ if ('error' in auth) return auth.error
454
+ // manual 模式:回退是真实 PLC 写入,与 dcw_control 同源推请用户批准
455
+ if (auth.binding.mode === 'manual') {
456
+ const node = getDcwController().byId(targetNodeId)
457
+ const approvals = getToolApprovals()
458
+ if (approvals.hasPendingFor(agentId, targetNodeId))
459
+ return { text: '你对该节点已有一条待审批指令,请等待用户处理后再发新的回退请求(避免审批堆积)。', isError: true }
460
+ const detail = `${node?.name ?? targetNodeId} 回退到${record ? `记录 ${recordId} 的 from 值` : '最近稳定锚'}${to ? `(${to})` : ''}`
461
+ const ap = await approvals.request(agentId, targetNodeId, 'dcw', detail)
462
+ if (!ap.approved) {
463
+ return { text: `回退未执行:用户${ap.comment.includes('超时') ? '未在时限内批准(超时)' : '拒绝了本次回退'}。用户备注:${ap.comment || '(无)'}` }
464
+ }
465
+ // 审批期间绑定可能已被解除:批准时二次校验(与 dcw_control 同口径)
466
+ if (!getAgentNodeBindingRepo().find(agentId, targetNodeId, 'dcw'))
467
+ return { text: '回退未执行:审批通过时你的该节点绑定已被解除(权限在批准时失效)。', isError: true }
468
+ }
469
+ if (record) {
406
470
  const fresh = await rb.rollbackRecord(recordId, agentId, 'agent', undefined, { actorName: agentBadgeLabel(agentId) })
407
471
  return { text: `回退已执行:记录 ${recordId} 标记 rolled-back;下发恢复值 ${fresh?.params[0]?.to}${'(以回读为准)'};新回退记录 ${fresh?.id} 已入册。请 daq_query 复测确认恢复。` }
408
472
  }
409
- const fresh = await rb.rollbackNode(nodeId, agentId, 'agent', to, { actorName: agentBadgeLabel(agentId) })
473
+ const fresh = await rb.rollbackNode(targetNodeId, agentId, 'agent', to, { actorName: agentBadgeLabel(agentId) })
410
474
  return { text: `节点单步回退已执行:恢复到最近稳定锚值;新回退记录 ${fresh?.id} 已入册。请 daq_query 复测确认恢复。` }
411
475
  }
412
476
  catch (err) {
@@ -868,3 +932,591 @@ export async function toolRecipeRollback(agentId: string, args: {
868
932
  return { text: `回退失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
869
933
  }
870
934
  }
935
+
936
+ // ================================================================
937
+ // AML 自动建模工具族(aml_*):数据集 → 训练作业 → 实验谱系 → 模型晋升 → 影子参考
938
+ // 权限模型:数据集构建节点级鉴权(daq 绑定,只缩不放)+ 归属产线一致;晋升走 HITL 人工审批;
939
+ // 作业提交/取消按 agentId 归因( submitJob 内部已记 ops,工具层不重复记提交动作)。
940
+ // ================================================================
941
+
942
+ /** recordOps 的 AML 分类(与 job-orchestrator/model-registry 的 kind='aml' 同源;仓储联合类型暂未列 'aml',此处收口断言) */
943
+ const AML_AUDIT_KIND = 'aml' as unknown as 'system'
944
+
945
+ function amlErr(text: string): { text: string, isError: true } {
946
+ return { text, isError: true }
947
+ }
948
+
949
+ /** 数值展示(4 位有效小数;空值统一 '-') */
950
+ function fmtAmlNum(v: number | null | undefined, digits = 4): string {
951
+ if (v == null || !Number.isFinite(v)) return '-'
952
+ return String(Number(v.toFixed(digits)))
953
+ }
954
+
955
+ function amlNodeName(nodeId: string): string {
956
+ return getDaqNodeRepo().byId(nodeId)?.name ?? nodeId
957
+ }
958
+
959
+ function amlNodeUnit(nodeId: string): string {
960
+ const n = getDaqNodeRepo().byId(nodeId)
961
+ return n?.unit ?? findDaqTemplate(n?.templateKey ?? '')?.unit ?? ''
962
+ }
963
+
964
+ /** 数据集构建报告惰性读(report.json 与 manifest 同目录) */
965
+ function amlReportOf(dataset: AmlDatasetRow): AmlDatasetReport | null {
966
+ try {
967
+ return JSON.parse(readFileSync(join(dataset.path, 'report.json'), 'utf8')) as AmlDatasetReport
968
+ }
969
+ catch {
970
+ return null
971
+ }
972
+ }
973
+
974
+ /** 门禁报告 → 逐项文本(解析失败降级为原始串) */
975
+ function amlGatesLines(gatesJson: string | null): string {
976
+ if (!gatesJson) return ''
977
+ try {
978
+ const g = JSON.parse(gatesJson) as { checks?: Array<{ id: string, name: string, value: number | null, threshold: number | null, pass: boolean, detail: string }> }
979
+ if (!g.checks?.length) return ''
980
+ return g.checks
981
+ .map(c => ` ${c.id} ${c.pass ? '✓' : '✗'} ${c.name}: ${c.detail}`)
982
+ .join('\n')
983
+ }
984
+ catch {
985
+ return ` (门禁数据解析失败) ${gatesJson.slice(0, 120)}`
986
+ }
987
+ }
988
+
989
+ /** 作业行 → 详情卡片(状态/阶段/进度/指标/门禁逐项/错误) */
990
+ function amlJobCard(job: AmlJobRow): string {
991
+ const gates = amlGatesLines(job.gatesJson)
992
+ let metrics = ''
993
+ try {
994
+ const m = JSON.parse(job.metricsJson ?? '{}') as { oneStepVal?: { windows?: number, nrmse?: number } | null, oneStepTest?: { windows?: number, nrmse?: number } | null, rolloutTest?: { windows?: number, nrmse?: number, horizon?: number } | null }
995
+ const parts: string[] = []
996
+ if (m.oneStepVal) parts.push(`单步验证 NRMSE=${fmtAmlNum(m.oneStepVal.nrmse)}(${m.oneStepVal.windows ?? '?'} 窗)`)
997
+ if (m.oneStepTest) parts.push(`单步测试 NRMSE=${fmtAmlNum(m.oneStepTest.nrmse)}(${m.oneStepTest.windows ?? '?'} 窗)`)
998
+ if (m.rolloutTest) parts.push(`滚动测试 NRMSE=${fmtAmlNum(m.rolloutTest.nrmse)}(horizon=${m.rolloutTest.horizon ?? '?'})`)
999
+ metrics = parts.join(' | ')
1000
+ }
1001
+ catch { /* 无指标 */ }
1002
+ return [
1003
+ `■ 作业 ${job.id}`,
1004
+ ` 状态 ${job.status} | 阶段 ${job.stage || '-'} | 进度 ${job.progress}% | purpose=${job.purpose}`,
1005
+ ` dataset: ${job.datasetId} | 提交者: ${job.agentId || '-'} | 重试 ${job.retryCount}/2`,
1006
+ ` 创建 ${job.createdAt.slice(0, 19).replace('T', ' ')}${job.startedAt ? ` | 开跑 ${job.startedAt.slice(0, 19).replace('T', ' ')}` : ''}${job.endedAt ? ` | 结束 ${job.endedAt.slice(0, 19).replace('T', ' ')}` : ''}`,
1007
+ metrics ? ` 指标: ${metrics}` : null,
1008
+ gates ? ` 门禁逐项:\n${gates}` : ' 门禁: 未产出(作业未完成评估)',
1009
+ job.error ? ` 错误: ${job.error}` : null,
1010
+ ].filter(x => x !== null).join('\n')
1011
+ }
1012
+
1013
+ /** 工具:aml_node_catalog —— 我可用的 AML 建模节点(daq 绑定面;物理语义 + 近 24h 批次数据可用性) */
1014
+ export async function toolAmlNodeCatalog(agentId: string): Promise<{ text: string }> {
1015
+ const bindings = getAgentNodeBindingRepo().byAgent(agentId).filter(b => b.kind === 'daq')
1016
+ if (bindings.length === 0) {
1017
+ return { text: '你尚未绑定任何数采节点,AML 自动建模工具不可用(数据集构建要求所用节点均有你的 daq 绑定,绑定只缩不放)。请在数字孪生界面绑定数采节点后重试。' }
1018
+ }
1019
+ const { getTsdb, tsdbReady } = await import('../daq/storage')
1020
+ await tsdbReady
1021
+ const tsdb = getTsdb()
1022
+ const from24h = Date.now() - 24 * 3_600_000
1023
+ const cards: string[] = []
1024
+ for (const b of bindings) {
1025
+ const node = getDaqNodeRepo().byId(b.nodeId)
1026
+ if (!node) continue
1027
+ const tpl = findDaqTemplate(node.templateKey)
1028
+ let dataTag = '近 24h 无批次数据(产线未运行?建模前先确认采集)'
1029
+ try {
1030
+ const pts = await tsdb.query(b.nodeId, { fromMs: from24h, toMs: Date.now(), limit: 1 })
1031
+ if (pts.length > 0) dataTag = '近 24h 有批次打标数据(可建模)'
1032
+ }
1033
+ catch { /* 时序库异常按无数据处理 */ }
1034
+ const lineTxt = node.lineId
1035
+ ? `${getDcwLineRepo().byId(node.lineId)?.name ?? node.lineId}(${node.lineId})`
1036
+ : '未分配产线(无批次打标,不能参与建模)'
1037
+ cards.push(
1038
+ `■ ${node.name} · node_id=${node.id}\n`
1039
+ + ` 物理量 ${tpl?.ch ?? node.templateKey} | 单位 ${node.unit} | 正常量程 ${node.min}~${node.max}${node.unit}\n`
1040
+ + ` 产线: ${lineTxt} | 数据: ${dataTag}${tpl?.semantics ? `\n 语义: ${tpl.semantics.slice(0, 160)}` : ''}`,
1041
+ )
1042
+ }
1043
+ return {
1044
+ text: `你可用的 AML 建模节点(${cards.length} 个 daq 绑定):\n\n${cards.join('\n\n')}\n\n---\n建模路径:aml_dataset_build(选 control/target 节点组数据集)→ aml_job_submit(提交训练代码)→ aml_job_status / aml_job_logs 轮询 → aml_leaderboard 看实验谱系 → aml_model_promote(lead 专属,人工审批)→ aml_model_reference(调参前查影子参考)。\nrole 语义:control=可控输入(未来轨迹已知)/ target=预测目标(必选 ≥1)/ feature=仅历史特征。`,
1045
+ }
1046
+ }
1047
+
1048
+ /** 工具:aml_dataset_build —— 组建训练数据集(节点级鉴权:daq 绑定 + 归属产线一致;隔离三元组防配方串味) */
1049
+ export async function toolAmlDatasetBuild(agentId: string, args: {
1050
+ line_id?: string
1051
+ product_id?: string
1052
+ recipe_id?: string
1053
+ nodes?: Array<{ node_id?: string, role?: string }>
1054
+ beat_ms?: number | string
1055
+ history_steps?: number | string
1056
+ horizon_steps?: number | string
1057
+ split_seed?: number | string
1058
+ val_ratio?: number | string
1059
+ test_ratio?: number | string
1060
+ purpose?: string
1061
+ note?: string
1062
+ run_ids?: string[]
1063
+ from_ms?: number | string
1064
+ to_ms?: number | string
1065
+ }): Promise<{ text: string, isError?: boolean }> {
1066
+ const lineId = String(args.line_id ?? '').trim()
1067
+ const productId = String(args.product_id ?? '').trim()
1068
+ const recipeId = String(args.recipe_id ?? '').trim()
1069
+ if (!lineId || !productId || !recipeId) {
1070
+ return amlErr('line_id / product_id / recipe_id 必填(隔离三元组,防配方串味;line_context 可查看当前批次的三个 id)。')
1071
+ }
1072
+ const beatMs = Number(args.beat_ms)
1073
+ const historySteps = Number(args.history_steps)
1074
+ const horizonSteps = Number(args.horizon_steps)
1075
+ if (!Number.isInteger(beatMs) || beatMs < 1000) return amlErr('beat_ms 必须为 ≥1000 的整数(数据对齐节拍,ms)。')
1076
+ if (!Number.isInteger(historySteps) || historySteps < 1 || historySteps > 2048) return amlErr('history_steps 必须为 1~2048 的整数(历史窗口步数)。')
1077
+ if (!Number.isInteger(horizonSteps) || horizonSteps < 1 || horizonSteps > 512) return amlErr('horizon_steps 必须为 1~512 的整数(预测步长)。')
1078
+ const nodes = (Array.isArray(args.nodes) ? args.nodes : [])
1079
+ .map(n => ({ nodeId: String(n?.node_id ?? '').trim(), role: String(n?.role ?? '').trim() }))
1080
+ .filter(n => n.nodeId)
1081
+ if (nodes.length < 2) return amlErr('nodes 至少 2 项({node_id, role}),且必须含 1 个 target(预测目标)。')
1082
+ if (nodes.some(n => !['control', 'feature', 'target'].includes(n.role))) return amlErr('nodes 的 role 必须为 control / feature / target。')
1083
+ if (!nodes.some(n => n.role === 'target')) return amlErr('nodes 必须含至少 1 个 target 节点(预测目标)。')
1084
+ // 鉴权:每个节点都要有该 Agent 的 daq 绑定,且归属参数给定的产线(绑定只缩不放)
1085
+ const repo = getAgentNodeBindingRepo()
1086
+ const daqBound = repo.byAgent(agentId).filter(b => b.kind === 'daq')
1087
+ for (const n of nodes) {
1088
+ if (!daqBound.some(b => b.nodeId === n.nodeId)) {
1089
+ return amlErr(`无权使用节点 ${n.nodeId}(无你的 daq 绑定;绑定只缩不放)。你有权访问的数采节点:${daqBound.map(b => b.nodeId).join(', ') || '(无)'},可先 aml_node_catalog 查看语义。`)
1090
+ }
1091
+ const nodeLine = getDaqNodeRepo().byId(n.nodeId)?.lineId ?? ''
1092
+ if (nodeLine !== lineId) {
1093
+ return amlErr(`节点 ${amlNodeName(n.nodeId)}(${n.nodeId})归属产线 ${nodeLine || '未分配'},与 line_id=${lineId} 不一致;数据集节点必须全部归属同一条产线(绑定只缩不放)。`)
1094
+ }
1095
+ }
1096
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
1097
+ try {
1098
+ const spec = parseDatasetSpec({
1099
+ lineId,
1100
+ productId,
1101
+ recipeId,
1102
+ runIds: Array.isArray(args.run_ids) ? args.run_ids.map(r => String(r)).filter(Boolean) : undefined,
1103
+ nodes: nodes.map(n => ({ nodeId: n.nodeId, role: n.role as 'control' | 'feature' | 'target' })),
1104
+ fromMs: Number(args.from_ms) || undefined,
1105
+ toMs: Number(args.to_ms) || undefined,
1106
+ beatMs,
1107
+ window: { historySteps, horizonSteps },
1108
+ split: {
1109
+ valRatio: Number.isFinite(Number(args.val_ratio)) ? Number(args.val_ratio) : 0.15,
1110
+ testRatio: Number.isFinite(Number(args.test_ratio)) ? Number(args.test_ratio) : 0.15,
1111
+ seed: Number.isFinite(Number(args.split_seed)) ? Math.trunc(Number(args.split_seed)) : 42,
1112
+ },
1113
+ purpose,
1114
+ note: args.note ? String(args.note) : undefined,
1115
+ })
1116
+ const { dataset, report } = await buildDataset(spec, { id: agentId, kind: 'agent' })
1117
+ recordOps({
1118
+ actor: agentId,
1119
+ actorName: agentBadgeLabel(agentId),
1120
+ actorKind: 'agent',
1121
+ action: 'aml.dataset.build',
1122
+ kind: AML_AUDIT_KIND,
1123
+ summary: `构建数据集 ${dataset.id}(行数 ${dataset.rowCount},批次 ${report.runsUsed.length},窗口 train/val/test ${report.windowCount.train}/${report.windowCount.val}/${report.windowCount.test})`,
1124
+ targetKind: 'aml_dataset',
1125
+ targetId: dataset.id,
1126
+ lineId: dataset.lineId,
1127
+ productId: dataset.productId,
1128
+ recipeId: dataset.recipeId,
1129
+ })
1130
+ const cleanLines = report.nodeSummaries.map((s) => {
1131
+ const c = report.cleaning[s.nodeId]
1132
+ return `- ${amlNodeName(s.nodeId)}(${s.nodeId},${s.role}):样本 ${fmtAmlNum(s.count, 0)},剔除率 ${(100 * s.cleanedRatio).toFixed(1)}%(状态 ${c?.droppedState ?? 0}/量程 ${c?.droppedRange ?? 0}/尖峰 ${c?.droppedHampel ?? 0}),插值 ${c?.interpolated ?? 0} 点,缺失率 ${(100 * s.missingRatio).toFixed(1)}%`
1133
+ })
1134
+ const lagLines = report.lagEstimates.map(l =>
1135
+ `- ${amlNodeName(l.controlId)} → ${amlNodeName(l.targetId)}:滞后 ${l.lagSteps} 拍(≈${fmtAmlNum((l.lagSteps * beatMs) / 1000, 1)}s),互相关 ${l.corr.toFixed(2)}`)
1136
+ const dropLines = report.runsDropped.map(d => `- ${d.runId}: ${d.reason}`)
1137
+ return {
1138
+ text: [
1139
+ `数据集构建完成:`,
1140
+ ` dataset_id: ${dataset.id}`,
1141
+ ` 三元组: 产线 ${dataset.lineId} / 产品 ${getDcwProductRepo().byId(dataset.productId)?.name ?? dataset.productId} / 配方 ${getDcwRecipeRepo().byId(dataset.recipeId)?.name ?? dataset.recipeId}(purpose=${purpose},beat=${beatMs}ms,history=${historySteps},horizon=${horizonSteps})`,
1142
+ ` 行数 ${dataset.rowCount} | 窗口 train ${report.windowCount.train} / val ${report.windowCount.val} / test ${report.windowCount.test} | 批次 ${report.runsUsed.length} 个参与构建`,
1143
+ cleanLines.length ? `\n逐节点清洗摘要:\n${cleanLines.join('\n')}` : null,
1144
+ lagLines.length ? `\n滞后估计(控制→目标,正 = 控制领先;训练/调参时参考):\n${lagLines.join('\n')}` : null,
1145
+ dropLines.length ? `\n丢弃批次(${dropLines.length}):\n${dropLines.join('\n')}` : null,
1146
+ `\n下一步:aml_dataset_stats { dataset_id: "${dataset.id}" } 看完整统计;确认后 aml_job_submit 提交训练(训练代码契约见该工具说明)。`,
1147
+ ].filter(x => x !== null).join('\n'),
1148
+ }
1149
+ }
1150
+ catch (err) {
1151
+ return { text: `数据集构建失败:${err instanceof Error ? err.message : String(err)}(常见原因:窗口内无批次打标数据/节点数据缺失率过高;可先 daq_query 确认目标时段数据)。`, isError: true }
1152
+ }
1153
+ }
1154
+
1155
+ /** 工具:aml_dataset_stats —— 数据集完整统计报告(逐节点统计/滞后/run 轮廓/窗口计数) */
1156
+ export async function toolAmlDatasetStats(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
1157
+ const datasetId = String(args.dataset_id ?? '').trim()
1158
+ if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
1159
+ const rt = getAmlRuntime()
1160
+ const dataset = rt.repo.dataset.get(datasetId)
1161
+ if (!dataset) return amlErr(`数据集 ${datasetId} 不存在(aml_node_catalog → aml_dataset_build 先建数据集)。`)
1162
+ const spec = (() => {
1163
+ try {
1164
+ return JSON.parse(dataset.specJson) as { window?: { historySteps?: number, horizonSteps?: number }, beatMs?: number, purpose?: string }
1165
+ }
1166
+ catch { return {} }
1167
+ })()
1168
+ const report = amlReportOf(dataset)
1169
+ if (!report) {
1170
+ return { text: `数据集 ${datasetId} 元数据:行数 ${dataset.rowCount},批次 ${dataset.runIds.length} 个,创建于 ${dataset.createdAt.slice(0, 19).replace('T', ' ')}(统计报告文件缺失,可能为旧版数据集)。` }
1171
+ }
1172
+ const beatMs = spec.beatMs ?? 1000
1173
+ const statLines = report.nodeSummaries.map(s =>
1174
+ `- ${amlNodeName(s.nodeId)}(${s.nodeId},${s.role}):n=${fmtAmlNum(s.count, 0)} 均值 ${fmtAmlNum(s.mean)} std ${fmtAmlNum(s.std)} | p05 ${fmtAmlNum(s.p05)} / p50 ${fmtAmlNum(s.p50)} / p95 ${fmtAmlNum(s.p95)} | 缺失率 ${(100 * s.missingRatio).toFixed(1)}% 清洗率 ${(100 * s.cleanedRatio).toFixed(1)}%`)
1175
+ const lagLines = report.lagEstimates.map(l =>
1176
+ `- ${amlNodeName(l.controlId)} → ${amlNodeName(l.targetId)}:滞后 ${l.lagSteps} 拍(≈${fmtAmlNum((l.lagSteps * beatMs) / 1000, 1)}s),互相关 ${l.corr.toFixed(2)}`)
1177
+ const profileLines = report.runProfiles.map(p =>
1178
+ `- ${p.runId.slice(0, 8)}: ${p.steps} 拍,目标均值 {${Object.entries(p.targetMeans).map(([k, v]) => `${amlNodeName(k)}=${fmtAmlNum(v, 3)}`).join(', ')}}`)
1179
+ return {
1180
+ text: [
1181
+ `数据集 ${datasetId} 统计报告(beat=${beatMs}ms,history=${spec.window?.historySteps ?? '?'} 拍,horizon=${spec.window?.horizonSteps ?? '?'} 拍,purpose=${spec.purpose ?? '-'})`,
1182
+ ` 三元组: ${dataset.lineId} / ${dataset.productId} / ${dataset.recipeId} | 行数 ${dataset.rowCount} | 批次 ${dataset.runIds.length}(${report.runsUsed.length} 参与构建)| 创建 ${dataset.createdAt.slice(0, 19).replace('T', ' ')}`,
1183
+ statLines.length ? `\n逐节点统计(train 切分):\n${statLines.join('\n')}` : null,
1184
+ lagLines.length ? `\n控制→目标滞后(互相关峰值,正 = 控制领先):\n${lagLines.join('\n')}` : null,
1185
+ profileLines.length ? `\nrun 轮廓(逐批次目标均值,漂移检测):\n${profileLines.join('\n')}` : null,
1186
+ `\n窗口计数:train ${report.windowCount.train} / val ${report.windowCount.val} / test ${report.windowCount.test}(byRun 分层切分,防同批泄漏)`,
1187
+ report.runsDropped.length > 0 ? `丢弃批次:\n${report.runsDropped.map(d => `- ${d.runId}: ${d.reason}`).join('\n')}` : null,
1188
+ `\n下一步:aml_job_submit { dataset_id: "${datasetId}", code } 提交训练。`,
1189
+ ].filter(x => x !== null).join('\n'),
1190
+ }
1191
+ }
1192
+
1193
+ /** 工具:aml_job_submit —— 提交训练作业(train.py 全文内联;归因 agentId;队列 FIFO) */
1194
+ export async function toolAmlJobSubmit(agentId: string, args: {
1195
+ dataset_id?: string
1196
+ code?: string
1197
+ change_note?: string
1198
+ params?: Record<string, unknown>
1199
+ seed?: number | string
1200
+ purpose?: string
1201
+ parent_experiment_id?: string
1202
+ }): Promise<{ text: string, isError?: boolean }> {
1203
+ const datasetId = String(args.dataset_id ?? '').trim()
1204
+ const code = typeof args.code === 'string' ? args.code : ''
1205
+ if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
1206
+ if (!code.trim()) return amlErr('code 必填:train.py 全文(单文件;契约见工具说明)。')
1207
+ if (code.length > 512_000) return amlErr(`code 过大(${Math.round(code.length / 1024)}KB),上限 500KB;精简训练代码(模型定义/训练循环拆薄)后重试。`)
1208
+ if (!/\bimport\s+amlkit\b/.test(code)) {
1209
+ return amlErr('code 必须 import amlkit(平台数据/进度/导出契约):amlkit.load_bundle(datasetPath) 取数、amlkit.report_progress(pct, note) 报进度、amlkit.export_torch_onnx(model, manifest) 导出。缺契约的作业必然失败。')
1210
+ }
1211
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : args.purpose === 'mpc_surrogate' ? 'mpc_surrogate' : undefined
1212
+ const changeNote = String(args.change_note ?? '').trim()
1213
+ if (!changeNote) return amlErr('change_note 必填:单组件改动纪律 —— 每次实验只改一个组件(网络结构/特征/超参之一),写清改了什么与预期,实验谱系靠它归因。')
1214
+ try {
1215
+ const job = submitJob({
1216
+ datasetId,
1217
+ purpose,
1218
+ changeNote,
1219
+ params: args.params && typeof args.params === 'object' && !Array.isArray(args.params) ? args.params : undefined,
1220
+ seed: Number.isInteger(Number(args.seed)) ? Number(args.seed) : undefined,
1221
+ parentExperimentId: String(args.parent_experiment_id ?? '').trim() || undefined,
1222
+ code,
1223
+ agent: { id: agentId },
1224
+ })
1225
+ const st = await runtimeStatus()
1226
+ return {
1227
+ text: [
1228
+ `训练作业已提交:`,
1229
+ ` job_id: ${job.id}`,
1230
+ ` dataset: ${job.datasetId} | purpose=${job.purpose} | seed=${fmtAmlNum(Number(job.budget.seed ?? 42), 0)} | change_note: ${changeNote}`,
1231
+ ` 队列: 排队 ${st.queued} 个(含本作业)/ 在跑 ${st.running} 个 | python ${st.python.ok ? (st.python.version ?? 'ok') : `不可用(${st.python.reason ?? '?'};作业会失败,请联系用户修复环境)`}`,
1232
+ `\n用 aml_job_status { job_id: "${job.id}" } 看状态/阶段/门禁,aml_job_logs { job_id: "${job.id}" } 看日志尾;训练完成后 aml_leaderboard 看谱系与门禁。`,
1233
+ ].join('\n'),
1234
+ }
1235
+ }
1236
+ catch (err) {
1237
+ return { text: `提交失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
1238
+ }
1239
+ }
1240
+
1241
+ /** 工具:aml_job_status —— 作业状态(单作业详情 / 缺省列最近 10 个) */
1242
+ export async function toolAmlJobStatus(_agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
1243
+ const rt = getAmlRuntime()
1244
+ const jobId = String(args.job_id ?? '').trim()
1245
+ if (jobId) {
1246
+ const job = rt.repo.job.get(jobId)
1247
+ if (!job) return amlErr(`作业 ${jobId} 不存在(aml_job_status 不带参数可列出最近 10 个)。`)
1248
+ return { text: `${amlJobCard(job)}\n\n轮询建议:training 阶段 30~60s 查一次;终态(done/failed)后看门禁与错误,失败原因可 in aml_job_logs 定位。` }
1249
+ }
1250
+ const jobs = rt.repo.job.list({ limit: 10 })
1251
+ if (jobs.length === 0) {
1252
+ return { text: '尚无训练作业。路径:aml_node_catalog 确认节点 → aml_dataset_build 组数据集 → aml_job_submit 提交训练。' }
1253
+ }
1254
+ const rows = jobs.map(j => `- ${j.id} [${j.status}] ${j.stage || '-'} ${j.progress}% dataset=${j.datasetId}${j.error ? ` | 错误: ${j.error.slice(0, 100)}` : ''}`)
1255
+ return { text: `最近 ${jobs.length} 个作业(新→旧):\n${rows.join('\n')}\n\n传 job_id 查看单作业详情(指标/门禁逐项/错误)。` }
1256
+ }
1257
+
1258
+ /** 工具:aml_job_logs —— 作业日志尾随(平台 ##AML 协议行 + 训练输出) */
1259
+ export async function toolAmlJobLogs(_agentId: string, args: { job_id?: string, lines?: number | string }): Promise<{ text: string, isError?: boolean }> {
1260
+ const jobId = String(args.job_id ?? '').trim()
1261
+ if (!jobId) return amlErr('job_id 必填(aml_job_status 不带参数可列出最近作业)。')
1262
+ const job = getAmlRuntime().repo.job.get(jobId)
1263
+ if (!job) return amlErr(`作业 ${jobId} 不存在。`)
1264
+ const n = Math.min(Math.max(Number(args.lines) || 80, 5), 400)
1265
+ const rows = jobLogsTail(jobId, n)
1266
+ if (rows.length === 0) {
1267
+ return { text: `作业 ${jobId} 暂无日志(${job.status === 'queued' ? '仍在排队,开跑后产生日志' : '日志未落盘或已被清理'});稍后重试或用 aml_job_status 看状态。` }
1268
+ }
1269
+ return { text: `作业 ${jobId} 日志尾(最近 ${rows.length} 行,时间正序;##AML 前缀行 = 平台协议事件):\n${rows.join('\n')}` }
1270
+ }
1271
+
1272
+ /** 工具:aml_job_cancel —— 取消排队/运行中的作业(归因入册) */
1273
+ export async function toolAmlJobCancel(agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
1274
+ const jobId = String(args.job_id ?? '').trim()
1275
+ if (!jobId) return amlErr('job_id 必填。')
1276
+ const rt = getAmlRuntime()
1277
+ const job = rt.repo.job.get(jobId)
1278
+ if (!job) return amlErr(`作业 ${jobId} 不存在。`)
1279
+ if (['done', 'failed', 'cancelled', 'timeout'].includes(job.status)) {
1280
+ return amlErr(`作业 ${jobId} 已是终态(${job.status}),无需取消;aml_job_status 复核。`)
1281
+ }
1282
+ const ok = cancelJob(jobId, { id: agentId, kind: 'agent' })
1283
+ if (!ok) return amlErr(`取消失败:作业 ${jobId} 不在排队/运行中(可能恰好结束);aml_job_status 复核。`)
1284
+ const dataset = rt.repo.dataset.get(job.datasetId)
1285
+ recordOps({
1286
+ actor: agentId,
1287
+ actorName: agentBadgeLabel(agentId),
1288
+ actorKind: 'agent',
1289
+ action: 'aml.job.cancel',
1290
+ kind: AML_AUDIT_KIND,
1291
+ summary: `取消训练作业 ${jobId}(原状态 ${job.status})`,
1292
+ targetKind: 'aml_job',
1293
+ targetId: jobId,
1294
+ lineId: dataset?.lineId,
1295
+ productId: dataset?.productId,
1296
+ recipeId: dataset?.recipeId,
1297
+ })
1298
+ return { text: `作业 ${jobId} 已取消(运行中的会终止进程树)。数据集 ${job.datasetId} 仍可复用;需要重训直接 aml_job_submit。` }
1299
+ }
1300
+
1301
+ /** 工具:aml_leaderboard —— 数据集的实验谱系与门禁对照(标当前最优) */
1302
+ export async function toolAmlLeaderboard(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
1303
+ const datasetId = String(args.dataset_id ?? '').trim()
1304
+ if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
1305
+ const rt = getAmlRuntime()
1306
+ const dataset = rt.repo.dataset.get(datasetId)
1307
+ if (!dataset) return amlErr(`数据集 ${datasetId} 不存在。`)
1308
+ const exps = rt.repo.experiment.listByDataset(datasetId, 50)
1309
+ if (exps.length === 0) {
1310
+ return { text: `数据集 ${datasetId}(${dataset.rowCount} 行)尚无实验:aml_job_submit 提交训练后,此处给出谱系与门禁对照。` }
1311
+ }
1312
+ const parsed = exps.map((e) => {
1313
+ let metrics: { oneStepTest?: { nrmse?: number }, rolloutTest?: { nrmse?: number } } = {}
1314
+ let gates: { passed?: boolean } = {}
1315
+ try {
1316
+ metrics = JSON.parse(e.metricsJson)
1317
+ }
1318
+ catch { /* 无指标 */ }
1319
+ try {
1320
+ gates = JSON.parse(e.gatesJson)
1321
+ }
1322
+ catch { /* 无门禁 */ }
1323
+ return { e, g1: metrics.oneStepTest?.nrmse ?? null, g2: metrics.rolloutTest?.nrmse ?? null, passed: gates.passed === true || e.status === 'gates_passed' }
1324
+ })
1325
+ const passers = parsed.filter(p => p.passed && p.g1 != null)
1326
+ const bestId = passers.length > 0 ? passers.reduce((a, b) => ((a.g1 ?? Infinity) <= (b.g1 ?? Infinity) ? a : b)).e.id : null
1327
+ const rows = parsed.map(p =>
1328
+ `- ${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 ? ' ★当前最优' : ''}`)
1329
+ const models = rt.repo.model.list({ limit: 100 }).filter(m => m.datasetId === datasetId)
1330
+ const modelLines = models.map(m => `- ${m.id} [${m.stage}] purpose=${m.purpose}(实验 ${m.experimentId})`)
1331
+ return {
1332
+ text: [
1333
+ `实验谱系(数据集 ${datasetId} · ${dataset.productId}/${dataset.recipeId} · ${exps.length} 条,新→旧):`,
1334
+ ...rows,
1335
+ modelLines.length > 0 ? `\n已登记模型(晋升对象;aml_leaderboard 最优 = 门禁通过且 G1 最小):` : null,
1336
+ ...modelLines,
1337
+ `\nG1=单步测试 NRMSE,G2=多步滚动 NRMSE(越小越好)。优化纪律:每次只改一个组件,change_note 写明;把最优模型推上生产用 aml_model_promote(lead 专属,需人工审批)。`,
1338
+ ].filter(x => x !== null).join('\n'),
1339
+ }
1340
+ }
1341
+
1342
+ /** 工具:aml_model_promote —— 模型晋升 shadow/production(lead 专属;HITL 人工审批;流转入册由 transitionModel 内部完成) */
1343
+ export async function toolAmlModelPromote(agentId: string, args: { model_id?: string, to_stage?: string }): Promise<{ text: string, isError?: boolean }> {
1344
+ // 治理硬守卫:晋升仅限 lead 实例(注入层过滤 + 分发层双重校验,HTTP 直调不可绕过)
1345
+ const roleRow = getAmlRuntime().db.prepare('SELECT role FROM channel_agents WHERE id = ? AND enabled = 1').get(agentId) as { role?: string } | undefined
1346
+ if (roleRow?.role !== 'lead') {
1347
+ return amlErr(`aml_model_promote 为 lead 专属工具:实例 ${agentId}(role=${roleRow?.role ?? '未知'})无权晋升模型。请由团队 lead 发起,晋升需人工 HITL 批准。`)
1348
+ }
1349
+ const modelId = String(args.model_id ?? '').trim()
1350
+ const toStage = String(args.to_stage ?? '').trim()
1351
+ if (!modelId) return amlErr('model_id 必填(aml_leaderboard 的「已登记模型」段可查)。')
1352
+ if (toStage !== 'shadow' && toStage !== 'production') return amlErr('to_stage 必须为 \'shadow\'(影子观测)或 \'production\'(生产生效)。')
1353
+ const rt = getAmlRuntime()
1354
+ const model = rt.repo.model.get(modelId)
1355
+ if (!model) return amlErr(`模型 ${modelId} 不存在。`)
1356
+ if (model.stage === toStage) return amlErr(`模型 ${modelId} 已是 ${toStage},无需流转。`)
1357
+ // production 预检:同组 (product, recipe, purpose) 旧生产将被退役
1358
+ let oldProdId: string | undefined
1359
+ if (toStage === 'production') {
1360
+ oldProdId = rt.repo.model
1361
+ .list({ stage: 'production', productId: model.productId, recipeId: model.recipeId, limit: 50 })
1362
+ .find(m => m.id !== modelId && m.purpose === model.purpose)?.id
1363
+ }
1364
+ // 同模型挂起审批去重(防审批面板堆积,与 dcw_control 同纪律)
1365
+ const approvals = getToolApprovals()
1366
+ if (approvals.hasPendingFor(agentId, modelId)) {
1367
+ return amlErr(`模型 ${modelId} 已有一条待审批的晋升请求,请等待用户处理后再发起新请求。`)
1368
+ }
1369
+ const detail = `AML 模型晋升:${modelId} ${model.stage} → ${toStage}(产品 ${model.productId} / 配方 ${model.recipeId} / purpose=${model.purpose}${oldProdId ? `;批准后原生产模型 ${oldProdId} 将自动退役` : ''})`
1370
+ const ap = await approvals.request(agentId, modelId, 'dcw', detail, { title: 'AML 模型晋升审批' })
1371
+ if (!ap.approved) {
1372
+ return { text: `人工未批准:模型 ${modelId} 保持 ${model.stage} 阶段。用户备注:${ap.comment || '(无)'}。可回炉重训(aml_job_submit)或换候选模型后再申请。` }
1373
+ }
1374
+ try {
1375
+ const r = transitionModel(modelId, toStage, agentBadgeLabel(agentId), 'agent')
1376
+ // 归属审计已由 transitionModel 内部 recordOps(aml.model.promote)完成,此处不重复记录
1377
+ return {
1378
+ text: `晋升完成:${modelId} ${r.from} → ${toStage}。${r.retiredId ? `原生产模型 ${r.retiredId} 已自动退役。` : ''}${toStage === 'shadow'
1379
+ ? '影子阶段:用 aml_model_reference 观测其预测与实际偏差,积累证据后再申请 production。'
1380
+ : '该模型已作为生产模型生效:aml_model_reference 的影子参考即来自它;调控 Agent 调参前请先查它。'}`,
1381
+ }
1382
+ }
1383
+ catch (err) {
1384
+ return { text: `晋升失败:${err instanceof Error ? err.message : String(err)}(审批已通过;若为并发竞态可刷新状态重试)。`, isError: true }
1385
+ }
1386
+ }
1387
+
1388
+ /** 工具:aml_model_reference —— 生产模型影子参考:拉最近历史组装模型输入 → 预测未来目标轨迹(调参前先问影子模型) */
1389
+ export async function toolAmlModelReference(agentId: string, args: {
1390
+ line_id?: string
1391
+ product_id?: string
1392
+ recipe_id?: string
1393
+ purpose?: string
1394
+ controls?: Record<string, number | string>
1395
+ steps?: number | string
1396
+ }): Promise<{ text: string, isError?: boolean }> {
1397
+ // 0. 绑定面:至少一个 daq 绑定;line_id 只缩不放
1398
+ const repo = getAgentNodeBindingRepo()
1399
+ const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
1400
+ if (daqBindings.length === 0) {
1401
+ return amlErr('你尚未绑定任何数采节点,无法组装影子参考所需的历史输入;请先绑定数采节点。')
1402
+ }
1403
+ const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
1404
+ const scopeLines = [...new Set(daqBindings.map(b => lineOf(b.nodeId)).filter(Boolean))]
1405
+ const lineFilter = String(args.line_id ?? '').trim()
1406
+ if (lineFilter && !scopeLines.includes(lineFilter)) {
1407
+ return amlErr(`产线 ${lineFilter} 不在你的负责范围(你绑定节点覆盖:${scopeLines.join(', ') || '无'};绑定只缩不放)。`)
1408
+ }
1409
+ const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
1410
+
1411
+ // 1. 解析 (productId, recipeId):参数给全用参数;缺省回退到候选产线的唯一活动批次
1412
+ let productId = String(args.product_id ?? '').trim()
1413
+ let recipeId = String(args.recipe_id ?? '').trim()
1414
+ let resolveHow = '参数指定'
1415
+ if (!productId || !recipeId) {
1416
+ const candidateLines = lineFilter ? [lineFilter] : scopeLines
1417
+ const runs = candidateLines
1418
+ .map(lid => getActiveLineRun(lid))
1419
+ .filter((r): r is NonNullable<ReturnType<typeof getActiveLineRun>> => !!r && !!r.productId && !!r.recipeId)
1420
+ if (runs.length === 1) {
1421
+ const run = runs[0]!
1422
+ if (!productId) productId = run.productId
1423
+ if (!recipeId) recipeId = run.recipeId
1424
+ resolveHow = `产线 ${run.lineId} 唯一活动批次 ${run.runId.slice(0, 8)}(产品「${run.productName}」/配方「${run.recipeName}」)`
1425
+ }
1426
+ else if (runs.length === 0) {
1427
+ return { text: `无法确定产品/配方:${candidateLines.length > 0 ? `产线 ${candidateLines.join(', ')}` : '你绑定节点所属产线'}当前无活动批次,且 product_id/recipe_id 未给全。请开跑后重试,或显式传 product_id 与 recipe_id(line_context 可查)。`, isError: true }
1428
+ }
1429
+ else {
1430
+ return { text: `无法确定产品/配方:候选产线存在多个活动批次(${runs.map(r => `${r.lineId} → ${r.productName}/${r.recipeName}`).join('; ')})。请传 line_id 缩小范围,或显式传 product_id 与 recipe_id。`, isError: true }
1431
+ }
1432
+ }
1433
+
1434
+ // 2. 生产模型(无则指引建模范式)
1435
+ const rt = getAmlRuntime()
1436
+ const model = rt.repo.model.productionOf(productId, recipeId, purpose)
1437
+ if (!model) {
1438
+ const cands = rt.repo.model.list({ productId, recipeId, limit: 20 })
1439
+ 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 证据。'}` }
1440
+ }
1441
+ // 3. 产线归属鉴权(绑定只缩不放;模型归属线经数据集追溯)
1442
+ const ds = rt.repo.dataset.get(model.datasetId)
1443
+ const modelLine = ds?.lineId ?? ''
1444
+ if (modelLine && !scopeLines.includes(modelLine)) {
1445
+ return amlErr(`模型 ${model.id} 归属产线 ${modelLine},不在你绑定节点覆盖的产线(${scopeLines.join(', ')})内;绑定只缩不放。`)
1446
+ }
1447
+
1448
+ // 4. io 契约 → 拉最近历史 → 网格对齐 → 组 [H][nAll](原始物理量,顺序 = allNodes)
1449
+ const io = readIoSpecFor(model.id)
1450
+ const H = io.historySteps
1451
+ const beatMs = io.beatMs
1452
+ const now = Date.now()
1453
+ const fromMs = now - H * beatMs - 5 * beatMs
1454
+ const { getTsdb, tsdbReady } = await import('../daq/storage')
1455
+ await tsdbReady
1456
+ const tsdb = getTsdb()
1457
+ const columns = new Map<string, number[]>()
1458
+ const shortage: string[] = []
1459
+ for (const nodeId of io.allNodes) {
1460
+ try {
1461
+ const pts = await tsdb.query(nodeId, { fromMs, toMs: now, limit: Math.min(Math.max(H * 10, 600), 5000) })
1462
+ const { grid } = alignToGrid(
1463
+ pts.map(p => ({ at: p.at, value: p.value ?? p.avg ?? 0 })).filter(p => Number.isFinite(p.value)),
1464
+ { beatMs, maxInterpMs: beatMs * 2 },
1465
+ )
1466
+ const tail = grid.slice(-H).map(g => g.value)
1467
+ if (tail.length < H) {
1468
+ shortage.push(`${amlNodeName(nodeId)}(${nodeId})仅 ${tail.length}/${H} 格点`)
1469
+ continue
1470
+ }
1471
+ columns.set(nodeId, tail)
1472
+ }
1473
+ catch (err) {
1474
+ shortage.push(`${amlNodeName(nodeId)}(${nodeId})查询失败:${err instanceof Error ? err.message : String(err)}`)
1475
+ }
1476
+ }
1477
+ if (shortage.length > 0) {
1478
+ return { text: `历史数据不足,无法组装模型输入:${shortage.join(';')}。需要从 ${new Date(fromMs).toISOString().slice(0, 16)} 起连续约 ${(H * beatMs / 60_000).toFixed(0)} 分钟的运行数据(产线须在跑);等数据积累后重试,或缩短 steps/换更短 history 的模型。`, isError: true }
1479
+ }
1480
+ const history: number[][] = []
1481
+ for (let i = 0; i < H; i++) history.push(io.allNodes.map(n => columns.get(n)![i]!))
1482
+
1483
+ // 5. 控制轨迹:controls 映射(节点 id → 值,常数外推 steps 行);缺省行持最后观测
1484
+ const steps = Math.max(1, Math.min(Number(args.steps) || io.horizonSteps, io.horizonSteps))
1485
+ const lastRow = history[history.length - 1]!
1486
+ const unknownKeys = args.controls ? Object.keys(args.controls).filter(k => !io.controlNodes.includes(k)) : []
1487
+ const controlRow = io.controlNodes.map((c) => {
1488
+ const provided = args.controls?.[c]
1489
+ const v = provided != null ? Number(provided) : Number.NaN
1490
+ return Number.isFinite(v) ? v : lastRow[io.allNodes.indexOf(c)]!
1491
+ })
1492
+ const controls: number[][] = Array.from({ length: steps }, () => [...controlRow])
1493
+
1494
+ // 6. 预测 + 人话报告
1495
+ try {
1496
+ const r = await predictProduction(productId, recipeId, purpose, { history, controls, steps })
1497
+ const header = `步 | ${r.targetNodes.map(t => `${amlNodeName(t)}(${amlNodeUnit(t)})`).join(' | ')}`
1498
+ const forecastLines = r.forecast.map((row, i) =>
1499
+ ` ${i + 1}(+${fmtAmlNum(((i + 1) * r.beatMs) / 1000, 0)}s) | ${row.map(v => fmtAmlNum(v, 3)).join(' | ')}`)
1500
+ const ctrlTxt = io.controlNodes.length > 0
1501
+ ? io.controlNodes.map((c) => {
1502
+ const provided = args.controls?.[c]
1503
+ return `${amlNodeName(c)}=${Number.isFinite(Number(provided)) ? Number(provided) : `${fmtAmlNum(lastRow[io.allNodes.indexOf(c)], 3)}(持最后观测)`}${amlNodeUnit(c)}`
1504
+ }).join(', ')
1505
+ : '无控制节点'
1506
+ return {
1507
+ text: [
1508
+ `影子模型参考(调参前先问影子模型;预测≠承诺,真实下发仍走 dcw_control 安全联锁):`,
1509
+ ` 模型 ${r.modelId}(stage=${r.stage},purpose=${purpose})| 三元组:产品 ${getDcwProductRepo().byId(productId)?.name ?? productId} / 配方 ${getDcwRecipeRepo().byId(recipeId)?.name ?? recipeId}(解析:${resolveHow})`,
1510
+ ` 输入:最近 ${H} 拍 × ${io.allNodes.length} 节点(beat=${beatMs}ms),截至 ${new Date(now).toISOString().slice(11, 19)};控制轨迹(共 ${steps} 步):${ctrlTxt}${unknownKeys.length > 0 ? `(已忽略非控制节点的键:${unknownKeys.join(', ')})` : ''}`,
1511
+ ` 预测(steps=${steps},每拍 ${beatMs / 1000}s):`,
1512
+ ` ${header}`,
1513
+ ...forecastLines,
1514
+ ` 假设: ${r.assumptions}`,
1515
+ `\n用法:把候选设定值作为 controls 传入(键 = 控制节点 id)对比不同方案的预测轨迹;选定后 dcw_control 下发并 daq_query 复测。`,
1516
+ ].join('\n'),
1517
+ }
1518
+ }
1519
+ catch (err) {
1520
+ return { text: `预测失败:${err instanceof Error ? err.message : String(err)}(模型 ${model.id};若为工件缺失可重训同规格数据集)。`, isError: true }
1521
+ }
1522
+ }