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
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/_audit/kb-team-mock-e2e.mjs —— 知识库集成 Channel + lead→worker 节点委派(mock 阶段验收)。
4
+ *
5
+ * 覆盖(无 LLM 依赖):
6
+ * 1) 模板知识库能力面:chtpl-generic-optimize-default / chtpl-aml-optimization-default 标记 knowledgeBaseCapable;
7
+ * 2) 实例化 enableKnowledgeBase=true → 频道插件开关含 rag-bridge=on,场景提示词含 KB 作业段;
8
+ * 3) 实例化 enableKnowledgeBase=false → rag-bridge=off;缺省 → 无显式行(平台默认);
9
+ * 4) 委派 REST:lead 绑定面内节点授予 worker(grantedByAgentId 溯源);
10
+ * 5) fail-closed:越面授予 403 / 授予 lead 自己 400;
11
+ * 6) 执行中授予:worker 有在飞任务时仍可被授予新节点;
12
+ * 7) 撤销:收回授予的节点;非 lead 授予且 lead 不持有的绑定不被误撤。
13
+ *
14
+ * 用法:AW_BASE=http://127.0.0.1:3456 node scripts/_audit/kb-team-mock-e2e.mjs
15
+ * 前置:全新实例(首注册即 admin)。脚本自行注册 admin 账号并搭一条 mock 产线。
16
+ */
17
+ const BASE = process.env.AW_BASE ?? 'http://127.0.0.1:3456'
18
+ const ADMIN = { email: process.env.AW_ADMIN_EMAIL ?? 'admin@awshop.local', password: process.env.AW_ADMIN_PASSWORD ?? 'Awshop@123!' }
19
+
20
+ let pass = 0
21
+ const fails = []
22
+ const ok = (name, cond, detail = '') => {
23
+ if (cond) { pass++; console.log(` PASS ${name}${detail ? ` — ${detail}` : ''}`) }
24
+ else { fails.push(name); console.log(` FAIL ${name}${detail ? ` — ${detail}` : ''}`) }
25
+ }
26
+ const section = t => console.log(`\n━━━ ${t} ━━━`)
27
+ const sleep = ms => new Promise(r => setTimeout(r, ms))
28
+
29
+ async function api(method, path, { body, token } = {}) {
30
+ const res = await fetch(BASE + path, {
31
+ method,
32
+ headers: { 'content-type': 'application/json', ...(token ? { authorization: `Bearer ${token}` } : {}) },
33
+ body: body != null ? JSON.stringify(body) : undefined,
34
+ signal: AbortSignal.timeout(30000),
35
+ })
36
+ const json = await res.json().catch(() => null)
37
+ return { status: res.status, json }
38
+ }
39
+
40
+ const TAG = `kbmock-${new Date().toISOString().slice(5, 16).replace(/[-T:]/g, '')}`
41
+
42
+ async function main() {
43
+ section('S0 管理员就绪(全新实例首注册即 admin)')
44
+ const reg = await api('POST', '/api/users/register', { body: { ...ADMIN, name: 'kb-mock-admin' } })
45
+ const token = reg.json?.data?.token ?? (await api('POST', '/api/users/login', { body: { email: ADMIN.email, password: ADMIN.password } })).json?.data?.token
46
+ ok('管理员 token 可用', Boolean(token))
47
+ const auth = { token }
48
+
49
+ section('S1 模板知识库能力面')
50
+ const tplList = (await api('GET', '/api/workshop/channel-templates', auth)).json?.data ?? []
51
+ const generic = tplList.find(t => t.id === 'chtpl-generic-optimize-default')
52
+ const optTpl = tplList.find(t => t.id === 'chtpl-aml-optimization-default')
53
+ ok('内置模板存在「通用闭环优化频道(标准)」', Boolean(generic), generic?.name)
54
+ ok('通用模板标记 knowledgeBaseCapable', generic?.knowledgeBaseCapable === true)
55
+ ok('工艺优化通道标记 knowledgeBaseCapable', optTpl?.knowledgeBaseCapable === true)
56
+ ok('其他模板不带该标记', tplList.find(t => t.id === 'chtpl-default-fullstack')?.knowledgeBaseCapable !== true)
57
+
58
+ section('S2 实例化:enableKnowledgeBase=true → rag-bridge 开 + KB 作业段')
59
+ const inst1 = (await api('POST', '/api/workshop/channel-templates/chtpl-generic-optimize-default/instantiate', { body: { name: `${TAG}-kb-on`, enableKnowledgeBase: true }, ...auth })).json?.data
60
+ ok('通用频道实例化成功', Boolean(inst1?.channelId), `agents=${inst1?.agentCount}`)
61
+ const ch1 = (await api('GET', `/api/workshop/channels/${inst1.channelId}`, auth)).json?.data
62
+ ok('场景提示词含知识库作业段', String(ch1?.scenarioPrompt ?? '').includes('知识库集成') && String(ch1?.scenarioPrompt ?? '').includes('kb_agent'))
63
+ const plug1 = (await api('GET', `/api/workshop/channels/${inst1.channelId}/plugins`, auth)).json?.data
64
+ const rb1 = (Array.isArray(plug1?.plugins) ? plug1.plugins : plug1 ?? []).find?.(p => p?.name === 'rag-bridge')
65
+ ?? (Array.isArray(plug1) ? plug1 : []).find(p => p?.name === 'rag-bridge')
66
+ ok('频道插件开关含 rag-bridge=on', Boolean(rb1 && rb1.enabled !== false), JSON.stringify(rb1 ?? plug1 ?? {}).slice(0, 120))
67
+ const members1 = (await api('GET', `/api/workshop/channels/${inst1.channelId}/agents`, auth)).json?.data ?? []
68
+ ok('频道含 lead + worker', members1.some(m => m.role === 'lead') && members1.filter(m => m.role === 'worker').length >= 2, `members=${members1.length}`)
69
+
70
+ section('S3 实例化:enableKnowledgeBase=false 与缺省行为')
71
+ const inst2 = (await api('POST', '/api/workshop/channel-templates/chtpl-aml-optimization-default/instantiate', { body: { name: `${TAG}-kb-off`, enableKnowledgeBase: false }, ...auth })).json?.data
72
+ const plug2 = (await api('GET', `/api/workshop/channels/${inst2.channelId}/plugins`, auth)).json?.data
73
+ const flat2 = Array.isArray(plug2?.plugins) ? plug2.plugins : (Array.isArray(plug2) ? plug2 : [])
74
+ ok('显式 false → rag-bridge=off', flat2.some(p => p?.name === 'rag-bridge' && p.enabled === false), JSON.stringify(flat2).slice(0, 120))
75
+ const inst3 = (await api('POST', '/api/workshop/channel-templates/chtpl-aml-optimization-default/instantiate', { body: { name: `${TAG}-kb-default` }, ...auth })).json?.data
76
+ const plug3 = (await api('GET', `/api/workshop/channels/${inst3.channelId}/plugins`, auth)).json?.data
77
+ const flat3 = Array.isArray(plug3?.plugins) ? plug3.plugins : (Array.isArray(plug3) ? plug3 : [])
78
+ const rb3 = flat3.find(p => p?.name === 'rag-bridge')
79
+ ok('缺省 → rag-bridge 保持平台默认(未被显式停用)', !rb3 || rb3.enabled !== false, JSON.stringify(flat3).slice(0, 120))
80
+
81
+ section('S4 搭 mock 产线(建线 + 模板 + 数采/数控节点)')
82
+ const line = (await api('POST', '/api/workshop/dcw/lines', { body: { name: `KBMock线-${TAG}`, description: 'kb-team mock e2e' }, ...auth })).json?.data
83
+ const lineId = line?.line?.id ?? line?.id
84
+ ok('建线成功', Boolean(lineId), lineId)
85
+ const dcwTpl = (await api('POST', '/api/workshop/dcw/templates', { body: { name: `kbmock-sp-tpl-${TAG}`, ch: '温度设定', unit: '℃', min: 150, max: 220, decimals: 1 }, ...auth })).json?.data
86
+ const daqTpl = (await api('POST', '/api/workshop/daq/templates', { body: { name: `kbmock-temp-tpl-${TAG}`, ch: '温度', unit: '℃', min: 0, max: 300, decimals: 1 }, ...auth })).json?.data
87
+ const dcwTplRef = dcwTpl?.template?.key ?? dcwTpl?.key
88
+ const daqTplRef = daqTpl?.template?.key ?? daqTpl?.key
89
+ ok('节点模板创建成功', Boolean(dcwTplRef) && Boolean(daqTplRef), `dcw=${dcwTplRef} daq=${daqTplRef}`)
90
+ const dcw = (await api('POST', '/api/workshop/dcw', { body: { name: `kbmock-sp-${TAG}`, templateRef: dcwTplRef, driver: 'mock', unit: '℃', min: 150, max: 220, stepLimit: 5, lineId }, ...auth })).json
91
+ const daq = (await api('POST', '/api/workshop/daq', { body: { name: `kbmock-temp-${TAG}`, templateRef: daqTplRef, driver: 'mock', intervalMs: 1000, publishIntervalMs: 0, lineId }, ...auth })).json
92
+ const dcwId = dcw?.data?.node?.id
93
+ const daqId = daq?.data?.node?.id
94
+ ok('数采/数控节点创建成功', Boolean(daqId) && Boolean(dcwId), `daq=${daqId} dcw=${dcwId}`)
95
+
96
+ section('S5 lead 绑定 + 委派核心面')
97
+ const lead = members1.find(m => m.role === 'lead')
98
+ const worker = members1.find(m => m.role === 'worker')
99
+ const b1 = await api('POST', '/api/workshop/agent-tools/bindings', { body: { agentId: lead.id, nodeId: dcwId, kind: 'dcw', mode: 'manual' }, ...auth })
100
+ const b2 = await api('POST', '/api/workshop/agent-tools/bindings', { body: { agentId: lead.id, nodeId: daqId, kind: 'daq', mode: 'auto' }, ...auth })
101
+ ok('lead 绑定 dcw+daq 成功', b1.status === 200 && b2.status === 200, `dcw=${b1.status} daq=${b2.status}`)
102
+
103
+ const grant = await api('POST', '/api/workshop/agent-tools/bindings/grant', { body: { channelId: inst1.channelId, agentId: worker.id, nodeIds: [dcwId, daqId] }, ...auth })
104
+ ok('委派授予成功(整单)', grant.status === 200, JSON.stringify(grant.json?.data ?? grant.json).slice(0, 120))
105
+ const granted = grant.json?.data?.granted ?? []
106
+ ok('授予绑定带 lead 溯源', granted.length === 2 && granted.every(g => g.grantedByAgentId === lead.id), `n=${granted.length}`)
107
+ ok('dcw 委派缺省随 lead 的 manual 模式', granted.find(g => g.kind === 'dcw')?.mode === 'manual')
108
+ const workerBindings = (await api('GET', `/api/workshop/agent-tools/bindings?agentId=${worker.id}`, auth)).json?.data
109
+ const wbFlat = Array.isArray(workerBindings) ? workerBindings : (workerBindings?.bindings ?? [])
110
+ ok('worker 绑定面已含委派节点', wbFlat.some(b => b.nodeId === dcwId) && wbFlat.some(b => b.nodeId === daqId), `n=${wbFlat.length}`)
111
+
112
+ section('S6 fail-closed:越面授予 / 授予 lead 自己')
113
+ const bad = await api('POST', '/api/workshop/agent-tools/bindings/grant', { body: { channelId: inst1.channelId, agentId: worker.id, nodeIds: [`ghost-${TAG}`] }, ...auth })
114
+ const badCode = bad.json?.code ?? bad.json?.data?.code
115
+ ok('越面授予被拒(403 DELEGATION_NOT_OWNED)', bad.status === 403 && badCode === 'DELEGATION_NOT_OWNED', `status=${bad.status} code=${badCode}`)
116
+ const self = await api('POST', '/api/workshop/agent-tools/bindings/grant', { body: { channelId: inst1.channelId, agentId: lead.id, nodeIds: [dcwId] }, ...auth })
117
+ ok('授予 lead 自己被拒(400)', self.status === 400, `status=${self.status}`)
118
+
119
+ section('S7 执行中授予(worker 有在飞任务时仍可授权)')
120
+ const task = (await api('POST', `/api/workshop/channels/${inst1.channelId}/tasks`, { body: { title: `巡检-${TAG}`, description: '读取授权节点并汇报(委派执行中授予验证)', assigneeId: worker.id }, ...auth })).json?.data
121
+ ok('worker 根任务已创建', Boolean(task?.id), task?.id)
122
+ await sleep(500)
123
+ const midGrant = await api('POST', '/api/workshop/agent-tools/bindings/grant', { body: { channelId: inst1.channelId, agentId: worker.id, nodeIds: [dcwId], mode: 'auto' }, ...auth })
124
+ ok('执行中授予成功(模式覆盖 auto)', midGrant.status === 200, JSON.stringify(midGrant.json?.data ?? {}).slice(0, 100))
125
+ await api('POST', `/api/workshop/channels/${inst1.channelId}/tasks/${task.id}/cancel`, { ...auth }).catch(() => {})
126
+
127
+ section('S8 撤销')
128
+ const revoke = await api('POST', '/api/workshop/agent-tools/bindings/revoke', { body: { channelId: inst1.channelId, agentId: worker.id, nodeIds: [daqId] }, ...auth })
129
+ const results = revoke.json?.data?.results ?? []
130
+ ok('撤销 daq 委派成功', revoke.status === 200 && results.every(r => r.revoked), JSON.stringify(results).slice(0, 100))
131
+ const afterRevoke = (await api('GET', `/api/workshop/agent-tools/bindings?agentId=${worker.id}`, auth)).json?.data
132
+ const arFlat = Array.isArray(afterRevoke) ? afterRevoke : (afterRevoke?.bindings ?? [])
133
+ ok('撤销后 worker 不再持有该节点', !arFlat.some(b => b.nodeId === daqId), `剩余=${arFlat.length}`)
134
+
135
+ console.log(`\n════ 结果: ${pass} PASS / ${fails.length} FAIL ════`)
136
+ if (fails.length) {
137
+ console.log('失败项:')
138
+ for (const f of fails) console.log(` - ${f}`)
139
+ process.exit(1)
140
+ }
141
+ }
142
+
143
+ main().catch((err) => {
144
+ console.error('E2E 致命异常:', err)
145
+ process.exit(1)
146
+ })
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scripts/_audit/kb-team-omp-e2e.mjs —— 知识库集成通用闭环优化频道 × 真实 omp × 多 PLC 模拟场景。
4
+ *
5
+ * 每个 scenario:
6
+ * ① 模拟器建场(ensureScenarioLine) + 平台建线开跑(provisionScenarioLine,真实协议链路);
7
+ * ② 实例化「通用闭环优化频道(标准)」模板,enableKnowledgeBase=true(频道加载 rag-bridge);
8
+ * ③ lead 绑定 PV 数采节点 + 调节数控节点(auto);
9
+ * ④ 提交优化 goal(要求:先查知识库 → lead 委派节点权限 → 治理小步下发复测 → 判定 → 经验沉淀);
10
+ * ⑤ 期间轮询任务/消息/事件,全程转录落盘(transcript.md + 原始 JSON);
11
+ * ⑥ 验收:根任务收口 + worker 确实被授予节点(grantedBy 溯源) + 发生过治理写入
12
+ * + PV 回带 + 知识库经验新增(kb_agent 异步落库)。
13
+ *
14
+ * 用法:
15
+ * node scripts/_audit/kb-team-omp-e2e.mjs --base http://127.0.0.1:3456 --scenarios injection,wwtp
16
+ * 前置:目标实例为本仓库构建(内置通用模板 + rag-bridge);rag-bridge token 已配置(启 KB 鉴权时);
17
+ * omp CLI 在 PATH 且可用;模拟器可自举(bench/lib/sim.mjs ensureSimulator)。
18
+ */
19
+ import { join, dirname, resolve } from 'node:path'
20
+ import { writeFileSync, appendFileSync } from 'node:fs'
21
+ import { fileURLToPath } from 'node:url'
22
+ import { makeApi, ensureDir, sleep } from '../../bench/lib/util.mjs'
23
+ import { ensureSimulator, simUp } from '../../bench/lib/sim.mjs'
24
+ import { SCENARIOS, ensureScenarioLine, provisionScenarioLine, readPvMean } from '../../bench/lib/scenarios.mjs'
25
+
26
+ const HERE = dirname(fileURLToPath(import.meta.url))
27
+ const REPO = resolve(HERE, '../..')
28
+ const args = process.argv.slice(2)
29
+ const arg = (k, d) => { const i = args.indexOf(`--${k}`); return i >= 0 ? (args[i + 1] ?? '') : d }
30
+
31
+ const BASE = arg('base', process.env.AW_BASE ?? 'http://127.0.0.1:3456')
32
+ const list = (arg('scenarios', 'injection') || 'injection').split(',').map(s => s.trim()).filter(id => SCENARIOS[id])
33
+ const TASK_TIMEOUT_MS = Number(arg('timeout-min', '32')) * 60_000
34
+ const KB_WAIT_MS = Number(arg('kb-wait-min', '6')) * 60_000
35
+ const POLL_MS = 20_000
36
+ const sfx = arg('sfx', `kb${new Date().toISOString().slice(5, 16).replace(/[-T:]/g, '')}`)
37
+
38
+ const rid = `kb-team-omp-${new Date().toISOString().slice(0, 19).replace(/[-T:]/g, '')}`
39
+ const outDir = ensureDir(join(REPO, 'bench', 'results', rid))
40
+ console.log(`=== kb-team × omp 闭环优化 × 多场景 ===\nbase=${BASE} scenarios=${list.join(',')} out=${outDir}\n`)
41
+
42
+ // ── 自举 ──
43
+ if (!(await simUp())) {
44
+ const r = await ensureSimulator({ log: console.log })
45
+ if (!r.started && !(await simUp())) { console.error(`✘ 模拟器自举失败: ${r.reason}`); process.exit(1) }
46
+ }
47
+ const api = makeApi(BASE)
48
+ const login = await api.login(process.env.AW_ADMIN_EMAIL ?? 'admin@awshop.local', process.env.AW_ADMIN_PASSWORD ?? 'Awshop@123!')
49
+ if (!login.ok) { console.error('✘ 平台登录失败'); process.exit(1) }
50
+ console.log(`平台就绪(${login.how},role=${login.role});模拟器就绪\n`)
51
+
52
+ const globalResult = { rid, base: BASE, scenarios: [] }
53
+
54
+ for (const id of list) {
55
+ const scen = SCENARIOS[id]
56
+ const dir = ensureDir(join(outDir, id))
57
+ const res = { scenario: id, zh: scen.zh, checks: {}, errors: [] }
58
+ globalResult.scenarios.push(res)
59
+ const log = (line) => { console.log(`[${id}] ${line}`); appendFileSync(join(dir, 'transcript.md'), `${line}\n`) }
60
+ writeFileSync(join(dir, 'transcript.md'), `# ${scen.zh}(kb-team × omp)作业转录\n\n- 开始: ${new Date().toISOString()}\n- 频道模板: chtl-generic-optimize-default(enableKnowledgeBase=true)\n\n`)
61
+
62
+ try {
63
+ // ── ① 建场 + 建线 ──
64
+ log(`① 模拟器建场 ${scen.key} …`)
65
+ const ensure = await ensureScenarioLine(scen)
66
+ log(` 设备=${ensure.verified.devices}/${ensure.verified.expectDevices} SP=${ensure.verified.sp} PV=${ensure.verified.pv} 协议=${ensure.verified.protocols.join('/')}`)
67
+ const line = await provisionScenarioLine(api, scen, { sfx: `${sfx}-${id}` })
68
+ if (line.errors?.length || !line.ids?.lineId) throw new Error(`建线失败: ${line.errors?.join(';')}`)
69
+ res.line = { lineId: line.ids.lineId, recipeId: line.ids.recipeId, started: line.ids.started, reused: line.reused }
70
+ log(`① 平台建线 ${line.lineName} started=${line.ids.started} dcw=${Object.keys(line.dcw).length} daq=${Object.keys(line.daq).length}`)
71
+
72
+ // ── ② 实例化 KB 通用频道 ──
73
+ const inst = (await api.call('POST', '/api/workshop/channel-templates/chtpl-generic-optimize-default/instantiate', {
74
+ name: `KB闭环优化-${scen.zh}-${sfx}-${id}`,
75
+ enableKnowledgeBase: true,
76
+ }))
77
+ const channelId = inst.data?.channelId
78
+ if (!channelId) throw new Error(`频道实例化失败: ${inst.message}`)
79
+ const agents = (await api.call('GET', `/api/workshop/channels/${channelId}/agents`)).data ?? []
80
+ const lead = agents.find(a => a.role === 'lead')
81
+ res.channel = { channelId, leadId: lead?.id, leadHarness: lead?.harness }
82
+ log(`② 频道 ${channelId} 已实例化(lead=${lead?.name}/${lead?.harness},成员=${agents.length})`)
83
+
84
+ // ── ③ lead 绑定 PV 数采 + 调节数控(auto) ──
85
+ const pvNode = line.daq[scen.pv.sig]
86
+ const knobSigs = (scen.knobs ?? []).map(k => k.sig).slice(0, 2)
87
+ const knobNodes = knobSigs.map(s => line.dcw[s]).filter(Boolean)
88
+ if (!pvNode || !knobNodes.length) throw new Error(`关键节点缺失: pv=${pvNode} knobs=${knobNodes}`)
89
+ for (const [nodeId, kind] of [[pvNode, 'daq'], ...knobNodes.map(n => [n, 'dcw'])]) {
90
+ const r = await api.call('POST', '/api/workshop/agent-tools/bindings', { agentId: lead.id, nodeId, kind, mode: 'auto' })
91
+ if (r.status !== 200) throw new Error(`lead 绑定失败 ${kind} ${nodeId}: ${r.message}`)
92
+ }
93
+ res.leadBindings = { pvNode, knobNodes }
94
+ log(`③ lead 绑定:daq(${scen.pv.sig})=${pvNode} dcw=${knobNodes.join(',')}`)
95
+
96
+ // ── ④ 提交 goal ──
97
+ const knobText = (scen.knobs ?? []).slice(0, 2).map(k => `${k.sig}`).join('、')
98
+ const guardText = (scen.guards ?? []).map(g => `${g.label}≤${g.max}`).join('、') || '无'
99
+ const goal = [
100
+ `【产线闭环优化】${scen.zh}:${scen.story}`,
101
+ `目标:把「${scen.pv.label}(${scen.pv.sig})」稳定控制回 ${scen.pv.target}±${scen.pv.tol}${scen.pv.unit} 目标带;守卫约束:${guardText}。`,
102
+ `可调手段(数控节点,治理下发):${knobText}。`,
103
+ `作业要求:`,
104
+ `1. 开工先查知识库:lead 用 kb_agent(mode=sync) 检索「${scen.zh} 数据分析」「${scen.pv.label} 物理机理与设定影响」,把检索结论作为寻优方向与步长依据;`,
105
+ `2. lead 把自己已绑定的节点授权授予 worker(dispatch_task 带 grant_node_ids 随任务授予,或 team_grant_nodes),确保工艺工程师与数据分析师各自拿到所需节点权限,不要无权限空转;`,
106
+ `3. 工艺工程师单变量小步调整(每步 ≤ 量程 2%,尊重单步限幅与写入间隔),每次调整后等 ${Math.round(scen.settleMs / 1000)}s 再 daq_query 复测「${scen.pv.label}」;`,
107
+ `4. 进入目标带且复测稳定后 dcw_judge 落判定(keep),lead 用 kb_agent(mode=async) 把本次经验沉淀入知识库(含调整前后参数值与响应数据),随后完成收口汇报。`,
108
+ ].join('\n')
109
+ const task = (await api.call('POST', `/api/workshop/channels/${channelId}/tasks`, { title: `${scen.zh}(KB 闭环)`, description: goal })).data
110
+ if (!task?.id) throw new Error(`根任务提交失败`)
111
+ res.rootTaskId = task.id
112
+ log(`④ 根任务 ${task.id} 已提交,开始作业(超时 ${Math.round(TASK_TIMEOUT_MS / 60000)}min)…\n`)
113
+
114
+ // ── ⑤ 轮询转录 ──
115
+ let seenMsg = new Set()
116
+ let seenTaskState = new Map()
117
+ let lastEventSeq = 0
118
+ let toolEvidence = { kbAgent: 0, grant: 0 }
119
+ const t0 = Date.now()
120
+ let terminal = null
121
+ const dump = async () => {
122
+ const msgs = (await api.call('GET', `/api/workshop/channels/${channelId}/messages?limit=200`)).data ?? []
123
+ for (const m of [...msgs].reverse()) {
124
+ const key = m.id ?? `${m.createdAt}:${m.fromAgentName}`
125
+ if (seenMsg.has(key)) continue
126
+ seenMsg.add(key)
127
+ const who = m.fromAgentName ?? m.from ?? '?'
128
+ const text = String(m.text ?? m.preview ?? '').slice(0, 600)
129
+ if (text.trim()) appendFileSync(join(dir, 'transcript.md'), `\n> **${who}** @ ${m.createdAt ?? ''}\n>\n${text.split('\n').map(l => `> ${l}`).join('\n')}\n`)
130
+ }
131
+ const tasks = (await api.call('GET', `/api/workshop/channels/${channelId}/tasks`)).data ?? []
132
+ const arr = Array.isArray(tasks) ? tasks : (tasks.tasks ?? [])
133
+ for (const t of arr) {
134
+ const st = `${t.id}:${t.state}:${t.progress ?? 0}`
135
+ if (seenTaskState.get(t.id) !== st) {
136
+ seenTaskState.set(t.id, st)
137
+ appendFileSync(join(dir, 'transcript.md'), `\n- [任务] ${t.id} 「${t.title}」 state=${t.state} progress=${t.progress ?? 0}% assignee=${t.assigneeId ?? '-'}`)
138
+ }
139
+ }
140
+ // 事件流:记录工具调用证据(kb_agent / team_grant_nodes / grant_node_ids)与 lead 进度报告
141
+ const ev = (await api.call('GET', `/api/workshop/channels/${channelId}/events?limit=200&afterSeq=${lastEventSeq}`)).data ?? {}
142
+ for (const item of (ev.items ?? [])) {
143
+ lastEventSeq = Math.max(lastEventSeq, Number(item.seq ?? 0))
144
+ const text = String(item.payload?.text ?? item.payload?.summary ?? '')
145
+ if (!text) continue
146
+ const kbHits = (text.match(/kb_agent/g) ?? []).length
147
+ const grantHits = (text.match(/team_grant_nodes|grant_node_ids/g) ?? []).length
148
+ toolEvidence.kbAgent += kbHits
149
+ toolEvidence.grant += grantHits
150
+ if (kbHits || grantHits) {
151
+ appendFileSync(join(dir, 'transcript.md'), `\n- [工具证据] @ ${(item.at ?? item.createdAt ?? '').slice(11, 19)} ${text.replace(/\n+/g, ' ').slice(0, 220)}`)
152
+ }
153
+ }
154
+ return { tasks: arr, msgs }
155
+ }
156
+ while (Date.now() - t0 < TASK_TIMEOUT_MS) {
157
+ await sleep(POLL_MS)
158
+ try {
159
+ const { tasks } = await dump()
160
+ const root = tasks.find(t => t.id === task.id)
161
+ if (root && ['COMPLETED', 'FAILED', 'CANCELED'].includes(root.state)) { terminal = root; break }
162
+ log(`… 作业中(${Math.round((Date.now() - t0) / 60000)}min)root=${root?.state ?? '?'}`)
163
+ }
164
+ catch (err) {
165
+ log(`… 轮询抖动(忽略): ${err?.message ?? err}`)
166
+ }
167
+ }
168
+ await dump()
169
+ if (!terminal) { res.errors.push(`根任务超时(${Math.round(TASK_TIMEOUT_MS / 60000)}min)未收口`) }
170
+ else if (terminal.state !== 'COMPLETED') { res.errors.push(`根任务终态=${terminal.state}`) }
171
+ res.checks.rootTaskClosed = terminal?.state === 'COMPLETED'
172
+ log(`\n⑤ 根任务终态=${terminal?.state ?? 'TIMEOUT'}`)
173
+
174
+ // ── ⑥ 验收 ──
175
+ const workers = agents.filter(a => a.role === 'worker')
176
+ let delegated = 0
177
+ for (const w of workers) {
178
+ const bs = (await api.call('GET', `/api/workshop/agent-tools/bindings?agentId=${w.id}`)).data
179
+ const flat = Array.isArray(bs) ? bs : (bs?.bindings ?? [])
180
+ if (flat.some(b => b.grantedByAgentId === lead.id)) delegated++
181
+ }
182
+ res.checks.workerDelegated = delegated > 0
183
+ log(`⑥ 委派核验:${delegated}/${workers.length} 个 worker 持有 lead 授予的节点授权`)
184
+
185
+ const dcwNow = (await api.call('GET', '/api/workshop/dcw')).data?.nodes ?? []
186
+ const myDcw = dcwNow.filter(n => Object.values(line.dcw).includes(n.id))
187
+ const wrote = myDcw.some(n => n.lastWriteAt)
188
+ res.checks.governedWriteHappened = wrote
189
+ res.dcAfter = myDcw.map(n => ({ id: n.id, name: n.name, value: n.value, lastWriteAt: n.lastWriteAt ?? null }))
190
+ log(`⑥ 治理写入核验:${wrote ? '发生过 dcw 治理写入' : '无 dcw 写入痕迹'}`)
191
+
192
+ const pvMean = await readPvMean(api, pvNode, 5).catch(() => null)
193
+ const inBand = pvMean != null && Math.abs(Number(pvMean) - scen.pv.target) <= scen.pv.tol
194
+ res.checks.pvInBand = inBand
195
+ res.pvMean = pvMean
196
+ log(`⑥ PV 复测:均值=${pvMean} 目标带=${scen.pv.target}±${scen.pv.tol} → ${inBand ? '达标' : '未达标'}`)
197
+
198
+ res.toolEvidence = toolEvidence
199
+ res.checks.kbToolUsed = toolEvidence.kbAgent > 0
200
+ res.checks.grantToolUsed = toolEvidence.grant > 0 || delegated > 0
201
+ log(`⑥ 工具证据(事件流):kb_agent×${toolEvidence.kbAgent} 委派×${toolEvidence.grant}`)
202
+
203
+ log(`⑥ 等待知识库经验沉淀可检索(≤${Math.round(KB_WAIT_MS / 60000)}min)…`)
204
+ const kbQuery = encodeURIComponent(`${scen.zh.slice(0, 6)} ${scen.pv.label} 经验`)
205
+ const kbDeadline = Date.now() + KB_WAIT_MS
206
+ let kbHit = false
207
+ while (Date.now() < kbDeadline) {
208
+ await sleep(45_000)
209
+ const sr = (await api.call('GET', `/api/plugins/rag-bridge/search?q=${kbQuery}&top_k=5`).catch(() => null))?.data
210
+ if ((sr?.total_results ?? 0) > 0 || (sr?.results ?? []).length > 0) { kbHit = true; break }
211
+ log(` … 检索暂未命中(累计等待 ${Math.round((kbDeadline - Date.now()) / 60000)}min)`)
212
+ }
213
+ res.checks.kbExperience = kbHit
214
+ log(`⑥ 知识库经验检索:${kbHit ? '已检出本场景经验内容' : '超时未检出(检索面后端索引漂移时以转录工具证据为准)'}`)
215
+ }
216
+ catch (err) {
217
+ res.errors.push(String(err?.message ?? err))
218
+ log(`✘ 异常: ${err?.message ?? err}`)
219
+ }
220
+
221
+ res.ok = res.errors.length === 0 && Object.values(res.checks).every(Boolean)
222
+ log(`\n════ [${id}] 结果: ${res.ok ? 'PASS' : 'FAIL'} checks=${JSON.stringify(res.checks)}${res.errors.length ? ` errors=${res.errors.join(';')}` : ''}`)
223
+ writeFileSync(join(dir, 'final.json'), JSON.stringify(res, null, 2))
224
+ }
225
+
226
+ writeFileSync(join(outDir, 'kb-team-omp-result.json'), JSON.stringify(globalResult, null, 2))
227
+ const allOk = globalResult.scenarios.every(s => s.ok)
228
+ console.log(`\n════ 总结果: ${allOk ? '✅ 全场景 PASS' : '❌ 存在 FAIL'}(明细: ${outDir})`)
229
+ process.exit(allOk ? 0 : 1)
@@ -21,7 +21,8 @@ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/
21
21
  import { createWorkshopMcpServer } from '../../mcp/workshop-server'
