agentworkshop 0.7.40 → 0.7.44

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 (327) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/B8uy9iRW.js +1 -0
  3. package/.output/public/_nuxt/BGTYYQH-.js +1 -0
  4. package/.output/public/_nuxt/BUmHEJ77.js +2 -0
  5. package/.output/public/_nuxt/BY7YrV_D.js +1 -0
  6. package/.output/public/_nuxt/Bqcgz95s.js +18 -0
  7. package/.output/public/_nuxt/C7UlqPeD.js +1 -0
  8. package/.output/public/_nuxt/CTmDn-YP.js +1 -0
  9. package/.output/public/_nuxt/Cs8pVeVG.js +1 -0
  10. package/.output/public/_nuxt/{DcsCcxp4.js → D98NH8kG.js} +1 -1
  11. package/.output/public/_nuxt/DKySmNPI.js +14 -0
  12. package/.output/public/_nuxt/Di0NY_ht.js +1 -0
  13. package/.output/public/_nuxt/Du9v6qGB.js +1 -0
  14. package/.output/public/_nuxt/{C_iYD-EB.js → EHlEMRii.js} +1 -1
  15. package/.output/public/_nuxt/Eke1fs-U.js +1 -0
  16. package/.output/public/_nuxt/{DeJykBFf.js → H0BcqZtT.js} +1 -1
  17. package/.output/public/_nuxt/{C4oW1HsE.js → HSYEkkce.js} +1 -1
  18. package/.output/public/_nuxt/{DZshyNLa.js → IREZ1eC2.js} +1 -1
  19. package/.output/public/_nuxt/{D_OTvQza.js → J9oU00D1.js} +1 -1
  20. package/.output/public/_nuxt/OmpTerminalPanel.BxR5-lvi.css +1 -0
  21. package/.output/public/_nuxt/SSyAPaHc.js +1 -0
  22. package/.output/public/_nuxt/TownView.li4EMQxK.css +1 -0
  23. package/.output/public/_nuxt/VdLk4jLE2.js +1 -0
  24. package/.output/public/_nuxt/_id_.BhsXoEuk.css +1 -0
  25. package/.output/public/_nuxt/_id_.DQyj-WKN.css +1 -0
  26. package/.output/public/_nuxt/{_wsId_.B4WiqkIS.css → _wsId_.CTx-BlfF.css} +1 -1
  27. package/.output/public/_nuxt/aShsv_rG.js +19 -0
  28. package/.output/public/_nuxt/{yF0aYMF1.js → aesgXKSr.js} +3 -3
  29. package/.output/public/_nuxt/agents.B21nUEUX.css +1 -0
  30. package/.output/public/_nuxt/aml.ekTjxFkf.css +1 -0
  31. package/.output/public/_nuxt/builds/latest.json +1 -1
  32. package/.output/public/_nuxt/builds/meta/b5506ef0-f48e-4f14-a6c0-d65e505d0b09.json +1 -0
  33. package/.output/public/_nuxt/ca4TJ3Op.js +1 -0
  34. package/.output/public/_nuxt/channel-templates.DplM1pJ3.css +1 -0
  35. package/.output/public/_nuxt/daq.BdVmoIfe.css +1 -0
  36. package/.output/public/_nuxt/dcw.DCgyzpWV.css +1 -0
  37. package/.output/public/_nuxt/{default.J32SgqFY.css → default.Bh3L2HU8.css} +1 -1
  38. package/.output/public/_nuxt/lHAxdSsj.js +1 -0
  39. package/.output/public/_nuxt/pages.j9rzRocr.css +1 -0
  40. package/.output/public/_nuxt/plugins.DhiZbHU8.css +1 -0
  41. package/.output/public/_nuxt/settings.BRx9rIDg.css +1 -0
  42. package/.output/public/_nuxt/teams.BLlOPB_Z.css +1 -0
  43. package/.output/public/_nuxt/tokens.De8xzszn.css +1 -0
  44. package/.output/public/_nuxt/workshop.D1jFNkrn.css +1 -0
  45. package/.output/server/chunks/_/nitro.mjs +1058 -830
  46. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  47. package/.output/server/chunks/build/{OmpTerminalPanel-Cu_s4i0A.mjs → OmpTerminalPanel-CVvxpsF7.mjs} +15 -15
  48. package/.output/server/chunks/build/{OmpTerminalPanel-Cu_s4i0A.mjs.map → OmpTerminalPanel-CVvxpsF7.mjs.map} +1 -1
  49. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs → TownView-CJ6IsDCc.mjs} +229 -228
  50. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs.map → TownView-CJ6IsDCc.mjs.map} +1 -1
  51. package/.output/server/chunks/build/{_id_-BU1wfOID.mjs → _id_-CVD_H0ir.mjs} +149 -147
  52. package/.output/server/chunks/build/_id_-CVD_H0ir.mjs.map +1 -0
  53. package/.output/server/chunks/build/{_id_-BYsEua57.mjs → _id_-CtxMb3qp.mjs} +47 -46
  54. package/.output/server/chunks/build/_id_-CtxMb3qp.mjs.map +1 -0
  55. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs → _wsId_-DpY3T-md.mjs} +516 -446
  56. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs.map → _wsId_-DpY3T-md.mjs.map} +1 -1
  57. package/.output/server/chunks/build/{agents-CLQqJF2y.mjs → agents-DsCkuXDV.mjs} +49 -46
  58. package/.output/server/chunks/build/agents-DsCkuXDV.mjs.map +1 -0
  59. package/.output/server/chunks/build/{aml-_7FdFL2p.mjs → aml-CT0xKGKI.mjs} +122 -105
  60. package/.output/server/chunks/build/aml-CT0xKGKI.mjs.map +1 -0
  61. package/.output/server/chunks/build/builtin-catalog-edpDcgfL.mjs +117 -0
  62. package/.output/server/chunks/build/builtin-catalog-edpDcgfL.mjs.map +1 -0
  63. package/.output/server/chunks/build/{channel-templates-p6SZNjlM.mjs → channel-templates-Dla9FbYa.mjs} +49 -37
  64. package/.output/server/chunks/build/channel-templates-Dla9FbYa.mjs.map +1 -0
  65. package/.output/server/chunks/build/{daq-cgyjKmJu.mjs → daq-DWWSKGAV.mjs} +95 -93
  66. package/.output/server/chunks/build/daq-DWWSKGAV.mjs.map +1 -0
  67. package/.output/server/chunks/build/{dcw-CoTxBlAZ.mjs → dcw-CT8k17_E.mjs} +46 -45
  68. package/.output/server/chunks/build/dcw-CT8k17_E.mjs.map +1 -0
  69. package/.output/server/chunks/build/{default-BE4r0FZN.mjs → default-D3525UFX.mjs} +16 -15
  70. package/.output/server/chunks/build/{default-BE4r0FZN.mjs.map → default-D3525UFX.mjs.map} +1 -1
  71. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs → logs--dByNyhw.mjs} +2 -2
  72. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs.map → logs--dByNyhw.mjs.map} +1 -1
  73. package/.output/server/chunks/build/{monitor-C0okQaXz.mjs → monitor-Dh2Kvaq5.mjs} +2 -2
  74. package/.output/server/chunks/build/{monitor-C0okQaXz.mjs.map → monitor-Dh2Kvaq5.mjs.map} +1 -1
  75. package/.output/server/chunks/build/{pages-DFxjn9Xa.mjs → pages-BHcSBM2D.mjs} +26 -20
  76. package/.output/server/chunks/build/pages-BHcSBM2D.mjs.map +1 -0
  77. package/.output/server/chunks/build/{plugins-lGlUr1lj.mjs → plugins-BNgIi61W.mjs} +23 -17
  78. package/.output/server/chunks/build/plugins-BNgIi61W.mjs.map +1 -0
  79. package/.output/server/chunks/build/{settings-Ddd1qx2Z.mjs → settings-ipYBDWdn.mjs} +45 -44
  80. package/.output/server/chunks/build/settings-ipYBDWdn.mjs.map +1 -0
  81. package/.output/server/chunks/build/{teams-MEDLZdMn.mjs → teams-5lx-CwFa.mjs} +47 -44
  82. package/.output/server/chunks/build/teams-5lx-CwFa.mjs.map +1 -0
  83. package/.output/server/chunks/build/{tokens-C7fTM5C2.mjs → tokens-q-IDT8Io.mjs} +73 -53
  84. package/.output/server/chunks/build/tokens-q-IDT8Io.mjs.map +1 -0
  85. package/.output/server/chunks/build/{town-qMPql9Se.mjs → town-QJWB5wng.mjs} +5 -4
  86. package/.output/server/chunks/build/town-QJWB5wng.mjs.map +1 -0
  87. package/.output/server/chunks/build/{useDaqStream-CIBaiGAl.mjs → useDaqStream-DfCFpb3p.mjs} +9 -3
  88. package/.output/server/chunks/build/useDaqStream-DfCFpb3p.mjs.map +1 -0
  89. package/.output/server/chunks/build/{useDcwStream-CBbiYnWe.mjs → useDcwStream-UPiX-3iO.mjs} +11 -2
  90. package/.output/server/chunks/build/useDcwStream-UPiX-3iO.mjs.map +1 -0
  91. package/.output/server/chunks/build/{workshop-BL5bhfs0.mjs → workshop-BIlCj_ZP.mjs} +45 -45
  92. package/.output/server/chunks/build/workshop-BIlCj_ZP.mjs.map +1 -0
  93. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  94. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  95. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  96. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  97. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  98. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  99. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  100. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  101. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  102. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  103. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  104. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  105. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  106. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  107. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +3 -1
  108. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  109. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +3 -1
  110. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  111. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  112. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  113. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  114. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  115. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  116. package/.output/server/chunks/routes/renderer.mjs +2 -2
  117. package/.output/server/chunks/virtual/entry.mjs +639 -88
  118. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  119. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  120. package/.output/server/package.json +1 -1
  121. package/README-zh.md +16 -6
  122. package/README.md +17 -7
  123. package/app/components/AppHeader.vue +961 -959
  124. package/app/components/workshop/A2aRpcDebugger.vue +237 -237
  125. package/app/components/workshop/AgentInspectorDrawer.vue +424 -424
  126. package/app/components/workshop/AgentLanesView.vue +998 -998
  127. package/app/components/workshop/ArtifactCard.vue +120 -120
  128. package/app/components/workshop/AssetLibrary.vue +452 -452
  129. package/app/components/workshop/ChannelSessionList.vue +812 -804
  130. package/app/components/workshop/CommandPalette.vue +269 -269
  131. package/app/components/workshop/Composer.vue +827 -827
  132. package/app/components/workshop/DeviceTwinPanel.vue +643 -643
  133. package/app/components/workshop/EventBlock.vue +602 -602
  134. package/app/components/workshop/FileSelectorModal.vue +188 -188
  135. package/app/components/workshop/InspectorPanel.vue +301 -301
  136. package/app/components/workshop/MemoryPanel.vue +364 -364
  137. package/app/components/workshop/MultiChannelView.vue +189 -189
  138. package/app/components/workshop/TaskBoardView.vue +686 -686
  139. package/app/components/workshop/TaskInspectorDrawer.vue +390 -390
  140. package/app/components/workshop/TranscriptTimeline.vue +601 -601
  141. package/app/components/workshop/blocks/ClusterArtifact.vue +61 -61
  142. package/app/components/workshop/blocks/ClusterError.vue +85 -85
  143. package/app/components/workshop/blocks/ClusterLife.vue +87 -87
  144. package/app/components/workshop/blocks/ClusterMember.vue +95 -93
  145. package/app/components/workshop/blocks/ClusterMemory.vue +84 -84
  146. package/app/components/workshop/blocks/ClusterOther.vue +67 -67
  147. package/app/components/workshop/blocks/ClusterStatus.vue +149 -147
  148. package/app/components/workshop/blocks/ClusterTool.vue +158 -158
  149. package/app/components/workshop/terminal/OmpTerminalPanel.vue +1011 -1011
  150. package/app/components/workshop/town/TownView.vue +56 -56
  151. package/app/composables/workshop/useDaqStream.ts +7 -4
  152. package/app/composables/workshop/useDcwStream.ts +8 -2
  153. package/app/middleware/locale-cookie.global.ts +22 -0
  154. package/app/pages/aml/index.vue +24 -2
  155. package/app/pages/daq/[id].vue +20 -16
  156. package/app/pages/daq/index.vue +2310 -2307
  157. package/app/pages/dcw/[id].vue +26 -23
  158. package/app/pages/dcw/index.vue +3 -3
  159. package/app/pages/index.vue +987 -981
  160. package/app/pages/plugins/index.vue +317 -311
  161. package/app/pages/settings.vue +1564 -1562
  162. package/app/pages/tokens.vue +15 -15
  163. package/app/pages/workshop/agents.vue +612 -609
  164. package/app/pages/workshop/channel-templates.vue +18 -11
  165. package/app/pages/workshop/index.vue +668 -668
  166. package/app/pages/workshop/teams.vue +743 -740
  167. package/app/pages/workshop/w/[wsId].vue +704 -704
  168. package/app/plugins/locale-restore.client.ts +16 -1
  169. package/app/utils/builtin-catalog.ts +104 -0
  170. package/config.yml +170 -170
  171. package/docs/cli.en.md +2 -2
  172. package/docs/cli.md +2 -2
  173. package/docs/full-test-plan.md +2 -3
  174. package/docs/plugins.en.md +33 -1
  175. package/docs/plugins.md +29 -1
  176. package/docs/sdk.en.md +1 -1
  177. package/docs/sdk.md +1 -1
  178. package/i18n/locales/en.ts +293 -35
  179. package/i18n/locales/zh-CN.ts +265 -7
  180. package/package.json +4 -3
  181. package/scripts/_dbg-perms-e2e.mjs +132 -109
  182. package/scripts/_demo-agentteam-capture.mjs +278 -0
  183. package/scripts/_e2e-ui-functional.mjs +371 -0
  184. package/scripts/_i18n-en-cjk-scan.mjs +28 -0
  185. package/scripts/_i18n-en-verify.mjs +107 -0
  186. package/scripts/_i18n-extra-checks.mjs +53 -0
  187. package/scripts/_i18n-scan-hardcoded.mjs +180 -0
  188. package/scripts/_i18n-verify-keys.mjs +50 -0
  189. package/scripts/_loop-biax-campaign.mjs +130 -0
  190. package/scripts/_sweep-button-contrast.mjs +87 -0
  191. package/scripts/test-serial-bridge.mjs +418 -0
  192. package/scripts/ui/e2e-interactive.mjs +328 -0
  193. package/scripts/ui/record-demo.mjs +557 -0
  194. package/scripts/ui/seed-industrial-demo.mjs +171 -0
  195. package/server/api/workshop/daq/index.get.ts +3 -1
  196. package/server/api/workshop/dcw/index.get.ts +3 -0
  197. package/server/plugins/aw-plugins.ts +9 -7
  198. package/server/plugins-builtin/diag-bridge/index.mjs +608 -661
  199. package/server/plugins-builtin/rag-bridge/index.mjs +57 -133
  200. package/server/plugins-builtin/serial-bridge/client.mjs +210 -0
  201. package/server/plugins-builtin/serial-bridge/drivers.mjs +409 -0
  202. package/server/plugins-builtin/serial-bridge/i18n.json +62 -0
  203. package/server/plugins-builtin/serial-bridge/index.mjs +247 -0
  204. package/server/plugins-builtin/serial-bridge/lib.mjs +208 -0
  205. package/server/plugins-builtin/serial-bridge/rtu.mjs +168 -0
  206. package/server/services/workshop/daq/daq-controller.ts +7 -2
  207. package/server/services/workshop/daq/drivers.ts +89 -3
  208. package/server/services/workshop/dcw/dcw-controller.ts +5 -1
  209. package/server/services/workshop/dcw/drivers.ts +85 -2
  210. package/server/services/workshop/dcw/plugin-bridge.ts +45 -0
  211. package/server/services/workshop/plugins/host.mjs +30 -0
  212. package/shared/daq-protocol.ts +15 -0
  213. package/.output/public/_nuxt/88GOowgO2.js +0 -1
  214. package/.output/public/_nuxt/BOt2SP4z.js +0 -1
  215. package/.output/public/_nuxt/BP-NyKVG.js +0 -18
  216. package/.output/public/_nuxt/BXxH0UQE.js +0 -1
  217. package/.output/public/_nuxt/BsROmY89.js +0 -1
  218. package/.output/public/_nuxt/ClILjvWH.js +0 -1
  219. package/.output/public/_nuxt/CzOCSGLe.js +0 -1
  220. package/.output/public/_nuxt/D8qvkfyY.js +0 -1
  221. package/.output/public/_nuxt/DCn7QZ5N.js +0 -2
  222. package/.output/public/_nuxt/DS8qj8EL.js +0 -1
  223. package/.output/public/_nuxt/DUjW5Yq5.js +0 -1
  224. package/.output/public/_nuxt/Dihnimlk.js +0 -19
  225. package/.output/public/_nuxt/Dqw1lpr-.js +0 -1
  226. package/.output/public/_nuxt/Dr9v6C0f.js +0 -14
  227. package/.output/public/_nuxt/Du9ZJtnj.js +0 -1
  228. package/.output/public/_nuxt/OmpTerminalPanel.B_Pl5Ynm.css +0 -1
  229. package/.output/public/_nuxt/TownView.f-YOdXRs.css +0 -1
  230. package/.output/public/_nuxt/_id_.CM4bIgKY.css +0 -1
  231. package/.output/public/_nuxt/_id_.bNV69Dtf.css +0 -1
  232. package/.output/public/_nuxt/agents.ZD0rVdHE.css +0 -1
  233. package/.output/public/_nuxt/aml.BN8ZEW4h.css +0 -1
  234. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +0 -1
  235. package/.output/public/_nuxt/channel-templates.BOtahzPi.css +0 -1
  236. package/.output/public/_nuxt/daq.B0D3dPAc.css +0 -1
  237. package/.output/public/_nuxt/dcw.8Y7FqCVN.css +0 -1
  238. package/.output/public/_nuxt/pages.D7aSDlUI.css +0 -1
  239. package/.output/public/_nuxt/plugins.sb4nDGqr.css +0 -1
  240. package/.output/public/_nuxt/qr6R6Ha1.js +0 -1
  241. package/.output/public/_nuxt/settings.BTgR-NiE.css +0 -1
  242. package/.output/public/_nuxt/teams.CxnxKVVs.css +0 -1
  243. package/.output/public/_nuxt/tokens.BFY7qv4f.css +0 -1
  244. package/.output/public/_nuxt/workshop.CR_QzeAN.css +0 -1
  245. package/.output/server/chunks/build/_id_-BU1wfOID.mjs.map +0 -1
  246. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +0 -1
  247. package/.output/server/chunks/build/agents-CLQqJF2y.mjs.map +0 -1
  248. package/.output/server/chunks/build/aml-_7FdFL2p.mjs.map +0 -1
  249. package/.output/server/chunks/build/channel-templates-p6SZNjlM.mjs.map +0 -1
  250. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +0 -1
  251. package/.output/server/chunks/build/dcw-CoTxBlAZ.mjs.map +0 -1
  252. package/.output/server/chunks/build/pages-DFxjn9Xa.mjs.map +0 -1
  253. package/.output/server/chunks/build/plugins-lGlUr1lj.mjs.map +0 -1
  254. package/.output/server/chunks/build/settings-Ddd1qx2Z.mjs.map +0 -1
  255. package/.output/server/chunks/build/teams-MEDLZdMn.mjs.map +0 -1
  256. package/.output/server/chunks/build/tokens-C7fTM5C2.mjs.map +0 -1
  257. package/.output/server/chunks/build/town-qMPql9Se.mjs.map +0 -1
  258. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +0 -1
  259. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +0 -1
  260. package/.output/server/chunks/build/workshop-BL5bhfs0.mjs.map +0 -1
  261. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.continue.json +0 -1
  262. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.json +0 -1
  263. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/054bb4bc4e4217a2ab0b0c6b663747214a9af464f5568ea60e784704e340bb0f.source +0 -153
  264. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/0554197c3d2bac203a1f5c48a5d52495d1336db1bd7aa4f4c19875810363e684.source +0 -153
  265. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/05c203d12a954fffba942e1d626e3f5fec05b18a5aef2bac003b7884a4b77406.source +0 -431
  266. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/145a6e6ba811af35aed31e0cc3211f53706a14980fa069ee9e3c1591139f96f0.source +0 -180
  267. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/1ae0fb281f97899c025e368ca73f41349b01fb5f85b19e08d7ebccff49095ed5.source +0 -112
  268. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/20ee9967aa0541c516db7575bdd4a1a745939bc7016bd10d7635903113edb8ec.source +0 -227
  269. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/233751843aeba9d4c5263f275b8102de00443c06f286918cbd23e0b6729e01aa.source +0 -131
  270. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/263c2e05b425e5c322e60c6475279f963bab3a873eb521b21df7fec935a46597.source +0 -160
  271. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/2ac5eaac28eaaee2178c4b32014df8e732f9dd432a285a872f5b7f31c1395fa4.source +0 -157
  272. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/33a0db0d2d95d2c11d0720090458e5fba1425376f5ceb5b422d1d3471be3226b.source +0 -348
  273. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/359e474ae83db35e4615d3728de6bf694b64d4dce9b536730a3b6518f9c0494a.source +0 -296
  274. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/37a4c3c31c4b70f6b719c53d1e9c4fcba603f31adfdd11bb6ef9f0d094923c56.source +0 -285
  275. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/461feca1c14a695eb8b0f17a6f95fe97eeceabc0510faaea4ba6d25bde147d8d.source +0 -217
  276. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/4cfadbda8591f29d5e1e230dc000e701b756e850441b3900fb596a4d2f6e98c2.source +0 -301
  277. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/50ca2810cf0b248c96948994c0c404531bbad6e553166b6816b3b03bfa0f75d2.source +0 -151
  278. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/52d9e8cb591a9ae86e238c3620a610cd386717bee222c0f37b25b2ac7e523dc4.source +0 -135
  279. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/6c87daafa4c006560a954636a97333f6123153c9d34d96203f7ee3a14e556357.source +0 -156
  280. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/77bc47854b577900621cacf1697f81fa2bc005af129d37614a97a3441c08f99f.source +0 -72
  281. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/7bbb789d3a527817118cf8399ed1861d6a962ade10878fd07223435d333a7089.source +0 -469
  282. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/86b7c1daafc8b60ba9982dde5bf1bcc74265709483c176e71f23ec6fc267451f.source +0 -259
  283. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/8df66d62bd41984d0970e8236882080c5085ac937d07a29779463d6a03b37c76.source +0 -97
  284. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/9962f2d1b3a85137bd40cc835725600b39f89ee02a27c06b2e0402e1eafde115.source +0 -277
  285. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/a1090ea066b792cb201739f4994e37bf7c12f52e805239a1eab87f18a537f266.source +0 -171
  286. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/a5241091650134d0919897e086a606a3846c8b2b54f8b4c84a8696c145ac3e9e.source +0 -425
  287. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/af19fa4c6e34d5540028be4b17600161283af3a2a2dfc61a3fdc0834436a0c14.source +0 -99
  288. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/b3713d78e2b2f93905ff6be8d58a8d0a2f42dea322eb67c987fda22ff6a084d5.source +0 -325
  289. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/b3849943c3aff102d1af815631fc843a2a52c17646a4b04696ece323e483bbec.source +0 -332
  290. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/bac735a3803a6650b7f1eb8f587e6dc5c68ea055000c3c99a11789438b78e837.source +0 -43
  291. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/d32c24d61eb8b33c73e5a8fc7e4dc7ef437aed238ee4371c2b00617e6104090a.source +0 -154
  292. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/d5170dc9a9879fda04fdf91d8a110d4efb6787ee38dda596d4da899883d36a72.source +0 -531
  293. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/dc59bcd7bb397be63ba2f2c3fec23f3782dcb17d2d75a9981eeced761f33eb32.source +0 -439
  294. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/eb5ff8cf66b92aec7bf6726781d8df74faa2b030c3aaac17d6b00c1fc04c9b32.source +0 -323
  295. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f10615a6fae18436e70d1201b2d44fdae3174a3aa7bb4db97dea1b3ed291d721.source +0 -433
  296. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f36d3e271668bc1260c2823542d22dbf1d0f7041ff16b1ac175bce2256e582ca.source +0 -280
  297. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/f94449380af09f31ac352152007146a75cc80bae8d6411ffe57b2c56f933b0ff.source +0 -117
  298. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/fe4dfd81178fd6b648335f6405d9ede71319aebde796008e50db21f8adf44c99.source +0 -160
  299. package/scripts/.mimosa/hook-state/sess_aeaecb58-8833-4b83-b93c-050467d21e03.mtxwtxme-61028-1f4519fbc4.baseline/ffb4e3aa548cfdadabaa44ab599f9b6a3ca6288176a2cc7a4b2fc2a12b5fb848.source +0 -101
  300. package/scripts/.mimosa/hook-status/sess_aeaecb58-8833-4b83-b93c-050467d21e03-d944d71bb3.json +0 -14
  301. package/scripts/_dbg-audit-all-pages.mjs +0 -43
  302. package/scripts/_dbg-daq-frames-e2e.mjs +0 -118
  303. package/scripts/_dbg-daq-rowstyle-verify.mjs +0 -112
  304. package/scripts/_dbg-hitl-timeout-e2e.mjs +0 -93
  305. package/scripts/_dbg-live-line-e2e.mjs +0 -279
  306. package/scripts/_dbg-minimal-omp.mjs +0 -77
  307. package/scripts/_dbg-mode-nav.mjs +0 -173
  308. package/scripts/_dbg-real-scenario-timeline.log +0 -55
  309. package/scripts/_dbg-team-repro.mjs +0 -76
  310. package/scripts/_dbg-town-agents-probe.mjs +0 -60
  311. package/scripts/_dbg-visual-acceptance.mjs +0 -63
  312. package/scripts/_townview_style.css +0 -1185
  313. package/scripts/_townview_template.html +0 -1215
  314. package/server/data/agent-node-bindings.json +0 -554
  315. package/server/data/daq-templates.json +0 -16
  316. package/server/data/daqs.json +0 -7464
  317. package/server/data/dcw-lines.json +0 -1787
  318. package/server/data/dcw-products.json +0 -1626
  319. package/server/data/dcw-recipes.json +0 -4672
  320. package/server/data/dcw-rollback.json +0 -20754
  321. package/server/data/dcw-runs.json +0 -6354
  322. package/server/data/dcw-templates.json +0 -146
  323. package/server/data/dcw-writes.json +0 -15650
  324. package/server/data/dcws.json +0 -9033
  325. package/server/data/device-twins.json +0 -133
  326. package/server/data/line-runs.json +0 -322
  327. package/server/data/scene-layouts.json +0 -277
