agentworkshop 0.7.23 → 0.7.27
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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/0jKrzLuM.js +19 -0
- package/.output/public/_nuxt/2jaJHWIJ.js +1 -0
- package/.output/public/_nuxt/{Cor9siSf.js → 6PZPfFcO.js} +1 -1
- package/.output/public/_nuxt/B7gZokg82.js +209 -0
- package/.output/public/_nuxt/B8kt898d.js +1 -0
- package/.output/public/_nuxt/{B-xskWta.js → BCJFMBQ6.js} +1 -1
- package/.output/public/_nuxt/BFGpEo8S.js +1 -0
- package/.output/public/_nuxt/BG4zduPf.js +14 -0
- package/.output/public/_nuxt/{DNxVTfhe.js → BGhOrgle.js} +1 -1
- package/.output/public/_nuxt/{n3vMFfrv.js → BHcpzI2n.js} +3 -3
- package/.output/public/_nuxt/{CEHmSufQ.js → BTLEvDxM.js} +1 -1
- package/.output/public/_nuxt/{CYBq3kS7.js → BWyR3awA.js} +1 -1
- package/.output/public/_nuxt/Bc89zKq2.js +1 -0
- package/.output/public/_nuxt/BetmGSO4.js +1 -0
- package/.output/public/_nuxt/{DAR70Lf5.js → BgCrZKv_2.js} +1 -1
- package/.output/public/_nuxt/BowTbasd.js +1 -0
- package/.output/public/_nuxt/BvtknqSC2.js +1 -0
- package/.output/public/_nuxt/CJviSvm-.js +1 -0
- package/.output/public/_nuxt/CTfqWGdy.js +1 -0
- package/.output/public/_nuxt/Cb3SnTM8.js +1 -0
- package/.output/public/_nuxt/Chc5pfAA.js +1 -0
- package/.output/public/_nuxt/CmHzfVc5.js +3 -0
- package/.output/public/_nuxt/Cn3J3NXR.js +23 -0
- package/.output/public/_nuxt/CobSUzQv.js +2 -0
- package/.output/public/_nuxt/{kZV5TQvh2.js → CucID8qg2.js} +1 -1
- package/.output/public/_nuxt/{CfVAr2nf.js → Cz9gD2Yo.js} +1 -1
- package/.output/public/_nuxt/{E88a-JCG.js → DGAOugLt.js} +1 -1
- package/.output/public/_nuxt/DHbTyoAV.js +1 -0
- package/.output/public/_nuxt/{BxtpDtzC.js → DNQF_TXX.js} +1 -1
- package/.output/public/_nuxt/DfLUN8kY.js +1 -0
- package/.output/public/_nuxt/DjU9Dx5Y.js +1 -0
- package/.output/public/_nuxt/DnziMlcX.js +1 -0
- package/.output/public/_nuxt/{BBwMH_hG.js → DoAlYsiF.js} +1 -1
- package/.output/public/_nuxt/{DA4lxCWC2.js → DosOJEmZ2.js} +2 -2
- package/.output/public/_nuxt/{DWcEk1ur2.js → DvgKXPgu2.js} +1 -1
- package/.output/public/_nuxt/{ed5qX-x5.js → Q_SJDSgx.js} +1 -1
- package/.output/public/_nuxt/{TownView.zu2rU5nS.css → TownView.CtskuMXS.css} +1 -1
- package/.output/public/_nuxt/XY2z78rj.js +1 -0
- package/.output/public/_nuxt/_id_.DdbYeLqn.css +1 -0
- package/.output/public/_nuxt/bFnZa2yd.js +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/f7a8e33d-5422-45ac-895d-27168f97e3ad.json +1 -0
- package/.output/public/_nuxt/daq.DGV9QS8d.css +1 -0
- package/.output/public/_nuxt/entry.BN02X8iR.css +1 -0
- package/.output/public/_nuxt/monitor.B--1dPzs.css +1 -0
- package/.output/public/_nuxt/permissions.B1pjGChZ.css +1 -0
- package/.output/public/_nuxt/plugins.DpCuwaJt.css +1 -0
- package/.output/public/_nuxt/rkVgzg62.js +1 -0
- package/.output/public/_nuxt/settings.W6qrYAui.css +1 -0
- package/.output/public/_nuxt/teams.BBXVkyKq.css +1 -0
- package/.output/public/_nuxt/tokens.xRb1fSPU.css +1 -0
- package/.output/public/_nuxt/users.DuAt_Zwf.css +1 -0
- package/.output/public/_nuxt/workshop.BJg84pOK.css +1 -0
- package/.output/public/assets/game/character/yangyang-walk.glb +0 -0
- package/.output/server/chunks/_/host-bindings.mjs +1 -1
- package/.output/server/chunks/_/nitro.mjs +1073 -925
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/build/{OmpTerminalPanel-Ban3yJZ4.mjs → OmpTerminalPanel-Cw_Vw9oO.mjs} +3 -3
- package/.output/server/chunks/build/{OmpTerminalPanel-Ban3yJZ4.mjs.map → OmpTerminalPanel-Cw_Vw9oO.mjs.map} +1 -1
- package/.output/server/chunks/build/{TownView-DxeQe1Bl.mjs → TownView-ftIylqiD.mjs} +178 -151
- package/.output/server/chunks/build/{TownView-DxeQe1Bl.mjs.map → TownView-ftIylqiD.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-DQDqj-cZ.mjs → _id_-3Axz2-gV.mjs} +35 -35
- package/.output/server/chunks/build/{_id_-DQDqj-cZ.mjs.map → _id_-3Axz2-gV.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-DY6v6sqB.mjs → _id_-CahfkmEt.mjs} +5 -5
- package/.output/server/chunks/build/{_id_-DY6v6sqB.mjs.map → _id_-CahfkmEt.mjs.map} +1 -1
- package/.output/server/chunks/build/{_wsId_-C2O5zZsI.mjs → _wsId_-BymlQhzS.mjs} +13 -15
- package/.output/server/chunks/build/{_wsId_-C2O5zZsI.mjs.map → _wsId_-BymlQhzS.mjs.map} +1 -1
- package/.output/server/chunks/build/{agents--6bzGtES.mjs → agents-DuMiSWKp.mjs} +7 -9
- package/.output/server/chunks/build/agents-DuMiSWKp.mjs.map +1 -0
- package/.output/server/chunks/build/button-DEcZFcqN.mjs +1 -1
- package/.output/server/chunks/build/{card-CCPQoKlh.mjs → card-Dipvaykh.mjs} +4 -4
- package/.output/server/chunks/build/{card-CCPQoKlh.mjs.map → card-Dipvaykh.mjs.map} +1 -1
- package/.output/server/chunks/build/{channel-templates-C1Bb-U75.mjs → channel-templates-BStqJ-of.mjs} +5 -7
- package/.output/server/chunks/build/channel-templates-BStqJ-of.mjs.map +1 -0
- package/.output/server/chunks/build/{checkbox-Dv1kjaUZ.mjs → checkbox-C1gABOca.mjs} +5 -5
- package/.output/server/chunks/build/{checkbox-Dv1kjaUZ.mjs.map → checkbox-C1gABOca.mjs.map} +1 -1
- package/.output/server/chunks/build/{daq-B-3xCp_2.mjs → daq-ChYCABz1.mjs} +312 -426
- package/.output/server/chunks/build/daq-ChYCABz1.mjs.map +1 -0
- package/.output/server/chunks/build/{dcw-BL2dhuz7.mjs → dcw-CcQNGggh.mjs} +3 -3
- package/.output/server/chunks/build/{dcw-BL2dhuz7.mjs.map → dcw-CcQNGggh.mjs.map} +1 -1
- package/.output/server/chunks/build/{default-DdV642BY.mjs → default-95-zOTPt.mjs} +3 -4
- package/.output/server/chunks/build/{default-DdV642BY.mjs.map → default-95-zOTPt.mjs.map} +1 -1
- package/.output/server/chunks/build/dropdown-vhn1NPFs.mjs +1 -1
- package/.output/server/chunks/build/{input-number-CZ3ZrCsy.mjs → input-number-Bd55elNN.mjs} +3 -3
- package/.output/server/chunks/build/{input-number-CZ3ZrCsy.mjs.map → input-number-Bd55elNN.mjs.map} +1 -1
- package/.output/server/chunks/build/{input-DxDqeyQW.mjs → input-sf_BT6o6.mjs} +553 -5
- package/.output/server/chunks/build/input-sf_BT6o6.mjs.map +1 -0
- package/.output/server/chunks/build/{logs-Dto_umFY.mjs → logs-D-2UyGtE.mjs} +3 -3
- package/.output/server/chunks/build/{logs-Dto_umFY.mjs.map → logs-D-2UyGtE.mjs.map} +1 -1
- package/.output/server/chunks/build/menu-WCrlpYVh.mjs +2 -2
- package/.output/server/chunks/build/modal-yvUquPj5.mjs +2 -2
- package/.output/server/chunks/build/{monitor-miqq9xHB.mjs → monitor-mfG5jBtz.mjs} +70 -192
- package/.output/server/chunks/build/monitor-mfG5jBtz.mjs.map +1 -0
- package/.output/server/chunks/build/{pages-D9tOoJsf.mjs → pages-Dfosfchr.mjs} +5 -6
- package/.output/server/chunks/build/pages-Dfosfchr.mjs.map +1 -0
- package/.output/server/chunks/build/{permissions-CxEgXic0.mjs → permissions-B-hhZuzm.mjs} +288 -194
- package/.output/server/chunks/build/permissions-B-hhZuzm.mjs.map +1 -0
- package/.output/server/chunks/build/{plugins-wLIKHcIE.mjs → plugins-DZR0T4Mh.mjs} +17 -17
- package/.output/server/chunks/build/{plugins-wLIKHcIE.mjs.map → plugins-DZR0T4Mh.mjs.map} +1 -1
- package/.output/server/chunks/build/popconfirm-CRaHcz5O.mjs +1 -1
- package/.output/server/chunks/build/{segmented-ChmQZwz6.mjs → segmented-LPPREMtZ.mjs} +336 -5
- package/.output/server/chunks/build/{segmented-ChmQZwz6.mjs.map → segmented-LPPREMtZ.mjs.map} +1 -1
- package/.output/server/chunks/build/{settings-BPBll_7K.mjs → settings-BajN9TQW.mjs} +254 -27
- package/.output/server/chunks/build/settings-BajN9TQW.mjs.map +1 -0
- package/.output/server/chunks/build/space-CCBYAkXt.mjs +1 -1
- package/.output/server/chunks/build/switch-CelRXpcy.mjs +1 -1
- package/.output/server/chunks/build/{table-BtksyDlQ.mjs → table-Bf1r2JjE.mjs} +5 -5
- package/.output/server/chunks/build/{table-BtksyDlQ.mjs.map → table-Bf1r2JjE.mjs.map} +1 -1
- package/.output/server/chunks/build/{tabs-DQv-_-R6.mjs → tabs-BM3tAh_J.mjs} +2 -2
- package/.output/server/chunks/build/{tabs-DQv-_-R6.mjs.map → tabs-BM3tAh_J.mjs.map} +1 -1
- package/.output/server/chunks/build/{tag-A0tZ2Ouq.mjs → tag-NO9jEqKy.mjs} +3 -3
- package/.output/server/chunks/build/{tag-A0tZ2Ouq.mjs.map → tag-NO9jEqKy.mjs.map} +1 -1
- package/.output/server/chunks/build/{teams-DD8ZXTKL.mjs → teams-t2SkRlJP.mjs} +349 -51
- package/.output/server/chunks/build/teams-t2SkRlJP.mjs.map +1 -0
- package/.output/server/chunks/build/{tokens-Dxnuw96_.mjs → tokens-DiCojbN8.mjs} +296 -200
- package/.output/server/chunks/build/tokens-DiCojbN8.mjs.map +1 -0
- package/.output/server/chunks/build/{town-Dsh0jlwZ.mjs → town-C7QM8DYK.mjs} +5 -5
- package/.output/server/chunks/build/{town-Dsh0jlwZ.mjs.map → town-C7QM8DYK.mjs.map} +1 -1
- package/.output/server/chunks/build/{useDaqStream-DkRL3tEW.mjs → useDaqStream-BeA2X8KR.mjs} +26 -11
- package/.output/server/chunks/build/useDaqStream-BeA2X8KR.mjs.map +1 -0
- package/.output/server/chunks/build/{useDcwStream-DyB2ufQI.mjs → useDcwStream-BJW_MitY.mjs} +14 -6
- package/.output/server/chunks/build/useDcwStream-BJW_MitY.mjs.map +1 -0
- package/.output/server/chunks/build/{useDeviceTwins-ZbT86L9O.mjs → useDeviceTwins-Dwz_EY_i.mjs} +2 -2
- package/.output/server/chunks/build/{useDeviceTwins-ZbT86L9O.mjs.map → useDeviceTwins-Dwz_EY_i.mjs.map} +1 -1
- package/.output/server/chunks/build/{useOpsLog-8HCYFb6n.mjs → useOpsLog-Dm8QEb1I.mjs} +2 -2
- package/.output/server/chunks/build/{useOpsLog-8HCYFb6n.mjs.map → useOpsLog-Dm8QEb1I.mjs.map} +1 -1
- package/.output/server/chunks/build/{useWorkshopApi-D2gq06N2.mjs → useWorkshopApi-B-L3MmIX.mjs} +9 -2
- package/.output/server/chunks/build/{useWorkshopApi-D2gq06N2.mjs.map → useWorkshopApi-B-L3MmIX.mjs.map} +1 -1
- package/.output/server/chunks/build/{users-D6RNylrW.mjs → users-B9SAdEtH.mjs} +12 -13
- package/.output/server/chunks/build/users-B9SAdEtH.mjs.map +1 -0
- package/.output/server/chunks/build/{workshop-CTcYDq2i.mjs → workshop-81xhz368.mjs} +21 -22
- package/.output/server/chunks/build/workshop-81xhz368.mjs.map +1 -0
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +14 -2
- package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +40 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +21 -9
- package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +33 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/channels.post.mjs +15 -1
- 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 +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.get.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
- package/.output/server/chunks/routes/renderer.mjs +3 -3
- package/.output/server/chunks/virtual/entry.mjs +381 -438
- package/.output/server/chunks/virtual/entry.mjs.map +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/app/app.vue +7 -0
- package/app/assets/css/main.css +12 -1
- package/app/components/workshop/DaqNodeRow.vue +398 -0
- package/app/components/workshop/town/ModelPreview3D.vue +26 -4
- package/app/components/workshop/town/TownScene3D.ts +60 -12
- package/app/components/workshop/town/TownView.vue +4 -3
- package/app/composables/workshop/useCharacterAssets.ts +1 -0
- package/app/composables/workshop/useDaqStream.ts +24 -5
- package/app/composables/workshop/useDcwStream.ts +13 -4
- package/app/composables/workshop/useWorkshopApi.ts +294 -259
- package/app/pages/daq/[id].vue +27 -3
- package/app/pages/daq/index.vue +8 -355
- package/app/pages/monitor.vue +56 -68
- package/app/pages/permissions/index.vue +86 -82
- package/app/pages/plugins/index.vue +12 -7
- package/app/pages/settings.vue +253 -2
- package/app/pages/tokens.vue +94 -96
- package/app/pages/users.vue +10 -18
- package/app/pages/workshop/index.vue +34 -5
- package/app/pages/workshop/teams.vue +212 -2
- package/i18n/dicts/_en.json +361 -1
- package/i18n/dicts/plugins.json +10 -0
- package/i18n/dicts/settings.json +1 -0
- package/i18n/dicts/teamPlugins.json +10 -0
- package/i18n/locales/en.ts +1861 -1901
- package/i18n/locales/zh-CN.ts +1789 -1830
- package/package.json +149 -148
- package/public/assets/game/character/yangyang-walk.glb +0 -0
- package/scripts/_dbg-cpu-profile.mjs +53 -0
- package/scripts/_dbg-logs-ui-e2e.py +3 -2
- package/scripts/_dbg-render-perf.mjs +142 -0
- package/scripts/_dbg-render-regression.mjs +130 -0
- package/scripts/_dbg-ui-survey.py +52 -0
- package/scripts/i18n-merge.mjs +152 -30
- package/scripts/production-closed-loop-e2e.mjs +254 -0
- package/scripts/team-plugins-api-smoke.mjs +149 -0
- package/scripts/three-system-e2e.mjs +448 -0
- package/server/api/plugins/[name]/[...path].ts +46 -31
- package/server/api/workshop/channels/[id]/plugins/index.get.ts +35 -0
- package/server/api/workshop/channels/[id]/plugins/index.put.ts +39 -0
- package/server/api/workshop/channels.post.ts +17 -0
- package/server/data/dcw-lines.json +14 -0
- package/server/data/dcw-products.json +14 -0
- package/server/data/dcw-recipes.json +23 -1
- package/server/data/dcw-rollback.json +585 -10
- package/server/data/dcw-runs.json +27 -27
- package/server/data/dcw-writes.json +96 -0
- package/server/data/dcws.json +394 -366
- package/server/data/scene-layouts.json +66 -0
- package/server/plugins/aw-plugins.ts +35 -27
- package/server/plugins-builtin/diag-bridge/index.mjs +556 -0
- package/server/plugins-builtin/rag-bridge/index.mjs +364 -0
- package/server/services/workshop/agents/host-tool-bridge.ts +659 -642
- package/server/services/workshop/agents/omp-agent.ts +1178 -1178
- package/server/services/workshop/agents/plugin-tools.ts +10 -1
- package/server/services/workshop/db/channel-plugins.repo.ts +65 -0
- package/server/services/workshop/plugins/host.mjs +52 -4
- package/server/services/workshop/runtime/manager.ts +2976 -2968
- package/shared/config/schema.json +4 -0
- package/.output/public/_nuxt/BJbhwS5o.js +0 -1
- package/.output/public/_nuxt/BUcmySDa2.js +0 -209
- package/.output/public/_nuxt/BWC4HQHQ.js +0 -1
- package/.output/public/_nuxt/BbZAzXjZ2.js +0 -1
- package/.output/public/_nuxt/BgOhoDTI.js +0 -1
- package/.output/public/_nuxt/Bo8t5fkJ.js +0 -1
- package/.output/public/_nuxt/BuiGDfMB.js +0 -1
- package/.output/public/_nuxt/BxPPAkGA.js +0 -3
- package/.output/public/_nuxt/C53drffV.js +0 -1
- package/.output/public/_nuxt/CcwJ2mrD2.js +0 -1
- package/.output/public/_nuxt/Cr9DkD1d.js +0 -1
- package/.output/public/_nuxt/DTYBfjRY.js +0 -1
- package/.output/public/_nuxt/DVoWWlUW.js +0 -1
- package/.output/public/_nuxt/Dc32T41C.js +0 -1
- package/.output/public/_nuxt/Dhqra7NB.js +0 -1
- package/.output/public/_nuxt/DlRO_q5L.js +0 -1
- package/.output/public/_nuxt/DsUUYP292.js +0 -1
- package/.output/public/_nuxt/Dsdy4Ua-.js +0 -1
- package/.output/public/_nuxt/DtzZqC0z.js +0 -1
- package/.output/public/_nuxt/Ko9mMsJj.js +0 -14
- package/.output/public/_nuxt/RzXYI9FM.js +0 -23
- package/.output/public/_nuxt/UtviM1bg.js +0 -1
- package/.output/public/_nuxt/_id_.C-YXjn8Q.css +0 -1
- package/.output/public/_nuxt/bAFueD6a.js +0 -1
- package/.output/public/_nuxt/builds/meta/1adc96e0-8bbd-4a79-ac7e-b6952556fef8.json +0 -1
- package/.output/public/_nuxt/daq.3OKj58HH.css +0 -1
- package/.output/public/_nuxt/dbi5bHkY.js +0 -2
- package/.output/public/_nuxt/eHYnGew0.js +0 -19
- package/.output/public/_nuxt/entry.OR_psZHp.css +0 -1
- package/.output/public/_nuxt/jyQyulh-.js +0 -1
- package/.output/public/_nuxt/monitor.CmwpEUCI.css +0 -1
- package/.output/public/_nuxt/permissions.DTRtZeTw.css +0 -1
- package/.output/public/_nuxt/plugins.BcSEwwGb.css +0 -1
- package/.output/public/_nuxt/settings.BqMF2nfj.css +0 -1
- package/.output/public/_nuxt/teams.DN0pAGGu.css +0 -1
- package/.output/public/_nuxt/tokens.BVXU1jOK.css +0 -1
- package/.output/public/_nuxt/users.D8lcLE62.css +0 -1
- package/.output/public/_nuxt/workshop.CbymC2LY.css +0 -1
- package/.output/public/_nuxt/zVkqCZ78.js +0 -1
- package/.output/server/chunks/build/Col-biaNnEPf.mjs +0 -338
- package/.output/server/chunks/build/Col-biaNnEPf.mjs.map +0 -1
- package/.output/server/chunks/build/agents--6bzGtES.mjs.map +0 -1
- package/.output/server/chunks/build/channel-templates-C1Bb-U75.mjs.map +0 -1
- package/.output/server/chunks/build/daq-B-3xCp_2.mjs.map +0 -1
- package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs +0 -554
- package/.output/server/chunks/build/hasIn-vQ9LWt-J.mjs.map +0 -1
- package/.output/server/chunks/build/input-DxDqeyQW.mjs.map +0 -1
- package/.output/server/chunks/build/monitor-miqq9xHB.mjs.map +0 -1
- package/.output/server/chunks/build/pages-D9tOoJsf.mjs.map +0 -1
- package/.output/server/chunks/build/permissions-CxEgXic0.mjs.map +0 -1
- package/.output/server/chunks/build/settings-BPBll_7K.mjs.map +0 -1
- package/.output/server/chunks/build/teams-DD8ZXTKL.mjs.map +0 -1
- package/.output/server/chunks/build/tokens-Dxnuw96_.mjs.map +0 -1
- package/.output/server/chunks/build/useDaqStream-DkRL3tEW.mjs.map +0 -1
- package/.output/server/chunks/build/useDcwStream-DyB2ufQI.mjs.map +0 -1
- package/.output/server/chunks/build/useSiteConfig-DJe_KMVr.mjs +0 -27
- package/.output/server/chunks/build/useSiteConfig-DJe_KMVr.mjs.map +0 -1
- package/.output/server/chunks/build/users-D6RNylrW.mjs.map +0 -1
- package/.output/server/chunks/build/workshop-CTcYDq2i.mjs.map +0 -1
- /package/.output/public/_nuxt/{CNs_Ozdc.js → CNs_Ozdc2.js} +0 -0
- /package/.output/public/_nuxt/{Cno6kYiO.js → Cno6kYiO2.js} +0 -0
- /package/.output/public/_nuxt/{ORt9oDIy2.js → ORt9oDIy.js} +0 -0
|
@@ -1,642 +1,659 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HostToolBridge —— workspace 工具桥(harness 无关)。
|
|
3
|
-
*
|
|
4
|
-
* 把 omp-agent 时代的 host tool 定义/角色装配/分发逻辑抽为共享模块:
|
|
5
|
-
* - omp:保持原生 host_tool_call → dispatch(经本桥);
|
|
6
|
-
* - codex/dsh/opencode:经 stdio MCP 桥(server/harness/aw-mcp-bridge.mjs)
|
|
7
|
-
* → HTTP agent-tools 面 → impl.dispatchHostTool → 同一本桥;
|
|
8
|
-
* - REST 直调(agent-tools/invoke)同样落本桥。
|
|
9
|
-
* 从而"工具注册一套逻辑、注入与分发全引擎一致"。
|
|
10
|
-
*
|
|
11
|
-
* 分发语义与原 omp 实现逐字节对齐:插件工具优先 → workspace 协作/任务/记忆面 →
|
|
12
|
-
* 工业工具族 → 插件兜底 → 未知工具报错。
|
|
13
|
-
*/
|
|
14
|
-
import { randomUUID } from 'node:crypto'
|
|
15
|
-
import type {
|
|
16
|
-
AgentInfo,
|
|
17
|
-
AgentWorkspace,
|
|
18
|
-
} from './agent-interface'
|
|
19
|
-
import type { A2AArtifact, Part } from '../types/a2a'
|
|
20
|
-
import type { WorkspaceTask } from '../types/task'
|
|
21
|
-
import type { RpcHostToolDefinition } from './adapters/omp-rpc-client'
|
|
22
|
-
import { loadHostToolDefs } from '../prompts/loader'
|
|
23
|
-
import { daqRuntimeSettings } from '../settings'
|
|
24
|
-
import { toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMyIndustrialNodes, toolOpsLog, toolRecipeLog, toolRecipeRollback, toolRecipeUpdate, toolRecipeVersions } from './industrial-tools'
|
|
25
|
-
import { listPluginTools } from './plugin-tools'
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
:
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
)
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
].
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
return {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
return {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const
|
|
547
|
-
const
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
case '
|
|
582
|
-
const agentId = args.agent_id as string
|
|
583
|
-
const
|
|
584
|
-
const
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* HostToolBridge —— workspace 工具桥(harness 无关)。
|
|
3
|
+
*
|
|
4
|
+
* 把 omp-agent 时代的 host tool 定义/角色装配/分发逻辑抽为共享模块:
|
|
5
|
+
* - omp:保持原生 host_tool_call → dispatch(经本桥);
|
|
6
|
+
* - codex/dsh/opencode:经 stdio MCP 桥(server/harness/aw-mcp-bridge.mjs)
|
|
7
|
+
* → HTTP agent-tools 面 → impl.dispatchHostTool → 同一本桥;
|
|
8
|
+
* - REST 直调(agent-tools/invoke)同样落本桥。
|
|
9
|
+
* 从而"工具注册一套逻辑、注入与分发全引擎一致"。
|
|
10
|
+
*
|
|
11
|
+
* 分发语义与原 omp 实现逐字节对齐:插件工具优先 → workspace 协作/任务/记忆面 →
|
|
12
|
+
* 工业工具族 → 插件兜底 → 未知工具报错。
|
|
13
|
+
*/
|
|
14
|
+
import { randomUUID } from 'node:crypto'
|
|
15
|
+
import type {
|
|
16
|
+
AgentInfo,
|
|
17
|
+
AgentWorkspace,
|
|
18
|
+
} from './agent-interface'
|
|
19
|
+
import type { A2AArtifact, Part } from '../types/a2a'
|
|
20
|
+
import type { WorkspaceTask } from '../types/task'
|
|
21
|
+
import type { RpcHostToolDefinition } from './adapters/omp-rpc-client'
|
|
22
|
+
import { loadHostToolDefs } from '../prompts/loader'
|
|
23
|
+
import { daqRuntimeSettings } from '../settings'
|
|
24
|
+
import { toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMyIndustrialNodes, toolOpsLog, toolRecipeLog, toolRecipeRollback, toolRecipeUpdate, toolRecipeVersions } from './industrial-tools'
|
|
25
|
+
import { listPluginTools, pluginOfTool } from './plugin-tools'
|
|
26
|
+
import { getChannelPluginsRepo } from '../db/channel-plugins.repo'
|
|
27
|
+
import { extractTaskMode } from '../runtime/execution-mode'
|
|
28
|
+
|
|
29
|
+
/** host tool 定义(外置 .AgentWorkShop/prompts/host-tools.json;加载器缓存) */
|
|
30
|
+
export const HOST_TOOLS: RpcHostToolDefinition[] = loadHostToolDefs()
|
|
31
|
+
|
|
32
|
+
/** 仅 lead 可见的工具名(dispatch/调度/团队管理面;worker 注册时剔除,压缩工具上下文) */
|
|
33
|
+
export const LEAD_ONLY_TOOL_NAMES = new Set([
|
|
34
|
+
'dispatch_task',
|
|
35
|
+
'get_queue_overview',
|
|
36
|
+
'read_channel_mail',
|
|
37
|
+
'reassign_task',
|
|
38
|
+
'update_task',
|
|
39
|
+
'create_team_agent',
|
|
40
|
+
'update_team_agent',
|
|
41
|
+
'remove_team_agent',
|
|
42
|
+
])
|
|
43
|
+
|
|
44
|
+
/** 占位符动态注入:工具描述里的运行时配置值(每次装配实时计算,配置热重载后 Agent 拿到新值) */
|
|
45
|
+
function applyDescriptionPlaceholders(tools: RpcHostToolDefinition[]): RpcHostToolDefinition[] {
|
|
46
|
+
let q: { defaultBucketMs: number, minBucketMs: number } | null = null
|
|
47
|
+
try {
|
|
48
|
+
q = daqRuntimeSettings().query
|
|
49
|
+
}
|
|
50
|
+
catch { /* 设置系统不可用(单测) → 保留原始描述 */ }
|
|
51
|
+
if (!q) return tools
|
|
52
|
+
const map: Record<string, string> = {
|
|
53
|
+
queryDefaultBucketMs: String(q.defaultBucketMs),
|
|
54
|
+
queryMinBucketMs: String(q.minBucketMs),
|
|
55
|
+
}
|
|
56
|
+
return tools.map(t => ({
|
|
57
|
+
...t,
|
|
58
|
+
description: t.description.replace(/\{(queryDefaultBucketMs|queryMinBucketMs)\}/g, (_, k) => map[k] ?? _),
|
|
59
|
+
parameters: JSON.parse(JSON.stringify(t.parameters ?? {}).replace(/\{(queryDefaultBucketMs|queryMinBucketMs)\}/g, (_m: string, k: string) => map[k] ?? _m)),
|
|
60
|
+
}))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 按角色装配 host tools:lead = 全量;worker = 剔除 lead 专属(执行面 + 通信面 + 记忆面);
|
|
65
|
+
* 尾部合并插件注册工具(roles 过滤,缺省双角色可用;channelId 给定且该团队有显式
|
|
66
|
+
* 插件开关时,关闭的插件其工具不注入 —— 防不需要插件的 channel 上下文被污染)。
|
|
67
|
+
* 全 harness 共用:omp 经 set_host_tools 下发;其余引擎经 MCP 桥 tools/list 拉取。
|
|
68
|
+
*/
|
|
69
|
+
export function hostToolsForRole(role: 'lead' | 'worker', channelId?: string): RpcHostToolDefinition[] {
|
|
70
|
+
const base = role === 'lead'
|
|
71
|
+
? HOST_TOOLS
|
|
72
|
+
: HOST_TOOLS.filter(t => !LEAD_ONLY_TOOL_NAMES.has(t.name))
|
|
73
|
+
const out = [...base]
|
|
74
|
+
// 团队级插件开关:显式配置过的 channel 按行过滤;未配置(无行)= 全启用,向后兼容
|
|
75
|
+
const channelOff = channelId
|
|
76
|
+
? getChannelPluginsRepo().explicitFor(channelId)
|
|
77
|
+
: null
|
|
78
|
+
for (const [name, tool] of listPluginTools()) {
|
|
79
|
+
if (out.some(t => t.name === name)) continue
|
|
80
|
+
if (tool.roles && !tool.roles.includes(role)) continue
|
|
81
|
+
const owner = pluginOfTool(name)
|
|
82
|
+
if (channelOff && owner && channelOff.get(owner) === false) continue
|
|
83
|
+
out.push({ name, label: tool.label ?? name, description: tool.description, parameters: tool.parameters ?? {} })
|
|
84
|
+
}
|
|
85
|
+
return applyDescriptionPlaceholders(out)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 工具调用请求(与引擎协议解耦的规范化形状) */
|
|
89
|
+
export interface HostToolCall {
|
|
90
|
+
toolName: string
|
|
91
|
+
arguments: Record<string, unknown>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface HostToolResult {
|
|
95
|
+
text: string
|
|
96
|
+
isError?: boolean
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 会话态(impl 持有,桥读写):当前执行任务 + 待回执上下文 */
|
|
100
|
+
export interface HostToolSessionState {
|
|
101
|
+
currentTaskId: string | null
|
|
102
|
+
replyContext: { fromId: string, messageId: string } | null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function createSessionState(): HostToolSessionState {
|
|
106
|
+
return { currentTaskId: null, replyContext: null }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** 桥上下文:impl 注入身份与 workspace 取值器 */
|
|
110
|
+
export interface HostToolBridgeContext {
|
|
111
|
+
identity: { agentId: string, channelId: string, role: 'lead' | 'worker', name: string }
|
|
112
|
+
state: HostToolSessionState
|
|
113
|
+
getWorkspace(): AgentWorkspace | null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** 从消息 parts 提取纯文本(多 harness 共用) */
|
|
117
|
+
export function partsToText(parts: Part[]): string {
|
|
118
|
+
return parts
|
|
119
|
+
.map((p) => {
|
|
120
|
+
if ('text' in p) return p.text
|
|
121
|
+
if ('data' in p) return JSON.stringify(p.data)
|
|
122
|
+
if ('url' in p) return p.url
|
|
123
|
+
if ('raw' in p) return p.raw
|
|
124
|
+
return ''
|
|
125
|
+
})
|
|
126
|
+
.join('\n')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* 分发一次 host tool 调用(全引擎唯一入口):
|
|
131
|
+
* 插件工具优先 → workspace 面 → 工业工具族 → 插件兜底 → 未知工具。
|
|
132
|
+
*/
|
|
133
|
+
export async function dispatchHostTool(ctx: HostToolBridgeContext, req: HostToolCall): Promise<HostToolResult> {
|
|
134
|
+
const identity = ctx.identity
|
|
135
|
+
// 插件工具分发(ctx.omp.registerTool 注册的自定义工具;不依赖 workspace,优先于内置面)
|
|
136
|
+
const pluginTool = listPluginTools().get(req.toolName)
|
|
137
|
+
if (pluginTool) {
|
|
138
|
+
// 团队级插件开关:显式关闭的插件,其工具在该团队拒绝执行(与注入过滤同源)
|
|
139
|
+
const channelOff = getChannelPluginsRepo().explicitFor(identity.channelId)
|
|
140
|
+
const owner = pluginOfTool(req.toolName)
|
|
141
|
+
if (channelOff && owner && channelOff.get(owner) === false) {
|
|
142
|
+
return {
|
|
143
|
+
text: `该团队未启用插件「${owner}」,${req.toolName} 不可用。可在团队设置→插件中开启。`,
|
|
144
|
+
isError: true,
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
return await pluginTool.handler(req.arguments ?? {}, identity)
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return {
|
|
152
|
+
text: `工具执行异常(${req.toolName}): ${err instanceof Error ? err.message : String(err)}`,
|
|
153
|
+
isError: true,
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const args = req.arguments ?? {}
|
|
158
|
+
|
|
159
|
+
// 工业工具族不依赖 workspace(只按 agentId 查绑定与节点),先于 workspace 门控执行 ——
|
|
160
|
+
// 否则 worker 首回合前的 REST/MCP 直调(my_industrial_nodes 等)会被误拒
|
|
161
|
+
switch (req.toolName) {
|
|
162
|
+
case 'my_industrial_nodes':
|
|
163
|
+
return toolMyIndustrialNodes(identity.agentId)
|
|
164
|
+
case 'dcw_control':
|
|
165
|
+
return toolDcwControl(identity.agentId, args as { node_id?: string, value?: number | string, hypothesis?: string, task_id?: string })
|
|
166
|
+
case 'dcw_read':
|
|
167
|
+
return toolDcwRead(identity.agentId, args as { node_id?: string })
|
|
168
|
+
case 'daq_query':
|
|
169
|
+
return toolDaqQuery(identity.agentId, args as Parameters<typeof toolDaqQuery>[1])
|
|
170
|
+
case 'daq_frames':
|
|
171
|
+
return toolDaqFrames(identity.agentId, args as Parameters<typeof toolDaqFrames>[1])
|
|
172
|
+
case 'dcw_judge':
|
|
173
|
+
return toolDcwJudge(identity.agentId, args as { record_id?: string, verdict?: string, reason?: string })
|
|
174
|
+
case 'dcw_rollback':
|
|
175
|
+
return toolDcwRollback(identity.agentId, args as { record_id?: string, node_id?: string, to?: string })
|
|
176
|
+
case 'dcw_journal':
|
|
177
|
+
return toolDcwJournal(identity.agentId, args as { node_id?: string, recipe_id?: string, limit?: number | string })
|
|
178
|
+
case 'ops_log':
|
|
179
|
+
return toolOpsLog(identity.agentId, args as Parameters<typeof toolOpsLog>[1])
|
|
180
|
+
case 'recipe_log':
|
|
181
|
+
return toolRecipeLog(identity.agentId, args as Parameters<typeof toolRecipeLog>[1])
|
|
182
|
+
case 'line_context':
|
|
183
|
+
return toolLineContext(identity.agentId, args as { line_id?: string })
|
|
184
|
+
case 'recipe_versions':
|
|
185
|
+
return toolRecipeVersions(identity.agentId, args as { recipe_id?: string, limit?: number | string })
|
|
186
|
+
case 'recipe_update':
|
|
187
|
+
return toolRecipeUpdate(identity.agentId, args as Parameters<typeof toolRecipeUpdate>[1])
|
|
188
|
+
case 'recipe_rollback':
|
|
189
|
+
return toolRecipeRollback(identity.agentId, args as Parameters<typeof toolRecipeRollback>[1])
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const ws = ctx.getWorkspace()
|
|
193
|
+
if (!ws) {
|
|
194
|
+
return { text: 'workspace 未就绪', isError: true }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
switch (req.toolName) {
|
|
199
|
+
case 'report_progress': {
|
|
200
|
+
const progress = args.progress as number
|
|
201
|
+
const message = args.message as string | undefined
|
|
202
|
+
const taskId = ctx.state.currentTaskId
|
|
203
|
+
if (!taskId) return { text: '无当前任务上下文', isError: true }
|
|
204
|
+
await ws.reportTask({ taskId, progress, message })
|
|
205
|
+
return { text: `进度已上报: ${progress}%${message ? ` (${message})` : ''}` }
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
case 'complete_task': {
|
|
209
|
+
const summary = args.summary as string
|
|
210
|
+
const deliverable = args.deliverable as string | undefined
|
|
211
|
+
const taskId = (args.task_id as string | undefined) ?? ctx.state.currentTaskId
|
|
212
|
+
if (!taskId) return { text: '无任务 ID', isError: true }
|
|
213
|
+
// 父任务保护:有未完成子任务时拒绝完成(lead 须等 worker 交付)
|
|
214
|
+
const allTasks = await ws.listTasks()
|
|
215
|
+
const incompleteChildren = allTasks.filter(t => t.parentId === taskId && t.state !== 'COMPLETED' && t.state !== 'CANCELED')
|
|
216
|
+
if (incompleteChildren.length > 0) {
|
|
217
|
+
return {
|
|
218
|
+
text: `任务 ${taskId} 有 ${incompleteChildren.length} 个未完成子任务,不能完成父任务。请等待子任务完成。`,
|
|
219
|
+
isError: true,
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// 终态幂等:任务已被平台收口(看门狗取消/调度器完成)时不撞状态机 ——
|
|
223
|
+
// 给 Agent 明确的"无需再完成,继续下一项"信号,杜绝重复重试烧 token
|
|
224
|
+
const current = await ws.getTask(taskId)
|
|
225
|
+
if (current && current.state !== 'SUBMITTED' && current.state !== 'ASSIGNED' && current.state !== 'WORKING' && current.state !== 'WAITING') {
|
|
226
|
+
if (current.state === 'COMPLETED') {
|
|
227
|
+
return { text: `任务 ${taskId} 已是完成状态(可能已被平台收口),无需重复完成。` }
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
const q = await ws.myQueue()
|
|
231
|
+
const next = q.queued[0]
|
|
232
|
+
return {
|
|
233
|
+
text: `任务 ${taskId} 已被平台${current.state === 'CANCELED' ? '取消(如停滞回收/上级作废)' : '判定失败'},不能再标记完成 —— 这不是你的错误,也无需重试。${next ? `队列还有 ${q.queued.length} 项,下一项「${next.title}」即将开始,请继续处理。` : '队列为空,保持待命。'}`,
|
|
234
|
+
isError: false,
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return { text: `任务 ${taskId} 已被平台${current.state === 'CANCELED' ? '取消' : '判定失败'},无需再完成,请继续处理队列下一项。` }
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const artifacts: A2AArtifact[] = []
|
|
242
|
+
if (deliverable || summary) {
|
|
243
|
+
artifacts.push({
|
|
244
|
+
artifactId: randomUUID(),
|
|
245
|
+
name: 'deliverable',
|
|
246
|
+
parts: [{ text: deliverable ?? summary }],
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
await ws.completeTask(taskId, artifacts)
|
|
250
|
+
ctx.state.currentTaskId = null
|
|
251
|
+
// 完成即衔接:报告队列余量与下一项(状态同步 + 驱动继续处理)
|
|
252
|
+
try {
|
|
253
|
+
const q = await ws.myQueue()
|
|
254
|
+
const next = q.queued[0]
|
|
255
|
+
if (next) {
|
|
256
|
+
return {
|
|
257
|
+
text: `任务 ${taskId} 已完成(状态已同步为 COMPLETED)。你的队列还有 ${q.queued.length} 项待处理,下一项:「${next.title}」(即将自动开始;收到任务指派消息后按工作流执行,完成后同样调用 complete_task)。`,
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return { text: `任务 ${taskId} 已完成(状态已同步为 COMPLETED),队列为空。保持待命:新任务/实时消息会自动到达你的信箱。` }
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return { text: `任务 ${taskId} 已完成(状态已同步为 COMPLETED)。` }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
case 'dispatch_task': {
|
|
268
|
+
const assigneeId = args.assignee_id as string
|
|
269
|
+
const title = args.title as string
|
|
270
|
+
const description = args.description as string | undefined
|
|
271
|
+
const parentTaskId = args.parent_task_id as string | undefined
|
|
272
|
+
const routeReason = args.route_reason as string | undefined
|
|
273
|
+
// 重复派发守卫(真实场景实测:lead 模型可能对同一目标重复派发,引发协调风暴):
|
|
274
|
+
// 同父任务下已存在同标题非终态子任务 → 不再创建,直接指路既有任务
|
|
275
|
+
const dup = await ws.listTasks()
|
|
276
|
+
const existing = dup.find(t =>
|
|
277
|
+
t.parentId === parentTaskId
|
|
278
|
+
&& t.title === title
|
|
279
|
+
&& t.state !== 'COMPLETED' && t.state !== 'FAILED' && t.state !== 'CANCELED')
|
|
280
|
+
if (existing) {
|
|
281
|
+
return {
|
|
282
|
+
text: `未创建:同父任务下已存在同标题进行中子任务 ${existing.id}("${existing.title}",state=${existing.state},assignee=${existing.assigneeId})。请勿重复派发;若需跟进请对该任务 notify 或 reassign。`,
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const task = await ws.dispatchTask({ assigneeId, title, description, parentTaskId, routeReason })
|
|
286
|
+
return { text: `子任务 ${task.id} 已创建并指派 → ${assigneeId}(父任务 ${parentTaskId ?? '无'},标题: ${title}${routeReason ? `,路由理由: ${routeReason}` : ''})` }
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
case 'send_message_to_agent': {
|
|
290
|
+
const toAgentId = args.to_agent_id as string
|
|
291
|
+
const message = args.message as string
|
|
292
|
+
// 回执自动实时:回复(in_reply_to)默认提升为 immediate——
|
|
293
|
+
// 接收方正等待该结果,realtime 路由会把回复直接注入其运行中的会话
|
|
294
|
+
let priority = (args.priority as string | undefined) ?? 'task'
|
|
295
|
+
const metadata: Record<string, unknown> = {}
|
|
296
|
+
if (args.require_reply === true) metadata['x-aw-require-reply'] = 'true'
|
|
297
|
+
let inReplyTo = args.in_reply_to as string | undefined
|
|
298
|
+
// 自动关联兜底:LLM 省略 in_reply_to 时,按待回执上下文盖章
|
|
299
|
+
const replyCtx = ctx.state.replyContext
|
|
300
|
+
ctx.state.replyContext = null
|
|
301
|
+
if (!inReplyTo && replyCtx && replyCtx.fromId === toAgentId) {
|
|
302
|
+
inReplyTo = replyCtx.messageId
|
|
303
|
+
}
|
|
304
|
+
if (inReplyTo) {
|
|
305
|
+
metadata['x-aw-in-reply-to'] = inReplyTo
|
|
306
|
+
if (priority === 'task') priority = 'immediate'
|
|
307
|
+
}
|
|
308
|
+
metadata['x-aw-msg-priority'] = priority
|
|
309
|
+
const sent = await ws.sendMessage({ toAgentId, parts: [{ text: message }], metadata })
|
|
310
|
+
const triggerNote = inReplyTo
|
|
311
|
+
? `(回复 ${inReplyTo.slice(0, 8)}…,已实时推送给对方)`
|
|
312
|
+
: metadata['x-aw-require-reply'] === 'true' ? '(已要求对方回复)' : ''
|
|
313
|
+
return { text: `消息 ${sent.messageId.slice(0, 8)}… 已发送给 ${toAgentId}(priority=${priority})${triggerNote}` }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
case 'send_cross_channel_message': {
|
|
317
|
+
const toChannelId = args.to_channel_id as string
|
|
318
|
+
const message = args.message as string
|
|
319
|
+
if (!toChannelId || !message) return { text: '缺少 to_channel_id 或 message', isError: true }
|
|
320
|
+
try {
|
|
321
|
+
const r = await ws.sendCrossChannelMessage({
|
|
322
|
+
toChannelId,
|
|
323
|
+
parts: [{ text: message }],
|
|
324
|
+
requireReply: args.require_reply === true,
|
|
325
|
+
inReplyTo: args.in_reply_to as string | undefined,
|
|
326
|
+
})
|
|
327
|
+
const note = args.require_reply === true ? '(已要求对方 Leader 回复)' : ''
|
|
328
|
+
return { text: `跨 Channel 消息 ${r.messageId.slice(0, 8)}… 已送达 channel「${r.toChannelName}」的 Leader(${r.toLeadAgentId.slice(0, 8)}…)${note}。对方将按你的信息需求处理;其回复会经 mailbox 到达你这里。` }
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
return { text: `跨 Channel 发送失败: ${err instanceof Error ? err.message : String(err)}(仅 Leader 可跨 Channel 通信)`, isError: true }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
case 'list_other_teams': {
|
|
336
|
+
const teams = await ws.listOtherTeams()
|
|
337
|
+
if (teams.length === 0) return { text: '当前没有其他团队(或均未启用)。' }
|
|
338
|
+
const text = teams.map((t) => {
|
|
339
|
+
const active = t.activeTasks.length > 0
|
|
340
|
+
? t.activeTasks.map(x => `「${x.title}」(${x.state})`).join('、')
|
|
341
|
+
: '无进行中任务'
|
|
342
|
+
const done = t.recentCompleted.length > 0
|
|
343
|
+
? t.recentCompleted.map(x => `「${x.title}」`).join('、')
|
|
344
|
+
: '无'
|
|
345
|
+
const mem = t.sharedMemories > 0 ? `共享记忆 ${t.sharedMemories} 条(可检索)` : '暂无共享记忆'
|
|
346
|
+
return `- ${t.name}${t.description ? `(${t.description})` : ''} · lead=${t.leadName ?? '?'} · ${mem}\n 进行中: ${active}\n 近期完成: ${done}\n channel_id: ${t.channelId}`
|
|
347
|
+
}).join('\n')
|
|
348
|
+
return { text: `其他团队概览:\n${text}\n(需要协作时用 send_cross_channel_message 向对应团队 Leader 发信;查具体知识用 search_other_teams_memory)` }
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
case 'search_other_teams_memory': {
|
|
352
|
+
const query = (args.query as string | undefined) ?? ''
|
|
353
|
+
if (!query) return { text: '缺少 query', isError: true }
|
|
354
|
+
const rows = await ws.searchOtherTeamsMemory({ query, limit: Number(args.limit ?? 5) })
|
|
355
|
+
if (rows.length === 0) return { text: `其他团队的共享记忆中没有命中「${query}」的内容。` }
|
|
356
|
+
const text = rows.map(r =>
|
|
357
|
+
`- [${r.channelName}] 「${r.title}」(${r.createdAt.slice(0, 10)}): ${r.content}`).join('\n')
|
|
358
|
+
return { text: `其他团队共享记忆命中 ${rows.length} 条:\n${text}` }
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
case 'refuse_task': {
|
|
362
|
+
const taskId = args.task_id as string
|
|
363
|
+
const reason = args.reason as string
|
|
364
|
+
if (!taskId || !reason) return { text: '缺少 task_id 或 reason', isError: true }
|
|
365
|
+
const r = await ws.refuseTask(taskId, reason)
|
|
366
|
+
const notified = r.notifiedTo ? `拒绝回执已送达 ${r.notifiedTo.slice(0, 8)}` : '无回执对象(创建者已不在 channel)'
|
|
367
|
+
return {
|
|
368
|
+
text: `任务 ${taskId.slice(0, 8)}("${r.task.title}") 已拒绝(state=${r.task.state});${notified}。调度器将改派他人,请勿再处理该任务。`,
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
case 'poll_messages': {
|
|
373
|
+
const limit = (args.limit as number | undefined) ?? 10
|
|
374
|
+
const waitSec = Math.min(180, Math.max(0, Number(args.wait_seconds ?? 0) || 0))
|
|
375
|
+
const msgs = await ws.waitMailbox(limit, waitSec * 1000)
|
|
376
|
+
if (msgs.length === 0) {
|
|
377
|
+
return {
|
|
378
|
+
text: waitSec > 0
|
|
379
|
+
? `等待 ${waitSec}s 后收件箱仍为空。若此前已有"[实时消息 from X]"注入你的会话,那就是回复本身(无需再轮询);否则可继续处理其他工作,对方回复会以新回合送达。`
|
|
380
|
+
: '收件箱为空(无未消费消息)。等待回复请用 wait_seconds 参数阻塞等待,不要反复空轮询。',
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// 读即取:协作消息(非任务投递)取出即确认;任务指派(assign)不确认
|
|
384
|
+
const ackIds = msgs
|
|
385
|
+
.filter(m => !m.metadata?.['x-aw-task-kind'])
|
|
386
|
+
.map(m => m.messageId)
|
|
387
|
+
if (ackIds.length > 0) await ws.ackMailbox(ackIds)
|
|
388
|
+
const trigger = msgs.find(m =>
|
|
389
|
+
m.metadata?.['x-aw-require-reply'] === 'true'
|
|
390
|
+
&& typeof m.metadata?.['x-aw-from-agent'] === 'string')
|
|
391
|
+
if (trigger) {
|
|
392
|
+
ctx.state.replyContext = {
|
|
393
|
+
fromId: String(trigger.metadata!['x-aw-from-agent']),
|
|
394
|
+
messageId: trigger.messageId,
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const text = msgs.map((m, i) => {
|
|
398
|
+
const from = m.metadata?.['x-aw-from-agent'] ?? '?'
|
|
399
|
+
const reply = m.metadata?.['x-aw-in-reply-to']
|
|
400
|
+
? ` (回复 ${String(m.metadata['x-aw-in-reply-to']).slice(0, 8)}…)`
|
|
401
|
+
: ''
|
|
402
|
+
const needReply = m.metadata?.['x-aw-require-reply'] === 'true'
|
|
403
|
+
? ` [需回复:用 send_message_to_agent 回 ${from},in_reply_to=${m.messageId}]`
|
|
404
|
+
: ''
|
|
405
|
+
const body = m.parts.map(p => 'text' in p ? p.text : '').join(' ')
|
|
406
|
+
return ` [${i + 1}/${msgs.length}] [from ${from}]${needReply}${reply} ${body.slice(0, 2000)}`
|
|
407
|
+
}).join('\n')
|
|
408
|
+
return {
|
|
409
|
+
text:
|
|
410
|
+
`未消费消息(${msgs.length},已读即取):\n${text}`
|
|
411
|
+
+ (msgs.length > 1
|
|
412
|
+
? '\n(收到多条:请按编号逐条处理并逐条回复,不要只回应最后一条或合并敷衍)'
|
|
413
|
+
: ''),
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
case 'read_channel_mail': {
|
|
418
|
+
const limit = (args.limit as number | undefined) ?? 50
|
|
419
|
+
const agentId = args.agent_id as string | undefined
|
|
420
|
+
const mails = await ws.listMail({ limit, agentId })
|
|
421
|
+
if (mails.length === 0) return { text: 'Channel 无邮件记录(或该成员无往来)' }
|
|
422
|
+
const text = mails.map((m) => {
|
|
423
|
+
const from = m.fromAgentId ?? '(系统)'
|
|
424
|
+
const to = m.toAgentId ?? '(广播)'
|
|
425
|
+
const body = partsToText(m.parts).trim().slice(0, 2000)
|
|
426
|
+
const reply = m.metadata?.['x-aw-in-reply-to']
|
|
427
|
+
? ` [回复 ${String(m.metadata['x-aw-in-reply-to']).slice(0, 8)}…]`
|
|
428
|
+
: ''
|
|
429
|
+
const label = m.metadata?.['x-aw-task-kind'] === 'assign'
|
|
430
|
+
? '[任务指派]'
|
|
431
|
+
: m.metadata?.['x-aw-msg-priority'] === 'immediate' ? '[实时]' : '[协作]'
|
|
432
|
+
const state = m.state === 'pending' ? '未读' : m.state === 'consuming' ? '处理中' : '已读'
|
|
433
|
+
return ` ${m.createdAt.slice(11, 19)} ${label} ${from} → ${to} (${state})${reply}: ${body || '(空)'}`
|
|
434
|
+
}).join('\n')
|
|
435
|
+
return { text: `Channel 邮件(${mails.length},倒序;可传 agent_id 查看指定成员信箱):\n${text}` }
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
case 'broadcast_message': {
|
|
439
|
+
const message = args.message as string
|
|
440
|
+
const priority = (args.priority as string | undefined) ?? 'task'
|
|
441
|
+
const agents = await ws.listAgents()
|
|
442
|
+
const others = agents.filter(a => a.id !== identity.agentId)
|
|
443
|
+
for (const agent of others) {
|
|
444
|
+
await ws.sendMessage({
|
|
445
|
+
toAgentId: agent.id,
|
|
446
|
+
parts: [{ text: message }],
|
|
447
|
+
metadata: { 'x-aw-msg-priority': priority },
|
|
448
|
+
})
|
|
449
|
+
}
|
|
450
|
+
return { text: `已广播给 ${others.length} 个 agent(priority=${priority})` }
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
case 'list_channel_tasks': {
|
|
454
|
+
const tasks = await ws.listTasks()
|
|
455
|
+
const text = tasks.map(t =>
|
|
456
|
+
` ${t.id} [${t.state}] "${t.title}" assignee=${t.assigneeId} progress=${t.progress}%`,
|
|
457
|
+
).join('\n')
|
|
458
|
+
return { text: `Channel 任务(${tasks.length}):\n${text || '(空)'}` }
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
case 'get_my_task_queue': {
|
|
462
|
+
const queue = await ws.myQueue()
|
|
463
|
+
const fmt = (t: WorkspaceTask): string =>
|
|
464
|
+
` ${t.id} [${t.state}] "${t.title}" progress=${t.progress}%`
|
|
465
|
+
return {
|
|
466
|
+
text: [
|
|
467
|
+
`我的任务队列(${identity.role}):`,
|
|
468
|
+
`执行中: ${queue.current ? `${queue.current.id} "${queue.current.title}" (${queue.current.progress}%)` : '(无)'}`,
|
|
469
|
+
`待执行(${queue.queued.length},FIFO):`,
|
|
470
|
+
...queue.queued.map(fmt),
|
|
471
|
+
`已完成(${queue.completed.length}):`,
|
|
472
|
+
...queue.completed.map(fmt),
|
|
473
|
+
].join('\n'),
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
case 'get_queue_overview': {
|
|
478
|
+
const overview = await ws.queueOverview()
|
|
479
|
+
const lines = overview.map(s =>
|
|
480
|
+
` ${s.agentId} (${s.name}, role=${s.role}, state=${s.state}, current=${s.currentTaskId ?? '-'}${s.currentTaskTitle ? `「${s.currentTaskTitle}」` : ''}, progress=${s.currentTaskProgress ?? '-'}%, queued=${s.queuedCount}, completed=${s.completedCount})`,
|
|
481
|
+
)
|
|
482
|
+
return { text: `团队队列总览(${overview.length}):\n${lines.join('\n') || '(空)'}` }
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
case 'reassign_task': {
|
|
486
|
+
const taskId = args.task_id as string
|
|
487
|
+
const toAgentId = args.to_agent_id as string
|
|
488
|
+
const task = await ws.reassignTask(taskId, toAgentId)
|
|
489
|
+
return { text: `任务 ${taskId}("${task.title}")已调配 → ${toAgentId}(state=${task.state})` }
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
case 'update_task': {
|
|
493
|
+
const taskId = args.task_id as string
|
|
494
|
+
const title = args.title as string | undefined
|
|
495
|
+
const description = args.description as string | undefined
|
|
496
|
+
const task = await ws.updateTask(taskId, { title, description })
|
|
497
|
+
return { text: `任务 ${taskId} 已更新: "${task.title}"` }
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
case 'cancel_task': {
|
|
501
|
+
const taskId = args.task_id as string
|
|
502
|
+
// 守卫:goal/loop/pipeline 的 mode 父任务是用户的作业主任务,Agent 不得经工具取消
|
|
503
|
+
const target = await ws.getTask(taskId).catch(() => null)
|
|
504
|
+
if (target && extractTaskMode(target)) {
|
|
505
|
+
return {
|
|
506
|
+
text: `拒绝:任务 ${taskId} 是 mode 父任务(${target.title}),不能用 cancel_task 取消。若目标未达成 → dispatch_task 派发子任务补齐差距;若确认无法达成 → complete_task 并在交付中说明未达成原因。终止整个作业请由用户操作。`,
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
await ws.cancelTask(taskId)
|
|
510
|
+
return { text: `任务 ${taskId} 已取消并移出 assignee 队列` }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
case 'list_team_agents': {
|
|
514
|
+
const agents = await ws.listAgents()
|
|
515
|
+
const text = agents.map(a =>
|
|
516
|
+
` ${a.id} (${a.name}, role=${a.role}, harness=${a.harness})`,
|
|
517
|
+
).join('\n')
|
|
518
|
+
return { text: `团队成员(${agents.length}):\n${text || '(空)'}` }
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
case 'get_task_details': {
|
|
522
|
+
const taskId = args.task_id as string
|
|
523
|
+
const task: WorkspaceTask = await ws.getTask(taskId)
|
|
524
|
+
const artifactText = task.artifacts.map(a =>
|
|
525
|
+
` artifact ${a.artifactId}: ${a.parts.map(p => 'text' in p ? p.text.slice(0, 100) : '').join('; ')}`,
|
|
526
|
+
).join('\n')
|
|
527
|
+
return {
|
|
528
|
+
text: `任务 ${task.id}\n 状态: ${task.state}\n 标题: ${task.title}\n 描述: ${task.description ?? '-'}\n 指派: ${task.assigneeId}\n 进度: ${task.progress}%\n 成果:\n${artifactText || ' (无)'}`,
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
case 'search_memory': {
|
|
533
|
+
const query = args.query as string
|
|
534
|
+
const scope = (args.scope as 'auto' | 'private' | 'shared' | undefined) ?? 'auto'
|
|
535
|
+
const snippets = await ws.recallMemory({ query, scope, limit: args.limit as number | undefined })
|
|
536
|
+
if (snippets.length === 0) {
|
|
537
|
+
return { text: `记忆检索无命中(query="${query}", scope=${scope})。可尝试更换关键词或放宽 scope。` }
|
|
538
|
+
}
|
|
539
|
+
const lines = snippets.map(s =>
|
|
540
|
+
` [${s.source}·${s.kind}·score=${s.score}] ${s.title}\n ${s.content}`,
|
|
541
|
+
)
|
|
542
|
+
return { text: `记忆检索结果(${snippets.length} 条, scope=${scope}):\n${lines.join('\n')}` }
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
case 'save_memory': {
|
|
546
|
+
const title = args.title as string
|
|
547
|
+
const content = args.content as string
|
|
548
|
+
const scope = args.scope as 'private' | 'shared'
|
|
549
|
+
const saved = await ws.saveMemory({
|
|
550
|
+
title,
|
|
551
|
+
content,
|
|
552
|
+
importance: args.importance as number | undefined,
|
|
553
|
+
scope,
|
|
554
|
+
dedupKey: args.dedup_key as string | undefined,
|
|
555
|
+
})
|
|
556
|
+
const where = scope === 'shared' ? 'Channel 公共记忆(全员可检索)' : '本人私有记忆'
|
|
557
|
+
return { text: `已沉淀到${where}: "${title}"(dedupKey=${saved.dedupKey})` }
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
case 'create_team_agent': {
|
|
561
|
+
const name = args.name as string
|
|
562
|
+
const harness = args.harness as string | undefined
|
|
563
|
+
const systemPrompt = args.system_prompt as string | undefined
|
|
564
|
+
const reason = args.reason as string | undefined
|
|
565
|
+
const agent: AgentInfo = await ws.createTeamMember({
|
|
566
|
+
name,
|
|
567
|
+
harness,
|
|
568
|
+
config: systemPrompt ? { systemPromptPrefix: systemPrompt } : undefined,
|
|
569
|
+
reason,
|
|
570
|
+
})
|
|
571
|
+
return {
|
|
572
|
+
text: [
|
|
573
|
+
`团队成员已创建并加入 channel:`,
|
|
574
|
+
` id: ${agent.id}`,
|
|
575
|
+
` name: ${agent.name}(role=worker, harness=${agent.harness})`,
|
|
576
|
+
`新成员当前空闲,可立即 dispatch_task 指派任务;list_team_agents 可随时查看团队名册。`,
|
|
577
|
+
].join('\n'),
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
case 'update_team_agent': {
|
|
582
|
+
const agentId = args.agent_id as string
|
|
583
|
+
const name = args.name as string | undefined
|
|
584
|
+
const systemPrompt = args.system_prompt as string | undefined
|
|
585
|
+
const enabled = args.enabled as boolean | undefined
|
|
586
|
+
const reason = args.reason as string | undefined
|
|
587
|
+
const agent = await ws.updateTeamMember(agentId, {
|
|
588
|
+
name,
|
|
589
|
+
config: systemPrompt !== undefined ? { systemPromptPrefix: systemPrompt } : undefined,
|
|
590
|
+
enabled: enabled === undefined ? undefined : (enabled ? 1 : 0),
|
|
591
|
+
reason,
|
|
592
|
+
})
|
|
593
|
+
return {
|
|
594
|
+
text: `团队成员 ${agentId} 已更新:name="${agent.name}"${enabled !== undefined ? `, enabled=${enabled ? 1 : 0}` : ''};运行时将按新配置重载(下次任务生效)。`,
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
case 'remove_team_agent': {
|
|
599
|
+
const agentId = args.agent_id as string
|
|
600
|
+
const reason = args.reason as string | undefined
|
|
601
|
+
const result = await ws.removeTeamMember(agentId, reason)
|
|
602
|
+
const recycleNote = result.recycledTasks.length > 0
|
|
603
|
+
? `其 ${result.recycledTasks.length} 个在途任务已回收(排队任务重派给剩余最短队列成员;执行中任务转 FAILED 待调度重试)。`
|
|
604
|
+
: `该成员无在途任务。`
|
|
605
|
+
return { text: `团队成员 ${agentId} 已移除。${recycleNote}` }
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
case 'my_industrial_nodes': {
|
|
609
|
+
return toolMyIndustrialNodes(identity.agentId)
|
|
610
|
+
}
|
|
611
|
+
case 'dcw_control': {
|
|
612
|
+
return toolDcwControl(identity.agentId, args as { node_id?: string, value?: number | string, hypothesis?: string, task_id?: string })
|
|
613
|
+
}
|
|
614
|
+
case 'dcw_read': {
|
|
615
|
+
return toolDcwRead(identity.agentId, args as { node_id?: string })
|
|
616
|
+
}
|
|
617
|
+
case 'daq_query': {
|
|
618
|
+
return toolDaqQuery(identity.agentId, args as Parameters<typeof toolDaqQuery>[1])
|
|
619
|
+
}
|
|
620
|
+
case 'daq_frames': {
|
|
621
|
+
return toolDaqFrames(identity.agentId, args as Parameters<typeof toolDaqFrames>[1])
|
|
622
|
+
}
|
|
623
|
+
case 'dcw_judge': {
|
|
624
|
+
return toolDcwJudge(identity.agentId, args as { record_id?: string, verdict?: string, reason?: string })
|
|
625
|
+
}
|
|
626
|
+
case 'dcw_rollback': {
|
|
627
|
+
return toolDcwRollback(identity.agentId, args as { record_id?: string, node_id?: string, to?: string })
|
|
628
|
+
}
|
|
629
|
+
case 'dcw_journal': {
|
|
630
|
+
return toolDcwJournal(identity.agentId, args as { node_id?: string, recipe_id?: string, limit?: number | string })
|
|
631
|
+
}
|
|
632
|
+
case 'ops_log': {
|
|
633
|
+
return toolOpsLog(identity.agentId, args as Parameters<typeof toolOpsLog>[1])
|
|
634
|
+
}
|
|
635
|
+
case 'recipe_log': {
|
|
636
|
+
return toolRecipeLog(identity.agentId, args as Parameters<typeof toolRecipeLog>[1])
|
|
637
|
+
}
|
|
638
|
+
case 'line_context': {
|
|
639
|
+
return toolLineContext(identity.agentId, args as { line_id?: string })
|
|
640
|
+
}
|
|
641
|
+
case 'recipe_versions': {
|
|
642
|
+
return toolRecipeVersions(identity.agentId, args as { recipe_id?: string, limit?: number | string })
|
|
643
|
+
}
|
|
644
|
+
case 'recipe_update': {
|
|
645
|
+
return toolRecipeUpdate(identity.agentId, args as Parameters<typeof toolRecipeUpdate>[1])
|
|
646
|
+
}
|
|
647
|
+
case 'recipe_rollback': {
|
|
648
|
+
return toolRecipeRollback(identity.agentId, args as Parameters<typeof toolRecipeRollback>[1])
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return { text: `未知工具: ${req.toolName}`, isError: true }
|
|
652
|
+
}
|
|
653
|
+
catch (err) {
|
|
654
|
+
return {
|
|
655
|
+
text: `工具执行异常(${req.toolName}): ${err instanceof Error ? err.message : String(err)}`,
|
|
656
|
+
isError: true,
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|