agentworkshop 0.7.27 → 0.7.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
- package/.AgentWorkShop/prompts/aml-playbook.md +49 -0
- package/.AgentWorkShop/prompts/host-tools.json +314 -0
- package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -0
- package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -0
- package/.output/.AgentWorkShop/prompts/host-tools.json +314 -0
- package/.output/.AgentWorkShop/schema.json +120 -0
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{BTLEvDxM.js → 4bHdIqEg.js} +8 -8
- package/.output/public/_nuxt/B9nXmjSB.js +19 -0
- package/.output/public/_nuxt/BASN8nZ0.js +1 -0
- package/.output/public/_nuxt/{DNQF_TXX.js → BBBtwOpo.js} +1 -1
- package/.output/public/_nuxt/{DoAlYsiF.js → BBwMH_hG.js} +1 -1
- package/.output/public/_nuxt/BWSE6hR6.js +1 -0
- package/.output/public/_nuxt/BZv4RFYN.js +1 -0
- package/.output/public/_nuxt/{BgCrZKv_2.js → Bc0AmjfT.js} +1 -1
- package/.output/public/_nuxt/BcmbLh2z2.js +1 -0
- package/.output/public/_nuxt/BgTB6h_q.js +2 -0
- package/.output/public/_nuxt/BkLJA9J5.js +1 -0
- package/.output/public/_nuxt/{XY2z78rj.js → BuCHayqN.js} +1 -1
- package/.output/public/_nuxt/{0jKrzLuM.js → BuvcLKh1.js} +1 -1
- package/.output/public/_nuxt/C-mDhyEd.js +1 -0
- package/.output/public/_nuxt/{DosOJEmZ2.js → C77oC8yC2.js} +1 -1
- package/.output/public/_nuxt/CQvmN-Mi.js +1 -0
- package/.output/public/_nuxt/CUDrOuW7.js +1 -0
- package/.output/public/_nuxt/{DjU9Dx5Y.js → CZcC-gpk.js} +1 -1
- package/.output/public/_nuxt/{Cz9gD2Yo.js → CbzsPO5H.js} +1 -1
- package/.output/public/_nuxt/CdSOrh2c.js +1 -0
- package/.output/public/_nuxt/Cgx818r-.js +1 -0
- package/.output/public/_nuxt/Cjm7VogC.js +1 -0
- package/.output/public/_nuxt/Cm5mDxzH.js +1 -0
- package/.output/public/_nuxt/Cp6z0RN7.js +1 -0
- package/.output/public/_nuxt/Ct-WOVr4.js +1 -0
- package/.output/public/_nuxt/CwqIxJGj.js +2 -0
- package/.output/public/_nuxt/{BGhOrgle.js → D0fhp-Ga.js} +2 -2
- package/.output/public/_nuxt/DIaTPH1M.js +1 -0
- package/.output/public/_nuxt/DLljr7g0.js +1 -0
- package/.output/public/_nuxt/DTYBfjRY.js +1 -0
- package/.output/public/_nuxt/DYKVPzN-.js +1 -0
- package/.output/public/_nuxt/DZzGarBE2.js +13 -0
- package/.output/public/_nuxt/DaMCzQhv.js +1 -0
- package/.output/public/_nuxt/DoMxCWN52.js +4 -0
- package/.output/public/_nuxt/{CucID8qg2.js → DoTdlVVe2.js} +1 -1
- package/.output/public/_nuxt/DsVcWfyR.js +1 -0
- package/.output/public/_nuxt/{BCJFMBQ6.js → DzuC31-i.js} +2 -2
- package/.output/public/_nuxt/FQri3dV3.js +1 -0
- package/.output/public/_nuxt/Lp7Ll94I.js +1 -0
- package/.output/public/_nuxt/PluginSlot.DmjNbrcX.css +1 -0
- package/.output/public/_nuxt/_id_.hRYo-EAB.css +1 -0
- package/.output/public/_nuxt/_wsId_.gXMEOYgX.css +1 -0
- package/.output/public/_nuxt/agents.BV70ioCv.css +1 -0
- package/.output/public/_nuxt/aml.WU_bh87J.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/adc365b6-f636-4a2b-9527-79819c1e874b.json +1 -0
- package/.output/public/_nuxt/daq.Bb6l44-O.css +1 -0
- package/.output/public/_nuxt/default.jNT73_hq.css +1 -0
- package/.output/public/_nuxt/ekuGmQ7R.js +1 -0
- package/.output/public/_nuxt/entry.jFrFAWuA.css +1 -0
- package/.output/public/_nuxt/pMoIO6rr.js +14 -0
- package/.output/public/_nuxt/pages.Cc8GX9T1.css +1 -0
- package/.output/public/_nuxt/plugins.wIPyfPn-.css +1 -0
- package/.output/public/_nuxt/settings.BCm4NZIc.css +1 -0
- package/.output/public/_nuxt/teams.BC75EGnR.css +1 -0
- package/.output/server/chunks/_/binding-authz.mjs +23 -0
- package/.output/server/chunks/_/binding-authz.mjs.map +1 -0
- package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
- package/.output/server/chunks/_/host-bindings.mjs +1 -1
- package/.output/server/chunks/_/nitro.mjs +15929 -9198
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/_/scene-layout.repo.mjs +3 -3
- package/.output/server/chunks/_/scene-layout.repo.mjs.map +1 -1
- package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs +207 -0
- package/.output/server/chunks/build/Checkbox-eax2M3o-.mjs.map +1 -0
- package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs → OmpTerminalPanel-Cu_s4i0A.mjs} +2 -2
- package/.output/server/chunks/build/{OmpTerminalPanel-Cw_Vw9oO.mjs.map → OmpTerminalPanel-Cu_s4i0A.mjs.map} +1 -1
- package/.output/server/chunks/build/{alert-qJnjyRcP.mjs → PluginSlot-CcR4Ys3T.mjs} +140 -4
- package/.output/server/chunks/build/PluginSlot-CcR4Ys3T.mjs.map +1 -0
- package/.output/server/chunks/build/{TownView-ftIylqiD.mjs → TownView-BdHnAilw.mjs} +5 -5
- package/.output/server/chunks/build/{TownView-ftIylqiD.mjs.map → TownView-BdHnAilw.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-CahfkmEt.mjs → _id_-Cb845FHR.mjs} +7 -5
- package/.output/server/chunks/build/_id_-Cb845FHR.mjs.map +1 -0
- package/.output/server/chunks/build/{_id_-3Axz2-gV.mjs → _id_-fadFPl2i.mjs} +50 -35
- package/.output/server/chunks/build/_id_-fadFPl2i.mjs.map +1 -0
- package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs → _wsId_-CTZswnm5.mjs} +181 -22
- package/.output/server/chunks/build/{_wsId_-BymlQhzS.mjs.map → _wsId_-CTZswnm5.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents-DuMiSWKp.mjs → agents-Bvin73QY.mjs} +82 -32
- package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +1 -0
- package/.output/server/chunks/build/aml-uBNIppIf.mjs +508 -0
- package/.output/server/chunks/build/aml-uBNIppIf.mjs.map +1 -0
- package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs +81 -0
- package/.output/server/chunks/build/apiClient-BwnfOQU8.mjs.map +1 -0
- package/.output/server/chunks/build/{channel-templates-BStqJ-of.mjs → channel-templates-BTq8570n.mjs} +6 -5
- package/.output/server/chunks/build/channel-templates-BTq8570n.mjs.map +1 -0
- package/.output/server/chunks/build/{checkbox-C1gABOca.mjs → checkbox-8fB-wI-T.mjs} +2 -2
- package/.output/server/chunks/build/{checkbox-C1gABOca.mjs.map → checkbox-8fB-wI-T.mjs.map} +1 -1
- package/.output/server/chunks/build/{daq-ChYCABz1.mjs → daq-BvihjQyW.mjs} +111 -109
- package/.output/server/chunks/build/daq-BvihjQyW.mjs.map +1 -0
- package/.output/server/chunks/build/{dcw-CcQNGggh.mjs → dcw-Ks2vJ4PF.mjs} +5 -3
- package/.output/server/chunks/build/dcw-Ks2vJ4PF.mjs.map +1 -0
- package/.output/server/chunks/build/{default-95-zOTPt.mjs → default-GgHt4O2R.mjs} +164 -101
- package/.output/server/chunks/build/{default-95-zOTPt.mjs.map → default-GgHt4O2R.mjs.map} +1 -1
- package/.output/server/chunks/build/{input-number-Bd55elNN.mjs → input-number-DzpyYB99.mjs} +2 -2
- package/.output/server/chunks/build/{input-number-Bd55elNN.mjs.map → input-number-DzpyYB99.mjs.map} +1 -1
- package/.output/server/chunks/build/{logs-D-2UyGtE.mjs → logs-CYBhkQwh.mjs} +5 -3
- package/.output/server/chunks/build/logs-CYBhkQwh.mjs.map +1 -0
- package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs → monitor-CyfDt4nR.mjs} +7 -6
- package/.output/server/chunks/build/{monitor-mfG5jBtz.mjs.map → monitor-CyfDt4nR.mjs.map} +1 -1
- package/.output/server/chunks/build/{pages-Dfosfchr.mjs → pages-C-6BRtv8.mjs} +57 -47
- package/.output/server/chunks/build/pages-C-6BRtv8.mjs.map +1 -0
- package/.output/server/chunks/build/{permissions-B-hhZuzm.mjs → permissions-B52oOmaO.mjs} +6 -5
- package/.output/server/chunks/build/permissions-B52oOmaO.mjs.map +1 -0
- package/.output/server/chunks/build/{plugins-DZR0T4Mh.mjs → plugins-dZRegC7m.mjs} +22 -18
- package/.output/server/chunks/build/plugins-dZRegC7m.mjs.map +1 -0
- package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs → segmented-3TrWo0lS.mjs} +3 -3
- package/.output/server/chunks/build/{segmented-LPPREMtZ.mjs.map → segmented-3TrWo0lS.mjs.map} +1 -1
- package/.output/server/chunks/build/{settings-BajN9TQW.mjs → settings-CgDLkP3s.mjs} +437 -62
- package/.output/server/chunks/build/settings-CgDLkP3s.mjs.map +1 -0
- package/.output/server/chunks/build/{table-Bf1r2JjE.mjs → table-BjSWwmic.mjs} +4 -4
- package/.output/server/chunks/build/{table-Bf1r2JjE.mjs.map → table-BjSWwmic.mjs.map} +1 -1
- package/.output/server/chunks/build/{tag-NO9jEqKy.mjs → tag-DNE9vXc0.mjs} +3 -131
- package/.output/server/chunks/build/tag-DNE9vXc0.mjs.map +1 -0
- package/.output/server/chunks/build/{teams-t2SkRlJP.mjs → teams-2kz3CusY.mjs} +31 -30
- package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-DiCojbN8.mjs → tokens-BbWLqtVz.mjs} +6 -5
- package/.output/server/chunks/build/tokens-BbWLqtVz.mjs.map +1 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs +1 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
- package/.output/server/chunks/build/{town-C7QM8DYK.mjs → town-DJ-V5G9U.mjs} +7 -5
- package/.output/server/chunks/build/town-DJ-V5G9U.mjs.map +1 -0
- package/.output/server/chunks/build/{useDaqStream-BeA2X8KR.mjs → useDaqStream-CIBaiGAl.mjs} +4 -3
- package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +1 -0
- package/.output/server/chunks/build/{useDcwStream-BJW_MitY.mjs → useDcwStream-CBbiYnWe.mjs} +4 -80
- package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +1 -0
- package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs → useDeviceTwins-Yko6nNPF.mjs} +2 -2
- package/.output/server/chunks/build/{useDeviceTwins-Dwz_EY_i.mjs.map → useDeviceTwins-Yko6nNPF.mjs.map} +1 -1
- package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs → useOpsLog-CO_VWh7t.mjs} +2 -2
- package/.output/server/chunks/build/{useOpsLog-Dm8QEb1I.mjs.map → useOpsLog-CO_VWh7t.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs → useWorkshopApi-NyjL0L3j.mjs} +4 -2
- package/.output/server/chunks/build/{useWorkshopApi-B-L3MmIX.mjs.map → useWorkshopApi-NyjL0L3j.mjs.map} +1 -1
- package/.output/server/chunks/build/{users-B9SAdEtH.mjs → users-4nzxTjFT.mjs} +6 -5
- package/.output/server/chunks/build/users-4nzxTjFT.mjs.map +1 -0
- package/.output/server/chunks/build/workshop-81xhz368.mjs +1 -0
- package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +1 -0
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/metrics.mjs +1 -0
- package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -0
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs +1 -0
- package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/i18n.get.mjs +26 -0
- package/.output/server/chunks/routes/api/plugins/i18n.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +2 -1
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +32 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +36 -0
- package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/config.get.mjs +1 -0
- package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.get.mjs +7 -2
- package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.post.mjs +36 -0
- package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/index2.get.mjs +28 -0
- package/.output/server/chunks/routes/api/system/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +2 -1
- package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +2 -1
- package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor.get.mjs +1 -0
- package/.output/server/chunks/routes/api/system/monitor.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/settings/events.get.mjs +8 -5
- package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +2 -1
- package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/users/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/login.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/logout.post.mjs +2 -1
- package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/me.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/register.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/setup-status.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/setup-status.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +2 -1
- package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/_...path_.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/_...path_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +5 -2
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +9 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +23 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +21 -3
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +75 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +46 -0
- package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +47 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +48 -0
- package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +41 -0
- package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +62 -0
- package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +35 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +36 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +34 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +38 -0
- package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +37 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +42 -0
- package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/character/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/devices/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/assets/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/audit.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/caller.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/caller.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/position.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/range.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/stop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/queue.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +4 -4
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +3 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +7 -2
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +32 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +3 -2
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs +12 -6
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs +4 -2
- package/.output/server/chunks/routes/api/workshop/index11.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs +28 -0
- package/.output/server/chunks/routes/api/workshop/index12.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs +17 -11
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs +11 -4
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs +5 -27
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs +24 -18
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs +23 -5
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs +4 -17
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs +8 -3
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs +20 -21
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs +24 -11
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/mailbox.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/memories/maintenance.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/runtime.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/scene/layouts.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/tasks.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +44 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +47 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs +2 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/users/me.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/users/me.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +2 -2
- package/.output/server/chunks/virtual/entry.mjs +601 -36
- package/.output/server/chunks/virtual/entry.mjs.map +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +1 -0
- package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/package.json +84 -0
- package/.output/server/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +225 -0
- package/.output/server/package.json +2 -1
- package/README-zh.md +507 -478
- package/README.md +517 -486
- package/app/app.vue +17 -2
- package/app/assets/css/main.css +421 -30
- package/app/components/AppHeader.vue +17 -0
- package/app/components/AppSidebar.vue +162 -63
- package/app/components/AwChart.vue +57 -54
- package/app/components/workshop/ChannelSessionList.vue +802 -703
- package/app/components/workshop/DaqNodeRow.vue +156 -0
- package/app/components/workshop/PluginSlot.vue +120 -0
- package/app/composables/workshop/useAmlStream.ts +136 -0
- package/app/composables/workshop/useDaqStream.ts +8 -1
- package/app/composables/workshop/usePluginPanels.ts +72 -0
- package/app/composables/workshop/useWorkshopApi.ts +7 -0
- package/app/pages/aml/index.vue +1949 -0
- package/app/pages/daq/[id].vue +60 -2
- package/app/pages/daq/index.vue +7 -148
- package/app/pages/index.vue +235 -213
- package/app/pages/plugins/index.vue +280 -274
- package/app/pages/settings.vue +555 -78
- package/app/pages/workshop/agents.vue +23 -1
- package/app/pages/workshop/teams.vue +2 -2
- package/app/plugins/aw-plugins.client.ts +95 -6
- package/app/plugins/runtime-config.client.ts +4 -14
- package/app/plugins/theme.client.ts +13 -3
- package/app/stores/app.ts +9 -2
- package/app/stores/runtime-config.ts +113 -7
- package/cli/aw.mjs +16 -3
- package/cli/commands/build.mjs +8 -8
- package/cli/commands/dev.mjs +5 -13
- package/cli/commands/init.mjs +1 -1
- package/cli/commands/start.mjs +10 -17
- package/cli/core/args.mjs +85 -4
- package/cli/core/child-lifecycle.mjs +136 -0
- package/config.yml +24 -0
- package/docs/plugins.md +128 -220
- package/docs/sdk.md +1 -1
- package/i18n/dicts/_en.json +43 -2
- package/i18n/dicts/aml.json +163 -0
- package/i18n/dicts/channelSessionList.json +4 -1
- package/i18n/dicts/daqDetail.json +1 -0
- package/i18n/dicts/settings.json +33 -1
- package/i18n/dicts/teams.json +9 -1
- package/i18n/locales/en.ts +364 -132
- package/i18n/locales/zh-CN.ts +433 -201
- package/nuxt.config.ts +18 -3
- package/package.json +153 -149
- package/scripts/_audit/.tmp/audit-data/dcws.json +28 -0
- package/scripts/_audit/.tmp/dcw-writes.json +15650 -0
- package/scripts/_audit/.tmp/dcws.json +9033 -0
- package/scripts/_audit/.tmp/pollution-backup/dcw-rollback.polluted.json +470006 -0
- package/scripts/_audit/.tmp/pollution-backup/dcws.polluted.json +9085 -0
- package/scripts/_audit/.tmp/probe-cwd.txt +1 -0
- package/scripts/_audit/audit-harness-adapters.md +664 -0
- package/scripts/_audit/awhome/commands/README.md +3 -0
- package/scripts/_audit/awhome/commands/hello.mjs +12 -0
- package/scripts/_audit/dcw-controller-e2e.ts +99 -0
- package/scripts/_audit/dcw-flush-cost.ts +43 -0
- package/scripts/_audit/dcw-rollback-ledger.ts +153 -0
- package/scripts/_audit/dcw-unrecorded-write.ts +171 -0
- package/scripts/_audit/dcw-write-mutex.ts +157 -0
- package/scripts/_audit/diag-cwd.ts +20 -0
- package/scripts/_audit/diag-cwd2.ts +19 -0
- package/scripts/_audit/exp-cost-scaling.mjs +54 -0
- package/scripts/_audit/exp-envelope-and-png.mjs +77 -0
- package/scripts/_audit/exp-png-decode.mjs +67 -0
- package/scripts/_audit/exp-retention-plan.mjs +61 -0
- package/scripts/_audit/exp-retention-rescan.mjs +42 -0
- package/scripts/_audit/exp-sweep-fairness.mjs +48 -0
- package/scripts/_audit/hello.mjs +12 -0
- package/scripts/_audit/http-api-authz-audit.md +657 -0
- package/scripts/_audit/ndjson-partial-line-repro.mjs +77 -0
- package/scripts/_audit/opencode-await-ternary-repro.mjs +20 -0
- package/scripts/_audit/part-frag.txt +84 -0
- package/scripts/_audit/part-head.txt +45 -0
- package/scripts/_audit/probe-binding.mjs +103 -0
- package/scripts/_audit/probe-child.mjs +17 -0
- package/scripts/_audit/probe-envelope.mjs +49 -0
- package/scripts/_audit/probe-packlist.mjs +67 -0
- package/scripts/_audit/probe-routes.mjs +47 -0
- package/scripts/_audit/probe-routes2.mjs +38 -0
- package/scripts/_audit/probe.ts +9 -0
- package/scripts/_audit/probe2.ts +6 -0
- package/scripts/_audit/probe3.ts +3 -0
- package/scripts/_audit/probe4.ts +3 -0
- package/scripts/_audit/proj/.AgentWorkShop/commands/echoargs.mjs +13 -0
- package/scripts/_audit/proj/config.yml +1 -0
- package/scripts/_audit/run.mjs +30 -0
- package/scripts/_audit/runtime-audit.md +716 -0
- package/scripts/_audit/ts-resolve-hook.mjs +41 -0
- package/scripts/_audit/tsconfig.probe.json +24 -0
- package/scripts/_audit/typecheck-out.txt +466 -0
- package/scripts/_audit/verify-data-integrity.mjs +112 -0
- package/scripts/_dbg-agents-dropdown-shot.py +33 -0
- package/scripts/_dbg-anim-verify.mjs +1 -1
- package/scripts/_dbg-audit-all-pages.mjs +1 -1
- package/scripts/_dbg-availability-probe.ts +11 -0
- package/scripts/_dbg-bind-bidi-e2e.mjs +1 -1
- package/scripts/_dbg-cf-line-shot.mjs +18 -0
- package/scripts/_dbg-channel-plugin-ui.mjs +94 -0
- package/scripts/_dbg-configroot-audit.mjs +84 -0
- package/scripts/_dbg-crash-recovery.mjs +1 -1
- package/scripts/_dbg-crush-probe.sh +21 -0
- package/scripts/_dbg-crush-spawn-probe.ts +22 -0
- package/scripts/_dbg-daq-acc-probe.mjs +1 -1
- package/scripts/_dbg-daq-attrib.mjs +1 -1
- package/scripts/_dbg-daq-debug.mjs +1 -1
- package/scripts/_dbg-daq-diag.mjs +1 -1
- package/scripts/_dbg-daq-e2e.mjs +1 -1
- package/scripts/_dbg-daq-filter-e2e.mjs +1 -1
- package/scripts/_dbg-daq-filter-e2e2.mjs +1 -1
- package/scripts/_dbg-daq-final-regression.mjs +1 -1
- package/scripts/_dbg-daq-frame-alarm.mjs +1 -1
- package/scripts/_dbg-daq-frame-ui.mjs +1 -1
- package/scripts/_dbg-daq-frame-ws.mjs +1 -1
- package/scripts/_dbg-daq-frames-e2e.mjs +1 -1
- package/scripts/_dbg-daq-full-check.mjs +1 -1
- package/scripts/_dbg-daq-intervals-func.mjs +94 -0
- package/scripts/_dbg-daq-pages-shot.mjs +1 -1
- package/scripts/_dbg-daq-perf.mjs +1 -1
- package/scripts/_dbg-daq-probe.mjs +1 -1
- package/scripts/_dbg-daq-recipe-e2e.mjs +1 -1
- package/scripts/_dbg-daq-rows-probe.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-e2e.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-shot.mjs +1 -1
- package/scripts/_dbg-daq-rowstate-shot2.mjs +1 -1
- package/scripts/_dbg-daq-rowstyle-verify.mjs +112 -0
- package/scripts/_dbg-dash-console-check.mjs +1 -1
- package/scripts/_dbg-dash-deep-probe.mjs +1 -1
- package/scripts/_dbg-dash-hitpoint.mjs +1 -1
- package/scripts/_dbg-dcw-read-rest.mjs +1 -1
- package/scripts/_dbg-dcw-read-ui.mjs +1 -1
- package/scripts/_dbg-dcw-shot2.mjs +1 -1
- package/scripts/_dbg-diag-mock-loop.mjs +89 -0
- package/scripts/_dbg-diag-watch.mjs +95 -0
- package/scripts/_dbg-error-probe.mjs +2 -2
- package/scripts/_dbg-filter-light-verify.mjs +1 -1
- package/scripts/_dbg-final-acceptance-2.mjs +1 -1
- package/scripts/_dbg-final-acceptance.mjs +1 -1
- package/scripts/_dbg-final-full-e2e.mjs +1 -1
- package/scripts/_dbg-final-shots.mjs +32 -0
- package/scripts/_dbg-final-t6-hitl.mjs +1 -1
- package/scripts/_dbg-fix-unused-imports.py +41 -0
- package/scripts/_dbg-fresh-scene-e2e.mjs +1 -1
- package/scripts/_dbg-goose-probe.mjs +33 -0
- package/scripts/_dbg-goose-probe.sh +10 -0
- package/scripts/_dbg-groups-ui-verify.mjs +122 -0
- package/scripts/_dbg-harness-cancel-repro.mjs +81 -0
- package/scripts/_dbg-harness-ui-shot.py +109 -0
- package/scripts/_dbg-hidden-check.mjs +1 -1
- package/scripts/_dbg-home-repro.mjs +1 -1
- package/scripts/_dbg-home-stack.mjs +1 -1
- package/scripts/_dbg-hydration-detail.mjs +1 -1
- package/scripts/_dbg-infra-lifecycle.mjs +1 -1
- package/scripts/_dbg-line-live-e2e.mjs +1 -1
- package/scripts/_dbg-line-repo-test.ts +10 -0
- package/scripts/_dbg-login-debug.py +23 -0
- package/scripts/_dbg-modbus-latency.mjs +22 -0
- package/scripts/_dbg-mqtt-chain-e2e.mjs +1 -1
- package/scripts/_dbg-oneshot-impl-probe.ts +67 -0
- package/scripts/_dbg-opslog-agent-e2e.mjs +5 -2
- package/scripts/_dbg-opt-team-e2e.mjs +1 -1
- package/scripts/_dbg-panesplitter-fix-check.mjs +1 -1
- package/scripts/_dbg-phase-e3-monitor.mjs +1 -1
- package/scripts/_dbg-pi-spawn-probe.ts +33 -0
- package/scripts/_dbg-plc-e2e.mjs +1 -1
- package/scripts/_dbg-plugin-config-ui.mjs +111 -0
- package/scripts/_dbg-plugin-panels-ui.mjs +54 -0
- package/scripts/_dbg-plugin-sink-rest.mjs +1 -1
- package/scripts/_dbg-plugin-sink-ui.mjs +1 -1
- package/scripts/_dbg-plugin-ui-wizard.mjs +1 -1
- package/scripts/_dbg-plugin-verify-e2e.mjs +1 -1
- package/scripts/_dbg-pop-clamp-verify.mjs +1 -1
- package/scripts/_dbg-preview-console.mjs +1 -1
- package/scripts/_dbg-preview-minrepro.mjs +1 -1
- package/scripts/_dbg-preview-pixels.mjs +1 -1
- package/scripts/_dbg-quality-pages-e2e.mjs +1 -1
- package/scripts/_dbg-qwen-acp-probe.mjs +30 -0
- package/scripts/_dbg-qwen-capture.mjs +21 -0
- package/scripts/_dbg-rail-tree-e2e.mjs +1 -1
- package/scripts/_dbg-real-driver-e2e.mjs +1 -1
- package/scripts/_dbg-real-scenario-timeline.log +55 -123
- package/scripts/_dbg-redesign-shots.mjs +1 -1
- package/scripts/_dbg-release-smoke.mjs +1 -1
- package/scripts/_dbg-resolve-probe.ts +6 -0
- package/scripts/_dbg-restart-persist.mjs +1 -1
- package/scripts/_dbg-sc001-dispatch.mjs +1 -1
- package/scripts/_dbg-scenario-final-shot.mjs +1 -1
- package/scripts/_dbg-scenario-phase-e2.mjs +1 -1
- package/scripts/_dbg-scenario-phase-e3.mjs +1 -1
- package/scripts/_dbg-scenario-phase1.mjs +1 -1
- package/scripts/_dbg-scenario-phase2.mjs +1 -1
- package/scripts/_dbg-scenario-phase3-monitor.mjs +1 -1
- package/scripts/_dbg-scenario-phase3.mjs +1 -1
- package/scripts/_dbg-settings-draft-probe.mjs +39 -0
- package/scripts/_dbg-settings-probe.mjs +33 -0
- package/scripts/_dbg-task-cancel-probe.mjs +66 -0
- package/scripts/_dbg-town-alarm-e2e.mjs +1 -1
- package/scripts/_dbg-town-daq-shot.mjs +1 -1
- package/scripts/_dbg-town-full-e2e.mjs +1 -1
- package/scripts/_dbg-town-gate.mjs +1 -1
- package/scripts/_dbg-town-ins-probe.mjs +1 -1
- package/scripts/_dbg-town-perf.mjs +1 -1
- package/scripts/_dbg-town-realtime.mjs +1 -1
- package/scripts/_dbg-town-shot.py +25 -0
- package/scripts/_dbg-town-shot3.mjs +1 -1
- package/scripts/_dbg-town-smoke.mjs +54 -0
- package/scripts/_dbg-town-truth.mjs +1 -1
- package/scripts/_dbg-town-truth2.mjs +1 -1
- package/scripts/_dbg-trend-expand-test.mjs +1 -1
- package/scripts/_dbg-twindaq-focus.mjs +1 -1
- package/scripts/_dbg-ui-polish-shot.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify1.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify2.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify3.mjs +1 -1
- package/scripts/_dbg-ui-polish-verify4.mjs +1 -1
- package/scripts/_dbg-unify-shot.mjs +1 -1
- package/scripts/_dbg-uplink-probe.mjs +1 -1
- package/scripts/_dbg-wizard-preview-shot.mjs +1 -1
- package/scripts/_dbg-wizard-ui-e2e.mjs +1 -1
- package/scripts/_dbg-ws-probe.mjs +1 -1
- package/scripts/_dbg-wsdot-sanity.mjs +1 -1
- package/scripts/_node-state-probe.mjs +1 -1
- package/scripts/_tmp-args-probe.mjs +20 -0
- package/scripts/_tmp-cyc-entry.mjs +8 -0
- package/scripts/_tmp-cyc-main.mjs +5 -0
- package/scripts/_tmp-cyc-mod.mjs +2 -0
- package/scripts/_tmp-cycle-a.mjs +6 -0
- package/scripts/_tmp-cycle-b.mjs +2 -0
- package/scripts/_tmp-cycle-probe.mjs +4 -0
- package/scripts/_tmp-entry-variant.mjs +2 -0
- package/scripts/_tmp-help-probe.mjs +19 -0
- package/scripts/_tmp-help-probe2.mjs +2 -0
- package/scripts/_tmp-trace-preload.mjs +1 -0
- package/scripts/aml-agent-bridge.ts +230 -0
- package/scripts/aml-industrial-loop.ts +232 -0
- package/scripts/aml-ui-smoke.mjs +67 -0
- package/scripts/aw-start-smoke.mjs +194 -0
- package/scripts/design-verify-templates.mjs +1 -1
- package/scripts/device-line-restore.mjs +1 -1
- package/scripts/e2e-aml.ts +259 -0
- package/scripts/e2e-config-groups.mjs +238 -0
- package/scripts/e2e-full-closedloop.mjs +911 -0
- package/scripts/e2e-full-scenario.ts +321 -0
- package/scripts/e2e-harness-consistency.ts +204 -0
- package/scripts/e2e-multi-harness.ts +233 -76
- package/scripts/e2e-plc-plugin-closedloop.mjs +518 -0
- package/scripts/e2e-real-scenario.mjs +466 -452
- package/scripts/e2e-template-isolation.mjs +2 -2
- package/scripts/experiment-castfilm-closedloop.mjs +423 -0
- package/scripts/experiment-castfilm-finish.mjs +194 -0
- package/scripts/experiment-castfilm-ui-shot.mjs +52 -0
- package/scripts/experiment-castfilm-viz.mjs +172 -0
- package/scripts/production-closed-loop-e2e.mjs +78 -29
- package/scripts/test-aml-integration.ts +159 -0
- package/scripts/test-aml-job.ts +174 -0
- package/scripts/test-aml-unit.ts +184 -0
- package/scripts/test-cli-exit.mjs +235 -0
- package/scripts/test-daq-frame-race.mjs +310 -0
- package/scripts/test-data-root.mjs +208 -0
- package/scripts/test-log-flooding.mjs +160 -0
- package/scripts/test-lru.mjs +78 -0
- package/scripts/test-memory-month-query.mjs +62 -0
- package/scripts/test-plugin-hardening.mjs +45 -0
- package/scripts/test-rollback-index.mjs +79 -0
- package/scripts/test-sdk-surface.mjs +155 -0
- package/scripts/three-system-e2e.mjs +662 -448
- package/scripts/town-scene-clear.mjs +1 -1
- package/sdk/client.d.mts +110 -0
- package/sdk/client.mjs +144 -124
- package/sdk/context.mjs +161 -1
- package/sdk/index.d.mts +37 -5
- package/sdk/index.mjs +44 -41
- package/sdk/lifecycle.mjs +4 -1
- package/server/api/plugins/i18n.get.ts +12 -0
- package/server/api/system/config-groups/[id].delete.ts +21 -0
- package/server/api/system/config-groups/[id].patch.ts +26 -0
- package/server/api/system/config-groups/index.get.ts +21 -0
- package/server/api/system/config-groups/index.post.ts +33 -0
- package/server/api/system/settings/events.get.ts +8 -4
- package/server/api/workshop/agent-tools/bindings/[id].delete.ts +6 -1
- package/server/api/workshop/agent-tools/bindings/[id].patch.ts +12 -3
- package/server/api/workshop/agent-tools/bindings/index.get.ts +29 -2
- package/server/api/workshop/agent-tools/invoke.post.ts +30 -5
- package/server/api/workshop/aml/datasets/[id]/preview.get.ts +68 -0
- package/server/api/workshop/aml/datasets/[id].get.ts +24 -0
- package/server/api/workshop/aml/datasets/index.get.ts +20 -0
- package/server/api/workshop/aml/datasets/index.post.ts +27 -0
- package/server/api/workshop/aml/experiments/index.get.ts +35 -0
- package/server/api/workshop/aml/index.get.ts +24 -0
- package/server/api/workshop/aml/jobs/[id]/cancel.post.ts +21 -0
- package/server/api/workshop/aml/jobs/[id]/logs.get.ts +23 -0
- package/server/api/workshop/aml/jobs/[id]/retry.post.ts +20 -0
- package/server/api/workshop/aml/jobs/[id].get.ts +23 -0
- package/server/api/workshop/aml/jobs/index.get.ts +26 -0
- package/server/api/workshop/aml/jobs/index.post.ts +44 -0
- package/server/api/workshop/aml/models/[id]/predict.post.ts +24 -0
- package/server/api/workshop/aml/models/[id]/promote.post.ts +30 -0
- package/server/api/workshop/aml/models/index.get.ts +48 -0
- package/server/api/workshop/daq/[id].delete.ts +6 -0
- package/server/api/workshop/dcw/[id].patch.ts +14 -2
- package/server/api/workshop/hitl/respond.post.ts +3 -1
- package/server/api/workshop/teams/[id]/plugins/index.get.ts +36 -0
- package/server/api/workshop/teams/[id]/plugins/index.put.ts +42 -0
- package/server/api/workshop/teams/index.post.ts +13 -0
- package/server/api/workshop/users/me.get.ts +5 -0
- package/server/api/workshop/ws.ts +14 -2
- package/server/data/daqs.json +1648 -123
- package/server/data/dcw-lines.json +301 -0
- package/server/data/dcw-products.json +140 -0
- package/server/data/dcw-recipes.json +890 -0
- package/server/data/dcw-rollback.json +11591 -5740
- package/server/data/dcw-runs.json +3745 -3559
- package/server/data/dcw-templates.json +120 -0
- package/server/data/dcw-writes.json +1800 -0
- package/server/data/dcws.json +1576 -287
- package/server/data/line-runs.json +137 -27
- package/server/harness/pi-aw-tools.mjs +51 -0
- package/server/plugins/dev-stability-guard.ts +63 -63
- package/server/plugins/system-config.ts +10 -11
- package/server/plugins/workshop.ts +10 -0
- package/server/plugins-builtin/diag-bridge/client.mjs +84 -0
- package/server/plugins-builtin/diag-bridge/i18n.json +72 -0
- package/server/plugins-builtin/diag-bridge/index.mjs +127 -22
- package/server/plugins-builtin/rag-bridge/client.mjs +108 -0
- package/server/plugins-builtin/rag-bridge/i18n.json +60 -0
- package/server/plugins-builtin/rag-bridge/index.mjs +67 -20
- package/server/services/system-config.ts +610 -396
- package/server/services/workshop/agents/adapters/line-spawn.ts +15 -6
- package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +530 -0
- package/server/services/workshop/agents/base-agent.ts +219 -0
- package/server/services/workshop/agents/binding-authz.ts +57 -0
- package/server/services/workshop/agents/claude-agent.ts +546 -30
- package/server/services/workshop/agents/codex-agent.ts +40 -116
- package/server/services/workshop/agents/copilot-agent.ts +136 -0
- package/server/services/workshop/agents/crush-agent.ts +107 -0
- package/server/services/workshop/agents/cursor-agent.ts +102 -0
- package/server/services/workshop/agents/dsh-agent.ts +578 -670
- package/server/services/workshop/agents/gemini-agent.ts +121 -0
- package/server/services/workshop/agents/goose-agent.ts +98 -0
- package/server/services/workshop/agents/harness-models.ts +305 -270
- package/server/services/workshop/agents/hermes-agent.ts +528 -0
- package/server/services/workshop/agents/host-tool-bridge.ts +53 -2
- package/server/services/workshop/agents/industrial-tools.ts +659 -7
- package/server/services/workshop/agents/omp-agent.ts +74 -59
- package/server/services/workshop/agents/opencode-agent.ts +936 -987
- package/server/services/workshop/agents/pi-agent.ts +108 -0
- package/server/services/workshop/agents/qwen-agent.ts +540 -0
- package/server/services/workshop/agents/registry.ts +117 -5
- package/server/services/workshop/agents/tool-approvals.ts +3 -3
- package/server/services/workshop/aml/aml.repo.ts +368 -0
- package/server/services/workshop/aml/clean.ts +120 -0
- package/server/services/workshop/aml/dataset-builder.ts +491 -0
- package/server/services/workshop/aml/gates.ts +121 -0
- package/server/services/workshop/aml/job-orchestrator.ts +650 -0
- package/server/services/workshop/aml/model-registry.ts +169 -0
- package/server/services/workshop/aml/predictor.ts +262 -0
- package/server/services/workshop/aml/python/aml_eval.py +171 -0
- package/server/services/workshop/aml/python/amlkit.py +120 -0
- package/server/services/workshop/aml/python/requirements.txt +7 -0
- package/server/services/workshop/aml/python/train-example.py +92 -0
- package/server/services/workshop/aml/python-runtime.ts +217 -0
- package/server/services/workshop/aml/retention.ts +98 -0
- package/server/services/workshop/aml/runtime.ts +45 -0
- package/server/services/workshop/aml/spec.ts +63 -0
- package/server/services/workshop/aml/stats.ts +140 -0
- package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -1
- package/server/services/workshop/daq/daq-controller.ts +147 -19
- package/server/services/workshop/daq/daq-node.repo.ts +13 -11
- package/server/services/workshop/daq/daq-runtime.ts +11 -0
- package/server/services/workshop/daq/drivers.ts +89 -8
- package/server/services/workshop/db/aml-team-seeds.ts +118 -0
- package/server/services/workshop/db/channel-plugins.repo.ts +27 -1
- package/server/services/workshop/db/database.ts +89 -1
- package/server/services/workshop/db/memory.repo.ts +31 -0
- package/server/services/workshop/db/user.repo.ts +9 -0
- package/server/services/workshop/dcw/dcw-controller.ts +33 -7
- package/server/services/workshop/dcw/dcw-line.repo.ts +5 -3
- package/server/services/workshop/dcw/dcw-node.repo.ts +4 -4
- package/server/services/workshop/dcw/dcw-product.repo.ts +8 -8
- package/server/services/workshop/dcw/dcw-recipe.repo.ts +6 -7
- package/server/services/workshop/dcw/dcw-runtime.ts +16 -2
- package/server/services/workshop/dcw/dcw-templates.ts +4 -4
- package/server/services/workshop/dcw/line-run.ts +5 -5
- package/server/services/workshop/dcw/recipe-rollback-manager.ts +3 -1
- package/server/services/workshop/dcw/recipe-rollback.repo.ts +155 -52
- package/server/services/workshop/logger.ts +145 -3
- package/server/services/workshop/plugins/host.mjs +854 -566
- package/server/services/workshop/prompts/loader.ts +32 -6
- package/server/services/workshop/runtime/agent-runtime.ts +32 -3
- package/server/services/workshop/runtime/manager.ts +53 -13
- package/server/services/workshop/runtime/scheduler-loop.ts +18 -1
- package/server/services/workshop/scene/scene-layout.repo.ts +5 -5
- package/server/services/workshop/settings.ts +64 -0
- package/shared/config/engine.mjs +5 -0
- package/shared/config/groups.mjs +220 -0
- package/shared/config/home.mjs +11 -2
- package/shared/config/schema.json +31 -6
- package/shared/daq-protocol.ts +6 -0
- package/shared/lru.mjs +94 -0
- package/shared/workshop-protocol.ts +2 -2
- package/.output/public/_nuxt/2jaJHWIJ.js +0 -1
- package/.output/public/_nuxt/B8kt898d.js +0 -1
- package/.output/public/_nuxt/BFGpEo8S.js +0 -1
- package/.output/public/_nuxt/BG4zduPf.js +0 -14
- package/.output/public/_nuxt/BHcpzI2n.js +0 -19
- package/.output/public/_nuxt/BWyR3awA.js +0 -1
- package/.output/public/_nuxt/Bc89zKq2.js +0 -1
- package/.output/public/_nuxt/BetmGSO4.js +0 -1
- package/.output/public/_nuxt/BowTbasd.js +0 -1
- package/.output/public/_nuxt/BvtknqSC2.js +0 -1
- package/.output/public/_nuxt/BytVi9VX2.js +0 -4
- package/.output/public/_nuxt/CJviSvm-.js +0 -1
- package/.output/public/_nuxt/CTfqWGdy.js +0 -1
- package/.output/public/_nuxt/Cb3SnTM8.js +0 -1
- package/.output/public/_nuxt/Chc5pfAA.js +0 -1
- package/.output/public/_nuxt/CobSUzQv.js +0 -2
- package/.output/public/_nuxt/D95h62Jn.js +0 -1
- package/.output/public/_nuxt/DGAOugLt.js +0 -1
- package/.output/public/_nuxt/DHbTyoAV.js +0 -1
- package/.output/public/_nuxt/DfLUN8kY.js +0 -1
- package/.output/public/_nuxt/DnziMlcX.js +0 -1
- package/.output/public/_nuxt/DvgKXPgu2.js +0 -13
- package/.output/public/_nuxt/Q_SJDSgx.js +0 -1
- package/.output/public/_nuxt/_id_.DdbYeLqn.css +0 -1
- package/.output/public/_nuxt/_wsId_.BqWBlY7X.css +0 -1
- package/.output/public/_nuxt/agents.CB9Ck7VQ.css +0 -1
- package/.output/public/_nuxt/bFnZa2yd.js +0 -1
- package/.output/public/_nuxt/builds/meta/f7a8e33d-5422-45ac-895d-27168f97e3ad.json +0 -1
- package/.output/public/_nuxt/daq.DGV9QS8d.css +0 -1
- package/.output/public/_nuxt/default.BbgdTDCk.css +0 -1
- package/.output/public/_nuxt/entry.BN02X8iR.css +0 -1
- package/.output/public/_nuxt/pages.CG8UJ2TK.css +0 -1
- package/.output/public/_nuxt/plugins.DpCuwaJt.css +0 -1
- package/.output/public/_nuxt/rkVgzg62.js +0 -1
- package/.output/public/_nuxt/settings.W6qrYAui.css +0 -1
- package/.output/public/_nuxt/teams.BBXVkyKq.css +0 -1
- package/.output/server/chunks/build/_id_-3Axz2-gV.mjs.map +0 -1
- package/.output/server/chunks/build/_id_-CahfkmEt.mjs.map +0 -1
- package/.output/server/chunks/build/agents-DuMiSWKp.mjs.map +0 -1
- package/.output/server/chunks/build/alert-qJnjyRcP.mjs.map +0 -1
- package/.output/server/chunks/build/channel-templates-BStqJ-of.mjs.map +0 -1
- package/.output/server/chunks/build/daq-ChYCABz1.mjs.map +0 -1
- package/.output/server/chunks/build/dcw-CcQNGggh.mjs.map +0 -1
- package/.output/server/chunks/build/logs-D-2UyGtE.mjs.map +0 -1
- package/.output/server/chunks/build/pages-Dfosfchr.mjs.map +0 -1
- package/.output/server/chunks/build/permissions-B-hhZuzm.mjs.map +0 -1
- package/.output/server/chunks/build/plugins-DZR0T4Mh.mjs.map +0 -1
- package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs +0 -78
- package/.output/server/chunks/build/responsiveObserve-CS0UB6wQ.mjs.map +0 -1
- package/.output/server/chunks/build/settings-BajN9TQW.mjs.map +0 -1
- package/.output/server/chunks/build/tag-NO9jEqKy.mjs.map +0 -1
- package/.output/server/chunks/build/teams-t2SkRlJP.mjs.map +0 -1
- package/.output/server/chunks/build/tokens-DiCojbN8.mjs.map +0 -1
- package/.output/server/chunks/build/town-C7QM8DYK.mjs.map +0 -1
- package/.output/server/chunks/build/useDaqStream-BeA2X8KR.mjs.map +0 -1
- package/.output/server/chunks/build/useDcwStream-BJW_MitY.mjs.map +0 -1
- package/.output/server/chunks/build/users-B9SAdEtH.mjs.map +0 -1
- /package/.output/public/_nuxt/{ORt9oDIy.js → ORt9oDIy2.js} +0 -0
|
@@ -19,10 +19,20 @@ import { daqRuntimeSettings } from '../settings'
|
|
|
19
19
|
import { getDaqNodeRepo } from '../daq/daq-node.repo'
|
|
20
20
|
import { findDaqTemplate } from '../daq/daq-templates'
|
|
21
21
|
import { getRecipeRollBackManager } from '../dcw/recipe-rollback-manager'
|
|
22
|
-
import { getOps } from '../ops/ops'
|
|
22
|
+
import { getOps, recordOps } from '../ops/ops'
|
|
23
23
|
import { getDcwLineRepo } from '../dcw/dcw-line.repo'
|
|
24
24
|
import { getDcwProductRepo } from '../dcw/dcw-product.repo'
|
|
25
25
|
import { getDcwRecipeRepo } from '../dcw/dcw-recipe.repo'
|
|
26
|
+
import { readFileSync } from 'node:fs'
|
|
27
|
+
import { join } from 'node:path'
|
|
28
|
+
import { getAmlRuntime } from '../aml/runtime'
|
|
29
|
+
import { parseDatasetSpec } from '../aml/spec'
|
|
30
|
+
import { buildDataset, type AmlDatasetReport } from '../aml/dataset-builder'
|
|
31
|
+
import { cancelJob, jobLogsTail, runtimeStatus, submitJob } from '../aml/job-orchestrator'
|
|
32
|
+
import { transitionModel } from '../aml/model-registry'
|
|
33
|
+
import { predictProduction, readIoSpecFor } from '../aml/predictor'
|
|
34
|
+
import { alignToGrid } from '../aml/clean'
|
|
35
|
+
import type { AmlDatasetRow, AmlJobRow } from '../aml/aml.repo'
|
|
26
36
|
|
|
27
37
|
export async function toolMyIndustrialNodes(agentId: string): Promise<{ text: string }> {
|
|
28
38
|
const repo = getAgentNodeBindingRepo()
|
|
@@ -352,8 +362,35 @@ export async function toolDaqQuery(agentId: string, args: {
|
|
|
352
362
|
return { text: `数采数据查询结果(${targets.length} 个节点):\n\n${sections.join('\n\n')}${prov}\n\n数值均为经标定钩子处理后的真实物理量纲;调整工艺前请结合 my_industrial_nodes 的节点判读方法与操作守则。` }
|
|
353
363
|
}
|
|
354
364
|
|
|
365
|
+
/**
|
|
366
|
+
* 写向工具的统一鉴权闸门(绑定必查)。
|
|
367
|
+
*
|
|
368
|
+
* 背景:dcw_control / dcw_read 各自抄了一份 `repo.find(agentId, nodeId, 'dcw')` 判定,
|
|
369
|
+
* 而 dcw_rollback / dcw_judge 的「接管孤儿记录」分支忘了这一步 —— 任何 agent(哪怕
|
|
370
|
+
* 零绑定)都能借 record_id 或超时接管,驱动真实 PLC 执行回退。这是权限模型里的
|
|
371
|
+
* **默认放行**,与 node-bindings.repo 自述的「未绑定节点一律拒绝」直接冲突。
|
|
372
|
+
* 收敛为单一入口后,新增写向工具不会再漏。
|
|
373
|
+
*
|
|
374
|
+
* @returns 命中返回绑定对象;未命中返回可直接回给模型的拒绝文本(isError)
|
|
375
|
+
*/
|
|
376
|
+
function requireDcwBinding(agentId: string, nodeId: string, action: string): { binding: AgentNodeBinding } | { error: { text: string, isError: true } } {
|
|
377
|
+
const repo = getAgentNodeBindingRepo()
|
|
378
|
+
const binding = nodeId ? repo.find(agentId, nodeId, 'dcw') : undefined
|
|
379
|
+
if (binding) return { binding }
|
|
380
|
+
const mine = repo.byAgent(agentId).filter(b => b.kind === 'dcw')
|
|
381
|
+
return {
|
|
382
|
+
error: {
|
|
383
|
+
text: mine.length
|
|
384
|
+
? `无权${action}节点 ${nodeId || '(空)'}。你有权控制的数控节点:${mine.map(b => b.nodeId).join(', ')}(可用 my_industrial_nodes 查看物理含义)。`
|
|
385
|
+
: `你尚未绑定任何数控节点,无权${action}。请在数字孪生界面绑定数控节点。`,
|
|
386
|
+
isError: true,
|
|
387
|
+
},
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
355
391
|
/** 工具:dcw_judge —— 对自己的优化记录落判定(keep/rollback/uncertain)。
|
|
356
|
-
* 判定与执行分离:rollback 判定只入册,执行必须再调 dcw_rollback。
|
|
392
|
+
* 判定与执行分离:rollback 判定只入册,执行必须再调 dcw_rollback。
|
|
393
|
+
* 鉴权:记录所属节点必须仍在你的 dcw 绑定内 —— 接管孤儿记录同样受此约束。 */
|
|
357
394
|
export async function toolDcwJudge(agentId: string, args: { record_id?: string, verdict?: string, reason?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
358
395
|
const recordId = String(args.record_id ?? '').trim()
|
|
359
396
|
const verdict = String(args.verdict ?? '').trim() as 'keep' | 'rollback' | 'uncertain'
|
|
@@ -371,6 +408,9 @@ export async function toolDcwJudge(agentId: string, args: { record_id?: string,
|
|
|
371
408
|
const takeover = record.agentId !== agentId && rb.isStale(record)
|
|
372
409
|
if (record.agentId !== agentId && !takeover)
|
|
373
410
|
return { text: `记录 ${recordId} 不是你发起的优化(发起者:${record.agentId ?? '用户'}),Agent 仅可判定自己的记录;他人记录请请用户在界面判定。`, isError: true }
|
|
411
|
+
// 接管是「时间」判定,不是「权限」判定 —— 权限必须单独查绑定(早先漏了这一步)
|
|
412
|
+
const auth = requireDcwBinding(agentId, record.nodeId, '判定该记录')
|
|
413
|
+
if ('error' in auth) return auth.error
|
|
374
414
|
try {
|
|
375
415
|
const finalReason = takeover ? `[接管孤儿记录,原属主 ${record.agentId ?? '?'} 超时未判定] ${reason}` : reason
|
|
376
416
|
const updated = rb.judge(recordId, verdict, finalReason, 'agent', agentId, { takeover, actorName: agentBadgeLabel(agentId) })
|
|
@@ -387,6 +427,8 @@ export async function toolDcwJudge(agentId: string, args: { record_id?: string,
|
|
|
387
427
|
}
|
|
388
428
|
|
|
389
429
|
/** 工具:dcw_rollback —— 执行回退(自己的记录直接执行;他人记录需用户在界面执行)。
|
|
430
|
+
* 鉴权:节点必须绑定给该 agent(record_id 路径先解析出 record.nodeId);
|
|
431
|
+
* manual 模式绑定与 dcw_control 同源 —— 回退也会改 PLC,必须推请用户确认。
|
|
390
432
|
* args: record_id(回退该记录到其 from 值)或 node_id(单步撤销到最近稳定锚);to = 指定目标锚。 */
|
|
391
433
|
export async function toolDcwRollback(agentId: string, args: { record_id?: string, node_id?: string, to?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
392
434
|
const rb = getRecipeRollBackManager()
|
|
@@ -396,17 +438,39 @@ export async function toolDcwRollback(agentId: string, args: { record_id?: strin
|
|
|
396
438
|
if (!recordId && !nodeId)
|
|
397
439
|
return { text: 'record_id 或 node_id 至少提供一个。', isError: true }
|
|
398
440
|
try {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
441
|
+
// 归属解析:record_id 路径的节点来自记录本身,node_id 路径直接用入参
|
|
442
|
+
const record = recordId ? rb.recordById(recordId) : undefined
|
|
443
|
+
if (recordId && !record)
|
|
444
|
+
return { text: `优化记录 ${recordId} 不存在。`, isError: true }
|
|
445
|
+
const targetNodeId = record?.nodeId ?? nodeId
|
|
446
|
+
if (record) {
|
|
403
447
|
const takeover = record.agentId !== agentId && rb.isStale(record)
|
|
404
448
|
if (record.agentId !== agentId && !takeover)
|
|
405
449
|
return { text: `记录 ${recordId} 不是你发起的优化(发起者:${record.agentId ?? '用户'}),回退他人记录请请用户在数采中心/产线详情执行;若原属主已消失(超时未判定),可先 dcw_judge 接管后再回退。`, isError: true }
|
|
450
|
+
}
|
|
451
|
+
// 授权闸门(早先整段缺失 → 任意 agent 可回退任意节点)
|
|
452
|
+
const auth = requireDcwBinding(agentId, targetNodeId, '回退')
|
|
453
|
+
if ('error' in auth) return auth.error
|
|
454
|
+
// manual 模式:回退是真实 PLC 写入,与 dcw_control 同源推请用户批准
|
|
455
|
+
if (auth.binding.mode === 'manual') {
|
|
456
|
+
const node = getDcwController().byId(targetNodeId)
|
|
457
|
+
const approvals = getToolApprovals()
|
|
458
|
+
if (approvals.hasPendingFor(agentId, targetNodeId))
|
|
459
|
+
return { text: '你对该节点已有一条待审批指令,请等待用户处理后再发新的回退请求(避免审批堆积)。', isError: true }
|
|
460
|
+
const detail = `${node?.name ?? targetNodeId} 回退到${record ? `记录 ${recordId} 的 from 值` : '最近稳定锚'}${to ? `(${to})` : ''}`
|
|
461
|
+
const ap = await approvals.request(agentId, targetNodeId, 'dcw', detail)
|
|
462
|
+
if (!ap.approved) {
|
|
463
|
+
return { text: `回退未执行:用户${ap.comment.includes('超时') ? '未在时限内批准(超时)' : '拒绝了本次回退'}。用户备注:${ap.comment || '(无)'}` }
|
|
464
|
+
}
|
|
465
|
+
// 审批期间绑定可能已被解除:批准时二次校验(与 dcw_control 同口径)
|
|
466
|
+
if (!getAgentNodeBindingRepo().find(agentId, targetNodeId, 'dcw'))
|
|
467
|
+
return { text: '回退未执行:审批通过时你的该节点绑定已被解除(权限在批准时失效)。', isError: true }
|
|
468
|
+
}
|
|
469
|
+
if (record) {
|
|
406
470
|
const fresh = await rb.rollbackRecord(recordId, agentId, 'agent', undefined, { actorName: agentBadgeLabel(agentId) })
|
|
407
471
|
return { text: `回退已执行:记录 ${recordId} 标记 rolled-back;下发恢复值 ${fresh?.params[0]?.to}${'(以回读为准)'};新回退记录 ${fresh?.id} 已入册。请 daq_query 复测确认恢复。` }
|
|
408
472
|
}
|
|
409
|
-
const fresh = await rb.rollbackNode(
|
|
473
|
+
const fresh = await rb.rollbackNode(targetNodeId, agentId, 'agent', to, { actorName: agentBadgeLabel(agentId) })
|
|
410
474
|
return { text: `节点单步回退已执行:恢复到最近稳定锚值;新回退记录 ${fresh?.id} 已入册。请 daq_query 复测确认恢复。` }
|
|
411
475
|
}
|
|
412
476
|
catch (err) {
|
|
@@ -868,3 +932,591 @@ export async function toolRecipeRollback(agentId: string, args: {
|
|
|
868
932
|
return { text: `回退失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
|
|
869
933
|
}
|
|
870
934
|
}
|
|
935
|
+
|
|
936
|
+
// ================================================================
|
|
937
|
+
// AML 自动建模工具族(aml_*):数据集 → 训练作业 → 实验谱系 → 模型晋升 → 影子参考
|
|
938
|
+
// 权限模型:数据集构建节点级鉴权(daq 绑定,只缩不放)+ 归属产线一致;晋升走 HITL 人工审批;
|
|
939
|
+
// 作业提交/取消按 agentId 归因( submitJob 内部已记 ops,工具层不重复记提交动作)。
|
|
940
|
+
// ================================================================
|
|
941
|
+
|
|
942
|
+
/** recordOps 的 AML 分类(与 job-orchestrator/model-registry 的 kind='aml' 同源;仓储联合类型暂未列 'aml',此处收口断言) */
|
|
943
|
+
const AML_AUDIT_KIND = 'aml' as unknown as 'system'
|
|
944
|
+
|
|
945
|
+
function amlErr(text: string): { text: string, isError: true } {
|
|
946
|
+
return { text, isError: true }
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/** 数值展示(4 位有效小数;空值统一 '-') */
|
|
950
|
+
function fmtAmlNum(v: number | null | undefined, digits = 4): string {
|
|
951
|
+
if (v == null || !Number.isFinite(v)) return '-'
|
|
952
|
+
return String(Number(v.toFixed(digits)))
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
function amlNodeName(nodeId: string): string {
|
|
956
|
+
return getDaqNodeRepo().byId(nodeId)?.name ?? nodeId
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
function amlNodeUnit(nodeId: string): string {
|
|
960
|
+
const n = getDaqNodeRepo().byId(nodeId)
|
|
961
|
+
return n?.unit ?? findDaqTemplate(n?.templateKey ?? '')?.unit ?? ''
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/** 数据集构建报告惰性读(report.json 与 manifest 同目录) */
|
|
965
|
+
function amlReportOf(dataset: AmlDatasetRow): AmlDatasetReport | null {
|
|
966
|
+
try {
|
|
967
|
+
return JSON.parse(readFileSync(join(dataset.path, 'report.json'), 'utf8')) as AmlDatasetReport
|
|
968
|
+
}
|
|
969
|
+
catch {
|
|
970
|
+
return null
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/** 门禁报告 → 逐项文本(解析失败降级为原始串) */
|
|
975
|
+
function amlGatesLines(gatesJson: string | null): string {
|
|
976
|
+
if (!gatesJson) return ''
|
|
977
|
+
try {
|
|
978
|
+
const g = JSON.parse(gatesJson) as { checks?: Array<{ id: string, name: string, value: number | null, threshold: number | null, pass: boolean, detail: string }> }
|
|
979
|
+
if (!g.checks?.length) return ''
|
|
980
|
+
return g.checks
|
|
981
|
+
.map(c => ` ${c.id} ${c.pass ? '✓' : '✗'} ${c.name}: ${c.detail}`)
|
|
982
|
+
.join('\n')
|
|
983
|
+
}
|
|
984
|
+
catch {
|
|
985
|
+
return ` (门禁数据解析失败) ${gatesJson.slice(0, 120)}`
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/** 作业行 → 详情卡片(状态/阶段/进度/指标/门禁逐项/错误) */
|
|
990
|
+
function amlJobCard(job: AmlJobRow): string {
|
|
991
|
+
const gates = amlGatesLines(job.gatesJson)
|
|
992
|
+
let metrics = ''
|
|
993
|
+
try {
|
|
994
|
+
const m = JSON.parse(job.metricsJson ?? '{}') as { oneStepVal?: { windows?: number, nrmse?: number } | null, oneStepTest?: { windows?: number, nrmse?: number } | null, rolloutTest?: { windows?: number, nrmse?: number, horizon?: number } | null }
|
|
995
|
+
const parts: string[] = []
|
|
996
|
+
if (m.oneStepVal) parts.push(`单步验证 NRMSE=${fmtAmlNum(m.oneStepVal.nrmse)}(${m.oneStepVal.windows ?? '?'} 窗)`)
|
|
997
|
+
if (m.oneStepTest) parts.push(`单步测试 NRMSE=${fmtAmlNum(m.oneStepTest.nrmse)}(${m.oneStepTest.windows ?? '?'} 窗)`)
|
|
998
|
+
if (m.rolloutTest) parts.push(`滚动测试 NRMSE=${fmtAmlNum(m.rolloutTest.nrmse)}(horizon=${m.rolloutTest.horizon ?? '?'})`)
|
|
999
|
+
metrics = parts.join(' | ')
|
|
1000
|
+
}
|
|
1001
|
+
catch { /* 无指标 */ }
|
|
1002
|
+
return [
|
|
1003
|
+
`■ 作业 ${job.id}`,
|
|
1004
|
+
` 状态 ${job.status} | 阶段 ${job.stage || '-'} | 进度 ${job.progress}% | purpose=${job.purpose}`,
|
|
1005
|
+
` dataset: ${job.datasetId} | 提交者: ${job.agentId || '-'} | 重试 ${job.retryCount}/2`,
|
|
1006
|
+
` 创建 ${job.createdAt.slice(0, 19).replace('T', ' ')}${job.startedAt ? ` | 开跑 ${job.startedAt.slice(0, 19).replace('T', ' ')}` : ''}${job.endedAt ? ` | 结束 ${job.endedAt.slice(0, 19).replace('T', ' ')}` : ''}`,
|
|
1007
|
+
metrics ? ` 指标: ${metrics}` : null,
|
|
1008
|
+
gates ? ` 门禁逐项:\n${gates}` : ' 门禁: 未产出(作业未完成评估)',
|
|
1009
|
+
job.error ? ` 错误: ${job.error}` : null,
|
|
1010
|
+
].filter(x => x !== null).join('\n')
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/** 工具:aml_node_catalog —— 我可用的 AML 建模节点(daq 绑定面;物理语义 + 近 24h 批次数据可用性) */
|
|
1014
|
+
export async function toolAmlNodeCatalog(agentId: string): Promise<{ text: string }> {
|
|
1015
|
+
const bindings = getAgentNodeBindingRepo().byAgent(agentId).filter(b => b.kind === 'daq')
|
|
1016
|
+
if (bindings.length === 0) {
|
|
1017
|
+
return { text: '你尚未绑定任何数采节点,AML 自动建模工具不可用(数据集构建要求所用节点均有你的 daq 绑定,绑定只缩不放)。请在数字孪生界面绑定数采节点后重试。' }
|
|
1018
|
+
}
|
|
1019
|
+
const { getTsdb, tsdbReady } = await import('../daq/storage')
|
|
1020
|
+
await tsdbReady
|
|
1021
|
+
const tsdb = getTsdb()
|
|
1022
|
+
const from24h = Date.now() - 24 * 3_600_000
|
|
1023
|
+
const cards: string[] = []
|
|
1024
|
+
for (const b of bindings) {
|
|
1025
|
+
const node = getDaqNodeRepo().byId(b.nodeId)
|
|
1026
|
+
if (!node) continue
|
|
1027
|
+
const tpl = findDaqTemplate(node.templateKey)
|
|
1028
|
+
let dataTag = '近 24h 无批次数据(产线未运行?建模前先确认采集)'
|
|
1029
|
+
try {
|
|
1030
|
+
const pts = await tsdb.query(b.nodeId, { fromMs: from24h, toMs: Date.now(), limit: 1 })
|
|
1031
|
+
if (pts.length > 0) dataTag = '近 24h 有批次打标数据(可建模)'
|
|
1032
|
+
}
|
|
1033
|
+
catch { /* 时序库异常按无数据处理 */ }
|
|
1034
|
+
const lineTxt = node.lineId
|
|
1035
|
+
? `${getDcwLineRepo().byId(node.lineId)?.name ?? node.lineId}(${node.lineId})`
|
|
1036
|
+
: '未分配产线(无批次打标,不能参与建模)'
|
|
1037
|
+
cards.push(
|
|
1038
|
+
`■ ${node.name} · node_id=${node.id}\n`
|
|
1039
|
+
+ ` 物理量 ${tpl?.ch ?? node.templateKey} | 单位 ${node.unit} | 正常量程 ${node.min}~${node.max}${node.unit}\n`
|
|
1040
|
+
+ ` 产线: ${lineTxt} | 数据: ${dataTag}${tpl?.semantics ? `\n 语义: ${tpl.semantics.slice(0, 160)}` : ''}`,
|
|
1041
|
+
)
|
|
1042
|
+
}
|
|
1043
|
+
return {
|
|
1044
|
+
text: `你可用的 AML 建模节点(${cards.length} 个 daq 绑定):\n\n${cards.join('\n\n')}\n\n---\n建模路径:aml_dataset_build(选 control/target 节点组数据集)→ aml_job_submit(提交训练代码)→ aml_job_status / aml_job_logs 轮询 → aml_leaderboard 看实验谱系 → aml_model_promote(lead 专属,人工审批)→ aml_model_reference(调参前查影子参考)。\nrole 语义:control=可控输入(未来轨迹已知)/ target=预测目标(必选 ≥1)/ feature=仅历史特征。`,
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
/** 工具:aml_dataset_build —— 组建训练数据集(节点级鉴权:daq 绑定 + 归属产线一致;隔离三元组防配方串味) */
|
|
1049
|
+
export async function toolAmlDatasetBuild(agentId: string, args: {
|
|
1050
|
+
line_id?: string
|
|
1051
|
+
product_id?: string
|
|
1052
|
+
recipe_id?: string
|
|
1053
|
+
nodes?: Array<{ node_id?: string, role?: string }>
|
|
1054
|
+
beat_ms?: number | string
|
|
1055
|
+
history_steps?: number | string
|
|
1056
|
+
horizon_steps?: number | string
|
|
1057
|
+
split_seed?: number | string
|
|
1058
|
+
val_ratio?: number | string
|
|
1059
|
+
test_ratio?: number | string
|
|
1060
|
+
purpose?: string
|
|
1061
|
+
note?: string
|
|
1062
|
+
run_ids?: string[]
|
|
1063
|
+
from_ms?: number | string
|
|
1064
|
+
to_ms?: number | string
|
|
1065
|
+
}): Promise<{ text: string, isError?: boolean }> {
|
|
1066
|
+
const lineId = String(args.line_id ?? '').trim()
|
|
1067
|
+
const productId = String(args.product_id ?? '').trim()
|
|
1068
|
+
const recipeId = String(args.recipe_id ?? '').trim()
|
|
1069
|
+
if (!lineId || !productId || !recipeId) {
|
|
1070
|
+
return amlErr('line_id / product_id / recipe_id 必填(隔离三元组,防配方串味;line_context 可查看当前批次的三个 id)。')
|
|
1071
|
+
}
|
|
1072
|
+
const beatMs = Number(args.beat_ms)
|
|
1073
|
+
const historySteps = Number(args.history_steps)
|
|
1074
|
+
const horizonSteps = Number(args.horizon_steps)
|
|
1075
|
+
if (!Number.isInteger(beatMs) || beatMs < 1000) return amlErr('beat_ms 必须为 ≥1000 的整数(数据对齐节拍,ms)。')
|
|
1076
|
+
if (!Number.isInteger(historySteps) || historySteps < 1 || historySteps > 2048) return amlErr('history_steps 必须为 1~2048 的整数(历史窗口步数)。')
|
|
1077
|
+
if (!Number.isInteger(horizonSteps) || horizonSteps < 1 || horizonSteps > 512) return amlErr('horizon_steps 必须为 1~512 的整数(预测步长)。')
|
|
1078
|
+
const nodes = (Array.isArray(args.nodes) ? args.nodes : [])
|
|
1079
|
+
.map(n => ({ nodeId: String(n?.node_id ?? '').trim(), role: String(n?.role ?? '').trim() }))
|
|
1080
|
+
.filter(n => n.nodeId)
|
|
1081
|
+
if (nodes.length < 2) return amlErr('nodes 至少 2 项({node_id, role}),且必须含 1 个 target(预测目标)。')
|
|
1082
|
+
if (nodes.some(n => !['control', 'feature', 'target'].includes(n.role))) return amlErr('nodes 的 role 必须为 control / feature / target。')
|
|
1083
|
+
if (!nodes.some(n => n.role === 'target')) return amlErr('nodes 必须含至少 1 个 target 节点(预测目标)。')
|
|
1084
|
+
// 鉴权:每个节点都要有该 Agent 的 daq 绑定,且归属参数给定的产线(绑定只缩不放)
|
|
1085
|
+
const repo = getAgentNodeBindingRepo()
|
|
1086
|
+
const daqBound = repo.byAgent(agentId).filter(b => b.kind === 'daq')
|
|
1087
|
+
for (const n of nodes) {
|
|
1088
|
+
if (!daqBound.some(b => b.nodeId === n.nodeId)) {
|
|
1089
|
+
return amlErr(`无权使用节点 ${n.nodeId}(无你的 daq 绑定;绑定只缩不放)。你有权访问的数采节点:${daqBound.map(b => b.nodeId).join(', ') || '(无)'},可先 aml_node_catalog 查看语义。`)
|
|
1090
|
+
}
|
|
1091
|
+
const nodeLine = getDaqNodeRepo().byId(n.nodeId)?.lineId ?? ''
|
|
1092
|
+
if (nodeLine !== lineId) {
|
|
1093
|
+
return amlErr(`节点 ${amlNodeName(n.nodeId)}(${n.nodeId})归属产线 ${nodeLine || '未分配'},与 line_id=${lineId} 不一致;数据集节点必须全部归属同一条产线(绑定只缩不放)。`)
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
|
|
1097
|
+
try {
|
|
1098
|
+
const spec = parseDatasetSpec({
|
|
1099
|
+
lineId,
|
|
1100
|
+
productId,
|
|
1101
|
+
recipeId,
|
|
1102
|
+
runIds: Array.isArray(args.run_ids) ? args.run_ids.map(r => String(r)).filter(Boolean) : undefined,
|
|
1103
|
+
nodes: nodes.map(n => ({ nodeId: n.nodeId, role: n.role as 'control' | 'feature' | 'target' })),
|
|
1104
|
+
fromMs: Number(args.from_ms) || undefined,
|
|
1105
|
+
toMs: Number(args.to_ms) || undefined,
|
|
1106
|
+
beatMs,
|
|
1107
|
+
window: { historySteps, horizonSteps },
|
|
1108
|
+
split: {
|
|
1109
|
+
valRatio: Number.isFinite(Number(args.val_ratio)) ? Number(args.val_ratio) : 0.15,
|
|
1110
|
+
testRatio: Number.isFinite(Number(args.test_ratio)) ? Number(args.test_ratio) : 0.15,
|
|
1111
|
+
seed: Number.isFinite(Number(args.split_seed)) ? Math.trunc(Number(args.split_seed)) : 42,
|
|
1112
|
+
},
|
|
1113
|
+
purpose,
|
|
1114
|
+
note: args.note ? String(args.note) : undefined,
|
|
1115
|
+
})
|
|
1116
|
+
const { dataset, report } = await buildDataset(spec, { id: agentId, kind: 'agent' })
|
|
1117
|
+
recordOps({
|
|
1118
|
+
actor: agentId,
|
|
1119
|
+
actorName: agentBadgeLabel(agentId),
|
|
1120
|
+
actorKind: 'agent',
|
|
1121
|
+
action: 'aml.dataset.build',
|
|
1122
|
+
kind: AML_AUDIT_KIND,
|
|
1123
|
+
summary: `构建数据集 ${dataset.id}(行数 ${dataset.rowCount},批次 ${report.runsUsed.length},窗口 train/val/test ${report.windowCount.train}/${report.windowCount.val}/${report.windowCount.test})`,
|
|
1124
|
+
targetKind: 'aml_dataset',
|
|
1125
|
+
targetId: dataset.id,
|
|
1126
|
+
lineId: dataset.lineId,
|
|
1127
|
+
productId: dataset.productId,
|
|
1128
|
+
recipeId: dataset.recipeId,
|
|
1129
|
+
})
|
|
1130
|
+
const cleanLines = report.nodeSummaries.map((s) => {
|
|
1131
|
+
const c = report.cleaning[s.nodeId]
|
|
1132
|
+
return `- ${amlNodeName(s.nodeId)}(${s.nodeId},${s.role}):样本 ${fmtAmlNum(s.count, 0)},剔除率 ${(100 * s.cleanedRatio).toFixed(1)}%(状态 ${c?.droppedState ?? 0}/量程 ${c?.droppedRange ?? 0}/尖峰 ${c?.droppedHampel ?? 0}),插值 ${c?.interpolated ?? 0} 点,缺失率 ${(100 * s.missingRatio).toFixed(1)}%`
|
|
1133
|
+
})
|
|
1134
|
+
const lagLines = report.lagEstimates.map(l =>
|
|
1135
|
+
`- ${amlNodeName(l.controlId)} → ${amlNodeName(l.targetId)}:滞后 ${l.lagSteps} 拍(≈${fmtAmlNum((l.lagSteps * beatMs) / 1000, 1)}s),互相关 ${l.corr.toFixed(2)}`)
|
|
1136
|
+
const dropLines = report.runsDropped.map(d => `- ${d.runId}: ${d.reason}`)
|
|
1137
|
+
return {
|
|
1138
|
+
text: [
|
|
1139
|
+
`数据集构建完成:`,
|
|
1140
|
+
` dataset_id: ${dataset.id}`,
|
|
1141
|
+
` 三元组: 产线 ${dataset.lineId} / 产品 ${getDcwProductRepo().byId(dataset.productId)?.name ?? dataset.productId} / 配方 ${getDcwRecipeRepo().byId(dataset.recipeId)?.name ?? dataset.recipeId}(purpose=${purpose},beat=${beatMs}ms,history=${historySteps},horizon=${horizonSteps})`,
|
|
1142
|
+
` 行数 ${dataset.rowCount} | 窗口 train ${report.windowCount.train} / val ${report.windowCount.val} / test ${report.windowCount.test} | 批次 ${report.runsUsed.length} 个参与构建`,
|
|
1143
|
+
cleanLines.length ? `\n逐节点清洗摘要:\n${cleanLines.join('\n')}` : null,
|
|
1144
|
+
lagLines.length ? `\n滞后估计(控制→目标,正 = 控制领先;训练/调参时参考):\n${lagLines.join('\n')}` : null,
|
|
1145
|
+
dropLines.length ? `\n丢弃批次(${dropLines.length}):\n${dropLines.join('\n')}` : null,
|
|
1146
|
+
`\n下一步:aml_dataset_stats { dataset_id: "${dataset.id}" } 看完整统计;确认后 aml_job_submit 提交训练(训练代码契约见该工具说明)。`,
|
|
1147
|
+
].filter(x => x !== null).join('\n'),
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
catch (err) {
|
|
1151
|
+
return { text: `数据集构建失败:${err instanceof Error ? err.message : String(err)}(常见原因:窗口内无批次打标数据/节点数据缺失率过高;可先 daq_query 确认目标时段数据)。`, isError: true }
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/** 工具:aml_dataset_stats —— 数据集完整统计报告(逐节点统计/滞后/run 轮廓/窗口计数) */
|
|
1156
|
+
export async function toolAmlDatasetStats(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
1157
|
+
const datasetId = String(args.dataset_id ?? '').trim()
|
|
1158
|
+
if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
|
|
1159
|
+
const rt = getAmlRuntime()
|
|
1160
|
+
const dataset = rt.repo.dataset.get(datasetId)
|
|
1161
|
+
if (!dataset) return amlErr(`数据集 ${datasetId} 不存在(aml_node_catalog → aml_dataset_build 先建数据集)。`)
|
|
1162
|
+
const spec = (() => {
|
|
1163
|
+
try {
|
|
1164
|
+
return JSON.parse(dataset.specJson) as { window?: { historySteps?: number, horizonSteps?: number }, beatMs?: number, purpose?: string }
|
|
1165
|
+
}
|
|
1166
|
+
catch { return {} }
|
|
1167
|
+
})()
|
|
1168
|
+
const report = amlReportOf(dataset)
|
|
1169
|
+
if (!report) {
|
|
1170
|
+
return { text: `数据集 ${datasetId} 元数据:行数 ${dataset.rowCount},批次 ${dataset.runIds.length} 个,创建于 ${dataset.createdAt.slice(0, 19).replace('T', ' ')}(统计报告文件缺失,可能为旧版数据集)。` }
|
|
1171
|
+
}
|
|
1172
|
+
const beatMs = spec.beatMs ?? 1000
|
|
1173
|
+
const statLines = report.nodeSummaries.map(s =>
|
|
1174
|
+
`- ${amlNodeName(s.nodeId)}(${s.nodeId},${s.role}):n=${fmtAmlNum(s.count, 0)} 均值 ${fmtAmlNum(s.mean)} std ${fmtAmlNum(s.std)} | p05 ${fmtAmlNum(s.p05)} / p50 ${fmtAmlNum(s.p50)} / p95 ${fmtAmlNum(s.p95)} | 缺失率 ${(100 * s.missingRatio).toFixed(1)}% 清洗率 ${(100 * s.cleanedRatio).toFixed(1)}%`)
|
|
1175
|
+
const lagLines = report.lagEstimates.map(l =>
|
|
1176
|
+
`- ${amlNodeName(l.controlId)} → ${amlNodeName(l.targetId)}:滞后 ${l.lagSteps} 拍(≈${fmtAmlNum((l.lagSteps * beatMs) / 1000, 1)}s),互相关 ${l.corr.toFixed(2)}`)
|
|
1177
|
+
const profileLines = report.runProfiles.map(p =>
|
|
1178
|
+
`- ${p.runId.slice(0, 8)}: ${p.steps} 拍,目标均值 {${Object.entries(p.targetMeans).map(([k, v]) => `${amlNodeName(k)}=${fmtAmlNum(v, 3)}`).join(', ')}}`)
|
|
1179
|
+
return {
|
|
1180
|
+
text: [
|
|
1181
|
+
`数据集 ${datasetId} 统计报告(beat=${beatMs}ms,history=${spec.window?.historySteps ?? '?'} 拍,horizon=${spec.window?.horizonSteps ?? '?'} 拍,purpose=${spec.purpose ?? '-'})`,
|
|
1182
|
+
` 三元组: ${dataset.lineId} / ${dataset.productId} / ${dataset.recipeId} | 行数 ${dataset.rowCount} | 批次 ${dataset.runIds.length}(${report.runsUsed.length} 参与构建)| 创建 ${dataset.createdAt.slice(0, 19).replace('T', ' ')}`,
|
|
1183
|
+
statLines.length ? `\n逐节点统计(train 切分):\n${statLines.join('\n')}` : null,
|
|
1184
|
+
lagLines.length ? `\n控制→目标滞后(互相关峰值,正 = 控制领先):\n${lagLines.join('\n')}` : null,
|
|
1185
|
+
profileLines.length ? `\nrun 轮廓(逐批次目标均值,漂移检测):\n${profileLines.join('\n')}` : null,
|
|
1186
|
+
`\n窗口计数:train ${report.windowCount.train} / val ${report.windowCount.val} / test ${report.windowCount.test}(byRun 分层切分,防同批泄漏)`,
|
|
1187
|
+
report.runsDropped.length > 0 ? `丢弃批次:\n${report.runsDropped.map(d => `- ${d.runId}: ${d.reason}`).join('\n')}` : null,
|
|
1188
|
+
`\n下一步:aml_job_submit { dataset_id: "${datasetId}", code } 提交训练。`,
|
|
1189
|
+
].filter(x => x !== null).join('\n'),
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/** 工具:aml_job_submit —— 提交训练作业(train.py 全文内联;归因 agentId;队列 FIFO) */
|
|
1194
|
+
export async function toolAmlJobSubmit(agentId: string, args: {
|
|
1195
|
+
dataset_id?: string
|
|
1196
|
+
code?: string
|
|
1197
|
+
change_note?: string
|
|
1198
|
+
params?: Record<string, unknown>
|
|
1199
|
+
seed?: number | string
|
|
1200
|
+
purpose?: string
|
|
1201
|
+
parent_experiment_id?: string
|
|
1202
|
+
}): Promise<{ text: string, isError?: boolean }> {
|
|
1203
|
+
const datasetId = String(args.dataset_id ?? '').trim()
|
|
1204
|
+
const code = typeof args.code === 'string' ? args.code : ''
|
|
1205
|
+
if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
|
|
1206
|
+
if (!code.trim()) return amlErr('code 必填:train.py 全文(单文件;契约见工具说明)。')
|
|
1207
|
+
if (code.length > 512_000) return amlErr(`code 过大(${Math.round(code.length / 1024)}KB),上限 500KB;精简训练代码(模型定义/训练循环拆薄)后重试。`)
|
|
1208
|
+
if (!/\bimport\s+amlkit\b/.test(code)) {
|
|
1209
|
+
return amlErr('code 必须 import amlkit(平台数据/进度/导出契约):amlkit.load_bundle(datasetPath) 取数、amlkit.report_progress(pct, note) 报进度、amlkit.export_torch_onnx(model, manifest) 导出。缺契约的作业必然失败。')
|
|
1210
|
+
}
|
|
1211
|
+
const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : args.purpose === 'mpc_surrogate' ? 'mpc_surrogate' : undefined
|
|
1212
|
+
const changeNote = String(args.change_note ?? '').trim()
|
|
1213
|
+
if (!changeNote) return amlErr('change_note 必填:单组件改动纪律 —— 每次实验只改一个组件(网络结构/特征/超参之一),写清改了什么与预期,实验谱系靠它归因。')
|
|
1214
|
+
try {
|
|
1215
|
+
const job = submitJob({
|
|
1216
|
+
datasetId,
|
|
1217
|
+
purpose,
|
|
1218
|
+
changeNote,
|
|
1219
|
+
params: args.params && typeof args.params === 'object' && !Array.isArray(args.params) ? args.params : undefined,
|
|
1220
|
+
seed: Number.isInteger(Number(args.seed)) ? Number(args.seed) : undefined,
|
|
1221
|
+
parentExperimentId: String(args.parent_experiment_id ?? '').trim() || undefined,
|
|
1222
|
+
code,
|
|
1223
|
+
agent: { id: agentId },
|
|
1224
|
+
})
|
|
1225
|
+
const st = await runtimeStatus()
|
|
1226
|
+
return {
|
|
1227
|
+
text: [
|
|
1228
|
+
`训练作业已提交:`,
|
|
1229
|
+
` job_id: ${job.id}`,
|
|
1230
|
+
` dataset: ${job.datasetId} | purpose=${job.purpose} | seed=${fmtAmlNum(Number(job.budget.seed ?? 42), 0)} | change_note: ${changeNote}`,
|
|
1231
|
+
` 队列: 排队 ${st.queued} 个(含本作业)/ 在跑 ${st.running} 个 | python ${st.python.ok ? (st.python.version ?? 'ok') : `不可用(${st.python.reason ?? '?'};作业会失败,请联系用户修复环境)`}`,
|
|
1232
|
+
`\n用 aml_job_status { job_id: "${job.id}" } 看状态/阶段/门禁,aml_job_logs { job_id: "${job.id}" } 看日志尾;训练完成后 aml_leaderboard 看谱系与门禁。`,
|
|
1233
|
+
].join('\n'),
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
catch (err) {
|
|
1237
|
+
return { text: `提交失败:${err instanceof Error ? err.message : String(err)}`, isError: true }
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
/** 工具:aml_job_status —— 作业状态(单作业详情 / 缺省列最近 10 个) */
|
|
1242
|
+
export async function toolAmlJobStatus(_agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
1243
|
+
const rt = getAmlRuntime()
|
|
1244
|
+
const jobId = String(args.job_id ?? '').trim()
|
|
1245
|
+
if (jobId) {
|
|
1246
|
+
const job = rt.repo.job.get(jobId)
|
|
1247
|
+
if (!job) return amlErr(`作业 ${jobId} 不存在(aml_job_status 不带参数可列出最近 10 个)。`)
|
|
1248
|
+
return { text: `${amlJobCard(job)}\n\n轮询建议:training 阶段 30~60s 查一次;终态(done/failed)后看门禁与错误,失败原因可 in aml_job_logs 定位。` }
|
|
1249
|
+
}
|
|
1250
|
+
const jobs = rt.repo.job.list({ limit: 10 })
|
|
1251
|
+
if (jobs.length === 0) {
|
|
1252
|
+
return { text: '尚无训练作业。路径:aml_node_catalog 确认节点 → aml_dataset_build 组数据集 → aml_job_submit 提交训练。' }
|
|
1253
|
+
}
|
|
1254
|
+
const rows = jobs.map(j => `- ${j.id} [${j.status}] ${j.stage || '-'} ${j.progress}% dataset=${j.datasetId}${j.error ? ` | 错误: ${j.error.slice(0, 100)}` : ''}`)
|
|
1255
|
+
return { text: `最近 ${jobs.length} 个作业(新→旧):\n${rows.join('\n')}\n\n传 job_id 查看单作业详情(指标/门禁逐项/错误)。` }
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/** 工具:aml_job_logs —— 作业日志尾随(平台 ##AML 协议行 + 训练输出) */
|
|
1259
|
+
export async function toolAmlJobLogs(_agentId: string, args: { job_id?: string, lines?: number | string }): Promise<{ text: string, isError?: boolean }> {
|
|
1260
|
+
const jobId = String(args.job_id ?? '').trim()
|
|
1261
|
+
if (!jobId) return amlErr('job_id 必填(aml_job_status 不带参数可列出最近作业)。')
|
|
1262
|
+
const job = getAmlRuntime().repo.job.get(jobId)
|
|
1263
|
+
if (!job) return amlErr(`作业 ${jobId} 不存在。`)
|
|
1264
|
+
const n = Math.min(Math.max(Number(args.lines) || 80, 5), 400)
|
|
1265
|
+
const rows = jobLogsTail(jobId, n)
|
|
1266
|
+
if (rows.length === 0) {
|
|
1267
|
+
return { text: `作业 ${jobId} 暂无日志(${job.status === 'queued' ? '仍在排队,开跑后产生日志' : '日志未落盘或已被清理'});稍后重试或用 aml_job_status 看状态。` }
|
|
1268
|
+
}
|
|
1269
|
+
return { text: `作业 ${jobId} 日志尾(最近 ${rows.length} 行,时间正序;##AML 前缀行 = 平台协议事件):\n${rows.join('\n')}` }
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/** 工具:aml_job_cancel —— 取消排队/运行中的作业(归因入册) */
|
|
1273
|
+
export async function toolAmlJobCancel(agentId: string, args: { job_id?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
1274
|
+
const jobId = String(args.job_id ?? '').trim()
|
|
1275
|
+
if (!jobId) return amlErr('job_id 必填。')
|
|
1276
|
+
const rt = getAmlRuntime()
|
|
1277
|
+
const job = rt.repo.job.get(jobId)
|
|
1278
|
+
if (!job) return amlErr(`作业 ${jobId} 不存在。`)
|
|
1279
|
+
if (['done', 'failed', 'cancelled', 'timeout'].includes(job.status)) {
|
|
1280
|
+
return amlErr(`作业 ${jobId} 已是终态(${job.status}),无需取消;aml_job_status 复核。`)
|
|
1281
|
+
}
|
|
1282
|
+
const ok = cancelJob(jobId, { id: agentId, kind: 'agent' })
|
|
1283
|
+
if (!ok) return amlErr(`取消失败:作业 ${jobId} 不在排队/运行中(可能恰好结束);aml_job_status 复核。`)
|
|
1284
|
+
const dataset = rt.repo.dataset.get(job.datasetId)
|
|
1285
|
+
recordOps({
|
|
1286
|
+
actor: agentId,
|
|
1287
|
+
actorName: agentBadgeLabel(agentId),
|
|
1288
|
+
actorKind: 'agent',
|
|
1289
|
+
action: 'aml.job.cancel',
|
|
1290
|
+
kind: AML_AUDIT_KIND,
|
|
1291
|
+
summary: `取消训练作业 ${jobId}(原状态 ${job.status})`,
|
|
1292
|
+
targetKind: 'aml_job',
|
|
1293
|
+
targetId: jobId,
|
|
1294
|
+
lineId: dataset?.lineId,
|
|
1295
|
+
productId: dataset?.productId,
|
|
1296
|
+
recipeId: dataset?.recipeId,
|
|
1297
|
+
})
|
|
1298
|
+
return { text: `作业 ${jobId} 已取消(运行中的会终止进程树)。数据集 ${job.datasetId} 仍可复用;需要重训直接 aml_job_submit。` }
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
/** 工具:aml_leaderboard —— 数据集的实验谱系与门禁对照(标当前最优) */
|
|
1302
|
+
export async function toolAmlLeaderboard(_agentId: string, args: { dataset_id?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
1303
|
+
const datasetId = String(args.dataset_id ?? '').trim()
|
|
1304
|
+
if (!datasetId) return amlErr('dataset_id 必填(aml_dataset_build 返回的 id)。')
|
|
1305
|
+
const rt = getAmlRuntime()
|
|
1306
|
+
const dataset = rt.repo.dataset.get(datasetId)
|
|
1307
|
+
if (!dataset) return amlErr(`数据集 ${datasetId} 不存在。`)
|
|
1308
|
+
const exps = rt.repo.experiment.listByDataset(datasetId, 50)
|
|
1309
|
+
if (exps.length === 0) {
|
|
1310
|
+
return { text: `数据集 ${datasetId}(${dataset.rowCount} 行)尚无实验:aml_job_submit 提交训练后,此处给出谱系与门禁对照。` }
|
|
1311
|
+
}
|
|
1312
|
+
const parsed = exps.map((e) => {
|
|
1313
|
+
let metrics: { oneStepTest?: { nrmse?: number }, rolloutTest?: { nrmse?: number } } = {}
|
|
1314
|
+
let gates: { passed?: boolean } = {}
|
|
1315
|
+
try {
|
|
1316
|
+
metrics = JSON.parse(e.metricsJson)
|
|
1317
|
+
}
|
|
1318
|
+
catch { /* 无指标 */ }
|
|
1319
|
+
try {
|
|
1320
|
+
gates = JSON.parse(e.gatesJson)
|
|
1321
|
+
}
|
|
1322
|
+
catch { /* 无门禁 */ }
|
|
1323
|
+
return { e, g1: metrics.oneStepTest?.nrmse ?? null, g2: metrics.rolloutTest?.nrmse ?? null, passed: gates.passed === true || e.status === 'gates_passed' }
|
|
1324
|
+
})
|
|
1325
|
+
const passers = parsed.filter(p => p.passed && p.g1 != null)
|
|
1326
|
+
const bestId = passers.length > 0 ? passers.reduce((a, b) => ((a.g1 ?? Infinity) <= (b.g1 ?? Infinity) ? a : b)).e.id : null
|
|
1327
|
+
const rows = parsed.map(p =>
|
|
1328
|
+
`- ${p.e.id} [${p.e.status}] ${p.e.changeNote ? `「${p.e.changeNote.slice(0, 60)}」` : '(无备注)'}${p.e.parentExperimentId ? ` ← 父 ${p.e.parentExperimentId}` : ''} | G1=${fmtAmlNum(p.g1)}${p.g2 != null ? ` G2=${fmtAmlNum(p.g2)}` : ''} | 门禁 ${p.passed ? '通过' : '未通过'}${p.e.id === bestId ? ' ★当前最优' : ''}`)
|
|
1329
|
+
const models = rt.repo.model.list({ limit: 100 }).filter(m => m.datasetId === datasetId)
|
|
1330
|
+
const modelLines = models.map(m => `- ${m.id} [${m.stage}] purpose=${m.purpose}(实验 ${m.experimentId})`)
|
|
1331
|
+
return {
|
|
1332
|
+
text: [
|
|
1333
|
+
`实验谱系(数据集 ${datasetId} · ${dataset.productId}/${dataset.recipeId} · ${exps.length} 条,新→旧):`,
|
|
1334
|
+
...rows,
|
|
1335
|
+
modelLines.length > 0 ? `\n已登记模型(晋升对象;aml_leaderboard 最优 = 门禁通过且 G1 最小):` : null,
|
|
1336
|
+
...modelLines,
|
|
1337
|
+
`\nG1=单步测试 NRMSE,G2=多步滚动 NRMSE(越小越好)。优化纪律:每次只改一个组件,change_note 写明;把最优模型推上生产用 aml_model_promote(lead 专属,需人工审批)。`,
|
|
1338
|
+
].filter(x => x !== null).join('\n'),
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/** 工具:aml_model_promote —— 模型晋升 shadow/production(lead 专属;HITL 人工审批;流转入册由 transitionModel 内部完成) */
|
|
1343
|
+
export async function toolAmlModelPromote(agentId: string, args: { model_id?: string, to_stage?: string }): Promise<{ text: string, isError?: boolean }> {
|
|
1344
|
+
// 治理硬守卫:晋升仅限 lead 实例(注入层过滤 + 分发层双重校验,HTTP 直调不可绕过)
|
|
1345
|
+
const roleRow = getAmlRuntime().db.prepare('SELECT role FROM channel_agents WHERE id = ? AND enabled = 1').get(agentId) as { role?: string } | undefined
|
|
1346
|
+
if (roleRow?.role !== 'lead') {
|
|
1347
|
+
return amlErr(`aml_model_promote 为 lead 专属工具:实例 ${agentId}(role=${roleRow?.role ?? '未知'})无权晋升模型。请由团队 lead 发起,晋升需人工 HITL 批准。`)
|
|
1348
|
+
}
|
|
1349
|
+
const modelId = String(args.model_id ?? '').trim()
|
|
1350
|
+
const toStage = String(args.to_stage ?? '').trim()
|
|
1351
|
+
if (!modelId) return amlErr('model_id 必填(aml_leaderboard 的「已登记模型」段可查)。')
|
|
1352
|
+
if (toStage !== 'shadow' && toStage !== 'production') return amlErr('to_stage 必须为 \'shadow\'(影子观测)或 \'production\'(生产生效)。')
|
|
1353
|
+
const rt = getAmlRuntime()
|
|
1354
|
+
const model = rt.repo.model.get(modelId)
|
|
1355
|
+
if (!model) return amlErr(`模型 ${modelId} 不存在。`)
|
|
1356
|
+
if (model.stage === toStage) return amlErr(`模型 ${modelId} 已是 ${toStage},无需流转。`)
|
|
1357
|
+
// production 预检:同组 (product, recipe, purpose) 旧生产将被退役
|
|
1358
|
+
let oldProdId: string | undefined
|
|
1359
|
+
if (toStage === 'production') {
|
|
1360
|
+
oldProdId = rt.repo.model
|
|
1361
|
+
.list({ stage: 'production', productId: model.productId, recipeId: model.recipeId, limit: 50 })
|
|
1362
|
+
.find(m => m.id !== modelId && m.purpose === model.purpose)?.id
|
|
1363
|
+
}
|
|
1364
|
+
// 同模型挂起审批去重(防审批面板堆积,与 dcw_control 同纪律)
|
|
1365
|
+
const approvals = getToolApprovals()
|
|
1366
|
+
if (approvals.hasPendingFor(agentId, modelId)) {
|
|
1367
|
+
return amlErr(`模型 ${modelId} 已有一条待审批的晋升请求,请等待用户处理后再发起新请求。`)
|
|
1368
|
+
}
|
|
1369
|
+
const detail = `AML 模型晋升:${modelId} ${model.stage} → ${toStage}(产品 ${model.productId} / 配方 ${model.recipeId} / purpose=${model.purpose}${oldProdId ? `;批准后原生产模型 ${oldProdId} 将自动退役` : ''})`
|
|
1370
|
+
const ap = await approvals.request(agentId, modelId, 'dcw', detail, { title: 'AML 模型晋升审批' })
|
|
1371
|
+
if (!ap.approved) {
|
|
1372
|
+
return { text: `人工未批准:模型 ${modelId} 保持 ${model.stage} 阶段。用户备注:${ap.comment || '(无)'}。可回炉重训(aml_job_submit)或换候选模型后再申请。` }
|
|
1373
|
+
}
|
|
1374
|
+
try {
|
|
1375
|
+
const r = transitionModel(modelId, toStage, agentBadgeLabel(agentId), 'agent')
|
|
1376
|
+
// 归属审计已由 transitionModel 内部 recordOps(aml.model.promote)完成,此处不重复记录
|
|
1377
|
+
return {
|
|
1378
|
+
text: `晋升完成:${modelId} ${r.from} → ${toStage}。${r.retiredId ? `原生产模型 ${r.retiredId} 已自动退役。` : ''}${toStage === 'shadow'
|
|
1379
|
+
? '影子阶段:用 aml_model_reference 观测其预测与实际偏差,积累证据后再申请 production。'
|
|
1380
|
+
: '该模型已作为生产模型生效:aml_model_reference 的影子参考即来自它;调控 Agent 调参前请先查它。'}`,
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
catch (err) {
|
|
1384
|
+
return { text: `晋升失败:${err instanceof Error ? err.message : String(err)}(审批已通过;若为并发竞态可刷新状态重试)。`, isError: true }
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
/** 工具:aml_model_reference —— 生产模型影子参考:拉最近历史组装模型输入 → 预测未来目标轨迹(调参前先问影子模型) */
|
|
1389
|
+
export async function toolAmlModelReference(agentId: string, args: {
|
|
1390
|
+
line_id?: string
|
|
1391
|
+
product_id?: string
|
|
1392
|
+
recipe_id?: string
|
|
1393
|
+
purpose?: string
|
|
1394
|
+
controls?: Record<string, number | string>
|
|
1395
|
+
steps?: number | string
|
|
1396
|
+
}): Promise<{ text: string, isError?: boolean }> {
|
|
1397
|
+
// 0. 绑定面:至少一个 daq 绑定;line_id 只缩不放
|
|
1398
|
+
const repo = getAgentNodeBindingRepo()
|
|
1399
|
+
const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
|
|
1400
|
+
if (daqBindings.length === 0) {
|
|
1401
|
+
return amlErr('你尚未绑定任何数采节点,无法组装影子参考所需的历史输入;请先绑定数采节点。')
|
|
1402
|
+
}
|
|
1403
|
+
const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
|
|
1404
|
+
const scopeLines = [...new Set(daqBindings.map(b => lineOf(b.nodeId)).filter(Boolean))]
|
|
1405
|
+
const lineFilter = String(args.line_id ?? '').trim()
|
|
1406
|
+
if (lineFilter && !scopeLines.includes(lineFilter)) {
|
|
1407
|
+
return amlErr(`产线 ${lineFilter} 不在你的负责范围(你绑定节点覆盖:${scopeLines.join(', ') || '无'};绑定只缩不放)。`)
|
|
1408
|
+
}
|
|
1409
|
+
const purpose = args.purpose === 'quality_predict' ? 'quality_predict' : 'mpc_surrogate'
|
|
1410
|
+
|
|
1411
|
+
// 1. 解析 (productId, recipeId):参数给全用参数;缺省回退到候选产线的唯一活动批次
|
|
1412
|
+
let productId = String(args.product_id ?? '').trim()
|
|
1413
|
+
let recipeId = String(args.recipe_id ?? '').trim()
|
|
1414
|
+
let resolveHow = '参数指定'
|
|
1415
|
+
if (!productId || !recipeId) {
|
|
1416
|
+
const candidateLines = lineFilter ? [lineFilter] : scopeLines
|
|
1417
|
+
const runs = candidateLines
|
|
1418
|
+
.map(lid => getActiveLineRun(lid))
|
|
1419
|
+
.filter((r): r is NonNullable<ReturnType<typeof getActiveLineRun>> => !!r && !!r.productId && !!r.recipeId)
|
|
1420
|
+
if (runs.length === 1) {
|
|
1421
|
+
const run = runs[0]!
|
|
1422
|
+
if (!productId) productId = run.productId
|
|
1423
|
+
if (!recipeId) recipeId = run.recipeId
|
|
1424
|
+
resolveHow = `产线 ${run.lineId} 唯一活动批次 ${run.runId.slice(0, 8)}(产品「${run.productName}」/配方「${run.recipeName}」)`
|
|
1425
|
+
}
|
|
1426
|
+
else if (runs.length === 0) {
|
|
1427
|
+
return { text: `无法确定产品/配方:${candidateLines.length > 0 ? `产线 ${candidateLines.join(', ')}` : '你绑定节点所属产线'}当前无活动批次,且 product_id/recipe_id 未给全。请开跑后重试,或显式传 product_id 与 recipe_id(line_context 可查)。`, isError: true }
|
|
1428
|
+
}
|
|
1429
|
+
else {
|
|
1430
|
+
return { text: `无法确定产品/配方:候选产线存在多个活动批次(${runs.map(r => `${r.lineId} → ${r.productName}/${r.recipeName}`).join('; ')})。请传 line_id 缩小范围,或显式传 product_id 与 recipe_id。`, isError: true }
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
// 2. 生产模型(无则指引建模范式)
|
|
1435
|
+
const rt = getAmlRuntime()
|
|
1436
|
+
const model = rt.repo.model.productionOf(productId, recipeId, purpose)
|
|
1437
|
+
if (!model) {
|
|
1438
|
+
const cands = rt.repo.model.list({ productId, recipeId, limit: 20 })
|
|
1439
|
+
return { text: `尚无生产模型:(${productId}, ${recipeId}, ${purpose}) 下没有 stage=production 的模型。${cands.length > 0 ? `现有候选:${cands.map(m => `${m.id}(${m.stage})`).join(', ')} —— 请 lead 用 aml_model_promote 晋升(需人工审批)。` : '该三元组下还没有任何模型:aml_dataset_build → aml_job_submit 训练,门禁通过后申请晋升。在此之前调参请依据 dcw_journal 历史经验与 daq_query 证据。'}` }
|
|
1440
|
+
}
|
|
1441
|
+
// 3. 产线归属鉴权(绑定只缩不放;模型归属线经数据集追溯)
|
|
1442
|
+
const ds = rt.repo.dataset.get(model.datasetId)
|
|
1443
|
+
const modelLine = ds?.lineId ?? ''
|
|
1444
|
+
if (modelLine && !scopeLines.includes(modelLine)) {
|
|
1445
|
+
return amlErr(`模型 ${model.id} 归属产线 ${modelLine},不在你绑定节点覆盖的产线(${scopeLines.join(', ')})内;绑定只缩不放。`)
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
// 4. io 契约 → 拉最近历史 → 网格对齐 → 组 [H][nAll](原始物理量,顺序 = allNodes)
|
|
1449
|
+
const io = readIoSpecFor(model.id)
|
|
1450
|
+
const H = io.historySteps
|
|
1451
|
+
const beatMs = io.beatMs
|
|
1452
|
+
const now = Date.now()
|
|
1453
|
+
const fromMs = now - H * beatMs - 5 * beatMs
|
|
1454
|
+
const { getTsdb, tsdbReady } = await import('../daq/storage')
|
|
1455
|
+
await tsdbReady
|
|
1456
|
+
const tsdb = getTsdb()
|
|
1457
|
+
const columns = new Map<string, number[]>()
|
|
1458
|
+
const shortage: string[] = []
|
|
1459
|
+
for (const nodeId of io.allNodes) {
|
|
1460
|
+
try {
|
|
1461
|
+
const pts = await tsdb.query(nodeId, { fromMs, toMs: now, limit: Math.min(Math.max(H * 10, 600), 5000) })
|
|
1462
|
+
const { grid } = alignToGrid(
|
|
1463
|
+
pts.map(p => ({ at: p.at, value: p.value ?? p.avg ?? 0 })).filter(p => Number.isFinite(p.value)),
|
|
1464
|
+
{ beatMs, maxInterpMs: beatMs * 2 },
|
|
1465
|
+
)
|
|
1466
|
+
const tail = grid.slice(-H).map(g => g.value)
|
|
1467
|
+
if (tail.length < H) {
|
|
1468
|
+
shortage.push(`${amlNodeName(nodeId)}(${nodeId})仅 ${tail.length}/${H} 格点`)
|
|
1469
|
+
continue
|
|
1470
|
+
}
|
|
1471
|
+
columns.set(nodeId, tail)
|
|
1472
|
+
}
|
|
1473
|
+
catch (err) {
|
|
1474
|
+
shortage.push(`${amlNodeName(nodeId)}(${nodeId})查询失败:${err instanceof Error ? err.message : String(err)}`)
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
if (shortage.length > 0) {
|
|
1478
|
+
return { text: `历史数据不足,无法组装模型输入:${shortage.join(';')}。需要从 ${new Date(fromMs).toISOString().slice(0, 16)} 起连续约 ${(H * beatMs / 60_000).toFixed(0)} 分钟的运行数据(产线须在跑);等数据积累后重试,或缩短 steps/换更短 history 的模型。`, isError: true }
|
|
1479
|
+
}
|
|
1480
|
+
const history: number[][] = []
|
|
1481
|
+
for (let i = 0; i < H; i++) history.push(io.allNodes.map(n => columns.get(n)![i]!))
|
|
1482
|
+
|
|
1483
|
+
// 5. 控制轨迹:controls 映射(节点 id → 值,常数外推 steps 行);缺省行持最后观测
|
|
1484
|
+
const steps = Math.max(1, Math.min(Number(args.steps) || io.horizonSteps, io.horizonSteps))
|
|
1485
|
+
const lastRow = history[history.length - 1]!
|
|
1486
|
+
const unknownKeys = args.controls ? Object.keys(args.controls).filter(k => !io.controlNodes.includes(k)) : []
|
|
1487
|
+
const controlRow = io.controlNodes.map((c) => {
|
|
1488
|
+
const provided = args.controls?.[c]
|
|
1489
|
+
const v = provided != null ? Number(provided) : Number.NaN
|
|
1490
|
+
return Number.isFinite(v) ? v : lastRow[io.allNodes.indexOf(c)]!
|
|
1491
|
+
})
|
|
1492
|
+
const controls: number[][] = Array.from({ length: steps }, () => [...controlRow])
|
|
1493
|
+
|
|
1494
|
+
// 6. 预测 + 人话报告
|
|
1495
|
+
try {
|
|
1496
|
+
const r = await predictProduction(productId, recipeId, purpose, { history, controls, steps })
|
|
1497
|
+
const header = `步 | ${r.targetNodes.map(t => `${amlNodeName(t)}(${amlNodeUnit(t)})`).join(' | ')}`
|
|
1498
|
+
const forecastLines = r.forecast.map((row, i) =>
|
|
1499
|
+
` ${i + 1}(+${fmtAmlNum(((i + 1) * r.beatMs) / 1000, 0)}s) | ${row.map(v => fmtAmlNum(v, 3)).join(' | ')}`)
|
|
1500
|
+
const ctrlTxt = io.controlNodes.length > 0
|
|
1501
|
+
? io.controlNodes.map((c) => {
|
|
1502
|
+
const provided = args.controls?.[c]
|
|
1503
|
+
return `${amlNodeName(c)}=${Number.isFinite(Number(provided)) ? Number(provided) : `${fmtAmlNum(lastRow[io.allNodes.indexOf(c)], 3)}(持最后观测)`}${amlNodeUnit(c)}`
|
|
1504
|
+
}).join(', ')
|
|
1505
|
+
: '无控制节点'
|
|
1506
|
+
return {
|
|
1507
|
+
text: [
|
|
1508
|
+
`影子模型参考(调参前先问影子模型;预测≠承诺,真实下发仍走 dcw_control 安全联锁):`,
|
|
1509
|
+
` 模型 ${r.modelId}(stage=${r.stage},purpose=${purpose})| 三元组:产品 ${getDcwProductRepo().byId(productId)?.name ?? productId} / 配方 ${getDcwRecipeRepo().byId(recipeId)?.name ?? recipeId}(解析:${resolveHow})`,
|
|
1510
|
+
` 输入:最近 ${H} 拍 × ${io.allNodes.length} 节点(beat=${beatMs}ms),截至 ${new Date(now).toISOString().slice(11, 19)};控制轨迹(共 ${steps} 步):${ctrlTxt}${unknownKeys.length > 0 ? `(已忽略非控制节点的键:${unknownKeys.join(', ')})` : ''}`,
|
|
1511
|
+
` 预测(steps=${steps},每拍 ${beatMs / 1000}s):`,
|
|
1512
|
+
` ${header}`,
|
|
1513
|
+
...forecastLines,
|
|
1514
|
+
` 假设: ${r.assumptions}`,
|
|
1515
|
+
`\n用法:把候选设定值作为 controls 传入(键 = 控制节点 id)对比不同方案的预测轨迹;选定后 dcw_control 下发并 daq_query 复测。`,
|
|
1516
|
+
].join('\n'),
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
catch (err) {
|
|
1520
|
+
return { text: `预测失败:${err instanceof Error ? err.message : String(err)}(模型 ${model.id};若为工件缺失可重训同规格数据集)。`, isError: true }
|
|
1521
|
+
}
|
|
1522
|
+
}
|