agentworkshop 0.7.49 → 0.7.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (883) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +409 -6
  2. package/.output/.AgentWorkShop/aml-python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  3. package/.output/.AgentWorkShop/aml-python/__pycache__/amlkit.cpython-312.pyc +0 -0
  4. package/.output/.AgentWorkShop/aml-python/__pycache__/train-example.cpython-312.pyc +0 -0
  5. package/.output/.AgentWorkShop/aml-python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  6. package/.output/.AgentWorkShop/aml-python/aml_eval.py +39 -6
  7. package/.output/.AgentWorkShop/aml-python/amlkit.py +222 -3
  8. package/.output/.AgentWorkShop/aml-python/train-hybrid-example.py +278 -32
  9. package/.output/.AgentWorkShop/prompts/host-tools.json +409 -6
  10. package/.output/.AgentWorkShop/schema.json +135 -133
  11. package/.output/nitro.json +1 -1
  12. package/.output/public/_nuxt/2_DkYoqD2.js +1 -0
  13. package/.output/public/_nuxt/8FXd9As6.js +1 -0
  14. package/.output/public/_nuxt/{d-w5jR8R.js → B3zB6K6m.js} +1 -1
  15. package/.output/public/_nuxt/{OXtV_ukR.js → B4ujjkUI.js} +1 -1
  16. package/.output/public/_nuxt/B9BmiUil.js +2 -0
  17. package/.output/public/_nuxt/B9QzrmgE.js +1 -0
  18. package/.output/public/_nuxt/BE7BrEw6.js +1 -0
  19. package/.output/public/_nuxt/{Cu8c3oMN2.js → BFZIll912.js} +1 -1
  20. package/.output/public/_nuxt/{ChtjzEpK2.js → BGAaKBeo2.js} +1 -1
  21. package/.output/public/_nuxt/BOmDHp5L.js +14 -0
  22. package/.output/public/_nuxt/BPou3U7b.js +1 -0
  23. package/.output/public/_nuxt/{CiTQY_n32.js → BXx9AxdF2.js} +1 -1
  24. package/.output/public/_nuxt/Bfe2qOYs.js +1 -0
  25. package/.output/public/_nuxt/BgEDwFMf.js +1 -0
  26. package/.output/public/_nuxt/BgnhB8r5.js +1 -0
  27. package/.output/public/_nuxt/Bhe953zV2.js +1 -0
  28. package/.output/public/_nuxt/{BITZvQBK.js → Bpkm4W5P.js} +1 -1
  29. package/.output/public/_nuxt/C4lagVdN2.js +1 -0
  30. package/.output/public/_nuxt/C5cf3T4d.js +1 -0
  31. package/.output/public/_nuxt/CBIoheY42.js +1 -0
  32. package/.output/public/_nuxt/{CN1CDAwe.js → CFQSjB1h.js} +1 -1
  33. package/.output/public/_nuxt/CFQyYMEn2.js +1 -0
  34. package/.output/public/_nuxt/CHrErv1E.js +1 -0
  35. package/.output/public/_nuxt/{fxWyOzyp2.js → CI2yXRr42.js} +1 -1
  36. package/.output/public/_nuxt/CIduggmC.js +1 -0
  37. package/.output/public/_nuxt/CU-mhG0-.js +1 -0
  38. package/.output/public/_nuxt/CXzfXC5M.js +1 -0
  39. package/.output/public/_nuxt/{H6pPjo0l.js → C_sjV3Ee.js} +1 -1
  40. package/.output/public/_nuxt/Ccps4cxo.js +1 -0
  41. package/.output/public/_nuxt/{CPmNRTBk2.js → CdIsmU5a2.js} +10 -10
  42. package/.output/public/_nuxt/{BS9P_Ies2.js → ChGuLxwW2.js} +1 -1
  43. package/.output/public/_nuxt/{Ck5oMvUk.js → Cn6ihm8j.js} +1 -1
  44. package/.output/public/_nuxt/{CWzp2R6G.js → D-Xyb3DA.js} +1 -1
  45. package/.output/public/_nuxt/D0SNhlnt.js +1 -0
  46. package/.output/public/_nuxt/D0ldVwl-.js +1 -0
  47. package/.output/public/_nuxt/DClNt1uS.js +1 -0
  48. package/.output/public/_nuxt/{CTVfcnjU.js → DQMbdg4t.js} +2 -2
  49. package/.output/public/_nuxt/{DHSDk8Bq2.js → DTxfFIvL2.js} +1 -1
  50. package/.output/public/_nuxt/DVKXGuMz2.js +1 -0
  51. package/.output/public/_nuxt/{CLySL7mW.js → Da0h_6VA.js} +1 -1
  52. package/.output/public/_nuxt/{PixDfCSm.js → DefDtlKK.js} +1 -1
  53. package/.output/public/_nuxt/DjefmmJu.js +1 -0
  54. package/.output/public/_nuxt/DnH9SRMW2.js +1 -0
  55. package/.output/public/_nuxt/{BmiMC_BC.js → DppqsiPC.js} +1 -1
  56. package/.output/public/_nuxt/Drq9iy6V.js +1 -0
  57. package/.output/public/_nuxt/DsGf2IV82.js +1 -0
  58. package/.output/public/_nuxt/{DoKpLEqc.js → DzfVS8N72.js} +1 -1
  59. package/.output/public/_nuxt/{DRpFsrno.js → I1cI6sPJ2.js} +1 -1
  60. package/.output/public/_nuxt/IU-UGkCJ2.js +1 -0
  61. package/.output/public/_nuxt/KXjvpIk2.js +1 -0
  62. package/.output/public/_nuxt/NJn94js_.js +1 -0
  63. package/.output/public/_nuxt/ON2x-t6n.js +1 -0
  64. package/.output/public/_nuxt/S799kNo8.js +1 -0
  65. package/.output/public/_nuxt/{uI9Ki_XZ.js → S9rLP7_v.js} +1 -1
  66. package/.output/public/_nuxt/UN3nSFjj2.js +1 -0
  67. package/.output/public/_nuxt/WVTVkqef.js +1 -0
  68. package/.output/public/_nuxt/{C_VAXV7I2.js → Yv9YItEX2.js} +1 -1
  69. package/.output/public/_nuxt/_id_.DamiFT0Q.css +1 -0
  70. package/.output/public/_nuxt/{_id_.BTrFUIHX.css → _id_.DpRe1PRh.css} +1 -1
  71. package/.output/public/_nuxt/_wsId_.DkrQkT6r.css +1 -0
  72. package/.output/public/_nuxt/aml.-czpKIs8.css +1 -0
  73. package/.output/public/_nuxt/asmJ99nX2.js +47 -0
  74. package/.output/public/_nuxt/builds/latest.json +1 -1
  75. package/.output/public/_nuxt/builds/meta/08ba670b-7512-426b-a0ae-b10cbeb1c985.json +1 -0
  76. package/.output/public/_nuxt/{default.uao9U50c.css → default.CXb_zoN6.css} +1 -1
  77. package/.output/public/_nuxt/{entry.6DEjPWvR.css → entry.JdEG3KJg.css} +1 -1
  78. package/.output/public/_nuxt/jRTz0hjN2.js +1 -0
  79. package/.output/public/_nuxt/{DLPuRMeG.js → k5K6Jj6g.js} +1 -1
  80. package/.output/public/_nuxt/operations.B8X9uWK6.css +1 -0
  81. package/.output/public/_nuxt/{settings.Bo5EYkLI.css → settings.O26Dw1iT.css} +1 -1
  82. package/.output/public/_nuxt/{BACBBVdw.js → tKxYgsf-.js} +1 -1
  83. package/.output/public/_nuxt/{Cm_PTn9t2.js → vXrNItas2.js} +1 -1
  84. package/.output/public/_nuxt/{Cr518Gh02.js → zsRclU9w2.js} +1 -1
  85. package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
  86. package/.output/server/chunks/_/SearchOutlined.mjs +1 -1
  87. package/.output/server/chunks/_/binding-authz.mjs +1 -1
  88. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  89. package/.output/server/chunks/_/entity.mjs +1 -1
  90. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  91. package/.output/server/chunks/_/nitro.mjs +26134 -21024
  92. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  93. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  94. package/.output/server/chunks/build/Checkbox-4EdGAAl_.mjs +1 -1
  95. package/.output/server/chunks/build/FormItemContext-4ORSzhWv.mjs +1 -1
  96. package/.output/server/chunks/build/{OmpTerminalPanel-EQHrOJbw.mjs → OmpTerminalPanel-mk31gVzA.mjs} +3 -3
  97. package/.output/server/chunks/build/{OmpTerminalPanel-EQHrOJbw.mjs.map → OmpTerminalPanel-mk31gVzA.mjs.map} +1 -1
  98. package/.output/server/chunks/build/{PluginSlot-BP_qedpQ.mjs → PluginSlot-D2WUZgbp.mjs} +2 -2
  99. package/.output/server/chunks/build/{PluginSlot-BP_qedpQ.mjs.map → PluginSlot-D2WUZgbp.mjs.map} +1 -1
  100. package/.output/server/chunks/build/{TownView-BAR8CPIZ.mjs → TownView-fP9BiALv.mjs} +6 -6
  101. package/.output/server/chunks/build/{TownView-BAR8CPIZ.mjs.map → TownView-fP9BiALv.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{_id_-DgMpjM3_.mjs → _id_-BUpQSlzo.mjs} +142 -106
  103. package/.output/server/chunks/build/_id_-BUpQSlzo.mjs.map +1 -0
  104. package/.output/server/chunks/build/{_id_-Dv3BQbYV.mjs → _id_-CDlur81q.mjs} +25 -24
  105. package/.output/server/chunks/build/_id_-CDlur81q.mjs.map +1 -0
  106. package/.output/server/chunks/build/{_wsId_-BKJvFmyf.mjs → _wsId_-DPy2BXRd.mjs} +547 -158
  107. package/.output/server/chunks/build/_wsId_-DPy2BXRd.mjs.map +1 -0
  108. package/.output/server/chunks/build/{agents-B2GLPmn2.mjs → agents-CDLcboCv.mjs} +12 -12
  109. package/.output/server/chunks/build/{agents-B2GLPmn2.mjs.map → agents-CDLcboCv.mjs.map} +1 -1
  110. package/.output/server/chunks/build/{aml-DdWicH3t.mjs → aml-DsgtDLWF.mjs} +28 -27
  111. package/.output/server/chunks/build/aml-DsgtDLWF.mjs.map +1 -0
  112. package/.output/server/chunks/build/api-BY6ji7RC.mjs +6 -6
  113. package/.output/server/chunks/build/card-CUSocE9p.mjs +1 -1
  114. package/.output/server/chunks/build/{channel-templates-RPOtkgRf.mjs → channel-templates-DjEsj0_v.mjs} +8 -8
  115. package/.output/server/chunks/build/{channel-templates-RPOtkgRf.mjs.map → channel-templates-DjEsj0_v.mjs.map} +1 -1
  116. package/.output/server/chunks/build/checkbox-C4AKj81e.mjs +1 -1
  117. package/.output/server/chunks/build/constants-HPHJvjne.mjs +6 -6
  118. package/.output/server/chunks/build/{daq-CPtsh0e7.mjs → daq-N69AOtgw.mjs} +12 -11
  119. package/.output/server/chunks/build/daq-N69AOtgw.mjs.map +1 -0
  120. package/.output/server/chunks/build/{dcw-ry5Gyw6Y.mjs → dcw-CN9d3Rs7.mjs} +10 -10
  121. package/.output/server/chunks/build/{dcw-ry5Gyw6Y.mjs.map → dcw-CN9d3Rs7.mjs.map} +1 -1
  122. package/.output/server/chunks/build/{default-DxOE1eB0.mjs → default-DCf9tn1i.mjs} +38 -30
  123. package/.output/server/chunks/build/{default-DxOE1eB0.mjs.map → default-DCf9tn1i.mjs.map} +1 -1
  124. package/.output/server/chunks/build/descriptions-CFaUq4y4.mjs +1 -1
  125. package/.output/server/chunks/build/drawer-Cfh9_zft.mjs +1 -1
  126. package/.output/server/chunks/build/dropdown-KdKWCS5K.mjs +1 -1
  127. package/.output/server/chunks/build/form-uSlNqIAV.mjs +1 -1
  128. package/.output/server/chunks/build/input-Cr_KFj4T.mjs +1 -1
  129. package/.output/server/chunks/build/input-number-BRVnxeiA.mjs +1 -1
  130. package/.output/server/chunks/build/{logs-CeaiO3y9.mjs → logs-BcAjU1Ps.mjs} +12 -11
  131. package/.output/server/chunks/build/logs-BcAjU1Ps.mjs.map +1 -0
  132. package/.output/server/chunks/build/menu-BgkRSSx7.mjs +1 -1
  133. package/.output/server/chunks/build/{monitor-DnuXEIi5.mjs → monitor-DX_K0WMq.mjs} +13 -13
  134. package/.output/server/chunks/build/{monitor-DnuXEIi5.mjs.map → monitor-DX_K0WMq.mjs.map} +1 -1
  135. package/.output/server/chunks/build/operations-OFHYXwh4.mjs +282 -0
  136. package/.output/server/chunks/build/operations-OFHYXwh4.mjs.map +1 -0
  137. package/.output/server/chunks/build/{pages-Bn90ijKD.mjs → pages-rZKH72eC.mjs} +10 -11
  138. package/.output/server/chunks/build/pages-rZKH72eC.mjs.map +1 -0
  139. package/.output/server/chunks/build/{permissions-DL70W1YD.mjs → permissions-BvmodvsO.mjs} +8 -8
  140. package/.output/server/chunks/build/{permissions-DL70W1YD.mjs.map → permissions-BvmodvsO.mjs.map} +1 -1
  141. package/.output/server/chunks/build/{plugins-DrsZo--K.mjs → plugins-DSka7-vS.mjs} +9 -9
  142. package/.output/server/chunks/build/{plugins-DrsZo--K.mjs.map → plugins-DSka7-vS.mjs.map} +1 -1
  143. package/.output/server/chunks/build/popconfirm-Ox-_2V8A.mjs +1 -1
  144. package/.output/server/chunks/build/{schedules-VLzNcjnW.mjs → schedules-lo4bfgVt.mjs} +8 -8
  145. package/.output/server/chunks/build/{schedules-VLzNcjnW.mjs.map → schedules-lo4bfgVt.mjs.map} +1 -1
  146. package/.output/server/chunks/build/segmented-C61yLHvo.mjs +1 -1
  147. package/.output/server/chunks/build/select-rdBWytVK.mjs +1 -1
  148. package/.output/server/chunks/build/{settings-DVAUVMsX.mjs → settings-CAJWvul5.mjs} +32 -13
  149. package/.output/server/chunks/build/settings-CAJWvul5.mjs.map +1 -0
  150. package/.output/server/chunks/build/space-B2uhHJG8.mjs +1 -1
  151. package/.output/server/chunks/build/spin-C2cuvGth.mjs +1 -1
  152. package/.output/server/chunks/build/switch-DZAUIbIN.mjs +1 -1
  153. package/.output/server/chunks/build/table-DOFAvY-v.mjs +1 -1
  154. package/.output/server/chunks/build/tabs-DTeIuZeP.mjs +1 -1
  155. package/.output/server/chunks/build/tag-CHLGvNM6.mjs +1 -1
  156. package/.output/server/chunks/build/{teams-Mc07PYO8.mjs → teams-DBBvIToa.mjs} +14 -14
  157. package/.output/server/chunks/build/{teams-Mc07PYO8.mjs.map → teams-DBBvIToa.mjs.map} +1 -1
  158. package/.output/server/chunks/build/{tokens-DiwD5qni.mjs → tokens-CloWk4x_.mjs} +12 -12
  159. package/.output/server/chunks/build/{tokens-DiwD5qni.mjs.map → tokens-CloWk4x_.mjs.map} +1 -1
  160. package/.output/server/chunks/build/{town-D8VmTCmN.mjs → town-BMlctE4m.mjs} +12 -12
  161. package/.output/server/chunks/build/{town-D8VmTCmN.mjs.map → town-BMlctE4m.mjs.map} +1 -1
  162. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  163. package/.output/server/chunks/build/{useAgentHarnessOptions-CPn5dzKe.mjs → useAgentHarnessOptions-D6SJ_uUr.mjs} +7 -7
  164. package/.output/server/chunks/build/{useAgentHarnessOptions-CPn5dzKe.mjs.map → useAgentHarnessOptions-D6SJ_uUr.mjs.map} +1 -1
  165. package/.output/server/chunks/build/{useAgentTemplateActions-DQWzVnZ0.mjs → useAgentTemplateActions-CdG4g_PF.mjs} +7 -7
  166. package/.output/server/chunks/build/{useAgentTemplateActions-DQWzVnZ0.mjs.map → useAgentTemplateActions-CdG4g_PF.mjs.map} +1 -1
  167. package/.output/server/chunks/build/useAgentTemplateDialogState-CZzpu5og.mjs +6 -6
  168. package/.output/server/chunks/build/{useAgentTemplateForm-vqyiRPtt.mjs → useAgentTemplateForm-a5y-N5sB.mjs} +7 -7
  169. package/.output/server/chunks/build/{useAgentTemplateForm-vqyiRPtt.mjs.map → useAgentTemplateForm-a5y-N5sB.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{useAgentTemplatesCatalog-DcQbsOik.mjs → useAgentTemplatesCatalog-pBVcUuN3.mjs} +7 -7
  171. package/.output/server/chunks/build/{useAgentTemplatesCatalog-DcQbsOik.mjs.map → useAgentTemplatesCatalog-pBVcUuN3.mjs.map} +1 -1
  172. package/.output/server/chunks/build/useAmlDatasets-BM0lZu40.mjs +6 -6
  173. package/.output/server/chunks/build/{useAmlEntities-BjXWvFd_.mjs → useAmlEntities-BDQ8TmLL.mjs} +7 -7
  174. package/.output/server/chunks/build/{useAmlEntities-BjXWvFd_.mjs.map → useAmlEntities-BDQ8TmLL.mjs.map} +1 -1
  175. package/.output/server/chunks/build/{useAmlEnv-BB7p6x_w.mjs → useAmlEnv-DgTVwpqi.mjs} +7 -7
  176. package/.output/server/chunks/build/{useAmlEnv-BB7p6x_w.mjs.map → useAmlEnv-DgTVwpqi.mjs.map} +1 -1
  177. package/.output/server/chunks/build/useAmlExperiments-BtyW32PO.mjs +6 -6
  178. package/.output/server/chunks/build/{useAmlFormat-WrKuRfw2.mjs → useAmlFormat-C2sl3MGB.mjs} +7 -7
  179. package/.output/server/chunks/build/{useAmlFormat-WrKuRfw2.mjs.map → useAmlFormat-C2sl3MGB.mjs.map} +1 -1
  180. package/.output/server/chunks/build/{useAmlJobs-DBuLvWMF.mjs → useAmlJobs-fk-H5Rp5.mjs} +10 -9
  181. package/.output/server/chunks/build/useAmlJobs-fk-H5Rp5.mjs.map +1 -0
  182. package/.output/server/chunks/build/{useAmlModels-VurmkBYe.mjs → useAmlModels-hgyVHoAq.mjs} +7 -7
  183. package/.output/server/chunks/build/{useAmlModels-VurmkBYe.mjs.map → useAmlModels-hgyVHoAq.mjs.map} +1 -1
  184. package/.output/server/chunks/build/{useAmlNotes-BUdj3X6Y.mjs → useAmlNotes-BjbYNADm.mjs} +7 -7
  185. package/.output/server/chunks/build/{useAmlNotes-BUdj3X6Y.mjs.map → useAmlNotes-BjbYNADm.mjs.map} +1 -1
  186. package/.output/server/chunks/build/{useAmlPredict-DFy-Do10.mjs → useAmlPredict-U24-SZNA.mjs} +7 -7
  187. package/.output/server/chunks/build/{useAmlPredict-DFy-Do10.mjs.map → useAmlPredict-U24-SZNA.mjs.map} +1 -1
  188. package/.output/server/chunks/build/useDaqAddNode-kW7uTSMQ.mjs +7 -7
  189. package/.output/server/chunks/build/useDaqDetailBinding-cpBz4hSL.mjs +6 -6
  190. package/.output/server/chunks/build/useDaqDetailFrames-BZGtKKXW.mjs +6 -6
  191. package/.output/server/chunks/build/{useDaqDetailHistory-C4_hVeqZ.mjs → useDaqDetailHistory-DtSTfyMi.mjs} +7 -7
  192. package/.output/server/chunks/build/{useDaqDetailHistory-C4_hVeqZ.mjs.map → useDaqDetailHistory-DtSTfyMi.mjs.map} +1 -1
  193. package/.output/server/chunks/build/{useDaqDetailNode-Bwid_iA8.mjs → useDaqDetailNode-D_vhG0jF.mjs} +8 -8
  194. package/.output/server/chunks/build/{useDaqDetailNode-Bwid_iA8.mjs.map → useDaqDetailNode-D_vhG0jF.mjs.map} +1 -1
  195. package/.output/server/chunks/build/useDaqDetailParams-JfqHvTxr.mjs +7 -7
  196. package/.output/server/chunks/build/{useDaqFilters-C13836p-.mjs → useDaqFilters-BUQtZ82a.mjs} +8 -8
  197. package/.output/server/chunks/build/{useDaqFilters-C13836p-.mjs.map → useDaqFilters-BUQtZ82a.mjs.map} +1 -1
  198. package/.output/server/chunks/build/useDaqNodeWindow-1DWj2H5G.mjs +6 -6
  199. package/.output/server/chunks/build/useDaqOptimizations-Ct-TSXxy.mjs +6 -6
  200. package/.output/server/chunks/build/useDaqStream-wOxZcMDA.mjs +1 -1
  201. package/.output/server/chunks/build/useDaqTemplates-BqQRdrIm.mjs +7 -7
  202. package/.output/server/chunks/build/{useDashboardCharts-DZysNDUX.mjs → useDashboardCharts-D45083s_.mjs} +7 -7
  203. package/.output/server/chunks/build/{useDashboardCharts-DZysNDUX.mjs.map → useDashboardCharts-D45083s_.mjs.map} +1 -1
  204. package/.output/server/chunks/build/{useDashboardData-Ny_wtbo6.mjs → useDashboardData-Do_Vsepa.mjs} +8 -8
  205. package/.output/server/chunks/build/{useDashboardData-Ny_wtbo6.mjs.map → useDashboardData-Do_Vsepa.mjs.map} +1 -1
  206. package/.output/server/chunks/build/{useDcwAddNode-C8nE7geh.mjs → useDcwAddNode-C1HDP3yG.mjs} +12 -9
  207. package/.output/server/chunks/build/useDcwAddNode-C1HDP3yG.mjs.map +1 -0
  208. package/.output/server/chunks/build/useDcwCards-ETEsHvVy.mjs +6 -6
  209. package/.output/server/chunks/build/{useDcwDetailScope-BNrpDzbO.mjs → useDcwDetailScope-QTr1G6Oe.mjs} +7 -7
  210. package/.output/server/chunks/build/{useDcwDetailScope-BNrpDzbO.mjs.map → useDcwDetailScope-QTr1G6Oe.mjs.map} +1 -1
  211. package/.output/server/chunks/build/{useDcwDetailTemplates-IcKAJ37Y.mjs → useDcwDetailTemplates-Djt-0Vse.mjs} +7 -7
  212. package/.output/server/chunks/build/{useDcwDetailTemplates-IcKAJ37Y.mjs.map → useDcwDetailTemplates-Djt-0Vse.mjs.map} +1 -1
  213. package/.output/server/chunks/build/useDcwFilter-FfVlDdyS.mjs +6 -6
  214. package/.output/server/chunks/build/useDcwLedger-BLoMmcu1.mjs +6 -6
  215. package/.output/server/chunks/build/useDcwLineMutations-BMC5BTWU.mjs +6 -6
  216. package/.output/server/chunks/build/{useDcwLineRun-Bpxk4mse.mjs → useDcwLineRun-74gN_s6T.mjs} +7 -7
  217. package/.output/server/chunks/build/{useDcwLineRun-Bpxk4mse.mjs.map → useDcwLineRun-74gN_s6T.mjs.map} +1 -1
  218. package/.output/server/chunks/build/useDcwProducts-D-zrMaeV.mjs +6 -6
  219. package/.output/server/chunks/build/{useDcwQuery-1lYHOaU6.mjs → useDcwQuery-7tX4QYmv.mjs} +7 -7
  220. package/.output/server/chunks/build/{useDcwQuery-1lYHOaU6.mjs.map → useDcwQuery-7tX4QYmv.mjs.map} +1 -1
  221. package/.output/server/chunks/build/useDcwQuickActions-C-tgcXIr.mjs +6 -6
  222. package/.output/server/chunks/build/{useDcwRecipes-BzGOymqz.mjs → useDcwRecipes-FVk5gDLV.mjs} +23 -15
  223. package/.output/server/chunks/build/useDcwRecipes-FVk5gDLV.mjs.map +1 -0
  224. package/.output/server/chunks/build/useDcwStream-D04kCV3J.mjs +1 -1
  225. package/.output/server/chunks/build/{useDcwTemplates-Dsjw9u6U.mjs → useDcwTemplates-LDZffy4u.mjs} +7 -7
  226. package/.output/server/chunks/build/{useDcwTemplates-Dsjw9u6U.mjs.map → useDcwTemplates-LDZffy4u.mjs.map} +1 -1
  227. package/.output/server/chunks/build/{useDcwWrites-3RxwN36I.mjs → useDcwWrites-B22mwliK.mjs} +25 -8
  228. package/.output/server/chunks/build/useDcwWrites-B22mwliK.mjs.map +1 -0
  229. package/.output/server/chunks/build/useLocalTime-DZ2RAtVs.mjs +49 -0
  230. package/.output/server/chunks/build/useLocalTime-DZ2RAtVs.mjs.map +1 -0
  231. package/.output/server/chunks/build/{useLogsFormat-BlwLpyzy.mjs → useLogsFormat-B-o4MHy7.mjs} +7 -7
  232. package/.output/server/chunks/build/{useLogsFormat-BlwLpyzy.mjs.map → useLogsFormat-B-o4MHy7.mjs.map} +1 -1
  233. package/.output/server/chunks/build/{useLogsManual-Deev2Cjk.mjs → useLogsManual-COfCyUtj.mjs} +7 -7
  234. package/.output/server/chunks/build/{useLogsManual-Deev2Cjk.mjs.map → useLogsManual-COfCyUtj.mjs.map} +1 -1
  235. package/.output/server/chunks/build/useLogsQuery-CRAm2hmS.mjs +6 -6
  236. package/.output/server/chunks/build/useLogsScope-ClNijVj4.mjs +6 -6
  237. package/.output/server/chunks/build/{useMonitorColumns-ylxrUNTK.mjs → useMonitorColumns-DhYvkLDq.mjs} +7 -7
  238. package/.output/server/chunks/build/{useMonitorColumns-ylxrUNTK.mjs.map → useMonitorColumns-DhYvkLDq.mjs.map} +1 -1
  239. package/.output/server/chunks/build/{useMonitorData-CEpKXoD4.mjs → useMonitorData-guVjMDtR.mjs} +9 -8
  240. package/.output/server/chunks/build/useMonitorData-guVjMDtR.mjs.map +1 -0
  241. package/.output/server/chunks/build/{useMonitorFormat-_7zLapf3.mjs → useMonitorFormat-C7lhZe4g.mjs} +13 -12
  242. package/.output/server/chunks/build/useMonitorFormat-C7lhZe4g.mjs.map +1 -0
  243. package/.output/server/chunks/build/useMonitorTerminal-Dj4QwRNW.mjs +6 -6
  244. package/.output/server/chunks/build/useOperationsFeed-CeXeHqUK.mjs +191 -0
  245. package/.output/server/chunks/build/useOperationsFeed-CeXeHqUK.mjs.map +1 -0
  246. package/.output/server/chunks/build/{useTeamActions-D6sxdpkP.mjs → useTeamActions-C4n-taBk.mjs} +7 -7
  247. package/.output/server/chunks/build/{useTeamActions-D6sxdpkP.mjs.map → useTeamActions-C4n-taBk.mjs.map} +1 -1
  248. package/.output/server/chunks/build/{useTeamAddMemberDialog-Q-ntQ6Vo.mjs → useTeamAddMemberDialog-Cp_z3nMa.mjs} +7 -7
  249. package/.output/server/chunks/build/{useTeamAddMemberDialog-Q-ntQ6Vo.mjs.map → useTeamAddMemberDialog-Cp_z3nMa.mjs.map} +1 -1
  250. package/.output/server/chunks/build/{useTeamCreateDialog-D7OMfDTM.mjs → useTeamCreateDialog-C8LKUoe2.mjs} +7 -7
  251. package/.output/server/chunks/build/{useTeamCreateDialog-D7OMfDTM.mjs.map → useTeamCreateDialog-C8LKUoe2.mjs.map} +1 -1
  252. package/.output/server/chunks/build/{useTeamDeployDialog-vBRqjiut.mjs → useTeamDeployDialog-wdBVsNWY.mjs} +7 -7
  253. package/.output/server/chunks/build/{useTeamDeployDialog-vBRqjiut.mjs.map → useTeamDeployDialog-wdBVsNWY.mjs.map} +1 -1
  254. package/.output/server/chunks/build/useTeamDialogState-CFRUQxAf.mjs +6 -6
  255. package/.output/server/chunks/build/{useTeamPluginDialog-B8kxewpZ.mjs → useTeamPluginDialog-CIk8G8nI.mjs} +7 -7
  256. package/.output/server/chunks/build/{useTeamPluginDialog-B8kxewpZ.mjs.map → useTeamPluginDialog-CIk8G8nI.mjs.map} +1 -1
  257. package/.output/server/chunks/build/{useTeamsCatalog-xRhk7ezA.mjs → useTeamsCatalog-D6TULzmS.mjs} +7 -7
  258. package/.output/server/chunks/build/{useTeamsCatalog-xRhk7ezA.mjs.map → useTeamsCatalog-D6TULzmS.mjs.map} +1 -1
  259. package/.output/server/chunks/build/useTokenClipboard-CwQpoFeP.mjs +6 -6
  260. package/.output/server/chunks/build/{useTokenCreate-DpDcF1Vx.mjs → useTokenCreate-DkYvEQUD.mjs} +7 -7
  261. package/.output/server/chunks/build/{useTokenCreate-DpDcF1Vx.mjs.map → useTokenCreate-DkYvEQUD.mjs.map} +1 -1
  262. package/.output/server/chunks/build/{useTokenRename-BRejFrtc.mjs → useTokenRename-DOCP4aeI.mjs} +7 -7
  263. package/.output/server/chunks/build/{useTokenRename-BRejFrtc.mjs.map → useTokenRename-DOCP4aeI.mjs.map} +1 -1
  264. package/.output/server/chunks/build/{useTokenReveal-DER2afAS.mjs → useTokenReveal-CybwwflV.mjs} +7 -7
  265. package/.output/server/chunks/build/{useTokenReveal-DER2afAS.mjs.map → useTokenReveal-CybwwflV.mjs.map} +1 -1
  266. package/.output/server/chunks/build/{useTokensList-DHt65IOY.mjs → useTokensList-BLiMvrc4.mjs} +7 -7
  267. package/.output/server/chunks/build/{useTokensList-DHt65IOY.mjs.map → useTokensList-BLiMvrc4.mjs.map} +1 -1
  268. package/.output/server/chunks/build/{useWorkbenchAuth-B2j-zILO.mjs → useWorkbenchAuth-DqjBX-6w.mjs} +7 -7
  269. package/.output/server/chunks/build/{useWorkbenchAuth-B2j-zILO.mjs.map → useWorkbenchAuth-DqjBX-6w.mjs.map} +1 -1
  270. package/.output/server/chunks/build/{useWorkbenchWorkspaces-B_2mOxN6.mjs → useWorkbenchWorkspaces-DgiSCzsX.mjs} +10 -9
  271. package/.output/server/chunks/build/useWorkbenchWorkspaces-DgiSCzsX.mjs.map +1 -0
  272. package/.output/server/chunks/build/{useWorkshopWs-B-Es2Xg3.mjs → useWorkshopWs-Bm80bLn7.mjs} +8 -7
  273. package/.output/server/chunks/build/useWorkshopWs-Bm80bLn7.mjs.map +1 -0
  274. package/.output/server/chunks/build/{useWorkspaceAuth-tQ1ORWXo.mjs → useWorkspaceAuth-Dlvj9csD.mjs} +8 -8
  275. package/.output/server/chunks/build/{useWorkspaceAuth-tQ1ORWXo.mjs.map → useWorkspaceAuth-Dlvj9csD.mjs.map} +1 -1
  276. package/.output/server/chunks/build/{useWorkspaceChannels-BwB6TAWY.mjs → useWorkspaceChannels-D61Al2dr.mjs} +11 -10
  277. package/.output/server/chunks/build/useWorkspaceChannels-D61Al2dr.mjs.map +1 -0
  278. package/.output/server/chunks/build/{useWorkspacePanels-CuAmDpT5.mjs → useWorkspacePanels-CTwREmq0.mjs} +8 -8
  279. package/.output/server/chunks/build/{useWorkspacePanels-CuAmDpT5.mjs.map → useWorkspacePanels-CTwREmq0.mjs.map} +1 -1
  280. package/.output/server/chunks/build/{useWorkspaceShell-CcQ4JlqO.mjs → useWorkspaceShell-BCypjjjE.mjs} +7 -7
  281. package/.output/server/chunks/build/{useWorkspaceShell-CcQ4JlqO.mjs.map → useWorkspaceShell-BCypjjjE.mjs.map} +1 -1
  282. package/.output/server/chunks/build/{users-De2HygNt.mjs → users-CCf5PgRs.mjs} +8 -8
  283. package/.output/server/chunks/build/{users-De2HygNt.mjs.map → users-CCf5PgRs.mjs.map} +1 -1
  284. package/.output/server/chunks/build/{workshop-CmgpTwyf.mjs → workshop-FQ4YzooB.mjs} +13 -12
  285. package/.output/server/chunks/build/workshop-FQ4YzooB.mjs.map +1 -0
  286. package/.output/server/chunks/build/{workspaces-DVIEk1Bl.mjs → workspaces-CmW0cpOt.mjs} +1 -1
  287. package/.output/server/chunks/build/{workspaces-DVIEk1Bl.mjs.map → workspaces-CmW0cpOt.mjs.map} +1 -1
  288. package/.output/server/chunks/routes/api/health.get.mjs +6 -6
  289. package/.output/server/chunks/routes/api/index.get.mjs +7 -7
  290. package/.output/server/chunks/routes/api/index.post.mjs +7 -7
  291. package/.output/server/chunks/routes/api/mcp/workshop.mjs +6 -6
  292. package/.output/server/chunks/routes/api/metrics.mjs +6 -6
  293. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +6 -6
  294. package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +6 -6
  295. package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +6 -6
  296. package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +6 -6
  297. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +6 -6
  298. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +6 -6
  299. package/.output/server/chunks/routes/api/system/config.get.mjs +6 -6
  300. package/.output/server/chunks/routes/api/system/index.get.mjs +6 -6
  301. package/.output/server/chunks/routes/api/system/index.patch.mjs +6 -6
  302. package/.output/server/chunks/routes/api/system/index.post.mjs +6 -6
  303. package/.output/server/chunks/routes/api/system/index2.get.mjs +6 -6
  304. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +6 -6
  305. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +6 -6
  306. package/.output/server/chunks/routes/api/system/monitor.get.mjs +6 -6
  307. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +6 -6
  308. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +6 -6
  309. package/.output/server/chunks/routes/api/system/timezone.get.mjs +36 -0
  310. package/.output/server/chunks/routes/api/system/timezone.get.mjs.map +1 -0
  311. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +7 -7
  312. package/.output/server/chunks/routes/api/users/_id_.get.mjs +7 -7
  313. package/.output/server/chunks/routes/api/users/_id_.put.mjs +7 -7
  314. package/.output/server/chunks/routes/api/users/index.get.mjs +7 -7
  315. package/.output/server/chunks/routes/api/users/index.post.mjs +7 -7
  316. package/.output/server/chunks/routes/api/users/login.post.mjs +7 -7
  317. package/.output/server/chunks/routes/api/users/logout.post.mjs +7 -7
  318. package/.output/server/chunks/routes/api/users/me.get.mjs +7 -7
  319. package/.output/server/chunks/routes/api/users/register.post.mjs +7 -7
  320. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +7 -7
  321. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +7 -7
  322. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +7 -7
  323. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +7 -7
  324. package/.output/server/chunks/routes/api/workshop/_...path_.mjs +6 -6
  325. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +7 -7
  326. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +5 -5
  327. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +6 -6
  328. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +7 -7
  329. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +7 -7
  330. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +10 -7
  331. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
  332. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +7 -7
  333. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +7 -7
  334. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +7 -7
  335. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +7 -7
  336. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +7 -7
  337. package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +6 -6
  338. package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +6 -6
  339. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +6 -6
  340. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +6 -6
  341. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +6 -6
  342. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +7 -7
  343. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +7 -7
  344. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +7 -7
  345. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs +7 -7
  346. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +7 -8
  347. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +7 -8
  349. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +7 -8
  351. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +7 -7
  353. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +7 -7
  354. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +6 -6
  355. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +20 -7
  356. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -1
  357. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +7 -8
  358. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -1
  359. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +49 -0
  360. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs.map +1 -0
  361. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +7 -7
  362. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +7 -7
  363. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +7 -7
  364. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +28 -0
  365. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs.map +1 -0
  366. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +7 -7
  367. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +7 -7
  368. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +7 -7
  369. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +7 -7
  370. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +7 -7
  371. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +7 -7
  372. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +7 -7
  373. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +7 -7
  374. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +7 -7
  375. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +35 -0
  376. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs.map +1 -0
  377. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +35 -0
  378. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs.map +1 -0
  379. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +44 -0
  380. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs.map +1 -0
  381. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +46 -0
  382. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs.map +1 -0
  383. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +7 -7
  384. package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +5 -5
  385. package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +5 -5
  386. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +6 -6
  387. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +6 -6
  388. package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +5 -5
  389. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +6 -6
  390. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +6 -6
  391. package/.output/server/chunks/routes/api/workshop/caller.mjs +7 -7
  392. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +16 -10
  393. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs.map +1 -1
  394. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +6 -6
  395. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +6 -6
  396. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +6 -6
  397. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +6 -6
  398. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +7 -7
  399. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +6 -6
  400. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +6 -6
  401. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +6 -6
  402. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +6 -6
  403. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +6 -6
  404. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +6 -6
  405. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +6 -6
  406. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +6 -6
  407. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +6 -6
  408. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +6 -6
  409. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.get.mjs +6 -6
  410. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +6 -6
  411. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/messages/_messageId/read.post.mjs +6 -6
  412. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/permissions.get.mjs +6 -6
  413. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +6 -6
  414. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +6 -6
  415. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +6 -6
  416. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +7 -7
  417. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +6 -6
  418. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +6 -6
  419. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +6 -6
  420. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +6 -6
  421. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +6 -6
  422. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +6 -6
  423. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +7 -7
  424. package/.output/server/chunks/routes/api/workshop/channels/_id/index6.get.mjs +6 -6
  425. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId/approve.post.mjs +6 -6
  426. package/.output/server/chunks/routes/api/workshop/channels/_id/members/_userId_.delete.mjs +6 -6
  427. package/.output/server/chunks/routes/api/workshop/channels/_id/members/join.post.mjs +6 -6
  428. package/.output/server/chunks/routes/api/workshop/channels/_id/members/leave.post.mjs +6 -6
  429. package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +6 -6
  430. package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +6 -6
  431. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +7 -7
  432. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +51 -0
  433. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs.map +1 -0
  434. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +71 -0
  435. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs.map +1 -0
  436. package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +6 -6
  437. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +7 -7
  438. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +6 -6
  439. package/.output/server/chunks/routes/api/workshop/channels.get.mjs +6 -6
  440. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +9 -9
  441. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +7 -7
  442. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +7 -7
  443. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +7 -7
  444. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +7 -7
  445. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +7 -7
  446. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +7 -7
  447. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +7 -7
  448. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +7 -7
  449. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +7 -7
  450. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +7 -7
  451. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +7 -7
  452. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +7 -7
  453. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +7 -7
  454. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +7 -7
  455. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +7 -7
  456. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +7 -7
  457. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +7 -7
  458. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +7 -7
  459. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +7 -7
  460. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +7 -7
  461. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +7 -7
  462. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +7 -7
  463. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +7 -7
  464. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +7 -7
  465. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +7 -7
  466. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +7 -7
  467. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +7 -7
  468. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +7 -7
  469. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +7 -7
  470. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +7 -7
  471. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +7 -7
  472. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +7 -7
  473. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +7 -7
  474. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +7 -7
  475. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +7 -7
  476. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +7 -7
  477. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +7 -7
  478. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +7 -7
  479. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +7 -7
  480. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +7 -7
  481. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +7 -7
  482. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +7 -7
  483. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +7 -7
  484. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +7 -7
  485. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +7 -7
  486. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +7 -7
  487. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +7 -7
  488. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +7 -7
  489. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +7 -7
  490. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +7 -7
  491. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +7 -7
  492. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +7 -7
  493. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +7 -7
  494. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +7 -7
  495. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +7 -7
  496. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +7 -7
  497. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +7 -7
  498. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +7 -7
  499. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +7 -7
  500. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +7 -7
  501. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +7 -7
  502. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +7 -7
  503. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +7 -7
  504. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +7 -7
  505. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +7 -7
  506. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +7 -7
  507. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +7 -7
  508. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +7 -7
  509. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +7 -7
  510. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +7 -7
  511. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +5 -5
  512. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +7 -7
  513. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +7 -7
  514. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +7 -7
  515. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +7 -7
  516. package/.output/server/chunks/routes/api/workshop/index.get.mjs +6 -6
  517. package/.output/server/chunks/routes/api/workshop/index.post.mjs +6 -6
  518. package/.output/server/chunks/routes/api/workshop/index.put.mjs +7 -7
  519. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +7 -7
  520. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +6 -6
  521. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +6 -6
  522. package/.output/server/chunks/routes/api/workshop/index13.get.mjs +6 -6
  523. package/.output/server/chunks/routes/api/workshop/index14.get.mjs +6 -6
  524. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +7 -8
  525. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  526. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +6 -6
  527. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +6 -6
  528. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +7 -7
  529. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +6 -6
  530. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +7 -7
  531. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +7 -7
  532. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +7 -7
  533. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +7 -7
  534. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +7 -7
  535. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +7 -7
  536. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +6 -6
  537. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +6 -6
  538. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +6 -6
  539. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +6 -6
  540. package/.output/server/chunks/routes/api/workshop/index9.post.mjs +6 -6
  541. package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +6 -6
  542. package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +6 -6
  543. package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +6 -6
  544. package/.output/server/chunks/routes/api/workshop/notifications/read.post.mjs +6 -6
  545. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +7 -7
  546. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +7 -7
  547. package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +6 -6
  548. package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +6 -6
  549. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +7 -7
  550. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +7 -7
  551. package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +6 -6
  552. package/.output/server/chunks/routes/api/workshop/schedules/_id/run.post.mjs +6 -6
  553. package/.output/server/chunks/routes/api/workshop/schedules/_id/runs.get.mjs +6 -6
  554. package/.output/server/chunks/routes/api/workshop/schedules/_id_.delete.mjs +6 -6
  555. package/.output/server/chunks/routes/api/workshop/schedules/_id_.get.mjs +6 -6
  556. package/.output/server/chunks/routes/api/workshop/schedules/_id_.patch.mjs +6 -6
  557. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +6 -6
  558. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +6 -6
  559. package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +6 -6
  560. package/.output/server/chunks/routes/api/workshop/tasks/_id/reassign.post.mjs +6 -6
  561. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +6 -6
  562. package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +6 -6
  563. package/.output/server/chunks/routes/api/workshop/tasks/_id/update.post.mjs +6 -6
  564. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +6 -6
  565. package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +6 -6
  566. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +6 -6
  567. package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +6 -6
  568. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +6 -6
  569. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +7 -7
  570. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +7 -7
  571. package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +6 -6
  572. package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +6 -6
  573. package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +6 -6
  574. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +6 -6
  575. package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +6 -6
  576. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +6 -6
  577. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +7 -7
  578. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +6 -6
  579. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +6 -6
  580. package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +6 -6
  581. package/.output/server/chunks/routes/renderer.mjs +2 -2
  582. package/.output/server/chunks/virtual/entry.mjs +645 -525
  583. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  584. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  585. package/.output/server/index.mjs +6 -6
  586. package/.output/server/package.json +1 -1
  587. package/README-zh.md +33 -17
  588. package/README.md +32 -16
  589. package/app/components/AppSidebar.vue +1 -0
  590. package/app/components/aml/AmlModelsTable.vue +180 -173
  591. package/app/components/daq/DaqDetailFramesTile.vue +140 -139
  592. package/app/components/daq/DaqDetailHistoryCard.vue +129 -128
  593. package/app/components/dcw/DcwAddNodeModal.vue +342 -328
  594. package/app/components/dcw/DcwNodesTable.vue +290 -253
  595. package/app/components/dcw/DcwQueryCard.vue +252 -251
  596. package/app/components/dcw/DcwRecipeEditModal.vue +297 -285
  597. package/app/components/dcw/DcwRecipePanel.vue +371 -367
  598. package/app/components/operations/OperationsFilterCard.vue +164 -0
  599. package/app/components/operations/OperationsPageHead.vue +47 -0
  600. package/app/components/operations/OperationsTimeline.vue +215 -0
  601. package/app/components/settings/RuntimeFieldRow.vue +207 -189
  602. package/app/components/workshop/ChatTimeline.vue +596 -569
  603. package/app/components/workshop/EventBlock.vue +224 -214
  604. package/app/components/workshop/blocks/ClusterTool.vue +20 -2
  605. package/app/components/workshop/console/LineOperationsPanel.vue +179 -0
  606. package/app/components/workshop/console/RightPane.vue +6 -0
  607. package/app/composables/workshop/event-blocks/constants.ts +48 -2
  608. package/app/composables/workshop/operation-events.ts +151 -0
  609. package/app/composables/workshop/useAmlStream.ts +137 -136
  610. package/app/composables/workshop/useLocalTime.ts +81 -37
  611. package/app/config/schema.ts +3 -0
  612. package/app/pages/aml/styles.css +422 -420
  613. package/app/pages/aml/types.ts +195 -189
  614. package/app/pages/dcw/[id].vue +300 -297
  615. package/app/pages/dcw/composables/useDcwAddNode.ts +124 -121
  616. package/app/pages/dcw/composables/useDcwRecipes.ts +242 -239
  617. package/app/pages/dcw/composables/useDcwWrites.ts +100 -81
  618. package/app/pages/monitor/composables/useMonitorData.ts +125 -124
  619. package/app/pages/monitor/composables/useMonitorFormat.ts +41 -39
  620. package/app/pages/operations/composables/useOperationsFeed.ts +137 -0
  621. package/app/pages/operations.vue +61 -0
  622. package/app/stores/runtime-config.ts +1 -1
  623. package/app/stores/workshop/chat.ts +434 -434
  624. package/app/stores/workshop/notifications.ts +288 -288
  625. package/app/utils/dcw-recipe-form.ts +26 -0
  626. package/cli/aw.mjs +3 -2
  627. package/cli/commands/mcp.mjs +154 -0
  628. package/cli/core/context.mjs +5 -0
  629. package/config.yml +180 -176
  630. package/docs/aml.md +112 -111
  631. package/docs/cli.en.md +13 -11
  632. package/docs/cli.md +12 -10
  633. package/docs/plugins.en.md +621 -567
  634. package/docs/plugins.md +610 -560
  635. package/docs/sdk.en.md +964 -922
  636. package/docs/sdk.md +900 -861
  637. package/i18n/dicts/aml.json +207 -205
  638. package/i18n/locales/en.ts +37 -0
  639. package/i18n/locales/zh-CN.ts +37 -0
  640. package/nuxt.config.ts +2 -0
  641. package/package.json +178 -172
  642. package/scripts/.chk-tok +1 -0
  643. package/scripts/.retrain-body.json +1 -0
  644. package/scripts/.retrain3-body.json +1 -0
  645. package/scripts/.rt-tok +1 -0
  646. package/scripts/.rt3-tok +1 -0
  647. package/scripts/_audit/.tmp/audit-data/dcw-params.json +15 -0
  648. package/scripts/_audit/.tmp/audit-data/dcws.json +30 -0
  649. package/scripts/_audit/aw-mcp-live-e2e.mjs +293 -0
  650. package/scripts/_audit/dcw-controller-e2e.ts +25 -18
  651. package/scripts/_audit/dcw-rollback-ledger.ts +4 -1
  652. package/scripts/_audit/feature-audit-e2e.mjs +339 -0
  653. package/scripts/_audit/full-e2e-adopt.mjs +238 -0
  654. package/scripts/_audit/full-e2e-close-loop.mjs +134 -0
  655. package/scripts/_audit/full-e2e-retrain.mjs +320 -0
  656. package/scripts/_audit/full-e2e-supplement.mjs +192 -0
  657. package/scripts/_audit/full-e2e-ui-final.mjs +111 -0
  658. package/scripts/_audit/full-e2e-ui-mount.mjs +111 -0
  659. package/scripts/_audit/full-feature-e2e-20260927.mjs +627 -0
  660. package/scripts/_audit/kb-diag-complete.mjs +261 -0
  661. package/scripts/_audit/kb-diag-complete2.mjs +271 -0
  662. package/scripts/_audit/kb-diag-loop-e2e.mjs +357 -0
  663. package/scripts/_audit/kb-diag-loop-mock.mjs +416 -0
  664. package/scripts/_audit/kb-diag-loop-v2.mjs +314 -0
  665. package/scripts/_audit/recipe-save-e2e.mjs +365 -0
  666. package/scripts/_audit/run.mjs +21 -0
  667. package/scripts/_audit/runtime-dir-e2e.mjs +393 -0
  668. package/scripts/_audit/skills-guided-e2e.mjs +316 -0
  669. package/scripts/_audit/stability-soak.mjs +252 -0
  670. package/scripts/_aw0748-failclosed-probe.mjs +1 -1
  671. package/scripts/_aw0748-mock-closedloop.mjs +12 -0
  672. package/scripts/_aw0748-mock-dispatch-diag.mjs +66 -0
  673. package/scripts/_dbg-configroot-audit.mjs +86 -84
  674. package/scripts/_dbg-daq-intervals-func.mjs +115 -94
  675. package/scripts/_dbg-optloop-ui-shots.mjs +52 -0
  676. package/scripts/_dbg-param-map-e2e.ts +7 -1
  677. package/scripts/_dbg-perms-e2e.mjs +11 -1
  678. package/scripts/_dbg-protocol-matrix.mjs +3 -1
  679. package/scripts/_dbg-render-regression.mjs +67 -25
  680. package/scripts/_lib-aml-python-run.mjs +17 -0
  681. package/scripts/_lint-reflow.mjs +105 -0
  682. package/scripts/_probe-model-channel-link.cjs +25 -0
  683. package/scripts/acceptance-aml-hybrid-e2e.ts +396 -0
  684. package/scripts/acceptance-aml-hybrid-twin.ts +3 -3
  685. package/scripts/acceptance-aml-model-identity.ts +137 -0
  686. package/scripts/dev-guard.mjs +4 -2
  687. package/scripts/dev-protocol-simulators.mjs +3 -2
  688. package/scripts/e2e-aml-decoupled.mjs +162 -0
  689. package/scripts/e2e-closedloop/scenarios-accounts.mjs +2 -0
  690. package/scripts/e2e-closedloop/scenarios-authz.mjs +12 -6
  691. package/scripts/e2e-closedloop/scenarios-daq-dcw.mjs +4 -1
  692. package/scripts/e2e-timezone-settings.mjs +57 -0
  693. package/scripts/live-aml-mockomp.mjs +304 -0
  694. package/scripts/live-aml-optloop-resume.mjs +322 -0
  695. package/scripts/live-aml-optloop.mjs +545 -0
  696. package/scripts/live-aml-stage9.mjs +169 -0
  697. package/scripts/live-aml-two-goals.mjs +315 -0
  698. package/scripts/live-optloop-two-modes.mjs +857 -0
  699. package/scripts/start.mjs +3 -1
  700. package/scripts/test-aw-skills.mjs +102 -0
  701. package/scripts/test-twin-plugin-sdk.mjs +30 -0
  702. package/sdk/context.mjs +305 -0
  703. package/sdk/index.d.mts +149 -0
  704. package/sdk/index.mjs +5 -2
  705. package/server/api/system/timezone.get.ts +20 -0
  706. package/server/api/workshop/agent-tools/bindings/[id].patch.ts +28 -23
  707. package/server/api/workshop/aml/jobs/index.post.ts +74 -44
  708. package/server/api/workshop/aml/training-plans/[id]/train.post.ts +18 -0
  709. package/server/api/workshop/aml/training-plans/[id].delete.ts +18 -0
  710. package/server/api/workshop/aml/training-plans/[id].patch.ts +30 -0
  711. package/server/api/workshop/aml/training-plans/index.get.ts +9 -0
  712. package/server/api/workshop/aml/training-plans/index.post.ts +43 -0
  713. package/server/api/workshop/aml/twin/providers.get.ts +33 -0
  714. package/server/api/workshop/channel-templates/[id]/instantiate.post.ts +8 -2
  715. package/server/api/workshop/channels/[id]/twin-profile.get.ts +45 -0
  716. package/server/api/workshop/channels/[id]/twin-profile.patch.ts +72 -0
  717. package/server/plugins/00-local-time.ts +13 -10
  718. package/server/plugins/aml-twin-worker.ts +32 -0
  719. package/server/plugins/aw-plugins.ts +16 -0
  720. package/server/plugins/workshop.ts +21 -0
  721. package/server/plugins-builtin/twin-injection-default/index.mjs +23 -0
  722. package/server/services/system-config/helpers.ts +42 -41
  723. package/server/services/system-config/recompute.ts +68 -66
  724. package/server/services/workshop/agents/host-tool-bridge/catalog.ts +50 -18
  725. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +51 -5
  726. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +19 -6
  727. package/server/services/workshop/agents/industrial/aml-dataset-tools.ts +276 -276
  728. package/server/services/workshop/agents/industrial/aml-job-tools.ts +549 -363
  729. package/server/services/workshop/agents/industrial/audit-query.ts +30 -0
  730. package/server/services/workshop/agents/industrial/dcw-judge-tools.ts +9 -13
  731. package/server/services/workshop/agents/industrial/dcw-tools.ts +208 -213
  732. package/server/services/workshop/agents/industrial/index.ts +3 -2
  733. package/server/services/workshop/agents/industrial/manual-approval.ts +45 -0
  734. package/server/services/workshop/agents/industrial/ops-tools.ts +370 -382
  735. package/server/services/workshop/agents/industrial/optimization-tools.ts +148 -0
  736. package/server/services/workshop/agents/industrial/param-tools.ts +169 -172
  737. package/server/services/workshop/agents/industrial/twin-tools.ts +618 -61
  738. package/server/services/workshop/agents/industrial-context.ts +4 -2
  739. package/server/services/workshop/agents/node-bindings.repo.ts +35 -2
  740. package/server/services/workshop/agents/tool-classes.ts +28 -0
  741. package/server/services/workshop/aml/aml.repo.ts +412 -386
  742. package/server/services/workshop/aml/job-orchestrator/stages.ts +108 -96
  743. package/server/services/workshop/aml/job-orchestrator/start-job.ts +29 -5
  744. package/server/services/workshop/aml/job-orchestrator/submit.ts +36 -1
  745. package/server/services/workshop/aml/model-registry.ts +265 -175
  746. package/server/services/workshop/aml/predictor.ts +336 -262
  747. package/server/services/workshop/aml/python/__pycache__/aml_eval.cpython-312.pyc +0 -0
  748. package/server/services/workshop/aml/python/__pycache__/amlkit.cpython-312.pyc +0 -0
  749. package/server/services/workshop/aml/python/__pycache__/train-example.cpython-312.pyc +0 -0
  750. package/server/services/workshop/aml/python/__pycache__/train-hybrid-example.cpython-312.pyc +0 -0
  751. package/server/services/workshop/aml/python/aml_eval.py +39 -6
  752. package/server/services/workshop/aml/python/amlkit.py +222 -3
  753. package/server/services/workshop/aml/python/train-hybrid-example.py +278 -32
  754. package/server/services/workshop/aml/runtime.ts +4 -3
  755. package/server/services/workshop/aml/twin/acceptance.ts +26 -0
  756. package/server/services/workshop/aml/twin/binding-snapshot.ts +603 -0
  757. package/server/services/workshop/aml/twin/calibration-worker.ts +150 -0
  758. package/server/services/workshop/aml/twin/channel-profile.ts +80 -7
  759. package/server/services/workshop/aml/twin/contracts.ts +3 -0
  760. package/server/services/workshop/aml/twin/declarative-provider.ts +108 -0
  761. package/server/services/workshop/aml/twin/feature-flags.ts +63 -0
  762. package/server/services/workshop/aml/twin/hybrid-provider.ts +86 -0
  763. package/server/services/workshop/aml/twin/model-backed-provider.ts +332 -0
  764. package/server/services/workshop/aml/twin/physics-spec-draft.ts +185 -0
  765. package/server/services/workshop/aml/twin/physics-spec.ts +338 -0
  766. package/server/services/workshop/aml/twin/prompt-composer.ts +143 -0
  767. package/server/services/workshop/aml/twin/provider-contracts.ts +98 -34
  768. package/server/services/workshop/aml/twin/provider-health.ts +69 -8
  769. package/server/services/workshop/aml/twin/provider-loader.ts +76 -45
  770. package/server/services/workshop/aml/twin/provider-registry.ts +670 -49
  771. package/server/services/workshop/aml/twin/repo.ts +63 -4
  772. package/server/services/workshop/aml/twin/scene-builder.ts +118 -0
  773. package/server/services/workshop/aml/twin/scene-lifecycle.ts +60 -0
  774. package/server/services/workshop/aml/twin/snapshot-service.ts +395 -22
  775. package/server/services/workshop/aml/twin/training-plans.ts +260 -0
  776. package/server/services/workshop/aml/twin/trial-service.ts +97 -13
  777. package/server/services/workshop/aml/twin/write-guard.ts +20 -0
  778. package/server/services/workshop/daq/daq-controller/state.ts +8 -5
  779. package/server/services/workshop/daq/drivers/registry.ts +116 -144
  780. package/server/services/workshop/db/database/migrations.ts +40 -0
  781. package/server/services/workshop/db/database/open.ts +4 -1
  782. package/server/services/workshop/db/database/schema.ts +68 -1
  783. package/server/services/workshop/db/database/seed.ts +22 -0
  784. package/server/services/workshop/db/readonly.ts +30 -0
  785. package/server/services/workshop/dcw/dcw-controller/crud.ts +162 -152
  786. package/server/services/workshop/dcw/dcw-controller/helpers.ts +61 -57
  787. package/server/services/workshop/dcw/dcw-controller/types.ts +61 -57
  788. package/server/services/workshop/dcw/dcw-controller/write-audit.ts +49 -0
  789. package/server/services/workshop/dcw/dcw-controller/write.ts +137 -147
  790. package/server/services/workshop/dcw/dcw-node.ts +18 -2
  791. package/server/services/workshop/dcw/dcw-recipe.repo.ts +5 -0
  792. package/server/services/workshop/dcw/dcw-runtime.ts +9 -3
  793. package/server/services/workshop/dcw/drivers/index.ts +2 -1
  794. package/server/services/workshop/dcw/drivers/modbus-rtu.ts +85 -93
  795. package/server/services/workshop/dcw/drivers/modbus.ts +131 -139
  796. package/server/services/workshop/dcw/drivers/opcua.ts +103 -110
  797. package/server/services/workshop/dcw/drivers/registry.ts +25 -45
  798. package/server/services/workshop/dcw/drivers/shared.ts +24 -6
  799. package/server/services/workshop/dcw/param-limits.ts +193 -142
  800. package/server/services/workshop/dcw/param-map.repo.ts +318 -305
  801. package/server/services/workshop/plugin-driver-registry.ts +108 -0
  802. package/server/services/workshop/runtime/manager/admin-channel.ts +13 -0
  803. package/server/services/workshop/runtime/manager/channel-templates.ts +29 -2
  804. package/server/services/workshop/runtime/manager/runtime-wiring.ts +8 -0
  805. package/server/services/workshop/runtime/permission-scope.ts +79 -81
  806. package/server/services/workshop/runtime/schedule-runtime.ts +33 -6
  807. package/server/utils/errors.ts +8 -0
  808. package/shared/config/engine.mjs +5 -0
  809. package/shared/config/home.mjs +15 -20
  810. package/shared/config/schema.json +135 -133
  811. package/shared/dcw-protocol/line.ts +133 -131
  812. package/shared/dcw-protocol/recipe.ts +311 -301
  813. package/shared/local-time.mjs +116 -36
  814. package/.output/public/_nuxt/-hB4kEmt.js +0 -1
  815. package/.output/public/_nuxt/74x7BOWv2.js +0 -1
  816. package/.output/public/_nuxt/9c5GOgbu.js +0 -1
  817. package/.output/public/_nuxt/BHwG4yNs.js +0 -1
  818. package/.output/public/_nuxt/BIOq3xqe2.js +0 -1
  819. package/.output/public/_nuxt/BL_dbd2v2.js +0 -1
  820. package/.output/public/_nuxt/BNnnYEYh2.js +0 -1
  821. package/.output/public/_nuxt/BxYTM0hb.js +0 -1
  822. package/.output/public/_nuxt/C3twEwTh2.js +0 -1
  823. package/.output/public/_nuxt/CGZVhYJ4.js +0 -1
  824. package/.output/public/_nuxt/CJRDL4EG.js +0 -1
  825. package/.output/public/_nuxt/CKQPwwZa2.js +0 -1
  826. package/.output/public/_nuxt/CeWnOF3O.js +0 -1
  827. package/.output/public/_nuxt/ChoLwR-s.js +0 -1
  828. package/.output/public/_nuxt/DGw8juu_.js +0 -2
  829. package/.output/public/_nuxt/DJdDFnjG2.js +0 -1
  830. package/.output/public/_nuxt/DXIaadqv.js +0 -1
  831. package/.output/public/_nuxt/D_7AzAWe.js +0 -1
  832. package/.output/public/_nuxt/DdvQ7LRI.js +0 -14
  833. package/.output/public/_nuxt/DeYsUzhr.js +0 -1
  834. package/.output/public/_nuxt/DkLCjrCk2.js +0 -47
  835. package/.output/public/_nuxt/DpqA8D8_.js +0 -1
  836. package/.output/public/_nuxt/DqtgGFEc.js +0 -1
  837. package/.output/public/_nuxt/Dy3oXKdn2.js +0 -1
  838. package/.output/public/_nuxt/PLGqdko0.js +0 -1
  839. package/.output/public/_nuxt/U8oQxruK.js +0 -1
  840. package/.output/public/_nuxt/WleoCtUX.js +0 -1
  841. package/.output/public/_nuxt/ZvXovq7N2.js +0 -1
  842. package/.output/public/_nuxt/_id_.Bossmhv1.css +0 -1
  843. package/.output/public/_nuxt/_wsId_.D-u-dbP9.css +0 -1
  844. package/.output/public/_nuxt/aml.Bi5X6_oi.css +0 -1
  845. package/.output/public/_nuxt/builds/meta/0530cee1-fff5-4025-a6f4-5708b6534608.json +0 -1
  846. package/.output/public/_nuxt/cDcDztgb2.js +0 -1
  847. package/.output/public/_nuxt/e7BBCLxr.js +0 -1
  848. package/.output/public/_nuxt/hkMGMTqt.js +0 -1
  849. package/.output/public/_nuxt/ikAUnxx3.js +0 -1
  850. package/.output/public/_nuxt/y9kob70X.js +0 -1
  851. package/.output/server/chunks/_/env-manager.mjs +0 -162
  852. package/.output/server/chunks/_/env-manager.mjs.map +0 -1
  853. package/.output/server/chunks/build/_id_-DgMpjM3_.mjs.map +0 -1
  854. package/.output/server/chunks/build/_id_-Dv3BQbYV.mjs.map +0 -1
  855. package/.output/server/chunks/build/_wsId_-BKJvFmyf.mjs.map +0 -1
  856. package/.output/server/chunks/build/aml-DdWicH3t.mjs.map +0 -1
  857. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs +0 -43
  858. package/.output/server/chunks/build/client-only-qNA2OVV_.mjs.map +0 -1
  859. package/.output/server/chunks/build/daq-CPtsh0e7.mjs.map +0 -1
  860. package/.output/server/chunks/build/logs-CeaiO3y9.mjs.map +0 -1
  861. package/.output/server/chunks/build/pages-Bn90ijKD.mjs.map +0 -1
  862. package/.output/server/chunks/build/settings-DVAUVMsX.mjs.map +0 -1
  863. package/.output/server/chunks/build/useAmlJobs-DBuLvWMF.mjs.map +0 -1
  864. package/.output/server/chunks/build/useDcwAddNode-C8nE7geh.mjs.map +0 -1
  865. package/.output/server/chunks/build/useDcwRecipes-BzGOymqz.mjs.map +0 -1
  866. package/.output/server/chunks/build/useDcwWrites-3RxwN36I.mjs.map +0 -1
  867. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs +0 -35
  868. package/.output/server/chunks/build/useLocalTime-9a4B-aHv.mjs.map +0 -1
  869. package/.output/server/chunks/build/useMonitorData-CEpKXoD4.mjs.map +0 -1
  870. package/.output/server/chunks/build/useMonitorFormat-_7zLapf3.mjs.map +0 -1
  871. package/.output/server/chunks/build/useWorkbenchWorkspaces-B_2mOxN6.mjs.map +0 -1
  872. package/.output/server/chunks/build/useWorkshopWs-B-Es2Xg3.mjs.map +0 -1
  873. package/.output/server/chunks/build/useWorkspaceChannels-BwB6TAWY.mjs.map +0 -1
  874. package/.output/server/chunks/build/workshop-CmgpTwyf.mjs.map +0 -1
  875. /package/.output/public/_nuxt/{B2x8SKRO.js → B2x8SKRO2.js} +0 -0
  876. /package/.output/public/_nuxt/{BzvHUfRR2.js → BzvHUfRR.js} +0 -0
  877. /package/.output/public/_nuxt/{DPUXbTg92.js → DPUXbTg9.js} +0 -0
  878. /package/.output/public/_nuxt/{DdNujZN5.js → DdNujZN52.js} +0 -0
  879. /package/.output/public/_nuxt/{DlUQa0wn2.js → DlUQa0wn.js} +0 -0
  880. /package/.output/public/_nuxt/{Du9v6qGB.js → Du9v6qGB2.js} +0 -0
  881. /package/.output/public/_nuxt/{TOWR4WpO.js → TOWR4WpO2.js} +0 -0
  882. /package/.output/public/_nuxt/{cBI0JqsV2.js → cBI0JqsV.js} +0 -0
  883. /package/.output/public/_nuxt/{zh-S_7rN.js → zh-S_7rN2.js} +0 -0
@@ -3,20 +3,35 @@
3
3
  * 该工具族不拥有任何 DCW 写入能力;模型门禁未通过时仅返回 safe_small_step 试探。
4
4
  */
5
5
  import { mkdir, writeFile } from 'node:fs/promises'
6
+ import { readFileSync } from 'node:fs'
6
7
  import { join } from 'node:path'
7
8
  import { agentBadgeLabel } from '../agent-badge'
8
9
  import { getAmlRuntime } from '../../aml/runtime'
9
- import { defaultInjectionScene, InjectionGreyboxProvider, smallStepCandidates } from '../../aml/twin/physics-runtime'
10
- import { createTwinSnapshot } from '../../aml/twin/snapshot-service'
11
- import { evaluateHybridGates, DEFAULT_ACCEPTANCE_PROFILE } from '../../aml/twin/acceptance'
12
- import { issueRecommendationCertificate, runVirtualTrial } from '../../aml/twin/trial-service'
13
- import { parseSceneContract, sha256, type SceneContract } from '../../aml/twin/contracts'
10
+ import { defaultInjectionScene, InjectionGreyboxProvider, smallStepCandidates, type PhysicsModelProvider } from '../../aml/twin/physics-runtime'
11
+ import { assertTwinSnapshot, createTwinSnapshot } from '../../aml/twin/snapshot-service'
12
+ import { createNodeBindingSnapshot } from '../../aml/twin/binding-snapshot'
13
+ import { evaluateHybridGates, resolveAcceptanceProfile } from '../../aml/twin/acceptance'
14
+ import { parseSceneContract, sha256, type ObjectiveProfile, type SceneContract, type TwinSnapshot } from '../../aml/twin/contracts'
15
+ import { sceneContractHash, type SceneWithDraftMetadata } from '../../aml/twin/scene-lifecycle'
14
16
  import { getDaqController } from '../../daq/daq-controller'
15
17
  import { getAgentNodeBindingRepo } from '../node-bindings.repo'
16
18
  import type { HostToolResult } from '../host-tool-bridge/types'
17
19
  import { recordOps } from '../../ops/ops'
18
20
  import { createTwinRepo } from '../../aml/twin/repo'
19
21
  import { requestCalibration, DEFAULT_TWIN_CALIBRATION_POLICY } from '../../aml/twin/calibration-scheduler'
22
+ import { getTwinProviderRegistry } from '../../aml/twin/provider-registry'
23
+ import { compileSceneDraft, discoverSceneNodes, type NodeSemanticInput } from '../../aml/twin/scene-builder'
24
+ import { getDcwController } from '../../dcw/dcw-controller'
25
+ import { getDaqNodeRepo } from '../../daq/daq-node.repo'
26
+ import { compileDeclarativeProvider } from '../../aml/twin/declarative-provider'
27
+ import { validatePhysicsSpec } from '../../aml/twin/physics-spec'
28
+ import { draftPhysicsSpecFromScene } from '../../aml/twin/physics-spec-draft'
29
+ import { ModelBackedHybridProvider, assertModelSceneLineage } from '../../aml/twin/model-backed-provider'
30
+ import { syncRolloutProvider, runVirtualTrial, issueRecommendationCertificate, type RolloutProvider } from '../../aml/twin/trial-service'
31
+ import { assertFrozenScene } from '../../aml/twin/scene-lifecycle'
32
+ import { getChannelTwinProfile } from '../../aml/twin/channel-profile'
33
+ import { channelIdForAgent } from '../../aml/twin/write-guard'
34
+ import { amlTwinFeatureFlags } from '../../aml/twin/feature-flags'
20
35
 
21
36
  function ok(text: string): HostToolResult {
22
37
  return { text }
@@ -47,12 +62,281 @@ async function persistTwinArtifact(kind: string, id: string, payload: unknown):
47
62
  return path
48
63
  }
49
64
 
65
+ function providerForScene(scene: SceneContract, channelId?: string): { provider: PhysicsModelProvider, release: () => void, providerId: string, providerVersion: string, providerHash: string, providerGeneration: number } {
66
+ const registry = getTwinProviderRegistry()
67
+ const profile = channelId ? getChannelTwinProfile(channelId) : null
68
+ const lineageKind = profile?.profile === 'hybrid_twin' || profile?.profile === 'aml_optimization'
69
+ if (lineageKind && profile?.sceneId && profile.sceneId !== scene.sceneId) throw new Error('TWIN_SCENE_CHANNEL_MISMATCH')
70
+ const requested = String(profile?.providerId || scene.physicsProfileId || 'injection-greybox-v1')
71
+ const lease = profile?.providerVersion
72
+ ? registry.resolveProvider(requested, profile.providerVersion, { generation: profile.providerGeneration, allowDraining: true })
73
+ : registry.resolveProvider(requested, { generation: profile?.providerGeneration, allowDraining: true })
74
+ if (lease) {
75
+ if (profile?.providerHash && profile.providerHash !== lease.lineage.providerHash) {
76
+ lease.release()
77
+ throw new Error('TWIN_PROVIDER_HASH_MISMATCH')
78
+ }
79
+ return { provider: lease.provider, release: lease.release, providerId: lease.lineage.providerId, providerVersion: lease.lineage.providerVersion, providerHash: lease.lineage.providerHash, providerGeneration: lease.lineage.generation }
80
+ }
81
+ // 场景谱系通道(hybrid_twin / aml_optimization)与非注入 provider 缺注册一律 fail-closed;
82
+ // aml_optimization 不允许静默回落注入物理模型 —— 优化通道的孪生评估必须有真模型或真 provider。
83
+ if (lineageKind || requested !== 'injection-greybox-v1') throw new Error(`TWIN_PROVIDER_UNAVAILABLE:${requested}`)
84
+ // Transitional compatibility is limited to an explicitly named injection scene/provider.
85
+ const fallback = new InjectionGreyboxProvider()
86
+ return { provider: fallback, release: () => {}, providerId: fallback.manifest.physicsModelId, providerVersion: fallback.manifest.version, providerHash: sha256({ ...fallback.manifest, createdAt: undefined }), providerGeneration: 0 }
87
+ }
88
+
89
+ export interface RolloutProviderRef {
90
+ rollout: RolloutProvider
91
+ modelId: string
92
+ modelHash: string
93
+ modelBacked: boolean
94
+ release: () => void
95
+ /** 模型驱动时的平台侧集成 UQ(rollout 后读取;coverage 来自训练工件) */
96
+ uncertainty?: () => { predictions: Array<Record<string, number>>, coverage: number, calibrationFresh: boolean, inputDistance: number }
97
+ }
98
+
99
+ /**
100
+ * 解析 VirtualTrial/MPC 的 rollout 模型面:
101
+ * - 给了 model_id → 必须是注册表中 stage ∈ candidate/shadow/production 的 hybrid 模型,
102
+ * 且其数据集 line/product/recipe 与场景一致(配方隔离);真实工件(校准后 PhysicsSpec
103
+ * + 残差集成 ONNX)驱动每次 rollout,并提供平台侧集成 UQ;
104
+ * - 未给 → 物理_only provider(旧行为),model_id 仅作记录标签。
105
+ */
106
+ export async function rolloutProviderFor(agentId: string, scene: SceneContract, snapshot: TwinSnapshot, modelId: string | undefined): Promise<RolloutProviderRef> {
107
+ let requested = String(modelId ?? '').trim()
108
+ if (!requested) {
109
+ // 投用语义:未显式指定模型时,自动生效同场景谱系(产线/产品/配方一致)的 production 模型;
110
+ // 无生产模型才回退物理_only —— 与 aml_model_promote「生产生效」承诺闭环。
111
+ try {
112
+ const rt = getAmlRuntime()
113
+ const prod = rt.repo.model.list({ stage: 'production', purpose: 'mpc_surrogate', limit: 50 })
114
+ .find((m) => {
115
+ const ds = rt.repo.dataset.get(m.datasetId)
116
+ if (!ds) return false
117
+ if (scene.lineId && ds.lineId !== scene.lineId) return false
118
+ if (scene.productId && ds.productId !== scene.productId) return false
119
+ if (scene.recipeId && ds.recipeId !== scene.recipeId) return false
120
+ return true
121
+ })
122
+ if (prod) requested = prod.id
123
+ }
124
+ catch { /* 注册表不可用时按无模型处理 */ }
125
+ }
126
+ if (!requested) {
127
+ const physicsRef = providerForScene(scene, channelIdForAgent(agentId))
128
+ return { rollout: syncRolloutProvider(physicsRef.provider), modelId: physicsRef.providerId, modelHash: physicsRef.providerHash, modelBacked: false, release: physicsRef.release }
129
+ }
130
+ const rt = getAmlRuntime()
131
+ const row = rt.repo.model.get(requested)
132
+ if (!row) throw new Error(`TWIN_MODEL_MISSING:${requested}`)
133
+ if (row.stage === 'retired') throw new Error(`TWIN_MODEL_RETIRED:${requested}`)
134
+ const dataset = rt.repo.dataset.get(row.datasetId)
135
+ if (!dataset) throw new Error(`TWIN_MODEL_DATASET_MISSING:${requested}`)
136
+ assertModelSceneLineage(dataset, scene)
137
+ const backed = await ModelBackedHybridProvider.create(row, {
138
+ stateEstimate: snapshot.stateEstimate ?? {},
139
+ controlValues: snapshot.controlValues ?? {},
140
+ disturbances: snapshot.disturbances ?? {},
141
+ })
142
+ let modelHash = `model:${row.id}`
143
+ try {
144
+ modelHash = sha256(readFileSync(join(row.path, 'hybrid_manifest.json'), 'utf8'))
145
+ }
146
+ catch { /* manifest 读取失败时退化为 id 哈希锚 */ }
147
+ return {
148
+ rollout: backed,
149
+ modelId: row.id,
150
+ modelHash,
151
+ modelBacked: true,
152
+ release: () => {},
153
+ uncertainty: () => {
154
+ const u = backed.takeUncertainty()
155
+ return { predictions: u.memberPredictions, coverage: u.calibrationCoverage ?? 0, calibrationFresh: u.calibrationCoverage != null, inputDistance: 0 }
156
+ },
157
+ }
158
+ }
159
+
160
+ /** 工具:twin_physics_spec_draft —— 从冻结场景生成骨架 PhysicsSpec(可校准/可训练的起步物理模型) */
161
+ export async function toolTwinPhysicsSpecDraft(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
162
+ try {
163
+ const supplied = jsonArg<Record<string, unknown>>(args, 'scene_json')
164
+ let scene: SceneContract
165
+ if (supplied) {
166
+ scene = parseSceneContract(supplied)
167
+ }
168
+ else {
169
+ const auth = authoritativeSceneForAgent(agentId, {}, defaultInjectionScene('twin-physics-draft'))
170
+ scene = auth.scene
171
+ }
172
+ const dtSec = Number(args.dt_sec)
173
+ const spec = draftPhysicsSpecFromScene({ scene, createdBy: agentId, ...(Number.isFinite(dtSec) && dtSec > 0 ? { dtSec } : {}) })
174
+ const artifact = await persistTwinArtifact('physics-spec-draft', `${spec.modelId}-${Date.now().toString(36)}`, spec)
175
+ const calibratable = spec.parameters.filter(p => p.min != null && p.max != null).length
176
+ return ok([
177
+ `PhysicsSpec 骨架已生成(场景 ${scene.sceneId}@${scene.sceneVersion}):`,
178
+ ` model_id: ${spec.modelId} | 状态变量 ${spec.states.length} | 观测方程 ${spec.observations.length} | 参数 ${spec.parameters.length}(可校准 ${calibratable})`,
179
+ ` 结构: 每个 state = 一阶惯性弛豫(τ/增益为先验盒内可校准参数);观测 = persistence 恒等基线`,
180
+ ` artifact: ${artifact}`,
181
+ `下一步: 按真实工况润色方程 → twin_physics_spec_validate 校验 → twin_physics_spec_compile 编译候选(须已冻结场景)→ aml_job_submit(job_kind=hybrid_residual)训练校准;骨架的 τ/增益在训练 stage A 自动按数据拟合。`,
182
+ `注意: dt_sec 需与训练数据集 beat 一致(缺省 1s);变量 id 已按标识符规则净化,nodeId 保留真实节点映射。`,
183
+ ].join('\n'))
184
+ }
185
+ catch (err) {
186
+ return fail(`PhysicsSpec 骨架生成失败:${err instanceof Error ? err.message : String(err)}`)
187
+ }
188
+ }
189
+
190
+ function authoritativeSceneForAgent(agentId: string, args: Record<string, unknown>, fallback: SceneContract): { scene: SceneWithDraftMetadata, channelId?: string, hybrid: boolean } {
191
+ const channelId = channelIdForAgent(agentId)
192
+ if (!channelId) return { scene: fallback, hybrid: false }
193
+ const profile = getChannelTwinProfile(channelId)
194
+ // 场景谱系通道:hybrid_twin 恒可;aml_optimization 仅 aml 模式(已绑模型)可 ——
195
+ // 与 dispatch 层 modelBackedToolPolicyFor 同判,未绑模型时回落 fallback(探索模式
196
+ // 的孪生工具在 dispatch 已被拒,这里只兜底)。优化通道实例化时存有
197
+ // sceneId/sceneVersion,冻结契约按 sceneId 全局解析(训练通道冻结、优化通道复用)。
198
+ const lineageKind = profile.profile === 'hybrid_twin'
199
+ || (profile.profile === 'aml_optimization' && profile.optimizationMode === 'aml' && Boolean(profile.boundModelId))
200
+ if (!lineageKind) return { scene: fallback, channelId, hybrid: false }
201
+ if (!profile.sceneId || !profile.sceneVersion) throw new Error('TWIN_CHANNEL_SCENE_LINEAGE_REQUIRED')
202
+ const row = createTwinRepo(getAmlRuntime().db).getScene(profile.sceneId, profile.sceneVersion)
203
+ if (!row) throw new Error('TWIN_CHANNEL_SCENE_NOT_FOUND')
204
+ const rawScene = JSON.parse(row.contractJson) as SceneWithDraftMetadata
205
+ parseSceneContract(rawScene)
206
+ assertFrozenScene(rawScene)
207
+ const persisted = rawScene
208
+ const supplied = jsonArg<Record<string, unknown>>(args, 'scene_json')
209
+ if (supplied) {
210
+ const suppliedParsed = parseSceneContract(supplied)
211
+ if (sceneContractHash(suppliedParsed) !== row.contractHash) throw new Error('TWIN_SCENE_HASH_MISMATCH')
212
+ }
213
+ return { scene: persisted, channelId, hybrid: true }
214
+ }
215
+
216
+ export async function toolTwinProviderCatalog(_agentId: string, args: Record<string, unknown> = {}): Promise<HostToolResult> {
217
+ try {
218
+ const registry = getTwinProviderRegistry()
219
+ const filter = typeof args.scene_kind === 'string' && args.scene_kind.trim() ? { sceneKind: args.scene_kind.trim() } : {}
220
+ return ok(JSON.stringify({ apiVersion: 'twin-provider.v1', providers: registry.listProviders(filter), scenePacks: registry.listScenePacks(), solverAdapters: registry.listSolverAdapters() }, null, 2))
221
+ }
222
+ catch (err) {
223
+ return fail(`Twin Provider 目录读取失败:${err instanceof Error ? err.message : String(err)}`)
224
+ }
225
+ }
226
+
227
+ function boundSceneNodes(agentId: string): NodeSemanticInput[] {
228
+ const bindings = getAgentNodeBindingRepo().byAgent(agentId)
229
+ const daq = getDaqNodeRepo()
230
+ const dcw = getDcwController()
231
+ const out: NodeSemanticInput[] = []
232
+ for (const binding of bindings) {
233
+ if (binding.kind === 'daq') {
234
+ const node = daq.byId(binding.nodeId)
235
+ if (!node) continue
236
+ out.push({ nodeId: node.id, kind: 'daq', name: node.name, physicalMeaning: node.semantics ?? node.name, unit: node.unit, min: node.min, max: node.max, lineId: node.lineId, protocol: node.driver, evidence: [node.semantics ?? '', node.templateKey].filter(Boolean) })
237
+ }
238
+ else {
239
+ const node = dcw.byId(binding.nodeId)
240
+ if (!node) continue
241
+ out.push({ nodeId: node.id, kind: 'dcw', name: node.name, physicalMeaning: node.semantics ?? node.name, unit: node.unit, min: node.min, max: node.max, maxStep: Math.max(Math.abs((node.max ?? 1) - (node.min ?? 0)) * 0.02, 0.001), lineId: node.lineId, protocol: node.driver, writable: true, evidence: [node.semantics ?? '', node.name, node.templateRef].filter(Boolean) })
242
+ }
243
+ }
244
+ return out
245
+ }
246
+
247
+ export async function toolTwinSceneDiscover(agentId: string, args: Record<string, unknown> = {}): Promise<HostToolResult> {
248
+ try {
249
+ const nodes = boundSceneNodes(agentId)
250
+ if (!nodes.length) return fail('尚未绑定 DAQ/DCW 节点,无法执行场景发现。请先绑定当前作业场景节点。')
251
+ const result = discoverSceneNodes(nodes)
252
+ return ok(JSON.stringify({ scene_kind: String(args.scene_kind ?? 'unknown'), nodeCount: nodes.length, counts: result.counts, nodes: result.nodes }, null, 2))
253
+ }
254
+ catch (err) {
255
+ return fail(`场景发现失败:${err instanceof Error ? err.message : String(err)}`)
256
+ }
257
+ }
258
+
259
+ export async function toolTwinSceneCompile(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
260
+ try {
261
+ const sceneId = String(args.scene_id ?? '').trim()
262
+ const lineId = String(args.line_id ?? '').trim()
263
+ if (!sceneId || !lineId) return fail('scene_id 和 line_id 必填。')
264
+ const nodes = boundSceneNodes(agentId).filter(node => !args.node_ids || (Array.isArray(args.node_ids) && args.node_ids.map(String).includes(node.nodeId)))
265
+ const draft = compileSceneDraft({ sceneId, sceneVersion: String(args.scene_version ?? '0.1.0-draft'), lineId, productId: args.product_id ? String(args.product_id) : undefined, recipeId: args.recipe_id ? String(args.recipe_id) : undefined, prompt: args.prompt ? String(args.prompt) : undefined, createdBy: agentId, nodes, physicsProfileId: args.physics_profile_id ? String(args.physics_profile_id) : undefined, objectiveProfileIds: Array.isArray(args.objective_profile_ids) ? args.objective_profile_ids.map(String) : undefined, freeze: false })
266
+ const repo = createTwinRepo(getAmlRuntime().db)
267
+ repo.upsertScene(draft, agentId)
268
+ const path = await persistTwinArtifact('scenes', `${draft.sceneId}-${draft.sceneVersion}`, draft)
269
+ return ok(`SceneContract Draft 已生成\n scene_id: ${draft.sceneId}\n scene_version: ${draft.sceneVersion}\n contract_hash: ${draft.draftMeta.contractHash}\n status: ${draft.draftMeta.status}\n controls: ${draft.controls.length}\n states: ${draft.states.length}\n targets: ${draft.observations.filter(x => x.role === 'target').length}\n guards: ${draft.guards.length}\n artifact: ${path}\n 注意:首次训练/上线前必须由用户确认并冻结 SceneContract;当前仅为 draft。`)
270
+ }
271
+ catch (err) {
272
+ return fail(`SceneContract 编译失败:${err instanceof Error ? err.message : String(err)}`)
273
+ }
274
+ }
275
+
276
+ export async function toolTwinSceneFreeze(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
277
+ try {
278
+ const sceneId = String(args.scene_id ?? '').trim()
279
+ const sceneVersion = String(args.scene_version ?? '').trim()
280
+ const approvedBy = String(args.approved_by ?? agentId).trim()
281
+ const confirmation = String(args.confirmation ?? '').trim()
282
+ if (!sceneId || !sceneVersion) return fail('scene_id 和 scene_version 必填。')
283
+ if (confirmation !== 'USER_CONFIRMED_SCENE_CONTRACT') return fail('冻结被拒绝:必须先完成用户确认,并传入 confirmation=USER_CONFIRMED_SCENE_CONTRACT。')
284
+ const repo = createTwinRepo(getAmlRuntime().db)
285
+ const frozen = repo.freezeScene(sceneId, sceneVersion, approvedBy, args.expected_hash ? String(args.expected_hash) : undefined)
286
+ const path = await persistTwinArtifact('scenes', `${sceneId}-${sceneVersion}-frozen`, frozen)
287
+ recordOps({ actor: agentId, actorName: agentId, actorKind: 'agent', action: 'twin.scene.freeze', kind: 'write', summary: `SceneContract ${sceneId}@${sceneVersion} 已冻结`, targetKind: 'twin_scene', targetId: `${sceneId}@${sceneVersion}` })
288
+ return ok(JSON.stringify({ sceneId, sceneVersion, status: frozen.status, contractHash: frozen.contractHash, approvedBy: frozen.approvedBy, approvedAt: frozen.approvedAt, artifact: path, next: '允许生成 PhysicsSpec 并进入物理校准;SceneContract 变更必须新建版本。' }, null, 2))
289
+ }
290
+ catch (err) {
291
+ return fail(`SceneContract 冻结失败:${err instanceof Error ? err.message : String(err)}`)
292
+ }
293
+ }
294
+
295
+ function physicsSpecArg(args: Record<string, unknown>): unknown {
296
+ return jsonArg(args, 'physics_spec') ?? jsonArg(args, 'spec_json')
297
+ }
298
+
299
+ export async function toolTwinPhysicsSpecValidate(_agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
300
+ try {
301
+ const input = physicsSpecArg(args)
302
+ if (!input) return fail('physics_spec 必填。')
303
+ const result = validatePhysicsSpec(input)
304
+ return ok(JSON.stringify({ apiVersion: 'physics-spec.v1', valid: result.valid, errors: result.errors, warnings: result.warnings, issues: result.issues, spec: result.spec ?? null }, null, 2))
305
+ }
306
+ catch (err) {
307
+ return fail(`PhysicsSpec 校验失败:${err instanceof Error ? err.message : String(err)}`)
308
+ }
309
+ }
310
+
311
+ export async function toolTwinPhysicsSpecCompile(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
312
+ try {
313
+ const input = physicsSpecArg(args)
314
+ if (!input) return fail('physics_spec 必填。')
315
+ const checked = validatePhysicsSpec(input)
316
+ if (!checked.valid || !checked.spec) return fail(JSON.stringify({ apiVersion: 'physics-spec.v1', valid: false, errors: checked.errors, warnings: checked.warnings, issues: checked.issues }, null, 2))
317
+ const sceneInput = jsonArg<Record<string, unknown>>(args, 'scene_json')
318
+ if (!sceneInput) return fail('physics_spec 编译前必须提供已冻结 scene_json。')
319
+ const scene = assertFrozenScene(sceneInput)
320
+ if (checked.spec.sceneId !== scene.sceneId) return fail(`PhysicsSpec 场景不匹配: spec=${checked.spec.sceneId}, scene=${scene.sceneId}`)
321
+ const provider = compileDeclarativeProvider(checked.spec)
322
+ const artifact = { apiVersion: 'physics-spec.v1', kind: 'declarative-provider-candidate', sceneId: scene.sceneId, sceneVersion: scene.sceneVersion, providerId: provider.manifest.physicsModelId, providerVersion: provider.manifest.version, sourceHash: provider.manifest.sourceHash, spec: checked.spec, manifest: provider.manifest, compiledBy: agentId, compiledAt: new Date().toISOString(), status: 'candidate_not_registered' }
323
+ const path = await persistTwinArtifact('physics-spec', `${checked.spec.modelId}-${provider.manifest.sourceHash ?? sha256(checked.spec)}`, artifact)
324
+ return ok(JSON.stringify({ ...artifact, artifact: path, next: '候选 Provider 仍须通过 Registry 注册、Replay/health、物理校准、AML Hybrid Gate;此工具不会直接切换 production。' }, null, 2))
325
+ }
326
+ catch (err) {
327
+ return fail(`PhysicsSpec 编译失败:${err instanceof Error ? err.message : String(err)}`)
328
+ }
329
+ }
50
330
  export async function toolTwinSceneRead(_agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
51
331
  const defaultScene = defaultInjectionScene('twin-scene-tool')
52
332
  const supplied = jsonArg<Record<string, unknown>>(args, 'scene_json')
53
- const scene = supplied ? parseSceneContract(supplied) : defaultScene
333
+ let scene = supplied ? parseSceneContract(supplied) : defaultScene
54
334
  const sceneId = String(args.scene_id ?? scene.sceneId)
55
- if (sceneId !== scene.sceneId) return fail(`场景契约未提供: scene_id=${sceneId};请通过 scene_json 注册该场景,或先注册 PhysicsModelProvider。`)
335
+ if (!supplied && sceneId !== scene.sceneId) {
336
+ const pack = getTwinProviderRegistry().listScenePacks().find(item => item.sceneKind === sceneId)
337
+ if (pack?.compile) scene = parseSceneContract(await pack.compile({ userPrompt: String(args.user_prompt ?? ''), nodeCatalog: [], lineContext: {} }))
338
+ }
339
+ if (sceneId !== scene.sceneId) return fail(`场景契约未提供: scene_id=${sceneId};请先调用 twin_provider_catalog,或通过 scene_json 注入场景契约。`)
56
340
  return ok(`场景契约 ${scene.sceneId}@${scene.sceneVersion}\n${JSON.stringify(scene, null, 2)}\n\n控制策略:recommendation-only;模型门禁未通过时只能 safe_small_step,禁止直接 DCW。\n快照前置:scene 的 observations/states 必须带 nodeId,且与 Agent 已绑定的真实 DAQ 节点一致;内置默认场景不带 nodeId,直接调用只会在 TwinSnapshot 里得到 fresh=false 并在 VirtualTrial 抛 SNAPSHOT_STALE —— 请用 scene_json 注入带 nodeId 的场景契约。`)
57
341
  }
58
342
 
@@ -79,26 +363,40 @@ async function autoDaqSamples(agentId: string, scene: SceneContract, nowMs: numb
79
363
 
80
364
  export async function toolTwinSnapshotCreate(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
81
365
  try {
82
- const scene = parseSceneContract(jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-snapshot-tool'))
366
+ const requestedScene = parseSceneContract(jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-snapshot-tool'))
367
+ const authoritative = authoritativeSceneForAgent(agentId, args, requestedScene)
368
+ const scene = authoritative.scene
369
+ const flags = amlTwinFeatureFlags()
370
+ if (authoritative.hybrid && !flags.trialEnabled) return fail('AML Twin trial/snapshot 功能开关已关闭。')
371
+ const channelId = authoritative.channelId ?? String(args.channel_id ?? '').trim()
372
+ if (!channelId) return fail('channel_id 必填;生产 TwinSnapshot 必须绑定 Channel。')
83
373
  const twinRepo = createTwinRepo(getAmlRuntime().db)
84
- twinRepo.upsertScene(scene, agentId)
85
374
  const nowMs = Number(args.now_ms) || Date.now()
86
375
  const freshnessMaxMs = Number(args.freshness_max_ms) || 60_000
376
+ const bindingSnapshot = authoritative.hybrid
377
+ ? createNodeBindingSnapshot({ channelId, createdBy: agentId, agentId, scene, lineId: scene.lineId, productId: scene.productId, recipeId: scene.recipeId, nowMs, requireFrozenScene: true })
378
+ : undefined
87
379
  const suppliedSamples = jsonArg<Array<{ nodeId: string, at: number, value: number, sequence?: string }>>(args, 'samples', []) ?? []
380
+ if (authoritative.hybrid && args.auto_daq !== true) return fail('Hybrid Twin 生产快照必须由服务端 bound DAQ 采集:请传 auto_daq=true;不接受 Agent 自报 samples。')
88
381
  const samples = args.auto_daq === true || suppliedSamples.length === 0
89
382
  ? await autoDaqSamples(agentId, scene, nowMs, freshnessMaxMs)
90
383
  : suppliedSamples
91
384
  const snapshot = createTwinSnapshot({
92
385
  scene,
93
- channelId: String(args.channel_id ?? ''),
386
+ frozenScene: authoritative.hybrid ? scene : undefined,
387
+ channelId,
94
388
  createdBy: agentId,
95
389
  phase: String(args.phase ?? 'holding'),
96
390
  controls: jsonArg<Record<string, number>>(args, 'controls', {}) ?? {},
97
391
  states: jsonArg<Record<string, number>>(args, 'states', {}) ?? {},
98
392
  disturbances: jsonArg<Record<string, number>>(args, 'disturbances', {}) ?? {},
99
393
  samples,
394
+ bindingSnapshot,
100
395
  nowMs,
101
396
  freshnessMaxMs,
397
+ strict: authoritative.hybrid,
398
+ requireBindingSnapshot: authoritative.hybrid,
399
+ requireFrozenScene: authoritative.hybrid,
102
400
  })
103
401
  twinRepo.insertSnapshot(snapshot)
104
402
  const path = await persistTwinArtifact('snapshots', snapshot.snapshotId, snapshot)
@@ -122,9 +420,18 @@ export async function toolTwinSnapshotCreate(agentId: string, args: Record<strin
122
420
 
123
421
  export async function toolTwinTrialRun(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
124
422
  try {
125
- const scene = (jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-trial-tool')) as ReturnType<typeof defaultInjectionScene>
126
- const snapshot = jsonArg<Record<string, unknown>>(args, 'snapshot_json') as never
127
- if (!snapshot) return fail('snapshot_json 必填;必须使用当前 DAQ 生成的 TwinSnapshot,禁止 Agent 伪造执行状态。')
423
+ const requestedScene = (jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-trial-tool')) as ReturnType<typeof defaultInjectionScene>
424
+ const authoritative = authoritativeSceneForAgent(agentId, args, requestedScene)
425
+ const scene = authoritative.scene
426
+ if (authoritative.hybrid && !amlTwinFeatureFlags().trialEnabled) return fail('AML Twin trial 功能开关已关闭。')
427
+ const twinRepo = createTwinRepo(getAmlRuntime().db)
428
+ const snapshotId = String(args.snapshot_id ?? '').trim()
429
+ const snapshot = (authoritative.hybrid ? (snapshotId ? twinRepo.getSnapshot(snapshotId) : null) : (jsonArg<Record<string, unknown>>(args, 'snapshot_json') as never)) as never
430
+ if (!snapshot) return fail(authoritative.hybrid ? 'Hybrid Twin VirtualTrial 必须提供已持久化 snapshot_id;禁止直接注入 snapshot_json。' : 'snapshot_json 必填;必须使用当前 DAQ 生成的 TwinSnapshot,禁止 Agent 伪造执行状态。')
431
+ if (authoritative.hybrid) {
432
+ const bindingSnapshot = createNodeBindingSnapshot({ channelId: authoritative.channelId!, createdBy: agentId, agentId, scene, lineId: scene.lineId, productId: scene.productId, recipeId: scene.recipeId, requireFrozenScene: true })
433
+ assertTwinSnapshot(snapshot as unknown, { scene, frozenScene: scene, bindingSnapshot, channelId: authoritative.channelId, expectedBindingSnapshotHash: bindingSnapshot.snapshotHash, requireFresh: true, requireBindingSnapshot: true, requireFrozenScene: true })
434
+ }
128
435
  // 形状校验:传半截 JSON / 工具结果信封 / 纯字符串时旧行为是原生 TypeError
129
436
  // (Cannot read properties of undefined (reading 'fresh')),调用方看不出该怎么修。
130
437
  const snap = snapshot as { dataQuality?: { fresh?: boolean }, snapshotHash?: string, snapshotId?: string }
@@ -132,19 +439,36 @@ export async function toolTwinTrialRun(agentId: string, args: Record<string, unk
132
439
  return fail('snapshot_json 不是 TwinSnapshot 工件:缺少 snapshotId/dataQuality。请先调用 twin_snapshot_create,并把其 artifact 文件的 JSON 原文整段回传(不要传工具结果文本或截断片段)。')
133
440
  }
134
441
  if (!snap.snapshotHash) return fail('snapshot_json 缺少 snapshotHash(快照被篡改或截断),拒绝执行 VirtualTrial。')
135
- const provider = new InjectionGreyboxProvider()
442
+ const requestedModelId = String(args.model_id ?? '').trim()
443
+ const ref = await rolloutProviderFor(agentId, scene, snap as unknown as TwinSnapshot, requestedModelId || undefined)
136
444
  const baseline = jsonArg<Record<string, number>>(args, 'baseline_controls', {}) ?? {}
137
445
  const candidate = jsonArg<Array<Record<string, number>>>(args, 'candidate_controls', []) ?? []
138
446
  const objective = jsonArg<Record<string, unknown>>(args, 'objective', {
139
447
  schemaVersion: 1, createdAt: new Date().toISOString(), createdBy: agentId, objectiveId: 'weight-quality', targets: { weight: 32.5 }, weights: { weight: 1 }, controlCosts: {}, horizonSteps: candidate.length || 4, trustRegion: {},
140
448
  }) as never
141
- const trial = runVirtualTrial({ scene, snapshot, modelId: String(args.model_id ?? 'physics-only-injection-v1'), modelHash: sha256(provider.manifest), objective, baselineControls: baseline, candidateControls: candidate, provider, uncertainty: jsonArg(args, 'uncertainty') as never, createdBy: agentId })
142
- const certificate = issueRecommendationCertificate(trial, agentId, sha256(provider.manifest), sha256(objective))
143
- const twinRepo = createTwinRepo(getAmlRuntime().db)
144
- twinRepo.insertTrial(trial, String(args.model_id ?? 'physics-only-injection-v1'))
449
+ // 模型驱动 rollout:平台侧集成 UQ(coverage 来自训练工件,而非 Agent 自报);
450
+ // 传 thunk 由 runVirtualTrial 在 rollout 后解析。物理_only 保留调用方透传(旧行为)。
451
+ const uncertainty = ref.modelBacked && ref.uncertainty
452
+ ? ref.uncertainty
453
+ : jsonArg(args, 'uncertainty') as never
454
+ const trial = await runVirtualTrial({ scene, snapshot: snap as unknown as TwinSnapshot, modelId: requestedModelId || ref.modelId, modelHash: ref.modelHash, objective, baselineControls: baseline, candidateControls: candidate, provider: ref.rollout, uncertainty, createdBy: agentId })
455
+ const certificate = issueRecommendationCertificate(trial, agentId, ref.modelHash, sha256(objective))
456
+ // Trial is also a valid first entry point for external ScenePacks. Persist
457
+ // the immutable SceneContract before the FK-backed trial row.
458
+ twinRepo.upsertScene(scene, agentId)
459
+ twinRepo.insertTrial(trial, requestedModelId || ref.modelId)
145
460
  if (certificate) twinRepo.insertRecommendation(certificate, agentId)
146
461
  const path = await persistTwinArtifact('trials', trial.trialId, { trial, certificate })
147
- return ok(`VirtualTrial 已完成(candidateExecuted=false)\n trial_id: ${trial.trialId}\n constraints_passed: ${trial.constraintResults.every(c => c.passed)}\n uq_ood_accepted: ${trial.outOfDistribution.accepted}\n improvement: ${trial.baselineComparison.improvement}\n recommendation_id: ${certificate?.recommendationId ?? '(未签发:门禁未通过或无收益)'}\n artifact: ${path}\n 控制路径: recommendation-only,未调用 DCW。`)
462
+ ref.release()
463
+ return ok(`VirtualTrial 已完成(candidateExecuted=false)
464
+ trial_id: ${trial.trialId}
465
+ rollout_model: ${requestedModelId || ref.modelId}${ref.modelBacked ? '(训练模型驱动:物理主干+有界残差集成)' : '(物理 provider 驱动;传 model_id 可用训练模型 rollout)'}
466
+ uq: coverage=${Number(trial.uncertainty.coverage).toFixed(3)} members=${trial.uncertainty.ensembleSize} ood=${trial.outOfDistribution.accepted ? 'accepted' : `rejected(${trial.outOfDistribution.rejectCode})`}
467
+ constraints_passed: ${trial.constraintResults.every(c => c.passed)}
468
+ improvement: ${trial.baselineComparison.improvement}
469
+ recommendation_id: ${certificate?.recommendationId ?? '(未签发:门禁未通过或无收益)'}
470
+ artifact: ${path}
471
+ 控制路径: recommendation-only,未调用 DCW。`)
148
472
  }
149
473
  catch (err) {
150
474
  return fail(`VirtualTrial 失败:${err instanceof Error ? err.message : String(err)}`)
@@ -153,10 +477,35 @@ export async function toolTwinTrialRun(agentId: string, args: Record<string, unk
153
477
 
154
478
  export async function toolMpcOptimize(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
155
479
  try {
156
- const scene = (jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-mpc-tool')) as ReturnType<typeof defaultInjectionScene>
480
+ const requestedScene = (jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-mpc-tool')) as ReturnType<typeof defaultInjectionScene>
481
+ const authoritative = authoritativeSceneForAgent(agentId, args, requestedScene)
482
+ const scene = authoritative.scene
483
+ if (authoritative.hybrid && !amlTwinFeatureFlags().mpcEnabled) return fail('AML Twin MPC 功能开关已关闭。')
157
484
  const baseline = jsonArg<Record<string, number>>(args, 'baseline_controls', {}) ?? {}
158
485
  const modelId = String(args.model_id ?? '').trim()
159
- const modelRow = modelId ? getAmlRuntime().repo.model.get(modelId) : null
486
+ let snapshot: TwinSnapshot | undefined
487
+ let objective = jsonArg<ObjectiveProfile>(args, 'objective')
488
+ if (authoritative.hybrid) {
489
+ const channelId = authoritative.channelId!
490
+ const snapshotId = String(args.snapshot_id ?? '').trim()
491
+ if (!snapshotId) return fail('Hybrid Twin MPC 必须提供已持久化 snapshot_id,禁止以自由 JSON 代替实时快照。')
492
+ snapshot = createTwinRepo(getAmlRuntime().db).getSnapshot(snapshotId) ?? undefined
493
+ if (!snapshot) return fail(`TwinSnapshot 不存在:${snapshotId}`)
494
+ const bindingSnapshot = createNodeBindingSnapshot({ channelId, createdBy: agentId, agentId, scene, lineId: scene.lineId, productId: scene.productId, recipeId: scene.recipeId, requireFrozenScene: true })
495
+ assertTwinSnapshot(snapshot, { scene, frozenScene: scene, bindingSnapshot, channelId, expectedBindingSnapshotHash: bindingSnapshot.snapshotHash, requireFresh: true, requireBindingSnapshot: true, requireFrozenScene: true })
496
+ objective ??= getChannelTwinProfile(channelId).objective as unknown as ObjectiveProfile
497
+ }
498
+ const targets = objective?.targets ?? Object.fromEntries(scene.observations.filter(v => v.role === 'target').map(v => [v.id, 0]))
499
+ const weights = objective?.weights ?? Object.fromEntries(Object.keys(targets).map(key => [key, 1]))
500
+ const objectiveProfile: ObjectiveProfile = objective ?? {
501
+ schemaVersion: 1, createdAt: new Date().toISOString(), createdBy: agentId, objectiveId: 'scene-default', targets, weights, controlCosts: {}, horizonSteps: Number(args.horizon_steps) || 4, trustRegion: {},
502
+ }
503
+ const providerRef = await rolloutProviderFor(agentId, scene, (snapshot ?? { stateEstimate: {}, controlValues: baseline, disturbances: {}, snapshotId: '', snapshotHash: '', dataQuality: { fresh: true } }) as TwinSnapshot, modelId || undefined)
504
+ const rollout = providerRef.rollout
505
+ // 升档判定跟随实际生效的模型:显式 model_id 或自动投用选中的 production 模型,
506
+ // 否则「投用后自动 precise_search」永远不触发(modelReady 只看显式 model_id)。
507
+ const effectiveModelId = modelId || (providerRef.modelBacked ? providerRef.modelId : '')
508
+ const modelRow = effectiveModelId ? getAmlRuntime().repo.model.get(effectiveModelId) : null
160
509
  let modelReady = false
161
510
  if (modelRow && (modelRow.stage === 'shadow' || modelRow.stage === 'production')) {
162
511
  try {
@@ -164,65 +513,273 @@ export async function toolMpcOptimize(agentId: string, args: Record<string, unkn
164
513
  const twin = metrics.twinEligibility as Record<string, unknown> | undefined
165
514
  modelReady = twin?.recommendationEligible === true && twin?.uqPassed === true && twin?.oodPassed === true && twin?.physicsPassed === true
166
515
  }
167
- catch {
168
- modelReady = false
169
- }
516
+ catch { modelReady = false }
170
517
  }
171
- const provider = new InjectionGreyboxProvider()
172
518
  const candidates = smallStepCandidates(scene, baseline)
173
519
  const mode = modelReady ? 'precise_search' : 'safe_small_step'
174
520
  const selected = modelReady ? candidates : candidates.slice(0, Math.min(3, candidates.length))
175
- const results = selected.map((candidate) => {
176
- const initial = provider.initialize({ stateEstimate: {}, controlValues: baseline })
177
- const trajectory = provider.simulate(initial, Array.from({ length: Number(args.horizon_steps) || 4 }, () => candidate), {})
178
- const constraints = provider.evaluateConstraints(scene, trajectory)
521
+ const horizon = Number(args.horizon_steps) || objectiveProfile.horizonSteps || 4
522
+ // 模型驱动 rollout 的平台侧集成 UQ(coverage 来自训练工件);物理_only 走旧行为
523
+ const trialUncertainty = providerRef.modelBacked && providerRef.uncertainty ? providerRef.uncertainty : undefined
524
+ const results = []
525
+ for (const candidate of selected) {
526
+ if (authoritative.hybrid && snapshot) {
527
+ const trial = await runVirtualTrial({ scene, snapshot, modelId: modelId || providerRef.modelId, modelHash: providerRef.modelHash, objective: objectiveProfile, baselineControls: baseline, candidateControls: Array.from({ length: horizon }, () => candidate), provider: rollout, uncertainty: trialUncertainty as never, createdBy: agentId })
528
+ results.push({ candidate, cost: trial.baselineComparison.candidateCost, constraintsPassed: trial.constraintResults.every(c => c.passed), constraints: trial.constraintResults, trial })
529
+ continue
530
+ }
531
+ const initial = rollout.initialize({ stateEstimate: {}, controlValues: baseline })
532
+ const trajectory = await rollout.rollout(initial, Array.from({ length: horizon }, () => candidate), {})
179
533
  const last = trajectory.steps.at(-1)?.observations ?? {}
180
- const cost = ((last.weight ?? 0) - 32.5) ** 2 + (last.flash_rate ?? 0) ** 2 + (last.sink_rate ?? 0) ** 2
181
- return { candidate, cost, constraintsPassed: constraints.every(c => c.passed), constraints }
182
- }).filter(x => x.constraintsPassed).sort((a, b) => a.cost - b.cost)
183
- const best = results[0]
184
- const report = { modelId: modelId || null, mode, modelReady, candidatesEvaluated: selected.length, bestCandidate: best?.candidate ?? null, bestCost: best?.cost ?? null, recommendationOnly: true, preciseSearchAllowed: modelReady && results.length > 0 }
534
+ const cost = Object.entries(objectiveProfile.targets).reduce((sum, [key, target]) => sum + (objectiveProfile.weights[key] ?? 1) * ((last[key] ?? 0) - target) ** 2, 0)
535
+ const constraints = rollout.evaluateConstraints(scene, trajectory)
536
+ results.push({ candidate, cost, constraintsPassed: constraints.every((c: { passed: boolean }) => c.passed), constraints })
537
+ }
538
+ const passed = results.filter(x => x.constraintsPassed).sort((a, b) => a.cost - b.cost)
539
+ const best = passed[0]
540
+ let recommendationId: string | null = null
541
+ let trialId: string | null = null
542
+ if (authoritative.hybrid && best && 'trial' in best && best.trial) {
543
+ const trial = best.trial
544
+ trialId = trial.trialId
545
+ const certificate = issueRecommendationCertificate(trial, agentId, providerRef.modelHash, sha256(objectiveProfile))
546
+ const twinRepo = createTwinRepo(getAmlRuntime().db)
547
+ twinRepo.insertTrial(trial, modelId || providerRef.modelId)
548
+ if (certificate) {
549
+ twinRepo.insertRecommendation(certificate, agentId)
550
+ recommendationId = certificate.recommendationId
551
+ }
552
+ }
553
+ const report = { modelId: modelId || null, rolloutModel: providerRef.modelId, rolloutModelBacked: providerRef.modelBacked, mode, modelReady, snapshotId: snapshot?.snapshotId ?? null, candidatesEvaluated: selected.length, bestCandidate: best?.candidate ?? null, bestCost: best?.cost ?? null, trialId, recommendationId, recommendationOnly: true, preciseSearchAllowed: modelReady && passed.length > 0 }
185
554
  const path = await persistTwinArtifact('mpc', `run-${Date.now().toString(36)}`, report)
186
- return ok(`MPC recommendation-only 试验完成\n${JSON.stringify(report, null, 2)}\nartifact: ${path}\n${modelReady ? '模型门禁已通过,可进行更精确的候选搜索,但仍不能直接写 DCW。' : '模型门禁未通过,仅执行 safe_small_step 小步试探;先收集 DAQ 数据,不执行精确搜索。'}`)
555
+ providerRef.release()
556
+ return ok(`MPC recommendation-only 试验完成
557
+ ${JSON.stringify(report, null, 2)}
558
+ artifact: ${path}
559
+ ${modelReady ? '模型门禁已通过,可进行更精确的候选搜索,但仍不能直接写 DCW。' : '模型门禁未通过,仅执行 safe_small_step 小步试探;先收集 DAQ 数据,不执行精确搜索。'}`)
187
560
  }
188
561
  catch (err) {
189
562
  return fail(`MPC 优化失败:${err instanceof Error ? err.message : String(err)}`)
190
563
  }
191
564
  }
192
565
 
193
- export async function toolTwinGateEvaluate(_agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
566
+ /**
567
+ * 工具:twin_bayes_optimize —— AML 模式贝叶斯寻优(绑定模型 surrogate + UCB 采集)。
568
+ * 仅工艺优化 Channel 的 aml 模式(dispatch 门控);与 mpc_optimize 的区别:
569
+ * 多轮收敛搜索(每轮围绕当前最优邻域生成候选,UCB=μ-κ·σ 权衡利用与探索),
570
+ * 产出收敛轨迹(供界面渲染)与最终受治理推荐(证书/recommendationOnly)。
571
+ */
572
+ export async function toolTwinBayesOptimize(agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
194
573
  try {
195
- const result = evaluateHybridGates({
196
- rows: Number(args.rows ?? 0), runs: Number(args.runs ?? 0), oneStepTestNrmse: Number(args.one_step_nrmse ?? 1), rolloutTestNrmse: Number(args.rollout_nrmse ?? 1), valTestGap: Number(args.val_test_gap ?? 1), calibrationRows: Number(args.calibration_rows ?? 0), calibrationCoverage: Number(args.coverage ?? 0), candidateTrials: jsonArg(args, 'candidate_trials', []) as never, physicsSolverFailureRate: Number(args.physics_failure_rate ?? 1),
197
- }, DEFAULT_ACCEPTANCE_PROFILE)
574
+ const requestedScene = (jsonArg(args, 'scene_json') ?? defaultInjectionScene('twin-bayes-tool')) as ReturnType<typeof defaultInjectionScene>
575
+ const authoritative = authoritativeSceneForAgent(agentId, args, requestedScene)
576
+ const scene = authoritative.scene
577
+ const baseline = jsonArg<Record<string, number>>(args, 'baseline_controls', {}) ?? {}
198
578
  const modelId = String(args.model_id ?? '').trim()
199
- let modelUpdate = ''
200
- if (modelId) {
201
- const rt = getAmlRuntime()
202
- const model = rt.repo.model.get(modelId)
203
- if (model) {
204
- let metrics: Record<string, unknown> = {}
205
- try {
206
- metrics = JSON.parse(model.metricsJson || '{}') as Record<string, unknown>
579
+ let snapshot: TwinSnapshot | undefined
580
+ let objective = jsonArg<ObjectiveProfile>(args, 'objective')
581
+ if (authoritative.hybrid) {
582
+ const channelId = authoritative.channelId!
583
+ const snapshotId = String(args.snapshot_id ?? '').trim()
584
+ if (!snapshotId) return fail('Hybrid Twin 贝叶斯寻优必须提供已持久化 snapshot_id。')
585
+ snapshot = createTwinRepo(getAmlRuntime().db).getSnapshot(snapshotId) ?? undefined
586
+ if (!snapshot) return fail(`TwinSnapshot 不存在:${snapshotId}`)
587
+ const bindingSnapshot = createNodeBindingSnapshot({ channelId, createdBy: agentId, agentId, scene, lineId: scene.lineId, productId: scene.productId, recipeId: scene.recipeId, requireFrozenScene: true })
588
+ assertTwinSnapshot(snapshot, { scene, frozenScene: scene, bindingSnapshot, channelId, expectedBindingSnapshotHash: bindingSnapshot.snapshotHash, requireFresh: true, requireBindingSnapshot: true, requireFrozenScene: true })
589
+ objective ??= getChannelTwinProfile(channelId).objective as unknown as ObjectiveProfile
590
+ }
591
+ const targets = objective?.targets ?? Object.fromEntries(scene.observations.filter(v => v.role === 'target').map(v => [v.id, 0]))
592
+ const weights = objective?.weights ?? Object.fromEntries(Object.keys(targets).map(key => [key, 1]))
593
+ const objectiveProfile: ObjectiveProfile = objective ?? {
594
+ schemaVersion: 1, createdAt: new Date().toISOString(), createdBy: agentId, objectiveId: 'scene-default', targets, weights, controlCosts: {}, horizonSteps: Number(args.horizon_steps) || 4, trustRegion: {},
595
+ }
596
+ const profile = authoritative.channelId ? getChannelTwinProfile(authoritative.channelId) : null
597
+ const boundModelId = profile?.boundModelId ?? ''
598
+ const effectiveRequested = modelId || boundModelId || undefined
599
+ const providerRef = await rolloutProviderFor(agentId, scene, (snapshot ?? { stateEstimate: {}, controlValues: baseline, disturbances: {}, snapshotId: '', snapshotHash: '', dataQuality: { fresh: true } }) as TwinSnapshot, effectiveRequested)
600
+ if (!providerRef.modelBacked) {
601
+ return fail('贝叶斯寻优要求模型驱动 rollout:请先在 Channel 设置绑定通过门禁的 AML 模型(当前回退到物理 provider)。')
602
+ }
603
+ const scale = Math.max(1e-6, ...Object.values(objectiveProfile.targets).map(v => Math.abs(Number(v)) * 0.05))
604
+ const kappa = Number(args.kappa) || 1.96
605
+ const rounds = Math.min(10, Math.max(1, Number(args.rounds) || 4))
606
+ const perRound = Math.min(20, Math.max(2, Number(args.candidates_per_round) || 6))
607
+ const horizon = Number(args.horizon_steps) || objectiveProfile.horizonSteps || 4
608
+ const trialUncertainty = providerRef.modelBacked && providerRef.uncertainty ? providerRef.uncertainty : undefined
609
+
610
+ // 候选生成:围绕锚点的单变量 ±1/±2 步 + 双变量随机组合;全局去重防重复评估
611
+ const controls = scene.controls
612
+ const seen = new Set<string>([JSON.stringify(baseline)])
613
+ let seed = rounds * 977 + perRound * 131 + controls.length
614
+ const rnd = () => {
615
+ seed = (seed * 1103515245 + 12345) % 2147483648
616
+ return seed / 2147483648
617
+ }
618
+ const genCandidates = (anchor: Record<string, number>, count: number): Array<Record<string, number>> => {
619
+ const out: Array<Record<string, number>> = []
620
+ const push = (cand: Record<string, number>) => {
621
+ const key = JSON.stringify(cand)
622
+ if (!seen.has(key)) {
623
+ seen.add(key)
624
+ out.push(cand)
207
625
  }
208
- catch {
209
- metrics = {}
626
+ }
627
+ for (const c of controls) {
628
+ const cur = anchor[c.id] ?? 0
629
+ const ms = c.maxStep || Math.abs(((c.max ?? 0) - (c.min ?? 0)) / 20)
630
+ for (const k of [1, 2]) {
631
+ for (const s of [1, -1]) {
632
+ const v = Math.min(c.max ?? Infinity, Math.max(c.min ?? -Infinity, cur + s * ms * k))
633
+ if (Math.abs(v - cur) > 1e-9) push({ ...anchor, [c.id]: v })
634
+ }
635
+ }
636
+ }
637
+ let guard = 0
638
+ while (out.length < count && controls.length >= 2 && guard++ < count * 4) {
639
+ const cand = { ...anchor }
640
+ for (let n = 0; n < 2; n++) {
641
+ const c = controls[Math.floor(rnd() * controls.length) % controls.length]!
642
+ const cur = cand[c.id] ?? 0
643
+ const ms = c.maxStep || Math.abs(((c.max ?? 0) - (c.min ?? 0)) / 20)
644
+ cand[c.id] = Math.min(c.max ?? Infinity, Math.max(c.min ?? -Infinity, cur + (rnd() < 0.5 ? 1 : -1) * ms * (1 + rnd())))
210
645
  }
211
- const twinEligibility = {
212
- gatePassed: result.passed,
213
- recommendationEligible: result.passed,
214
- uqPassed: result.checks.filter(c => c.id === 'G7_UQ_OOD').every(c => c.passed),
215
- oodPassed: result.checks.filter(c => c.id === 'G7_UQ_OOD').every(c => c.passed),
216
- physicsPassed: result.checks.filter(c => c.id === 'G5_PHYSICS').every(c => c.passed),
217
- evaluatedAt: new Date().toISOString(),
646
+ push(cand)
647
+ }
648
+ return out.slice(0, count)
649
+ }
650
+
651
+ const convergence: Array<{ round: number, evaluated: number, bestCost: number | null, ucbScore: number | null, bestCandidate: Record<string, number> | null }> = []
652
+ let anchor: Record<string, number> = baseline
653
+ let globalBest: { candidate: Record<string, number>, cost: number, trial?: unknown } | null = null
654
+ for (let r = 1; r <= rounds; r++) {
655
+ const cands = genCandidates(anchor, perRound)
656
+ const results: Array<{ candidate: Record<string, number>, cost: number, score: number, constraintsPassed: boolean, trial?: unknown }> = []
657
+ for (const candidate of cands) {
658
+ if (authoritative.hybrid && snapshot) {
659
+ const trial = await runVirtualTrial({ scene, snapshot, modelId: effectiveRequested || providerRef.modelId, modelHash: providerRef.modelHash, objective: objectiveProfile, baselineControls: baseline, candidateControls: Array.from({ length: horizon }, () => candidate), provider: providerRef.rollout, uncertainty: trialUncertainty as never, createdBy: agentId })
660
+ const cost = trial.baselineComparison.candidateCost
661
+ const sigmaN = Number(trial.uncertainty?.maxStd ?? 0) / scale
662
+ results.push({ candidate, cost, score: cost - kappa * sigmaN, constraintsPassed: trial.constraintResults.every(c => c.passed), trial })
663
+ continue
218
664
  }
219
- metrics.twinEligibility = twinEligibility
220
- rt.db.prepare('UPDATE aml_models SET metrics_json = ? WHERE id = ?').run(JSON.stringify(metrics), modelId)
221
- modelUpdate = `\nmodel_id: ${modelId}\nmodel_twin_eligibility: ${JSON.stringify(twinEligibility)}`
665
+ const initial = providerRef.rollout.initialize({ stateEstimate: {}, controlValues: baseline })
666
+ const trajectory = await providerRef.rollout.rollout(initial, Array.from({ length: horizon }, () => candidate), {})
667
+ const last = trajectory.steps.at(-1)?.observations ?? {}
668
+ const cost = Object.entries(objectiveProfile.targets).reduce((sum, [key, target]) => sum + (objectiveProfile.weights[key] ?? 1) * ((last[key] ?? 0) - target) ** 2, 0)
669
+ const constraints = providerRef.rollout.evaluateConstraints(scene, trajectory)
670
+ results.push({ candidate, cost, score: cost, constraintsPassed: constraints.every((c: { passed: boolean }) => c.passed) })
671
+ }
672
+ const passed = results.filter(x => x.constraintsPassed).sort((a, b) => a.score - b.score)
673
+ const roundBest = passed[0]
674
+ convergence.push({ round: r, evaluated: cands.length, bestCost: roundBest?.cost ?? null, ucbScore: roundBest?.score ?? null, bestCandidate: roundBest?.candidate ?? null })
675
+ if (roundBest && roundBest.cost < (globalBest?.cost ?? Infinity)) {
676
+ globalBest = { candidate: roundBest.candidate, cost: roundBest.cost, trial: roundBest.trial }
677
+ anchor = roundBest.candidate
678
+ }
679
+ }
680
+ let recommendationId: string | null = null
681
+ let trialId: string | null = null
682
+ if (authoritative.hybrid && globalBest?.trial) {
683
+ const trial = globalBest.trial as Awaited<ReturnType<typeof runVirtualTrial>>
684
+ trialId = trial.trialId
685
+ const certificate = issueRecommendationCertificate(trial, agentId, providerRef.modelHash, sha256(objectiveProfile))
686
+ const twinRepo = createTwinRepo(getAmlRuntime().db)
687
+ twinRepo.insertTrial(trial, effectiveRequested || providerRef.modelId)
688
+ if (certificate) {
689
+ twinRepo.insertRecommendation(certificate, agentId)
690
+ recommendationId = certificate.recommendationId
691
+ }
692
+ }
693
+ const report = {
694
+ algorithm: 'surrogate_ucb', kappa, scale: Number(scale.toFixed(6)), rounds, perRound,
695
+ boundModelId: boundModelId || null, modelId: effectiveRequested || null, rolloutModel: providerRef.modelId, rolloutModelBacked: providerRef.modelBacked,
696
+ snapshotId: snapshot?.snapshotId ?? null, candidatesEvaluated: seen.size - 1,
697
+ convergence, bestCandidate: globalBest?.candidate ?? null, bestCost: globalBest?.cost ?? null,
698
+ trialId, recommendationId, recommendationOnly: true,
699
+ }
700
+ const path = await persistTwinArtifact('bayes', `run-${Date.now().toString(36)}`, report)
701
+ providerRef.release()
702
+ return ok(`贝叶斯寻优完成(surrogate+UCB,${rounds} 轮×≤${perRound} 候选)
703
+ ${JSON.stringify(report, null, 2)}
704
+ artifact: ${path}
705
+ 推荐仍为 recommendation-only:写入 DCW 须经治理审批。`)
706
+ }
707
+ catch (err) {
708
+ return fail(`贝叶斯寻优失败:${err instanceof Error ? err.message : String(err)}`)
709
+ }
710
+ }
711
+
712
+ export async function toolTwinGateEvaluate(_agentId: string, args: Record<string, unknown>): Promise<HostToolResult> {
713
+ try {
714
+ const modelId = String(args.model_id ?? '').trim()
715
+ if (!modelId) return fail('twin_gate_evaluate 必须提供 model_id;门禁指标只能来自平台作业/工件,不能由 Agent 自报。')
716
+ const rt = getAmlRuntime()
717
+ const model = rt.repo.model.get(modelId)
718
+ if (!model) return fail(`模型不存在:${modelId}`)
719
+ const metrics = JSON.parse(model.metricsJson || '{}') as Record<string, unknown>
720
+ // 兼容两种存储形状:concludeJob 展平后平台指标在顶层,旧行嵌套于 platform.*
721
+ const platform = (metrics.platform ?? metrics) as Record<string, unknown> | undefined
722
+ const oneStepTest = platform?.oneStepTest as Record<string, unknown> | undefined
723
+ const oneStepVal = platform?.oneStepVal as Record<string, unknown> | undefined
724
+ const rolloutTest = platform?.rolloutTest as Record<string, unknown> | undefined
725
+ if (!oneStepTest) return fail('平台权威 metrics.platform.oneStepTest 缺失:模型尚未完成 aml_eval.py,拒绝计算 Twin Gate。')
726
+ const dataset = rt.repo.dataset.get(model.datasetId)
727
+ if (!dataset) return fail('模型数据集不存在,拒绝计算 Twin Gate。')
728
+ const oneStepTestNrmse = Number(oneStepTest.nrmse)
729
+ const oneStepValNrmse = Number(oneStepVal?.nrmse)
730
+ const valTestGap = Number.isFinite(oneStepValNrmse) && Math.abs(oneStepValNrmse) > 1e-9 ? Math.abs(oneStepTestNrmse - oneStepValNrmse) / Math.abs(oneStepValNrmse) : 1
731
+ const rolloutTestNrmse = Number(rolloutTest?.nrmse ?? 1)
732
+ const hybrid = metrics.hybrid as Record<string, unknown> | undefined
733
+ const uncertainty = metrics.uncertainty as Record<string, unknown> | undefined
734
+ const physics = metrics.physics as Record<string, unknown> | undefined
735
+ const trialRows = rt.db.prepare('SELECT result_json AS resultJson FROM twin_trials WHERE twin_model_id = ? ORDER BY created_at DESC LIMIT 200').all(modelId) as Array<{ resultJson?: string }>
736
+ const candidateTrials = trialRows.map((row) => {
737
+ try {
738
+ return JSON.parse(String(row.resultJson ?? '{}'))
739
+ }
740
+ catch {
741
+ return null
742
+ }
743
+ }).filter(Boolean) as never[]
744
+ const result = evaluateHybridGates({
745
+ rows: dataset.rowCount,
746
+ runs: dataset.runIds.length,
747
+ oneStepTestNrmse,
748
+ rolloutTestNrmse,
749
+ valTestGap,
750
+ calibrationRows: Number(hybrid?.calibrationRows ?? uncertainty?.calibrationRows ?? 0),
751
+ calibrationCoverage: Number(hybrid?.calibrationCoverage ?? uncertainty?.coverage ?? 0),
752
+ candidateTrials,
753
+ physicsSolverFailureRate: Number(hybrid?.physicsFailureRate ?? physics?.solverFailureRate ?? 1),
754
+ }, resolveAcceptanceProfile(String(args.scene_id ?? '') || undefined))
755
+ const twinEligibility = {
756
+ gatePassed: result.passed,
757
+ recommendationEligible: result.passed,
758
+ uqPassed: result.checks.some(c => c.id === 'G7_UQ_OOD') && result.checks.find(c => c.id === 'G7_UQ_OOD')?.passed === true,
759
+ oodPassed: result.checks.find(c => c.id === 'G7_UQ_OOD')?.passed === true,
760
+ physicsPassed: result.checks.find(c => c.id === 'G5_PHYSICS' || c.id === 'G5_PHYSICS_FAILURE')?.passed === true,
761
+ evaluatedAt: new Date().toISOString(),
762
+ source: 'platform_artifacts',
763
+ datasetHash: dataset.sha256,
764
+ modelId,
765
+ }
766
+ metrics.twinEligibility = twinEligibility
767
+ // 影子证据(shadow→production 晋升的验收输入):场景级 Twin Gate 全过时,把平台权威
768
+ // 证据(候选试验数/UQ 覆盖/门禁明细)落为 shadowEvidence —— 此前该字段只有验收读取
769
+ // 没有任何写入者,production 晋升永远不可达;来源与时间戳可审计,不由 Agent 自报。
770
+ if (result.passed) {
771
+ const trialCount = result.checks.find(c => c.id === 'G6_CANDIDATE_COUNT')?.value
772
+ const coverage = result.checks.find(c => c.id === 'G4_COVERAGE')?.value
773
+ metrics.shadowEvidence = {
774
+ passed: true,
775
+ source: 'twin_gate_all_passed',
776
+ basis: `场景级 Twin Gate G0-G7 全过(候选试验 ${String(trialCount ?? '?')} 条无硬违规,UQ coverage ${String(coverage ?? '?')})`,
777
+ sceneId: String(args.scene_id ?? '') || undefined,
778
+ evaluatedAt: twinEligibility.evaluatedAt,
222
779
  }
223
- else modelUpdate = `\nmodel_id: ${modelId}\nmodel_twin_eligibility: MODEL_NOT_FOUND`
224
780
  }
225
- return ok(JSON.stringify({ ...result, modelUpdate }, null, 2))
781
+ rt.db.prepare('UPDATE aml_models SET metrics_json = ? WHERE id = ?').run(JSON.stringify(metrics), modelId)
782
+ return ok(JSON.stringify({ ...result, source: 'platform_artifacts', modelId, datasetId: model.datasetId, twinEligibility }, null, 2))
226
783
  }
227
784
  catch (err) {
228
785
  return fail(`Twin Gate 评估失败:${err instanceof Error ? err.message : String(err)}`)