agentworkshop 0.7.51 → 0.7.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +2097 -1955
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +2097 -1955
  3. package/.output/.AgentWorkShop/schema.json +2 -0
  4. package/.output/nitro.json +1 -1
  5. package/.output/public/_nuxt/{D0ldVwl-.js → 77DRSnQv.js} +1 -1
  6. package/.output/public/_nuxt/8oRmGaAV.js +1 -0
  7. package/.output/public/_nuxt/{BPou3U7b.js → BLnLjzka.js} +1 -1
  8. package/.output/public/_nuxt/{CFQyYMEn2.js → BSdJTnk12.js} +1 -1
  9. package/.output/public/_nuxt/{C4lagVdN2.js → BUD1CNvB2.js} +1 -1
  10. package/.output/public/_nuxt/BXR3tgEk.js +1 -0
  11. package/.output/public/_nuxt/{B9QzrmgE.js → BhlRInVa.js} +1 -1
  12. package/.output/public/_nuxt/{DhFv8S2Z.js → BkfA3BbD.js} +1 -1
  13. package/.output/public/_nuxt/{ChGuLxwW2.js → BpcQDwKM2.js} +1 -1
  14. package/.output/public/_nuxt/{DQMbdg4t.js → BwlGxRxA.js} +1 -1
  15. package/.output/public/_nuxt/{Bt2ZL5332.js → C4sQKuhk2.js} +1 -1
  16. package/.output/public/_nuxt/{zh-S_7rN2.js → CBUIODly2.js} +1 -1
  17. package/.output/public/_nuxt/CR-ILcRu2.js +1 -0
  18. package/.output/public/_nuxt/CZLnEnbE.js +14 -0
  19. package/.output/public/_nuxt/{jRTz0hjN2.js → Chxx-DIE2.js} +1 -1
  20. package/.output/public/_nuxt/{BGAaKBeo2.js → CjwxhpwR2.js} +1 -1
  21. package/.output/public/_nuxt/{D89BUtx6.js → CvGYm7w8.js} +1 -1
  22. package/.output/public/_nuxt/{B9BmiUil.js → DAGuPgXa.js} +1 -1
  23. package/.output/public/_nuxt/{DefDtlKK.js → DE6H1HdJ.js} +1 -1
  24. package/.output/public/_nuxt/{DzfVS8N72.js → DFhyhDGa2.js} +1 -1
  25. package/.output/public/_nuxt/{BXx9AxdF2.js → DSqMyLCV2.js} +1 -1
  26. package/.output/public/_nuxt/{asmJ99nX2.js → DV5joWTn2.js} +1 -1
  27. package/.output/public/_nuxt/{DClNt1uS.js → DVOR2pWg.js} +1 -1
  28. package/.output/public/_nuxt/DWsgRq2c.js +1 -0
  29. package/.output/public/_nuxt/{CU-mhG0-.js → DZDi8inD.js} +1 -1
  30. package/.output/public/_nuxt/{DMYYS5sK.js → Dep0Hc9w.js} +1 -1
  31. package/.output/public/_nuxt/{JAM4aNC_.js → DffgG8vT.js} +1 -1
  32. package/.output/public/_nuxt/{CFQSjB1h.js → DlCktWDT.js} +1 -1
  33. package/.output/public/_nuxt/{CP0I2l-6.js → DmzmgYHb.js} +1 -1
  34. package/.output/public/_nuxt/PluginSlot.CGH0vb95.css +1 -0
  35. package/.output/public/_nuxt/{lWYQbIR3.js → WmMwIS4y.js} +1 -1
  36. package/.output/public/_nuxt/{_id_.DamiFT0Q.css → _id_.rdGx-UDx.css} +1 -1
  37. package/.output/public/_nuxt/{BgEDwFMf.js → _kUzq9VF.js} +1 -1
  38. package/.output/public/_nuxt/_wsId_.XjmieZaJ.css +1 -0
  39. package/.output/public/_nuxt/{B7jlMWsz.js → aV6YPjg0.js} +1 -1
  40. package/.output/public/_nuxt/builds/latest.json +1 -1
  41. package/.output/public/_nuxt/builds/meta/5ccc21c2-aba0-4b63-9a13-410e0569e345.json +1 -0
  42. package/.output/public/_nuxt/channel-templates.DkNZg-lF.css +1 -0
  43. package/.output/public/_nuxt/{default.CXb_zoN6.css → default.CyLpQD1C.css} +1 -1
  44. package/.output/public/_nuxt/o9rJf00k.js +1 -0
  45. package/.output/public/_nuxt/sl1EEoCr2.js +21 -0
  46. package/.output/public/robots.txt +3 -0
  47. package/.output/server/chunks/_/binding-authz.mjs +1 -1
  48. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  49. package/.output/server/chunks/_/entity.mjs +1 -1
  50. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  51. package/.output/server/chunks/_/nitro.mjs +2268 -1501
  52. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  53. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  54. package/.output/server/chunks/build/{PluginSlot-D2WUZgbp.mjs → PluginSlot-CT4YaNrB.mjs} +5 -5
  55. package/.output/server/chunks/build/{PluginSlot-D2WUZgbp.mjs.map → PluginSlot-CT4YaNrB.mjs.map} +1 -1
  56. package/.output/server/chunks/build/TownView-fP9BiALv.mjs +1 -1
  57. package/.output/server/chunks/build/{_id_-BUpQSlzo.mjs → _id_-CK-QFrDV.mjs} +55 -51
  58. package/.output/server/chunks/build/_id_-CK-QFrDV.mjs.map +1 -0
  59. package/.output/server/chunks/build/{_wsId_-DPy2BXRd.mjs → _wsId_-DdqXzycE.mjs} +320 -202
  60. package/.output/server/chunks/build/{_wsId_-DPy2BXRd.mjs.map → _wsId_-DdqXzycE.mjs.map} +1 -1
  61. package/.output/server/chunks/build/{agents-CDLcboCv.mjs → agents-DqICy4AL.mjs} +6 -6
  62. package/.output/server/chunks/build/{agents-CDLcboCv.mjs.map → agents-DqICy4AL.mjs.map} +1 -1
  63. package/.output/server/chunks/build/{channel-templates-DjEsj0_v.mjs → channel-templates-gdCLajKy.mjs} +114 -25
  64. package/.output/server/chunks/build/channel-templates-gdCLajKy.mjs.map +1 -0
  65. package/.output/server/chunks/build/daq-N69AOtgw.mjs +1 -1
  66. package/.output/server/chunks/build/dcw-CN9d3Rs7.mjs +1 -1
  67. package/.output/server/chunks/build/{default-DCf9tn1i.mjs → default-CXUe4HL7.mjs} +65 -62
  68. package/.output/server/chunks/build/{default-DCf9tn1i.mjs.map → default-CXUe4HL7.mjs.map} +1 -1
  69. package/.output/server/chunks/build/{pages-rZKH72eC.mjs → pages-CRMeXrxG.mjs} +3 -3
  70. package/.output/server/chunks/build/{pages-rZKH72eC.mjs.map → pages-CRMeXrxG.mjs.map} +1 -1
  71. package/.output/server/chunks/build/{plugins-DSka7-vS.mjs → plugins-NAS9MQ5r.mjs} +2 -2
  72. package/.output/server/chunks/build/{plugins-DSka7-vS.mjs.map → plugins-NAS9MQ5r.mjs.map} +1 -1
  73. package/.output/server/chunks/build/{schedules-lo4bfgVt.mjs → schedules-D8vYHgQ5.mjs} +2 -2
  74. package/.output/server/chunks/build/{schedules-lo4bfgVt.mjs.map → schedules-D8vYHgQ5.mjs.map} +1 -1
  75. package/.output/server/chunks/build/{settings-CAJWvul5.mjs → settings-B7HA-sdb.mjs} +3 -3
  76. package/.output/server/chunks/build/{settings-CAJWvul5.mjs.map → settings-B7HA-sdb.mjs.map} +1 -1
  77. package/.output/server/chunks/build/{teams-DBBvIToa.mjs → teams-wM-MdLv9.mjs} +8 -8
  78. package/.output/server/chunks/build/{teams-DBBvIToa.mjs.map → teams-wM-MdLv9.mjs.map} +1 -1
  79. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  80. package/.output/server/chunks/build/{useAgentHarnessOptions-D6SJ_uUr.mjs → useAgentHarnessOptions-BnFCh23W.mjs} +2 -2
  81. package/.output/server/chunks/build/{useAgentHarnessOptions-D6SJ_uUr.mjs.map → useAgentHarnessOptions-BnFCh23W.mjs.map} +1 -1
  82. package/.output/server/chunks/build/{useAgentTemplateActions-CdG4g_PF.mjs → useAgentTemplateActions-DsBRUQni.mjs} +2 -2
  83. package/.output/server/chunks/build/{useAgentTemplateActions-CdG4g_PF.mjs.map → useAgentTemplateActions-DsBRUQni.mjs.map} +1 -1
  84. package/.output/server/chunks/build/{useAgentTemplateForm-a5y-N5sB.mjs → useAgentTemplateForm-DzQ_t2Ue.mjs} +2 -2
  85. package/.output/server/chunks/build/{useAgentTemplateForm-a5y-N5sB.mjs.map → useAgentTemplateForm-DzQ_t2Ue.mjs.map} +1 -1
  86. package/.output/server/chunks/build/{useAgentTemplatesCatalog-pBVcUuN3.mjs → useAgentTemplatesCatalog-Q7LgG1Af.mjs} +2 -2
  87. package/.output/server/chunks/build/{useAgentTemplatesCatalog-pBVcUuN3.mjs.map → useAgentTemplatesCatalog-Q7LgG1Af.mjs.map} +1 -1
  88. package/.output/server/chunks/build/useDaqAddNode-kW7uTSMQ.mjs +1 -1
  89. package/.output/server/chunks/build/useDaqDetailNode-D_vhG0jF.mjs +1 -1
  90. package/.output/server/chunks/build/useDaqDetailParams-JfqHvTxr.mjs +1 -1
  91. package/.output/server/chunks/build/useDaqFilters-BUQtZ82a.mjs +1 -1
  92. package/.output/server/chunks/build/useDaqStream-wOxZcMDA.mjs +1 -1
  93. package/.output/server/chunks/build/useDaqTemplates-BqQRdrIm.mjs +1 -1
  94. package/.output/server/chunks/build/{useDashboardData-Do_Vsepa.mjs → useDashboardData-DWJ6vHjm.mjs} +2 -2
  95. package/.output/server/chunks/build/{useDashboardData-Do_Vsepa.mjs.map → useDashboardData-DWJ6vHjm.mjs.map} +1 -1
  96. package/.output/server/chunks/build/useDcwAddNode-C1HDP3yG.mjs +1 -1
  97. package/.output/server/chunks/build/useDcwStream-D04kCV3J.mjs +1 -1
  98. package/.output/server/chunks/build/{useTeamActions-C4n-taBk.mjs → useTeamActions-BOLQkYxg.mjs} +2 -2
  99. package/.output/server/chunks/build/{useTeamActions-C4n-taBk.mjs.map → useTeamActions-BOLQkYxg.mjs.map} +1 -1
  100. package/.output/server/chunks/build/{useTeamAddMemberDialog-Cp_z3nMa.mjs → useTeamAddMemberDialog-BCgrLPxI.mjs} +2 -2
  101. package/.output/server/chunks/build/{useTeamAddMemberDialog-Cp_z3nMa.mjs.map → useTeamAddMemberDialog-BCgrLPxI.mjs.map} +1 -1
  102. package/.output/server/chunks/build/{useTeamCreateDialog-C8LKUoe2.mjs → useTeamCreateDialog-CJk40LqS.mjs} +2 -2
  103. package/.output/server/chunks/build/{useTeamCreateDialog-C8LKUoe2.mjs.map → useTeamCreateDialog-CJk40LqS.mjs.map} +1 -1
  104. package/.output/server/chunks/build/{useTeamDeployDialog-wdBVsNWY.mjs → useTeamDeployDialog-49hdUXQP.mjs} +2 -2
  105. package/.output/server/chunks/build/{useTeamDeployDialog-wdBVsNWY.mjs.map → useTeamDeployDialog-49hdUXQP.mjs.map} +1 -1
  106. package/.output/server/chunks/build/{useTeamPluginDialog-CIk8G8nI.mjs → useTeamPluginDialog-Dh-QOoiU.mjs} +2 -2
  107. package/.output/server/chunks/build/{useTeamPluginDialog-CIk8G8nI.mjs.map → useTeamPluginDialog-Dh-QOoiU.mjs.map} +1 -1
  108. package/.output/server/chunks/build/{useTeamsCatalog-D6TULzmS.mjs → useTeamsCatalog-HBSyKt5P.mjs} +2 -2
  109. package/.output/server/chunks/build/{useTeamsCatalog-D6TULzmS.mjs.map → useTeamsCatalog-HBSyKt5P.mjs.map} +1 -1
  110. package/.output/server/chunks/build/{useWorkshopApi-B1B9vd4m.mjs → useWorkshopApi-C9sTYu1F.mjs} +13 -2
  111. package/.output/server/chunks/build/useWorkshopApi-C9sTYu1F.mjs.map +1 -0
  112. package/.output/server/chunks/build/useWorkshopWs-Bm80bLn7.mjs.map +1 -1
  113. package/.output/server/chunks/routes/api/index.get.mjs +1 -1
  114. package/.output/server/chunks/routes/api/index.post.mjs +14 -3
  115. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  116. package/.output/server/chunks/routes/api/mcp/workshop.mjs +43 -14
  117. package/.output/server/chunks/routes/api/mcp/workshop.mjs.map +1 -1
  118. package/.output/server/chunks/routes/api/metrics.mjs +2 -0
  119. package/.output/server/chunks/routes/api/metrics.mjs.map +1 -1
  120. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs +1 -1
  121. package/.output/server/chunks/routes/api/plugins/_name/_...path_.mjs.map +1 -1
  122. package/.output/server/chunks/routes/api/system/backup/list.get.mjs +47 -0
  123. package/.output/server/chunks/routes/api/system/backup/list.get.mjs.map +1 -0
  124. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +35 -0
  125. package/.output/server/chunks/routes/api/system/backup/run.post.mjs.map +1 -0
  126. package/.output/server/chunks/routes/api/system/config-groups/_id_.delete.mjs +1 -1
  127. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs +1 -1
  128. package/.output/server/chunks/routes/api/system/index.get.mjs +1 -1
  129. package/.output/server/chunks/routes/api/system/index.patch.mjs +15 -4
  130. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  131. package/.output/server/chunks/routes/api/system/index.post.mjs +1 -1
  132. package/.output/server/chunks/routes/api/system/index2.get.mjs +1 -1
  133. package/.output/server/chunks/routes/api/system/monitor/terminal/ws.mjs +1 -1
  134. package/.output/server/chunks/routes/api/system/monitor/terminate.post.mjs +1 -1
  135. package/.output/server/chunks/routes/api/system/settings/events.get.mjs +1 -1
  136. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs +15 -3
  137. package/.output/server/chunks/routes/api/system/settings/reset.post.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/system/timezone.get.mjs +1 -1
  139. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +14 -3
  140. package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
  141. package/.output/server/chunks/routes/api/users/_id_.get.mjs +1 -1
  142. package/.output/server/chunks/routes/api/users/_id_.put.mjs +14 -3
  143. package/.output/server/chunks/routes/api/users/_id_.put.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/users/index.get.mjs +1 -1
  145. package/.output/server/chunks/routes/api/users/index.post.mjs +1 -1
  146. package/.output/server/chunks/routes/api/users/login.post.mjs +3 -2
  147. package/.output/server/chunks/routes/api/users/login.post.mjs.map +1 -1
  148. package/.output/server/chunks/routes/api/users/logout.post.mjs +1 -1
  149. package/.output/server/chunks/routes/api/users/me.get.mjs +1 -1
  150. package/.output/server/chunks/routes/api/users/register.post.mjs +4 -1
  151. package/.output/server/chunks/routes/api/users/register.post.mjs.map +1 -1
  152. package/.output/server/chunks/routes/api/users/setup-status.get.mjs +1 -1
  153. package/.output/server/chunks/routes/api/users/tokens/_id/token.get.mjs +1 -1
  154. package/.output/server/chunks/routes/api/users/tokens/_id_.delete.mjs +1 -1
  155. package/.output/server/chunks/routes/api/users/tokens/_id_.patch.mjs +1 -1
  156. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.get.mjs +1 -1
  157. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs +19 -15
  158. package/.output/server/chunks/routes/api/workshop/a2a/_agentId/index.post.mjs.map +1 -1
  159. package/.output/server/chunks/routes/api/workshop/a2a/send.post.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/agent-tools/approvals/_id/decide.post.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.delete.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/_id_.patch.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/grant.post.mjs +54 -0
  164. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/grant.post.mjs.map +1 -0
  165. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/revoke.post.mjs +51 -0
  166. package/.output/server/chunks/routes/api/workshop/agent-tools/bindings/revoke.post.mjs.map +1 -0
  167. package/.output/server/chunks/routes/api/workshop/agent-tools/index.get.mjs +1 -1
  168. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +1 -1
  169. package/.output/server/chunks/routes/api/workshop/agent-tools/index2.get.mjs +1 -1
  170. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/agent-tools/list.get.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +1 -1
  173. package/.output/server/chunks/routes/api/workshop/agents/subscribe.post.mjs +1 -1
  174. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +1 -1
  175. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +1 -1
  176. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +1 -1
  177. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +1 -1
  178. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs +1 -1
  179. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +1 -1
  180. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +1 -1
  181. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +1 -1
  184. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/aml/index3.post.mjs +1 -1
  187. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +1 -1
  188. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +1 -1
  190. package/.output/server/chunks/routes/api/workshop/aml/index7.get.mjs +1 -1
  191. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +1 -1
  194. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +1 -1
  197. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id/train.post.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.delete.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/aml/training-plans/_id_.patch.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/aml/twin/providers.get.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/approvals/_id/decide.post.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/assets/index.get.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/audit.get.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/caller.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +10 -4
  211. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs.map +1 -1
  212. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/channel-templates/from-channel.post.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/index.post.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId/memories/search.post.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.get.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/channels/_id/events.get.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/channels/_id/index2.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/channels/_id/index5.get.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +37 -0
  228. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs.map +1 -0
  229. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.get.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/channels/_id/twin-profile.patch.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/channels/index.patch.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +4 -4
  235. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -1
  236. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
  237. package/.output/server/chunks/routes/api/workshop/daq/_id/frames/content.get.mjs +1 -1
  238. package/.output/server/chunks/routes/api/workshop/daq/_id/frames.get.mjs +1 -1
  239. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  240. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
  241. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
  242. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -1
  243. package/.output/server/chunks/routes/api/workshop/daq/alarms/_id/ack.post.mjs +1 -1
  244. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +1 -1
  245. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
  246. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
  247. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  248. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  249. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  250. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  251. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  252. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  253. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  254. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  255. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  256. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  257. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  258. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  259. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  260. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  261. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  262. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  263. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  264. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  265. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  266. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  267. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  268. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  269. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  270. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +1 -1
  272. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  273. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +6 -1
  274. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  276. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  277. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  278. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs +1 -1
  279. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  280. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  281. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  282. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  283. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +1 -1
  284. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  285. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  286. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  287. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  288. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  289. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  290. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  291. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs +3 -3
  292. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/revert.post.mjs.map +1 -1
  293. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  294. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +1 -1
  295. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  296. package/.output/server/chunks/routes/api/workshop/dcw/recipes/index.patch.mjs +1 -1
  297. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  298. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  299. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  300. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  301. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  302. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  303. package/.output/server/chunks/routes/api/workshop/device-twins/_id/control.post.mjs +1 -1
  304. package/.output/server/chunks/routes/api/workshop/device-twins/_id/telemetry.post.mjs +1 -1
  305. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  306. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  307. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +14 -2
  308. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs.map +1 -1
  309. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  310. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  311. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  312. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  313. package/.output/server/chunks/routes/api/workshop/index.post.mjs +1 -1
  314. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  315. package/.output/server/chunks/routes/api/workshop/index10.get.mjs +1 -1
  316. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +1 -1
  317. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +1 -1
  318. package/.output/server/chunks/routes/api/workshop/index3.get.mjs +1 -1
  319. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  320. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  321. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +1 -1
  322. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  323. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  324. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
  325. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  326. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  327. package/.output/server/chunks/routes/api/workshop/index8.get.mjs +1 -1
  328. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +1 -1
  329. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +3 -3
  330. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  331. package/.output/server/chunks/routes/api/workshop/index9.post.mjs +1 -1
  332. package/.output/server/chunks/routes/api/workshop/notifications/read.post.mjs +1 -1
  333. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  334. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  335. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  336. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  337. package/.output/server/chunks/routes/api/workshop/schedules/_id/runs.get.mjs +1 -1
  338. package/.output/server/chunks/routes/api/workshop/schedules/_id_.patch.mjs +1 -1
  339. package/.output/server/chunks/routes/api/workshop/tasks/_id/complete.post.mjs +1 -1
  340. package/.output/server/chunks/routes/api/workshop/tasks/_id/dispatch.post.mjs +1 -1
  341. package/.output/server/chunks/routes/api/workshop/tasks/_id/report.post.mjs +1 -1
  342. package/.output/server/chunks/routes/api/workshop/tasks/_id_.get.mjs +1 -1
  343. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  344. package/.output/server/chunks/routes/api/workshop/teams/_id/index.post.mjs +1 -1
  345. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  346. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  347. package/.output/server/chunks/routes/api/workshop/teams/_id_.patch.mjs +1 -1
  348. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs +4 -1
  349. package/.output/server/chunks/routes/api/workshop/users/register.post.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  351. package/.output/server/chunks/routes/renderer.mjs +2 -2
  352. package/.output/server/chunks/virtual/entry.mjs +350 -52
  353. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  354. package/.output/server/package.json +1 -1
  355. package/README-zh.md +7 -3
  356. package/README.md +11 -5
  357. package/app/components/app-header/HitlBell.vue +9 -9
  358. package/app/components/dcw/DcwAddNodeModal.vue +3 -3
  359. package/app/components/dcw/DcwNodesTable.vue +4 -4
  360. package/app/components/dcw/DcwRecipeEditModal.vue +2 -2
  361. package/app/components/workshop/ChatMemberPanel.vue +39 -38
  362. package/app/components/workshop/ChatTimeline.vue +33 -24
  363. package/app/components/workshop/Composer.vue +7 -7
  364. package/app/components/workshop/NotificationCenter.vue +22 -13
  365. package/app/components/workshop/PluginSlot.vue +1 -1
  366. package/app/components/workshop/TaskInspectorDrawer.vue +5 -5
  367. package/app/components/workshop/blocks/ClusterTool.vue +1 -1
  368. package/app/components/workshop/composer/ComposerToolbar.vue +2 -2
  369. package/app/components/workshop/composer/MentionMenu.vue +1 -1
  370. package/app/components/workshop/composer/ReplyChip.vue +2 -2
  371. package/app/components/workshop/composer/StatusChip.vue +7 -7
  372. package/app/components/workshop/console/LineOperationsPanel.vue +15 -14
  373. package/app/components/workshop/lanes/LaneHeader.vue +5 -3
  374. package/app/components/workshop/session-list/ChannelSettingsModal.vue +43 -1
  375. package/app/composables/useCodeCopy.ts +16 -2
  376. package/app/composables/workshop/useWorkshopApi.ts +11 -2
  377. package/app/pages/workshop/channel-templates.vue +43 -4
  378. package/app/stores/workshop/notifications.ts +43 -17
  379. package/config.yml +1 -1
  380. package/docs/cli.en.md +3 -3
  381. package/docs/cli.md +2 -2
  382. package/docs/plugins.en.md +1 -1
  383. package/docs/plugins.md +1 -1
  384. package/docs/sdk.en.md +1 -1
  385. package/docs/sdk.md +1 -1
  386. package/i18n/dicts/_en.json +1551 -1557
  387. package/i18n/dicts/_en2.json +300 -300
  388. package/i18n/dicts/_en4.json +114 -115
  389. package/i18n/dicts/agentLanesView.json +61 -57
  390. package/i18n/dicts/appHeader.json +17 -7
  391. package/i18n/dicts/channelSessionList.json +51 -48
  392. package/i18n/dicts/chat.json +79 -0
  393. package/i18n/dicts/clusterTool.json +4 -3
  394. package/i18n/dicts/composer.json +38 -38
  395. package/i18n/dicts/ctpl.json +37 -32
  396. package/i18n/dicts/dcwDetail.json +219 -209
  397. package/i18n/dicts/lineOps.json +14 -0
  398. package/i18n/dicts/multiChannelView.json +13 -13
  399. package/i18n/dicts/notifications.json +13 -0
  400. package/i18n/dicts/taskInspectorDrawer.json +25 -19
  401. package/i18n/locales/en.ts +157 -8
  402. package/i18n/locales/zh-CN.ts +157 -8
  403. package/package.json +1 -1
  404. package/public/robots.txt +3 -0
  405. package/scripts/_audit/kb-team-mock-e2e.mjs +146 -0
  406. package/scripts/_audit/kb-team-omp-e2e.mjs +229 -0
  407. package/server/api/mcp/workshop.ts +8 -1
  408. package/server/api/metrics.ts +4 -1
  409. package/server/api/plugins/[name]/[...path].ts +4 -3
  410. package/server/api/system/backup/list.get.ts +32 -0
  411. package/server/api/system/backup/run.post.ts +21 -0
  412. package/server/api/system/settings/index.patch.ts +12 -2
  413. package/server/api/system/settings/reset.post.ts +11 -2
  414. package/server/api/users/[id].delete.ts +9 -2
  415. package/server/api/users/[id].put.ts +9 -2
  416. package/server/api/users/index.post.ts +9 -2
  417. package/server/api/users/login.post.ts +3 -3
  418. package/server/api/users/register.post.ts +11 -1
  419. package/server/api/workshop/a2a/[agentId]/rpc/index.post.ts +23 -13
  420. package/server/api/workshop/agent-tools/bindings/grant.post.ts +45 -0
  421. package/server/api/workshop/agent-tools/bindings/revoke.post.ts +42 -0
  422. package/server/api/workshop/channel-templates/[id]/instantiate.post.ts +8 -1
  423. package/server/api/workshop/channels/[id]/line.put.ts +30 -0
  424. package/server/api/workshop/dcw/line/query.get.ts +6 -0
  425. package/server/api/workshop/dcw/recipes/[id]/revert.post.ts +3 -2
  426. package/server/api/workshop/fs/dirs.get.ts +19 -1
  427. package/server/api/workshop/ops-logs/index.get.ts +3 -2
  428. package/server/api/workshop/users/register.post.ts +7 -0
  429. package/server/mcp/workshop-server.ts +36 -13
  430. package/server/middleware/00-security-headers.ts +38 -0
  431. package/server/middleware/01-rate-guard.ts +101 -0
  432. package/server/plugins/backup.ts +56 -1
  433. package/server/plugins-builtin/diag-bridge/host/plugin.mjs +18 -11
  434. package/server/repositories/user.repository.ts +10 -5
  435. package/server/services/user.service.ts +24 -1
  436. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +7 -2
  437. package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +4 -2
  438. package/server/services/workshop/agents/host-tool-bridge/tools/tasks.ts +15 -2
  439. package/server/services/workshop/agents/host-tool-bridge/tools/team-delegation.ts +104 -0
  440. package/server/services/workshop/agents/industrial/index.ts +1 -1
  441. package/server/services/workshop/agents/industrial/ops-tools.ts +168 -26
  442. package/server/services/workshop/agents/node-bindings.repo.ts +10 -1
  443. package/server/services/workshop/agents/node-delegation.ts +150 -0
  444. package/server/services/workshop/agents/tool-classes.ts +4 -0
  445. package/server/services/workshop/aml/dataset-builder.ts +4 -2
  446. package/server/services/workshop/aml/job-orchestrator/process.ts +1 -0
  447. package/server/services/workshop/aml/job-orchestrator/shared.ts +2 -0
  448. package/server/services/workshop/aml/job-orchestrator/start-job.ts +5 -2
  449. package/server/services/workshop/db/channel.repo.ts +11 -1
  450. package/server/services/workshop/db/database/migrations.ts +2 -0
  451. package/server/services/workshop/db/database/rows.ts +2 -0
  452. package/server/services/workshop/db/database/seed.ts +30 -0
  453. package/server/services/workshop/dcw/dcw-controller/recipes.ts +60 -4
  454. package/server/services/workshop/dcw/dcw-controller/write.ts +35 -6
  455. package/server/services/workshop/dcw/dcw-recipe.repo.ts +4 -3
  456. package/server/services/workshop/dcw/param-map.repo.ts +3 -0
  457. package/server/services/workshop/plugins/host/init.mjs +9 -1
  458. package/server/services/workshop/plugins/host/load.mjs +2 -2
  459. package/server/services/workshop/runtime/manager/admin-channel.ts +27 -1
  460. package/server/services/workshop/runtime/manager/channel-templates.ts +27 -2
  461. package/server/services/workshop/runtime/manager/runtime-wiring.ts +17 -1
  462. package/server/services/workshop/runtime/manager/types.ts +2 -0
  463. package/shared/config/schema.json +2 -0
  464. package/.output/public/_nuxt/8FXd9As6.js +0 -1
  465. package/.output/public/_nuxt/BOmDHp5L.js +0 -14
  466. package/.output/public/_nuxt/BWU1pvLL.js +0 -1
  467. package/.output/public/_nuxt/CdIsmU5a2.js +0 -21
  468. package/.output/public/_nuxt/D0SNhlnt.js +0 -1
  469. package/.output/public/_nuxt/DnH9SRMW2.js +0 -1
  470. package/.output/public/_nuxt/ON2x-t6n.js +0 -1
  471. package/.output/public/_nuxt/PluginSlot.DmjNbrcX.css +0 -1
  472. package/.output/public/_nuxt/_wsId_.DkrQkT6r.css +0 -1
  473. package/.output/public/_nuxt/builds/meta/912eb5bb-670e-4cc8-b21d-7fc097723466.json +0 -1
  474. package/.output/public/_nuxt/channel-templates.DplM1pJ3.css +0 -1
  475. package/.output/server/chunks/build/_id_-BUpQSlzo.mjs.map +0 -1
  476. package/.output/server/chunks/build/channel-templates-DjEsj0_v.mjs.map +0 -1
  477. package/.output/server/chunks/build/useWorkshopApi-B1B9vd4m.mjs.map +0 -1
  478. package/scripts/.chk-tok +0 -1
  479. package/scripts/.retrain-body.json +0 -1
  480. package/scripts/.retrain3-body.json +0 -1
  481. package/scripts/.rt-tok +0 -1
  482. package/scripts/.rt3-tok +0 -1
