agentworkshop 0.7.59 → 0.7.60

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 (544) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +108 -0
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +108 -0
  3. package/.output/.AgentWorkShop/schema.json +1 -0
  4. package/.output/nitro.json +1 -1
  5. package/.output/public/_nuxt/{CZwDnomB.js → 59a6cSgj.js} +1 -1
  6. package/.output/public/_nuxt/5juo_WO2.js +13 -0
  7. package/.output/public/_nuxt/9j2J4k4w.js +1 -0
  8. package/.output/public/_nuxt/B-WTxXEK2.js +1 -0
  9. package/.output/public/_nuxt/{DTx_DtUo.js → B0w8DZ4C.js} +1 -1
  10. package/.output/public/_nuxt/B1BCga5h2.js +13 -0
  11. package/.output/public/_nuxt/B5lMtA7I2.js +1 -0
  12. package/.output/public/_nuxt/B6_fJd2X.js +1 -0
  13. package/.output/public/_nuxt/B7K5B04W2.js +1 -0
  14. package/.output/public/_nuxt/B7KyS_q2.js +1 -0
  15. package/.output/public/_nuxt/B8q3BGY5.js +37 -0
  16. package/.output/public/_nuxt/B9IK8kDl2.js +1 -0
  17. package/.output/public/_nuxt/BFBysc2M2.js +1 -0
  18. package/.output/public/_nuxt/{BMUEVeOK.js → BGFhOMVM.js} +2 -2
  19. package/.output/public/_nuxt/{cBI0JqsV.js → BMlesJth.js} +1 -1
  20. package/.output/public/_nuxt/BNd2NDxg2.js +1 -0
  21. package/.output/public/_nuxt/BP629NAi.js +1 -0
  22. package/.output/public/_nuxt/BVinTfuN.js +1 -0
  23. package/.output/public/_nuxt/{DJZzthKt2.js → B_BYwIf22.js} +1 -1
  24. package/.output/public/_nuxt/{CW1HGp5X.js → B_JLVF30.js} +1 -1
  25. package/.output/public/_nuxt/BdE41Y_c.js +28 -0
  26. package/.output/public/_nuxt/Bdq2LNSO.js +1 -0
  27. package/.output/public/_nuxt/{BMZ1d25O.js → BeNdseTX.js} +1 -1
  28. package/.output/public/_nuxt/Be_StT8b2.js +1 -0
  29. package/.output/public/_nuxt/BhllzW3K2.js +1 -0
  30. package/.output/public/_nuxt/BjUpWKS6.js +1 -0
  31. package/.output/public/_nuxt/{CCCq9H7D2.js → BlEJRYAn2.js} +1 -1
  32. package/.output/public/_nuxt/{Du0zf-d3.js → BplhglEM.js} +1 -1
  33. package/.output/public/_nuxt/BsYEYxWv.js +24 -0
  34. package/.output/public/_nuxt/BtXwFpv42.js +1 -0
  35. package/.output/public/_nuxt/{BrFF_9742.js → BuNXYpib2.js} +1 -1
  36. package/.output/public/_nuxt/{BzKT-ne_2.js → C0sNwDTK2.js} +1 -1
  37. package/.output/public/_nuxt/{h46i74oE.js → C4AICl3l.js} +4 -4
  38. package/.output/public/_nuxt/{BuVH9MB-.js → C5OSTzBh.js} +1 -1
  39. package/.output/public/_nuxt/{DKhRushG.js → C8XVZGSZ.js} +1 -1
  40. package/.output/public/_nuxt/{zGDAozGA.js → C93LpBMF.js} +4 -4
  41. package/.output/public/_nuxt/CDaZC0_6.js +3 -0
  42. package/.output/public/_nuxt/CE43-V_L.js +2 -0
  43. package/.output/public/_nuxt/{B4R5CHkk.js → CEHT9inW.js} +1 -1
  44. package/.output/public/_nuxt/CGChCy-w2.js +1 -0
  45. package/.output/public/_nuxt/{DvUt9uMt2.js → CMDAjShv2.js} +1 -1
  46. package/.output/public/_nuxt/CUjdqsjC2.js +1 -0
  47. package/.output/public/_nuxt/CWfBtswB.js +70 -0
  48. package/.output/public/_nuxt/CYtH1bv2.js +1 -0
  49. package/.output/public/_nuxt/CZmMgjIK.js +1 -0
  50. package/.output/public/_nuxt/{iZa330UY.js → Cdw4juXw.js} +1 -1
  51. package/.output/public/_nuxt/{DMPpE41S2.js → Ce5SiMQR2.js} +1 -1
  52. package/.output/public/_nuxt/{B03LfmKR.js → Cfp00Rdo.js} +1 -1
  53. package/.output/public/_nuxt/{Dy-V8OEW2.js → CgbP5yJk2.js} +7 -7
  54. package/.output/public/_nuxt/ChPNKPw_.js +1 -0
  55. package/.output/public/_nuxt/{C5wBzGO7.js → CjeMxUv8.js} +1 -1
  56. package/.output/public/_nuxt/CktUrk8z.js +1 -0
  57. package/.output/public/_nuxt/Cst8yEet.js +1 -0
  58. package/.output/public/_nuxt/Cuw2--X2.js +2 -0
  59. package/.output/public/_nuxt/Cyd68Xbv2.js +1 -0
  60. package/.output/public/_nuxt/{pNy4V4kd.js → Cyuxcv5s2.js} +1 -1
  61. package/.output/public/_nuxt/{CIz7SM4H.js → D0vmf1z9.js} +1 -1
  62. package/.output/public/_nuxt/D5-QB_-l.js +1 -0
  63. package/.output/public/_nuxt/D9sgxxsM2.js +1 -0
  64. package/.output/public/_nuxt/DBdwjOGB2.js +1 -0
  65. package/.output/public/_nuxt/DBzdrPzw2.js +1 -0
  66. package/.output/public/_nuxt/DD4J2Otc.js +1 -0
  67. package/.output/public/_nuxt/DMCoWgSb2.js +1 -0
  68. package/.output/public/_nuxt/{CmTqFlYZ.js → DTcsb0fG.js} +1 -1
  69. package/.output/public/_nuxt/Ddc_Pn7D.js +19 -0
  70. package/.output/public/_nuxt/Dg1iMuZ-.js +1 -0
  71. package/.output/public/_nuxt/DhSlJyZD2.js +1 -0
  72. package/.output/public/_nuxt/DmwMkvoQ2.js +1 -0
  73. package/.output/public/_nuxt/EQijmkCh2.js +1 -0
  74. package/.output/public/_nuxt/KXQppTXc.js +1 -0
  75. package/.output/public/_nuxt/{CZ0Gt81h.js → KXvRkBgg.js} +2 -2
  76. package/.output/public/_nuxt/LwITbamf2.js +47 -0
  77. package/.output/public/_nuxt/N9TYd_Mk2.js +1 -0
  78. package/.output/public/_nuxt/VeOVO2sE2.js +1 -0
  79. package/.output/public/_nuxt/_jfzcYrl.js +1 -0
  80. package/.output/public/_nuxt/analysis.D2Pao1rm.css +1 -0
  81. package/.output/public/_nuxt/builds/latest.json +1 -1
  82. package/.output/public/_nuxt/builds/meta/f78a1992-e424-494d-ac4b-aa18971ffc10.json +1 -0
  83. package/.output/public/_nuxt/{default.8ac6QU28.css → default.Bx6RJSbr.css} +1 -1
  84. package/.output/public/_nuxt/{entry.BHNNQA9H.css → entry.BlbU43qz.css} +1 -1
  85. package/.output/public/_nuxt/{MEwEMEMl2.js → iCvdSYYN2.js} +6 -6
  86. package/.output/public/_nuxt/{CYGkUj5M2.js → p2sDc0tO2.js} +1 -1
  87. package/.output/public/_nuxt/{Drhta6gr.js → zVupTo2z2.js} +2 -2
  88. package/.output/server/chunks/_/LeftOutlined.mjs +1 -1
  89. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  90. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  91. package/.output/server/chunks/_/nitro.mjs +1651 -1268
  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/{AuthGate-DDPYswkA.mjs → AuthGate-CZYkvPrg.mjs} +5 -5
  95. package/.output/server/chunks/build/{AuthGate-DDPYswkA.mjs.map → AuthGate-CZYkvPrg.mjs.map} +1 -1
  96. package/.output/server/chunks/build/Checkbox-4EdGAAl_.mjs +1 -1
  97. package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs → FormItemContext-DcWIIAaK.mjs} +2 -2
  98. package/.output/server/chunks/build/{FormItemContext-4ORSzhWv.mjs.map → FormItemContext-DcWIIAaK.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs → OmpTerminalPanel-CtFJ6Kc8.mjs} +4 -4
  100. package/.output/server/chunks/build/{OmpTerminalPanel-DZ2wHMS1.mjs.map → OmpTerminalPanel-CtFJ6Kc8.mjs.map} +1 -1
  101. package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs → PluginSlot-BT7kYQgK.mjs} +2 -2
  102. package/.output/server/chunks/build/{PluginSlot-CT4YaNrB.mjs.map → PluginSlot-BT7kYQgK.mjs.map} +1 -1
  103. package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs → TownView-kQZFf4zj.mjs} +3 -3
  104. package/.output/server/chunks/build/{TownView-CZbFn6mO.mjs.map → TownView-kQZFf4zj.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs → _id_-Bbx1b74O.mjs} +3 -3
  106. package/.output/server/chunks/build/{_id_-Df2pgsAq.mjs.map → _id_-Bbx1b74O.mjs.map} +1 -1
  107. package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs → _id_-IijrRw3f.mjs} +3 -3
  108. package/.output/server/chunks/build/{_id_-CCVhpJtj.mjs.map → _id_-IijrRw3f.mjs.map} +1 -1
  109. package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs → _wsId_-DOEw9jgZ.mjs} +22 -21
  110. package/.output/server/chunks/build/{_wsId_-CJqF-hmP.mjs.map → _wsId_-DOEw9jgZ.mjs.map} +1 -1
  111. package/.output/server/chunks/build/{agents-BTsbna5H.mjs → agents-C36wR56A.mjs} +18 -17
  112. package/.output/server/chunks/build/agents-C36wR56A.mjs.map +1 -0
  113. package/.output/server/chunks/build/{aml-BBKfWto1.mjs → aml-CBGndvHT.mjs} +7 -7
  114. package/.output/server/chunks/build/{aml-BBKfWto1.mjs.map → aml-CBGndvHT.mjs.map} +1 -1
  115. package/.output/server/chunks/build/analysis-tgzvOWmD.mjs +332 -0
  116. package/.output/server/chunks/build/analysis-tgzvOWmD.mjs.map +1 -0
  117. package/.output/server/chunks/build/{card-DJOYGuVH.mjs → card-Db7OB49d.mjs} +4 -4
  118. package/.output/server/chunks/build/{card-DJOYGuVH.mjs.map → card-Db7OB49d.mjs.map} +1 -1
  119. package/.output/server/chunks/build/{channel-templates-BPKJ8e4l.mjs → channel-templates-BixUrDmU.mjs} +11 -10
  120. package/.output/server/chunks/build/channel-templates-BixUrDmU.mjs.map +1 -0
  121. package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs → checkbox-CyF96D30.mjs} +3 -3
  122. package/.output/server/chunks/build/{checkbox-C4AKj81e.mjs.map → checkbox-CyF96D30.mjs.map} +1 -1
  123. package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs → daq-DLMLufDq.mjs} +5 -5
  124. package/.output/server/chunks/build/{daq-Cz7TaUAM.mjs.map → daq-DLMLufDq.mjs.map} +1 -1
  125. package/.output/server/chunks/build/dcw-EhjJpVQM.mjs +2 -2
  126. package/.output/server/chunks/build/{default-DweMY872.mjs → default-C7Qmdyz_.mjs} +30 -19
  127. package/.output/server/chunks/build/{default-DweMY872.mjs.map → default-C7Qmdyz_.mjs.map} +1 -1
  128. package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs → descriptions-1bH81YsZ.mjs} +2 -2
  129. package/.output/server/chunks/build/{descriptions-CFaUq4y4.mjs.map → descriptions-1bH81YsZ.mjs.map} +1 -1
  130. package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs → drawer-C7shdEHy.mjs} +2 -2
  131. package/.output/server/chunks/build/{drawer-Cfh9_zft.mjs.map → drawer-C7shdEHy.mjs.map} +1 -1
  132. package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs → dropdown-BhLSIp5A.mjs} +2 -2
  133. package/.output/server/chunks/build/{dropdown-CIsqbX4P.mjs.map → dropdown-BhLSIp5A.mjs.map} +1 -1
  134. package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs → dropdown-BiwcuXDi.mjs} +6 -5
  135. package/.output/server/chunks/build/{dropdown-CV9GW3z9.mjs.map → dropdown-BiwcuXDi.mjs.map} +1 -1
  136. package/.output/server/chunks/build/{form-cs_RcfGx.mjs → form-nE8C0G8B.mjs} +7 -6
  137. package/.output/server/chunks/build/{form-cs_RcfGx.mjs.map → form-nE8C0G8B.mjs.map} +1 -1
  138. package/.output/server/chunks/build/{input-CobQ5LJ5.mjs → input-DwF72eVI.mjs} +93 -3449
  139. package/.output/server/chunks/build/input-DwF72eVI.mjs.map +1 -0
  140. package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs → input-number-TSq6ltkz.mjs} +6 -5
  141. package/.output/server/chunks/build/{input-number-BpPYAWMk.mjs.map → input-number-TSq6ltkz.mjs.map} +1 -1
  142. package/.output/server/chunks/build/{logs-As9fZqU-.mjs → logs-hOEVuxqm.mjs} +3 -3
  143. package/.output/server/chunks/build/{logs-As9fZqU-.mjs.map → logs-hOEVuxqm.mjs.map} +1 -1
  144. package/.output/server/chunks/build/{menu-CVmvHyFT.mjs → menu-Cy5Nrecn.mjs} +4 -3
  145. package/.output/server/chunks/build/{menu-CVmvHyFT.mjs.map → menu-Cy5Nrecn.mjs.map} +1 -1
  146. package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs → monitor-CfVoiavp.mjs} +20 -19
  147. package/.output/server/chunks/build/{monitor-CdFQ2z4g.mjs.map → monitor-CfVoiavp.mjs.map} +1 -1
  148. package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs → operations-fxI8lEBJ.mjs} +3 -3
  149. package/.output/server/chunks/build/{operations-B2gHCWgZ.mjs.map → operations-fxI8lEBJ.mjs.map} +1 -1
  150. package/.output/server/chunks/build/{pages-BItCt1ar.mjs → pages-6JD9VSbx.mjs} +5 -5
  151. package/.output/server/chunks/build/{pages-BItCt1ar.mjs.map → pages-6JD9VSbx.mjs.map} +1 -1
  152. package/.output/server/chunks/build/{permissions-D6mQw_9j.mjs → permissions-XPtQJSaO.mjs} +14 -13
  153. package/.output/server/chunks/build/permissions-XPtQJSaO.mjs.map +1 -0
  154. package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs → plugins-DjBSG9pV.mjs} +5 -5
  155. package/.output/server/chunks/build/{plugins-NAS9MQ5r.mjs.map → plugins-DjBSG9pV.mjs.map} +1 -1
  156. package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs → popconfirm-DKeEbaGd.mjs} +3 -3
  157. package/.output/server/chunks/build/{popconfirm-DFfoFhmt.mjs.map → popconfirm-DKeEbaGd.mjs.map} +1 -1
  158. package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs → schedules-PcDLCUWN.mjs} +20 -19
  159. package/.output/server/chunks/build/{schedules-BjWNDWL5.mjs.map → schedules-PcDLCUWN.mjs.map} +1 -1
  160. package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs → segmented-BdWCdZUM.mjs} +3 -3
  161. package/.output/server/chunks/build/{segmented-D7FkCgg7.mjs.map → segmented-BdWCdZUM.mjs.map} +1 -1
  162. package/.output/server/chunks/build/{select-FqBNxgxT.mjs → select-C5yighj8.mjs} +5 -4
  163. package/.output/server/chunks/build/{select-FqBNxgxT.mjs.map → select-C5yighj8.mjs.map} +1 -1
  164. package/.output/server/chunks/build/{settings-Cl_KRyEn.mjs → settings-90zT_h9w.mjs} +14 -13
  165. package/.output/server/chunks/build/settings-90zT_h9w.mjs.map +1 -0
  166. package/.output/server/chunks/build/{space-B2uhHJG8.mjs → space-BCffbXIG.mjs} +3 -3
  167. package/.output/server/chunks/build/{space-B2uhHJG8.mjs.map → space-BCffbXIG.mjs.map} +1 -1
  168. package/.output/server/chunks/build/{switch-DZAUIbIN.mjs → switch-OG0SM_Px.mjs} +3 -3
  169. package/.output/server/chunks/build/{switch-DZAUIbIN.mjs.map → switch-OG0SM_Px.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{table-CeOYERqr.mjs → table-UpVzu50c.mjs} +11 -10
  171. package/.output/server/chunks/build/{table-CeOYERqr.mjs.map → table-UpVzu50c.mjs.map} +1 -1
  172. package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs → tabs-CWwoL33v.mjs} +6 -5
  173. package/.output/server/chunks/build/{tabs-LLNSdLl2.mjs.map → tabs-CWwoL33v.mjs.map} +1 -1
  174. package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs → tag-CS7mwrfG.mjs} +5 -4
  175. package/.output/server/chunks/build/{tag-Dwvkh0Dj.mjs.map → tag-CS7mwrfG.mjs.map} +1 -1
  176. package/.output/server/chunks/build/{teams-CGDZHaQl.mjs → teams-BIAFvRw1.mjs} +19 -18
  177. package/.output/server/chunks/build/teams-BIAFvRw1.mjs.map +1 -0
  178. package/.output/server/chunks/build/{tokens-BOYkZuoB.mjs → tokens-CLpdrzQ7.mjs} +19 -18
  179. package/.output/server/chunks/build/tokens-CLpdrzQ7.mjs.map +1 -0
  180. package/.output/server/chunks/build/tooltip-CJlH_8ZK.mjs +3362 -0
  181. package/.output/server/chunks/build/tooltip-CJlH_8ZK.mjs.map +1 -0
  182. package/.output/server/chunks/build/town-BV-hbwb5.mjs +1 -1
  183. package/.output/server/chunks/build/{town-P1rYoi0v.mjs → town-Bfme7P2I.mjs} +5 -5
  184. package/.output/server/chunks/build/{town-P1rYoi0v.mjs.map → town-Bfme7P2I.mjs.map} +1 -1
  185. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  186. package/.output/server/chunks/build/types-DWqIeMRP.mjs +75 -0
  187. package/.output/server/chunks/build/types-DWqIeMRP.mjs.map +1 -0
  188. package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs → useAgentTemplateActions-6VyAHgu5.mjs} +1 -1
  189. package/.output/server/chunks/build/{useAgentTemplateActions-DsBRUQni.mjs.map → useAgentTemplateActions-6VyAHgu5.mjs.map} +1 -1
  190. package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs → useAgentTemplateForm-DWa-ezNq.mjs} +1 -1
  191. package/.output/server/chunks/build/{useAgentTemplateForm-DzQ_t2Ue.mjs.map → useAgentTemplateForm-DWa-ezNq.mjs.map} +1 -1
  192. package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs → useAmlEntities-Co2fgjzh.mjs} +1 -1
  193. package/.output/server/chunks/build/{useAmlEntities-BMLHU_39.mjs.map → useAmlEntities-Co2fgjzh.mjs.map} +1 -1
  194. package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs → useAmlEnv-JTiWPrzH.mjs} +1 -1
  195. package/.output/server/chunks/build/{useAmlEnv-DdlyVzPu.mjs.map → useAmlEnv-JTiWPrzH.mjs.map} +1 -1
  196. package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs → useAmlJobs-By4pjOzc.mjs} +1 -1
  197. package/.output/server/chunks/build/{useAmlJobs-BG_v21hJ.mjs.map → useAmlJobs-By4pjOzc.mjs.map} +1 -1
  198. package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs → useAmlModels-B1_5vjMA.mjs} +1 -1
  199. package/.output/server/chunks/build/{useAmlModels-D7MuOWOy.mjs.map → useAmlModels-B1_5vjMA.mjs.map} +1 -1
  200. package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs → useAmlNotes-5uwvCb3h.mjs} +1 -1
  201. package/.output/server/chunks/build/{useAmlNotes-CTZe-GI0.mjs.map → useAmlNotes-5uwvCb3h.mjs.map} +1 -1
  202. package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs → useAmlPredict-lxUv7lAO.mjs} +1 -1
  203. package/.output/server/chunks/build/{useAmlPredict-BToRrVRV.mjs.map → useAmlPredict-lxUv7lAO.mjs.map} +1 -1
  204. package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs +128 -0
  205. package/.output/server/chunks/build/useAnalysisFeed-B4OwUd7p.mjs.map +1 -0
  206. package/.output/server/chunks/build/useDaqAddNode-CaOCbe4-.mjs +1 -1
  207. package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs → useDaqDetailNode-DtZ0oDAn.mjs} +3 -3
  208. package/.output/server/chunks/build/{useDaqDetailNode-DXgwAu5u.mjs.map → useDaqDetailNode-DtZ0oDAn.mjs.map} +1 -1
  209. package/.output/server/chunks/build/useDaqDetailParams-CrTMDs-2.mjs +1 -1
  210. package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs → useDaqFilters-DYHGhECw.mjs} +3 -3
  211. package/.output/server/chunks/build/{useDaqFilters-Jx6EERfr.mjs.map → useDaqFilters-DYHGhECw.mjs.map} +1 -1
  212. package/.output/server/chunks/build/useDaqStream-DhzdoyIR.mjs +1 -1
  213. package/.output/server/chunks/build/useDaqTemplates-C7GzQmdJ.mjs +1 -1
  214. package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs → useDashboardData-B3lZjE7x.mjs} +3 -3
  215. package/.output/server/chunks/build/{useDashboardData-Ce-EU5DJ.mjs.map → useDashboardData-B3lZjE7x.mjs.map} +1 -1
  216. package/.output/server/chunks/build/useDcwAddNode-4mTPQ6T8.mjs +1 -1
  217. package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs → useDcwDetailScope-BWH7jnVh.mjs} +2 -2
  218. package/.output/server/chunks/build/{useDcwDetailScope-4j3B03Pi.mjs.map → useDcwDetailScope-BWH7jnVh.mjs.map} +1 -1
  219. package/.output/server/chunks/build/useDcwStream-BXJ2V8HM.mjs +1 -1
  220. package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs → useLogsManual-BLfiSU3u.mjs} +1 -1
  221. package/.output/server/chunks/build/{useLogsManual-CMjD62nt.mjs.map → useLogsManual-BLfiSU3u.mjs.map} +1 -1
  222. package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs → useMonitorData-BZ6Z-Sy8.mjs} +1 -1
  223. package/.output/server/chunks/build/{useMonitorData-D2gFSonG.mjs.map → useMonitorData-BZ6Z-Sy8.mjs.map} +1 -1
  224. package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs → useTeamActions-ahht5J8Y.mjs} +1 -1
  225. package/.output/server/chunks/build/{useTeamActions-BOLQkYxg.mjs.map → useTeamActions-ahht5J8Y.mjs.map} +1 -1
  226. package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs → useTeamAddMemberDialog-DvXxsVy0.mjs} +1 -1
  227. package/.output/server/chunks/build/{useTeamAddMemberDialog-BCgrLPxI.mjs.map → useTeamAddMemberDialog-DvXxsVy0.mjs.map} +1 -1
  228. package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs → useTeamCreateDialog-A_k-XX5B.mjs} +1 -1
  229. package/.output/server/chunks/build/{useTeamCreateDialog-CJk40LqS.mjs.map → useTeamCreateDialog-A_k-XX5B.mjs.map} +1 -1
  230. package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs → useTeamDeployDialog-CfAFjIr_.mjs} +1 -1
  231. package/.output/server/chunks/build/{useTeamDeployDialog-49hdUXQP.mjs.map → useTeamDeployDialog-CfAFjIr_.mjs.map} +1 -1
  232. package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs → useTeamPluginDialog-Djmkk1Nl.mjs} +1 -1
  233. package/.output/server/chunks/build/{useTeamPluginDialog-Dh-QOoiU.mjs.map → useTeamPluginDialog-Djmkk1Nl.mjs.map} +1 -1
  234. package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs → useTokenCreate-CkWoxSI-.mjs} +1 -1
  235. package/.output/server/chunks/build/{useTokenCreate-DkYvEQUD.mjs.map → useTokenCreate-CkWoxSI-.mjs.map} +1 -1
  236. package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs → useTokenRename-BohjnGT0.mjs} +1 -1
  237. package/.output/server/chunks/build/{useTokenRename-DOCP4aeI.mjs.map → useTokenRename-BohjnGT0.mjs.map} +1 -1
  238. package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs → useTokenReveal-BBN5iGz7.mjs} +1 -1
  239. package/.output/server/chunks/build/{useTokenReveal-CybwwflV.mjs.map → useTokenReveal-BBN5iGz7.mjs.map} +1 -1
  240. package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs → useTokensList-BQX9WqfT.mjs} +1 -1
  241. package/.output/server/chunks/build/{useTokensList-BLiMvrc4.mjs.map → useTokensList-BQX9WqfT.mjs.map} +1 -1
  242. package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs → useWorkbenchAuth-BTRlS2wZ.mjs} +1 -1
  243. package/.output/server/chunks/build/{useWorkbenchAuth-DAabQl7X.mjs.map → useWorkbenchAuth-BTRlS2wZ.mjs.map} +1 -1
  244. package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs → useWorkbenchWorkspaces-C6ky7OJH.mjs} +1 -1
  245. package/.output/server/chunks/build/{useWorkbenchWorkspaces-6-mpCGCR.mjs.map → useWorkbenchWorkspaces-C6ky7OJH.mjs.map} +1 -1
  246. package/.output/server/chunks/build/{users-B_pHStEa.mjs → users-BHOEW3Az.mjs} +15 -14
  247. package/.output/server/chunks/build/users-BHOEW3Az.mjs.map +1 -0
  248. package/.output/server/chunks/build/{workshop-C0DefygA.mjs → workshop-DyJ1LXwu.mjs} +11 -10
  249. package/.output/server/chunks/build/workshop-DyJ1LXwu.mjs.map +1 -0
  250. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  251. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  252. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs +46 -0
  253. package/.output/server/chunks/routes/api/workshop/analysis/_id_.delete.mjs.map +1 -0
  254. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs +39 -0
  255. package/.output/server/chunks/routes/api/workshop/analysis/_id_.get.mjs.map +1 -0
  256. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  257. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  258. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  259. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  260. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  261. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  262. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  263. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  264. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  265. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  266. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  267. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  268. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  269. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  270. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +7 -7
  272. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  273. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
  274. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  275. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  276. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  277. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  278. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  279. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  280. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  281. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  282. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  285. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  286. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  287. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  288. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  290. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  291. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  292. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  293. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  294. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  296. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  297. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/dcw/index7.get.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  301. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  302. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  304. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +1 -1
  306. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  307. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  308. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  309. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  310. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  316. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  317. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  321. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  330. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  331. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  332. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +20 -23
  341. package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
  342. package/.output/server/chunks/routes/api/workshop/index11.get.mjs +25 -11
  343. package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
  344. package/.output/server/chunks/routes/api/workshop/index12.get.mjs +10 -4
  345. package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -1
  346. package/.output/server/chunks/routes/api/workshop/index13.get.mjs +2 -3
  347. package/.output/server/chunks/routes/api/workshop/index13.get.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/workshop/index14.get.mjs +3 -2
  349. package/.output/server/chunks/routes/api/workshop/index14.get.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/index15.get.mjs +30 -0
  351. package/.output/server/chunks/routes/api/workshop/index15.get.mjs.map +1 -0
  352. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +20 -9
  353. package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
  354. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  355. package/.output/server/chunks/routes/api/workshop/index4.get.mjs +10 -4
  356. package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
  357. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  358. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +4 -29
  359. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  360. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  361. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +25 -22
  362. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  363. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +26 -5
  364. package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
  365. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +4 -39
  366. package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
  367. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +40 -20
  368. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  369. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  370. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  371. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  372. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  373. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  374. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  375. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  376. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  377. package/.output/server/chunks/routes/renderer.mjs +2 -2
  378. package/.output/server/chunks/virtual/entry.mjs +551 -824
  379. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  380. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  381. package/.output/server/package.json +1 -1
  382. package/README-zh.md +17 -0
  383. package/README.md +20 -0
  384. package/app/components/AppSidebar.vue +1 -0
  385. package/app/components/analysis/AnalysisFilterCard.vue +160 -0
  386. package/app/components/analysis/AnalysisPageHead.vue +47 -0
  387. package/app/components/analysis/AnalysisTable.vue +306 -0
  388. package/app/composables/useRouteMeta.ts +1 -0
  389. package/app/config/schema.ts +1 -0
  390. package/app/pages/analysis/composables/useAnalysisFeed.ts +85 -0
  391. package/app/pages/analysis/index.vue +92 -0
  392. package/app/pages/analysis/types.ts +44 -0
  393. package/cli/commands/mcp.mjs +160 -160
  394. package/i18n/locales/en.ts +55 -0
  395. package/i18n/locales/zh-CN.ts +55 -0
  396. package/mcp/aw-mcp-server.mjs +799 -799
  397. package/package.json +2 -2
  398. package/scripts/onboarding/onboard.mjs +5 -2
  399. package/scripts/onboarding/sim-twin.mjs +312 -0
  400. package/server/api/workshop/analysis/[id].delete.ts +30 -0
  401. package/server/api/workshop/analysis/[id].get.ts +23 -0
  402. package/server/api/workshop/analysis/index.get.ts +33 -0
  403. package/server/plugins/workshop.ts +4 -0
  404. package/server/repositories/user.repository.ts +2 -2
  405. package/server/services/workshop/agents/host-tool-bridge/catalog.ts +4 -1
  406. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +5 -2
  407. package/server/services/workshop/agents/industrial/analysis-tools.ts +242 -0
  408. package/server/services/workshop/agents/industrial/index.ts +1 -0
  409. package/server/services/workshop/agents/industrial/ops-tools.ts +3 -2
  410. package/server/services/workshop/analysis/analysis.repo.ts +189 -0
  411. package/server/services/workshop/db/database/schema.ts +28 -1
  412. package/server/services/workshop/db/ops.repo.ts +1 -1
  413. package/server/services/workshop/db/retention.ts +2 -0
  414. package/server/services/workshop/db/schema.sql +27 -0
  415. package/server/services/workshop/settings.ts +1 -0
  416. package/shared/config/schema.json +1 -0
  417. package/.output/public/_nuxt/B-Y_rsfn.js +0 -106
  418. package/.output/public/_nuxt/B02cxZz72.js +0 -1
  419. package/.output/public/_nuxt/BAqtRt0q.js +0 -1
  420. package/.output/public/_nuxt/BKHd_sKD2.js +0 -47
  421. package/.output/public/_nuxt/BXKCB3rS.js +0 -1
  422. package/.output/public/_nuxt/BhrnGVGz.js +0 -1
  423. package/.output/public/_nuxt/BikIgp9R.js +0 -1
  424. package/.output/public/_nuxt/BkGqyjWm.js +0 -3
  425. package/.output/public/_nuxt/Bn1N3mJv.js +0 -1
  426. package/.output/public/_nuxt/Br2LgfbH2.js +0 -13
  427. package/.output/public/_nuxt/BtNT93vm2.js +0 -1
  428. package/.output/public/_nuxt/BtYg4aGR2.js +0 -1
  429. package/.output/public/_nuxt/C4X_Z1lA.js +0 -1
  430. package/.output/public/_nuxt/CBATzTUf.js +0 -13
  431. package/.output/public/_nuxt/CEP4UrDv.js +0 -1
  432. package/.output/public/_nuxt/CIPKYgrH2.js +0 -1
  433. package/.output/public/_nuxt/CPSHP_EI.js +0 -1
  434. package/.output/public/_nuxt/CSyIwYcJ2.js +0 -1
  435. package/.output/public/_nuxt/CZkTlW93.js +0 -2
  436. package/.output/public/_nuxt/CZyYdpqZ2.js +0 -1
  437. package/.output/public/_nuxt/CeDkXWCz.js +0 -1
  438. package/.output/public/_nuxt/Cl19UD7U.js +0 -1
  439. package/.output/public/_nuxt/ClrkV0C4.js +0 -1
  440. package/.output/public/_nuxt/CoGETbe-2.js +0 -1
  441. package/.output/public/_nuxt/CuRtzvsa2.js +0 -1
  442. package/.output/public/_nuxt/Cv_H1gOM2.js +0 -1
  443. package/.output/public/_nuxt/D5i2ofVw2.js +0 -1
  444. package/.output/public/_nuxt/D6XGn5vM.js +0 -2
  445. package/.output/public/_nuxt/D6c5ppqB.js +0 -1
  446. package/.output/public/_nuxt/D8VQGThE.js +0 -28
  447. package/.output/public/_nuxt/DBwuADr82.js +0 -1
  448. package/.output/public/_nuxt/DTZO6WMs2.js +0 -1
  449. package/.output/public/_nuxt/DfqRQSFn.js +0 -19
  450. package/.output/public/_nuxt/DraEWn4N2.js +0 -1
  451. package/.output/public/_nuxt/DyMgrV29.js +0 -1
  452. package/.output/public/_nuxt/H7Rbu32y2.js +0 -1
  453. package/.output/public/_nuxt/TjGWqrHo.js +0 -1
  454. package/.output/public/_nuxt/VVomhVqu2.js +0 -1
  455. package/.output/public/_nuxt/YDs3mbQu2.js +0 -1
  456. package/.output/public/_nuxt/Z3MSTcdu2.js +0 -1
  457. package/.output/public/_nuxt/_vR_sc7t.js +0 -24
  458. package/.output/public/_nuxt/builds/meta/92fd7e2e-18f2-45c3-8588-d93004dda6e3.json +0 -1
  459. package/.output/public/_nuxt/gbaq2UOO.js +0 -1
  460. package/.output/public/_nuxt/o-G6YtmK2.js +0 -1
  461. package/.output/public/_nuxt/ylowSquM2.js +0 -1
  462. package/.output/server/chunks/build/agents-BTsbna5H.mjs.map +0 -1
  463. package/.output/server/chunks/build/channel-templates-BPKJ8e4l.mjs.map +0 -1
  464. package/.output/server/chunks/build/input-CobQ5LJ5.mjs.map +0 -1
  465. package/.output/server/chunks/build/permissions-D6mQw_9j.mjs.map +0 -1
  466. package/.output/server/chunks/build/settings-Cl_KRyEn.mjs.map +0 -1
  467. package/.output/server/chunks/build/teams-CGDZHaQl.mjs.map +0 -1
  468. package/.output/server/chunks/build/tokens-BOYkZuoB.mjs.map +0 -1
  469. package/.output/server/chunks/build/users-B_pHStEa.mjs.map +0 -1
  470. package/.output/server/chunks/build/workshop-C0DefygA.mjs.map +0 -1
  471. package/scripts/_audit/.tmp/audit-data/dcw-params.json +0 -15
  472. package/scripts/_audit/.tmp/audit-data/dcws.json +0 -30
  473. package/scripts/_audit/aml-layout-diag.mjs +0 -83
  474. package/scripts/_audit/channel-inspect.mjs +0 -49
  475. package/scripts/_audit/cleanup-apply.mjs +0 -89
  476. package/scripts/_audit/cleanup-plan.mjs +0 -82
  477. package/scripts/_audit/contrast-check.mjs +0 -43
  478. package/scripts/_audit/dcw-controller-e2e.ts +0 -106
  479. package/scripts/_audit/dcw-flush-cost.ts +0 -43
  480. package/scripts/_audit/dcw-rollback-ledger.ts +0 -156
  481. package/scripts/_audit/dcw-unrecorded-write.ts +0 -171
  482. package/scripts/_audit/dcw-write-mutex.ts +0 -157
  483. package/scripts/_audit/design-shots.mjs +0 -145
  484. package/scripts/_audit/docs-font-probe.mjs +0 -68
  485. package/scripts/_audit/docs-probe.mjs +0 -107
  486. package/scripts/_audit/docs-shots.mjs +0 -171
  487. package/scripts/_audit/docs-v3-verify.mjs +0 -255
  488. package/scripts/_audit/docs-vue-lint.mjs +0 -81
  489. package/scripts/_audit/docs-vue-lint2.mjs +0 -91
  490. package/scripts/_audit/exp-cost-scaling.mjs +0 -57
  491. package/scripts/_audit/exp-envelope-and-png.mjs +0 -78
  492. package/scripts/_audit/exp-png-decode.mjs +0 -67
  493. package/scripts/_audit/exp-retention-plan.mjs +0 -61
  494. package/scripts/_audit/exp-retention-rescan.mjs +0 -42
  495. package/scripts/_audit/exp-sweep-fairness.mjs +0 -50
  496. package/scripts/_audit/feature-audit-e2e.mjs +0 -342
  497. package/scripts/_audit/fix-settings-count.mjs +0 -57
  498. package/scripts/_audit/full-e2e-adopt.mjs +0 -238
  499. package/scripts/_audit/full-e2e-close-loop.mjs +0 -134
  500. package/scripts/_audit/full-e2e-retrain.mjs +0 -320
  501. package/scripts/_audit/full-e2e-supplement.mjs +0 -192
  502. package/scripts/_audit/full-e2e-ui-final.mjs +0 -111
  503. package/scripts/_audit/full-e2e-ui-mount.mjs +0 -111
  504. package/scripts/_audit/full-feature-e2e-20260927.mjs +0 -627
  505. package/scripts/_audit/glass-verify.mjs +0 -155
  506. package/scripts/_audit/hydration-diff.mjs +0 -104
  507. package/scripts/_audit/hydration-head.mjs +0 -36
  508. package/scripts/_audit/hydration-probe.mjs +0 -59
  509. package/scripts/_audit/idd-scenarios-e2e.mjs +0 -239
  510. package/scripts/_audit/kb-diag-complete.mjs +0 -261
  511. package/scripts/_audit/kb-diag-complete2.mjs +0 -271
  512. package/scripts/_audit/kb-diag-loop-e2e.mjs +0 -357
  513. package/scripts/_audit/kb-diag-loop-mock.mjs +0 -416
  514. package/scripts/_audit/kb-diag-loop-v2.mjs +0 -314
  515. package/scripts/_audit/lead-matrix-test.mjs +0 -172
  516. package/scripts/_audit/plc-agent-task.mjs +0 -74
  517. package/scripts/_audit/plc-clean-scenario.mjs +0 -434
  518. package/scripts/_audit/plc-clean-shots.mjs +0 -161
  519. package/scripts/_audit/plc-fc10-probe.mjs +0 -30
  520. package/scripts/_audit/probe-binding.mjs +0 -114
  521. package/scripts/_audit/recipe-save-e2e.mjs +0 -365
  522. package/scripts/_audit/review-fix-verify.mjs +0 -158
  523. package/scripts/_audit/runtime-dir-e2e.mjs +0 -393
  524. package/scripts/_audit/town-focus-shot.mjs +0 -129
  525. package/scripts/_audit/town-reposition.mjs +0 -85
  526. package/scripts/_audit/verify-cleanup.mjs +0 -67
  527. package/scripts/_audit/verify-data-integrity.mjs +0 -112
  528. package/scripts/_audit/watchdog-recovery-test.mjs +0 -149
  529. package/scripts/_dbg-optloop-ui-shots.mjs +0 -52
  530. /package/.output/public/_nuxt/{4RTUlYvj2.js → 4RTUlYvj.js} +0 -0
  531. /package/.output/public/_nuxt/{BBhLVYdM.js → BBhLVYdM2.js} +0 -0
  532. /package/.output/public/_nuxt/{BG7XSX-S2.js → BG7XSX-S.js} +0 -0
  533. /package/.output/public/_nuxt/{BU7WuuKh.js → BU7WuuKh2.js} +0 -0
  534. /package/.output/public/_nuxt/{BrRX-l9B2.js → BrRX-l9B.js} +0 -0
  535. /package/.output/public/_nuxt/{CHyzK5m52.js → CHyzK5m5.js} +0 -0
  536. /package/.output/public/_nuxt/{Ckafrjnw2.js → Ckafrjnw.js} +0 -0
  537. /package/.output/public/_nuxt/{D1Xw30Dj2.js → D1Xw30Dj.js} +0 -0
  538. /package/.output/public/_nuxt/{DEhjFhZ2.js → DEhjFhZ22.js} +0 -0
  539. /package/.output/public/_nuxt/{DdNujZN5.js → DdNujZN52.js} +0 -0
  540. /package/.output/public/_nuxt/{DzwIZ81f.js → DzwIZ81f2.js} +0 -0
  541. /package/.output/public/_nuxt/{M6NcguDO.js → M6NcguDO2.js} +0 -0
  542. /package/.output/public/_nuxt/{MW-V7IIP2.js → MW-V7IIP.js} +0 -0
  543. /package/.output/public/_nuxt/{WmMwIS4y.js → WmMwIS4y2.js} +0 -0
  544. /package/.output/public/_nuxt/{qIQFsHtF.js → qIQFsHtF2.js} +0 -0
