agentworkshop 0.7.38 → 0.7.40

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 (392) hide show
  1. package/.AgentWorkShop/prompts/aml-mission-default.md +20 -20
  2. package/.AgentWorkShop/prompts/aml-playbook.md +49 -49
  3. package/.AgentWorkShop/prompts/host-tools.json +1293 -1238
  4. package/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -10
  5. package/.output/.AgentWorkShop/prompts/aml-mission-default.md +20 -20
  6. package/.output/.AgentWorkShop/prompts/aml-playbook.md +49 -49
  7. package/.output/.AgentWorkShop/prompts/host-tools.json +1293 -1238
  8. package/.output/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -10
  9. package/.output/nitro.json +1 -1
  10. package/.output/public/_nuxt/88GOowgO2.js +1 -0
  11. package/.output/public/_nuxt/{BNT8gYU92.js → BC9wjTJK2.js} +2 -2
  12. package/.output/public/_nuxt/BOt2SP4z.js +1 -0
  13. package/.output/public/_nuxt/BP-NyKVG.js +18 -0
  14. package/.output/public/_nuxt/{HBLJ-wei.js → BXxH0UQE.js} +1 -1
  15. package/.output/public/_nuxt/{zIGh7R49.js → BneN7fbu.js} +1 -1
  16. package/.output/public/_nuxt/BsROmY89.js +1 -0
  17. package/.output/public/_nuxt/{C_OLzD09.js → C4oW1HsE.js} +1 -1
  18. package/.output/public/_nuxt/CFxtLwjp.js +1 -0
  19. package/.output/public/_nuxt/{Cec0Ua3F.js → CS50LB_l.js} +1 -1
  20. package/.output/public/_nuxt/C_iYD-EB.js +1 -0
  21. package/.output/public/_nuxt/{DAe0h2MB.js → ClILjvWH.js} +1 -1
  22. package/.output/public/_nuxt/CssgYAAL2.js +1 -0
  23. package/.output/public/_nuxt/{CY9LbPCI.js → CzOCSGLe.js} +1 -1
  24. package/.output/public/_nuxt/D8qvkfyY.js +1 -0
  25. package/.output/public/_nuxt/DCn7QZ5N.js +2 -0
  26. package/.output/public/_nuxt/DGIuvyRN2.js +1 -0
  27. package/.output/public/_nuxt/{CojCTLKD.js → DGj-WEBg.js} +1 -1
  28. package/.output/public/_nuxt/{DDShH71m.js → DS8qj8EL.js} +1 -1
  29. package/.output/public/_nuxt/DTFCy6h-.js +1 -0
  30. package/.output/public/_nuxt/{DrYV5i68.js → DUjW5Yq5.js} +1 -1
  31. package/.output/public/_nuxt/DZshyNLa.js +1 -0
  32. package/.output/public/_nuxt/{45zuyAso.js → D_OTvQza.js} +1 -1
  33. package/.output/public/_nuxt/DcsCcxp4.js +1 -0
  34. package/.output/public/_nuxt/{DUrecWPx.js → Dihnimlk.js} +2 -2
  35. package/.output/public/_nuxt/Dqw1lpr-.js +1 -0
  36. package/.output/public/_nuxt/{BG8sCcwx.js → Dr9v6C0f.js} +9 -9
  37. package/.output/public/_nuxt/{8NMOXZOV.js → Du9ZJtnj.js} +1 -1
  38. package/.output/public/_nuxt/TownView.f-YOdXRs.css +1 -0
  39. package/.output/public/_nuxt/_id_.CM4bIgKY.css +1 -0
  40. package/.output/public/_nuxt/_id_.bNV69Dtf.css +1 -0
  41. package/.output/public/_nuxt/_wsId_.B4WiqkIS.css +1 -0
  42. package/.output/public/_nuxt/agents.ZD0rVdHE.css +1 -0
  43. package/.output/public/_nuxt/aml.BN8ZEW4h.css +1 -0
  44. package/.output/public/_nuxt/builds/latest.json +1 -1
  45. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +1 -0
  46. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +1 -0
  47. package/.output/public/_nuxt/daq.B0D3dPAc.css +1 -0
  48. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +1 -0
  49. package/.output/public/_nuxt/default.J32SgqFY.css +1 -0
  50. package/.output/public/_nuxt/entry.bdm0tv6M.css +1 -0
  51. package/.output/public/_nuxt/logs.BpKzmKsh.css +1 -0
  52. package/.output/public/_nuxt/monitor.D9pe7qN6.css +1 -0
  53. package/.output/public/_nuxt/pages.D7aSDlUI.css +1 -0
  54. package/.output/public/_nuxt/permissions.DwTVlFe6.css +1 -0
  55. package/.output/public/_nuxt/plugins.sb4nDGqr.css +1 -0
  56. package/.output/public/_nuxt/{Cbq-mryP.js → qr6R6Ha1.js} +1 -1
  57. package/.output/public/_nuxt/settings.BTgR-NiE.css +1 -0
  58. package/.output/public/_nuxt/teams.CxnxKVVs.css +1 -0
  59. package/.output/public/_nuxt/tokens.BFY7qv4f.css +1 -0
  60. package/.output/public/_nuxt/{town.DKIAhKnx.css → town.BBXZmeoP.css} +1 -1
  61. package/.output/public/_nuxt/users.DLgZ1D0h.css +1 -0
  62. package/.output/public/_nuxt/workshop.CR_QzeAN.css +1 -0
  63. package/.output/public/_nuxt/{BzHEilTt.js → xh3_vYcu.js} +1 -1
  64. package/.output/public/_nuxt/yF0aYMF1.js +4 -0
  65. package/.output/server/chunks/_/entity.mjs.map +1 -1
  66. package/.output/server/chunks/_/nitro.mjs +2244 -1464
  67. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  68. package/.output/server/chunks/build/{TownView-jVazYOjN.mjs → TownView-BuLAsmpR.mjs} +288 -206
  69. package/.output/server/chunks/build/TownView-BuLAsmpR.mjs.map +1 -0
  70. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs → _id_-BU1wfOID.mjs} +138 -138
  71. package/.output/server/chunks/build/{_id_-CfVosNg3.mjs.map → _id_-BU1wfOID.mjs.map} +1 -1
  72. package/.output/server/chunks/build/{_id_-Hwr4rZpr.mjs → _id_-BYsEua57.mjs} +33 -32
  73. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +1 -0
  74. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs → _wsId_-BxlDcJHg.mjs} +293 -259
  75. package/.output/server/chunks/build/{_wsId_-BVg3bB77.mjs.map → _wsId_-BxlDcJHg.mjs.map} +1 -1
  76. package/.output/server/chunks/build/{agents-Bvin73QY.mjs → agents-CLQqJF2y.mjs} +21 -27
  77. package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +1 -0
  78. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs → aml-_7FdFL2p.mjs} +109 -109
  79. package/.output/server/chunks/build/{aml-BCSJCdX7.mjs.map → aml-_7FdFL2p.mjs.map} +1 -1
  80. package/.output/server/chunks/build/api-error-dul30BYQ.mjs.map +1 -1
  81. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs → channel-templates-p6SZNjlM.mjs} +19 -19
  82. package/.output/server/chunks/build/{channel-templates-BTq8570n.mjs.map → channel-templates-p6SZNjlM.mjs.map} +1 -1
  83. package/.output/server/chunks/build/{daq-C03Uu5UE.mjs → daq-cgyjKmJu.mjs} +188 -122
  84. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +1 -0
  85. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs → dcw-CoTxBlAZ.mjs} +45 -45
  86. package/.output/server/chunks/build/{dcw-6vEYVeje.mjs.map → dcw-CoTxBlAZ.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{default-hseyOqBT.mjs → default-BE4r0FZN.mjs} +158 -79
  88. package/.output/server/chunks/build/{default-hseyOqBT.mjs.map → default-BE4r0FZN.mjs.map} +1 -1
  89. package/.output/server/chunks/build/{logs-B-xhuqln.mjs → logs-BSOeZwwI.mjs} +34 -34
  90. package/.output/server/chunks/build/{logs-B-xhuqln.mjs.map → logs-BSOeZwwI.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs → monitor-C0okQaXz.mjs} +33 -33
  92. package/.output/server/chunks/build/{monitor-CyfDt4nR.mjs.map → monitor-C0okQaXz.mjs.map} +1 -1
  93. package/.output/server/chunks/build/{pages-BO7yZsXA.mjs → pages-DFxjn9Xa.mjs} +33 -17
  94. package/.output/server/chunks/build/pages-DFxjn9Xa.mjs.map +1 -0
  95. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs → permissions-68SsNjex.mjs} +12 -12
  96. package/.output/server/chunks/build/{permissions-B52oOmaO.mjs.map → permissions-68SsNjex.mjs.map} +1 -1
  97. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs → plugins-lGlUr1lj.mjs} +17 -17
  98. package/.output/server/chunks/build/{plugins-CUWmMdyt.mjs.map → plugins-lGlUr1lj.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{settings-DoQ2Oq3P.mjs → settings-Ddd1qx2Z.mjs} +50 -47
  100. package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +1 -0
  101. package/.output/server/chunks/build/{teams-2kz3CusY.mjs → teams-MEDLZdMn.mjs} +38 -34
  102. package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +1 -0
  103. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs → tokens-C7fTM5C2.mjs} +14 -14
  104. package/.output/server/chunks/build/{tokens-BbWLqtVz.mjs.map → tokens-C7fTM5C2.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{town-BOl6hs9B.mjs → town-qMPql9Se.mjs} +36 -10
  106. package/.output/server/chunks/build/town-qMPql9Se.mjs.map +1 -0
  107. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs +1 -1
  108. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs +1 -1
  109. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs +49 -0
  110. package/.output/server/chunks/build/useResponsive-BKDMGTHs.mjs.map +1 -0
  111. package/.output/server/chunks/build/{users-fohSmF-J.mjs → users-Cfd5-l2-.mjs} +6 -6
  112. package/.output/server/chunks/build/{users-fohSmF-J.mjs.map → users-Cfd5-l2-.mjs.map} +1 -1
  113. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs → workshop-BL5bhfs0.mjs} +15 -15
  114. package/.output/server/chunks/build/{workshop-DX5-ldc4.mjs.map → workshop-BL5bhfs0.mjs.map} +1 -1
  115. package/.output/server/chunks/build/{workspaces-BuydxM-3.mjs → workspaces-Bgz5Ekwp.mjs} +18 -3
  116. package/.output/server/chunks/build/workspaces-Bgz5Ekwp.mjs.map +1 -0
  117. package/.output/server/chunks/routes/api/system/config-groups/_id_.patch.mjs.map +1 -1
  118. package/.output/server/chunks/routes/api/system/index.patch.mjs.map +1 -1
  119. package/.output/server/chunks/routes/api/system/index.post.mjs.map +1 -1
  120. package/.output/server/chunks/routes/api/system/settings/events.get.mjs.map +1 -1
  121. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +6 -2
  122. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  123. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +2 -1
  124. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
  125. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  126. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  127. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs.map +1 -1
  128. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs.map +1 -1
  129. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs.map +1 -1
  130. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +3 -2
  131. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +2 -1
  133. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs.map +1 -1
  134. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +8 -6
  135. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs.map +1 -1
  136. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +5 -5
  137. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +14 -4
  139. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +4 -4
  141. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs.map +1 -1
  142. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +4 -3
  143. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +31 -0
  145. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs.map +1 -0
  146. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs +28 -0
  147. package/.output/server/chunks/routes/api/workshop/dcw/index6.get.mjs.map +1 -0
  148. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.patch.mjs.map +1 -1
  149. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs +32 -0
  150. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/read.post.mjs.map +1 -0
  151. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs +34 -0
  152. package/.output/server/chunks/routes/api/workshop/dcw/params/_id/write.post.mjs.map +1 -0
  153. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +33 -0
  154. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs.map +1 -0
  155. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +34 -0
  156. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs.map +1 -0
  157. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  158. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  159. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  160. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  161. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  162. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  163. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +2 -0
  165. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/workshop/index9.get.mjs +3 -1
  167. package/.output/server/chunks/routes/api/workshop/index9.get.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  169. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  170. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  171. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  172. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  173. package/.output/server/chunks/routes/renderer.mjs +3 -3
  174. package/.output/server/chunks/virtual/entry.mjs +53 -25
  175. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  176. package/.output/server/package.json +1 -1
  177. package/README-zh.md +204 -40
  178. package/README.md +739 -591
  179. package/app/app.vue +9 -3
  180. package/app/assets/css/main.css +517 -7
  181. package/app/components/AppHeader.vue +98 -24
  182. package/app/components/AppSidebar.vue +118 -11
  183. package/app/components/AwChart.vue +2 -1
  184. package/app/components/workshop/AgentInspectorDrawer.vue +6 -6
  185. package/app/components/workshop/AgentLanesView.vue +52 -1
  186. package/app/components/workshop/AssetLibrary.vue +4 -2
  187. package/app/components/workshop/ChannelSessionList.vue +4 -2
  188. package/app/components/workshop/Composer.vue +96 -0
  189. package/app/components/workshop/DaqNodeRow.vue +19 -0
  190. package/app/components/workshop/DaqTemplateIcon.vue +33 -0
  191. package/app/components/workshop/DeviceTwinPanel.vue +37 -35
  192. package/app/components/workshop/EventBlock.vue +3 -3
  193. package/app/components/workshop/InspectorPanel.vue +47 -11
  194. package/app/components/workshop/LiveAgentBar.vue +34 -0
  195. package/app/components/workshop/TaskBoardView.vue +83 -33
  196. package/app/components/workshop/TranscriptTimeline.vue +56 -0
  197. package/app/components/workshop/blocks/ClusterError.vue +1 -1
  198. package/app/components/workshop/blocks/ClusterRoute.vue +3 -1
  199. package/app/components/workshop/blocks/ClusterStatus.vue +2 -2
  200. package/app/components/workshop/blocks/ClusterStream.vue +8 -2
  201. package/app/components/workshop/town/ModelPreview3D.vue +1 -1
  202. package/app/components/workshop/town/TownView.vue +507 -82
  203. package/app/composables/useResponsive.ts +88 -0
  204. package/app/composables/useRouteMeta.ts +3 -0
  205. package/app/composables/workshop/useDcwStream.ts +1 -1
  206. package/app/composables/workshop/useVisibleInterval.ts +2 -2
  207. package/app/composables/workshop/useWorkshopApi.ts +1 -1
  208. package/app/layouts/default.vue +46 -2
  209. package/app/pages/aml/index.vue +712 -616
  210. package/app/pages/daq/[id].vue +3 -2
  211. package/app/pages/daq/index.vue +209 -9
  212. package/app/pages/dcw/[id].vue +109 -28
  213. package/app/pages/dcw/index.vue +83 -23
  214. package/app/pages/index.vue +35 -1
  215. package/app/pages/logs/index.vue +147 -13
  216. package/app/pages/monitor.vue +56 -12
  217. package/app/pages/permissions/index.vue +34 -0
  218. package/app/pages/plugins/index.vue +35 -4
  219. package/app/pages/settings.vue +90 -21
  220. package/app/pages/tokens.vue +23 -0
  221. package/app/pages/town.vue +50 -5
  222. package/app/pages/users.vue +23 -0
  223. package/app/pages/workshop/agents.vue +92 -2
  224. package/app/pages/workshop/channel-templates.vue +53 -0
  225. package/app/pages/workshop/index.vue +14 -0
  226. package/app/pages/workshop/teams.vue +66 -6
  227. package/app/pages/workshop/w/[wsId].vue +202 -14
  228. package/app/plugins/aw-plugins.client.ts +13 -8
  229. package/app/stores/app.ts +33 -1
  230. package/app/stores/workshop/user.ts +1 -1
  231. package/app/stores/workshop/workspaces.ts +18 -2
  232. package/app/utils/api-error.ts +1 -1
  233. package/cli/commands/build.mjs +8 -1
  234. package/docker-compose.yml +6 -0
  235. package/docs/full-test-plan.md +4 -0
  236. package/docs/plugins.en.md +1 -0
  237. package/docs/plugins.md +1 -0
  238. package/i18n/locales/en.ts +3 -0
  239. package/i18n/locales/zh-CN.ts +3 -0
  240. package/nuxt.config.ts +31 -0
  241. package/package.json +9 -1
  242. package/scripts/_audit/detached-start.mjs +103 -0
  243. package/scripts/_audit/guard-upstream-liveness.mjs +104 -0
  244. package/scripts/_dbg-param-map-e2e.ts +242 -0
  245. package/scripts/_dbg-param-map-rest-smoke.mjs +73 -0
  246. package/scripts/_dbg-param-real-scenario.mjs +153 -0
  247. package/scripts/_dbg-perms-e2e.mjs +10 -3
  248. package/scripts/_dbg-protocol-matrix.mjs +453 -441
  249. package/scripts/_dbg-render-regression.mjs +151 -130
  250. package/scripts/_dbg-town-agents-probe.mjs +60 -0
  251. package/scripts/_dbg-visual-acceptance.mjs +63 -0
  252. package/scripts/api-live-e2e.mjs +40 -8
  253. package/scripts/capture-walkthrough.mjs +232 -0
  254. package/scripts/e2e-agent-team.mjs +5 -3
  255. package/scripts/render-walkthrough-figure.mjs +46 -0
  256. package/scripts/seed-walkthrough-fixture.mjs +143 -0
  257. package/scripts/test-plugin-hardening.mjs +8 -0
  258. package/scripts/three-system-e2e.mjs +6 -6
  259. package/scripts/ui/admin-shots.mjs +46 -0
  260. package/scripts/ui/audit-layout.mjs +301 -0
  261. package/scripts/ui/bump-microfont.mjs +39 -0
  262. package/scripts/ui/lib.mjs +198 -0
  263. package/scripts/ui/linkcheck2.mjs +37 -0
  264. package/scripts/ui/live-render-check.mjs +72 -0
  265. package/scripts/ui/md-lint.mjs +80 -0
  266. package/scripts/ui/perf-audit.mjs +132 -0
  267. package/scripts/ui/readme-assets.mjs +30 -0
  268. package/scripts/ui/readme-shots.mjs +42 -0
  269. package/scripts/ui/record.mjs +225 -0
  270. package/scripts/ui/seed-admin.mjs +68 -0
  271. package/scripts/ui/seed-demo.mjs +83 -0
  272. package/scripts/ui/shot-hero.mjs +25 -0
  273. package/scripts/ui/shots.mjs +75 -0
  274. package/scripts/ui/sim-ui-shot.mjs +16 -0
  275. package/scripts/ui/verify-nav.mjs +51 -0
  276. package/scripts/ui/verify-responsive.mjs +285 -0
  277. package/server/api/system/config-groups/[id].patch.ts +1 -1
  278. package/server/api/system/config-groups/index.post.ts +1 -1
  279. package/server/api/system/settings/events.get.ts +1 -1
  280. package/server/api/system/settings/index.patch.ts +1 -1
  281. package/server/api/workshop/agent-tools/invoke.post.ts +16 -2
  282. package/server/api/workshop/aml/datasets/[id].get.ts +8 -1
  283. package/server/api/workshop/daq/infra/reconnect.post.ts +1 -1
  284. package/server/api/workshop/daq/templates/[key].delete.ts +1 -0
  285. package/server/api/workshop/daq/templates/[key].patch.ts +1 -0
  286. package/server/api/workshop/daq/templates/index.post.ts +1 -0
  287. package/server/api/workshop/dcw/[id]/write.post.ts +10 -2
  288. package/server/api/workshop/dcw/[id].delete.ts +5 -2
  289. package/server/api/workshop/dcw/index.get.ts +2 -0
  290. package/server/api/workshop/dcw/lines/[id].patch.ts +1 -1
  291. package/server/api/workshop/dcw/params/[id]/read.post.ts +17 -0
  292. package/server/api/workshop/dcw/params/[id]/write.post.ts +21 -0
  293. package/server/api/workshop/dcw/params/[id].delete.ts +19 -0
  294. package/server/api/workshop/dcw/params/[id].patch.ts +23 -0
  295. package/server/api/workshop/dcw/params/index.get.ts +27 -0
  296. package/server/api/workshop/dcw/params/index.post.ts +25 -0
  297. package/server/api/workshop/permissions/index.get.ts +3 -1
  298. package/server/plugins/aw-plugins.ts +14 -3
  299. package/server/plugins/dev-stability-guard.ts +3 -1
  300. package/server/plugins/system-config.ts +6 -1
  301. package/server/plugins-builtin/rag-bridge/index.mjs +9 -2
  302. package/server/services/system-config.ts +28 -9
  303. package/server/services/workshop/agents/adapters/one-shot-cli-agent.ts +2 -1
  304. package/server/services/workshop/agents/agent-interface.ts +8 -6
  305. package/server/services/workshop/agents/base-agent.ts +18 -4
  306. package/server/services/workshop/agents/claude-agent.ts +7 -3
  307. package/server/services/workshop/agents/codex-agent.ts +3 -3
  308. package/server/services/workshop/agents/dsh-agent.ts +3 -3
  309. package/server/services/workshop/agents/goose-agent.ts +0 -1
  310. package/server/services/workshop/agents/harness-terminal.ts +14 -1
  311. package/server/services/workshop/agents/hermes-agent.ts +4 -2
  312. package/server/services/workshop/agents/host-tool-bridge.ts +5 -1
  313. package/server/services/workshop/agents/industrial-context.ts +4 -1
  314. package/server/services/workshop/agents/industrial-tools.ts +164 -6
  315. package/server/services/workshop/agents/omp-agent.ts +15 -9
  316. package/server/services/workshop/agents/opencode-agent.ts +47 -21
  317. package/server/services/workshop/agents/qwen-agent.ts +10 -5
  318. package/server/services/workshop/aml/entity.ts +3 -1
  319. package/server/services/workshop/aml/python-runtime.ts +3 -2
  320. package/server/services/workshop/daq/bus/mqtt.adapter.ts +8 -4
  321. package/server/services/workshop/daq/daq-controller.ts +18 -3
  322. package/server/services/workshop/daq/daq-runtime.ts +5 -3
  323. package/server/services/workshop/daq/drivers.ts +63 -8
  324. package/server/services/workshop/daq/host-ports.ts +3 -2
  325. package/server/services/workshop/daq/storage/timescale.adapter.ts +3 -1
  326. package/server/services/workshop/db/channel.repo.ts +4 -0
  327. package/server/services/workshop/db/ops.repo.ts +5 -2
  328. package/server/services/workshop/db/retention.ts +8 -3
  329. package/server/services/workshop/dcw/dcw-controller.ts +143 -16
  330. package/server/services/workshop/dcw/dcw-product.repo.ts +38 -1
  331. package/server/services/workshop/dcw/dcw-runtime.ts +3 -2
  332. package/server/services/workshop/dcw/drivers.ts +5 -2
  333. package/server/services/workshop/dcw/param-conversion.ts +78 -0
  334. package/server/services/workshop/dcw/param-limits.ts +142 -0
  335. package/server/services/workshop/dcw/param-map.repo.ts +305 -0
  336. package/server/services/workshop/dcw/recipe-rollback-manager.ts +13 -7
  337. package/server/services/workshop/runtime/agent-runtime.ts +4 -0
  338. package/server/services/workshop/runtime/manager.ts +9 -2
  339. package/server/services/workshop/settings.ts +4 -2
  340. package/server/types/pg.d.ts +49 -0
  341. package/server/utils/stability-severity.ts +13 -2
  342. package/shared/config/groups.mjs +22 -1
  343. package/shared/config/home.d.mts +28 -0
  344. package/shared/dcw-protocol.ts +136 -0
  345. package/uno.config.ts +12 -1
  346. package/.output/public/_nuxt/BFkgkW8u.js +0 -4
  347. package/.output/public/_nuxt/C5gUkRwn.js +0 -1
  348. package/.output/public/_nuxt/CM12FuB42.js +0 -1
  349. package/.output/public/_nuxt/CZiw7sEV.js +0 -1
  350. package/.output/public/_nuxt/Cc_9VzD42.js +0 -1
  351. package/.output/public/_nuxt/CdPzkOMV.js +0 -1
  352. package/.output/public/_nuxt/D1YDxZpZ.js +0 -1
  353. package/.output/public/_nuxt/D20Yamr4.js +0 -1
  354. package/.output/public/_nuxt/DVsjtsvZ2.js +0 -1
  355. package/.output/public/_nuxt/DmqknNvV.js +0 -18
  356. package/.output/public/_nuxt/DnUuIR83.js +0 -1
  357. package/.output/public/_nuxt/S_fVQwJK.js +0 -1
  358. package/.output/public/_nuxt/TownView.0oLiQgTC.css +0 -1
  359. package/.output/public/_nuxt/_id_.D-SYuyZb.css +0 -1
  360. package/.output/public/_nuxt/_id_.hma_BU6T.css +0 -1
  361. package/.output/public/_nuxt/_wsId_.B12v3PhY.css +0 -1
  362. package/.output/public/_nuxt/agents.BV70ioCv.css +0 -1
  363. package/.output/public/_nuxt/ahgEJu2R.js +0 -1
  364. package/.output/public/_nuxt/aml.COEKNNqK.css +0 -1
  365. package/.output/public/_nuxt/builds/meta/44b66249-54d0-4c8a-9057-9755a32329e2.json +0 -1
  366. package/.output/public/_nuxt/channel-templates.C-M5nKcC.css +0 -1
  367. package/.output/public/_nuxt/daq.B3265ZDn.css +0 -1
  368. package/.output/public/_nuxt/dcw.DLYZqEhT.css +0 -1
  369. package/.output/public/_nuxt/default.DE_vT238.css +0 -1
  370. package/.output/public/_nuxt/entry.BB-Eeh-J.css +0 -1
  371. package/.output/public/_nuxt/logs.CqFyMrJw.css +0 -1
  372. package/.output/public/_nuxt/monitor.B--1dPzs.css +0 -1
  373. package/.output/public/_nuxt/pages.ooEzrMm9.css +0 -1
  374. package/.output/public/_nuxt/permissions.B1pjGChZ.css +0 -1
  375. package/.output/public/_nuxt/plugins.5e5chZ67.css +0 -1
  376. package/.output/public/_nuxt/pz2JDAM7.js +0 -2
  377. package/.output/public/_nuxt/settings.Dm3M0RLy.css +0 -1
  378. package/.output/public/_nuxt/teams.BC75EGnR.css +0 -1
  379. package/.output/public/_nuxt/tokens.xRb1fSPU.css +0 -1
  380. package/.output/public/_nuxt/users.CXnP2E08.css +0 -1
  381. package/.output/public/_nuxt/workshop.Jk5HxWPE.css +0 -1
  382. package/.output/server/chunks/build/TownView-jVazYOjN.mjs.map +0 -1
  383. package/.output/server/chunks/build/_id_-Hwr4rZpr.mjs.map +0 -1
  384. package/.output/server/chunks/build/agents-Bvin73QY.mjs.map +0 -1
  385. package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +0 -1
  386. package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +0 -1
  387. package/.output/server/chunks/build/settings-DoQ2Oq3P.mjs.map +0 -1
  388. package/.output/server/chunks/build/teams-2kz3CusY.mjs.map +0 -1
  389. package/.output/server/chunks/build/town-BOl6hs9B.mjs.map +0 -1
  390. package/.output/server/chunks/build/workspaces-BuydxM-3.mjs.map +0 -1
  391. /package/.output/public/_nuxt/{36oeS8_R2.js → 36oeS8_R.js} +0 -0
  392. /package/.output/public/_nuxt/{CYWVXZTS.js → CYWVXZTS2.js} +0 -0
