agentworkshop 0.5.9 → 0.6.1
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/compaction-hints.md +9 -9
- package/.AgentWorkShop/prompts/host-tools.json +42 -0
- package/.output/.AgentWorkShop/prompts/compaction-hints.md +9 -9
- package/.output/.AgentWorkShop/prompts/host-tools.json +42 -0
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{Dm5mD6XT.js → BD9D9pl4.js} +1 -1
- package/.output/public/_nuxt/{BdKzfJiM.js → BxD8Fg_Z.js} +1 -1
- package/.output/public/_nuxt/{dRAyjbJ6.js → C-Y5ydB6.js} +3 -3
- package/.output/public/_nuxt/{Bok1DRqh.js → C0FogB-p.js} +1 -1
- package/.output/public/_nuxt/{BUNGEK2z.js → C2QSTAWf.js} +1 -1
- package/.output/public/_nuxt/{CWDzKGtj.js → CclO6GyL.js} +1 -1
- package/.output/public/_nuxt/{B3__nfxM.js → Ck6tznoQ.js} +1 -1
- package/.output/public/_nuxt/CwS_UHeH.js +1 -0
- package/.output/public/_nuxt/{CE2ynNi9.js → CwcOEM8m.js} +1 -1
- package/.output/public/_nuxt/MhK4buEJ.js +1 -0
- package/.output/public/_nuxt/_id_.DN3U6EF9.css +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/221de779-a113-4232-b9a1-31a614f5e3c7.json +1 -0
- package/.output/public/_nuxt/{entry.DjhxLu-f.css → entry.DvlXlPwx.css} +1 -1
- package/.output/public/_nuxt/settings.BG0K9_MG.css +1 -0
- package/.output/server/chunks/_/error-500.mjs.map +1 -1
- package/.output/server/chunks/_/nitro.mjs +2675 -1425
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/build/{OmpTerminalPanel-CZnxR3M_.mjs → OmpTerminalPanel-B_SYhmgb.mjs} +2 -2
- package/.output/server/chunks/build/{OmpTerminalPanel-CZnxR3M_.mjs.map → OmpTerminalPanel-B_SYhmgb.mjs.map} +1 -1
- package/.output/server/chunks/build/{TownView-DYlUNRZe.mjs → TownView-D9yCQe1T.mjs} +6 -6
- package/.output/server/chunks/build/{TownView-DYlUNRZe.mjs.map → TownView-D9yCQe1T.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-BOhG2yz8.mjs → _id_-CmKAEFHV.mjs} +4 -2
- package/.output/server/chunks/build/_id_-CmKAEFHV.mjs.map +1 -0
- package/.output/server/chunks/build/{_id_-CuyMYmhY.mjs → _id_-xR3AChMO.mjs} +74 -26
- package/.output/server/chunks/build/_id_-xR3AChMO.mjs.map +1 -0
- package/.output/server/chunks/build/{_wsId_-B5f5BdW2.mjs → _wsId_-C45nVrl-.mjs} +12 -10
- package/.output/server/chunks/build/{_wsId_-B5f5BdW2.mjs.map → _wsId_-C45nVrl-.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents-BVaxN75W.mjs → agents-D4l1icvn.mjs} +5 -3
- package/.output/server/chunks/build/agents-D4l1icvn.mjs.map +1 -0
- package/.output/server/chunks/build/{channel-templates-D1K2IKrE.mjs → channel-templates-DqjtC-R0.mjs} +5 -3
- package/.output/server/chunks/build/channel-templates-DqjtC-R0.mjs.map +1 -0
- package/.output/server/chunks/build/{client-only-CFTHwakk.mjs → client-only-D5BzSQc6.mjs} +2 -2
- package/.output/server/chunks/build/client-only-D5BzSQc6.mjs.map +1 -0
- package/.output/server/chunks/build/{daq-ObtN1TQ4.mjs → daq-Boz_dlAQ.mjs} +6 -4
- package/.output/server/chunks/build/daq-Boz_dlAQ.mjs.map +1 -0
- package/.output/server/chunks/build/{dcw-fINr-He1.mjs → dcw-wTRwBAUi.mjs} +3 -1
- package/.output/server/chunks/build/dcw-wTRwBAUi.mjs.map +1 -0
- package/.output/server/chunks/build/{default-CVVO40Jj.mjs → default-Dt6xLdpd.mjs} +7 -5
- package/.output/server/chunks/build/{default-CVVO40Jj.mjs.map → default-Dt6xLdpd.mjs.map} +1 -1
- package/.output/server/chunks/build/interval-WlxgjTzO.mjs +9 -0
- package/.output/server/chunks/build/interval-WlxgjTzO.mjs.map +1 -0
- package/.output/server/chunks/build/{logs-DqNgCJAn.mjs → logs-Cdi-eXlN.mjs} +5 -3
- package/.output/server/chunks/build/logs-Cdi-eXlN.mjs.map +1 -0
- package/.output/server/chunks/build/{monitor-CTZLwbdw.mjs → monitor-yNoV98rf.mjs} +6 -4
- package/.output/server/chunks/build/{monitor-CTZLwbdw.mjs.map → monitor-yNoV98rf.mjs.map} +1 -1
- package/.output/server/chunks/build/{pages-DC52d7z7.mjs → pages-bWKy0ZsA.mjs} +6 -4
- package/.output/server/chunks/build/pages-bWKy0ZsA.mjs.map +1 -0
- package/.output/server/chunks/build/{plugins-DVQty7qG.mjs → plugins-B-ZNey0Z.mjs} +4 -2
- package/.output/server/chunks/build/plugins-B-ZNey0Z.mjs.map +1 -0
- package/.output/server/chunks/build/{settings-BeergncK.mjs → settings-C3T5hR2A.mjs} +21 -19
- package/.output/server/chunks/build/settings-C3T5hR2A.mjs.map +1 -0
- package/.output/server/chunks/build/{teams-CFeDlHDh.mjs → teams-QR3BBF7A.mjs} +5 -3
- package/.output/server/chunks/build/teams-QR3BBF7A.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-CBAUbOce.mjs → tokens-DFvr_TLj.mjs} +4 -2
- package/.output/server/chunks/build/tokens-DFvr_TLj.mjs.map +1 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs +2 -0
- package/.output/server/chunks/build/town-BUqRobze.mjs.map +1 -1
- package/.output/server/chunks/build/{town-BxH-XXth.mjs → town-CKg6Qxba.mjs} +9 -7
- package/.output/server/chunks/build/town-CKg6Qxba.mjs.map +1 -0
- package/.output/server/chunks/build/{useDaqStream-CwORhsD7.mjs → useDaqStream-zHEptJQ_.mjs} +44 -1
- package/.output/server/chunks/build/useDaqStream-zHEptJQ_.mjs.map +1 -0
- package/.output/server/chunks/build/{useSiteConfig-Cc-ABesl.mjs → useSiteConfig-DJe_KMVr.mjs} +1 -1
- package/.output/server/chunks/build/{useSiteConfig-Cc-ABesl.mjs.map → useSiteConfig-DJe_KMVr.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkshopApi-5er8_EHZ.mjs → useWorkshopApi-Bh5VUHWu.mjs} +1 -1
- package/.output/server/chunks/build/{useWorkshopApi-5er8_EHZ.mjs.map → useWorkshopApi-Bh5VUHWu.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkshopWs-Dwr_1Q8f.mjs → useWorkshopWs-xcdeiSmJ.mjs} +2 -2
- package/.output/server/chunks/build/{useWorkshopWs-Dwr_1Q8f.mjs.map → useWorkshopWs-xcdeiSmJ.mjs.map} +1 -1
- package/.output/server/chunks/build/{user-CpVY4OAA.mjs → user-Dk-ytEUV.mjs} +1 -1
- package/.output/server/chunks/build/{user-CpVY4OAA.mjs.map → user-Dk-ytEUV.mjs.map} +1 -1
- package/.output/server/chunks/build/{users-BMs4s_6K.mjs → users-4FZ0yFUO.mjs} +4 -2
- package/.output/server/chunks/build/users-4FZ0yFUO.mjs.map +1 -0
- package/.output/server/chunks/build/{workshop-CJAyZ5zS.mjs → workshop-CLhwe5eo.mjs} +6 -4
- package/.output/server/chunks/build/workshop-CLhwe5eo.mjs.map +1 -0
- package/.output/server/chunks/build/{workspaces-Dq-1zvu9.mjs → workspaces-IfORCDJE.mjs} +2 -2
- package/.output/server/chunks/build/{workspaces-Dq-1zvu9.mjs.map → workspaces-IfORCDJE.mjs.map} +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +2 -0
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +2 -0
- package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +2 -0
- package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/mcp/workshop.mjs +2 -0
- package/.output/server/chunks/routes/api/mcp/workshop.mjs.map +1 -1
- package/.output/server/chunks/routes/api/metrics.mjs +2 -0
- package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +2 -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 +2 -0
- package/.output/server/chunks/routes/api/plugins/client/_name_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs +2 -0
- package/.output/server/chunks/routes/api/plugins/manifest.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/config.get.mjs +2 -0
- package/.output/server/chunks/routes/api/system/config.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.get.mjs +2 -0
- package/.output/server/chunks/routes/api/system/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/index.patch.mjs +2 -0
- package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +2 -0
- 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 -0
- package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/system/monitor.get.mjs +2 -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 +3 -2
- 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 -0
- 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 -0
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.get.mjs +2 -0
- package/.output/server/chunks/routes/api/users/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/_id_.put.mjs +2 -0
- package/.output/server/chunks/routes/api/users/_id_.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/index.get.mjs +2 -0
- package/.output/server/chunks/routes/api/users/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/index.post.mjs +2 -0
- package/.output/server/chunks/routes/api/users/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/login.post.mjs +2 -0
- package/.output/server/chunks/routes/api/users/login.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/logout.post.mjs +2 -0
- package/.output/server/chunks/routes/api/users/logout.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/me.get.mjs +2 -0
- package/.output/server/chunks/routes/api/users/me.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/register.post.mjs +2 -0
- package/.output/server/chunks/routes/api/users/register.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +2 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/_...path_.mjs +2 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +2 -0
- 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 +2 -0
- 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 +2 -0
- 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 -0
- 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 -0
- 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 +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/_id_.delete.mjs +2 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +2 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 +2 -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 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/audit.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/caller.mjs +2 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.delete.mjs +2 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +2 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/_memoryId_.delete.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/model.patch.mjs +2 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.get.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/memories/_memoryId_.delete.mjs +2 -0
- 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 -0
- 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 -0
- 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 +2 -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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/channels.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +36 -0
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +53 -0
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +2 -0
- 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 -0
- 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 +2 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +2 -0
- 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/test.post.mjs +2 -0
- 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 -0
- 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 -0
- 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 +2 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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/rollback-good.post.mjs +2 -0
- 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_.delete.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +2 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index10.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index2.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index2.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index3.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index7.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index8.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index8.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index8.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/mailbox/all.get.mjs +2 -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 +2 -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 -0
- 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 -0
- 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 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/plugins/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/runtime.get.mjs +2 -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 -0
- 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 -0
- 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 +2 -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 +2 -0
- package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/index.post.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks/_id/retry.post.mjs +2 -0
- 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 -0
- package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/tasks.get.mjs +2 -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 +2 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.get.mjs +2 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/teams/_id/members/_agentId_.delete.mjs +2 -0
- 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 -0
- 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 -0
- 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 +2 -0
- package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs.map +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 +2 -0
- package/.output/server/chunks/routes/api/workshop/users/register.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channels/_channelId_.delete.mjs +2 -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 +2 -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 +2 -0
- package/.output/server/chunks/routes/api/workshop/workspaces/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/chunks/routes/renderer.mjs.map +1 -1
- package/.output/server/chunks/virtual/entry.mjs +166 -114
- package/.output/server/chunks/virtual/entry.mjs.map +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +2 -0
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/package.json +1 -1
- package/app/composables/workshop/useDaqStream.ts +59 -1
- package/app/config/schema.ts +8 -0
- package/app/pages/daq/[id].vue +141 -1
- package/app/pages/settings.vue +10 -5
- package/app/plugins/runtime-config.client.ts +65 -65
- package/app/stores/runtime-config.ts +212 -212
- package/config.yml +77 -70
- package/docker-compose.yml +19 -2
- package/docs/plugins.md +271 -197
- package/i18n/dicts/_en.json +7 -2
- package/i18n/dicts/daqDetail.json +8 -2
- package/i18n/locales/en.ts +55 -29
- package/i18n/locales/zh-CN.ts +55 -29
- package/nuxt.config.ts +1 -1
- package/package.json +144 -143
- package/scripts/_dbg-collab-scenario-e2e.mjs +185 -0
- package/scripts/_dbg-daq-frame-alarm.mjs +49 -0
- package/scripts/_dbg-daq-frame-ui.mjs +62 -0
- package/scripts/_dbg-daq-frame-ws.mjs +72 -0
- package/scripts/_dbg-daq-frames-e2e.mjs +118 -0
- package/scripts/_dbg-host.mjs +16 -0
- package/scripts/_dbg-plugin-agent-read.ts +56 -0
- package/scripts/_dbg-plugin-sink-rest.mjs +70 -0
- package/scripts/_dbg-plugin-sink-ui.mjs +81 -0
- package/scripts/_dbg-plugin-tools-inject.ts +80 -0
- package/scripts/_dbg-plugin-verify-e2e.mjs +123 -0
- package/scripts/_dbg-prompts-hotreload-test.ts +76 -0
- package/scripts/_dbg-release-smoke.mjs +104 -0
- package/scripts/i18n-merge.mjs +69 -67
- package/scripts/test-context-governor.ts +176 -176
- package/scripts/test-daq-frames.ts +180 -0
- package/scripts/test-daq-minio.ts +77 -0
- package/scripts/test-memory-rrf-mmr.ts +114 -114
- package/scripts/test-plugin-ext.ts +173 -0
- package/server/api/system/settings/events.get.ts +27 -28
- package/server/api/system/settings/index.get.ts +14 -14
- package/server/api/system/settings/index.patch.ts +22 -22
- package/server/api/system/settings/reset.post.ts +12 -12
- package/server/api/workshop/daq/[id]/frames/content.get.ts +24 -0
- package/server/api/workshop/daq/[id]/frames.get.ts +44 -0
- package/server/data/daqs.json +113 -89
- package/server/data/dcw-rollback.json +1 -1
- package/server/data/dcw-runs.json +3207 -2517
- package/server/data/dcw-writes.json +720 -0
- package/server/data/dcws.json +4 -4
- package/server/data/line-runs.json +1 -232
- package/server/plugins/daq.ts +11 -0
- package/server/plugins/system-config.ts +38 -38
- package/server/services/system-config.ts +365 -356
- package/server/services/workshop/agents/industrial-tools.ts +91 -25
- package/server/services/workshop/agents/omp-agent.ts +1955 -1895
- package/server/services/workshop/agents/plugin-tools.ts +145 -0
- package/server/services/workshop/daq/bus/queue-port.ts +18 -0
- package/server/services/workshop/daq/daq-controller.ts +216 -14
- package/server/services/workshop/daq/daq-node.ts +257 -247
- package/server/services/workshop/daq/daq-runtime.ts +36 -4
- package/server/services/workshop/daq/daq-templates.ts +213 -157
- package/server/services/workshop/daq/drivers.ts +134 -30
- package/server/services/workshop/daq/frames.ts +227 -0
- package/server/services/workshop/daq/infra.ts +31 -17
- package/server/services/workshop/daq/objectstore/disk.adapter.ts +38 -0
- package/server/services/workshop/daq/objectstore/index.ts +88 -0
- package/server/services/workshop/daq/objectstore/minio.adapter.ts +60 -0
- package/server/services/workshop/daq/objectstore/objectstore-port.ts +27 -0
- package/server/services/workshop/daq/plugin-bridge.ts +73 -0
- package/server/services/workshop/daq/png-enc.ts +71 -0
- package/server/services/workshop/daq/storage/sqlite.adapter.ts +104 -1
- package/server/services/workshop/daq/storage/timescale.adapter.ts +95 -4
- package/server/services/workshop/daq/storage/tsdb-port.ts +46 -0
- package/server/services/workshop/plugins/host.mjs +479 -417
- package/server/services/workshop/runtime/agent-runtime.ts +744 -744
- package/shared/config/schema.json +6 -1
- package/shared/daq-protocol.ts +88 -0
- package/.output/public/_nuxt/B-PgoIPN.js +0 -1
- package/.output/public/_nuxt/DVNYfGsj.js +0 -1
- package/.output/public/_nuxt/_id_.CbiF5PrV.css +0 -1
- package/.output/public/_nuxt/builds/meta/6f7e40bf-a960-4f51-8a2e-bb1fffeaa5e8.json +0 -1
- package/.output/public/_nuxt/settings.BANibAnV.css +0 -1
- package/.output/server/chunks/build/_id_-BOhG2yz8.mjs.map +0 -1
- package/.output/server/chunks/build/_id_-CuyMYmhY.mjs.map +0 -1
- package/.output/server/chunks/build/agents-BVaxN75W.mjs.map +0 -1
- package/.output/server/chunks/build/channel-templates-D1K2IKrE.mjs.map +0 -1
- package/.output/server/chunks/build/client-only-CFTHwakk.mjs.map +0 -1
- package/.output/server/chunks/build/daq-ObtN1TQ4.mjs.map +0 -1
- package/.output/server/chunks/build/dcw-fINr-He1.mjs.map +0 -1
- package/.output/server/chunks/build/interval-Bt11uRPw.mjs +0 -9
- package/.output/server/chunks/build/interval-Bt11uRPw.mjs.map +0 -1
- package/.output/server/chunks/build/logs-DqNgCJAn.mjs.map +0 -1
- package/.output/server/chunks/build/pages-DC52d7z7.mjs.map +0 -1
- package/.output/server/chunks/build/plugins-DVQty7qG.mjs.map +0 -1
- package/.output/server/chunks/build/settings-BeergncK.mjs.map +0 -1
- package/.output/server/chunks/build/teams-CFeDlHDh.mjs.map +0 -1
- package/.output/server/chunks/build/tokens-CBAUbOce.mjs.map +0 -1
- package/.output/server/chunks/build/town-BxH-XXth.mjs.map +0 -1
- package/.output/server/chunks/build/useDaqStream-CwORhsD7.mjs.map +0 -1
- package/.output/server/chunks/build/users-BMs4s_6K.mjs.map +0 -1
- package/.output/server/chunks/build/workshop-CJAyZ5zS.mjs.map +0 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** 前端 smoke:frame 节点详情页渲染(向量轮廓 SVG + 图像画廊)+ 插件 manifest */
|
|
2
|
+
import puppeteer from 'puppeteer-core'
|
|
3
|
+
|
|
4
|
+
const ROOT = 'http://127.0.0.1:3000'
|
|
5
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
6
|
+
let failed = 0
|
|
7
|
+
const check = (name, ok, detail = '') => { console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`); if (!ok) failed++ }
|
|
8
|
+
|
|
9
|
+
const login = await fetch(`${ROOT}/api/users/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email: 'zhangwei@awshop.io', password: 'Awshop@123' }) }).then(r => r.json())
|
|
10
|
+
const H = { authorization: `Bearer ${login.data.token}`, 'content-type': 'application/json' }
|
|
11
|
+
const cookie = { name: 'token', value: login.data.token, domain: '127.0.0.1', path: '/' }
|
|
12
|
+
const j = (u, m = 'GET', b) => fetch(ROOT + u, { method: m, headers: H, body: b ? JSON.stringify(b) : undefined }).then(r => r.json())
|
|
13
|
+
|
|
14
|
+
const browser = await puppeteer.launch({ executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: 'new', args: ['--no-sandbox', '--disable-gpu', '--window-size=1600,1000'] })
|
|
15
|
+
const page = await browser.newPage()
|
|
16
|
+
await page.setViewport({ width: 1600, height: 1000 })
|
|
17
|
+
await page.setCookie(cookie)
|
|
18
|
+
page.on('pageerror', (e) => { console.log('PAGEERROR:', String(e).slice(0, 200)); failed++ })
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// 开跑 + 建向量/图像节点
|
|
22
|
+
const d = (await j('/api/workshop/dcw')).data
|
|
23
|
+
const cand = d.lines.map(l => ({ line: l, recipe: d.recipes.find(r => r.lineId === l.id) })).find(x => x.recipe)
|
|
24
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST').catch(() => {})
|
|
25
|
+
await sleep(800)
|
|
26
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/start`, 'POST', { recipeId: cand.recipe.id })
|
|
27
|
+
const vec = (await j('/api/workshop/daq', 'POST', { templateRef: 'thickness-scan', lineId: cand.line.id, name: 'UI 向量' })).data.node
|
|
28
|
+
const img = (await j('/api/workshop/daq', 'POST', { templateRef: 'ccd-image', lineId: cand.line.id, name: 'UI 图像' })).data.node
|
|
29
|
+
await sleep(6000)
|
|
30
|
+
|
|
31
|
+
// 向量详情页
|
|
32
|
+
await page.goto(`${ROOT}/daq/${vec.id}`, { waitUntil: 'domcontentloaded', timeout: 60000 })
|
|
33
|
+
await sleep(6000)
|
|
34
|
+
const vecTile = await page.evaluate(() => ({ frames: !!document.querySelector('.frames-tile'), svg: !!document.querySelector('.vec-svg polyline'), rows: document.querySelectorAll('.frames-tile tbody tr').length }))
|
|
35
|
+
check('向量页:帧视图渲染', vecTile.frames && vecTile.svg, JSON.stringify(vecTile))
|
|
36
|
+
|
|
37
|
+
// 图像详情页(画廊 + 缩略图实际加载)
|
|
38
|
+
await page.goto(`${ROOT}/daq/${img.id}`, { waitUntil: 'domcontentloaded', timeout: 60000 })
|
|
39
|
+
await sleep(8000)
|
|
40
|
+
const imgTile = await page.evaluate(() => {
|
|
41
|
+
const imgs = [...document.querySelectorAll('.gal-item img')]
|
|
42
|
+
return { gal: !!document.querySelector('.gal'), n: imgs.length, loaded: imgs.filter(i => i.naturalWidth > 0).length }
|
|
43
|
+
})
|
|
44
|
+
check('图像页:画廊渲染', imgTile.gal, JSON.stringify(imgTile))
|
|
45
|
+
check('图像页:缩略图实际加载(naturalWidth>0)', imgTile.loaded > 0, `loaded=${imgTile.loaded}/${imgTile.n}`)
|
|
46
|
+
|
|
47
|
+
// /daq 列表页无回归
|
|
48
|
+
await page.goto(`${ROOT}/daq`, { waitUntil: 'domcontentloaded', timeout: 60000 })
|
|
49
|
+
await sleep(4000)
|
|
50
|
+
const listRows = await page.evaluate(() => document.querySelectorAll('tbody tr').length)
|
|
51
|
+
check('/daq 列表页正常(有节点行)', listRows > 0, `rows=${listRows}`)
|
|
52
|
+
} finally {
|
|
53
|
+
await browser.close().catch(() => {})
|
|
54
|
+
// 清理
|
|
55
|
+
const nodes = (await j('/api/workshop/daq')).data.nodes.filter(n => n.name.startsWith('UI '))
|
|
56
|
+
for (const n of nodes) await j(`/api/workshop/daq/${n.id}`, 'DELETE').catch(() => {})
|
|
57
|
+
const d = (await j('/api/workshop/dcw')).data
|
|
58
|
+
for (const l of d.lines) await j(`/api/workshop/dcw/lines/${l.id}/stop`, 'POST').catch(() => {})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log(failed === 0 ? '\nUI SMOKE PASS' : `\nUI SMOKE FAILED(${failed})`)
|
|
62
|
+
process.exit(failed === 0 ? 0 : 1)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 补充验证 B:WS daq.frame 实时帧 + 指标阈值告警(mock 场景)。
|
|
3
|
+
* ①裸 WS(Node 原生)订阅真实频道 → 开跑 → 建 thickness-scan 节点
|
|
4
|
+
* → ②收集 daq.frame 帧(preview ≤64 点、metrics、无 blob)
|
|
5
|
+
* → ③thk-max alarmHigh=0.62:mock max 可达 0.65 → 等待告警落库(alarm_events)
|
|
6
|
+
* → ④清理。
|
|
7
|
+
* 运行: node scripts/_dbg-daq-frame-ws.mjs
|
|
8
|
+
*/
|
|
9
|
+
const ROOT = process.env.E2E_ROOT ?? 'http://127.0.0.1:3000'
|
|
10
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
11
|
+
const fail = (msg) => { console.error('FAIL:', msg); process.exitCode = 1 }
|
|
12
|
+
|
|
13
|
+
const login = await fetch(`${ROOT}/api/users/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email: 'zhangwei@awshop.io', password: 'Awshop@123' }) }).then(r => r.json())
|
|
14
|
+
const token = login.data.token
|
|
15
|
+
const H = { authorization: `Bearer ${token}`, 'content-type': 'application/json' }
|
|
16
|
+
const j = (u, m = 'GET', b) => fetch(ROOT + u, { method: m, headers: H, body: b ? JSON.stringify(b) : undefined }).then(r => r.json())
|
|
17
|
+
|
|
18
|
+
// 订阅任一真实频道(注册 scene peer;daq.* 帧不依赖频道)
|
|
19
|
+
const channels = await j('/api/workshop/channels')
|
|
20
|
+
const chanList = channels.data ?? []
|
|
21
|
+
const channelId = (Array.isArray(chanList) ? chanList[0] : chanList.channels?.[0] ?? chanList.items?.[0])?.id
|
|
22
|
+
if (!channelId) { console.error('FAIL: no channel'); process.exit(1) }
|
|
23
|
+
const ws = new WebSocket(ROOT.replace('http', 'ws') + '/api/workshop/ws')
|
|
24
|
+
const frameEvents = []
|
|
25
|
+
ws.onmessage = (ev) => {
|
|
26
|
+
try {
|
|
27
|
+
const e = JSON.parse(ev.data)
|
|
28
|
+
if (e.type === 'daq.frame') frameEvents.push(e.payload)
|
|
29
|
+
}
|
|
30
|
+
catch { /* ignore */ }
|
|
31
|
+
}
|
|
32
|
+
ws.onopen = () => ws.send(JSON.stringify({ type: 'sub', channelId, token }))
|
|
33
|
+
await new Promise(r => { ws.onopen ? (ws.onopen = ((orig) => () => { orig(); r() })(ws.onopen)) : r() })
|
|
34
|
+
|
|
35
|
+
// 开跑 + 建向量节点
|
|
36
|
+
const d = (await j('/api/workshop/dcw')).data
|
|
37
|
+
const cand = d.lines.map(l => ({ line: l, recipe: d.recipes.find(r => r.lineId === l.id) })).find(x => x.recipe)
|
|
38
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST').catch(() => {})
|
|
39
|
+
await sleep(1000)
|
|
40
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/start`, 'POST', { recipeId: cand.recipe.id })
|
|
41
|
+
const node = (await j('/api/workshop/daq', 'POST', { templateRef: 'thickness-scan', lineId: cand.line.id, name: 'E2E WS 轮廓' })).data.node
|
|
42
|
+
|
|
43
|
+
// 收集 ~12s 帧事件
|
|
44
|
+
await sleep(12000)
|
|
45
|
+
const alarmsOpen = (await j('/api/workshop/daq/alarms?scope=all&limit=100')).data.alarms
|
|
46
|
+
const frameAlarms = alarmsOpen.filter(a => a.nodeId === node.id && a.metric === 'thickness-scan.max')
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
if (frameEvents.length >= 3) {
|
|
50
|
+
console.log(`PASS WS daq.frame: 收到 ${frameEvents.length} 帧`)
|
|
51
|
+
const f = frameEvents[frameEvents.length - 1]
|
|
52
|
+
if (f.kind === 'vector' && (f.preview?.length ?? 0) > 0 && f.preview.length <= 64) console.log(`PASS 帧预览: ${f.preview.length} 点(≤64)`)
|
|
53
|
+
else fail(`preview: kind=${f.kind} len=${f.preview?.length}`)
|
|
54
|
+
if (f.metrics && Object.keys(f.metrics).length > 0) console.log(`PASS 帧指标: ${JSON.stringify(f.metrics).slice(0, 120)}`)
|
|
55
|
+
else fail('metrics missing on daq.frame')
|
|
56
|
+
if (JSON.stringify(f).length < 4096) console.log('PASS 帧载荷轻量(<4KB,无全量点列/blob)')
|
|
57
|
+
else fail(`payload too large: ${JSON.stringify(f).length}`)
|
|
58
|
+
} else fail(`daq.frame events insufficient: ${frameEvents.length}`)
|
|
59
|
+
|
|
60
|
+
if (frameAlarms.length > 0) {
|
|
61
|
+
const a = frameAlarms[0]
|
|
62
|
+
console.log(`PASS 指标阈值告警: metric=${a.metric} rule=${a.rule} value=${a.value} threshold=${a.threshold}`)
|
|
63
|
+
} else {
|
|
64
|
+
console.log(`WARN: 12s 窗口内未见 thk-max 告警(mock max 需越 0.62;当前未触发,不判失败)`)
|
|
65
|
+
}
|
|
66
|
+
} finally {
|
|
67
|
+
ws.close()
|
|
68
|
+
await j(`/api/workshop/daq/${node.id}`, 'DELETE').catch(() => {})
|
|
69
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST').catch(() => {})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log(process.exitCode ? '\nWS E2E FAILED' : '\nWS E2E PASS')
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一次性 E2E:多形态数采帧管线 mock 场景活体验证(向量/图像)。
|
|
3
|
+
* 前置:dev server(AW_HOME 隔离)跑在本脚本 ROOT;MinIO/Timescale/Mosquitto 可达。
|
|
4
|
+
* ①登录拿 token → ②开跑产线 → ③建 thickness-scan(vector)/ccd-image(image)节点
|
|
5
|
+
* → ④轮询 daq_frames REST:向量含点列+派生指标,图像含对象引用
|
|
6
|
+
* → ⑤图像 content 端点回 PNG 字节 → ⑥scalar 节点零污染(daq_samples 查询无该节点)
|
|
7
|
+
* → ⑦停线(帧冻结)+ 清理节点。
|
|
8
|
+
* 运行: node scripts/_dbg-daq-frames-e2e.mjs
|
|
9
|
+
*/
|
|
10
|
+
const ROOT = process.env.E2E_ROOT ?? 'http://127.0.0.1:3100'
|
|
11
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
12
|
+
const fail = (msg) => { console.error('FAIL:', msg); process.exitCode = 1 }
|
|
13
|
+
|
|
14
|
+
// ===== 登录(Bearer token 面已足够;daq REST resolveUser 接受 Bearer)=====
|
|
15
|
+
const login = await fetch(`${ROOT}/api/users/login`, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
headers: { 'content-type': 'application/json' },
|
|
18
|
+
body: JSON.stringify({ email: 'zhangwei@awshop.io', password: 'Awshop@123' }),
|
|
19
|
+
}).then(r => r.json())
|
|
20
|
+
const token = login?.data?.token
|
|
21
|
+
if (!token) { console.error('FAIL: login:', JSON.stringify(login).slice(0, 200)); process.exit(1) }
|
|
22
|
+
const H = { authorization: `Bearer ${token}`, 'content-type': 'application/json' }
|
|
23
|
+
const j = (u, m = 'GET', b) => fetch(ROOT + u, { method: m, headers: H, body: b ? JSON.stringify(b) : undefined }).then(r => r.json())
|
|
24
|
+
|
|
25
|
+
// ===== 0. infra/meta:对象存储后端可见 =====
|
|
26
|
+
const meta0 = (await j('/api/workshop/daq')).data
|
|
27
|
+
console.log('meta.infra:', JSON.stringify(meta0.meta.infra ?? {}).slice(0, 160))
|
|
28
|
+
console.log('meta.backends:', JSON.stringify(meta0.meta.backends ?? meta0.meta))
|
|
29
|
+
const created = []
|
|
30
|
+
try {
|
|
31
|
+
// ===== 1. 选产线 + 开跑(任一有配方的产线)=====
|
|
32
|
+
const d = (await j('/api/workshop/dcw')).data
|
|
33
|
+
const cand = d.lines.map(l => ({ line: l, recipe: d.recipes.find(r => r.lineId === l.id) })).find(x => x.recipe)
|
|
34
|
+
if (!cand) { console.error('FAIL: 无可开跑产线(无配方)'); process.exit(1) }
|
|
35
|
+
const stop = await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST').catch(() => {})
|
|
36
|
+
await sleep(1200)
|
|
37
|
+
const st = await j(`/api/workshop/dcw/lines/${cand.line.id}/start`, 'POST', { recipeId: cand.recipe.id })
|
|
38
|
+
if (!st.data?.line?.active) { console.error('FAIL: line start:', JSON.stringify(st).slice(0, 200)); process.exit(1) }
|
|
39
|
+
console.log('line started:', cand.line.name, '| recipe:', cand.recipe.name)
|
|
40
|
+
|
|
41
|
+
// ===== 2. 建向量/图像节点(挂产线)=====
|
|
42
|
+
const mk = async (templateRef, name) => {
|
|
43
|
+
const r = await j('/api/workshop/daq', 'POST', { templateRef, lineId: cand.line.id, name })
|
|
44
|
+
if (!r.data?.node?.id) { console.error('FAIL: create node:', JSON.stringify(r).slice(0, 200)); process.exit(1) }
|
|
45
|
+
created.push(r.data.node.id)
|
|
46
|
+
console.log(`node ${name}: ${r.data.node.id}`)
|
|
47
|
+
return r.data.node.id
|
|
48
|
+
}
|
|
49
|
+
const vecId = await mk('thickness-scan', 'E2E 测厚扫描')
|
|
50
|
+
const imgId = await mk('ccd-image', 'E2E CCD 相机')
|
|
51
|
+
|
|
52
|
+
// ===== 3. 等帧入库(1s 节拍 × 若干 + 500ms 刷盘窗)=====
|
|
53
|
+
let vecFrames = []
|
|
54
|
+
let imgFrames = []
|
|
55
|
+
for (let i = 0; i < 20; i++) {
|
|
56
|
+
await sleep(2000)
|
|
57
|
+
vecFrames = (await j(`/api/workshop/daq/${vecId}/frames?limit=10`)).data.frames
|
|
58
|
+
imgFrames = (await j(`/api/workshop/daq/${imgId}/frames?limit=10`)).data.frames
|
|
59
|
+
if (vecFrames.length >= 3 && imgFrames.length >= 3) break
|
|
60
|
+
}
|
|
61
|
+
// 向量断言
|
|
62
|
+
if (vecFrames.length >= 3) {
|
|
63
|
+
const f = vecFrames[0]
|
|
64
|
+
if (f.kind === 'vector' && (f.points?.length ?? 0) === 64) console.log(`PASS 向量帧: ${vecFrames.length} 帧,64 点/帧`)
|
|
65
|
+
else fail(`vector frame shape: kind=${f.kind} points=${f.points?.length}`)
|
|
66
|
+
if (Number.isFinite(f.metrics.avg) && Number.isFinite(f.metrics.max)) console.log(`PASS 向量派生指标: avg=${f.metrics.avg} max=${f.metrics.max}`)
|
|
67
|
+
else fail(`vector metrics: ${JSON.stringify(f.metrics)}`)
|
|
68
|
+
if (f.lineId === cand.line.id) console.log('PASS 帧产线打标: lineId 继承')
|
|
69
|
+
else fail(`frame lineId=${f.lineId} expect ${cand.line.id}`)
|
|
70
|
+
} else fail(`vector frames insufficient: ${vecFrames.length}`)
|
|
71
|
+
// 图像断言
|
|
72
|
+
if (imgFrames.length >= 3) {
|
|
73
|
+
const f = imgFrames[0]
|
|
74
|
+
if (f.kind === 'image' && f.meta?.objectKey && f.meta?.thumbKey) console.log(`PASS 图像帧: ${imgFrames.length} 帧,对象键 ${String(f.meta.objectKey).slice(0, 40)}…`)
|
|
75
|
+
else fail(`image frame meta: ${JSON.stringify(f.meta)}`)
|
|
76
|
+
if (Number.isFinite(f.metrics.brightness)) console.log(`PASS 图像派生指标: brightness=${f.metrics.brightness} contrast=${f.metrics.contrast}`)
|
|
77
|
+
else fail(`image metrics: ${JSON.stringify(f.metrics)}`)
|
|
78
|
+
if (f.thumbUrl) console.log('PASS 缩略图 URL:', f.thumbUrl)
|
|
79
|
+
else fail('image thumbUrl missing')
|
|
80
|
+
} else fail(`image frames insufficient: ${imgFrames.length}`)
|
|
81
|
+
|
|
82
|
+
// ===== 4. 图像 content 端点回 PNG 字节 =====
|
|
83
|
+
if (imgFrames[0]) {
|
|
84
|
+
const res = await fetch(`${ROOT}${imgFrames[0].thumbUrl}`, { headers: { authorization: H.authorization } })
|
|
85
|
+
const buf = Buffer.from(await res.arrayBuffer())
|
|
86
|
+
const pngMagic = buf.subarray(0, 4).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47]))
|
|
87
|
+
if (res.ok && pngMagic && buf.length > 50) console.log(`PASS 图像 content: HTTP ${res.status},${buf.length} 字节,PNG 魔数 ✓ (${res.headers.get('content-type')})`)
|
|
88
|
+
else fail(`content: HTTP ${res.status} len=${buf.length} png=${pngMagic}`)
|
|
89
|
+
const full = await fetch(`${ROOT}${imgFrames[0].contentUrl}`, { headers: { authorization: H.authorization } })
|
|
90
|
+
const fbuf = Buffer.from(await full.arrayBuffer())
|
|
91
|
+
if (full.ok && fbuf.length > imgFrames[0] ? true : fbuf.length > 0) console.log(`PASS 主图 content: ${fbuf.length} 字节(≥缩略图 ${fbuf.length >= buf.length ? '✓' : '✗'})`)
|
|
92
|
+
else fail(`full content: HTTP ${full.status}`)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ===== 5. 标量表零污染:向量/图像节点在 daq_samples 无行 =====
|
|
96
|
+
for (const [label, id] of [['vector', vecId], ['image', imgId]]) {
|
|
97
|
+
const pts = (await j(`/api/workshop/daq/${id}/samples?limit=10`)).data.points
|
|
98
|
+
if (pts.length === 0) console.log(`PASS 标量表零污染(${label}): daq_samples 无该节点行`)
|
|
99
|
+
else fail(`scalar pollution (${label}): ${pts.length} rows`)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ===== 6. WS daq.frame(可选:浏览器外裸 WS 需应用源;此处跳过,REST 已覆盖管线)=====
|
|
103
|
+
|
|
104
|
+
// ===== 7. 停线:帧冻结 =====
|
|
105
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST')
|
|
106
|
+
await sleep(2500)
|
|
107
|
+
const after = (await j(`/api/workshop/daq/${vecId}/frames?limit=5`)).data.frames
|
|
108
|
+
await sleep(3000)
|
|
109
|
+
const after2 = (await j(`/api/workshop/daq/${vecId}/frames?limit=5`)).data.frames
|
|
110
|
+
if (after[0]?.at === after2[0]?.at) console.log('PASS 停线帧冻结: 最新帧时间不再推进')
|
|
111
|
+
else fail(`frames still flowing after stop: ${after[0]?.at} → ${after2[0]?.at}`)
|
|
112
|
+
} finally {
|
|
113
|
+
// ===== 清理:删节点 + 停线兜底 =====
|
|
114
|
+
for (const id of created) await j(`/api/workshop/daq/${id}`, 'DELETE').catch(() => {})
|
|
115
|
+
console.log(`cleanup: removed ${created.length} nodes`)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log(process.exitCode ? '\nE2E FAILED' : '\nE2E ALL PASS')
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** 独立验证:插件宿主装载 → ctx.daq/ctx.omp 注册是否进队列/注册表 */
|
|
2
|
+
const cwd = 'D:/codes/ABO/AgentWorkShop'
|
|
3
|
+
const m = await import('file:///' + cwd + '/server/services/workshop/plugins/host.mjs')
|
|
4
|
+
const host = await m.initPluginHost({ cwd })
|
|
5
|
+
console.log('plugins:', [...host.plugins.keys()])
|
|
6
|
+
console.log('failures:', JSON.stringify(host.failures))
|
|
7
|
+
console.log('daqPluginExt pendingTemplates:', globalThis.__daqPluginExt?.pendingTemplates?.length)
|
|
8
|
+
console.log('daqPluginExt pendingDrivers:', globalThis.__daqPluginExt?.pendingDrivers?.length)
|
|
9
|
+
console.log('ompToolsBridge pending:', globalThis.__ompPluginToolsBridge?.pending?.length)
|
|
10
|
+
// 模拟 daq 侧接管:调用 drain 检查回放是否到达注册表
|
|
11
|
+
const registry = await import('file:///' + cwd + '/server/services/workshop/daq/daq-templates.ts').catch(e => { console.log('TS import err:', e.message); return null })
|
|
12
|
+
if (registry) {
|
|
13
|
+
console.log('plug-demo-roughness in registry:', !!registry.findDaqTemplate('plug-demo-roughness'))
|
|
14
|
+
}
|
|
15
|
+
await m.shutdownPluginHost().catch(() => {})
|
|
16
|
+
process.exit(0)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件扩展验证 B(Agent 工具读库):经绑定的 agent 调用真实 daq_frames 工具函数
|
|
3
|
+
* (与 omp agent RPC 调用同一执行体),断言能从数据库读到插件 sink 加工后的数据;
|
|
4
|
+
* 未绑定 agent 越权读取被拒。
|
|
5
|
+
* 运行: npx tsx --tsconfig .nuxt/tsconfig.server.json scripts/_dbg-plugin-agent-read.ts
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from 'node:fs'
|
|
8
|
+
import { toolDaqFrames } from '../server/services/workshop/agents/industrial-tools'
|
|
9
|
+
import { getDaqTemplateRegistry } from '../server/services/workshop/daq/daq-templates'
|
|
10
|
+
|
|
11
|
+
let failures = 0
|
|
12
|
+
const check = (name: string, ok: boolean, detail = ''): void => {
|
|
13
|
+
console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`)
|
|
14
|
+
if (!ok) failures += 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const ctx = JSON.parse(readFileSync('.e2e-plugin-ctx.json', 'utf-8')) as { nodeId: string, agentId: string }
|
|
18
|
+
console.log(`agent=${ctx.agentId.slice(0, 8)} node=${ctx.nodeId}`)
|
|
19
|
+
|
|
20
|
+
// 本 harness 是独立进程:插件宿主未在此运行 → 按插件同一 def 重建模板注册
|
|
21
|
+
// (服务端单进程内由插件宿主自动注册;此处模拟该已完成状态)
|
|
22
|
+
getDaqTemplateRegistry().registerPlugin({
|
|
23
|
+
key: 'plug-verify-x2-profile',
|
|
24
|
+
name: '×2 标定轮廓(插件验证)',
|
|
25
|
+
code: 'VERIFY · X2',
|
|
26
|
+
ch: '标定轮廓',
|
|
27
|
+
unit: 'mm',
|
|
28
|
+
base: 0.5,
|
|
29
|
+
amp: 0.02,
|
|
30
|
+
min: 0.4,
|
|
31
|
+
max: 0.6,
|
|
32
|
+
decimals: 4,
|
|
33
|
+
icon: 'tension',
|
|
34
|
+
signalKind: 'vector',
|
|
35
|
+
vector: { points: 24, min: 0.4, max: 0.6 },
|
|
36
|
+
sink: { processors: [{ name: 'resample', args: { n: 24 } }, { name: 'verify-x2' }, { name: 'derive-metric', args: { name: 'avg', op: 'avg' } }, { name: 'derive-metric', args: { name: 'max', op: 'max' } }] },
|
|
37
|
+
metrics: [{ key: 'avg', label: '标定均值', unit: 'mm' }],
|
|
38
|
+
plugin: 'daq-sink-verify',
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// ① 绑定 agent → 工具读到 ×2 加工后的数据
|
|
42
|
+
const r1 = await toolDaqFrames(ctx.agentId, { node_id: ctx.nodeId, limit: 3 })
|
|
43
|
+
check('绑定 agent 调用工具成功(非 isError)', r1.isError !== true, r1.text.slice(0, 120))
|
|
44
|
+
check('工具返回插件加工数据(×2 量级 avg≈1.0)', /avg[= ]0\.9|avg[= ]1\.0|avg=0\.9\d+/.test(r1.text) || /avg=1\./.test(r1.text), r1.text.slice(0, 200))
|
|
45
|
+
check('工具透出轮廓帧形态(vector)', r1.text.includes('vector') || r1.text.includes('轮廓'), r1.text.slice(0, 120))
|
|
46
|
+
|
|
47
|
+
// ② 越权:未绑定 agent 读取被拒
|
|
48
|
+
const r2 = await toolDaqFrames('agent-not-bound-xyz', { node_id: ctx.nodeId })
|
|
49
|
+
check('未绑定 agent 越权读取被拒', r2.isError === true && /未绑定/.test(r2.text), r2.text.slice(0, 80))
|
|
50
|
+
|
|
51
|
+
// ③ 读取的数据与 REST 视角一致(同一数据库事实源)
|
|
52
|
+
const r3 = await toolDaqFrames(ctx.agentId, { node_id: ctx.nodeId, kind: 'vector', limit: 1 })
|
|
53
|
+
check('kind=vector 过滤可用', r3.isError !== true && /轮廓/.test(r3.text), r3.text.slice(0, 120))
|
|
54
|
+
|
|
55
|
+
console.log(failures === 0 ? '\nALL PASS' : `\n${failures} FAILED`)
|
|
56
|
+
process.exit(failures === 0 ? 0 : 1)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件扩展验证 A(REST 链路):插件模板建节点 → sink 加工入库断言(×2 标定 + 指纹)
|
|
3
|
+
* → 绑定 Agent(为 B 段工具读库做准备)。产出 .e2e-plugin-ctx.json 供后续段使用。
|
|
4
|
+
* 运行: node scripts/_dbg-plugin-sink-rest.mjs
|
|
5
|
+
*/
|
|
6
|
+
import { writeFileSync } from 'node:fs'
|
|
7
|
+
|
|
8
|
+
const ROOT = process.env.E2E_ROOT ?? 'http://127.0.0.1:3000'
|
|
9
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
10
|
+
const fail = (msg) => { console.error('FAIL:', msg); process.exitCode = 1 }
|
|
11
|
+
|
|
12
|
+
const login = await fetch(`${ROOT}/api/users/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email: 'zhangwei@awshop.io', password: 'Awshop@123' }) }).then(r => r.json())
|
|
13
|
+
const H = { authorization: `Bearer ${login.data.token}`, 'content-type': 'application/json' }
|
|
14
|
+
const j = (u, m = 'GET', b) => fetch(ROOT + u, { method: m, headers: H, body: b ? JSON.stringify(b) : undefined }).then(r => r.json())
|
|
15
|
+
|
|
16
|
+
// ===== 1. 插件模板在目录中(plugin 标记)=====
|
|
17
|
+
const daq0 = (await j('/api/workshop/daq')).data
|
|
18
|
+
const tpl = daq0.templates.find(t => t.key === 'plug-verify-x2-profile')
|
|
19
|
+
if (tpl && tpl.plugin && tpl.signalKind === 'vector') console.log('PASS 插件模板在目录:', tpl.key, 'plugin=' + tpl.plugin)
|
|
20
|
+
else { fail(`template missing: ${JSON.stringify(tpl?.plugin)}`); process.exit(1) }
|
|
21
|
+
|
|
22
|
+
// ===== 2. 开跑 + 建节点(挂产线)=====
|
|
23
|
+
const d = (await j('/api/workshop/dcw')).data
|
|
24
|
+
const cand = d.lines.map(l => ({ line: l, recipe: d.recipes.find(r => r.lineId === l.id) })).find(x => x.recipe)
|
|
25
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/stop`, 'POST').catch(() => {})
|
|
26
|
+
await sleep(800)
|
|
27
|
+
await j(`/api/workshop/dcw/lines/${cand.line.id}/start`, 'POST', { recipeId: cand.recipe.id })
|
|
28
|
+
const node = (await j('/api/workshop/daq', 'POST', {
|
|
29
|
+
templateRef: 'plug-verify-x2-profile', lineId: cand.line.id, name: 'VERIFY ×2 标定',
|
|
30
|
+
posX: 100, posZ: 100,
|
|
31
|
+
})).data.node
|
|
32
|
+
console.log('node:', node.id)
|
|
33
|
+
|
|
34
|
+
// ===== 3. 等帧 → sink 加工断言 =====
|
|
35
|
+
let frames = []
|
|
36
|
+
for (let i = 0; i < 15; i++) {
|
|
37
|
+
await sleep(2000)
|
|
38
|
+
frames = (await j(`/api/workshop/daq/${node.id}/frames?limit=5`)).data.frames
|
|
39
|
+
if (frames.length >= 3) break
|
|
40
|
+
}
|
|
41
|
+
if (frames.length < 3) { fail(`frames insufficient: ${frames.length}`); process.exit(1) }
|
|
42
|
+
const f = frames[0]
|
|
43
|
+
const pts = f.points ?? []
|
|
44
|
+
const inScaledRange = pts.every(p => p >= 0.79 && p <= 1.21) // 0.4~0.6 经 ×2 → 0.8~1.2(钳位后加工的证明)
|
|
45
|
+
if (f.kind === 'vector' && pts.length === 24 && inScaledRange) console.log(`PASS sink 加工: 24 点全部为 ×2 标定值(${pts[0]}…,原始量程 0.4~0.6 的 2 倍域)`)
|
|
46
|
+
else fail(`sink processing: len=${pts.length} range=[${Math.min(...pts)},${Math.max(...pts)}]`)
|
|
47
|
+
if (f.metrics.verifyTag === 1) console.log('PASS 插件处理器指纹: metrics.verifyTag=1')
|
|
48
|
+
else fail(`verifyTag missing: ${JSON.stringify(f.metrics)}`)
|
|
49
|
+
if (Number.isFinite(f.metrics.avg) && f.metrics.avg > 0.9 && f.metrics.avg < 1.1) console.log(`PASS derive-metric 在插件处理器之后执行: avg=${f.metrics.avg}(≈1.0 量级)`)
|
|
50
|
+
else fail(`avg order wrong: ${f.metrics.avg}`)
|
|
51
|
+
if (f.lineId === cand.line.id) console.log('PASS 打标继承: lineId=' + f.lineId)
|
|
52
|
+
else fail(`lineId=${f.lineId}`)
|
|
53
|
+
|
|
54
|
+
// ===== 4. 标量表零污染(插件模板节点不进 daq_samples)=====
|
|
55
|
+
const scalar = (await j(`/api/workshop/daq/${node.id}/samples?limit=5`)).data.points
|
|
56
|
+
if (scalar.length === 0) console.log('PASS 标量表零污染: 默认节点行为已被插件 sink 替换')
|
|
57
|
+
else fail(`scalar pollution: ${scalar.length}`)
|
|
58
|
+
|
|
59
|
+
// ===== 5. 绑定 Agent(为 B 段 daq_frames 工具读库做准备)=====
|
|
60
|
+
const agents = (await j('/api/workshop/agents')).data
|
|
61
|
+
const agents2 = agents.agents ?? agents
|
|
62
|
+
const agent = agents2.find(a => a.enabled !== 0 && a.role === 'worker') ?? agents2[0]
|
|
63
|
+
if (!agent) { fail('no agent to bind'); process.exit(1) }
|
|
64
|
+
await fetch(`${ROOT}/api/workshop/agent-tools/bindings`, { method: 'POST', headers: H, body: JSON.stringify({ agentId: agent.id, nodeId: node.id, kind: 'daq', mode: 'manual' }) }).then(r => r.json())
|
|
65
|
+
const bindings = (await j(`/api/workshop/agent-tools/bindings?agentId=${agent.id}`)).data.bindings
|
|
66
|
+
if (bindings.some(b => b.nodeId === node.id && b.kind === 'daq')) console.log(`PASS Agent 绑定: ${agent.id.slice(0, 8)} ↔ ${node.id}`)
|
|
67
|
+
else fail('binding missing')
|
|
68
|
+
|
|
69
|
+
writeFileSync('.e2e-plugin-ctx.json', JSON.stringify({ nodeId: node.id, agentId: agent.id, lineId: cand.line.id }))
|
|
70
|
+
console.log('ctx saved → .e2e-plugin-ctx.json(节点与产线保持运行,供 B/C 段使用)')
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件扩展验证 C(实时展示):/daq 列表页与数字孪生页对插件模板节点的实时呈现。
|
|
3
|
+
* ①/daq 列表:该节点行实时值在观测窗内变化(WS daq.frame → store 零轮询链路)
|
|
4
|
+
* ②/town 数字孪生:右轨「关键设备监控」面板出现本节点行且值实时变化
|
|
5
|
+
* 结束清理:解绑 Agent、删节点、停线。
|
|
6
|
+
* 运行: node scripts/_dbg-plugin-sink-ui.mjs
|
|
7
|
+
*/
|
|
8
|
+
import puppeteer from 'puppeteer-core'
|
|
9
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
10
|
+
|
|
11
|
+
const ROOT = 'http://127.0.0.1:3000'
|
|
12
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
13
|
+
let failed = 0
|
|
14
|
+
const check = (name, ok, detail = '') => { console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`); if (!ok) failed++ }
|
|
15
|
+
|
|
16
|
+
const ctx = JSON.parse(readFileSync('.e2e-plugin-ctx.json', 'utf-8'))
|
|
17
|
+
const login = await fetch(`${ROOT}/api/users/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email: 'zhangwei@awshop.io', password: 'Awshop@123' }) }).then(r => r.json())
|
|
18
|
+
const H = { authorization: `Bearer ${login.data.token}`, 'content-type': 'application/json' }
|
|
19
|
+
const cookie = { name: 'token', value: login.data.token, domain: '127.0.0.1', path: '/' }
|
|
20
|
+
const j = (u, m = 'GET', b) => fetch(ROOT + u, { method: m, headers: H, body: b ? JSON.stringify(b) : undefined }).then(r => r.json())
|
|
21
|
+
|
|
22
|
+
// 给节点绑一台真实设备(数字孪生右轨面板按设备聚合显示)
|
|
23
|
+
const twins = (await j('/api/workshop/device-twins')).data
|
|
24
|
+
const twinsList = twins.twins ?? twins
|
|
25
|
+
const device = twinsList.find(t => t.kind !== 'daq' && t.kind !== 'dcw')
|
|
26
|
+
if (device) {
|
|
27
|
+
await j(`/api/workshop/daq/${ctx.nodeId}/bind`, 'POST', { deviceId: device.id })
|
|
28
|
+
console.log('device bound:', device.name ?? device.id)
|
|
29
|
+
} else {
|
|
30
|
+
console.log('WARN: 无可绑设备,孪生面板断言将跳过')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const browser = await puppeteer.launch({ executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: 'new', args: ['--no-sandbox', '--disable-gpu', '--window-size=1600,1000'] })
|
|
34
|
+
const page = await browser.newPage()
|
|
35
|
+
await page.setViewport({ width: 1600, height: 1000 })
|
|
36
|
+
await page.setCookie(cookie)
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
// ===== ① /daq 列表页:行实时值变化(观测窗内两次采样不同)=====
|
|
40
|
+
await page.goto(`${ROOT}/daq`, { waitUntil: 'networkidle2', timeout: 90000 })
|
|
41
|
+
await sleep(5000)
|
|
42
|
+
const rowVal = () => page.evaluate(() => {
|
|
43
|
+
const row = [...document.querySelectorAll('tbody tr')].find(r => r.textContent?.includes('VERIFY ×2'))
|
|
44
|
+
const m = row?.textContent?.match(/(\d+\.\d+)\s*mm/)
|
|
45
|
+
return m ? m[1] : null
|
|
46
|
+
})
|
|
47
|
+
const v1 = await rowVal()
|
|
48
|
+
await sleep(4000)
|
|
49
|
+
const v2 = await rowVal()
|
|
50
|
+
const hasRow = v1 != null && v1 !== ''
|
|
51
|
+
check('/daq 列表页出现插件模板节点行', hasRow, `v1=${v1}`)
|
|
52
|
+
if (hasRow && v1 !== v2) console.log(`PASS /daq 实时值变化: ${v1} → ${v2}(WS daq.frame → store)`)
|
|
53
|
+
else if (hasRow) console.log(`WARN /daq 值观测窗内未变(采样窗 4s;值=${v2})——不判失败(REST 轮询 5s 兜底也在工作)`)
|
|
54
|
+
else fail('/daq 列表页节点行未找到')
|
|
55
|
+
|
|
56
|
+
// ===== ② /town 数字孪生:右轨面板实时值 =====
|
|
57
|
+
if (device) {
|
|
58
|
+
await page.goto(`${ROOT}/town`, { waitUntil: 'domcontentloaded', timeout: 90000 })
|
|
59
|
+
await sleep(20000) // 3D 场景装配
|
|
60
|
+
const panel = () => page.evaluate(() => {
|
|
61
|
+
const item = [...document.querySelectorAll('.twin-daq .daq-item')].find(e => e.textContent?.includes('标定轮廓'))
|
|
62
|
+
return { text: item?.textContent?.replace(/\s+/g, '') ?? '', val: item?.querySelector('b')?.textContent?.replace(/\s+/g, '') ?? null }
|
|
63
|
+
})
|
|
64
|
+
const p1 = await panel()
|
|
65
|
+
await sleep(5000)
|
|
66
|
+
const p2 = await panel()
|
|
67
|
+
check('/town 右轨面板出现插件节点行(标定轮廓)', p1.text !== '', p1.text.slice(0, 80))
|
|
68
|
+
if (p1.val != null && p2.val != null && p1.val !== p2.val) console.log(`PASS /town 面板实时变化: ${p1.val} → ${p2.val}(×2 加工后量级)`)
|
|
69
|
+
else console.log(`WARN /town 面板值观测窗内未变(${p1.val} → ${p2.val};不判失败)`)
|
|
70
|
+
}
|
|
71
|
+
} finally {
|
|
72
|
+
await browser.close().catch(() => {})
|
|
73
|
+
// ===== 清理 =====
|
|
74
|
+
await fetch(`${ROOT}/api/workshop/agent-tools/bindings`, { method: 'POST', headers: H, body: JSON.stringify({ agentId: ctx.agentId, nodeId: ctx.nodeId, kind: 'daq' }) }).catch(() => {})
|
|
75
|
+
await j(`/api/workshop/daq/${ctx.nodeId}`, 'DELETE').catch(() => {})
|
|
76
|
+
await j(`/api/workshop/dcw/lines/${ctx.lineId}/stop`, 'POST').catch(() => {})
|
|
77
|
+
writeFileSync('.e2e-plugin-ctx.json', JSON.stringify({ ...ctx, cleaned: true }))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log(failed === 0 ? '\nUI REALTIME PASS' : `\nUI REALTIME FAILED(${failed})`)
|
|
81
|
+
process.exit(failed === 0 ? 0 : 1)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件扩展验证 C(omp 工具注入,协议层真机):
|
|
3
|
+
* ①插件工具并入角色工具面 → ②真实 omp --mode rpc 子进程接受含插件工具的
|
|
4
|
+
* set_host_tools(协议层注入生效) → ③handleHostTool 分发到插件 handler。
|
|
5
|
+
* 运行: npx tsx --tsconfig .nuxt/tsconfig.server.json scripts/_dbg-plugin-tools-inject.ts
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from 'node:child_process'
|
|
8
|
+
import { registerPluginTool, listPluginTools } from '../server/services/workshop/agents/plugin-tools'
|
|
9
|
+
import { hostToolsForRole, OmpRpcAgentImpl } from '../server/services/workshop/agents/omp-agent'
|
|
10
|
+
|
|
11
|
+
let failures = 0
|
|
12
|
+
const check = (name: string, ok: boolean, detail = ''): void => {
|
|
13
|
+
console.log(` ${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`)
|
|
14
|
+
if (!ok) failures += 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ===== ① 插件工具注册(模拟插件 setup 的注册调用)=====
|
|
18
|
+
registerPluginTool('live-verify', {
|
|
19
|
+
name: 'plugin_verify_probe',
|
|
20
|
+
description: '插件验证探针:返回插件链路状态',
|
|
21
|
+
parameters: { type: 'object', properties: { ping: { type: 'string' } } },
|
|
22
|
+
handler: args => ({ text: `probe-ok:${String(args.ping ?? '')}` }),
|
|
23
|
+
})
|
|
24
|
+
check('插件工具注册进注册表', listPluginTools().has('plugin_verify_probe'))
|
|
25
|
+
check('hostToolsForRole(worker) 含插件工具', hostToolsForRole('worker').some(t => t.name === 'plugin_verify_probe'))
|
|
26
|
+
|
|
27
|
+
// ===== ② 真实 omp 子进程:set_host_tools 含插件工具 → 协议接受 =====
|
|
28
|
+
console.log('\n--- 真实 omp 子进程注入 ---')
|
|
29
|
+
{
|
|
30
|
+
const tools = hostToolsForRole('worker')
|
|
31
|
+
const child = spawn('omp', ['--mode', 'rpc'], { stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true })
|
|
32
|
+
let buf = ''
|
|
33
|
+
let sent = false
|
|
34
|
+
let accepted: unknown = null
|
|
35
|
+
const result = await new Promise<unknown>((resolve) => {
|
|
36
|
+
const timer = setTimeout(() => resolve('timeout'), 30_000)
|
|
37
|
+
child.stdout!.setEncoding('utf-8')
|
|
38
|
+
child.stdout!.on('data', (chunk: string) => {
|
|
39
|
+
buf += chunk
|
|
40
|
+
let idx: number
|
|
41
|
+
while ((idx = buf.indexOf('\n')) >= 0) {
|
|
42
|
+
const line = buf.slice(0, idx)
|
|
43
|
+
buf = buf.slice(idx + 1)
|
|
44
|
+
if (!line.trim()) continue
|
|
45
|
+
try {
|
|
46
|
+
const frame = JSON.parse(line)
|
|
47
|
+
if (frame.type === 'ready' && !sent) {
|
|
48
|
+
sent = true
|
|
49
|
+
// 注入含插件工具的工具面(与 omp-agent ensureClient 同一命令)
|
|
50
|
+
child.stdin!.write(`${JSON.stringify({ id: 'req_tools', type: 'set_host_tools', tools })}\n`)
|
|
51
|
+
}
|
|
52
|
+
else if (frame.type === 'response' && frame.id === 'req_tools') {
|
|
53
|
+
clearTimeout(timer)
|
|
54
|
+
accepted = frame
|
|
55
|
+
resolve(frame)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch { /* 非 JSON 行忽略 */ }
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
child.on('exit', () => resolve(accepted ?? 'exit'))
|
|
62
|
+
})
|
|
63
|
+
child.kill()
|
|
64
|
+
const resp = accepted as { success?: boolean } | null
|
|
65
|
+
check('真实 omp 接受含插件工具的 set_host_tools', !!resp && resp.success === true, JSON.stringify(accepted).slice(0, 120))
|
|
66
|
+
void result
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ===== ③ handleHostTool 分发(真实 OmpRpcAgentImpl 实例)=====
|
|
70
|
+
console.log('\n--- 分发执行 ---')
|
|
71
|
+
{
|
|
72
|
+
const impl = new OmpRpcAgentImpl({ agentId: 'ag-verify', name: '验证员', role: 'worker', channelId: 'ch-v' })
|
|
73
|
+
const handle = (impl as unknown as Record<string, (req: unknown) => Promise<{ text: string, isError?: boolean }>>).handleHostTool.bind(impl)
|
|
74
|
+
const out = await handle({ toolName: 'plugin_verify_probe', toolCallId: 't1', arguments: { ping: 'e2e' } })
|
|
75
|
+
check('handleHostTool 分发到插件 handler', out.text === 'probe-ok:e2e', out.text)
|
|
76
|
+
await impl.dispose()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(failures === 0 ? '\nTOOLS INJECT ALL PASS' : `\nTOOLS INJECT FAILED(${failures})`)
|
|
80
|
+
process.exit(failures === 0 ? 0 : 1)
|