22
22
  import { getWorkshopManager } from '../../plugins/workshop'
23
23
 
24
- /** 会话注册表:sessionId → transport(stateful 会话状态保留) */
24
+ /** 会话注册表:sessionId → transport(stateful 会话状态保留);上限防匿名刷爆内存 */
25
+ const MAX_MCP_SESSIONS = 64
25
26
  const sessions = new Map<string, WebStandardStreamableHTTPServerTransport>()
26
27
 
27
28
  /** h3 event → web Request(跨 h3 1.x/2.x 兼容:不用版本互异的转换助手) */
@@ -65,6 +66,12 @@ export default defineEventHandler(async (event) => {
65
66
 
66
67
  // 新会话:预生成 sessionId,transport 在 initialize 时把它写入响应头
67
68
  if (!transport) {
69
+ if (sessions.size >= MAX_MCP_SESSIONS) {
70
+ return new Response(JSON.stringify({ error: 'TOO_MANY_SESSIONS', message: `MCP 会话数已达上限 ${MAX_MCP_SESSIONS}` }), {
71
+ status: 429,
72
+ headers: { 'content-type': 'application/json' },
73
+ })
74
+ }
68
75
  const newSessionId = randomUUID()
69
76
  transport = new WebStandardStreamableHTTPServerTransport({
70
77
  sessionIdGenerator: () => newSessionId,
@@ -2,11 +2,13 @@
2
2
  * GET /api/metrics —— 运维指标端点(R4,production-readiness-plan)。
3
3
  *
4
4
  * text/plain 简易指标格式(键值行,Prometheus 可用 textfile/自定义采集器接入)。
5
- * 无鉴权:仅暴露聚合计数与时间戳,不含业务数据;内网部署语义。
5
+ * 鉴权:任意有效用户 token(Bearer)——聚合计数与时间戳不含业务数据,
6
+ * 但公网部署下不向匿名暴露运行面信息;采集器配 Token 头即可接入。
6
7
  * 只读 globalThis 单例(不主动实例化),服务未装配时输出 0 —— 首次抓取即合法。
7
8
  */
8
9
  import { defineEventHandler, setResponseHeader } from 'h3'
9
10
  import { getOps } from '../services/workshop/ops/ops'
11
+ import { resolveUser } from './workshop/caller'
10
12
 
11
13
  interface MetricLine { name: string, help: string, value: number | string }
12
14
 
@@ -15,6 +17,7 @@ function fmt(lines: MetricLine[]): string {
15
17
  }
16
18
 
17
19
  export default defineEventHandler(async (event) => {
20
+ resolveUser(event)
18
21
  const g = globalThis as typeof globalThis & {
19
22
  __daqController?: { controllerState(): Record<string, number | boolean>, running?: boolean }
20
23
  __daqQueue?: { lost?: number }
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * /api/plugins/:name/** —— 插件自注册 API 的转发层(exact-match)。
3
3
  * 插件经 ctx.route(method, path, handler) 注册;handler(event) 返回值由 nitro 序列化。
4
- * 鉴权:插件在入口声明 auth:'user' | 'admin' | 'agent-or-user' 时由转发层统一校验
5
- * (缺省 'none' 保持开放,兼容既有插件/浏览器面板)。
4
+ * 鉴权:插件在入口声明 auth:'user' | 'admin' | 'agent-or-user' | 'none' 时由转发层统一校验。
5
+ * 安全默认 = 'user'(default-deny):未声明的插件不再匿名暴露,须显式声明 'none' 才开放
6
+ * (公网部署基线;确需匿名的只读面由插件作者显式声明并承担暴露责任)。
6
7
  * 错误隔离:插件 handler 抛错 → 结构化日志(带插件归属)+ 干净 500 信封,不裸传堆栈。
7
8
  */
8
9
  import { defineEventHandler, createError, readBody } from 'h3'
@@ -16,7 +17,7 @@ export default defineEventHandler(async (event) => {
16
17
  const path = '/' + (event.context.params?.path ?? '').replace(/^\/+/, '')
17
18
  const rec = host.plugins.get(name)
18
19
  // 声明式鉴权门:在进入插件 handler 前统一校验(禁用插件的路由表已不含其路由,天然 404)
19
- const authMode = String(rec?.auth ?? 'none')
20
+ const authMode = String(rec?.auth ?? 'user')
20
21
  if (authMode !== 'none') {
21
22
  try {
22
23
  if (authMode === 'admin') await requireAdmin(event)
@@ -0,0 +1,32 @@
1
+ /**
2
+ * GET /api/system/backup/list —— 备份清单(admin):库快照文件 + JSON/配置束目录。
3
+ * 只列文件名与大小/时间,不回传内容;恢复操作 = 停实例后由运维手工替换(安全优先不给在线恢复 API)。
4
+ */
5
+ import { readdirSync, statSync } from 'node:fs'
6
+ import { resolve } from 'node:path'
7
+ import { defineApiHandler } from '../../../utils/response'
8
+ import { requireAdmin } from '../../workshop/caller'
9
+ import { ensureDataDir } from '@/shared/config/home.mjs'
10
+
11
+ export default defineApiHandler(async (event) => {
12
+ requireAdmin(event)
13
+ const backupDir = resolve(ensureDataDir(), 'backups')
14
+ let entries: Array<{ name: string, kind: 'db' | 'files', bytes: number, mtime: string }> = []
15
+ try {
16
+ entries = readdirSync(backupDir, { withFileTypes: true }).flatMap((e) => {
17
+ const full = resolve(backupDir, e.name)
18
+ try {
19
+ const st = statSync(full)
20
+ return [{
21
+ name: e.name,
22
+ kind: (e.isDirectory() ? 'files' : 'db') as 'db' | 'files',
23
+ bytes: st.size,
24
+ mtime: st.mtime.toISOString(),
25
+ }]
26
+ }
27
+ catch { return [] }
28
+ }).sort((a, b) => b.mtime.localeCompare(a.mtime))
29
+ }
30
+ catch { /* 备份目录尚不存在 = 还没备过 */ }
31
+ return { backupDir, count: entries.length, entries: entries.slice(0, 200) }
32
+ })
@@ -0,0 +1,21 @@
1
+ /**
2
+ * POST /api/system/backup/run —— 手动触发一次全量备份(admin)。
3
+ * 复用 server/plugins/backup.ts 的 backupOnce(三库在线快照 + JSON/配置面 + 保留轮转),
4
+ * 成败均落 audit_log(system.backup.*)。
5
+ */
6
+ import { defineApiHandler } from '../../../utils/response'
7
+ import { requireAdmin } from '../../workshop/caller'
8
+ import { AppError } from '../../../utils/errors'
9
+
10
+ export default defineApiHandler(async (event) => {
11
+ requireAdmin(event)
12
+ const { backupOnce } = await import('../../../plugins/backup')
13
+ const { ensureDataDir } = await import('@/shared/config/home.mjs')
14
+ try {
15
+ await backupOnce(ensureDataDir())
16
+ }
17
+ catch (err) {
18
+ throw new AppError(500, 'BACKUP_FAILED', `备份失败: ${err instanceof Error ? err.message : String(err)}`)
19
+ }
20
+ return { ok: true, at: new Date().toISOString() }
21
+ })
@@ -10,13 +10,23 @@ import { readBody } from 'h3'
10
10
  import { defineApiHandler } from '../../../utils/response'
11
11
  import { requireRole } from '../../workshop/caller'
12
12
  import { getSystemConfigService } from '../../../services/system-config'
13
+ import { recordOps } from '../../../services/workshop/ops/ops'
13
14
 
14
15
  export default defineApiHandler(async (event) => {
15
- requireRole(event, ['admin'])
16
+ const user = requireRole(event, ['admin'])
16
17
  const body = (await readBody<Record<string, unknown>>(event)) ?? {}
17
18
  const overrides = body.override ?? body.overrides ?? body
18
19
  if (!overrides || typeof overrides !== 'object' || Array.isArray(overrides)) {
19
20
  return { ok: false, message: '请求体应为 { "override": { key: value } }' }
20
21
  }
21
- return { ok: true, ...getSystemConfigService().patch(overrides as Record<string, unknown>) }
22
+ const res = getSystemConfigService().patch(overrides as Record<string, unknown>)
23
+ // 高危管理面留痕:改了哪些键(值不落审计——可能含凭据),谁改的
24
+ if (res.changed?.length) {
25
+ recordOps({
26
+ actor: user.id, actorName: user.name, actorKind: 'user',
27
+ action: 'system.settings.update', kind: 'system',
28
+ summary: `运行时设置变更:${res.changed.join(', ')}`,
29
+ })
30
+ }
31
+ return { ok: true, ...res }
22
32
  })
@@ -5,8 +5,17 @@
5
5
  import { defineApiHandler } from '../../../utils/response'
6
6
  import { requireRole } from '../../workshop/caller'
7
7
  import { getSystemConfigService } from '../../../services/system-config'
8
+ import { recordOps } from '../../../services/workshop/ops/ops'
8
9
 
9
10
  export default defineApiHandler((event) => {
10
- requireRole(event, ['admin'])
11
- return { ok: true, ...getSystemConfigService().reset() }
11
+ const user = requireRole(event, ['admin'])
12
+ const res = getSystemConfigService().reset()
13
+ if (res.changed?.length) {
14
+ recordOps({
15
+ actor: user.id, actorName: user.name, actorKind: 'user',
16
+ action: 'system.settings.reset', kind: 'system',
17
+ summary: `清空运行时覆盖(${res.changed.length} 键回落 config.yml)`,
18
+ })
19
+ }
20
+ return { ok: true, ...res }
12
21
  })
@@ -2,10 +2,17 @@ import { getRouterParam } from 'h3'
2
2
  import { userService } from '../../services/user.service'
3
3
  import { defineApiHandler } from '../../utils/response'
4
4
  import { requireAdmin } from '../workshop/caller'
5
+ import { recordOps } from '../../services/workshop/ops/ops'
5
6
 
6
7
  /** DELETE /api/users/:id —— 删除用户(仅 admin) */
7
8
  export default defineApiHandler((event) => {
8
- requireAdmin(event)
9
+ const admin = requireAdmin(event)
9
10
  const id = getRouterParam(event, 'id') ?? ''
10
- return userService.remove(id)
11
+ const res = userService.remove(id)
12
+ recordOps({
13
+ actor: admin.id, actorName: admin.name, actorKind: 'user',
14
+ action: 'user.delete', kind: 'system', targetKind: 'user', targetId: id,
15
+ summary: `删除用户 ${id}`,
16
+ })
17
+ return res
11
18
  })
@@ -4,11 +4,18 @@ import { userService } from '../../services/user.service'
4
4
  import { defineApiHandler } from '../../utils/response'
5
5
  import { zValidator } from '../../utils/validate'
6
6
  import { requireAdmin } from '../workshop/caller'
7
+ import { recordOps } from '../../services/workshop/ops/ops'
7
8
 
8
9
  /** PUT /api/users/:id —— 更新用户(部分字段) */
9
10
  export default defineApiHandler(async (event) => {
10
- requireAdmin(event)
11
+ const admin = requireAdmin(event)
11
12
  const id = getRouterParam(event, 'id') ?? ''
12
13
  const body = await readValidatedBody(event, zValidator(userUpdateSchema)) as UserUpdate
13
- return userService.update(id, body)
14
+ const user = userService.update(id, body)
15
+ recordOps({
16
+ actor: admin.id, actorName: admin.name, actorKind: 'user',
17
+ action: 'user.update', kind: 'system', targetKind: 'user', targetId: id,
18
+ summary: `更新用户 ${id}(字段:${Object.keys(body).join(', ')})`,
19
+ })
20
+ return user
14
21
  })
@@ -4,10 +4,17 @@ import { userService } from '../../services/user.service'
4
4
  import { defineApiHandler } from '../../utils/response'
5
5
  import { zValidator } from '../../utils/validate'
6
6
  import { requireAdmin } from '../workshop/caller'
7
+ import { recordOps } from '../../services/workshop/ops/ops'
7
8
 
8
9
  /** POST /api/users —— 创建用户 */
9
10
  export default defineApiHandler(async (event) => {
10
- requireAdmin(event)
11
+ const admin = requireAdmin(event)
11
12
  const body = await readValidatedBody(event, zValidator(userCreateSchema)) as UserCreate
12
- return userService.create(body)
13
+ const user = userService.create(body)
14
+ recordOps({
15
+ actor: admin.id, actorName: admin.name, actorKind: 'user',
16
+ action: 'user.create', kind: 'system', targetKind: 'user', targetId: user.id,
17
+ summary: `创建用户 ${user.name}(${user.role})`,
18
+ })
19
+ return user
13
20
  })
@@ -1,11 +1,11 @@
1
- import { readValidatedBody } from 'h3'
1
+ import { getRequestIP, readValidatedBody } from 'h3'
2
2
  import { userLoginSchema, type UserLogin } from '../../schemas/user.schema'
3
3
  import { userService } from '../../services/user.service'
4
4
  import { defineApiHandler } from '../../utils/response'
5
5
  import { zValidator } from '../../utils/validate'
6
6
 
7
- /** POST /api/users/login —— 公开登录(email + password),签发新会话 token */
7
+ /** POST /api/users/login —— 公开登录(email + password),签发新会话 token;带 IP 供防爆破锁定 */
8
8
  export default defineApiHandler(async (event) => {
9
9
  const body = await readValidatedBody(event, zValidator(userLoginSchema)) as UserLogin
10
- return userService.login(body)
10
+ return userService.login(body, { ip: getRequestIP(event, { xForwardedFor: true }) ?? '' })
11
11
  })