@@ -53,7 +53,41 @@ async function backupOne(src: string, target: string): Promise<void> {
53
53
  }
54
54
  }
55
55
 
56
- async function backupOnce(dataDir: string): Promise<void> {
56
+ /** 数据目录内的 JSON 仓储/状态文件(kv、参数面、节点绑定、插件 kv 等)+ 上级配置根的 config.yml/runtime-settings.json */
57
+ async function backupFlatFiles(dataDir: string, backupDir: string, stamp: string): Promise<void> {
58
+ const bundleDir = resolve(backupDir, `files-${stamp}`)
59
+ mkdirSync(bundleDir, { recursive: true })
60
+ const targets: Array<{ src: string, name: string }> = []
61
+ // dataDir 下所有 .json(逐文件拷贝,目录型子树由各自仓储自轮转,不整树递归)
62
+ try {
63
+ for (const f of readdirSync(dataDir, { withFileTypes: true })) {
64
+ if (f.isFile() && f.name.endsWith('.json')) targets.push({ src: resolve(dataDir, f.name), name: f.name })
65
+ }
66
+ }
67
+ catch { /* 数据目录不可读时跳过 JSON 面 */ }
68
+ // 配置根(config.yml + runtime-settings.json)——重建实例的"怎么做"半边
69
+ try {
70
+ const homeMod = await import('@/shared/config/home.mjs')
71
+ const rm = homeMod.resolveRunMode({ cwd: process.cwd(), env: process.env })
72
+ for (const cfg of ['config.yml', 'runtime-settings.json']) {
73
+ const p = resolve(rm.configRoot, cfg)
74
+ if (existsSync(p)) targets.push({ src: p, name: cfg })
75
+ }
76
+ }
77
+ catch { /* 模式解析失败只降级 JSON 面 */ }
78
+ for (const t of targets) {
79
+ try {
80
+ const tmp = resolve(bundleDir, `${t.name}.tmp`)
81
+ await copyFileAsync(t.src, tmp)
82
+ renameSync(tmp, resolve(bundleDir, t.name))
83
+ }
84
+ catch (err) {
85
+ console.error(`[backup] ${t.name} 快照失败:`, err instanceof Error ? err.message : err)
86
+ }
87
+ }
88
+ }
89
+
90
+ export async function backupOnce(dataDir: string): Promise<void> {
57
91
  const backupDir = resolve(dataDir, 'backups')
58
92
  mkdirSync(backupDir, { recursive: true })
59
93
  const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)
@@ -69,6 +103,8 @@ async function backupOnce(dataDir: string): Promise<void> {
69
103
  console.error(`[backup] ${file} 快照失败:`, err instanceof Error ? err.message : err)
70
104
  }
71
105
  }
