agentworkshop 0.8.5 → 0.8.6

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 (349) hide show
  1. package/.AgentWorkShop/prompts/host-tools.en.json +3 -3
  2. package/.AgentWorkShop/prompts/host-tools.json +14 -4
  3. package/.output/.AgentWorkShop/prompts/host-tools.en.json +3 -3
  4. package/.output/.AgentWorkShop/prompts/host-tools.json +14 -4
  5. package/.output/nitro.json +1 -1
  6. package/.output/public/_nuxt/{U_n8pryv2.js → 7op-BMk82.js} +1 -1
  7. package/.output/public/_nuxt/{zWZ26UWi.js → B1SIgyrl.js} +1 -1
  8. package/.output/public/_nuxt/{C4tXwpSt.js → BA2lmfW4.js} +1 -1
  9. package/.output/public/_nuxt/{EJkmXP432.js → BDXQqSkl2.js} +1 -1
  10. package/.output/public/_nuxt/{CY_7u1ST2.js → BI9jj13f2.js} +1 -1
  11. package/.output/public/_nuxt/{CGf9neEK2.js → BiXqyYNw2.js} +1 -1
  12. package/.output/public/_nuxt/{D9GoOkyP2.js → BlOm8JIs2.js} +1 -1
  13. package/.output/public/_nuxt/{CQ31GiJU2.js → BoXKUOiN2.js} +1 -1
  14. package/.output/public/_nuxt/{DZzbCFY2.js → BuLoPmcf.js} +1 -1
  15. package/.output/public/_nuxt/{D9ppMCbw.js → BwOK42JQ.js} +1 -1
  16. package/.output/public/_nuxt/{CZJ5cw6r2.js → C1RMfPoB2.js} +1 -1
  17. package/.output/public/_nuxt/{CGviZq4E.js → COfo_Bg3.js} +1 -1
  18. package/.output/public/_nuxt/CTGJHZ8X2.js +1 -0
  19. package/.output/public/_nuxt/{SgsmmrsZ.js → CY2NkFvI.js} +1 -1
  20. package/.output/public/_nuxt/{B4GOTVfN.js → C_4mzQ5X.js} +1 -1
  21. package/.output/public/_nuxt/{DGmFHb7m.js → CdvMP3lv.js} +1 -1
  22. package/.output/public/_nuxt/{iqxZGXsY.js → CooauJ7D.js} +1 -1
  23. package/.output/public/_nuxt/{C3vxePED.js → D1eVi1zr.js} +1 -1
  24. package/.output/public/_nuxt/{DnuJ66Jy.js → D6PUmBb0.js} +1 -1
  25. package/.output/public/_nuxt/{BBhroEeN.js → DC8sMA36.js} +1 -1
  26. package/.output/public/_nuxt/{DOUuGOQR2.js → DDHh85c42.js} +1 -1
  27. package/.output/public/_nuxt/{Cy_HDgSl.js → DDXOfmo2.js} +2 -2
  28. package/.output/public/_nuxt/{Cr2xJ_CY.js → DMFwLxfu.js} +1 -1
  29. package/.output/public/_nuxt/{BZg_MIK42.js → DoprKJ5a2.js} +1 -1
  30. package/.output/public/_nuxt/{BzBBEE-o2.js → Dr1FVeQG2.js} +1 -1
  31. package/.output/public/_nuxt/{W0sNnJQh.js → DtnsTW7e.js} +1 -1
  32. package/.output/public/_nuxt/{gUYi1hLJ2.js → DxDqd6T42.js} +1 -1
  33. package/.output/public/_nuxt/{B0UUODeh.js → DzU3zEKX.js} +1 -1
  34. package/.output/public/_nuxt/{BkO5WdX5.js → EgO70wrE.js} +1 -1
  35. package/.output/public/_nuxt/{7OZQiw002.js → HJKu4eEV2.js} +1 -1
  36. package/.output/public/_nuxt/{ChF6qLpY2.js → K5Xen0wZ2.js} +1 -1
  37. package/.output/public/_nuxt/{CNrRZmSx2.js → Rb4o4o-82.js} +1 -1
  38. package/.output/public/_nuxt/{BqBTlfiz.js → Tf6SJSDj.js} +1 -1
  39. package/.output/public/_nuxt/{DJaGVY4v2.js → ZzOyoXex2.js} +1 -1
  40. package/.output/public/_nuxt/{PbzVdCTA2.js → azOGy_tU2.js} +1 -1
  41. package/.output/public/_nuxt/{D1thFC3z.js → be-4wyTo.js} +1 -1
  42. package/.output/public/_nuxt/builds/latest.json +1 -1
  43. package/.output/public/_nuxt/builds/meta/593b65bd-cf1d-4b7f-a993-57e939c38f36.json +1 -0
  44. package/.output/public/_nuxt/{8b9CKi6F.js → dcjPjLPI.js} +1 -1
  45. package/.output/public/_nuxt/{ae2-5ZPt.js → h-Fn7pRD.js} +1 -1
  46. package/.output/public/_nuxt/{-gy9k_TE2.js → hyLdZsOd2.js} +1 -1
  47. package/.output/public/_nuxt/{BHxG41IQ2.js → o8sYG6xx2.js} +1 -1
  48. package/.output/server/chunks/_/access.mjs +1 -1
  49. package/.output/server/chunks/_/agent-dto.mjs +26 -0
  50. package/.output/server/chunks/_/agent-dto.mjs.map +1 -0
  51. package/.output/server/chunks/_/data-export.mjs +6 -6
  52. package/.output/server/chunks/_/data-query.mjs +3 -3
  53. package/.output/server/chunks/_/eda-run.repo.mjs +2 -2
  54. package/.output/server/chunks/_/features.mjs +5 -5
  55. package/.output/server/chunks/_/golden.mjs +3 -3
  56. package/.output/server/chunks/_/harness-spawn-policy.mjs +77 -0
  57. package/.output/server/chunks/_/harness-spawn-policy.mjs.map +1 -0
  58. package/.output/server/chunks/_/index.mjs +1 -1
  59. package/.output/server/chunks/_/line-scope.mjs +32 -0
  60. package/.output/server/chunks/_/line-scope.mjs.map +1 -0
  61. package/.output/server/chunks/_/mes-console.mjs +1 -1
  62. package/.output/server/chunks/_/nitro.mjs +2429 -1726
  63. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  64. package/.output/server/chunks/_/ocap.mjs +1 -1
  65. package/.output/server/chunks/_/rest-auth.mjs +1 -1
  66. package/.output/server/chunks/_/spc.mjs +1 -1
  67. package/.output/server/chunks/build/TownView-BWMDbosY.mjs +1 -1
  68. package/.output/server/chunks/build/daq-CdxcfY_G.mjs +1 -1
  69. package/.output/server/chunks/build/dcw-BlDQtS4q.mjs +1 -1
  70. package/.output/server/chunks/build/types-D6J7slEa.mjs +1 -1
  71. package/.output/server/chunks/build/useDaqAddNode-D_Rkju0f.mjs +1 -1
  72. package/.output/server/chunks/build/useDaqDetailNode-DeOsDxK5.mjs +1 -1
  73. package/.output/server/chunks/build/useDaqDetailParams-Cm9a9r5G.mjs +1 -1
  74. package/.output/server/chunks/build/useDaqFilters-CctmO03p.mjs +1 -1
  75. package/.output/server/chunks/build/useDaqStream-B9ZBVQrI.mjs +1 -1
  76. package/.output/server/chunks/build/useDaqTemplates-CK37sMfi.mjs +1 -1
  77. package/.output/server/chunks/build/useDcwAddNode-DACVcEHs.mjs +1 -1
  78. package/.output/server/chunks/build/useDcwStream-Dir5ufAU.mjs +1 -1
  79. package/.output/server/chunks/routes/api/mcp/workshop.mjs +1 -1
  80. package/.output/server/chunks/routes/api/system/backup/run.post.mjs +2 -2
  81. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +17 -9
  82. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  83. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs +3 -0
  84. package/.output/server/chunks/routes/api/workshop/agents/_id_.patch.mjs.map +1 -1
  85. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  86. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs +6 -0
  87. package/.output/server/chunks/routes/api/workshop/channel-templates/_id_.patch.mjs.map +1 -1
  88. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs +5 -0
  89. package/.output/server/chunks/routes/api/workshop/channels/_id/agents/_agentId_.patch.mjs.map +1 -1
  90. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs +5 -2
  91. package/.output/server/chunks/routes/api/workshop/channels/_id/index.get.mjs.map +1 -1
  92. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +7 -1
  93. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs.map +1 -1
  94. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +3 -1
  95. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs.map +1 -1
  96. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +8 -6
  97. package/.output/server/chunks/routes/api/workshop/channels.post.mjs.map +1 -1
  98. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs +29 -49
  99. package/.output/server/chunks/routes/api/workshop/daq/_id/ingest.post.mjs.map +1 -1
  100. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  101. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +6 -1
  102. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs.map +1 -1
  103. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs +4 -2
  104. package/.output/server/chunks/routes/api/workshop/daq/alarms.get.mjs.map +1 -1
  105. package/.output/server/chunks/routes/api/workshop/daq/index2.post.mjs +1 -1
  106. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +14 -5
  107. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs.map +1 -1
  108. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  109. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  110. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  111. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +7 -4
  112. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs.map +1 -1
  113. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  114. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  115. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +6 -2
  116. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs.map +1 -1
  117. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +6 -2
  118. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  120. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  121. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  122. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +6 -1
  123. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs.map +1 -1
  124. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  125. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +7 -4
  126. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs.map +1 -1
  127. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  128. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  129. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +6 -2
  131. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  133. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +7 -4
  134. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  135. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  137. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +6 -2
  139. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  141. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  142. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  143. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  144. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  145. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs +6 -2
  146. package/.output/server/chunks/routes/api/workshop/dcw/mes-artifacts/file.get.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workshop/dcw/mes-hook-test.post.mjs +1 -1
  148. package/.output/server/chunks/routes/api/workshop/dcw/mes-test-read.post.mjs +1 -1
  149. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  150. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  151. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +6 -2
  152. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs.map +1 -1
  153. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +4 -2
  154. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs.map +1 -1
  155. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +5 -2
  156. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -1
  157. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  159. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs +7 -3
  165. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/versions.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +8 -1
  167. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +6 -2
  169. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs.map +1 -1
  170. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  173. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  174. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +7 -4
  175. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs.map +1 -1
  176. package/.output/server/chunks/routes/api/workshop/eda/commonality.get.mjs +1 -1
  177. package/.output/server/chunks/routes/api/workshop/eda/vm/predict.post.mjs +1 -1
  178. package/.output/server/chunks/routes/api/workshop/exp/confirmations/_id/decide.post.mjs +1 -1
  179. package/.output/server/chunks/routes/api/workshop/exp/index.get.mjs +1 -1
  180. package/.output/server/chunks/routes/api/workshop/fs/dirs.get.mjs +1 -1
  181. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  184. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  185. package/.output/server/chunks/routes/api/workshop/index.mjs +1 -1
  186. package/.output/server/chunks/routes/api/workshop/index.post.mjs +2 -0
  187. package/.output/server/chunks/routes/api/workshop/index.post.mjs.map +1 -1
  188. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +8 -3
  190. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  191. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/index7.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/mes/datasets.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/autofix.mjs +1 -1
  197. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/compile.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/evidence.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/publish.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval-decision.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/approval.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/rules/_ruleId/transition.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/subgraph.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId/validate.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/ontology/drafts/_draftId_.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/ontology/export/_ontologyId_.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/ontology/index.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/ontology/scene.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/ontology/traces/_ontologyId_.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId/compare.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/ontology/versions/_ontologyId_.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/optimization/capabilities.get.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/optimization/index.get.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/optimization/index.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/optimization/index2.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/optimization/profiles/_id/publish.post.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/crosscheck.post.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/optimization/recommendations/_id/dispatch.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/optimization/solve.post.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/process-model/index.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/process-model/specs/_id/publish.post.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/process-model/train.post.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/tools/sync.post.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  231. package/.output/server/chunks/routes/renderer.mjs +2 -2
  232. package/.output/server/chunks/virtual/entry.mjs +1 -1
  233. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  234. package/.output/server/package.json +1 -1
  235. package/README-zh.md +4 -2
  236. package/README.md +9 -2
  237. package/config.yml +1 -1
  238. package/docker-compose.yml +4 -2
  239. package/docs/cli.en.md +2 -2
  240. package/docs/cli.md +2 -2
  241. package/docs/plugins.en.md +1 -1
  242. package/docs/plugins.md +1 -1
  243. package/docs/sdk.en.md +1 -1
  244. package/docs/sdk.md +1 -1
  245. package/package.json +1 -1
  246. package/scripts/_audit/_live-mqtt-e2e-20261028.mjs +219 -0
  247. package/scripts/_audit/prompt-injection-probe.mts +76 -0
  248. package/scripts/api-live-e2e.mjs +9 -3
  249. package/scripts/e2e-multiexpert-remediation-real.mjs +453 -0
  250. package/scripts/e2e-node-binding-3mode-real.mjs +697 -0
  251. package/scripts/e2e-node-binding-authz.mjs +332 -0
  252. package/scripts/security-acceptance.mjs +218 -0
  253. package/server/api/workshop/agent-tools/bindings/index.post.ts +33 -17
  254. package/server/api/workshop/agents/[id].patch.ts +3 -0
  255. package/server/api/workshop/agents/index.post.ts +3 -0
  256. package/server/api/workshop/channel-templates/[id].patch.ts +5 -0
  257. package/server/api/workshop/channel-templates/index.post.ts +6 -0
  258. package/server/api/workshop/channels/[id]/agents/[agentId].patch.ts +5 -0
  259. package/server/api/workshop/channels/[id]/agents/index.get.ts +8 -2
  260. package/server/api/workshop/channels/[id]/agents/index.post.ts +7 -0
  261. package/server/api/workshop/channels/[id]/index.get.ts +10 -4
  262. package/server/api/workshop/channels.post.ts +3 -0
  263. package/server/api/workshop/daq/[id]/ingest.post.ts +26 -22
  264. package/server/api/workshop/daq/[id].patch.ts +8 -0
  265. package/server/api/workshop/daq/alarms.get.ts +18 -16
  266. package/server/api/workshop/daq/infra/reconnect.post.ts +21 -5
  267. package/server/api/workshop/daq/test-driver.post.ts +10 -3
  268. package/server/api/workshop/dcw/[id]/param-ledger.get.ts +7 -1
  269. package/server/api/workshop/dcw/[id]/read.post.ts +6 -1
  270. package/server/api/workshop/dcw/[id].patch.ts +49 -40
  271. package/server/api/workshop/dcw/journal/index.get.ts +7 -3
  272. package/server/api/workshop/dcw/mes-artifacts/file.get.ts +7 -1
  273. package/server/api/workshop/dcw/mes-artifacts/index.get.ts +7 -1
  274. package/server/api/workshop/dcw/optimizations/[id]/series.get.ts +6 -1
  275. package/server/api/workshop/dcw/optimizations/[id].get.ts +3 -1
  276. package/server/api/workshop/dcw/optimizations/index.get.ts +6 -3
  277. package/server/api/workshop/dcw/params/[id]/read.post.ts +22 -17
  278. package/server/api/workshop/dcw/recipes/[id]/versions.get.ts +20 -14
  279. package/server/api/workshop/dcw/recipes/[id].delete.ts +33 -25
  280. package/server/api/workshop/dcw/recipes/index.get.ts +17 -12
  281. package/server/api/workshop/dcw/runs/[id]/close.post.ts +21 -15
  282. package/server/api/workshop/dcw/test-driver.post.ts +21 -16
  283. package/server/api/workshop/ws/hub.ts +2 -1
  284. package/server/plugins/01-instance-guard.ts +82 -0
  285. package/server/plugins/daq.ts +40 -8
  286. package/server/plugins/workshop.ts +12 -0
  287. package/server/services/workshop/agents/adapters/line-spawn.ts +24 -1
  288. package/server/services/workshop/agents/agent-dto.ts +54 -0
  289. package/server/services/workshop/agents/harness-spawn-policy.ts +114 -0
  290. package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +22 -0
  291. package/server/services/workshop/agents/host-tool-bridge/index.ts +1 -1
  292. package/server/services/workshop/agents/host-tool-bridge/per-agent.ts +17 -3
  293. package/server/services/workshop/agents/host-tool-bridge/tools/tasks.ts +1 -1
  294. package/server/services/workshop/agents/host-tool-bridge/tools/team-delegation.ts +5 -1
  295. package/server/services/workshop/agents/industrial/dcw-tools.ts +6 -2
  296. package/server/services/workshop/agents/industrial/ops-tools.ts +54 -12
  297. package/server/services/workshop/agents/industrial/recipe-gate.ts +68 -15
  298. package/server/services/workshop/agents/industrial/tool-verify-legacy-specs.ts +2 -2
  299. package/server/services/workshop/agents/industrial/tool-verify.ts +31 -2
  300. package/server/services/workshop/agents/node-bindings.repo.ts +4 -3
  301. package/server/services/workshop/agents/node-delegation.ts +49 -4
  302. package/server/services/workshop/agents/tool-approvals.ts +23 -0
  303. package/server/services/workshop/agents/tool-reference-spec.ts +3 -0
  304. package/server/services/workshop/daq/bus/mqtt.adapter.ts +12 -0
  305. package/server/services/workshop/daq/daq-controller/crud.ts +5 -3
  306. package/server/services/workshop/daq/daq-controller/ingest.ts +23 -0
  307. package/server/services/workshop/daq/daq-controller/push.ts +24 -3
  308. package/server/services/workshop/daq/daq-controller/runtime-control.ts +6 -0
  309. package/server/services/workshop/daq/daq-controller/sweep-alarms.ts +3 -1
  310. package/server/services/workshop/daq/daq-controller/tsdb-twin.ts +21 -1
  311. package/server/services/workshop/daq/daq-node.repo.ts +10 -7
  312. package/server/services/workshop/daq/daq-node.ts +2 -0
  313. package/server/services/workshop/daq/daq-runtime.ts +10 -2
  314. package/server/services/workshop/daq/drivers/modbus-tcp.ts +8 -5
  315. package/server/services/workshop/daq/drivers/registry.ts +5 -4
  316. package/server/services/workshop/daq/infra.ts +13 -0
  317. package/server/services/workshop/daq/ingest-policy.ts +24 -1
  318. package/server/services/workshop/daq/storage/timescale.adapter.ts +42 -3
  319. package/server/services/workshop/db/database/migrations.ts +83 -68
  320. package/server/services/workshop/dcw/dcw-controller/crud.ts +27 -2
  321. package/server/services/workshop/dcw/dcw-controller/lines.ts +14 -3
  322. package/server/services/workshop/dcw/dcw-controller/recipes.ts +63 -5
  323. package/server/services/workshop/dcw/dcw-recipe.repo.ts +10 -1
  324. package/server/services/workshop/dcw/dcw-runtime.ts +37 -14
  325. package/server/services/workshop/dcw/drivers/shared.ts +62 -6
  326. package/server/services/workshop/dcw/recipe-op-anchor.ts +28 -0
  327. package/server/services/workshop/dcw/recipe-rollback-manager/rollback.ts +204 -190
  328. package/server/services/workshop/dcw/recipe-rollback-manager/sweep.ts +97 -77
  329. package/server/services/workshop/line-scope.ts +80 -0
  330. package/server/services/workshop/optimization/dispatch.service.ts +18 -2
  331. package/server/services/workshop/permissions.ts +2 -0
  332. package/server/services/workshop/runtime/agent-runtime/message.ts +17 -0
  333. package/server/services/workshop/runtime/agent-runtime/state.ts +9 -3
  334. package/server/services/workshop/runtime/agent-runtime/types.ts +2 -1
  335. package/server/services/workshop/runtime/channel-runtime.ts +3 -1
  336. package/server/services/workshop/runtime/mailbox.ts +6 -3
  337. package/server/services/workshop/runtime/manager/a2a.ts +4 -2
  338. package/server/services/workshop/runtime/manager/admin-channel.ts +1 -1
  339. package/server/services/workshop/runtime/manager/chat.ts +3 -1
  340. package/server/services/workshop/runtime/manager/host-tools.ts +1 -1
  341. package/server/services/workshop/runtime/manager/runtime-wiring.ts +31 -19
  342. package/server/services/workshop/runtime/manager/state.ts +43 -1
  343. package/server/services/workshop/runtime/permission-scope.ts +21 -0
  344. package/server/services/workshop/runtime/scheduler-loop/tick.ts +16 -4
  345. package/server/services/workshop/scene-events.ts +19 -0
  346. package/shared/daq-protocol.ts +24 -5
  347. package/shared/dcw-protocol/catalog.ts +4 -4
  348. package/.output/public/_nuxt/CCI-fwcS2.js +0 -1
  349. package/.output/public/_nuxt/builds/meta/5cd11284-05bf-4fcd-9a69-56a01c9f56dd.json +0 -1