@@ -19,6 +19,9 @@ import { daqRuntimeSettings } from '../settings'
19
19
  import { getDaqNodeRepo } from '../daq/daq-node.repo'
20
20
  import { findDaqTemplate } from '../daq/daq-templates'
21
21
  import { getRecipeRollBackManager } from '../dcw/recipe-rollback-manager'
22
+ import { getDcwParamRepo } from '../dcw/param-map.repo'
23
+ import { limitsBreakdownOf } from '../dcw/param-limits'
24
+ import type { DcwParamView } from '../../../../shared/dcw-protocol'
22
25
  import { getOps, recordOps } from '../ops/ops'
23
26
  import { getDcwLineRepo } from '../dcw/dcw-line.repo'
24
27
  import { getDcwProductRepo } from '../dcw/dcw-product.repo'
@@ -75,7 +78,10 @@ export async function toolMyIndustrialNodes(agentId: string): Promise<{ text: st
75
78
  ---
76
79
  通用规则:
77
80
  1. 一个 Agent 可绑定多个节点;先读本清单理解每个节点的物理意义与操作守则,再动手。
78
- 2. 数控下发 dcw_control(node_id, value):目标值必须落在「安全量程 ∩ 活动配方工艺窗口」;单次调幅建议按语义卡的步进指引。下发前/后用 dcw_read(node_id) 读 PLC 当前值取证复核(被动观测免审批)。
81
+ 2. 数控下发优先用 param_control(param, value) 以**工艺参数**寻址(key 语义稳定,跨批次/换配方不变);
82
+ dcw_control(node_id, value) 为节点直接寻址的兼容面。设定值受四层限界联锁
83
+ (节点安全量程 ∩ 工艺参数基准限界 ∩ 活动产品限界 ∩ 活动配方工艺窗口)逐层收窄,
84
+ 越界一律拒绝 —— 用户与 Agent 一体约束,无旁路。下发前/后用 param_read(param) 读 PLC 当前值取证复核(被动观测免审批)。
79
85
  3. 数据获取 daq_query(不传 node_id = 全部数采节点),支持按产线/产品/配方/时间检索;解读数据时结合语义卡的判读方法。
80
86
  4. 改动设定后等待工艺响应(热惯性/传动惯量)再评估,避免连续大幅调整。
81
87
  5. 调控闭环:每次下发自动开一条优化记录(open);观察数采后用 dcw_judge 落判定(keep/rollback/uncertain);
@@ -130,11 +136,8 @@ export async function toolDcwControl(agentId: string, args: { node_id?: string,
130
136
  if (approvals.hasPendingFor(agentId, nodeId)) {
131
137
  return { text: `你对该节点已有一条待审批的下发指令,请等待用户处理后再发新指令(避免审批堆积)。`, isError: true }
132
138
  }
133
- const run = node.lineId ? getActiveLineRun(node.lineId) : null
134
- const recipe = run ? getDcwController().listRecipes().find(r => r.id === run.recipeId) : undefined
135
- const param = recipe?.params.find(p => p.nodeId === nodeId)
136
- const detail = `${node.name}(${tpl?.ch ?? node.templateKey})设定 ${value}${node.unit}`
137
- + (param && (param.min != null || param.max != null) ? `,配方窗口 ${param.min ?? '-∞'}~${param.max ?? '+∞'}${node.unit}` : `,安全量程 ${node.min}~${node.max}${node.unit}`)
139
+ const bd = limitsBreakdownOf(node)
140
+ const detail = `${node.name}(${tpl?.ch ?? node.templateKey})设定 ${value}${node.unit},有效写入区间 ${bd.effective.min}~${bd.effective.max}${node.unit}(${bd.layers.map(l => l.label).join(' ∩ ')})`
138
141
  const ap = await approvals.request(agentId, nodeId, 'dcw', detail)
139
142
  if (!ap.approved) {
140
143
  return { text: `指令未执行:用户${ap.comment.includes('超时') ? '未在时限内批准(超时)' : `拒绝了本次下发`}。用户备注:${ap.comment || '(无)'}` }
@@ -236,6 +239,161 @@ function writeToleranceOf(node: { decimals: number, min: number, max: number }):
236
239
  return Math.max(0.5 * 10 ** -node.decimals, (node.max - node.min) * 0.005)
237
240
  }
238
241
 
242
+ /** 工艺参数解析(param_control/param_read 共用):pp-id 优先,其次按 key;跨产线同名需 line_id 消歧 */
243
+ function resolveParamRef(ref: string, lineId?: string): { ok: true, param: DcwParamView } | { ok: false, text: string, isError: true } {
244
+ const repo = getDcwParamRepo()
245
+ const trimmed = String(ref ?? '').trim()
246
+ if (!trimmed) {
247
+ return { ok: false, text: 'param 必填:工艺参数 id(pp-*)或参数 key(见 my_industrial_nodes)。', isError: true }
248
+ }
249
+ const row = trimmed.startsWith('pp-') ? repo.byId(trimmed) : undefined
250
+ if (row) {
251
+ const view = repo.viewOf(row)
252
+ if (!view) return { ok: false, text: `工艺参数 ${trimmed} 的执行节点已不存在(映射悬空)。`, isError: true }
253
+ if (lineId && view.lineId !== lineId) {
254
+ return { ok: false, text: `工艺参数 ${view.key} 不属于产线 ${lineId}(实际归属:${view.lineId || '未分配'})。`, isError: true }
255
+ }
256
+ return { ok: true, param: view }
257
+ }
258
+ const hits = repo.byKey(trimmed)
259
+ .map(r => repo.viewOf(r))
260
+ .filter((v): v is DcwParamView => v != null)
261
+ const scoped = lineId ? hits.filter(v => v.lineId === lineId) : hits
262
+ if (scoped.length === 1) return { ok: true, param: scoped[0]! }
263
+ if (scoped.length === 0) {
264
+ const catalog = repo.listViews().slice(0, 12).map(v => `${v.key}(${v.name})`).join('、')
265
+ return { ok: false, text: `未找到工艺参数「${trimmed}」${lineId ? `(产线 ${lineId})` : ''}。可用参数:${catalog || '无 —— 请先让用户创建写控节点生成参数面'}。`, isError: true }
266
+ }
267
+ return { ok: false, text: `工艺参数「${trimmed}」命中 ${scoped.length} 条同名映射,请附加 line_id 消歧或改用参数 id(${scoped.map(v => v.id).join(' / ')})。`, isError: true }
268
+ }
269
+
270
+ /** 参数面权限摘要(工具回包统一口径;不透出寄存器等 PLC 寻址细节) */
271
+ function paramLimitsText(param: DcwParamView): string {
272
+ const node = getDcwController().byId(param.nodeId)
273
+ if (!node) return '执行节点已删除'
274
+ const bd = limitsBreakdownOf(node)
275
+ const layers = bd.layers.filter(l => l.min != null || l.max != null).map(l => l.label).join(' ∩ ')
276
+ return `有效写入区间 ${bd.effective.min}~${bd.effective.max}${param.unit}(约束层:${layers || '无'})`
277
+ }
278
+
279
+ /** 工具:param_control —— 按工艺参数下发设定值(推荐的参数语义寻址面)。
280
+ * 权限沿用节点绑定(参数 → 执行节点);限界联锁(参数基准 ∩ 产品 ∩ 配方 ∩ 节点安全量程)
281
+ * 在网关咽喉点统一生效。args.hypothesis 声明本次假设(入册),args.task_id 关联任务。 */
282
+ export async function toolParamControl(agentId: string, args: {
283
+ param?: string
284
+ value?: number | string
285
+ hypothesis?: string
286
+ task_id?: string
287
+ line_id?: string
288
+ }): Promise<{ text: string, isError?: boolean }> {
289
+ const resolved = resolveParamRef(String(args.param ?? ''), args.line_id ? String(args.line_id) : undefined)
290
+ if (!resolved.ok) return resolved
291
+ const param = resolved.param
292
+ const value = Number(args.value)
293
+ if (!Number.isFinite(value)) {
294
+ return { text: '设定值 value 必须为数字。', isError: true }
295
+ }
296
+ const repo = getAgentNodeBindingRepo()
297
+ const binding = repo.find(agentId, param.nodeId, 'dcw')
298
+ if (!binding) {
299
+ const mine = repo.byAgent(agentId).filter(b => b.kind === 'dcw')
300
+ return {
301
+ text: mine.length
302
+ ? `无权操作工艺参数「${param.key}」(执行节点 ${param.nodeId} 未绑定给你)。你有权控制的数控节点:${mine.map(b => b.nodeId).join(', ')}。`
303
+ : '你尚未绑定任何数控节点,无权下发控制指令。请在数字孪生界面绑定数控节点。',
304
+ isError: true,
305
+ }
306
+ }
307
+ const node = getDcwController().byId(param.nodeId)
308
+ if (!node) {
309
+ repo.removeAgentNode(agentId, param.nodeId, 'dcw')
310
+ return { text: `工艺参数「${param.key}」的执行节点已不存在(可能被删除),原绑定已自动清理。`, isError: true }
311
+ }
312
+ if (!node.enabled) {
313
+ return { text: `工艺参数「${param.key}」的执行节点「${node.name}」已停用(控制已暂停),无法下发。`, isError: true }
314
+ }
315
+ // 手动确认模式:与 dcw_control 同源审批面,备注回给 Agent
316
+ if (binding.mode === 'manual') {
317
+ const approvals = getToolApprovals()
318
+ if (approvals.hasPendingFor(agentId, param.nodeId)) {
319
+ return { text: '你对该执行节点已有一条待审批的下发指令,请等待用户处理后再发新指令(避免审批堆积)。', isError: true }
320
+ }
321
+ const detail = `工艺参数「${param.key}」(${param.name})设定 ${value}${param.unit},${paramLimitsText(param)}`
322
+ const ap = await approvals.request(agentId, param.nodeId, 'dcw', detail)
323
+ if (!ap.approved) {
324
+ return { text: `指令未执行:用户${ap.comment.includes('超时') ? '未在时限内批准(超时)' : `拒绝了本次下发`}。用户备注:${ap.comment || '(无)'}` }
325
+ }
326
+ if (!repo.find(agentId, param.nodeId, 'dcw')) {
327
+ return { text: '指令未执行:审批通过时你的该节点绑定已被解除(权限在批准时失效)。', isError: true }
328
+ }
329
+ }
330
+ try {
331
+ const meta = {
332
+ source: 'agent' as const,
333
+ actor: agentId,
334
+ actorName: agentBadgeLabel(agentId),
335
+ taskId: args.task_id ? String(args.task_id) : undefined,
336
+ hypothesis: args.hypothesis ? String(args.hypothesis) : '',
337
+ }
338
+ const outcome = await getDcwController().writeParam(param.id, value, meta)
339
+ if (outcome.ok) {
340
+ const stable = getRecipeRollBackManager().journal({ nodeId: param.nodeId, limit: 10 }).find(a => a.prevValue != null && a.prevValue !== a.newValue)
341
+ const loopTxt = [
342
+ outcome.recordId ? `优化记录 ${outcome.recordId} 已开窗(观察数采后 dcw_judge 落判定)` : null,
343
+ stable ? `上一稳定锚:${stable.prevValue}${param.unit}(可 dcw_rollback 回退)` : null,
344
+ ].filter(Boolean).join(';')
345
+ return {
346
+ text: `下发成功:工艺参数「${param.key}」(${param.name})设定 ${value}${param.unit} → 执行节点「${node.name}」;回读 ${outcome.readback != null ? `${outcome.readback}${param.unit}` : '不支持'}一致。${paramLimitsText(param)}。${outcome.message}${loopTxt ? `\n[调控闭环] ${loopTxt}` : ''}`,
347
+ }
348
+ }
349
+ return { text: `下发失败:${outcome.message}(工艺参数 ${param.key},执行节点「${node.name}」;${paramLimitsText(param)};当前设定值保持 ${node.value ?? '原值'}${param.unit} 未被改动)`, isError: true }
350
+ }
351
+ catch (err) {
352
+ const msg = err instanceof Error ? err.message : String(err)
353
+ return { text: `下发被拒绝:${msg}(工艺参数 ${param.key};${paramLimitsText(param)})`, isError: true }
354
+ }
355
+ }
356
+
357
+ /** 工具:param_read —— 按工艺参数读取 PLC 当前值(被动观测免审批) */
358
+ export async function toolParamRead(agentId: string, args: {
359
+ param?: string
360
+ line_id?: string
361
+ }): Promise<{ text: string, isError?: boolean }> {
362
+ const resolved = resolveParamRef(String(args.param ?? ''), args.line_id ? String(args.line_id) : undefined)
363
+ if (!resolved.ok) return resolved
364
+ const param = resolved.param
365
+ const repo = getAgentNodeBindingRepo()
366
+ if (!repo.find(agentId, param.nodeId, 'dcw')) {
367
+ const mine = repo.byAgent(agentId).filter(b => b.kind === 'dcw')
368
+ return {
369
+ text: mine.length
370
+ ? `无权读取工艺参数「${param.key}」(执行节点 ${param.nodeId} 未绑定给你)。你有权读取的数控节点:${mine.map(b => b.nodeId).join(', ')}。`
371
+ : '你尚未绑定任何数控节点,无权读取控制通道数据。请在数字孪生界面绑定数控节点。',
372
+ isError: true,
373
+ }
374
+ }
375
+ const node = getDcwController().byId(param.nodeId)
376
+ if (!node) {
377
+ repo.removeAgentNode(agentId, param.nodeId, 'dcw')
378
+ return { text: `工艺参数「${param.key}」的执行节点已不存在(可能被删除),原绑定已自动清理。`, isError: true }
379
+ }
380
+ try {
381
+ const read = await getDcwController().readParam(param.id)
382
+ if (!read.ok && read.value == null && !node.readValue) {
383
+ return { text: `读取失败:${read.message}(执行节点「${node.name}」驱动 ${node.driver} 可能不支持读取;可改用 daq_query 查关联数采通道)`, isError: true }
384
+ }
385
+ const readTxt = read.value != null
386
+ ? `${Number(read.value.toFixed(param.decimals))}${param.unit} @ ${read.at.slice(11, 19)}`
387
+ : (node.readValue != null ? `${node.readValue}${param.unit}(最近一次)` : '无读数')
388
+ return {
389
+ text: `读取成功:工艺参数「${param.key}」(${param.name})\n PLC 读数(ACT): ${readTxt}\n 当前设定(SET): ${node.value != null ? `${node.value}${param.unit}` : '从未下发'}\n ${paramLimitsText(param)}`,
390
+ }
391
+ }
392
+ catch (err) {
393
+ return { text: `读取被拒绝:${err instanceof Error ? err.message : String(err)}(工艺参数 ${param.key})`, isError: true }
394
+ }
395
+ }
396
+
239
397
  /**
240
398
  * 数采目标集解析(工具共用鉴权面):Agent 绑定(kind=daq)为权限边界 ——
241
399
  * node_id/line_id 只能缩小范围,不能放大(越权节点一律拒绝)。
@@ -18,7 +18,7 @@
18
18
  * 与 codex/dsh/opencode impl 全引擎一致。协议权威:omp://rpc.md。
19
19
  */
20
20
  import { createLogger } from '../logger'
21
- import { BaseAgentImpl } from './base-agent'
21
+ import { BaseAgentImpl, type BaseAgentConfigView } from './base-agent'
22
22
  import { randomUUID } from 'node:crypto'
23
23
  import type {
24
24
  AgentEvent,
@@ -133,8 +133,8 @@ export class OmpRpcAgentImpl extends BaseAgentImpl implements AgentInterface {
133
133
  return 'omp'
134
134
  }
135
135
 
136
- protected configRecord(): Record<string, unknown> {
137
- return this.config as unknown as Record<string, unknown>
136
+ protected configRecord(): BaseAgentConfigView {
137
+ return this.config
138
138
  }
139
139
 
140
140
  /**
@@ -205,7 +205,9 @@ export class OmpRpcAgentImpl extends BaseAgentImpl implements AgentInterface {
205
205
  /** 当前回合产生的 assistant 文本(供诊断) */
206
206
  private turnText = ''
207
207
  /** agent 身份信息(factory 注入;无需等待 init()) */
208
- private agentRole: 'lead' | 'worker' = 'worker'
208
+ // agentRole 由 BaseAgentImpl 持有(protected);同名私有声明会遮蔽基类 identity 角色。
209
+ // 仅收窄可见性声明,运行时代码不变(构造函数与 ensureClient 仍显式同步)。
210
+ protected override agentRole: 'lead' | 'worker' = 'worker'
209
211
 
210
212
  // ===== 上下文治理(70% 无中断压缩环)=====
211
213
  /** 压缩进行中(平台 gate 与 omp 原生压缩共用互斥位) */
@@ -421,7 +423,7 @@ export class OmpRpcAgentImpl extends BaseAgentImpl implements AgentInterface {
421
423
 
422
424
  // ===== 生命周期 =====
423
425
 
424
- async init(input: { agent: AgentInfo, channelId: string }): Promise<void> {
426
+ override async init(input: { agent: AgentInfo, channelId: string }): Promise<void> {
425
427
  this.agentInfo = input.agent
426
428
  this.channelId = input.channelId
427
429
  this.agentName = input.agent.name
@@ -550,10 +552,13 @@ export class OmpRpcAgentImpl extends BaseAgentImpl implements AgentInterface {
550
552
 
551
553
  // ===== supervise() =====
552
554
 
553
- /** supervise 单飞守卫:同一 client 不并发 LLM 回合(残留回合与下一 prompt 混流的根因) */
554
- private supervising = false
555
+ /**
556
+ * supervise 单飞守卫:同一 client 不并发 LLM 回合(残留回合与下一 prompt 混流的根因)。
557
+ * 守卫位由 BaseAgentImpl 的 protected supervising 承载 —— 本类原先的私有重复声明与基类构成
558
+ * "两个私有声明"(TS2415),而 JS 只有一个实例字段,故删除后语义与运行时完全一致。
559
+ */
555
560
 
556
- async supervise(snapshot: SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<SupervisionDecision[]> {
561
+ override async supervise(snapshot: SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<SupervisionDecision[]> {
557
562
  await this.ensureClient(ctx)
558
563
  if (!this.client) return []
559
564
  if (this.supervising) return [] // 上一轮 supervise 未收口:跳过本拍(节流即正确)
@@ -1109,7 +1114,8 @@ export class OmpRpcAgentImpl extends BaseAgentImpl implements AgentInterface {
1109
1114
  const client = new OmpRpcClient({
1110
1115
  command,
1111
1116
  mode: this.rpcMode,
1112
- args: [...(this.config.thinkingLevel ? ['--thinking', this.config.thinkingLevel] : [])],
1117
+ // 重复键 args 的生效者是下一行(JS 对象字面量后写覆盖先写):保留生效语义,删除被覆盖项。
1118
+ // (原 ['--thinking', level] 从未真正传给 omp —— 见报告"未修的缺陷"一节。)
1113
1119
  args: this.config.args,
1114
1120
  cwd: this.config.cwd ?? process.cwd(),
1115
1121
  // 进程退出 → 注册表标记(供运行时资源监控);pid=-1 表示无法取得,忽略
@@ -32,7 +32,7 @@ import { extractJsonArray, peerPrompt, supervisePrompt, systemManual, toolArgsPr
32
32
  import { getHitlRegistry } from './hitl-registry'
33
33
  import { harnessSettings } from '../settings'
34
34
  import { spawnLineProcess } from './adapters/line-spawn'
35
- import { BaseAgentImpl } from './base-agent'
35
+ import { BaseAgentImpl, type BaseAgentConfigView } from './base-agent'
36
36
  import { resolveBridgePath, resolvePlatformBaseUrl } from './harness-env'
37
37
 
38
38
  const log = createLogger('workshop.opencode')
@@ -152,7 +152,7 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
152
152
  return 'opencode'
153
153
  }
154
154
 
155
- protected configRecord(): Record<string, unknown> {
155
+ protected configRecord(): BaseAgentConfigView {
156
156
  return this.config
157
157
  }
158
158
 
@@ -222,7 +222,7 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
222
222
  }
223
223
 
224
224
  /** HITL 应答(codex/opencode/dsh 统一入口;本 impl 处理 opencode-permission) */
225
- async respondHitl(kind: string, id: string, outcome: {
225
+ override async respondHitl(kind: string, id: string, outcome: {
226
226
  confirmed?: boolean
227
227
  cancelled?: boolean
228
228
  value?: string
@@ -247,7 +247,9 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
247
247
  await this.api('POST', `/question/${encodeURIComponent(id)}/reply`, { answer: outcome.value ?? outcome.comment ?? '' })
248
248
  }
249
249
  }
250
- if (pending.timer) clearTimeout(p.timer)
250
+ // 原为 clearTimeout(p.timer):p 在本作用域不存在(ReferenceError,且仅当计时器非空时触发),
251
+ // 该待办条目在此处就是 pending(与 dsh/codex/hermes 的同名分支写法一致)。
252
+ if (pending.timer) clearTimeout(pending.timer)
251
253
  this.pendingHitl.delete(id)
252
254
  getHitlRegistry().resolve(kind, id, cancelled ? 'cancelled' : 'answered')
253
255
  }
@@ -273,9 +275,9 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
273
275
  }
274
276
  }
275
277
 
276
- private supervising = false
278
+ // supervising 由 BaseAgentImpl 持有(protected):同名私有声明会与基类形成"两个私有声明"(TS2415)。
277
279
 
278
- async supervise(snapshot: SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<SupervisionDecision[]> {
280
+ override async supervise(snapshot: SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<SupervisionDecision[]> {
279
281
  // 引擎/会话不可用 → 本轮监督降级为空(调度器回退规则引擎);绝不让引擎故障
280
282
  // 以 unhandledRejection 形态逃逸(dev-stability-guard 会据此杀掉整个服务端)
281
283
  try {
@@ -296,16 +298,22 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
296
298
  memory: ctx.memory,
297
299
  })
298
300
  const timeoutMs = this.config.superviseTimeoutMs ?? 150_000
299
- return await this.runTurn(prompt, undefined, {
300
- timeoutMs,
301
- signal: opts?.signal,
302
- onDone: async () => {
303
- this.supervising = false
304
- },
305
- beforeStart: () => {
306
- this.supervising = true
307
- },
308
- }).then((events) => {
301
+ // runTurn 是 async generator(返回 AsyncGenerator,不是 Promise),必须以异步迭代消费完整个回合。
302
+ // (原实现写 .then(...)/.catch(...):运行时是 "then is not a function" 的 TypeError,supervise 整条路径实际不可用。)
303
+ try {
304
+ const events: AgentEvent[] = []
305
+ for await (const e of this.runTurn(prompt, undefined, {
306
+ timeoutMs,
307
+ signal: opts?.signal,
308
+ onDone: async () => {
309
+ this.supervising = false
310
+ },
311
+ beforeStart: () => {
312
+ this.supervising = true
313
+ },
314
+ })) {
315
+ events.push(e)
316
+ }
309
317
  // 从事件流提取最终文本 → JSON 决策兜底(工具直执行路径返回空)
310
318
  let text = ''
311
319
  for (const e of events) {
@@ -315,10 +323,21 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
315
323
  }
316
324
  const parsed = extractJsonArray(text)
317
325
  return parsed && parsed.length > 0 ? parsed as SupervisionDecision[] : []
318
- }).catch(() => {
326
+ }
327
+ catch {
319
328
  this.supervising = false
320
329
  return []
321
- })
330
+ }
331
+ }
332
+
333
+ /** supervise 用:收齐整个回合的事件(基类抽象成员;本类 supervise 自行消费并需 beforeStart/onDone 钩子) */
334
+ protected async collectTurnEvents(prompt: string, timeoutMs: number, signal?: AbortSignal): Promise<AgentEvent[]> {
335
+ const events: AgentEvent[] = []
336
+ for await (const e of this.runTurn(prompt, undefined, { timeoutMs, signal })) {
337
+ events.push(e)
338
+ if (e.kind === 'error') break
339
+ }
340
+ return events
322
341
  }
323
342
 
324
343
  protected async* workerTurn(request: AgentRunRequest, ctx: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown> {
@@ -800,10 +819,17 @@ export class OpenCodeAgentImpl extends BaseAgentImpl implements AgentInterface {
800
819
  }
801
820
  const createWith = async (extra: Record<string, unknown> | undefined): Promise<Record<string, unknown>> =>
802
821
  this.api('POST', '/session', { ...body, ...(extra ?? {}) })
803
- const created = await (this.config.permission ?? DEFAULT_PERMISSION)
822
+ // 历史实现写作 `await (cond) ? a : b`:await 只作用于条件,整个三元表达式的结果是**未 await** 的
823
+ // Promise,故 created?.id 恒为 undefined → sessionId 恒为 String(undefined ?? '') === '' →
824
+ // 必然落到下面的 2.5s 重试循环(真正被使用的会话来自重试那次 createWith(undefined))。
825
+ // 此处逐字保留该运行时语义:同样的 await 让出一次微任务、同样的请求照发、首次结果同样丢弃。
826
+ // 直白的修法是给整个三元表达式加括号 await(会用上带 permission 的首次会话、省掉 2.5s 重试),
827
+ // 但那会改变 opencode 会话的权限策略与启动时序,故本次不改 —— 见报告"未修的缺陷"一节。
828
+ const firstAttempt = await (this.config.permission ?? DEFAULT_PERMISSION)
829
+ void (firstAttempt
804
830
  ? createWith({ permission: this.config.permission ?? DEFAULT_PERMISSION }).catch(() => createWith(undefined))
805
- : createWith(undefined)
806
- this.sessionId = String(created?.id ?? '')
831
+ : createWith(undefined))
832
+ this.sessionId = ''
807
833
  if (!this.sessionId) {
808
834
  // 瞬态失败(实例刚起/内部分配竞态/权限规则不兼容)→ 无附加字段重试,最多 3 次
809
835
  for (let i = 0; i < 3 && !this.sessionId; i++) {
@@ -27,7 +27,7 @@ import type {
27
27
  } from './agent-interface'
28
28
  import type { AgentContextStats } from '../types/task'
29
29
  import { markHarnessProcessExit, registerHarnessProcess, bindHarnessProcess, killHarnessProcess } from './harness-process'
30
- import { peerPrompt, systemManual, toolArgsPreview, workerPrompt } from './prompt-builder'
30
+ import { extractJsonArray, peerPrompt, supervisePrompt, systemManual, toolArgsPreview, workerPrompt } from './prompt-builder'
31
31
  import { getHitlRegistry } from './hitl-registry'
32
32
  import { harnessSettings } from '../settings'
33
33
  import { StdioJsonRpcClient, type JsonRpcRequestIncoming } from './adapters/stdio-jsonrpc'
@@ -111,7 +111,9 @@ export interface QwenAgentConfig {
111
111
  export class QwenAgentImpl extends BaseAgentImpl {
112
112
  private readonly config: QwenAgentConfig
113
113
 
114
- private agentRole: 'lead' | 'worker' = 'worker'
114
+ // agentRole 由 BaseAgentImpl 持有(protected);同名私有声明会遮蔽基类 identity 角色。
115
+ // 仅收窄可见性声明,运行时代码不变。
116
+ protected override agentRole: 'lead' | 'worker' = 'worker'
115
117
  private client: StdioJsonRpcClient | null = null
116
118
  private clientStarting: Promise<void> | null = null
117
119
  private turnActive = false
@@ -177,7 +179,7 @@ export class QwenAgentImpl extends BaseAgentImpl {
177
179
  }
178
180
 
179
181
  /** HITL 应答:requestToolCallConfirmation → outcome allow/reject/cancel(fail-closed) */
180
- async respondHitl(kind: string, id: string, outcome: {
182
+ override async respondHitl(kind: string, id: string, outcome: {
181
183
  confirmed?: boolean
182
184
  cancelled?: boolean
183
185
  }): Promise<void> {
@@ -202,7 +204,7 @@ export class QwenAgentImpl extends BaseAgentImpl {
202
204
 
203
205
  // ===== run / supervise =====
204
206
 
205
- async supervise(snapshot: import('./agent-interface').SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<import('./agent-interface').SupervisionDecision[]> {
207
+ override async supervise(snapshot: import('./agent-interface').SupervisionSnapshot, ctx: AgentRunContext, opts?: { signal?: AbortSignal }): Promise<import('./agent-interface').SupervisionDecision[]> {
206
208
  await this.ensureClient(ctx)
207
209
  if (!this.client || !this.sessionStarted) return []
208
210
  if (this.supervising) return []
@@ -216,7 +218,10 @@ export class QwenAgentImpl extends BaseAgentImpl {
216
218
  })
217
219
  this.supervising = true
218
220
  try {
219
- const events = await this.collectTurn(prompt, this.config.superviseTimeoutMs ?? 150_000, opts?.signal)
221
+ // 原为 this.collectTurn(...):该类唯一存在的整回合收集实现是 collectTurnEvents
222
+ // (与基类 supervise 调用的同名抽象成员同签名)。原调用在运行时抛 TypeError 并被
223
+ // 本方法的 catch 吞掉 → supervise 恒返回 [],详见报告。
224
+ const events = await this.collectTurnEvents(prompt, this.config.superviseTimeoutMs ?? 150_000, opts?.signal)
220
225
  let text = ''
221
226
  for (const e of events) {
222
227
  if (e.kind === 'artifact') {
@@ -72,7 +72,9 @@ export function inventory(): AmlInventory {
72
72
  kind: EntityIssue['kind'],
73
73
  rows: Array<{ id: string, path?: string }>,
74
74
  baseDir: string,
75
- contract: string[],
75
+ // 非空契约列表:三个调用点都传字面量,且下面按"多选一"语义读 contract[0] 作展示路径,
76
+ // 用非空元组表达"至少一项"这一既有前提(纯类型,运行时零变化)
77
+ contract: readonly [string, ...string[]],
76
78
  ): number => {
77
79
  const ids = new Set(rows.map(r => r.id))
78
80
  for (const r of rows) {
@@ -362,7 +362,8 @@ export async function installUv(rt: AmlRuntime, onLog?: ProgressFn): Promise<{ o
362
362
  const hit = findUvInDir(rt.toolsDir)
363
363
  if (hit) {
364
364
  const v = await runCapture(hit, ['--version'], 15_000)
365
- const version = (v.out || v.err).trim().split('\n')[0]
365
+ // 运行时 `''.split('\n')[0] === ''`,首行恒存在;?? '' 只是 noUncheckedIndexedAccess 下的写法
366
+ const version = (v.out || v.err).trim().split('\n')[0] ?? ''
366
367
  writeUvRecord(rt, { uvPath: hit, version, installedAt: new Date().toISOString(), installDir: rt.toolsDir, method: 'official-script' })
367
368
  resetProbeCache()
368
369
  emit(`安装成功:${version} @ ${hit}`)
@@ -390,7 +391,7 @@ export async function installUv(rt: AmlRuntime, onLog?: ProgressFn): Promise<{ o
390
391
  }
391
392
  catch { /* Windows 无 x 位 */ }
392
393
  const v = await runCapture(hit, ['--version'], 15_000)
393
- const version = (v.out || v.err).trim().split('\n')[0]
394
+ const version = (v.out || v.err).trim().split('\n')[0] ?? ''
394
395
  writeUvRecord(rt, { uvPath: hit, version, installedAt: new Date().toISOString(), installDir: rt.toolsDir, method: 'pip-target' })
395
396
  resetProbeCache()
396
397
  emit(`安装成功:${version} @ ${hit}`)
@@ -25,6 +25,10 @@ const TOPIC_WILDCARD = `${TOPIC_ROOT}/+/sample`
25
25
  /** 断连离线缓冲上限(满丢最旧;补发帧按消费侧乱序防御自然去重) */
26
26
  const OFFLINE_CAP = 2000
27
27
 
28
+ /** MQTT QoS 协议取值(0/1/2;shared/config/schema.json 的 daq.mqtt.qos 声明 min 0 / max 2)。
29
+ * settings 面(settings.ts)把该配置读成 number,这里按协议收窄 —— 运行时原值透传,不做钳制/兜底。 */
30
+ type MqttQos = 0 | 1 | 2
31
+
28
32
  export class MqttQueueAdapter implements DaqQueuePort {
29
33
  readonly backend = 'mqtt' as const
30
34
  private client: MqttClient | null = null
@@ -48,7 +52,7 @@ export class MqttQueueAdapter implements DaqQueuePort {
48
52
  const mod = requireMqtt('mqtt') as unknown as { connect: (url: string, opts?: Record<string, unknown>) => MqttClient }
49
53
  // 凭据/QoS/TLS 配置驱动(daq.mqtt.*;legacy DAQ_MQTT_* env 别名兼容,DAQ_MQTT_URL 整串覆盖仍最高优先)
50
54
  const mqttCfg = daqRuntimeSettings().mqtt
51
- const qos = mqttCfg.qos
55
+ const qos = mqttCfg.qos as MqttQos
52
56
  const opts: Record<string, unknown> = {
53
57
  clientId: `aw-daq-${process.pid}-${Math.random().toString(36).slice(2, 6)}`,
54
58
  reconnectPeriod: 2000,
@@ -99,7 +103,7 @@ export class MqttQueueAdapter implements DaqQueuePort {
99
103
  return
100
104
  }
101
105
  this.published++
102
- this.client.publish(TOPIC_SAMPLE(env.nodeId), JSON.stringify(env), { qos: daqRuntimeSettings().mqtt.qos })
106
+ this.client.publish(TOPIC_SAMPLE(env.nodeId), JSON.stringify(env), { qos: daqRuntimeSettings().mqtt.qos as MqttQos })
103
107
  }
104
108
 
105
109
  consume(fn: DaqConsumer): () => void {
@@ -123,8 +127,8 @@ export class MqttQueueAdapter implements DaqQueuePort {
123
127
  // end() 回调在某些断连路径下不触发,旧 client 的 connect/message/error 监听器
124
128
  // 会连同 socket 一起滞留(client 对象被闭包引用,GC 不可达)。
125
129
  // rebuildDaqQueue 反复换装时会累积;显式摘除是唯一确定性的清理点。
126
- try {
127
- c.removeAllListeners()
130
+ try {
131
+ c.removeAllListeners()
128
132
  }
129
133
  catch { /* 已销毁等场景:尽力而为 */ }
130
134
  }
@@ -106,6 +106,16 @@ export interface DaqPatchInput {
106
106
 
107
107
  type BroadcastFn = (type: string, payload: unknown) => void
108
108
 
109
+ /** 有界 LRU 的最小泛型面:shared/lru.mjs 是 allowJs 推断出的**非泛型**类(JS 里没有 @template),
110
+ * 直接 `new LruMap<K, V>()` 无处安放类型参数。这里按实际使用面(get/set/delete/size)声明键值类型,
111
+ * 调用点即可拿到准确的读写类型;运行时仍是同一个 LruMap(纯类型声明,零运行时差异)。 */
112
+ interface LruLike<K, V> {
113
+ readonly size: number
114
+ get(key: K): V | undefined
115
+ set(key: K, value: V): unknown
116
+ delete(key: K): unknown
117
+ }
118
+
109
119
  /** TSDB 批量写窗口(ms):消费端攒批再落盘 */
110
120
  const TSDB_FLUSH_MS = 500
111
121
  /** TSDB 攒批缓冲上限(背压:满则丢最旧并计数,防慢库拖爆内存) */
@@ -416,7 +426,9 @@ class DaqController {
416
426
  // 指标阈值告警(模板 metrics 规则;alarm 硬限边沿 → 既有告警链路)
417
427
  this.evaluateMetricAlarms(node, tpl, metrics)
418
428
  if (!allowPublish) return
419
- const payload: AepDaqFrame = {
429
+ // lineId 是 WS 逐产线扇出的依据(scene-events.payloadLineId 读的就是 payload.lineId,
430
+ // 与 AepDaqReading.lineId 同义);AepDaqFrame 协议类型漏了该字段 —— 见报告。
431
+ const payload: AepDaqFrame & { lineId: string | null } = {
420
432
  nodeId: node.id,
421
433
  templateRef: node.templateRef,
422
434
  kind: f.kind,
@@ -694,7 +706,7 @@ class DaqController {
694
706
 
695
707
  /** 同绑定 siblings 缓存(1s TTL):回写热路径不再逐样本全量 scan,O(N²)→O(N)/周期。
696
708
  * 用有界 LRU 而非「超 500 整体 clear()」——后者会造成周期性全量缓存穿透。 */
697
- private siblingsCache = new LruMap<string, { at: number, list: DaqNode[] }>(500)
709
+ private siblingsCache: LruLike<string, { at: number, list: DaqNode[] }> = new LruMap(500)
698
710
 
699
711
  private siblingsOf(bindingId: string): DaqNode[] {
700
712
  const hit = this.siblingsCache.get(bindingId)
@@ -759,7 +771,10 @@ class DaqController {
759
771
  this.broadcast = fn
760
772
  }
761
773
 
762
- controllerState(): AepDaqControllerState & { produced?: number, consumed?: number, dropped?: number, samplesStored?: number, tsdbDropped?: number } {
774
+ /** minIntervalMs / alarmsRaised / framesStored 都是本方法**实际返回**的字段,但 AepDaqControllerState
775
+ * 未收录(协议类型与实现漂移):minIntervalMs 被前端 useDaqStream 消费,alarmsRaised 被
776
+ * server/api/metrics.ts 消费(framesStored 供管线指标展示)。这里按实现补齐返回面 —— 见报告。 */
777
+ controllerState(): AepDaqControllerState & { minIntervalMs: number, alarmsRaised: number, framesStored: number, produced?: number, consumed?: number, dropped?: number, samplesStored?: number, tsdbDropped?: number } {
763
778
  // 丢弃 = 队列层真实丢弃(inproc 拥塞/mqtt 断连)+ 消费侧乱序迟到帧(诚实可见)
764
779
  const queueLost = g_queueLost()
765
780
  // 单次遍历(hardening PERF-1):status 高频路径不再对全表多次 all()
@@ -10,9 +10,9 @@
10
10
  */
11
11
 
12
12
  import { applyTransform } from '../../../../shared/daq-protocol'
13
- import { classifyCommError } from './drivers'
13
+ import { classifyCommError, type DaqFrameSample } from './drivers'
14
14
  import type { DaqNode } from './daq-node'
15
- import type { DaqFrameSample, DaqSampleEnvelope } from './bus/queue-port'
15
+ import type { DaqSampleEnvelope } from './bus/queue-port'
16
16
 
17
17
  /** 驱动故障广播节流(ms;每运行时独立计时) */
18
18
  const ERR_THROTTLE_MS = 30_000
@@ -94,7 +94,9 @@ export class DaqNodeRuntime {
94
94
  if (now < this.lastSampleAt + node.effectiveInterval(defs.intervalMs, defs.minIntervalMs)) return
95
95
  this.sampling = true
96
96
  try {
97
- let v: number | DaqFrameSample | null = null
97
+ // 生产面可能返回三种形态:标量 / 驱动原生帧(DaqFrameSample)/ 生产侧已剥离 blob 的帧信封
98
+ // (与 DaqRuntimeHost.sample 的返回面一致 —— 后者不能丢,否则帧信封分支拿不到 kind/points)
99
+ let v: number | DaqFrameSample | { frame: NonNullable<DaqSampleEnvelope['frame']> } | null = null
98
100
  try {
99
101
  v = await this.host.sample(node, now)
100
102
  }