106
+ // JSON 仓储 + 配置面快照(三库之外的可重建性半边)
107
+ await backupFlatFiles(dataDir, backupDir, stamp)
72
108
  // 轮转:每库仅保留最近 backup.keep 份(按文件名内时间戳倒序;env BACKUP_KEEP 兼容)
73
109
  const keep = Math.max(1, backupSettings().keep)
74
110
  for (const file of DB_FILES) {
@@ -83,9 +119,28 @@ async function backupOnce(dataDir: string): Promise<void> {
83
119
  catch { /* 轮转失败不致命 */ }
84
120
  }
85
121
  }
122
+ // files-<stamp>/ 目录同 keep 轮转
123
+ const fileBundles = readdirSync(backupDir)
124
+ .filter(f => f.startsWith('files-') && !f.includes('.'))
125
+ .sort()
126
+ .reverse()
127
+ for (const stale of fileBundles.slice(keep)) {
128
+ try {
129
+ rmSync(resolve(backupDir, stale), { recursive: true })
130
+ }
131
+ catch { /* 轮转失败不致命 */ }
132
+ }
86
133
  console.log('[backup] 快照完成 →', backupDir)
87
134
  // R4:记录最近一次成功备份时间,供 /api/metrics 观测
88
135
  g.__awBackupLastAt = new Date().toISOString()