@@ -1,627 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * scripts/_audit/full-feature-e2e-20260927.mjs —— 全功能真实端到端验收。
4
- *
5
- * 覆盖:节点绑定(DCW 写入/DAQ 数采/SP 回读)→ 前后端交互(真实 Chrome 登录+全页面巡检)
6
- * → 数字孪生 /town 渲染(canvas+__townStats+截图)→ AgentTeam 创建 + goal 任务下发
7
- * (进程内 mock harness 真实调度闭环)→ 群聊(REST 落库 + 前端 composer 实发)
8
- * → AML 集成(4 批次激励数据 → 数据集 → hybrid_residual 真实训练 → 平台门禁 →
9
- * 场景快照/试验/门禁 → shadow/production 两段 HITL 晋升 → MPC 未传 model_id 自动投用 → 写回复测)。
10
- *
11
- * 用法:node scripts/_audit/full-feature-e2e-20260927.mjs [--keep]
12
- */
13
- import { spawn, spawnSync } from 'node:child_process'
14
- import { closeSync, existsSync, mkdtempSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs'
15
- import { tmpdir } from 'node:os'
16
- import { dirname, join, resolve } from 'node:path'
17
- import { fileURLToPath } from 'node:url'
18
-
19
- const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..')
20
- const AW_PORT = 3474
21
- const SIM_PORT = 4023
22
- const HOME = mkdtempSync(join(tmpdir(), 'aw-full-e2e-'))
23
- const SIM_DIR = resolve(REPO, '..', 'plc-node-simulator-bench-4023')
24
- const BASE = `http://127.0.0.1:${AW_PORT}`
25
- const SIM = `http://127.0.0.1:${SIM_PORT}`
26
- const KEEP = process.argv.includes('--keep')
27
- const SHOTS = join(HOME, 'shots')
28
- mkdirSync(SHOTS, { recursive: true })
29
-
30
- let pass = 0
31
- const fails = []
32
- const ok = (name, cond, detail = '') => {
33
- if (cond) { pass++; console.log(` ✔ ${name}`) }
34
- else { fails.push(name); console.log(` ✖ ${name}${detail ? ` — ${String(detail).slice(0, 200)}` : ''}`) }
35
- }
36
- const sleep = ms => new Promise(r => setTimeout(r, ms))
37
- const getJson = async (url, token) => {
38
- try {
39
- const r = await fetch(url, { signal: AbortSignal.timeout(30000), headers: token ? { authorization: `Bearer ${token}` } : {} })
40
- return await r.json()
41
- }
42
- catch { return null }
43
- }
44
- const callA = async (method, path, body) => {
45
- const r = await fetch(`${BASE}${path}`, {
46
- method, headers: { 'content-type': 'application/json', 'authorization': `Bearer ${TOKEN}` },
47
- body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(120000),
48
- })
49
- const json = await r.json().catch(() => null)
50
- return { status: r.status, json, data: json?.data, message: json?.message }
51
- }
52
- const killPort = (port) => {
53
- try {
54
- const psi = spawnSync('powershell', ['-NoProfile', '-Command',
55
- `Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`], { encoding: 'utf8' })
56
- const pid = Number(psi.stdout.trim())
57
- if (Number.isInteger(pid) && pid > 0) spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' })
58
- }
59
- catch { /* 尽力而为 */ }
60
- }
61
-
62
- let TOKEN = ''
63
- const ADMIN = { name: 'e2e-full-admin', email: 'e2e-full@awshop.local', password: 'E2eFull2026!' }
64
-
65
- /* ═══ Phase 0 · 清场 + 自举(平台 + 模拟器 + AML venv 复用)═══ */
66
- console.log('═══ [P0] 清场自举:平台 3474 + 模拟器 4023(全新 home)═══')
67
- for (const p of [AW_PORT, SIM_PORT, 4010, 4012]) killPort(p)
68
- writeFileSync(join(HOME, 'runtime-settings.json'), JSON.stringify({ version: 1, overrides: { 'mcp.enabled': true } }))
69
- {
70
- // AML venv/tools 以目录联接复用仓库运行时的既有安装(免 10 分钟 uv 装环境);产物仍落全新 home
71
- const src = join(REPO, '.AgentWorkShop', 'aml')
72
- mkdirSync(join(HOME, 'aml'), { recursive: true })
73
- for (const seg of ['.venv', 'tools']) {
74
- const r = spawnSync('cmd', ['/c', 'mklink', '/J', join(HOME, 'aml', seg), join(src, seg)], { encoding: 'utf8' })
75
- if (!existsSync(join(HOME, 'aml', seg))) console.log(` ↳ junction ${seg} 失败(${String(r.stderr).trim().slice(0, 80)}),训练环境将现场自建`)
76
- }
77
- }
78
- {
79
- const out = openSync(join(HOME, 'instance.log'), 'a')
80
- const p = spawn(process.execPath, [join(REPO, 'bin', 'aw.mjs'), 'start', '--port', String(AW_PORT)], {
81
- cwd: REPO,
82
- env: { ...process.env, NO_PROXY: '127.0.0.1,localhost', HTTP_PROXY: '', HTTPS_PROXY: '', AW_MODE: 'home', AW_HOME: HOME, NUXT_SESSION_PASSWORD: 'full-e2e-session-password-012345678' },
83
- detached: true, windowsHide: true, stdio: ['ignore', out, out],
84
- })
85
- closeSync(out); p.unref()
86
- }
87
- let up = false
88
- for (let i = 0; i < 45; i++) {
89
- await sleep(2000)
90
- if ((await getJson(`${BASE}/api/health`))?.data?.status === 'ok') { up = true; break }
91
- }
92
- ok('P0a 平台健康门(全新 home)', up)
93
- {
94
- const reg = await (await fetch(`${BASE}/api/users/register`, {
95
- method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(ADMIN),
96
- })).json()
97
- TOKEN = reg?.data?.token ?? ''
98
- }
99
- ok('P0b admin 首注册', Boolean(TOKEN))
100
- {
101
- process.env.SIM_BASE = SIM
102
- process.env.SIM_SHADOW_DIR = SIM_DIR
103
- const { ensureSimulator, applyPreset } = await import('../../bench/lib/sim.mjs')
104
- await ensureSimulator({ log: () => {} })
105
- await applyPreset('cast-film-physics')
106
- }
107
- ok('P0c 模拟器在跑(cast-film-physics)', (await getJson(`${SIM}/api/plant/state`))?.data?.running === true)
108
- let gateCalibFail = 0
109
- for (const [k, v] of Object.entries({ 'aml.gates.nrmse': 0.9, 'aml.gates.rolloutNrmse': 0.99, 'aml.gates.valTestGap': 2.0 })) {
110
- const r = await callA('PATCH', '/api/system/settings', { override: { [k]: v } })
111
- if (r.status !== 200) { gateCalibFail++; console.log(` ↳ 门禁校准 ${k} 未生效(${r.status}),用默认值继续`) }
112
- }
113
- ok('P0d AML 门禁校准下发', gateCalibFail === 0, `fail=${gateCalibFail}`)
114
-
115
- /* ═══ Phase 1 · 节点绑定:权威建线 6 DCW + 5 DAQ + 6 SP 回读 + 数采启动 + 批次1 ═══ */
116
- console.log('═══ [P1] 节点绑定:建线 + DCW/DAQ 绑定 + SP 回读 + 批次开跑 ═══')
117
- let twin, recipeId
118
- {
119
- const simDevices = (await getJson(`${SIM}/api/nodes`))?.data ?? []
120
- const { provisionTwinLine, startTwinBatch } = await import('../../bench/lib/closedloop.mjs')
121
- const api = { call: async (m, p, b) => { const r = await callA(m, p, b); return { status: r.status, data: r.data, message: r.message } } }
122
- twin = await provisionTwinLine(api, { simDevices, sfx: 'fulle2e' })
123
- ok('P1a 权威建线(6 DCW + 5 DAQ 绑定)', twin.ok, (twin.ev ?? []).join(' | ').slice(0, 160))
124
- const spReadback = {}
125
- for (const dev of simDevices) {
126
- const exp = (await getJson(`${SIM}/api/nodes/${dev.id}/export`))?.data?.items ?? []
127
- for (const id of Object.keys(twin.dcw)) {
128
- if (spReadback[id]) continue
129
- const sig = (dev.signals ?? []).find(s => s.id === id)
130
- if (!sig) continue
131
- const item = exp.find(i => i.signal === sig.name)
132
- if (!item?.driverConfig) continue
133
- const cfg = { ...item.driverConfig }
134
- if (cfg.jsonKey !== undefined && cfg.jsonPath === undefined) { cfg.jsonPath = cfg.jsonKey; delete cfg.jsonKey }
135
- const r = await callA('POST', '/api/workshop/daq', {
136
- name: `${sig.name} 回读 e2e`, templateRef: 'daq-temp-tc', driver: dev.protocol, driverConfig: cfg,
137
- unit: sig.unit, min: sig.min, max: sig.max, lineId: twin.lineId, intervalMs: 1000, publishIntervalMs: 0,
138
- semantics: `执行器设定点回读(AML control 输入) ${item.signal}`,
139
- })
140
- spReadback[id] = r.json?.data?.node?.id ?? r.json?.data?.id
141
- }
142
- }
143
- globalThis.__spReadback = spReadback
144
- ok('P1b SP 回读 DAQ ×6(执行器→数采绑定)', Object.keys(spReadback).length === 6, JSON.stringify(spReadback))
145
- await callA('PATCH', `/api/workshop/daq/${twin.daq['film-thickness']}`, { semantics: '流延膜厚度测量(优化目标 goal,单位 μm;厚度质量输出)' })
146
- const cs = await callA('POST', '/api/workshop/daq/controller', { action: 'start' })
147
- ok('P1c 数采控制器启动', cs.status === 200, String(cs.message ?? ''))
148
- // SV→PV 因果:写一次设定点,PV 应在滞后后跟随
149
- const w = await callA('POST', `/api/workshop/dcw/${twin.dcw['diegap-sp']}/write`, { value: 1.01 })
150
- ok('P1d DCW SV 写入(治理链放行)', w.status === 200, String(w.message ?? ''))
151
- const batch = await startTwinBatch(api, { lineId: twin.lineId, productId: twin.productId, dcw: twin.dcw, sfx: 'fulle2e' })
152
- recipeId = batch.recipeId
153
- ok('P1e 配方下发并开跑(批次1)', batch.ok && Boolean(recipeId), JSON.stringify(batch).slice(0, 120))
154
- }
155
-
156
- /* ═══ Phase 2 · 前后端交互(真实 Chrome):登录流 + 全页面巡检 + 孪生渲染(批次1 窗口内)═══ */
157
- console.log('═══ [P2] 浏览器真实操作:登录流 + 全路由巡检 + /town 渲染 ═══')
158
- process.env.AW_BASE = BASE
159
- process.env.AW_UI_SCALE = '1'
160
- {
161
- const { launch, openPage, gotoReady } = await import('../ui/lib.mjs')
162
- const CHROME = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
163
- /* 硬超时护栏:任何浏览器操作都不允许挂死主流程(超时即记败让路);
164
- 输家 promise 预挂 catch,避免迟到拒绝变成 unhandledRejection 杀进程 */
165
- const withT = (label, ms, fn) => new Promise((resolve) => {
166
- let settled = false
167
- const done = (r) => { if (!settled) { settled = true; clearTimeout(timer); resolve(r) } }
168
- const timer = setTimeout(() => done({ okT: false, e: new Error(`hard-timeout:${label}(${ms}ms)`) }), ms)
169
- Promise.resolve().then(fn).then(v => done({ okT: true, v }), e => done({ okT: false, e }))
170
- })
171
- const killBrowser = async (b) => {
172
- if (!b) return
173
- const r = await withT('browser-close', 12000, () => b.close())
174
- if (!r.okT) { try { b.process()?.kill() } catch { /* 已死 */ } }
175
- }
176
- if (!existsSync(CHROME)) { ok('P2 前置:本机 Chrome 存在', false, CHROME) }
177
- else {
178
- /* P2a 未登录真实登录流(登录门在工作台 /workshop;首页为访客浏览态) */
179
- {
180
- const rA = await withT('login-flow', 150000, async () => {
181
- const browser = await launch()
182
- try {
183
- const lp = await browser.newPage()
184
- const loginErrs = []
185
- lp.on('pageerror', e => loginErrs.push(String(e.message).slice(0, 120)))
186
- await lp.goto(`${BASE}/workshop`, { waitUntil: 'domcontentloaded', timeout: 40000 })
187
- await lp.waitForFunction(() => document.documentElement.dataset.vpTier !== undefined, { timeout: 40000, polling: 200 })
188
- await sleep(3500)
189
- const emailBox = await lp.$('input[type=email]')
190
- const pwdBox = await lp.$('input[type=password]')
191
- let loggedIn = false
192
- if (emailBox && pwdBox) {
193
- await emailBox.type(ADMIN.email)
194
- await pwdBox.type(ADMIN.password)
195
- const btn = await lp.evaluateHandle(() => Array.from(document.querySelectorAll('button')).find(x => /登\s*录/.test(x.textContent ?? '')))
196
- await btn.asElement()?.click()
197
- await sleep(5000)
198
- loggedIn = (await lp.$$('input[type=email], input[type=password]')).length === 0
199
- }
200
- await lp.screenshot({ path: join(SHOTS, 'login-flow.png') })
201
- return { loggedIn, n: emailBox && pwdBox ? 2 : 0, errs: loginErrs.length }
202
- }
203
- finally { await killBrowser(browser) }
204
- })
205
- ok('P2a 真实登录流(/workshop 登录门提交→进入工作台)', rA.okT && rA.v?.loggedIn, rA.okT ? `inputs=${rA.v?.n} errs=${rA.v?.errs}` : String(rA.e).slice(0, 120))
206
- }
207
-
208
- /* P2b 登录态全页面巡检(每路由独立 page + 硬超时;浏览器死亡自动重建) */
209
- const ROUTES = ['/', '/workshop', '/workshop/agents', '/workshop/teams', '/workshop/channel-templates', '/monitor',
210
- '/daq', '/dcw', '/aml', '/operations', '/logs', '/permissions', '/plugins', '/settings', '/tokens', '/users']
211
- const pageErrs = {}
212
- let rendered = 0
213
- let browser = null
214
- let browserDead = false
215
- for (const r of ROUTES) {
216
- if (!browser) {
217
- const lb = await withT('launch', 60000, () => launch())
218
- if (!lb.okT) { (pageErrs.all ??= []).push('launch-fail'); break }
219
- browser = lb.v
220
- }
221
- const op = await withT(`route:${r}`, 75000, async () => {
222
- const page = await openPage(browser, { token: TOKEN, width: 1366, height: 850 })
223
- page.on('pageerror', (e) => { (pageErrs[r] ??= []).push(String(e.message).slice(0, 100)) })
224
- await gotoReady(page, r, { wait: 2000, timeout: 30000 })
225
- const hasBody = await page.evaluate(() => (document.body.innerText ?? '').length > 40)
226
- await page.screenshot({ path: join(SHOTS, `route${r.replaceAll('/', '_')}.png`) })
227
- await page.close().catch(() => {})
228
- return hasBody
229
- })
230
- if (op.okT && op.v) rendered++
231
- const es = String(op.e ?? '')
232
- if (!op.okT) {
233
- (pageErrs[r] ??= []).push(es.slice(0, 80))
234
- if (es.includes('Not launched') || es.includes('closed') || es.includes('Session closed') || es.includes('Target')) browserDead = true
235
- }
236
- if (browserDead) { await killBrowser(browser); browser = null; browserDead = false }
237
- }
238
- await killBrowser(browser)
239
- ok('P2b 全路由渲染(16 页)', rendered >= 15, `rendered=${rendered}/16 errs=${JSON.stringify(pageErrs).slice(0, 260)}`)
240
- const pageErrorCount = Object.entries(pageErrs).filter(([k]) => k.startsWith('http')).reduce((a, [, lst]) => a + lst.length, 0)
241
- ok('P2c 全站零 pageerror', pageErrorCount === 0, JSON.stringify(pageErrs).slice(0, 300))
242
- /* 孪生渲染深检(P2d)挪到 P3 批次4 窗口:/town 渲染的是**已挂载的 workshop Channel**,
243
- 此时尚无频道,空态「还没有挂载任何 Channel」是正确产品行为(实测截图确认过) */
244
- }
245
- }
246
-
247
- /* ═══ Phase 3 · 批次 2-4(激励)窗口内并行:团队 goal / 群聊 / AML 通道准备 / 工作台 UI ═══ */
248
- console.log('═══ [P3] 批次 2-4 激励 + 并行:AgentTeam goal / 群聊 / AML 通道 / 工作台 UI ═══')
249
- const spReadback = globalThis.__spReadback
250
- const closeAndRestart = async (i) => {
251
- await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
252
- await sleep(3000)
253
- const st = await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId })
254
- if (st.status !== 200) { await sleep(8000); await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId }) }
255
- console.log(` ↳ 批次 ${i} 闭合/重启`)
256
- }
257
- const runBatch = async (n, steps, sideWork) => {
258
- await closeAndRestart(n)
259
- const t0 = Date.now()
260
- let prev = 0
261
- for (const st of steps) {
262
- await sleep(st.at - prev); prev = st.at
263
- const w = await callA('POST', `/api/workshop/dcw/${twin.dcw[st.node]}/write`, { value: st.v })
264
- console.log(` ↳ 批次 ${n} 阶跃 ${st.node} ← ${st.v} ${w.status === 200 ? '√' : '✘ ' + String(w.message ?? '').slice(0, 60)}`)
265
- }
266
- const rest = 300_000 - (Date.now() - t0)
267
- if (sideWork) await Promise.race([sideWork(), sleep(Math.max(rest, 5000)).then(() => console.log(` ↳ 批次 ${n} 窗口到,侧线作业让路`))])
268
- await sleep(Math.max(0, 300_000 - (Date.now() - t0)))
269
- }
270
- const BATCHES = [
271
- { n: 2, steps: [{ at: 65_000, node: 'linespeed-sp', v: 97 }, { at: 200_000, node: 'diegap-sp', v: 1.03 }] },
272
- { n: 3, steps: [{ at: 65_000, node: 'linespeed-sp', v: 93 }, { at: 200_000, node: 'diegap-sp', v: 0.97 }] },
273
- { n: 4, steps: [{ at: 65_000, node: 'linespeed-sp', v: 97 }, { at: 200_000, node: 'diegap-sp', v: 1.0 }] },
274
- ]
275
-
276
- /* ── 侧线 A:AgentTeam 创建 + goal 任务下发(mock harness 真实调度)+ 群聊 REST ── */
277
- const sideTeamChat = async () => {
278
- const TAG = Date.now().toString(36)
279
- /* 团队正确流:全局 Agent 模板(/agents)→ team members(引用模板)→ deploy 克隆进频道;
280
- 频道初始不带 lead(部署自带 lead,重复会 409 LEAD_EXISTS) */
281
- const tpl = {}
282
- for (const k of ['lead', 'wa', 'wb']) {
283
- const a = await callA('POST', '/api/workshop/agents', { name: `e2e-${k}-${TAG}`, harness: 'mock' })
284
- tpl[k] = a.data?.id ?? a.data?.agent?.id
285
- }
286
- ok('P3a-1 mock Agent 模板 ×3(全局库)', Boolean(tpl.lead && tpl.wa && tpl.wb), JSON.stringify(tpl))
287
- const ch = await callA('POST', '/api/workshop/channels', {
288
- name: `全功能E2E-team-${TAG}`, description: '全功能 E2E:mock 团队 goal 闭环 + 群聊',
289
- })
290
- const channelId = ch.data?.channelId
291
- ok('P3a 创建团队 Channel(无预置成员)', Boolean(channelId), String(ch.message ?? ''))
292
- const team = await callA('POST', '/api/workshop/teams', { name: `全功能E2E-Team-${TAG}` })
293
- const teamId = team.data?.id ?? team.data?.teamId
294
- const m1 = await callA('POST', `/api/workshop/teams/${teamId}/members`, { agentId: tpl.lead, role: 'lead' })
295
- const m2 = await callA('POST', `/api/workshop/teams/${teamId}/members`, { agentId: tpl.wa, role: 'worker' })
296
- const m3 = await callA('POST', `/api/workshop/teams/${teamId}/members`, { agentId: tpl.wb, role: 'worker' })
297
- ok('P3b 团队成员挂接(1 lead + 2 worker 模板)', [m1.status, m2.status, m3.status].every(s => s === 200), `${m1.status}/${m2.status}/${m3.status}`)
298
- const dep = await callA('POST', `/api/workshop/teams/${teamId}/deploy`, { channelId })
299
- ok('P3c AgentTeam 部署到 Channel(克隆成实例)', dep.status === 200, String(dep.message ?? ''))
300
- const agents = (await callA('GET', `/api/workshop/channels/${channelId}/agents`)).data ?? []
301
- ok('P3b-2 频道成员结构(1 lead + 2 worker)', agents.length === 3 && agents.filter(a => a.role === 'worker').length === 2, `n=${agents.length}`)
302
-
303
- try { await callA('POST', `/api/workshop/channels/${channelId}/activate`, {}) } catch { /* 未激活也可:任务提交即自动装配 */ }
304
- const lead = agents.find(a => a.role === 'lead')
305
- const task = await callA('POST', `/api/workshop/channels/${channelId}/tasks`, {
306
- title: `膜厚优化 goal ${TAG}`, mode: 'goal',
307
- description: '[mock:complex] 目标:确认产线膜厚工况稳定。拆解:①检查当前 PV 趋势 ②给出结论收口。',
308
- assigneeId: lead?.id,
309
- })
310
- const taskId = task.data?.id
311
- ok('P3d goal 任务下发', Boolean(taskId), String(task.message ?? ''))
312
- let row = null
313
- for (let i = 0; i < 60 && !row; i++) {
314
- await sleep(3000)
315
- const tasks = (await callA('GET', `/api/workshop/channels/${channelId}/tasks`)).data ?? []
316
- row = tasks.find(t => t.id === taskId)
317
- if (row && ['COMPLETED', 'FAILED', 'CANCELED'].includes(row.state)) break
318
- row = null
319
- }
320
- ok('P3e goal 任务真实调度完成(COMPLETED)', row?.state === 'COMPLETED', `state=${row?.state ?? 'timeout'}`)
321
- const sub = (await callA('GET', `/api/workshop/channels/${channelId}/tasks`)).data ?? []
322
- ok('P3f lead 派发子任务并收口(≥2 任务)', sub.length >= 2, `tasks=${sub.length}`)
323
-
324
- const chatOn = await callA('PATCH', `/api/workshop/channels/${channelId}`, { chatEnabled: 1 })
325
- const msg = await callA('POST', `/api/workshop/channels/${channelId}/chat/messages`, { text: `E2E 群聊消息 ${TAG}:请关注膜厚 PV 波动。` })
326
- ok('P3g 群聊开启+消息落库', msg.status === 200, `patch=${chatOn.status} ${String(msg.message ?? '')}`)
327
- const hist = (await callA('GET', `/api/workshop/channels/${channelId}/chat/messages?limit=50`)).data
328
- const items = Array.isArray(hist) ? hist : (hist?.items ?? hist?.messages ?? [])
329
- const fromAgents = new Set(items.map(m => m.agentName ?? m.senderName ?? m.from).filter(Boolean))
330
- ok('P3h 群聊时间线:人类+多成员发言', items.length >= 3 && fromAgents.size >= 2, `msgs=${items.length} senders=${[...fromAgents].join('|').slice(0, 80)}`)
331
- globalThis.__teamChannel = channelId
332
- return channelId
333
- }
334
-
335
- /* ── 侧线 B:AML 训练通道准备(模板实例化 + 绑定 + 场景编译冻结 + PhysicsSpec)── */
336
- const sideAmlPrep = async () => {
337
- const scene = { sceneId: `fulle2e-thickness-${Date.now().toString(36)}`, sceneVersion: '1.0.0', lineId: twin.lineId, productId: twin.productId, recipeId }
338
- const inst = await callA('POST', '/api/workshop/channel-templates/chtpl-hybrid-twin-mpc-default/instantiate', {
339
- name: '全功能E2E训练通道', toolProfile: 'hybrid_twin', scene,
340
- objective: { objectiveId: 'thickness-50um', targets: { film_thickness: 50 } },
341
- controlPolicy: 'recommendation_only',
342
- })
343
- const d = inst.data ?? {}
344
- const channelA = d.channelId
345
- const workerA = (d.agents ?? []).find(a => a.role === 'worker')?.id
346
- ok('P3i AML 训练通道实例化(hybrid_twin)+ worker', Boolean(channelA && workerA), JSON.stringify({ channelA, workerA }).slice(0, 100))
347
- for (const nodeId of Object.values(twin.dcw)) await callA('POST', '/api/workshop/agent-tools/bindings', { agentId: workerA, nodeId, kind: 'dcw', mode: 'auto' })
348
- for (const nodeId of Object.values(twin.daq)) await callA('POST', '/api/workshop/agent-tools/bindings', { agentId: workerA, nodeId, kind: 'daq', mode: 'auto' })
349
- const invoke = async (tool, args, agentId) => {
350
- const r = await callA('POST', '/api/workshop/agent-tools/invoke', { agentId, tool, args })
351
- const result = r.json?.data?.result
352
- return { isError: Boolean(result?.isError), text: String(result?.text ?? ''), data: result?.data ?? null }
353
- }
354
- const disco = await invoke('twin_scene_discover', {}, workerA)
355
- ok('P3j 场景发现(target=1 语义命中)', !disco.isError && /"target"\s*:\s*1/.test(disco.text), disco.text.slice(0, 120))
356
- const compiled = await invoke('twin_scene_compile', {
357
- scene_id: scene.sceneId, scene_version: '1.0.0', line_id: twin.lineId, product_id: twin.productId, recipe_id: recipeId,
358
- prompt: '流延膜厚度闭环优化:目标膜厚 50μm。控制=6 个执行器设定点,观测=膜厚(目标)/熔温/熔压。约束:熔温 195~225℃,熔压 ≤22MPa。',
359
- }, workerA)
360
- ok('P3k 场景编译', !compiled.isError, compiled.text.slice(0, 120))
361
- const frozen = await invoke('twin_scene_freeze', { scene_id: scene.sceneId, scene_version: '1.0.0', confirmation: 'USER_CONFIRMED_SCENE_CONTRACT', approved_by: 'full-feature-e2e' }, workerA)
362
- ok('P3l 场景冻结(用户确认令牌)', !frozen.isError, frozen.text.slice(0, 120))
363
- const draft = await invoke('twin_physics_spec_draft', { dt_sec: 1 }, workerA)
364
- const artifactPath = (draft.text.match(/artifact:\s*([^\n]+)/) || [])[1]?.trim()
365
- ok('P3m 骨架 PhysicsSpec 生成', !draft.isError && Boolean(artifactPath) && existsSync(artifactPath), draft.text.slice(0, 120))
366
- globalThis.__aml = { channelA, workerA, scene, physicsSpec: artifactPath ? JSON.parse(readFileSync(artifactPath, 'utf8')) : null, invoke }
367
- }
368
-
369
- /* ── 侧线 C:工作台 UI 实发群聊(puppeteer,硬超时护栏)── */
370
- const sideWorkshopUi = async () => {
371
- const { launch, openPage, gotoReady } = await import('../ui/lib.mjs')
372
- const withT = (label, ms, fn) => new Promise((resolve) => {
373
- let settled = false
374
- const done = (r) => { if (!settled) { settled = true; clearTimeout(timer); resolve(r) } }
375
- const timer = setTimeout(() => done({ okT: false, e: new Error(`hard-timeout:${label}(${ms}ms)`) }), ms)
376
- Promise.resolve().then(fn).then(v => done({ okT: true, v }), e => done({ okT: false, e }))
377
- })
378
- const killBrowser = async (b) => {
379
- if (!b) return
380
- const r = await withT('browser-close', 12000, () => b.close())
381
- if (!r.okT) { try { b.process()?.kill() } catch { /* 已死 */ } }
382
- }
383
- const r = await withT('workshop-ui', 180000, async () => {
384
- const b = await launch()
385
- try {
386
- const page = await openPage(b, { token: TOKEN, width: 1440, height: 900 })
387
- for (let i = 0; i < 30 && !globalThis.__teamChannel; i++) await sleep(2000)
388
- const chId = globalThis.__teamChannel
389
- if (!chId) return { clicked: false, sent: false, why: '团队频道未就绪' }
390
- await gotoReady(page, '/workshop', { wait: 3000, timeout: 40000 })
391
- const clicked = await page.evaluate(() => {
392
- const el = Array.from(document.querySelectorAll('[class*=channel], li, a, .menu-item'))
393
- .find(e => (e.textContent ?? '').includes('全功能E2E-team') && e.offsetHeight > 0)
394
- if (el) { el.click(); return true }
395
- return false
396
- })
397
- await sleep(2500)
398
- const ta = await page.$('.composer-pane textarea') ?? await page.$('textarea')
399
- let sent = false
400
- if (ta) {
401
- await ta.type('UI 直发:工作台 composer 群聊消息(E2E)')
402
- await page.keyboard.press('Enter')
403
- await sleep(4000)
404
- sent = await page.evaluate(() => (document.body.innerText ?? '').includes('UI 直发:工作台 composer 群聊消息(E2E)'))
405
- }
406
- await page.screenshot({ path: join(SHOTS, 'workshop-chat.png') })
407
- return { clicked, sent, why: '' }
408
- }
409
- finally { await killBrowser(b) }
410
- })
411
- ok('P3n 工作台 UI 实发群聊(composer→时间线)', r.okT && r.v?.clicked && r.v?.sent, r.okT ? `clicked=${r.v?.clicked} sent=${r.v?.sent} ${r.v?.why}` : String(r.e).slice(0, 120))
412
- }
413
-
414
- /* ── 侧线 D:孪生渲染深检(频道已挂载后;/town 渲染 workshop Channel)── */
415
- const sideTownCheck = async () => {
416
- const { launch, openPage, gotoReady } = await import('../ui/lib.mjs')
417
- const withT = (label, ms, fn) => new Promise((resolve) => {
418
- let settled = false
419
- const done = (r) => { if (!settled) { settled = true; clearTimeout(timer); resolve(r) } }
420
- const timer = setTimeout(() => done({ okT: false, e: new Error(`hard-timeout:${label}(${ms}ms)`) }), ms)
421
- Promise.resolve().then(fn).then(v => done({ okT: true, v }), e => done({ okT: false, e }))
422
- })
423
- const killBrowser = async (b) => {
424
- if (!b) return
425
- const r = await withT('browser-close', 12000, () => b.close())
426
- if (!r.okT) { try { b.process()?.kill() } catch { /* 已死 */ } }
427
- }
428
- const r = await withT('town-deep', 120000, async () => {
429
- const b = await launch()
430
- try {
431
- const page = await openPage(b, { token: TOKEN, width: 1440, height: 900 })
432
- const errs = []
433
- page.on('pageerror', e => errs.push(String(e.message).slice(0, 100)))
434
- await gotoReady(page, '/town', { wait: 9000, timeout: 40000 })
435
- const town = await page.evaluate(() => {
436
- const canvas = document.querySelector('canvas')
437
- const stats = window.__townStats
438
- return {
439
- canvas: Boolean(canvas), w: canvas?.width ?? 0, h: canvas?.height ?? 0,
440
- statsKeys: stats ? Object.keys(stats) : [], fps: Number(stats?.fps ?? stats?.fpsAvg ?? 0) || null,
441
- }
442
- })
443
- await page.screenshot({ path: join(SHOTS, 'town-deep.png') })
444
- return { town, errs }
445
- }
446
- finally { await killBrowser(b) }
447
- })
448
- if (r.okT) {
449
- ok('P3q-1 孪生 canvas 渲染(频道挂载后)', r.v.town.canvas && r.v.town.w > 400, JSON.stringify({ w: r.v.town.w, h: r.v.town.h }))
450
- ok('P3q-2 __townStats 仪表在位', r.v.town.statsKeys.length > 0, `keys=${r.v.town.statsKeys.join(',')} fps=${r.v.town.fps} errs=${r.v.errs.length}`)
451
- }
452
- else { ok('P3q-1 孪生 canvas 渲染(频道挂载后)', false, String(r.e).slice(0, 120)); ok('P3q-2 __townStats 仪表在位', false, 'town 页未完成') }
453
- }
454
-
455
- await runBatch(2, BATCHES[0].steps, sideTeamChat)
456
- ok('P3o 群聊频道句柄就绪', Boolean(globalThis.__teamChannel))
457
- await runBatch(3, BATCHES[1].steps, sideAmlPrep)
458
- await runBatch(4, BATCHES[2].steps, async () => { await sideWorkshopUi(); await sideTownCheck() })
459
- await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
460
- await sleep(3000)
461
- {
462
- const runs = (await callA('GET', '/api/workshop/dcw/recipes')).data?.runs ?? []
463
- const closed = runs.filter(x => x.endedAt && x.recipeId === recipeId)
464
- ok('P3p 4 个已闭合批次(激励数据)', closed.length >= 4, `closed=${closed.length}`)
465
- }
466
-
467
- /* ═══ Phase 4 · AML:数据集 → 真实训练(平台门禁)═══ */
468
- console.log('═══ [P4] AML 集成:数据集构建 + hybrid_residual 真实训练 ═══')
469
- let ds, model
470
- {
471
- const { scene, physicsSpec } = globalThis.__aml
472
- ds = (await callA('POST', '/api/workshop/aml/datasets', {
473
- lineId: twin.lineId, productId: twin.productId, recipeId,
474
- nodes: [
475
- ...Object.values(spReadback).map(nid => ({ nodeId: nid, role: 'control' })),
476
- { nodeId: twin.daq['film-thickness'], role: 'target' },
477
- { nodeId: twin.daq['melt-pressure'], role: 'feature' },
478
- { nodeId: twin.daq['melt-temp'], role: 'feature' },
479
- ],
480
- beatMs: 1000, window: { historySteps: 8, horizonSteps: 4 },
481
- split: { valRatio: 0.34, testRatio: 0.33, seed: 42 },
482
- purpose: 'mpc_surrogate', note: '全功能 E2E 数据集',
483
- })).data?.dataset
484
- ok('P4a 数据集构建(9 变量 + ≥4 runs)', Boolean(ds?.id) && (ds.runIds?.length ?? 0) >= 4, JSON.stringify({ id: ds?.id, rows: ds?.rowCount, runs: ds?.runIds?.length }).slice(0, 140))
485
- ok('P4b 数据集实体落运行时目录', existsSync(join(HOME, 'aml', 'datasets', ds.id, 'manifest.json')), join(HOME, 'aml', 'datasets', ds.id))
486
-
487
- const man = JSON.parse(readFileSync(join(HOME, 'aml', 'datasets', ds.id, 'manifest.json'), 'utf8'))
488
- const datasetNodes = new Set(man.allNodes)
489
- const dwToDn = {}
490
- for (const [sig, dn] of Object.entries(spReadback)) dwToDn[twin.dcw[sig]] = dn
491
- for (const v of physicsSpec.variables) {
492
- if (v.nodeId && !datasetNodes.has(v.nodeId) && dwToDn[v.nodeId]) v.nodeId = dwToDn[v.nodeId]
493
- }
494
- const keptVars = physicsSpec.variables.filter(v => !v.nodeId || datasetNodes.has(v.nodeId))
495
- const keptIds = new Set(keptVars.map(v => v.id))
496
- physicsSpec.variables = keptVars
497
- physicsSpec.states = physicsSpec.states.filter((e) => { const base = e.lhs.endsWith('_next') ? e.lhs.slice(0, -5) : e.lhs; return keptIds.has(base) })
498
- physicsSpec.observations = physicsSpec.observations.filter(e => keptIds.has(e.lhs))
499
- physicsSpec.guards = (physicsSpec.guards ?? []).filter(e => keptIds.has(e.lhs))
500
- physicsSpec.constraints = physicsSpec.constraints.filter(c => keptIds.has(c.id))
501
-
502
- const job = (await callA('POST', '/api/workshop/aml/jobs', {
503
- datasetId: ds.id, purpose: 'mpc_surrogate', changeNote: '全功能 E2E 真实训练',
504
- params: { epochs: 600, hidden: 192, lr: 0.0008, residual_scale: 2.5, ensemble: 3 },
505
- seed: 7, jobKind: 'hybrid_residual', sceneId: scene.sceneId, sceneVersion: '1.0.0', objectiveId: 'thickness-50um',
506
- physicsSpec, providerId: physicsSpec.modelId, providerVersion: '1.0.0', providerHash: `sha256:${JSON.stringify(physicsSpec).length}`,
507
- modelName: '全功能E2E 膜厚闭环模型', modelDescription: '全功能端到端验收:输入=6 执行器 SP 回读,输出=膜厚(目标 50μm)',
508
- })).data?.job
509
- ok('P4c 训练作业提交(hybrid_residual)', Boolean(job?.id), JSON.stringify(job ?? {}).slice(0, 140))
510
-
511
- let done = null
512
- for (let i = 0; i < 120; i++) {
513
- await sleep(5000)
514
- done = (await callA('GET', `/api/workshop/aml/jobs/${job.id}`)).data?.job
515
- if (done?.status === 'done' || done?.status === 'failed') break
516
- if (i > 0 && i % 12 === 0) console.log(` ↳ 训练中 (${i * 5 / 60 | 0}min) status=${done?.status ?? '?'}`)
517
- }
518
- ok('P4d 训练完成且平台门禁全过', done?.status === 'done', `status=${done?.status} err=${String(done?.error ?? '').slice(0, 160)}`)
519
- const models = (await callA('GET', '/api/workshop/aml/models')).data?.models ?? []
520
- model = models.filter(m => m.datasetId === ds.id).sort((a, b) => String(b.createdAt ?? '').localeCompare(String(a.createdAt ?? '')))[0]
521
- ok('P4e 模型注册 + 工件在运行时目录', Boolean(model?.id) && existsSync(join(HOME, 'aml', 'models', model.id, 'model.onnx')), join(HOME, 'aml', 'models', model?.id ?? '?'))
522
- console.log(` ↳ 模型 ${model?.id} label=${model?.label} G1=${model?.metrics?.oneStepTest?.nrmse} G2=${model?.metrics?.rolloutTest?.nrmse}`)
523
- }
524
-
525
- /* ═══ Phase 5 · AML 投用链:快照 → 试验 → 场景门禁 → 两段 HITL 晋升 → MPC 自动投用 → 写回复测 ═══ */
526
- console.log('═══ [P5] AML 投用:快照/试验/门禁/HITL 晋升/MPC 自动投用 ═══')
527
- if (!model?.id) {
528
- console.log(' ↳ 训练未产出可用模型(P4 门禁未过)→ fail-closed:跳过投用链,治理正确行为')
529
- ok('P5 投用链前置(存在已过门禁模型)', false, 'model 不存在')
530
- await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
531
- }
532
- else {
533
- const { workerA, invoke, scene } = globalThis.__aml
534
- const st = await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId })
535
- if (st.status !== 200) { await sleep(8000); await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/start`, { recipeId }) }
536
- let snapshotId = null
537
- let snap = null
538
- for (let attempt = 1; attempt <= 8 && !snapshotId; attempt++) {
539
- if (attempt > 1) { console.log(' ↳ 快照重试'); await sleep(20000) }
540
- snap = await invoke('twin_snapshot_create', { auto_daq: true, channel_id: globalThis.__aml.channelA, phase: 'calibration' }, workerA)
541
- snapshotId = (snap.text.match(/snapshot_id:\s*([^\n]+)/) || [])[1]?.trim()
542
- }
543
- ok('P5a 孪生快照创建(auto_daq)', Boolean(snapshotId), snap?.text.slice(0, 140))
544
-
545
- const frozen = JSON.parse(readFileSync(join(HOME, 'aml', 'twins', 'scenes', `${scene.sceneId}-1.0.0-frozen`, 'scenes.json'), 'utf8')).scene ?? {}
546
- const targetObs = (frozen.observations ?? []).find(o => o.role === 'target')
547
- const speedCtl = (frozen.controls ?? []).find(c => (c.nodeId ?? '').includes('linespeed')) ?? (frozen.controls ?? [])[0]
548
- const dcwRes = await callA('GET', '/api/workshop/dcw/')
549
- const dwValueById = Object.fromEntries((dcwRes.data?.nodes ?? []).filter(n => n.lineId === twin.lineId).map(n => [n.id, Number(n.value)]))
550
- const baseline = Object.fromEntries((frozen.controls ?? []).map(c => [c.id, dwValueById[c.nodeId]]).filter(([, v]) => Number.isFinite(v)))
551
- let trialOk = 0
552
- for (let k = 0; k < 12; k++) {
553
- const delta = (k % 2 === 0 ? 1 : -0.5) * (speedCtl.maxStep ?? 2) * (0.3 + 0.07 * k)
554
- const cand = { ...baseline, [speedCtl.id]: (baseline[speedCtl.id] ?? 95) + delta }
555
- const t = await invoke('twin_trial_run', { snapshot_id: snapshotId, model_id: model.id, baseline_controls: baseline, candidate_controls: Array.from({ length: 4 }, () => cand) }, workerA)
556
- if (!t.isError && /improvement/.test(t.text)) trialOk++
557
- }
558
- ok('P5b 模型背书试验 12 组', trialOk >= 10, `ok=${trialOk}/12`)
559
- const gate = await invoke('twin_gate_evaluate', { model_id: model.id, scene_id: scene.sceneId }, workerA)
560
- const gatePassed = /"gatePassed":\s*true/.test(gate.text)
561
- ok('P5c 场景级门禁评估(eligibility 写回)', !gate.isError && /gatePassed/.test(gate.text), gate.text.slice(0, 160))
562
- writeFileSync(join(HOME, 'e2e-gate.txt'), gate.text)
563
-
564
- if (gatePassed) {
565
- const promoteStage = async (toStage) => {
566
- const p = invoke('aml_model_promote', { model_id: model.id, to_stage: toStage }, (await callA('GET', `/api/workshop/channels/${globalThis.__aml.channelA}/agents`)).data?.find(a => a.role === 'lead')?.id)
567
- let rid = null
568
- for (let i = 0; i < 30 && !rid; i++) {
569
- await sleep(2000)
570
- const pend = await callA('GET', '/api/workshop/hitl/pending')
571
- const items = pend.data?.items ?? pend.data ?? []
572
- const hit = (Array.isArray(items) ? items : []).find(x => (x.detail ?? x.title ?? '').includes(model.id))
573
- if (hit) rid = hit.id ?? hit.requestId
574
- }
575
- if (rid) await callA('POST', '/api/workshop/hitl/respond', { kind: 'dcw-approval', id: rid, confirmed: true, comment: `E2E:门禁全过,批准 ${toStage}` })
576
- const r = await p
577
- return r.text
578
- }
579
- const s1 = await promoteStage('shadow')
580
- ok('P5d HITL 晋升 shadow', /晋升完成|shadow/.test(s1), s1.slice(0, 140))
581
- const s2 = /晋升完成/.test(s1) ? await promoteStage('production') : ''
582
- ok('P5e HITL 晋升 production', /晋升完成/.test(s2), s2.slice(0, 140))
583
-
584
- const objective = {
585
- schemaVersion: 1, createdAt: new Date().toISOString(), createdBy: 'full-e2e',
586
- objectiveId: 'thickness-50um', targets: { [targetObs.id]: 50 }, weights: { [targetObs.id]: 1 },
587
- controlCosts: {}, horizonSteps: 4, trustRegion: {},
588
- }
589
- const mpc = await invoke('mpc_optimize', { snapshot_id: snapshotId, baseline_controls: baseline, horizon_steps: 4, objective }, workerA)
590
- const rolloutModel = (mpc.text.match(/"rolloutModel":\s*"([^"]+)"/) || [])[1]
591
- const backed = (mpc.text.match(/"rolloutModelBacked":\s*(true|false)/) || [])[1]
592
- const bestCandidate = (mpc.text.match(/"bestCandidate":\s*(\{[^}]*\})/) || [])[1]
593
- ok('P5f MPC 未传 model_id 自动投用 production', rolloutModel === model.id && backed === 'true', `rollout=${rolloutModel} backed=${backed}`)
594
- let best = null
595
- try { best = JSON.parse(bestCandidate ?? 'null') } catch { /* 忽略 */ }
596
- const idToNode = Object.fromEntries((frozen.controls ?? []).map(c => [c.id, c.nodeId]))
597
- let wrote = 0
598
- for (const [specId, value] of Object.entries(best ?? {})) {
599
- const nodeId = idToNode[specId]
600
- if (!nodeId || !Number.isFinite(Number(value))) continue
601
- const w = await callA('POST', `/api/workshop/dcw/${nodeId}/write`, { value })
602
- if (w.status === 200) wrote++
603
- }
604
- ok('P5g MPC 推荐写回 DCW(治理链)', wrote > 0, `wrote=${wrote}`)
605
- await sleep(90000)
606
- const r = await callA('GET', `/api/workshop/daq/${targetObs.nodeId}/samples?bucketMs=1000&limit=60`)
607
- const pts = (r.data?.points ?? []).map(p => Number(p.avg ?? p.value)).filter(Number.isFinite).slice(0, 30)
608
- const mean = pts.length ? pts.reduce((a, b) => a + b, 0) / pts.length : Number.NaN
609
- ok('P5h 写回后 PV 复测(膜厚有读数)', Number.isFinite(mean), `mean=${Number.isFinite(mean) ? mean.toFixed(2) : 'n/a'} μm(目标 50)`)
610
- }
611
- else {
612
- console.log(' ↳ 场景门禁未过 → fail-closed:不发起投用审批、不写 DCW(治理正确行为)')
613
- ok('P5d 门禁未过时 fail-closed(不越级投用)', true)
614
- }
615
- await callA('POST', `/api/workshop/dcw/lines/${twin.lineId}/stop`, {})
616
- }
617
-
618
- /* ═══ 汇总 ═══ */
619
- console.log(`\n═══ 全功能端到端验收:${pass} PASS / ${fails.length} FAIL ═══`)
620
- if (fails.length) console.log(fails.map(f => ` ✖ ${f}`).join('\n'))
621
- console.log(`截图与工件:${SHOTS}`)
622
- console.log(`实例保留:${BASE}(admin ${ADMIN.email} / ${ADMIN.password});模拟器 ${SIM}`)
623
- writeFileSync(join(HOME, 'e2e-summary.json'), JSON.stringify({ pass, fails, base: BASE, sim: SIM, lineId: twin.lineId, recipeId, dataset: ds?.id, model: model?.id }, null, 2))
624
- if (!KEEP) {
625
- console.log('(默认不清理实例,便于人工复核;如需清理请 kill 上述端口进程)')
626
- }
627
- process.exit(fails.length ? 1 : 0)