@@ -1,469 +0,0 @@
1
- /**
2
- * SchedulerLoop 调度循环测试(node + tsx 直跑,无浏览器)。
3
- *
4
- * 覆盖:
5
- * 1. 定时 tick:SUBMITTED 任务自动 dispatch 给 worker → worker 自动接取完成 → child-completed → 父任务完成(端到端)
6
- * 2. wake() 立即触发一轮(大 tickMs 下无定时 tick 仍能 dispatch)
7
- * 3. supervise 抛错 → 内置规则引擎兜底 dispatch
8
- * 4. stop() 后不再调度
9
- * 5. createAgentImpl 工厂(mock/claude/omp/未知 harness)
10
- *
11
- * 装配:真实 :memory: repo + 真实 TaskEngine + 真实 ChannelRuntime + 真实 Mailbox
12
- * + 真实 AgentRuntime(MockAgentImpl lead/worker)+ 真实 SchedulerLoop。
13
- */
14
- import { randomUUID } from 'node:crypto'
15
- import { openWorkshopDb } from '../server/services/workshop/db/database'
16
- import { createChannelRepo } from '../server/services/workshop/db/channel.repo'
17
- import { createAgentRepo } from '../server/services/workshop/db/agent.repo'
18
- import { createChannelAgentRepo } from '../server/services/workshop/db/channel-agent.repo'
19
- import { createTaskRepo } from '../server/services/workshop/db/task.repo'
20
- import type { TaskPatch } from '../server/services/workshop/db/task.repo'
21
- import { createMessageRepo } from '../server/services/workshop/db/message.repo'
22
- import { createSubscriptionRepo } from '../server/services/workshop/db/subscription.repo'
23
- import { TaskEngine } from '../server/services/workshop/runtime/task-engine'
24
- import type { WorkspaceTask } from '../server/services/workshop/types/task'
25
- import { ChannelRuntime } from '../server/services/workshop/runtime/channel-runtime'
26
- import { AgentRuntime } from '../server/services/workshop/runtime/agent-runtime'
27
- import type { ChannelBus } from '../server/services/workshop/runtime/agent-runtime'
28
- import { Mailbox, rowToMessage } from '../server/services/workshop/runtime/mailbox'
29
- import { SchedulerLoop } from '../server/services/workshop/runtime/scheduler-loop'
30
- import { MockAgentImpl } from '../server/services/workshop/agents/mock-agent'
31
- import { ClaudeSdkAgentImpl } from '../server/services/workshop/agents/claude-agent'
32
- import { createAgentImpl } from '../server/services/workshop/agents/factory'
33
- import { encodeTaskMode, type ModeConfig } from '../server/services/workshop/runtime/execution-mode'
34
- import type {
35
- AgentEvent,
36
- AgentInfo,
37
- AgentInterface,
38
- AgentWorkspace,
39
- SupervisionDecision,
40
- } from '../server/services/workshop/agents/agent-interface'
41
- import type { A2AMessage, ChannelMail } from '../server/services/workshop/types/a2a'
42
- import { AppError } from '../server/utils/errors'
43
-
44
- let failures = 0
45
- function check(name: string, ok: boolean, detail = ''): void {
46
- console.log(`${ok ? 'PASS' : 'FAIL'} ${name}${detail ? ` — ${detail}` : ''}`)
47
- if (!ok) failures += 1
48
- }
49
-
50
- function sleep(ms: number): Promise<void> {
51
- return new Promise(r => setTimeout(r, ms))
52
- }
53
-
54
- async function waitUntil(cond: () => boolean, timeoutMs = 5000): Promise<boolean> {
55
- const start = Date.now()
56
- for (;;) {
57
- if (cond()) return true
58
- if (Date.now() - start >= timeoutMs) return cond()
59
- await sleep(10)
60
- }
61
- }
62
-
63
- /** AgentRow(模板)与 ChannelAgentRow(实例)共有字段;实例 id 才是运行时身份 */
64
- type RowWithConfig = { id: string, name: string, harness: string, configJson: string }
65
-
66
- function rowToAgentInfo(row: RowWithConfig, channelId: string, role: 'lead' | 'worker'): AgentInfo {
67
- return {
68
- id: row.id,
69
- channelId,
70
- name: row.name,
71
- harness: row.harness,
72
- role,
73
- config: JSON.parse(row.configJson) as Record<string, unknown>,
74
- }
75
- }
76
-
77
- interface WorkspaceDeps {
78
- engine: TaskEngine
79
- cr: ChannelRuntime
80
- tasks: ReturnType<typeof createTaskRepo>
81
- messages: ReturnType<typeof createMessageRepo>
82
- }
83
-
84
- /** 进程内 AgentWorkspace(委托真实 TaskEngine/ChannelRuntime/repo,模拟 manager 的最小能力面) */
85
- function buildWorkspace(agent: AgentInfo, deps: WorkspaceDeps): AgentWorkspace {
86
- const { engine, cr, tasks, messages } = deps
87
- return {
88
- listAgents: async () => [],
89
- dispatchTask: async () => {
90
- throw new AppError(400, 'BAD_REQUEST', '测试 workspace 不使用 dispatchTask')
91
- },
92
- listTasks: async () => engine.list(agent.channelId),
93
- getTask: async (taskId) => {
94
- const task = engine.get(taskId)
95
- if (!task) throw new AppError(404, 'NOT_FOUND', `任务不存在: ${taskId}`)
96
- return task
97
- },
98
- reportTask: async ({ taskId, progress, artifact, message }) => {
99
- const task = engine.get(taskId)
100
- if (!task) throw new AppError(404, 'NOT_FOUND', `任务不存在: ${taskId}`)
101
- const patch: TaskPatch = {}
102
- if (progress !== undefined) patch.progress = progress
103
- if (artifact) patch.artifacts = [...task.artifacts, artifact]
104
- if (message) {
105
- patch.history = [
106
- ...task.history,
107
- { messageId: randomUUID(), contextId: task.channelId, role: 'ROLE_AGENT' as const, parts: [{ text: message }] },
108
- ]
109
- }
110
- tasks.update(taskId, patch)
111
- return engine.get(taskId)!
112
- },
113
- completeTask: async (taskId, artifacts) => {
114
- const completed = engine.complete(taskId, artifacts)
115
- if (completed.parentId) {
116
- engine.onChildCompleted(completed)
117
- const parent = engine.get(completed.parentId)
118
- if (parent) cr.getAgents().find(a => a.agentId === parent.assigneeId)?.wakeMailbox()
119
- }
120
- return completed
121
- },
122
- cancelTask: async taskId => engine.cancel(taskId, agent.id),
123
- myQueue: async () => engine.queueViewOf(agent.channelId, agent.id),
124
- queueOverview: async () => [],
125
- updateTask: async (taskId, patch) => engine.updateTask(taskId, patch, agent.id),
126
- reassignTask: async (taskId, toAgentId) => engine.reassign(taskId, toAgentId),
127
- sendMessage: async ({ toAgentId, parts, metadata }) => {
128
- const message: A2AMessage = {
129
- messageId: randomUUID(),
130
- contextId: agent.channelId,
131
- role: 'ROLE_AGENT',
132
- parts,
133
- metadata: { ...(metadata ?? {}), 'x-aw-target-agent': toAgentId, 'x-aw-from-agent': agent.id },
134
- }
135
- cr.route(message)
136
- return message
137
- },
138
- pollMailbox: async (limit = 100) =>
139
- messages.listPendingByChannelAgent(agent.channelId, agent.id).slice(0, limit).map(rowToMessage),
140
- listMail: async (opts) => {
141
- const limit = Math.max(1, Math.min(500, opts?.limit ?? 200))
142
- const rows = messages.listRecentByChannel(agent.channelId, limit)
143
- const mails: ChannelMail[] = rows.map(r => ({
144
- messageId: r.id,
145
- taskId: r.taskId,
146
- fromAgentId: r.fromAgentId,
147
- toAgentId: r.toAgentId,
148
- role: r.role as 'ROLE_USER' | 'ROLE_AGENT',
149
- parts: (JSON.parse(r.partsJson) ?? []) as ChannelMail['parts'],
150
- metadata: (JSON.parse(r.metadataJson) ?? {}) as Record<string, unknown>,
151
- state: r.state,
152
- createdAt: r.createdAt,
153
- consumedAt: r.consumedAt,
154
- }))
155
- return opts?.agentId
156
- ? mails.filter(m => m.fromAgentId === opts.agentId || m.toAgentId === opts.agentId)
157
- : mails
158
- },
159
- subscribe: async () => {},
160
- recallMemory: async () => [],
161
- saveMemory: async () => { throw new Error('unused') },
162
- }
163
- }
164
-
165
- interface Setup {
166
- engine: TaskEngine
167
- cr: ChannelRuntime
168
- lead: AgentRuntime
169
- worker: AgentRuntime
170
- channelId: string
171
- loop: SchedulerLoop
172
- }
173
-
174
- interface SetupOptions {
175
- tickMs?: number
176
- leadImpl?: AgentInterface
177
- workerImpl?: AgentInterface
178
- }
179
-
180
- function setup(opts: SetupOptions = {}): Setup {
181
- const db = openWorkshopDb(':memory:')
182
- const channels = createChannelRepo(db)
183
- const agents = createAgentRepo(db)
184
- const tasks = createTaskRepo(db)
185
- const messages = createMessageRepo(db)
186
- const subscriptions = createSubscriptionRepo(db)
187
- const engine = new TaskEngine({ tasks, messages })
188
- const channel = channels.create({ name: 'test-channel' })
189
-
190
- const channelAgents = createChannelAgentRepo(db)
191
- const leadRow = agents.create({ name: 'lead', harness: 'mock', config: { delayMs: 0 } })
192
- const workerRow = agents.create({ name: 'worker', harness: 'mock', config: { delayMs: 0 } })
193
- // 实例行(独立身份 id)才是运行时身份:lead 派发时 assignee 用的是实例 id
194
- const leadInst = channelAgents.create({ channelId: channel.id, templateId: leadRow.id, name: leadRow.name, harness: leadRow.harness, config: { delayMs: 0 }, role: 'lead' })
195
- const workerInst = channelAgents.create({ channelId: channel.id, templateId: workerRow.id, name: workerRow.name, harness: workerRow.harness, config: { delayMs: 0 }, role: 'worker' })
196
- const leadInfo = rowToAgentInfo(leadInst, channel.id, 'lead')
197
- const workerInfo = rowToAgentInfo(workerInst, channel.id, 'worker')
198
-
199
- const cr = new ChannelRuntime(channel.id, { taskEngine: engine, subscriptionRepo: subscriptions, channelAgents })
200
- const bus: ChannelBus = { emit: () => {}, onEvent: () => () => {}, notifyTask: () => {}, notifyAgent: () => {}, onAgentStatus: () => {}, onTaskEvent: () => {}, wakeScheduler: () => {} }
201
-
202
- const lead = new AgentRuntime(leadInfo, opts.leadImpl ?? new MockAgentImpl(leadInfo.config), {
203
- mailbox: new Mailbox(messages, leadInfo.channelId, leadInfo.id, () => cr.wakeScheduler()),
204
- taskEngine: engine,
205
- bus,
206
- workspace: buildWorkspace(leadInfo, { engine, cr, tasks, messages }),
207
- })
208
- const worker = new AgentRuntime(workerInfo, opts.workerImpl ?? new MockAgentImpl(workerInfo.config), {
209
- mailbox: new Mailbox(messages, workerInfo.channelId, workerInfo.id, () => cr.wakeScheduler()),
210
- taskEngine: engine,
211
- bus,
212
- workspace: buildWorkspace(workerInfo, { engine, cr, tasks, messages }),
213
- })
214
-
215
- cr.addAgent(lead)
216
- cr.addAgent(worker)
217
- lead.start()
218
- worker.start()
219
-
220
- const loop = new SchedulerLoop(cr, lead, { tickMs: opts.tickMs ?? 10 })
221
- cr.scheduler = loop
222
-
223
- return { engine, cr, lead, worker, channelId: channel.id, loop }
224
- }
225
-
226
- async function teardown(s: Setup): Promise<void> {
227
- s.loop.stop()
228
- await Promise.all([s.lead.stop(), s.worker.stop()])
229
- }
230
-
231
- function submitTask(s: Setup, title: string) {
232
- return s.engine.create({
233
- channelId: s.channelId,
234
- creatorId: '',
235
- assigneeId: s.lead.agentId,
236
- title,
237
- description: '统筹交付',
238
- })
239
- }
240
-
241
- /** 提交 loop 模式主任务(描述按 [mode:loop][interval:..][max:..] 编码,与 manager.submitChannelTask 同构) */
242
- function submitLoopTask(s: Setup, title: string, config: ModeConfig) {
243
- return s.engine.create({
244
- channelId: s.channelId,
245
- creatorId: '',
246
- assigneeId: s.lead.agentId,
247
- title,
248
- description: encodeTaskMode('loop', config, '循环测试任务'),
249
- })
250
- }
251
-
252
- /** 模拟 manager 的 loop 重提交回调:原样创建新一轮主任务(经调度循环 dispatch 给 worker) */
253
- function wireLoopResubmit(s: Setup): void {
254
- s.loop.setLoopResubmitCallback((title, description) => {
255
- s.engine.create({
256
- channelId: s.channelId,
257
- creatorId: '',
258
- assigneeId: s.lead.agentId,
259
- title,
260
- description,
261
- })
262
- })
263
- }
264
-
265
- // ===== 场景 =====
266
-
267
- async function testAutoDispatchAndComplete(): Promise<void> {
268
- console.log('\n--- 1. 定时 tick 自动 dispatch + worker 完成 + 父完成 ---')
269
- const s = setup({ tickMs: 10 })
270
- s.loop.start()
271
- const parent = submitTask(s, '主任务')
272
-
273
- const dispatched = await waitUntil(() =>
274
- s.engine.list(s.channelId).some(t => t.parentId === parent.id && t.assigneeId === s.worker.agentId),
275
- )
276
- check('定时 tick dispatch 子任务给 worker', dispatched)
277
-
278
- const completed = await waitUntil(() => s.engine.get(parent.id)?.state === 'COMPLETED')
279
- check('worker 完成子任务 → child-completed → 父任务完成', completed, `state=${s.engine.get(parent.id)?.state}`)
280
-
281
- const child = s.engine.list(s.channelId).find(t => t.parentId === parent.id)
282
- check('子任务 COMPLETED 且进度 100', child?.state === 'COMPLETED' && child?.progress === 100, `state=${child?.state} progress=${child?.progress}`)
283
-
284
- await teardown(s)
285
- }
286
-
287
- async function testWakeTriggersRound(): Promise<void> {
288
- console.log('\n--- 2. wake 立即触发一轮(大 tickMs,无定时 tick) ---')
289
- const s = setup({ tickMs: 100000 })
290
- s.loop.start()
291
- const parent = submitTask(s, '主任务')
292
- s.loop.wake()
293
-
294
- const dispatched = await waitUntil(
295
- () => s.engine.list(s.channelId).some(t => t.parentId === parent.id && t.assigneeId === s.worker.agentId),
296
- 2000,
297
- )
298
- check('wake 立即触发 dispatch(无定时 tick)', dispatched)
299
-
300
- await teardown(s)
301
- }
302
-
303
- class ThrowingSuperviseImpl implements AgentInterface {
304
- async* run(): AsyncIterable<AgentEvent> {
305
- // 无消息处理(lead 仅测试 supervise 抛错)
306
- }
307
-
308
- async supervise(): Promise<SupervisionDecision[]> {
309
- throw new Error('supervise boom')
310
- }
311
- }
312
-
313
- async function testSuperviseThrowFallsBackToRules(): Promise<void> {
314
- console.log('\n--- 3. supervise 抛错 → 规则引擎兜底 dispatch ---')
315
- const s = setup({ tickMs: 10, leadImpl: new ThrowingSuperviseImpl() })
316
- s.loop.start()
317
- const parent = submitTask(s, '主任务')
318
-
319
- const dispatched = await waitUntil(() =>
320
- s.engine.list(s.channelId).some(t => t.parentId === parent.id && t.assigneeId === s.worker.agentId),
321
- )
322
- check('supervise 抛错后规则引擎兜底 dispatch', dispatched)
323
-
324
- await teardown(s)
325
- }
326
-
327
- class FlakyWorkerImpl implements AgentInterface {
328
- private attempts = 0
329
- private readonly fallback = new MockAgentImpl({ delayMs: 100 })
330
-
331
- async* run(request: Parameters<NonNullable<AgentInterface['run']>>[0], ctx: Parameters<NonNullable<AgentInterface['run']>>[1]): AsyncIterable<AgentEvent> {
332
- if (request.message.metadata?.['x-aw-task-kind'] === 'assign' && ctx.role === 'worker' && this.attempts++ === 0) {
333
- yield { kind: 'error', error: { code: 'TEST_TRANSIENT', message: 'transient test failure' } }
334
- return
335
- }
336
- yield* this.fallback.run(request, ctx)
337
- }
338
- }
339
-
340
- async function testRetryKeepsParentAlive(): Promise<void> {
341
- console.log('\n--- 4. 可重试子任务失败时不提前取消父任务 ---')
342
- const s = setup({ tickMs: 10, workerImpl: new FlakyWorkerImpl() })
343
- s.loop.start()
344
- const parent = submitTask(s, '可重试主任务')
345
-
346
- const retried = await waitUntil(() => {
347
- const child = s.engine.list(s.channelId).find(t => t.parentId === parent.id)
348
- return child?.retryCount === 1
349
- })
350
- const retriedChild = s.engine.list(s.channelId).find(t => t.parentId === parent.id)
351
- check('失败子任务被重派', retried, `parent=${s.engine.get(parent.id)?.state}`)
352
- check(
353
- '重试期间父任务保持 WAITING',
354
- s.engine.get(parent.id)?.state === 'WAITING'
355
- && (retriedChild?.state === 'ASSIGNED' || retriedChild?.state === 'WORKING'),
356
- `parent=${s.engine.get(parent.id)?.state} child=${retriedChild?.state}`,
357
- )
358
-
359
- const completed = await waitUntil(() => s.engine.get(parent.id)?.state === 'COMPLETED')
360
- check('重试成功后父任务完成', completed, `state=${s.engine.get(parent.id)?.state}`)
361
-
362
- await teardown(s)
363
- }
364
-
365
- async function testStopStopsScheduling(): Promise<void> {
366
- console.log('\n--- 5. stop 后不再调度 ---')
367
- const s = setup({ tickMs: 10 })
368
- s.loop.start()
369
- const first = submitTask(s, '任务一')
370
- const firstDone = await waitUntil(() => s.engine.get(first.id)?.state === 'COMPLETED')
371
- check('stop 前任务完整完成', firstDone)
372
-
373
- s.loop.stop()
374
-
375
- const second = submitTask(s, '任务二')
376
- await sleep(200)
377
- const state = s.engine.get(second.id)?.state
378
- const hasChild = s.engine.list(s.channelId).some(t => t.parentId === second.id)
379
- check('stop 后新任务不再被 dispatch', state === 'SUBMITTED' && !hasChild, `state=${state} hasChild=${hasChild}`)
380
-
381
- await teardown(s)
382
- }
383
-
384
- async function testLoopIntervalAndMaxIterations(): Promise<void> {
385
- console.log('\n--- 6. loop 模式:间隔生效 + maxIterations 后停止 ---')
386
- const s = setup({ tickMs: 10 })
387
- wireLoopResubmit(s)
388
- s.loop.start()
389
-
390
- const title = '循环任务'
391
- const intervalMs = 300
392
- const maxIterations = 2
393
- const first = submitLoopTask(s, title, { intervalMs, maxIterations })
394
- // mock lead dispatch 的子任务会继承父任务标题,统计主任务需排除子任务(parentId 存在)
395
- const parents = (): WorkspaceTask[] =>
396
- s.engine.list(s.channelId).filter(t => t.title === title && !t.parentId)
397
-
398
- // 首轮执行完成(此时才开始等待间隔)
399
- await waitUntil(() => s.engine.get(first.id)?.state === 'COMPLETED')
400
- check('loop 首轮执行完成', s.engine.get(first.id)?.state === 'COMPLETED')
401
-
402
- // 间隔后重提交:出现第 2 轮主任务,且间隔 ≥ intervalMs(从首轮完成时刻起算)
403
- const firstDoneAt = Date.now()
404
- const resubmitted = await waitUntil(() => {
405
- const same = parents()
406
- return same.length >= 2 && same[1]!.state === 'COMPLETED'
407
- }, 5000)
408
- const waitMs = Date.now() - firstDoneAt
409
- check('间隔后重提交并完成第 2 轮', resubmitted, `主任务数=${parents().length}`)
410
- check('等待时长 ≥ 配置间隔', waitMs >= intervalMs, `wait=${waitMs}ms interval=${intervalMs}ms`)
411
-
412
- // 达到 maxIterations=2 后不再重提交:再等数个间隔,主任务数仍为 2
413
- await sleep(intervalMs * 3)
414
- const finalCount = parents().length
415
- check('达到 maxIterations 后停止重提交', finalCount === maxIterations, `主任务数=${finalCount}(期望 ${maxIterations})`)
416
-
417
- // 全部主任务均完成(无残留半截循环)
418
- const loopTasks = parents()
419
- check('所有轮次主任务均完成', loopTasks.every(t => t.state === 'COMPLETED'), loopTasks.map(t => t.state).join(','))
420
-
421
- await teardown(s)
422
- }
423
-
424
- function testFactory(): void {
425
- console.log('\n--- 6. createAgentImpl 工厂 ---')
426
- const mk = (harness: string): AgentInfo => ({
427
- id: randomUUID(),
428
- channelId: 'ch',
429
- name: 'a',
430
- harness,
431
- role: 'worker',
432
- config: {},
433
- })
434
-
435
- check('mock → MockAgentImpl 实例', createAgentImpl(mk('mock')) instanceof MockAgentImpl)
436
-
437
- check('claude → ClaudeSdkAgentImpl 实例', createAgentImpl(mk('claude')) instanceof ClaudeSdkAgentImpl)
438
-
439
- try {
440
- createAgentImpl(mk('unknown'))
441
- check('未知 harness 抛 UNKNOWN_HARNESS', false, '未抛异常')
442
- }
443
- catch (e) {
444
- const err = e as AppError
445
- check(
446
- '未知 harness 抛 UNKNOWN_HARNESS',
447
- err instanceof AppError && err.code === 'UNKNOWN_HARNESS' && err.status === 400,
448
- `code=${err?.code} status=${err?.status}`,
449
- )
450
- }
451
- }
452
-
453
- async function main(): Promise<void> {
454
- await testAutoDispatchAndComplete()
455
- await testWakeTriggersRound()
456
- await testSuperviseThrowFallsBackToRules()
457
- await testRetryKeepsParentAlive()
458
- await testStopStopsScheduling()
459
- await testLoopIntervalAndMaxIterations()
460
- testFactory()
461
-
462
- console.log(`\n${failures === 0 ? 'ALL PASS' : `${failures} FAILED`}`)
463
- process.exit(failures === 0 ? 0 : 1)
464
- }
465
-
466
- main().catch((e) => {
467
- console.error('测试异常:', e)
468
- process.exit(1)
469
- })