136
+ // 备份成败留痕(audit_log;动态导入避免插件装载期循环依赖)
137
+ void import('../services/workshop/ops/ops').then(({ recordOps }) => {
138
+ recordOps({
139
+ actor: 'system', actorName: 'backup', actorKind: 'system',
140
+ action: 'system.backup.run', kind: 'system',
141
+ summary: `数据库快照完成(${DB_FILES.length} 库 + JSON/配置)→ ${backupDir}`,
142
+ })
143
+ }).catch(() => {})
89
144
  }
90
145
 
91
146
  export default function backupPlugin() {
@@ -68,17 +68,24 @@ export default {
68
68
  if (Date.now() - last < AUTO_COOLDOWN_MS) return
69
69
  const now = Date.now()
70
70
  ctx.kv.set(`cooldown:${line}`, now) // 先占冷却,防同窗连发
71
- startDiagnosis(ctx, {
72
- line,
73
- fromMs: now - 60 * MIN,
74
- toMs: now,
75
- question: `${line} 产线该时窗数据深度根因诊断(自动触发:节点 ${s.nodeId} 采样值 ${s.value} ${rule.op === 'lt' ? '<' : '>'} ${rule.value})`,
76
- scene: `${line}_auto`,
77
- source: 'auto',
78
- }).then((r) => {
79
- if (r.ok) ctx.logger.warn(`自动诊断已发起:产线 ${line} runId=${r.runId}(节点 ${s.nodeId}=${s.value} 越限)`)
80
- else ctx.logger.warn(`自动诊断发起失败(产线 ${line}): ${r.error}`)
81
- }).catch(() => {})
71
+ // 首拍竞态:开线后首个越限样本即刻触发,快照查询早于 tsdb 首次刷盘(TSDB_FLUSH_MS=500ms)
72
+ // → 时窗查空失败。空窗失败定向重试(≤3 次、间隔 5s,总窗 ≤20s);冷却不回滚,仍只此一次派发。
73
+ const question = `${line} 产线该时窗数据深度根因诊断(自动触发:节点 ${s.nodeId} 采样值 ${s.value} ${rule.op === 'lt' ? '<' : '>'} ${rule.value})`
74
+ const attempt = (n) => {
75
+ startDiagnosis(ctx, {
76
+ line,
77
+ fromMs: now - 60 * MIN,
78
+ toMs: now,
79
+ question,
80
+ scene: `${line}_auto`,
81
+ source: 'auto',
82
+ }).then((r) => {
83
+ if (r.ok) ctx.logger.warn(`自动诊断已发起:产线 ${line} runId=${r.runId}(节点 ${s.nodeId}=${s.value} 越限)`)
84
+ else if (n < 3 && String(r.error ?? '').includes('无数采样本')) setTimeout(() => attempt(n + 1), 5000)
85
+ else ctx.logger.warn(`自动诊断发起失败(产线 ${line}): ${r.error}`)
86
+ }).catch(() => {})
87
+ }
88
+ attempt(0)
82
89
  }
83
90
  catch { /* 钩子内绝不抛 */ }
84
91
  })