@@ -0,0 +1,453 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 多专家审查整改 · 真实场景验收(2026-10-28)。
4
+ *
5
+ * 真实平台(.output 生产构建)+ 真实 omp 子进程 + 本机 LM Studio Qwen3.5-9B(32k),
6
+ * 单频道、**worker 身份执行**(lead 只存在不派活):
7
+ * R1 AgentChannel 创建(lead + worker 成员)
8
+ * R2 worker 绑定节点(DAQ 观察 + DCW 点位写授权)落库
9
+ * R3 运行时提示词注入:节点语义卡(名称/量程/单步/手动确认)+ 执行模式卡
10
+ * R4 工具注入面按绑定面差异化(recipe_trial 描述含该 worker 的 dcw 节点)
11
+ * R5 任务 COMPLETED(omp + Qwen3.5),工具链 my_industrial_nodes → daq_query → recipe_trial
12
+ * R6 手动模式 HITL:审批卡挂起 → 人工批准 → ACK 设备证实
13
+ * R7 效果:节点值变更、trial 不改配方版本、journal 锚点新增、TSDB 有真实样本
14
+ *
15
+ * 运行:node scripts/e2e-multiexpert-remediation-real.mjs
16
+ * 证据:docs/audit/evidence/2026-10-28-multiexpert-remediation/report.json
17
+ */
18
+ import { spawn, spawnSync } from 'node:child_process'
19
+ import { existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
20
+ import { dirname, join, resolve } from 'node:path'
21
+ import { fileURLToPath } from 'node:url'
22
+ import { DatabaseSync } from 'node:sqlite'
23
+
24
+ const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..')
25
+ const HOME = process.env.AW_ACCEPT_HOME ?? 'D:/tmp/aw-multiexpert-20261028'
26
+ const PORT = Number(process.env.AW_ACCEPT_PORT ?? 3411)
27
+ const BASE = `http://127.0.0.1:${PORT}`
28
+ const MODEL = { provider: 'lm-studio', model: 'qwen3.5-9b-32k', contextTokens: 32768 }
29
+ const EVIDENCE_DIR = join(REPO, 'docs', 'audit', 'evidence', '2026-10-28-multiexpert-remediation')
30
+ const results = []
31
+ const sleep = ms => new Promise(r => setTimeout(r, ms))
32
+ const ok = (id, name, cond, detail = '') => {
33
+ results.push({ id, name, pass: Boolean(cond), detail: String(detail).slice(0, 1200) })
34
+ console.log(`${cond ? '✔' : '✖'} [${id}] ${name}${cond ? '' : ` — ${String(detail).slice(0, 800)}`}`)
35
+ return Boolean(cond)
36
+ }
37
+
38
+ function stopOwnedInstance() {
39
+ const pidFile = join(HOME, 'server.pid')
40
+ if (!existsSync(pidFile)) return
41
+ const pid = Number(readFileSync(pidFile, 'utf8').trim())
42
+ if (!Number.isInteger(pid) || pid <= 0) return
43
+ try {
44
+ spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { windowsHide: true })
45
+ }
46
+ catch { /* 已退出 */ }
47
+ }
48
+
49
+ async function health() {
50
+ try {
51
+ const r = await fetch(`${BASE}/api/health`, { signal: AbortSignal.timeout(2500) })
52
+ if (!r.ok) return null
53
+ return (await r.json())?.data ?? null
54
+ }
55
+ catch {
56
+ return null
57
+ }
58
+ }
59
+
60
+ async function startInstance() {
61
+ stopOwnedInstance()
62
+ await sleep(1500)
63
+ const running = await health()
64
+ if (running) throw new Error(`端口 ${PORT} 已被非本验收实例占用:${running.app} ${running.version}`)
65
+ if (process.env.AW_ACCEPT_RESET !== '0') {
66
+ if (!/aw-multiexpert/.test(HOME)) throw new Error(`拒绝清理非验收目录:${HOME}`)
67
+ rmSync(HOME, { recursive: true, force: true })
68
+ }
69
+ mkdirSync(HOME, { recursive: true })
70
+ const log = openSync(join(HOME, 'server.log'), 'a')
71
+ const child = spawn(process.execPath, [join(REPO, '.output', 'server', 'index.mjs')], {
72
+ cwd: REPO,
73
+ env: {
74
+ ...process.env,
75
+ AW_MODE: 'home',
76
+ AW_HOME: HOME,
77
+ PORT: String(PORT),
78
+ NUXT_SESSION_PASSWORD: 'multiexpert-20261028-session-key-abcdef',
79
+ AW_TRIAL_INTERVAL_MS: '0',
80
+ AW_RATE_LIMIT_OFF: '1',
81
+ NO_PROXY: '127.0.0.1,localhost',
82
+ },
83
+ detached: true,
84
+ stdio: ['ignore', log, log],
85
+ windowsHide: true,
86
+ })
87
+ child.unref()
88
+ writeFileSync(join(HOME, 'server.pid'), String(child.pid))
89
+ for (let i = 0; i < 120; i++) {
90
+ await sleep(1000)
91
+ const h = await health()
92
+ if (h?.workshop === 'ready') return h
93
+ }
94
+ throw new Error('隔离实例未在 120s 内就绪')
95
+ }
96
+
97
+ let admin = ''
98
+ async function api(method, path, body, token = admin, extraHeaders = {}, timeoutMs = 120_000) {
99
+ const res = await fetch(BASE + path, {
100
+ method,
101
+ headers: {
102
+ ...(body !== undefined ? { 'content-type': 'application/json' } : {}),
103
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
104
+ ...extraHeaders,
105
+ },
106
+ body: body === undefined ? undefined : JSON.stringify(body),
107
+ signal: AbortSignal.timeout(timeoutMs),
108
+ })
109
+ let json = null
110
+ try {
111
+ json = await res.json()
112
+ }
113
+ catch { /* 非 JSON */ }
114
+ return { status: res.status, ...json }
115
+ }
116
+
117
+ const dbPath = join(HOME, 'data', 'workshop.sqlite')
118
+ function agentTokenOf(agentId) {
119
+ const db = new DatabaseSync(dbPath, { readOnly: true })
120
+ try {
121
+ return String(db.prepare('SELECT token FROM channel_agents WHERE id = ?').get(agentId)?.token ?? '')
122
+ }
123
+ finally {
124
+ db.close()
125
+ }
126
+ }
127
+
128
+ async function pendingOf(agentId) {
129
+ const r = await api('GET', `/api/workshop/agent-tools/approvals?agentId=${encodeURIComponent(agentId)}`)
130
+ return (r?.data?.approvals ?? []).filter(a => a.status === 'pending')
131
+ }
132
+
133
+ async function approvalsHistory(agentId) {
134
+ const r = await api('GET', `/api/workshop/agent-tools/approvals?agentId=${encodeURIComponent(agentId)}&scope=history`)
135
+ return r?.data?.approvals ?? []
136
+ }
137
+
138
+ async function approve(cardId, comment) {
139
+ return api('POST', `/api/workshop/agent-tools/approvals/${cardId}/decide`, { approved: true, comment })
140
+ }
141
+
142
+ function taskOf(r) {
143
+ return r?.data?.task ?? r?.data ?? null
144
+ }
145
+
146
+ function deliverableOf(task) {
147
+ const art = (task?.artifacts ?? []).find(a => a.name === 'deliverable')
148
+ return String(art?.parts?.map(p => p.text ?? '').join('\n') ?? '')
149
+ }
150
+
151
+ function toolCallsOf(task) {
152
+ return (task?.history ?? [])
153
+ .map(h => String(h?.parts?.map(p => p.text ?? '').join(' ') ?? ''))
154
+ .filter(t => t.includes('🔧'))
155
+ .map(t => t.replace(/\s+/g, ' ').slice(0, 300))
156
+ }
157
+
158
+ async function waitTask(taskId, { timeoutMs = 15 * 60_000, autoApprove = false, onCard = null } = {}) {
159
+ const started = Date.now()
160
+ const cards = []
161
+ let lastState = ''
162
+ while (Date.now() - started < timeoutMs) {
163
+ const r = await api('GET', `/api/workshop/tasks/${taskId}`)
164
+ const task = taskOf(r)
165
+ const state = String(task?.state ?? '')
166
+ if (state !== lastState) {
167
+ lastState = state
168
+ console.log(` · task ${taskId.slice(0, 8)} state=${state}`)
169
+ }
170
+ if (autoApprove && task?.assigneeId) {
171
+ const pending = await pendingOf(String(task.assigneeId))
172
+ for (const card of pending) {
173
+ if (cards.some(c => c.id === card.id)) continue
174
+ cards.push(card)
175
+ if (onCard) onCard(card)
176
+ }
177
+ }
178
+ if (['COMPLETED', 'FAILED', 'CANCELED', 'CANCELLED'].includes(state)) return { task, cards, timedOut: false }
179
+ await sleep(3000)
180
+ }
181
+ const r = await api('GET', `/api/workshop/tasks/${taskId}`)
182
+ return { task: taskOf(r), cards, timedOut: true }
183
+ }
184
+
185
+ async function submitTask(channelId, title, description, assigneeId) {
186
+ const r = await api('POST', `/api/workshop/channels/${channelId}/tasks`, { title, description, assigneeId })
187
+ const task = taskOf(r)
188
+ if (!task?.id) throw new Error(`任务创建失败: ${JSON.stringify(r).slice(0, 400)}`)
189
+ return task
190
+ }
191
+
192
+ const scenarioLine = (name, controlMode, description) =>
193
+ api('POST', '/api/workshop/dcw/lines', { name, simulated: true, controlMode, description }).then(r => r.data.line)
194
+
195
+ const makeDaq = async attrs => (await api('POST', '/api/workshop/daq', {
196
+ driver: 'mock', intervalMs: 1000, enabled: true, publishIntervalMs: 0, ...attrs,
197
+ })).data.node
198
+
199
+ const makeDcw = async attrs => (await api('POST', '/api/workshop/dcw', {
200
+ driver: 'mock', enabled: true, holdIntervalMs: 0, readIntervalMs: 0, writeLockSeconds: 0, stepLimit: 5, ...attrs,
201
+ })).data.node
202
+
203
+ async function remapParam(lineId, nodeId, key, desc) {
204
+ const params = (await api('GET', `/api/workshop/dcw/params?lineId=${lineId}`)).data.params ?? []
205
+ const pm = params.find(p => p.nodeId === nodeId)
206
+ if (!pm) throw new Error(`参数映射不存在: node=${nodeId}`)
207
+ await api('PATCH', `/api/workshop/dcw/params/${pm.id}`, { key, desc, min: 0, max: 100 })
208
+ }
209
+
210
+ /** 注:本函数创建 lead;worker 另经 /agents 路由加入(worker 才是本轮的作业身份) */
211
+ async function makeChannel(name, lineId, scenarioPrompt, mode, toolNames) {
212
+ const ch = (await api('POST', '/api/workshop/channels', {
213
+ name,
214
+ lineId,
215
+ scenarioPrompt,
216
+ leadAgent: { name: `${name}-线长`, harness: 'omp', config: { rpcMode: 'rpc', args: ['--no-tools'] } },
217
+ })).data
218
+ const channelId = ch?.channelId
219
+ if (!channelId) throw new Error(`频道创建失败: ${JSON.stringify(ch).slice(0, 300)}`)
220
+ await api('PATCH', `/api/workshop/channels/${channelId}`, { llm: { provider: MODEL.provider, model: MODEL.model } })
221
+ await api('PATCH', `/api/workshop/channels/${channelId}/execution-mode`, mode === 'auto' ? { mode: 'auto', confirm: true } : { mode })
222
+ const put = await api('PUT', `/api/workshop/channels/${channelId}/tools`, {
223
+ mode: 'selected',
224
+ tools: toolNames.map(n => ({ name: n, enabled: true })),
225
+ })
226
+ const agents = (await api('GET', `/api/workshop/channels/${channelId}`))?.data?.agents ?? []
227
+ const lead = agents.find(a => a.role === 'lead')
228
+ return { channelId, lead, toolsSaved: put.status, agents }
229
+ }
230
+
231
+ async function addWorker(channelId, name) {
232
+ const r = await api('POST', `/api/workshop/channels/${channelId}/agents`, {
233
+ name,
234
+ harness: 'omp',
235
+ role: 'worker',
236
+ config: { rpcMode: 'rpc', args: ['--no-tools'] },
237
+ })
238
+ const worker = r?.data?.agent ?? r?.data
239
+ if (!worker?.id) throw new Error(`worker 创建失败: ${JSON.stringify(r).slice(0, 400)}`)
240
+ return worker
241
+ }
242
+
243
+ async function bindNode(agentId, nodeId, kind, mode = 'manual') {
244
+ const created = await api('POST', '/api/workshop/agent-tools/bindings', { agentId, nodeId, kind, mode })
245
+ const b = created?.data?.binding
246
+ if (!b) throw new Error(`绑定失败: ${JSON.stringify(created).slice(0, 300)}`)
247
+ if (mode === 'auto' && b.mode !== 'auto') {
248
+ const patched = await api('PATCH', `/api/workshop/agent-tools/bindings/${b.id}`, { mode: 'auto', confirm: true })
249
+ return patched?.data?.binding ?? b
250
+ }
251
+ return b
252
+ }
253
+
254
+ /** 提示词注入探针:同一 AW_HOME 的只读 sidecar,调用运行时同一个 buildIndustrialContext */
255
+ function promptProbe(agentId) {
256
+ const r = spawnSync(process.execPath, [
257
+ join(REPO, 'node_modules', 'tsx', 'dist', 'cli.mjs'),
258
+ '--tsconfig', '.nuxt/tsconfig.server.json',
259
+ join(REPO, 'scripts', '_audit', 'prompt-injection-probe.mts'),
260
+ agentId,
261
+ ], {
262
+ cwd: REPO,
263
+ env: { ...process.env, AW_MODE: 'home', AW_HOME: HOME, AW_SKIP_DATA_LOCK: '1' },
264
+ encoding: 'utf8',
265
+ timeout: 120_000,
266
+ windowsHide: true,
267
+ })
268
+ if (r.status !== 0) throw new Error(`prompt probe 失败(${r.status}): ${String(r.stderr ?? '').slice(0, 800)}`)
269
+ return JSON.parse(String(r.stdout))
270
+ }
271
+
272
+ const WORK_PROMPT = lineId => [
273
+ '你是工艺闭环的作业员(worker)。严格按四步执行,不要做别的:',
274
+ '1) 调用 my_industrial_nodes 查看你绑定的数控节点(id/量程/单步);',
275
+ '2) 调用 daq_query:line_id="' + lineId + '",last_minutes=5,bucket_ms=15000,limit=200,记录温度均值与样本数;',
276
+ '3) 调用 recipe_trial:line_id="' + lineId + '",params 只包含你绑定的那个数控节点,value=56,hypothesis 写「基于数采集证据把温度设定由 60 调到 56,验证窗口内响应」;审批由人工处理,工具会返回结果,你不需要等待;',
277
+ '4) 调用 complete_task 提交:daq_query 的样本数与均值、recipe_trial 的完整回执原文与批次 id。',
278
+ '本任务只做这四步:禁止复测、禁止等待/睡眠、禁止 recipe_update/rollback、禁止使用 bash/终端。',
279
+ ].join('\n')
280
+
281
+ const TOOLS = ['my_industrial_nodes', 'daq_query', 'recipe_trial', 'recipe_rollback', 'complete_task', 'report_progress']
282
+
283
+ const evidence = {
284
+ at: new Date().toISOString(),
285
+ env: {
286
+ base: BASE,
287
+ home: HOME,
288
+ version: '',
289
+ model: MODEL,
290
+ harness: 'omp(真实子进程)',
291
+ devices: 'mock(daq+dcw;无物理响应耦合)',
292
+ note: '真实平台 .output + 真实 omp + 本机 LM Studio Qwen3.5-9B(32k);作业身份 = worker',
293
+ },
294
+ scenario: {},
295
+ prompt: {},
296
+ task: {},
297
+ assertions: results,
298
+ }
299
+
300
+ try {
301
+ const h = await startInstance()
302
+ evidence.env.version = String(h?.version ?? '')
303
+ ok('R1', '生产构建隔离实例就绪(workshop ready)', h?.workshop === 'ready', `port=${PORT} version=${h?.version}`)
304
+
305
+ const reg = await api('POST', '/api/users/register', { name: '验收管理员', email: `accept-${Date.now()}@awshop.local`, password: 'Accept#2026' })
306
+ admin = reg?.data?.token
307
+ ok('R1b', 'admin 注册/登录', Boolean(admin), `status=${reg.status}`)
308
+ writeFileSync(join(HOME, 'admin.json'), JSON.stringify({ token: admin }))
309
+
310
+ // ── 产线:DAQ 测温 + DCW 温度设定 + 产品/配方 + 开跑 ──
311
+ const line = await scenarioLine('验收-整改-产线', 'auto', '多专家整改验收线:温度监测 + 点位写授权(模拟设备)')
312
+ const daqTemp = await makeDaq({
313
+ name: '腔体温度', templateRef: 'temp-tc', lineId: line.id, unit: 'C', decimals: 2, min: 0, max: 100,
314
+ semantics: '腔体温度测点;正常工艺窗口 50~70C',
315
+ })
316
+ const dcwSp = await makeDcw({
317
+ name: '温度设定', templateRef: 'temp-sp', lineId: line.id, unit: 'C', decimals: 2, min: 0, max: 100,
318
+ driverConfig: { key: 'accept-mx-temp-sp' }, semantics: '腔体温度设定点;单步 <=4C,窗口 50~70C',
319
+ })
320
+ await remapParam(line.id, dcwSp.id, 'temp_sp', '腔体温度设定值(C)')
321
+ const product = (await api('POST', '/api/workshop/dcw/products', {
322
+ name: '验收产品', lineId: line.id, description: '温度窗口 50~70C',
323
+ paramLimits: { temp_sp: { min: 50, max: 70 } },
324
+ })).data.product
325
+ const recipe = (await api('POST', '/api/workshop/dcw/recipes', {
326
+ name: '验收配方', productId: product.id, description: '验收配方;温度设定 50~70C,单步 4C',
327
+ opIntervalMs: 0,
328
+ params: [{ nodeId: dcwSp.id, value: 60, min: 50, max: 70, stepLimit: 4 }],
329
+ daqWindows: [{ nodeId: daqTemp.id, min: 50, max: 70 }],
330
+ })).data.recipe
331
+ const start = await api('POST', `/api/workshop/dcw/lines/${line.id}/start`, { recipeId: recipe.id })
332
+ ok('R1c', '产线开跑(活动批次建立,配方整批下发)', start.status === 200, `status=${start.status} line=${line.id} recipe=${recipe.id}`)
333
+ // 采集总控必须显式启动(否则节点不采样,daq_query 无数据)
334
+ const daqStart = await api('POST', '/api/workshop/daq/controller', { action: 'start' })
335
+ ok('R1d', '数采网关启动(controller action=start)', daqStart.status === 200, `status=${daqStart.status}`)
336
+ await sleep(12_000)
337
+
338
+ // ── AgentChannel:lead + worker ──
339
+ const ch = await makeChannel('验收-整改-频道', line.id, '作业频道:worker 绑定节点后按任务四步执行;手动模式所有下发需人工批准。', 'manual', TOOLS)
340
+ const channelId = ch.channelId
341
+ const worker = await addWorker(channelId, '验收-整改-作业员')
342
+ ok('R2', 'AgentChannel 创建成功(lead + worker 成员)', Boolean(ch.lead?.id && worker.id),
343
+ JSON.stringify({ channelId, lead: ch.lead?.id, worker: worker.id, toolsSaved: ch.toolsSaved }))
344
+
345
+ // ── worker 绑定节点:DAQ(观察,auto)+ DCW(点位写授权,manual) ──
346
+ const bDaq = await bindNode(worker.id, daqTemp.id, 'daq', 'auto')
347
+ const bDcw = await bindNode(worker.id, dcwSp.id, 'dcw', 'manual')
348
+ ok('R2b', 'worker 节点绑定落库(daq=auto / dcw=manual)',
349
+ bDaq.mode === 'auto' && bDcw.mode === 'manual' && bDaq.nodeId === daqTemp.id && bDcw.nodeId === dcwSp.id,
350
+ JSON.stringify({ daq: { id: bDaq.id, mode: bDaq.mode }, dcw: { id: bDcw.id, mode: bDcw.mode } }))
351
+ evidence.scenario = {
352
+ line: line.id, recipe: recipe.id, product: product.id,
353
+ daq: daqTemp.id, dcw: dcwSp.id, channel: channelId,
354
+ lead: ch.lead?.id, worker: worker.id,
355
+ bindings: { daq: bDaq.id, dcw: bDcw.id },
356
+ }
357
+
358
+ // ── R3 运行时提示词注入(运行时同一个 buildIndustrialContext / nodeSemanticCards) ──
359
+ const probe = promptProbe(worker.id)
360
+ const cardsText = String(probe.cards ?? '')
361
+ evidence.prompt = {
362
+ channelId: probe.channelId,
363
+ profileMode: probe.profileMode,
364
+ text: String(probe.text ?? '').slice(0, 8000),
365
+ cards: cardsText.slice(0, 8000),
366
+ stale: probe.stale,
367
+ error: probe.error,
368
+ }
369
+ ok('R3', '运行时提示词注入:执行模式卡(manual)+ 绑定节点语义卡(名称/量程/单步/手动确认)',
370
+ probe.profileMode === 'manual'
371
+ && cardsText.includes('频道执行模式:manual')
372
+ && cardsText.includes('温度设定') && cardsText.includes(dcwSp.id)
373
+ && cardsText.includes('安全量程') && cardsText.includes('单步') && cardsText.includes('手动确认模式')
374
+ && cardsText.includes('腔体温度') && cardsText.includes(daqTemp.id),
375
+ cardsText.slice(0, 600))
376
+
377
+ // ── R4 工具注入面按绑定面差异化 ──
378
+ const tok = agentTokenOf(worker.id)
379
+ const list = await api('GET', `/api/workshop/agent-tools/list?agentId=${encodeURIComponent(worker.id)}`, undefined, undefined, { 'x-aw-agent-token': tok })
380
+ const trialDesc = String((list?.data?.tools ?? []).find(t => t.name === 'recipe_trial')?.description ?? '')
381
+ ok('R4', '工具注入面携带该 worker 的绑定节点(recipe_trial 描述含 dcw id)',
382
+ trialDesc.includes(dcwSp.id), trialDesc.slice(-260))
383
+
384
+ // ── R5 worker 真实 omp 回合 ──
385
+ const task = await submitTask(channelId, '验收-整改-worker作业', WORK_PROMPT(line.id), worker.id)
386
+ const t0 = Date.now()
387
+ const run = await waitTask(task.id, {
388
+ timeoutMs: 18 * 60_000,
389
+ autoApprove: true,
390
+ onCard: (card) => {
391
+ console.log(` · HITL card ${card.id} 出现,自动批准`)
392
+ void approve(card.id, '验收:批准基于数采集证据的温度试验(→56C)').then(r => console.log(` · approve status=${r.status}`))
393
+ },
394
+ })
395
+ const elapsed = Math.round((Date.now() - t0) / 1000)
396
+ const deliverable = deliverableOf(run.task)
397
+ const calls = toolCallsOf(run.task)
398
+ evidence.task = {
399
+ id: task.id, state: run.task?.state, elapsedSec: elapsed, assignee: run.task?.assigneeId,
400
+ deliverable, toolCalls: calls,
401
+ cards: run.cards.map(c => ({ id: c.id, detail: String(c.detail ?? '').slice(0, 600) })),
402
+ }
403
+ ok('R5', 'worker 任务 COMPLETED(omp + Qwen3.5)', run.task?.state === 'COMPLETED', `state=${run.task?.state} elapsed=${elapsed}s`)
404
+ const completedExplicitly = calls.some(c => c.includes('complete_task'))
405
+ evidence.task.completedExplicitly = completedExplicitly
406
+ ok('R5b', '工具链覆盖 my_industrial_nodes/daq_query/recipe_trial(闭环结论见交付物)',
407
+ calls.some(c => c.includes('my_industrial_nodes')) && calls.some(c => c.includes('daq_query'))
408
+ && calls.some(c => c.includes('recipe_trial'))
409
+ && /recipe_trial/i.test(deliverable) && /样本数|均值/.test(deliverable),
410
+ `complete_task=${completedExplicitly}(false=平台按交付物隐式收口) | ${calls.join(' || ').slice(0, 700)}`)
411
+
412
+ // ── R6 HITL + ACK ──
413
+ const history = await approvalsHistory(worker.id)
414
+ const approved = history.filter(a => String(a.status ?? a.decision ?? '') === 'approved' || a.approved === true || a.decision === 'approved')
415
+ ok('R6', '手动模式挂起人工审批并获批(HITL)', run.cards.length >= 1 && (approved.length >= 1 || history.length >= 1),
416
+ JSON.stringify({ cards: run.cards.length, history: history.length, approved: approved.length }))
417
+ ok('R6b', '审批卡展示依据(hypothesis/理由)', run.cards.some(c => /hypothesis|依据|56/.test(String(c.detail ?? ''))),
418
+ run.cards.map(c => String(c.detail ?? '').slice(0, 200)).join(' | '))
419
+ ok('R6c', '下发获得设备证实(交付物含 ACK/证实)', /ACK|证实|verified/i.test(deliverable), deliverable.slice(0, 500))
420
+
421
+ // ── R7 效果核验 ──
422
+ const nodes = (await api('GET', `/api/workshop/dcw?lineId=${line.id}`))?.data?.nodes ?? []
423
+ const node = nodes.find(n => n.id === dcwSp.id)
424
+ ok('R7', '节点实际值变更为 56(设备侧生效)', Number(node?.value) === 56, `value=${node?.value} state=${node?.state}`)
425
+ const recipes = (await api('GET', `/api/workshop/dcw/recipes/${recipe.id}`))?.data
426
+ const recipeVersion = Number(recipes?.recipe?.version ?? recipes?.version ?? 1)
427
+ ok('R7b', 'trial 不写配方版本(版本仍为 1)', recipeVersion === 1, `version=${recipeVersion}`)
428
+ const journal = (await api('GET', `/api/workshop/dcw/journal?lineId=${line.id}&limit=500`))?.data?.anchors ?? []
429
+ ok('R7c', '账本新增写入锚点(可审计)', journal.length >= 2, `anchors=${journal.length}`)
430
+ // 数采链路:经权威查询端点(REST)取该测点最近 10 分钟的原始桶
431
+ const dq = await api('GET', `/api/workshop/daq/query?node_ids=${encodeURIComponent(daqTemp.id)}&last_minutes=10&bucket_ms=15000&limit=200`)
432
+ const series = dq?.data?.series ?? dq?.series ?? []
433
+ const pts = series.flatMap(s => s.points ?? s.data ?? [])
434
+ ok('R7d', 'TSDB 有该测点真实样本(数采链路入库,daq 查询端点可读)', dq.status === 200 && pts.length > 0,
435
+ `status=${dq.status} points=${pts.length} sample=${JSON.stringify(pts[0] ?? null).slice(0, 160)}`)
436
+ evidence.scenario.final = { nodeValue: node?.value, recipeVersion, journal: journal.length, dpsPoints: pts.length }
437
+ }
438
+ catch (err) {
439
+ ok('R0', '验收执行未抛异常', false, err instanceof Error ? `${err.message}\n${err.stack ?? ''}` : String(err))
440
+ }
441
+ finally {
442
+ const pass = results.filter(r => r.pass).length
443
+ const fail = results.length - pass
444
+ evidence.summary = { total: results.length, pass, fail }
445
+ mkdirSync(EVIDENCE_DIR, { recursive: true })
446
+ writeFileSync(join(EVIDENCE_DIR, 'report.json'), `${JSON.stringify(evidence, null, 2)}\n`)
447
+ writeFileSync(join(EVIDENCE_DIR, 'prompt-injection.json'), `${JSON.stringify(evidence.prompt, null, 2)}\n`)
448
+ writeFileSync(join(EVIDENCE_DIR, 'task.json'), `${JSON.stringify(evidence.task, null, 2)}\n`)
449
+ console.log(`\n=== ${pass}/${results.length} PASS, ${fail} FAIL ===`)
450
+ console.log(`证据:${EVIDENCE_DIR}`)
451
+ stopOwnedInstance()
452
+ if (fail > 0) process.exitCode = 1
453
+ }