@@ -139,7 +139,8 @@ function importLegacyWorkshopUsers(d: DatabaseSync): void {
139
139
  insertUser.run(row.id, row.name, email, hashPassword(randomPassword()), 'user', 'active', row.created_at ?? now())
140
140
  const hash = hashToken(row.token)
141
141
  if (!tokenExists.get(hash)) {
142
- insertToken.run(randomUUID(), row.id, 'legacy', hash, row.token, row.created_at ?? now())
142
+ // 安全基线:token_plain 不落明文(哈希即可鉴权;明文列仅为旧库形状兼容,恒 NULL)
143
+ insertToken.run(randomUUID(), row.id, 'legacy', hash, null, row.created_at ?? now())
143
144
  }
144
145
  }
145
146
  }
@@ -241,17 +242,21 @@ function toUser(row: Record<string, unknown>): User {
241
242
  export const userRepository = {
242
243
  list({ page, pageSize, keyword }: UserListQuery): Paginated<User> {
243
244
  const d = getDb()
244
- const kw = keyword?.toLowerCase() ?? ''
245
+ // 分页边界钳制:超大/非法分页参数在 SQL 外收口(OFFSET 1e20 会打穿 sqlite 抛 500)
246
+ const safePage = Number.isSafeInteger(page) && page >= 1 ? page : 1
247
+ const safeSize = Number.isSafeInteger(pageSize) && pageSize >= 1 ? Math.min(pageSize, 200) : 20
248
+ // LIKE 通配符转义:用户关键词里的 %/_ 按字面匹配,不放大匹配面(ESCAPE 子句配套)
249
+ const kw = keyword?.toLowerCase() ? keyword.toLowerCase().replace(/[\\%_]/g, ch => `\\${ch}`) : ''
245
250
  const where = kw
246
- ? `WHERE LOWER(name) LIKE ? OR LOWER(email) LIKE ?`
251
+ ? `WHERE LOWER(name) LIKE ? ESCAPE '\\' OR LOWER(email) LIKE ? ESCAPE '\\'`
247
252
  : ''
248
253
  const params = kw ? [`%${kw}%`, `%${kw}%`] : []
249
254
  const total = (d.prepare(`SELECT COUNT(*) AS n FROM users ${where}`).get(...params) as { n: number }).n
250
255
  const rows = d.prepare(
251
256
  `SELECT id, name, email, role, status, created_at AS createdAt FROM users ${where}
252
257
  ORDER BY created_at DESC LIMIT ? OFFSET ?`,
253
- ).all(...params, pageSize, (page - 1) * pageSize) as Array<Record<string, unknown>>
254
- return { items: rows.map(toUser), total, page, pageSize }
258
+ ).all(...params, safeSize, (safePage - 1) * safeSize) as Array<Record<string, unknown>>
259
+ return { items: rows.map(toUser), total, page: safePage, pageSize: safeSize }
255
260
  },
256
261
 
257
262
  /** 全量用户(不分页;管理面授权矩阵用,避免分页截断) */
@@ -23,6 +23,12 @@ export function resolveUserByToken(token: string): UserProfile | null {
23
23
  }
24
24
 
25
25
  export const userService = {
26
+ /**
27
+ * 登录防爆破:同 IP+邮箱在 15 分钟窗口内累计失败 ≥5 次 → 锁到窗口结束(429)。
28
+ * 内存态,重启即清;多实例部署由反代层限流补齐。计数表封顶 5000 条防内存滥用。
29
+ */
30
+ _loginFails: new Map<string, { count: number, firstAt: number }>(),
31
+
26
32
  // ===== 管理面(与既有契约一致)=====
27
33
 
28
34
  list(input: UserListInput) {
@@ -104,9 +110,25 @@ export const userService = {
104
110
  },
105
111
 
106
112
  /** 登录:密码校验通过后签发新 token(每次登录生成一个可独立吊销的会话 token) */
107
- login(input: UserLogin): AuthResult {
113
+ login(input: UserLogin, opts: { ip?: string } = {}): AuthResult {
114
+ const FAIL_WINDOW_MS = 15 * 60_000
115
+ const LOCK_THRESHOLD = 5
116
+ const lockKey = `${opts.ip ?? 'local'}|${input.email.toLowerCase()}`
117
+ const fails = this._loginFails
118
+ if (fails.size > 5000) {
119
+ const oldest = fails.keys().next().value
120
+ if (oldest) fails.delete(oldest)
121
+ }
122
+ const rec = fails.get(lockKey)
123
+ // 已达阈值且窗口未过 → 锁定;偶发失败(1-4 次)不锁,窗口滑过即重置
124
+ if (rec && rec.count >= LOCK_THRESHOLD && Date.now() - rec.firstAt < FAIL_WINDOW_MS) {
125
+ const waitMin = Math.ceil((FAIL_WINDOW_MS - (Date.now() - rec.firstAt)) / 60_000)
126
+ throw new AppError(429, 'LOGIN_LOCKED', `失败次数过多,账号已临时锁定,请约 ${waitMin} 分钟后再试`)
127
+ }
108
128
  const { id, hash } = userRepository.getPasswordHash(input.email) ?? {}
109
129
  if (!id || !hash || !verifyPassword(input.password, hash)) {
130
+ if (!rec || Date.now() - rec.firstAt >= FAIL_WINDOW_MS) fails.set(lockKey, { count: 1, firstAt: Date.now() })
131
+ else rec.count += 1
110
132
  throw new AppError(401, 'UNAUTHORIZED', '邮箱或密码错误')
111
133
  }
112
134
  const user = userRepository.findById(id)
@@ -116,6 +138,7 @@ export const userService = {
116
138
  if (user.status !== 'active') {
117
139
  throw new AppError(403, 'FORBIDDEN', '账号已禁用')
118
140
  }
141
+ fails.delete(lockKey)
119
142
  const { raw } = userRepository.createToken(id, `session-${Date.now()}`)
120
143
  return { user: this.publicProfile(user), token: raw }
121
144
  },
@@ -19,6 +19,7 @@ import type { HostToolBridgeContext, HostToolCall, HostToolResult } from './type
19
19
  import { INDUSTRIAL_TOOL_NAMES, dispatchIndustrialTool } from './tools/industrial'
20
20
  import { handleCompleteTask, handleReportProgress } from './tools/progress'
21
21
  import { handleCancelTask, handleDispatchTask, handleGetMyTaskQueue, handleGetTaskDetails, handleListChannelTasks, handleReassignTask, handleRefuseTask, handleSubmitTask, handleUpdateTask } from './tools/tasks'
22
+ import { handleGrantNodes, handleRevokeNodes } from './tools/team-delegation'
22
23
  import { handleBroadcastMessage, handleListOtherTeams, handlePollMessages, handleReadChannelMail, handleSearchOtherTeamsMemory, handleSendCrossChannelMessage, handleSendMessageToAgent } from './tools/messaging'
23
24
  import { handleSaveMemory, handleSearchMemory } from './tools/memory'
24
25
  import { handleCreateTeamAgent, handleGetQueueOverview, handleListTeamAgents, handleRemoveTeamAgent, handleUpdateTeamAgent } from './tools/team'
@@ -95,7 +96,7 @@ export async function dispatchHostTool(ctx: HostToolBridgeContext, req: HostTool
95
96
  }
96
97
 
97
98
  // 所有真实写入口在统一分发层再做一次服务端 fail-closed 守卫;工具目录隐藏不是安全边界。
98
- if (['dcw_control', 'param_control', 'dcw_rollback', 'recipe_update', 'recipe_rollback'].includes(req.toolName)) {
99
+ if (['dcw_control', 'param_control', 'dcw_rollback', 'recipe_update', 'recipe_rollback', 'recipe_trial', 'recipe_apply'].includes(req.toolName)) {
99
100
  const profile = getChannelTwinProfile(identity.channelId)
100
101
  const guard = twinWriteGuard(identity.channelId, profile)
101
102
  if (!guard.allowed) return { text: `${guard.code}: ${guard.message}`, isError: true }
@@ -121,7 +122,11 @@ export async function dispatchHostTool(ctx: HostToolBridgeContext, req: HostTool
121
122
  case 'submit_task':
122
123
  return await handleSubmitTask(args, state, ws)
123
124
  case 'dispatch_task':
124
- return await handleDispatchTask(args, ws)
125
+ return await handleDispatchTask(args, ws, identity)
126
+ case 'team_grant_nodes':
127
+ return await handleGrantNodes(identity, args, ws)
128
+ case 'team_revoke_nodes':
129
+ return await handleRevokeNodes(identity, args, ws)
125
130
  case 'send_message_to_agent':
126
131
  return await handleSendMessageToAgent(args, state, ws)
127
132
  case 'send_cross_channel_message':
@@ -9,7 +9,7 @@
9
9
  * 该族**不依赖 workspace**,由 dispatch 在 workspace 门控之前分流(保持原分发顺序)。
10
10
  */
11
11
  import type { HostToolResult } from '../types'
12
- import { toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolParamRead, toolRecipeLog, toolRecipeRollback, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest } from '../../industrial'
12
+ import { toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRead, toolDcwRollback, toolLineContext, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolParamRead, toolRecipeApply, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest } from '../../industrial'
13
13
 
14
14
  type IndustrialToolHandler = (agentId: string, args: Record<string, unknown>, channelId?: string) => Promise<HostToolResult>
15
15
 
@@ -59,7 +59,9 @@ const INDUSTRIAL_HANDLERS = new Map<string, IndustrialToolHandler>([
59
59
  ['line_context', (agentId, args) => toolLineContext(agentId, args as { line_id?: string })],
60
60
  ['recipe_versions', (agentId, args) => toolRecipeVersions(agentId, args as { recipe_id?: string, limit?: number | string })],
61
61
  ['recipe_update', (agentId, args) => toolRecipeUpdate(agentId, args as Parameters<typeof toolRecipeUpdate>[1])],
62
- ['recipe_rollback', (agentId, args) => toolRecipeRollback(agentId, args as Parameters<typeof toolRecipeRollback>[1])],
62
+ ['recipe_rollback', (agentId, args) => toolRecipeRollback(agentId, args as Parameters<typeof toolRecipeRollback>[1])],
63
+ ['recipe_trial', (agentId, args) => toolRecipeTrial(agentId, args as Parameters<typeof toolRecipeTrial>[1])],
64
+ ['recipe_apply', (agentId, args) => toolRecipeApply(agentId, args as Parameters<typeof toolRecipeApply>[1])],
63
65
  ])
64
66
 
65
67
  /** 工业工具名集合(与 INDUSTRIAL_HANDLERS 同源;dispatch 据此在 workspace 门控前分流) */
@@ -23,12 +23,25 @@ export async function handleSubmitTask(args: Record<string, unknown>, state: Hos
23
23
  }
24
24
  }
25
25
 
26
- export async function handleDispatchTask(args: Record<string, unknown>, ws: AgentWorkspace): Promise<HostToolResult> {
26
+ export async function handleDispatchTask(args: Record<string, unknown>, ws: AgentWorkspace, identity?: HostToolBridgeContext['identity']): Promise<HostToolResult> {
27
27
  const assigneeId = args.assignee_id as string
28
28
  const title = args.title as string
29
29
  const description = args.description as string | undefined
30
30
  const parentTaskId = args.parent_task_id as string | undefined
31
31
  const routeReason = args.route_reason as string | undefined
32
+ // 派发时随任务授予节点权限(lead 专属;grant_node_ids ⊆ lead 自身绑定面,fail-closed):
33
+ // 任一节点不满足则整单拒绝,任务不创建 —— 避免 worker 拿到任务却没有节点权限的半途态。
34
+ let grantNote = ''
35
+ const rawGrant = args.grant_node_ids ?? args.grantNodeIds
36
+ if (rawGrant != null && identity) {
37
+ const { grantNodesForDispatch } = await import('./team-delegation')
38
+ const grantNodeIds = (Array.isArray(rawGrant) ? rawGrant : String(rawGrant).split(',')).map(x => String(x ?? '').trim()).filter(Boolean)
39
+ if (!grantNodeIds.length) return { text: 'grant_node_ids 为空:要么不传,要么给出至少一个节点 id。', isError: true }
40
+ const grantMode = args.grant_mode === 'manual' || args.grant_mode === 'auto' ? (args.grant_mode as 'auto' | 'manual') : undefined
41
+ const grant = await grantNodesForDispatch(identity, assigneeId, grantNodeIds, grantMode, ws)
42
+ if (!grant.ok) return { text: `未派发:${grant.text}\n请先用 team_grant_nodes 确认你持有这些节点,或修正 node id 后重试。`, isError: true }
43
+ grantNote = `\n${grant.text}`
44
+ }
32
45
  // 重复派发守卫(真实场景实测:lead 模型可能对同一目标重复派发,引发协调风暴):
33
46
  // 同父任务下已存在同标题非终态子任务 → 不再创建,直接指路既有任务
34
47
  const dup = await ws.listTasks()
@@ -42,7 +55,7 @@ export async function handleDispatchTask(args: Record<string, unknown>, ws: Agen
42
55
  }
43
56
  }
44
57
  const task = await ws.dispatchTask({ assigneeId, title, description, parentTaskId, routeReason })
45
- return { text: `子任务 ${task.id} 已创建并指派 → ${assigneeId}(父任务 ${parentTaskId ?? '无'},标题: ${title}${routeReason ? `,路由理由: ${routeReason}` : ''})` }
58
+ return { text: `子任务 ${task.id} 已创建并指派 → ${assigneeId}(父任务 ${parentTaskId ?? '无'},标题: ${title}${routeReason ? `,路由理由: ${routeReason}` : ''})${grantNote}` }
46
59
  }
47
60
 
48
61
  export async function handleRefuseTask(args: Record<string, unknown>, ws: AgentWorkspace): Promise<HostToolResult> {
@@ -0,0 +1,104 @@
1
+ /**
2
+ * 团队节点权限委派工具(lead 专属):team_grant_nodes / team_revoke_nodes。
3
+ *
4
+ * lead 把**自己已绑定**的 DAQ/DCW 节点授权给同频道 worker(派发前、执行中均可),
5
+ * 授权面不可超越 lead 本人的绑定面(planDelegation fail-closed 校验)。
6
+ * 校验核心在 agents/node-delegation.ts;本文件只做工具面参数解析与结果文本。
7
+ */
8
+ import { AppError } from '../../../../../utils/errors'
9
+ import { applyDelegation, planDelegation, revokeDelegation, type DelegationMember } from '../../node-delegation'
10
+ import type { HostToolBridgeContext, HostToolResult } from '../types'
11
+
12
+ /** workspace 成员视图(listAgents 与本工具面的最小接口;便于单测桩替换) */
13
+ interface MembersView {
14
+ listAgents(): Promise<Array<{ id: string, role: 'lead' | 'worker', enabled?: number }>>
15
+ }
16
+
17
+ function membersOf(ws: MembersView): Promise<DelegationMember[]> {
18
+ return ws.listAgents() as Promise<DelegationMember[]>
19
+ }
20
+
21
+ function summaryText(bindings: Array<{ nodeId: string, kind: string, mode: string }>): string {
22
+ const lines = bindings.map(b => ` - ${b.kind === 'daq' ? '数采' : '写控'} ${b.nodeId}(mode=${b.mode})`)
23
+ return `\n${lines.join('\n')}`
24
+ }
25
+
26
+ function parseNodeIds(args: Record<string, unknown>): string[] {
27
+ const raw = args.node_ids ?? args.nodeIds
28
+ const list = Array.isArray(raw) ? raw : String(raw ?? '').split(',')
29
+ return list.map(x => String(x ?? '').trim()).filter(Boolean)
30
+ }
31
+
32
+ /** lead → worker 授予节点(自己绑定面内的节点;fail-closed 全成全败) */
33
+ export async function handleGrantNodes(identity: HostToolBridgeContext['identity'], args: Record<string, unknown>, ws: MembersView): Promise<HostToolResult> {
34
+ const targetAgentId = String(args.agent_id ?? args.assignee_id ?? '').trim()
35
+ const nodeIds = parseNodeIds(args)
36
+ const mode = args.mode === 'manual' || args.mode === 'auto' ? (args.mode as 'auto' | 'manual') : undefined
37
+ try {
38
+ const plan = planDelegation({
39
+ leaderAgentId: identity.agentId,
40
+ channelId: identity.channelId,
41
+ targetAgentId,
42
+ nodeIds,
43
+ members: await membersOf(ws),
44
+ mode,
45
+ })
46
+ const bindings = applyDelegation(plan, identity.agentId)
47
+ return {
48
+ text: `已把 ${bindings.length} 条节点授权授予 ${targetAgentId}:${summaryText(bindings)}\n来源:lead 绑定面内的节点;worker 现在可用 my_industrial_nodes 查看自己的授权。`,
49
+ }
50
+ }
51
+ catch (err) {
52
+ return { text: err instanceof AppError ? err.message : `节点授权失败: ${err instanceof Error ? err.message : String(err)}`, isError: true }
53
+ }
54
+ }
55
+
56
+ /** lead 收回授予给 worker 的节点授权 */
57
+ export async function handleRevokeNodes(identity: HostToolBridgeContext['identity'], args: Record<string, unknown>, ws: MembersView): Promise<HostToolResult> {
58
+ const targetAgentId = String(args.agent_id ?? args.assignee_id ?? '').trim()
59
+ const nodeIds = parseNodeIds(args)
60
+ try {
61
+ const results = revokeDelegation({
62
+ leaderAgentId: identity.agentId,
63
+ targetAgentId,
64
+ nodeIds,
65
+ members: await membersOf(ws),
66
+ })
67
+ const okList = results.filter(r => r.revoked)
68
+ const missList = results.filter(r => !r.revoked)
69
+ const parts = [`已收回 ${okList.length} 条授权`, ...okList.map(r => ` - ${r.kind} ${r.nodeId}`)]
70
+ if (missList.length) parts.push(`未收回(不在其绑定面或非你授予):${missList.map(r => `${r.kind}:${r.nodeId}`).join('、')}`)
71
+ return { text: parts.join('\n') }
72
+ }
73
+ catch (err) {
74
+ return { text: err instanceof AppError ? err.message : `收回授权失败: ${err instanceof Error ? err.message : String(err)}`, isError: true }
75
+ }
76
+ }
77
+
78
+ export interface DispatchGrantResult {
79
+ ok: boolean
80
+ text: string
81
+ }
82
+
83
+ /**
84
+ * 派发时随任务授予节点(dispatch_task 的 grant_node_ids;lead 专属)。
85
+ * fail-closed:任一节点不在 lead 绑定面 → 整单失败,任务不创建。
86
+ */
87
+ export async function grantNodesForDispatch(identity: HostToolBridgeContext['identity'], assigneeId: string, nodeIds: string[], mode: 'auto' | 'manual' | undefined, ws: MembersView): Promise<DispatchGrantResult> {
88
+ try {
89
+ const plan = planDelegation({
90
+ leaderAgentId: identity.agentId,
91
+ channelId: identity.channelId,
92
+ targetAgentId: assigneeId,
93
+ nodeIds,
94
+ members: await membersOf(ws),
95
+ mode,
96
+ })
97
+ const bindings = applyDelegation(plan, identity.agentId)
98
+ return { ok: true, text: `随任务授予 ${bindings.length} 条节点授权 → ${assigneeId}${summaryText(bindings)}` }
99
+ }
100
+ catch (err) {
101
+ const msg = err instanceof AppError ? err.message : `随任务授予节点失败: ${err instanceof Error ? err.message : String(err)}`
102
+ return { ok: false, text: msg }
103
+ }
104
+ }
@@ -17,7 +17,7 @@ export { toolMyIndustrialNodes, toolDcwControl, toolDcwRead } from './dcw-tools'
17
17
  export { toolParamControl, toolParamRead } from './param-tools'
18
18
  export { toolDaqQuery, toolDaqFrames } from './daq-tools'
19
19
  export { toolDcwJudge, toolDcwRollback, toolDcwJournal } from './dcw-judge-tools'
20
- export { toolOpsLog, toolRecipeLog, toolLineContext, toolRecipeVersions, toolRecipeUpdate, toolRecipeRollback } from './ops-tools'
20
+ export { toolOpsLog, toolRecipeLog, toolLineContext, toolRecipeVersions, toolRecipeUpdate, toolRecipeRollback, toolRecipeTrial, toolRecipeApply } from './ops-tools'
21
21
  export { toolAmlNodeCatalog, toolAmlDatasetBuild, toolAmlDatasetStats } from './aml-dataset-tools'
22
22
  export { toolAmlJobSubmit, toolAmlJobStatus, toolAmlJobLogs, toolAmlJobCancel, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolAmlTrainingPlanCreate } from './aml-job-tools'
23
23