agentworkshop 0.7.33 → 0.7.37

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 (945) hide show
  1. package/.output/.AgentWorkShop/aml-python/aml_eval.py +171 -0
  2. package/.output/.AgentWorkShop/aml-python/amlkit.py +120 -0
  3. package/.output/.AgentWorkShop/aml-python/requirements.txt +7 -0
  4. package/.output/.AgentWorkShop/aml-python/train-example.py +92 -0
  5. package/.output/.AgentWorkShop/schema.json +2 -1
  6. package/.output/nitro.json +1 -1
  7. package/.output/public/_nuxt/{DLljr7g0.js → 45zuyAso.js} +1 -1
  8. package/.output/public/_nuxt/4sIEbgcl.js +42 -0
  9. package/.output/public/_nuxt/8NMOXZOV.js +1 -0
  10. package/.output/public/_nuxt/BCGafdXT.js +2 -0
  11. package/.output/public/_nuxt/BDNMzG2s2.js +1 -0
  12. package/.output/public/_nuxt/{C-mDhyEd.js → BDmh31hl.js} +1 -1
  13. package/.output/public/_nuxt/BFkgkW8u.js +4 -0
  14. package/.output/public/_nuxt/BG8sCcwx.js +14 -0
  15. package/.output/public/_nuxt/{D8CqF0yy.js → BHA40aHa.js} +1 -1
  16. package/.output/public/_nuxt/BJHKLJJU.js +1 -0
  17. package/.output/public/_nuxt/{DoTdlVVe2.js → BN6iuJEg2.js} +1 -1
  18. package/.output/public/_nuxt/BNT8gYU92.js +4 -0
  19. package/.output/public/_nuxt/BU83-NnX.js +106 -0
  20. package/.output/public/_nuxt/BYhEUx8t.js +17 -0
  21. package/.output/public/_nuxt/BzHEilTt.js +1 -0
  22. package/.output/public/_nuxt/{Ct-WOVr4.js → C3J6FYKa.js} +1 -1
  23. package/.output/public/_nuxt/C3gwHTz0.js +1 -0
  24. package/.output/public/_nuxt/C4DWUZ6d2.js +1 -0
  25. package/.output/public/_nuxt/C5gUkRwn.js +1 -0
  26. package/.output/public/_nuxt/CClOy-Hz2.js +1 -0
  27. package/.output/public/_nuxt/{CUXCQXjG.js → CM12FuB42.js} +1 -1
  28. package/.output/public/_nuxt/{BSCpFtzG.js → CSkxz2NX.js} +1 -1
  29. package/.output/public/_nuxt/CWoJjWmZ.js +1 -0
  30. package/.output/public/_nuxt/CY9LbPCI.js +1 -0
  31. package/.output/public/_nuxt/CYWVXZTS.js +7 -0
  32. package/.output/public/_nuxt/CZiw7sEV.js +1 -0
  33. package/.output/public/_nuxt/C_OLzD09.js +1 -0
  34. package/.output/public/_nuxt/C__m4EhR.js +1 -0
  35. package/.output/public/_nuxt/Cbq-mryP.js +1 -0
  36. package/.output/public/_nuxt/{C4OAdbVK2.js → Cc_9VzD42.js} +1 -1
  37. package/.output/public/_nuxt/{BASN8nZ0.js → CdPzkOMV.js} +1 -1
  38. package/.output/public/_nuxt/Cec0Ua3F.js +1 -0
  39. package/.output/public/_nuxt/{DYKVPzN-.js → CoNpEq5X.js} +1 -1
  40. package/.output/public/_nuxt/CojCTLKD.js +1 -0
  41. package/.output/public/_nuxt/{B7wL3pDk.js → Crod5z2f.js} +1 -1
  42. package/.output/public/_nuxt/CzlMDL5H.js +13 -0
  43. package/.output/public/_nuxt/{G0qIw7Gq2.js → D0ZBQrN_2.js} +1 -1
  44. package/.output/public/_nuxt/{Lp7Ll94I.js → D1YDxZpZ.js} +1 -1
  45. package/.output/public/_nuxt/{Bc0AmjfT.js → D20Yamr4.js} +1 -1
  46. package/.output/public/_nuxt/D6uzXueg.js +2 -0
  47. package/.output/public/_nuxt/D9Oidm5I.js +1 -0
  48. package/.output/public/_nuxt/DAe0h2MB.js +1 -0
  49. package/.output/public/_nuxt/DBHNsT1Y.js +23 -0
  50. package/.output/public/_nuxt/DDShH71m.js +1 -0
  51. package/.output/public/_nuxt/DDgJcSET.js +19 -0
  52. package/.output/public/_nuxt/DHFrCUxA2.js +13 -0
  53. package/.output/public/_nuxt/{BcrN7QEl2.js → DIaZ2PTo2.js} +1 -1
  54. package/.output/public/_nuxt/DPnwL14Y.js +1 -0
  55. package/.output/public/_nuxt/DR12_WCA.js +3 -0
  56. package/.output/public/_nuxt/{B9nXmjSB.js → DUrecWPx.js} +4 -4
  57. package/.output/public/_nuxt/DVsjtsvZ2.js +1 -0
  58. package/.output/public/_nuxt/DYr1VMiQ.js +6 -0
  59. package/.output/public/_nuxt/DZtm4l-P2.js +1 -0
  60. package/.output/public/_nuxt/DdD9mCHM.js +1 -0
  61. package/.output/public/_nuxt/DeJykBFf.js +9 -0
  62. package/.output/public/_nuxt/{DoMxCWN52.js → DeyBFhKH2.js} +1 -1
  63. package/.output/public/_nuxt/DkGQ7lnb2.js +1 -0
  64. package/.output/public/_nuxt/DmqknNvV.js +18 -0
  65. package/.output/public/_nuxt/DnUuIR83.js +1 -0
  66. package/.output/public/_nuxt/DrYV5i68.js +1 -0
  67. package/.output/public/_nuxt/{B5S_UyaC.js → DtYHUi5Z.js} +1 -1
  68. package/.output/public/_nuxt/Dz_Q3Lpw2.js +1 -0
  69. package/.output/public/_nuxt/DzbFpZRk.js +3 -0
  70. package/.output/public/_nuxt/HBLJ-wei.js +1 -0
  71. package/.output/public/_nuxt/JCoYF4IJ.js +31 -0
  72. package/.output/public/_nuxt/JTLM-kqr2.js +1 -0
  73. package/.output/public/_nuxt/{BeIfu4N3.js → KZQX7xoM.js} +2 -2
  74. package/.output/public/_nuxt/S_fVQwJK.js +1 -0
  75. package/.output/public/_nuxt/TownView.0oLiQgTC.css +1 -0
  76. package/.output/public/_nuxt/YnQxK3eG.js +1 -0
  77. package/.output/public/_nuxt/_id_.D-SYuyZb.css +1 -0
  78. package/.output/public/_nuxt/_id_.hma_BU6T.css +1 -0
  79. package/.output/public/_nuxt/_wsId_.B12v3PhY.css +1 -0
  80. package/.output/public/_nuxt/aLLjF2K-2.js +1 -0
  81. package/.output/public/_nuxt/aWWIh8YL.js +24 -0
  82. package/.output/public/_nuxt/ahgEJu2R.js +1 -0
  83. package/.output/public/_nuxt/aml.COEKNNqK.css +1 -0
  84. package/.output/public/_nuxt/builds/latest.json +1 -1
  85. package/.output/public/_nuxt/builds/meta/a66fdef7-dcfd-453b-b1f6-543c7dfd98d5.json +1 -0
  86. package/.output/public/_nuxt/daq.B3265ZDn.css +1 -0
  87. package/.output/public/_nuxt/dcw.DLYZqEhT.css +1 -0
  88. package/.output/public/_nuxt/default.DE_vT238.css +1 -0
  89. package/.output/public/_nuxt/entry.BB-Eeh-J.css +1 -0
  90. package/.output/public/_nuxt/jZsY8yYz.js +1 -0
  91. package/.output/public/_nuxt/logs.CqFyMrJw.css +1 -0
  92. package/.output/public/_nuxt/pages.ooEzrMm9.css +1 -0
  93. package/.output/public/_nuxt/pdk8jLGT.js +1 -0
  94. package/.output/public/_nuxt/plugins.5e5chZ67.css +1 -0
  95. package/.output/public/_nuxt/pz2JDAM7.js +2 -0
  96. package/.output/public/_nuxt/settings.Dm3M0RLy.css +1 -0
  97. package/.output/public/_nuxt/town.DKIAhKnx.css +1 -0
  98. package/.output/public/_nuxt/users.CXnP2E08.css +1 -0
  99. package/.output/public/_nuxt/vRTjoWqd.js +1 -0
  100. package/.output/public/_nuxt/workshop.Jk5HxWPE.css +1 -0
  101. package/.output/public/_nuxt/zIGh7R49.js +75 -0
  102. package/.output/public/_nuxt/zq5t1vyX.js +1 -0
  103. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  104. package/.output/server/chunks/_/entity.mjs +174 -0
  105. package/.output/server/chunks/_/entity.mjs.map +1 -0
  106. package/.output/server/chunks/_/env-manager.mjs +162 -0
  107. package/.output/server/chunks/_/env-manager.mjs.map +1 -0
  108. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  109. package/.output/server/chunks/_/nitro.mjs +1568 -1043
  110. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  111. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  112. package/.output/server/chunks/build/{TownView-BdHnAilw.mjs → TownView-jVazYOjN.mjs} +141 -141
  113. package/.output/server/chunks/build/{TownView-BdHnAilw.mjs.map → TownView-jVazYOjN.mjs.map} +1 -1
  114. package/.output/server/chunks/build/{_id_-Cb845FHR.mjs → _id_-CfVosNg3.mjs} +136 -136
  115. package/.output/server/chunks/build/{_id_-Cb845FHR.mjs.map → _id_-CfVosNg3.mjs.map} +1 -1
  116. package/.output/server/chunks/build/{_id_-fadFPl2i.mjs → _id_-Hwr4rZpr.mjs} +32 -32
  117. package/.output/server/chunks/build/{_id_-fadFPl2i.mjs.map → _id_-Hwr4rZpr.mjs.map} +1 -1
  118. package/.output/server/chunks/build/{_wsId_-CTZswnm5.mjs → _wsId_-BVg3bB77.mjs} +175 -165
  119. package/.output/server/chunks/build/{_wsId_-CTZswnm5.mjs.map → _wsId_-BVg3bB77.mjs.map} +1 -1
  120. package/.output/server/chunks/build/aml-BCSJCdX7.mjs +588 -0
  121. package/.output/server/chunks/build/aml-BCSJCdX7.mjs.map +1 -0
  122. package/.output/server/chunks/build/{daq-BvihjQyW.mjs → daq-C03Uu5UE.mjs} +108 -106
  123. package/.output/server/chunks/build/daq-C03Uu5UE.mjs.map +1 -0
  124. package/.output/server/chunks/build/{dcw-Ks2vJ4PF.mjs → dcw-6vEYVeje.mjs} +44 -44
  125. package/.output/server/chunks/build/{dcw-Ks2vJ4PF.mjs.map → dcw-6vEYVeje.mjs.map} +1 -1
  126. package/.output/server/chunks/build/{default-GgHt4O2R.mjs → default-hseyOqBT.mjs} +30 -27
  127. package/.output/server/chunks/build/{default-GgHt4O2R.mjs.map → default-hseyOqBT.mjs.map} +1 -1
  128. package/.output/server/chunks/build/{logs-CYBhkQwh.mjs → logs-B-xhuqln.mjs} +35 -35
  129. package/.output/server/chunks/build/{logs-CYBhkQwh.mjs.map → logs-B-xhuqln.mjs.map} +1 -1
  130. package/.output/server/chunks/build/{pages-C-6BRtv8.mjs → pages-BO7yZsXA.mjs} +18 -27
  131. package/.output/server/chunks/build/pages-BO7yZsXA.mjs.map +1 -0
  132. package/.output/server/chunks/build/{plugins-dZRegC7m.mjs → plugins-CUWmMdyt.mjs} +17 -17
  133. package/.output/server/chunks/build/{plugins-dZRegC7m.mjs.map → plugins-CUWmMdyt.mjs.map} +1 -1
  134. package/.output/server/chunks/build/{settings-CgDLkP3s.mjs → settings-DoQ2Oq3P.mjs} +43 -43
  135. package/.output/server/chunks/build/{settings-CgDLkP3s.mjs.map → settings-DoQ2Oq3P.mjs.map} +1 -1
  136. package/.output/server/chunks/build/{town-DJ-V5G9U.mjs → town-BOl6hs9B.mjs} +7 -7
  137. package/.output/server/chunks/build/{town-DJ-V5G9U.mjs.map → town-BOl6hs9B.mjs.map} +1 -1
  138. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs +1 -1
  139. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs +1 -1
  140. package/.output/server/chunks/build/{useWorkshopWs-CprkZEdq.mjs → useWorkshopWs-C_I7q9As.mjs} +110 -32
  141. package/.output/server/chunks/build/{useWorkshopWs-CprkZEdq.mjs.map → useWorkshopWs-C_I7q9As.mjs.map} +1 -1
  142. package/.output/server/chunks/build/{users-4nzxTjFT.mjs → users-fohSmF-J.mjs} +6 -6
  143. package/.output/server/chunks/build/{users-4nzxTjFT.mjs.map → users-fohSmF-J.mjs.map} +1 -1
  144. package/.output/server/chunks/build/{workshop-81xhz368.mjs → workshop-DX5-ldc4.mjs} +15 -15
  145. package/.output/server/chunks/build/{workshop-81xhz368.mjs.map → workshop-DX5-ldc4.mjs.map} +1 -1
  146. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs +21 -8
  147. package/.output/server/chunks/routes/api/workshop/agent-tools/index.post.mjs.map +1 -1
  148. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id/preview.get.mjs +1 -1
  149. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs +58 -0
  150. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.delete.mjs.map +1 -0
  151. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs +27 -6
  152. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.get.mjs.map +1 -1
  153. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs +49 -0
  154. package/.output/server/chunks/routes/api/workshop/aml/datasets/_id_.patch.mjs.map +1 -0
  155. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs +45 -0
  156. package/.output/server/chunks/routes/api/workshop/aml/entities/prune.post.mjs.map +1 -0
  157. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs +30 -0
  158. package/.output/server/chunks/routes/api/workshop/aml/env/recheck.post.mjs.map +1 -0
  159. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs +40 -0
  160. package/.output/server/chunks/routes/api/workshop/aml/env/uv.post.mjs.map +1 -0
  161. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs +42 -0
  162. package/.output/server/chunks/routes/api/workshop/aml/env/venv.post.mjs.map +1 -0
  163. package/.output/server/chunks/routes/api/workshop/aml/index.get.mjs +1 -1
  164. package/.output/server/chunks/routes/api/workshop/aml/index.post.mjs +1 -1
  165. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs +4 -22
  166. package/.output/server/chunks/routes/api/workshop/aml/index2.get.mjs.map +1 -1
  167. package/.output/server/chunks/routes/api/workshop/aml/index2.post.mjs +1 -1
  168. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs +4 -16
  169. package/.output/server/chunks/routes/api/workshop/aml/index3.get.mjs.map +1 -1
  170. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs +19 -34
  171. package/.output/server/chunks/routes/api/workshop/aml/index4.get.mjs.map +1 -1
  172. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs +41 -0
  173. package/.output/server/chunks/routes/api/workshop/aml/index5.get.mjs.map +1 -0
  174. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs +62 -0
  175. package/.output/server/chunks/routes/api/workshop/aml/index6.get.mjs.map +1 -0
  176. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/cancel.post.mjs +1 -1
  177. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/logs.get.mjs +1 -1
  178. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id/retry.post.mjs +1 -1
  179. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs +63 -0
  180. package/.output/server/chunks/routes/api/workshop/aml/jobs/_id_.delete.mjs.map +1 -0
  181. package/.output/server/chunks/routes/api/workshop/aml/models/_id/predict.post.mjs +1 -1
  182. package/.output/server/chunks/routes/api/workshop/aml/models/_id/promote.post.mjs +1 -1
  183. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs +54 -0
  184. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.delete.mjs.map +1 -0
  185. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs +46 -0
  186. package/.output/server/chunks/routes/api/workshop/aml/models/_id_.patch.mjs.map +1 -0
  187. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  188. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  189. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +2 -2
  190. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  191. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  192. package/.output/server/chunks/routes/api/workshop/channels/_id/index.put.mjs +1 -1
  193. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/workshop/channels/_id/terminals.get.mjs +1 -1
  195. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  196. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +4 -4
  197. package/.output/server/chunks/routes/api/workshop/daq/_id/bind.post.mjs +1 -1
  198. package/.output/server/chunks/routes/api/workshop/daq/_id/bindings.put.mjs +1 -1
  199. package/.output/server/chunks/routes/api/workshop/daq/_id/samples.get.mjs +1 -1
  200. package/.output/server/chunks/routes/api/workshop/daq/_id/test.post.mjs +1 -1
  201. package/.output/server/chunks/routes/api/workshop/daq/_id_.delete.mjs +1 -1
  202. package/.output/server/chunks/routes/api/workshop/daq/_id_.patch.mjs +1 -1
  203. package/.output/server/chunks/routes/api/workshop/daq/controller.post.mjs +1 -1
  204. package/.output/server/chunks/routes/api/workshop/daq/index.post.mjs +1 -1
  205. package/.output/server/chunks/routes/api/workshop/daq/infra/reconnect.post.mjs +1 -1
  206. package/.output/server/chunks/routes/api/workshop/daq/infra.get.mjs +1 -1
  207. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.delete.mjs +1 -1
  208. package/.output/server/chunks/routes/api/workshop/daq/templates/_key_.patch.mjs +1 -1
  209. package/.output/server/chunks/routes/api/workshop/daq/test-driver.post.mjs +1 -1
  210. package/.output/server/chunks/routes/api/workshop/dcw/_id/bind.post.mjs +1 -1
  211. package/.output/server/chunks/routes/api/workshop/dcw/_id/bindings.put.mjs +1 -1
  212. package/.output/server/chunks/routes/api/workshop/dcw/_id/param-ledger.get.mjs +1 -1
  213. package/.output/server/chunks/routes/api/workshop/dcw/_id/read.post.mjs +1 -1
  214. package/.output/server/chunks/routes/api/workshop/dcw/_id/test.post.mjs +1 -1
  215. package/.output/server/chunks/routes/api/workshop/dcw/_id/write.post.mjs +1 -1
  216. package/.output/server/chunks/routes/api/workshop/dcw/_id_.delete.mjs +1 -1
  217. package/.output/server/chunks/routes/api/workshop/dcw/_id_.patch.mjs +1 -1
  218. package/.output/server/chunks/routes/api/workshop/dcw/controller.post.mjs +1 -1
  219. package/.output/server/chunks/routes/api/workshop/dcw/index.get.mjs +1 -1
  220. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/workshop/dcw/index2.get.mjs +1 -1
  222. package/.output/server/chunks/routes/api/workshop/dcw/index2.post.mjs +1 -1
  223. package/.output/server/chunks/routes/api/workshop/dcw/index3.get.mjs +1 -1
  224. package/.output/server/chunks/routes/api/workshop/dcw/index3.post.mjs +1 -1
  225. package/.output/server/chunks/routes/api/workshop/dcw/index4.get.mjs +1 -1
  226. package/.output/server/chunks/routes/api/workshop/dcw/index4.post.mjs +1 -1
  227. package/.output/server/chunks/routes/api/workshop/dcw/index5.get.mjs +1 -1
  228. package/.output/server/chunks/routes/api/workshop/dcw/journal/node/_nodeId/rollback.post.mjs +1 -1
  229. package/.output/server/chunks/routes/api/workshop/dcw/line/query.get.mjs +1 -1
  230. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  231. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  232. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  233. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/judge.post.mjs +1 -1
  234. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/rollback.post.mjs +1 -1
  235. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id/series.get.mjs +1 -1
  236. package/.output/server/chunks/routes/api/workshop/dcw/optimizations/_id_.get.mjs +1 -1
  237. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.delete.mjs +1 -1
  238. package/.output/server/chunks/routes/api/workshop/dcw/products/_id_.patch.mjs +1 -1
  239. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/apply.post.mjs +1 -1
  240. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/mark-good.post.mjs +1 -1
  241. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id/rollback-good.post.mjs +1 -1
  242. package/.output/server/chunks/routes/api/workshop/dcw/recipes/_id_.delete.mjs +1 -1
  243. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/close.post.mjs +1 -1
  244. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/data.get.mjs +1 -1
  245. package/.output/server/chunks/routes/api/workshop/dcw/runs/_id/rollback.post.mjs +1 -1
  246. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  247. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  248. package/.output/server/chunks/routes/api/workshop/dcw/test-driver.post.mjs +1 -1
  249. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.delete.mjs +1 -1
  250. package/.output/server/chunks/routes/api/workshop/device-twins/_id_.patch.mjs +1 -1
  251. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  252. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  253. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  254. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  255. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  256. package/.output/server/chunks/routes/api/workshop/index2.get.mjs +12 -1
  257. package/.output/server/chunks/routes/api/workshop/index2.get.mjs.map +1 -1
  258. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  259. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +1 -1
  260. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +1 -1
  261. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +1 -1
  262. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +1 -1
  263. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +1 -1
  264. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  265. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  266. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  267. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  268. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  269. package/.output/server/chunks/routes/api/workshop/teams/_id/index.put.mjs +1 -1
  270. package/.output/server/chunks/routes/api/workshop/teams/_id/index2.get.mjs +1 -1
  271. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +2 -2
  272. package/.output/server/chunks/routes/renderer.mjs +2 -2
  273. package/.output/server/chunks/virtual/entry.mjs +103 -17
  274. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  275. package/.output/server/package.json +1 -1
  276. package/README-zh.md +578 -507
  277. package/README.md +125 -51
  278. package/app/assets/css/main.css +329 -22
  279. package/app/components/AppHeader.vue +5 -4
  280. package/app/components/AppSidebar.vue +5 -4
  281. package/app/components/AwChart.vue +17 -0
  282. package/app/components/workshop/AgentLanesView.vue +2 -2
  283. package/app/components/workshop/ChannelSessionList.vue +3 -3
  284. package/app/components/workshop/CommandPalette.vue +1 -2
  285. package/app/components/workshop/Composer.vue +4 -4
  286. package/app/components/workshop/DaqNodeRow.vue +20 -1
  287. package/app/components/workshop/EventBlock.vue +3 -3
  288. package/app/components/workshop/MentionHoverCard.vue +1 -1
  289. package/app/components/workshop/MultiChannelView.vue +1 -1
  290. package/app/components/workshop/TaskBoardView.vue +5 -5
  291. package/app/components/workshop/TranscriptTimeline.vue +3 -3
  292. package/app/components/workshop/blocks/ClusterRoute.vue +3 -3
  293. package/app/components/workshop/blocks/ClusterStream.vue +1 -1
  294. package/app/components/workshop/blocks/ClusterTool.vue +1 -1
  295. package/app/components/workshop/lanes/LaneBlocks.vue +5 -2
  296. package/app/components/workshop/town/TownView.vue +0 -7
  297. package/app/composables/workshop/useClusteredBlocks.ts +22 -3
  298. package/app/composables/workshop/useEscClose.ts +44 -0
  299. package/app/config/index.ts +2 -1
  300. package/app/layouts/default.vue +25 -8
  301. package/app/pages/aml/index.vue +626 -4
  302. package/app/pages/daq/[id].vue +1 -1
  303. package/app/pages/daq/index.vue +10 -12
  304. package/app/pages/dcw/[id].vue +2 -2
  305. package/app/pages/dcw/index.vue +7 -11
  306. package/app/pages/index.vue +24 -6
  307. package/app/pages/logs/index.vue +2 -6
  308. package/app/pages/plugins/index.vue +1 -1
  309. package/app/pages/settings.vue +2 -2
  310. package/app/pages/town.vue +0 -2
  311. package/app/pages/users.vue +1 -1
  312. package/app/pages/workshop/index.vue +2 -2
  313. package/app/plugins/esc-close.client.ts +31 -0
  314. package/app/stores/workshop/events.ts +186 -36
  315. package/bin/aw.mjs +7 -2
  316. package/cli/aw.mjs +19 -34
  317. package/cli/commands/build.mjs +18 -1
  318. package/cli/commands/config.mjs +2 -0
  319. package/cli/commands/plugin.mjs +45 -18
  320. package/cli/commands/register.mjs +6 -2
  321. package/cli/commands/status.mjs +2 -1
  322. package/cli/commands/update.mjs +1 -1
  323. package/cli/commands/version.mjs +1 -1
  324. package/cli/core/args.mjs +76 -4
  325. package/cli/core/help.mjs +3 -1
  326. package/cli/core/meta.mjs +38 -0
  327. package/cli/core/post-build.mjs +96 -0
  328. package/cli/core/registry.mjs +6 -3
  329. package/config.yml +28 -26
  330. package/docs/aml.md +99 -0
  331. package/docs/cli.en.md +445 -0
  332. package/docs/cli.md +410 -220
  333. package/docs/full-test-plan.md +174 -0
  334. package/docs/multi-harness-architecture.md +248 -0
  335. package/docs/plugins.en.md +534 -0
  336. package/docs/plugins.md +531 -179
  337. package/docs/sdk.en.md +922 -0
  338. package/docs/sdk.md +725 -129
  339. package/i18n/dicts/aml.json +43 -1
  340. package/i18n/locales/en.ts +1928 -1885
  341. package/i18n/locales/zh-CN.ts +1928 -1885
  342. package/nuxt.config.ts +27 -2
  343. package/package.json +164 -153
  344. package/scripts/.mimosa/hook-status/sess_aeaecb58-8833-4b83-b93c-050467d21e03-d944d71bb3.json +14 -0
  345. package/scripts/_audit/aml-layout-diag.mjs +83 -0
  346. package/scripts/_audit/bump-version.mjs +51 -0
  347. package/scripts/_audit/channel-inspect.mjs +49 -0
  348. package/scripts/_audit/cleanup-apply.mjs +89 -0
  349. package/scripts/_audit/cleanup-plan.mjs +82 -0
  350. package/scripts/_audit/contrast-check.mjs +43 -0
  351. package/scripts/_audit/dcw-unrecorded-write.ts +1 -1
  352. package/scripts/_audit/design-shots.mjs +145 -0
  353. package/scripts/_audit/docs-font-probe.mjs +68 -0
  354. package/scripts/_audit/docs-probe.mjs +107 -0
  355. package/scripts/_audit/docs-shots.mjs +171 -0
  356. package/scripts/_audit/docs-v3-verify.mjs +255 -0
  357. package/scripts/_audit/docs-vue-lint.mjs +81 -0
  358. package/scripts/_audit/docs-vue-lint2.mjs +91 -0
  359. package/scripts/_audit/exp-cost-scaling.mjs +4 -1
  360. package/scripts/_audit/exp-envelope-and-png.mjs +2 -1
  361. package/scripts/_audit/exp-sweep-fairness.mjs +4 -2
  362. package/scripts/_audit/fix-settings-count.mjs +57 -0
  363. package/scripts/_audit/glass-verify.mjs +155 -0
  364. package/scripts/_audit/hydration-diff.mjs +104 -0
  365. package/scripts/_audit/hydration-head.mjs +36 -0
  366. package/scripts/_audit/hydration-probe.mjs +59 -0
  367. package/scripts/_audit/lead-matrix-test.mjs +172 -0
  368. package/scripts/_audit/plc-agent-task.mjs +74 -0
  369. package/scripts/_audit/plc-clean-scenario.mjs +434 -0
  370. package/scripts/_audit/plc-clean-shots.mjs +161 -0
  371. package/scripts/_audit/plc-fc10-probe.mjs +30 -0
  372. package/scripts/_audit/probe-binding.mjs +114 -103
  373. package/scripts/_audit/review-fix-verify.mjs +158 -0
  374. package/scripts/_audit/seed-demo.mjs +165 -0
  375. package/scripts/_audit/town-focus-shot.mjs +129 -0
  376. package/scripts/_audit/town-reposition.mjs +85 -0
  377. package/scripts/_audit/ts-resolve-hook.mjs +57 -22
  378. package/scripts/_audit/verify-cleanup.mjs +67 -0
  379. package/scripts/_audit/verify-release-pack.mjs +82 -0
  380. package/scripts/_audit/watchdog-recovery-test.mjs +127 -0
  381. package/scripts/_dbg-audit-all-pages.mjs +43 -43
  382. package/scripts/_dbg-configroot-audit.mjs +84 -84
  383. package/scripts/_dbg-daq-intervals-func.mjs +94 -94
  384. package/scripts/_dbg-daq-rowstyle-verify.mjs +112 -112
  385. package/scripts/_dbg-groups-ui-verify.mjs +122 -122
  386. package/scripts/_dbg-harness-e2e.mjs +92 -92
  387. package/scripts/_dbg-harness-ui-e2e.py +97 -97
  388. package/scripts/_dbg-hitl-timeout-e2e.mjs +93 -93
  389. package/scripts/_dbg-multiharness-live-e2e.mjs +254 -254
  390. package/scripts/_dbg-opslog-agent-e2e.mjs +194 -191
  391. package/scripts/_dbg-opt-team-e2e.mjs +133 -133
  392. package/scripts/_dbg-recipe-e2e.mjs +176 -176
  393. package/scripts/_dbg-recipe-stale-e2e.mjs +135 -135
  394. package/scripts/_dbg-render-perf.mjs +142 -142
  395. package/scripts/_dbg-render-regression.mjs +130 -130
  396. package/scripts/_dbg-town-smoke.mjs +54 -54
  397. package/scripts/aw-start-smoke.mjs +27 -8
  398. package/scripts/check-docs-sync.mjs +367 -0
  399. package/scripts/e2e-full-closedloop.mjs +36 -18
  400. package/scripts/production-closed-loop-e2e.mjs +300 -300
  401. package/scripts/test-cli-exit.mjs +129 -21
  402. package/scripts/test-daq-frame-race.mjs +144 -96
  403. package/scripts/test-events-index.mjs +176 -0
  404. package/scripts/test-lru.mjs +34 -11
  405. package/scripts/test-memory-month-query.mjs +11 -3
  406. package/scripts/test-plugin-hardening.mjs +7 -2
  407. package/scripts/test-plugin-lifecycle.mjs +173 -0
  408. package/scripts/test-rollback-index.mjs +76 -18
  409. package/scripts/test-sdk-surface.mjs +6 -3
  410. package/sdk/client.mjs +16 -7
  411. package/sdk/context.mjs +21 -9
  412. package/sdk/examples/line-sentinel/client.mjs +13 -6
  413. package/sdk/examples/line-sentinel/index.mjs +5 -2
  414. package/sdk/examples/ops-notifier/client.mjs +3 -1
  415. package/sdk/examples/sample-insight/client.mjs +4 -2
  416. package/sdk/index.d.mts +133 -16
  417. package/sdk/index.mjs +3 -2
  418. package/sdk/lifecycle.mjs +8 -3
  419. package/server/api/workshop/agent-tools/bindings/index.post.ts +22 -7
  420. package/server/api/workshop/aml/datasets/[id].delete.ts +39 -0
  421. package/server/api/workshop/aml/datasets/[id].get.ts +31 -9
  422. package/server/api/workshop/aml/datasets/[id].patch.ts +30 -0
  423. package/server/api/workshop/aml/entities/index.get.ts +13 -0
  424. package/server/api/workshop/aml/entities/prune.post.ts +28 -0
  425. package/server/api/workshop/aml/env/index.get.ts +13 -0
  426. package/server/api/workshop/aml/env/recheck.post.ts +14 -0
  427. package/server/api/workshop/aml/env/uv.post.ts +21 -0
  428. package/server/api/workshop/aml/env/venv.post.ts +24 -0
  429. package/server/api/workshop/aml/index.get.ts +14 -1
  430. package/server/api/workshop/aml/jobs/[id].delete.ts +44 -0
  431. package/server/api/workshop/aml/models/[id].delete.ts +35 -0
  432. package/server/api/workshop/aml/models/[id].patch.ts +30 -0
  433. package/server/services/workshop/agents/agent-interface.ts +3 -0
  434. package/server/services/workshop/agents/base-agent.ts +9 -0
  435. package/server/services/workshop/agents/codex-agent.ts +743 -729
  436. package/server/services/workshop/agents/dsh-agent.ts +4 -7
  437. package/server/services/workshop/agents/opencode-agent.ts +5 -7
  438. package/server/services/workshop/aml/aml.repo.ts +18 -0
  439. package/server/services/workshop/aml/dataset-builder.ts +4 -0
  440. package/server/services/workshop/aml/entity.ts +365 -0
  441. package/server/services/workshop/aml/env-manager.ts +242 -0
  442. package/server/services/workshop/aml/job-orchestrator.ts +4 -15
  443. package/server/services/workshop/aml/model-registry.ts +6 -0
  444. package/server/services/workshop/aml/python-runtime.ts +396 -62
  445. package/server/services/workshop/aml/runtime.ts +95 -4
  446. package/server/services/workshop/daq/bus/mqtt.adapter.ts +3 -1
  447. package/server/services/workshop/daq/daq-controller.ts +95 -47
  448. package/server/services/workshop/daq/daq-node.repo.ts +0 -10
  449. package/server/services/workshop/daq/daq-runtime.ts +0 -5
  450. package/server/services/workshop/json-store.mjs +35 -2
  451. package/server/services/workshop/plugins/host.mjs +18 -12
  452. package/server/services/workshop/runtime/agent-runtime.ts +32 -3
  453. package/server/services/workshop/runtime/manager.ts +28 -1
  454. package/server/services/workshop/runtime/scheduler-loop.ts +10 -1
  455. package/server/services/workshop/settings.ts +2 -0
  456. package/shared/config/home.mjs +58 -0
  457. package/shared/config/schema.json +2 -1
  458. package/shared/lru.mjs +4 -1
  459. package/.output/public/_nuxt/-6OnbLFb.js +0 -1
  460. package/.output/public/_nuxt/-nb2uqVg.js +0 -1
  461. package/.output/public/_nuxt/4bHdIqEg.js +0 -18
  462. package/.output/public/_nuxt/6PZPfFcO.js +0 -17
  463. package/.output/public/_nuxt/BBBtwOpo.js +0 -9
  464. package/.output/public/_nuxt/BBwMH_hG.js +0 -7
  465. package/.output/public/_nuxt/BDUjyaF4.js +0 -42
  466. package/.output/public/_nuxt/BNXfwXpE.js +0 -1
  467. package/.output/public/_nuxt/BN_PdN3J.js +0 -24
  468. package/.output/public/_nuxt/BSSUlJnx2.js +0 -1
  469. package/.output/public/_nuxt/BWSE6hR6.js +0 -1
  470. package/.output/public/_nuxt/BZGNTgTQ2.js +0 -1
  471. package/.output/public/_nuxt/BZv4RFYN.js +0 -1
  472. package/.output/public/_nuxt/BcmbLh2z2.js +0 -1
  473. package/.output/public/_nuxt/BfGc7TJp.js +0 -1
  474. package/.output/public/_nuxt/BgTB6h_q.js +0 -2
  475. package/.output/public/_nuxt/BkLJA9J5.js +0 -1
  476. package/.output/public/_nuxt/Bp5luxkg2.js +0 -1
  477. package/.output/public/_nuxt/BuCHayqN.js +0 -1
  478. package/.output/public/_nuxt/BuvcLKh1.js +0 -19
  479. package/.output/public/_nuxt/C3tCneTM.js +0 -1
  480. package/.output/public/_nuxt/C77oC8yC2.js +0 -7
  481. package/.output/public/_nuxt/C9f8QMp12.js +0 -1
  482. package/.output/public/_nuxt/CKfhtOt7.js +0 -13
  483. package/.output/public/_nuxt/CQvmN-Mi.js +0 -1
  484. package/.output/public/_nuxt/CUDrOuW7.js +0 -1
  485. package/.output/public/_nuxt/CZcC-gpk.js +0 -1
  486. package/.output/public/_nuxt/CbzsPO5H.js +0 -1
  487. package/.output/public/_nuxt/CdSOrh2c.js +0 -1
  488. package/.output/public/_nuxt/Cgx818r-.js +0 -1
  489. package/.output/public/_nuxt/Cjm7VogC.js +0 -1
  490. package/.output/public/_nuxt/Cm5mDxzH.js +0 -1
  491. package/.output/public/_nuxt/CmHzfVc5.js +0 -3
  492. package/.output/public/_nuxt/Cn3J3NXR.js +0 -23
  493. package/.output/public/_nuxt/Cno6kYiO2.js +0 -1
  494. package/.output/public/_nuxt/Cp6z0RN7.js +0 -1
  495. package/.output/public/_nuxt/CwqIxJGj.js +0 -2
  496. package/.output/public/_nuxt/D-Ca4BGY.js +0 -70
  497. package/.output/public/_nuxt/D0fhp-Ga.js +0 -75
  498. package/.output/public/_nuxt/D1z7i2UP.js +0 -31
  499. package/.output/public/_nuxt/DIaTPH1M.js +0 -1
  500. package/.output/public/_nuxt/DTYBfjRY.js +0 -1
  501. package/.output/public/_nuxt/DXRZPxGs.js +0 -1
  502. package/.output/public/_nuxt/DZzGarBE2.js +0 -13
  503. package/.output/public/_nuxt/DaMCzQhv.js +0 -1
  504. package/.output/public/_nuxt/DoLasgPj2.js +0 -1
  505. package/.output/public/_nuxt/DpojD719.js +0 -1
  506. package/.output/public/_nuxt/DsVcWfyR.js +0 -1
  507. package/.output/public/_nuxt/DtBu71ev.js +0 -32
  508. package/.output/public/_nuxt/Dy-mxvXY2.js +0 -1
  509. package/.output/public/_nuxt/DzuC31-i.js +0 -2
  510. package/.output/public/_nuxt/FQri3dV3.js +0 -1
  511. package/.output/public/_nuxt/ORt9oDIy2.js +0 -1
  512. package/.output/public/_nuxt/TownView.CtskuMXS.css +0 -1
  513. package/.output/public/_nuxt/VLI2Zy4t.js +0 -5
  514. package/.output/public/_nuxt/_id_.MbzdFygI.css +0 -1
  515. package/.output/public/_nuxt/_id_.hRYo-EAB.css +0 -1
  516. package/.output/public/_nuxt/_wsId_.gXMEOYgX.css +0 -1
  517. package/.output/public/_nuxt/aml.WU_bh87J.css +0 -1
  518. package/.output/public/_nuxt/arUY5dyq2.js +0 -4
  519. package/.output/public/_nuxt/builds/meta/291ef3e6-fa6a-4dee-8f46-05da1aeab815.json +0 -1
  520. package/.output/public/_nuxt/daq.Bb6l44-O.css +0 -1
  521. package/.output/public/_nuxt/dcw.rXH2fc2Z.css +0 -1
  522. package/.output/public/_nuxt/default.jNT73_hq.css +0 -1
  523. package/.output/public/_nuxt/ekuGmQ7R.js +0 -1
  524. package/.output/public/_nuxt/entry.jFrFAWuA.css +0 -1
  525. package/.output/public/_nuxt/logs.DMOM-iHe.css +0 -1
  526. package/.output/public/_nuxt/niDwBOZW.js +0 -3
  527. package/.output/public/_nuxt/pMoIO6rr.js +0 -14
  528. package/.output/public/_nuxt/pages.Cc8GX9T1.css +0 -1
  529. package/.output/public/_nuxt/plugins.wIPyfPn-.css +0 -1
  530. package/.output/public/_nuxt/rqZ-1SoP.js +0 -2
  531. package/.output/public/_nuxt/settings.BCm4NZIc.css +0 -1
  532. package/.output/public/_nuxt/town.C_DsNW0J.css +0 -1
  533. package/.output/public/_nuxt/users.DuAt_Zwf.css +0 -1
  534. package/.output/public/_nuxt/vJ4FPb-_.js +0 -1
  535. package/.output/public/_nuxt/workshop.BJg84pOK.css +0 -1
  536. package/.output/server/chunks/build/aml-uBNIppIf.mjs +0 -508
  537. package/.output/server/chunks/build/aml-uBNIppIf.mjs.map +0 -1
  538. package/.output/server/chunks/build/daq-BvihjQyW.mjs.map +0 -1
  539. package/.output/server/chunks/build/pages-C-6BRtv8.mjs.map +0 -1
  540. package/scripts/_audit/.tmp/audit-data/dcws.json +0 -28
  541. package/scripts/_audit/.tmp/dcw-writes.json +0 -15650
  542. package/scripts/_audit/.tmp/dcws.json +0 -9033
  543. package/scripts/_audit/.tmp/pollution-backup/dcw-rollback.polluted.json +0 -470006
  544. package/scripts/_audit/.tmp/pollution-backup/dcws.polluted.json +0 -9085
  545. package/scripts/_audit/.tmp/probe-cwd.txt +0 -1
  546. package/scripts/_audit/awhome/commands/README.md +0 -3
  547. package/scripts/_audit/awhome/commands/hello.mjs +0 -12
  548. package/scripts/_audit/diag-cwd.ts +0 -20
  549. package/scripts/_audit/diag-cwd2.ts +0 -19
  550. package/scripts/_audit/hello.mjs +0 -12
  551. package/scripts/_audit/ndjson-partial-line-repro.mjs +0 -77
  552. package/scripts/_audit/opencode-await-ternary-repro.mjs +0 -20
  553. package/scripts/_audit/part-frag.txt +0 -84
  554. package/scripts/_audit/part-head.txt +0 -45
  555. package/scripts/_audit/probe-child.mjs +0 -17
  556. package/scripts/_audit/probe-envelope.mjs +0 -49
  557. package/scripts/_audit/probe-packlist.mjs +0 -67
  558. package/scripts/_audit/probe-routes.mjs +0 -47
  559. package/scripts/_audit/probe-routes2.mjs +0 -38
  560. package/scripts/_audit/probe.ts +0 -9
  561. package/scripts/_audit/probe2.ts +0 -6
  562. package/scripts/_audit/probe3.ts +0 -3
  563. package/scripts/_audit/probe4.ts +0 -3
  564. package/scripts/_audit/proj/.AgentWorkShop/commands/echoargs.mjs +0 -13
  565. package/scripts/_audit/proj/config.yml +0 -1
  566. package/scripts/_audit/run.mjs +0 -30
  567. package/scripts/_audit/tsconfig.probe.json +0 -24
  568. package/scripts/_audit/typecheck-out.txt +0 -466
  569. package/scripts/_daq-realtime-probe.mjs +0 -68
  570. package/scripts/_daq-warn-probe.mjs +0 -50
  571. package/scripts/_dbg-acc-1-setup.mjs +0 -57
  572. package/scripts/_dbg-acc-2-diag.mjs +0 -14
  573. package/scripts/_dbg-acc-2-intervals.mjs +0 -81
  574. package/scripts/_dbg-acc-3-daq.mjs +0 -48
  575. package/scripts/_dbg-acc-4-team.mjs +0 -92
  576. package/scripts/_dbg-acc-5-visual.mjs +0 -63
  577. package/scripts/_dbg-acc-5b-ws-town.mjs +0 -18
  578. package/scripts/_dbg-acc-5c-town.mjs +0 -12
  579. package/scripts/_dbg-acc-6-i18n.mjs +0 -19
  580. package/scripts/_dbg-agent-tools-audit.mjs +0 -154
  581. package/scripts/_dbg-agent-workflow-audit.mjs +0 -177
  582. package/scripts/_dbg-agents-dropdown-shot.py +0 -33
  583. package/scripts/_dbg-anim-verify.mjs +0 -81
  584. package/scripts/_dbg-app-shot.mjs +0 -48
  585. package/scripts/_dbg-autoframe.mjs +0 -103
  586. package/scripts/_dbg-availability-probe.ts +0 -11
  587. package/scripts/_dbg-beacon-final.mjs +0 -181
  588. package/scripts/_dbg-bind-bidi-e2e.mjs +0 -239
  589. package/scripts/_dbg-callout-near.mjs +0 -108
  590. package/scripts/_dbg-catalog-smoke.ts +0 -20
  591. package/scripts/_dbg-cf-line-shot.mjs +0 -18
  592. package/scripts/_dbg-chan-focus.mjs +0 -49
  593. package/scripts/_dbg-channel-plugin-ui.mjs +0 -94
  594. package/scripts/_dbg-cleanup.mjs +0 -31
  595. package/scripts/_dbg-closedloop-ui-shot.mjs +0 -61
  596. package/scripts/_dbg-codex-handshake.ts +0 -30
  597. package/scripts/_dbg-codex-probe.mjs +0 -58
  598. package/scripts/_dbg-codex-sandbox.ts +0 -58
  599. package/scripts/_dbg-codex-turn.ts +0 -65
  600. package/scripts/_dbg-collab-scenario-e2e.mjs +0 -185
  601. package/scripts/_dbg-config-smoke.ts +0 -28
  602. package/scripts/_dbg-console-audit.mjs +0 -61
  603. package/scripts/_dbg-console-probe.mjs +0 -23
  604. package/scripts/_dbg-context-inject-audit.mjs +0 -231
  605. package/scripts/_dbg-cpu-profile.mjs +0 -53
  606. package/scripts/_dbg-crash-recovery.mjs +0 -143
  607. package/scripts/_dbg-crop-shot.mjs +0 -16
  608. package/scripts/_dbg-cross-channel-e2e.mjs +0 -157
  609. package/scripts/_dbg-cross-team-visibility-e2e.mjs +0 -129
  610. package/scripts/_dbg-crush-probe.sh +0 -21
  611. package/scripts/_dbg-crush-spawn-probe.ts +0 -22
  612. package/scripts/_dbg-daq-acc-probe.mjs +0 -24
  613. package/scripts/_dbg-daq-attrib.mjs +0 -34
  614. package/scripts/_dbg-daq-bind-audit.mjs +0 -119
  615. package/scripts/_dbg-daq-cadence.mjs +0 -104
  616. package/scripts/_dbg-daq-debug.mjs +0 -22
  617. package/scripts/_dbg-daq-diag.mjs +0 -33
  618. package/scripts/_dbg-daq-e2e.mjs +0 -171
  619. package/scripts/_dbg-daq-film.mjs +0 -136
  620. package/scripts/_dbg-daq-filter-e2e.mjs +0 -109
  621. package/scripts/_dbg-daq-filter-e2e2.mjs +0 -62
  622. package/scripts/_dbg-daq-final-regression.mjs +0 -78
  623. package/scripts/_dbg-daq-frame-alarm.mjs +0 -49
  624. package/scripts/_dbg-daq-frame-ui.mjs +0 -62
  625. package/scripts/_dbg-daq-frame-ws.mjs +0 -72
  626. package/scripts/_dbg-daq-full-check.mjs +0 -179
  627. package/scripts/_dbg-daq-line-note-verify.mjs +0 -61
  628. package/scripts/_dbg-daq-linebanner-audit.mjs +0 -107
  629. package/scripts/_dbg-daq-pages-shot.mjs +0 -37
  630. package/scripts/_dbg-daq-perf.mjs +0 -61
  631. package/scripts/_dbg-daq-probe.mjs +0 -27
  632. package/scripts/_dbg-daq-recipe-e2e.mjs +0 -30
  633. package/scripts/_dbg-daq-redesign-shot.mjs +0 -88
  634. package/scripts/_dbg-daq-rows-probe.mjs +0 -26
  635. package/scripts/_dbg-daq-rowstate-e2e.mjs +0 -152
  636. package/scripts/_dbg-daq-rowstate-shot.mjs +0 -45
  637. package/scripts/_dbg-daq-rowstate-shot2.mjs +0 -38
  638. package/scripts/_dbg-daq-tpl.mjs +0 -144
  639. package/scripts/_dbg-dash-console-check.mjs +0 -49
  640. package/scripts/_dbg-dash-deep-probe.mjs +0 -61
  641. package/scripts/_dbg-dash-hitpoint.mjs +0 -44
  642. package/scripts/_dbg-dash-live-shot.mjs +0 -36
  643. package/scripts/_dbg-dash-shot.mjs +0 -21
  644. package/scripts/_dbg-dashboard-shot.mjs +0 -35
  645. package/scripts/_dbg-dcw-audit.mjs +0 -126
  646. package/scripts/_dbg-dcw-card-e2e.mjs +0 -108
  647. package/scripts/_dbg-dcw-channel-ui.mjs +0 -144
  648. package/scripts/_dbg-dcw-examples.mjs +0 -81
  649. package/scripts/_dbg-dcw-light-shot.mjs +0 -19
  650. package/scripts/_dbg-dcw-line-audit.mjs +0 -107
  651. package/scripts/_dbg-dcw-pause-tpl-audit.mjs +0 -161
  652. package/scripts/_dbg-dcw-pause-ui.mjs +0 -175
  653. package/scripts/_dbg-dcw-read-toolface.ts +0 -13
  654. package/scripts/_dbg-dcw-read-ui.mjs +0 -74
  655. package/scripts/_dbg-dcw-scene.mjs +0 -72
  656. package/scripts/_dbg-dcw-shot2.mjs +0 -14
  657. package/scripts/_dbg-dcw-twin-e2e.mjs +0 -192
  658. package/scripts/_dbg-diag-mock-loop.mjs +0 -89
  659. package/scripts/_dbg-diag-watch.mjs +0 -95
  660. package/scripts/_dbg-docs-site-shot.mjs +0 -32
  661. package/scripts/_dbg-dsh-probe.mjs +0 -31
  662. package/scripts/_dbg-dt-interact.mjs +0 -193
  663. package/scripts/_dbg-error-probe.mjs +0 -54
  664. package/scripts/_dbg-filter-light-verify.mjs +0 -54
  665. package/scripts/_dbg-final-acceptance-2.mjs +0 -72
  666. package/scripts/_dbg-final-acceptance.mjs +0 -192
  667. package/scripts/_dbg-final-agent-e2e.mjs +0 -151
  668. package/scripts/_dbg-final-features.mjs +0 -155
  669. package/scripts/_dbg-final-fixups.mjs +0 -62
  670. package/scripts/_dbg-final-full-e2e.mjs +0 -218
  671. package/scripts/_dbg-final-line-e2e.mjs +0 -173
  672. package/scripts/_dbg-final-shots.mjs +0 -32
  673. package/scripts/_dbg-final-t6-hitl.mjs +0 -38
  674. package/scripts/_dbg-final-visual.mjs +0 -29
  675. package/scripts/_dbg-fix-unused-imports.py +0 -41
  676. package/scripts/_dbg-focus-range.mjs +0 -115
  677. package/scripts/_dbg-fresh-scene-e2e.mjs +0 -125
  678. package/scripts/_dbg-fullchain-e2e.mjs +0 -178
  679. package/scripts/_dbg-gate-debug.mjs +0 -37
  680. package/scripts/_dbg-gif-encode.mjs +0 -111
  681. package/scripts/_dbg-gizmo.mjs +0 -95
  682. package/scripts/_dbg-glass-probe.mjs +0 -57
  683. package/scripts/_dbg-glass-shot.mjs +0 -50
  684. package/scripts/_dbg-glass-sweep.mjs +0 -25
  685. package/scripts/_dbg-glb-probe.mjs +0 -43
  686. package/scripts/_dbg-goose-probe.mjs +0 -33
  687. package/scripts/_dbg-goose-probe.sh +0 -10
  688. package/scripts/_dbg-hardening-probe.mjs +0 -90
  689. package/scripts/_dbg-harness-ui-dbg.py +0 -49
  690. package/scripts/_dbg-harness-ui-shot.py +0 -109
  691. package/scripts/_dbg-hero-btn-probe.mjs +0 -21
  692. package/scripts/_dbg-hidden-check.mjs +0 -21
  693. package/scripts/_dbg-hmi-audit.mjs +0 -164
  694. package/scripts/_dbg-home-repro.mjs +0 -24
  695. package/scripts/_dbg-home-stack.mjs +0 -13
  696. package/scripts/_dbg-host.mjs +0 -16
  697. package/scripts/_dbg-huashu-survey.mjs +0 -31
  698. package/scripts/_dbg-huashu-survey2.mjs +0 -35
  699. package/scripts/_dbg-huashu-verify.mjs +0 -25
  700. package/scripts/_dbg-huashu-verify2.mjs +0 -26
  701. package/scripts/_dbg-hydration-detail.mjs +0 -18
  702. package/scripts/_dbg-i18n-debug.mjs +0 -27
  703. package/scripts/_dbg-i18n-debug2.mjs +0 -26
  704. package/scripts/_dbg-i18n-final.mjs +0 -42
  705. package/scripts/_dbg-i18n-scan.mjs +0 -38
  706. package/scripts/_dbg-infra-lifecycle.mjs +0 -44
  707. package/scripts/_dbg-interval-config.mjs +0 -156
  708. package/scripts/_dbg-interval-scenario.mjs +0 -126
  709. package/scripts/_dbg-kicker-check.mjs +0 -11
  710. package/scripts/_dbg-line-aura-shots.mjs +0 -54
  711. package/scripts/_dbg-line-control-e2e.mjs +0 -120
  712. package/scripts/_dbg-line-gate-audit.mjs +0 -108
  713. package/scripts/_dbg-line-live-e2e.mjs +0 -144
  714. package/scripts/_dbg-line-repo-test.ts +0 -10
  715. package/scripts/_dbg-line-scenario-e2e.mjs +0 -256
  716. package/scripts/_dbg-line-spawn.ts +0 -31
  717. package/scripts/_dbg-live-engine-probe.mjs +0 -80
  718. package/scripts/_dbg-login-debug.py +0 -23
  719. package/scripts/_dbg-login-e2e.mjs +0 -26
  720. package/scripts/_dbg-logs-ui-e2e.py +0 -126
  721. package/scripts/_dbg-mcp-bridge-probe.mjs +0 -147
  722. package/scripts/_dbg-modbus-latency.mjs +0 -22
  723. package/scripts/_dbg-mqtt-chain-e2e.mjs +0 -90
  724. package/scripts/_dbg-mqtt-publisher.mjs +0 -17
  725. package/scripts/_dbg-nav-rpg.mjs +0 -84
  726. package/scripts/_dbg-nav-shot.mjs +0 -28
  727. package/scripts/_dbg-nav.mjs +0 -27
  728. package/scripts/_dbg-oneshot-impl-probe.ts +0 -67
  729. package/scripts/_dbg-opencode-sse.mjs +0 -101
  730. package/scripts/_dbg-opencode-start.ts +0 -57
  731. package/scripts/_dbg-opslog-e2e.mjs +0 -121
  732. package/scripts/_dbg-opslog-shots.mjs +0 -62
  733. package/scripts/_dbg-optimization-e2e.mjs +0 -94
  734. package/scripts/_dbg-orbit.mjs +0 -58
  735. package/scripts/_dbg-overview-probe.sh +0 -31
  736. package/scripts/_dbg-panesplitter-fix-check.mjs +0 -62
  737. package/scripts/_dbg-perms-visual.mjs +0 -36
  738. package/scripts/_dbg-pg-tcp-probe.cjs +0 -27
  739. package/scripts/_dbg-phase-e3-monitor.mjs +0 -25
  740. package/scripts/_dbg-pi-spawn-probe.ts +0 -33
  741. package/scripts/_dbg-plc-agent-loop.ts +0 -102
  742. package/scripts/_dbg-plc-e2e.mjs +0 -171
  743. package/scripts/_dbg-plugin-agent-read.ts +0 -56
  744. package/scripts/_dbg-plugin-config-ui.mjs +0 -111
  745. package/scripts/_dbg-plugin-matrix.mjs +0 -212
  746. package/scripts/_dbg-plugin-panels-ui.mjs +0 -54
  747. package/scripts/_dbg-plugin-sink-rest.mjs +0 -70
  748. package/scripts/_dbg-plugin-sink-ui.mjs +0 -81
  749. package/scripts/_dbg-plugin-tools-inject.ts +0 -80
  750. package/scripts/_dbg-plugin-ui-wizard.mjs +0 -125
  751. package/scripts/_dbg-plugin-verify-e2e.mjs +0 -123
  752. package/scripts/_dbg-plugins-e2e.mjs +0 -101
  753. package/scripts/_dbg-pop-clamp-verify.mjs +0 -77
  754. package/scripts/_dbg-preset-e2e.mjs +0 -116
  755. package/scripts/_dbg-preview-console.mjs +0 -28
  756. package/scripts/_dbg-preview-minrepro.mjs +0 -156
  757. package/scripts/_dbg-preview-pixels.mjs +0 -93
  758. package/scripts/_dbg-prompts-hotreload-test.ts +0 -76
  759. package/scripts/_dbg-prompts-resolve-test.ts +0 -39
  760. package/scripts/_dbg-quality-pages-e2e.mjs +0 -84
  761. package/scripts/_dbg-query-cancel.ts +0 -12
  762. package/scripts/_dbg-qwen-acp-probe.mjs +0 -30
  763. package/scripts/_dbg-qwen-capture.mjs +0 -21
  764. package/scripts/_dbg-rail-tree-e2e.mjs +0 -183
  765. package/scripts/_dbg-real-driver-e2e.mjs +0 -55
  766. package/scripts/_dbg-redesign-shots.mjs +0 -34
  767. package/scripts/_dbg-registry-smoke.ts +0 -14
  768. package/scripts/_dbg-release-smoke.mjs +0 -104
  769. package/scripts/_dbg-repo-setup-verify.mjs +0 -31
  770. package/scripts/_dbg-resolve-probe.ts +0 -6
  771. package/scripts/_dbg-restart-persist.mjs +0 -41
  772. package/scripts/_dbg-retention-test.ts +0 -25
  773. package/scripts/_dbg-rollback-mgr-audit.mjs +0 -169
  774. package/scripts/_dbg-rpg.mjs +0 -71
  775. package/scripts/_dbg-sc001-dispatch.mjs +0 -63
  776. package/scripts/_dbg-scenario-final-shot.mjs +0 -24
  777. package/scripts/_dbg-scenario-phase-e2.mjs +0 -75
  778. package/scripts/_dbg-scenario-phase-e3.mjs +0 -96
  779. package/scripts/_dbg-scenario-phase1.mjs +0 -90
  780. package/scripts/_dbg-scenario-phase2.mjs +0 -105
  781. package/scripts/_dbg-scenario-phase3-monitor.mjs +0 -48
  782. package/scripts/_dbg-scenario-phase3.mjs +0 -111
  783. package/scripts/_dbg-scene-polish-shot.mjs +0 -118
  784. package/scripts/_dbg-selring-probe.mjs +0 -47
  785. package/scripts/_dbg-settings-draft-probe.mjs +0 -39
  786. package/scripts/_dbg-settings-probe.mjs +0 -33
  787. package/scripts/_dbg-setup-e2e.mjs +0 -88
  788. package/scripts/_dbg-sideinfo.mjs +0 -101
  789. package/scripts/_dbg-sim-keeper.mjs +0 -100
  790. package/scripts/_dbg-splitter.mjs +0 -88
  791. package/scripts/_dbg-swatch-check.mjs +0 -10
  792. package/scripts/_dbg-task-cancel-probe.mjs +0 -66
  793. package/scripts/_dbg-team-drill.mjs +0 -173
  794. package/scripts/_dbg-town-alarm-e2e.mjs +0 -40
  795. package/scripts/_dbg-town-beauty-shots.mjs +0 -54
  796. package/scripts/_dbg-town-daq-shot.mjs +0 -26
  797. package/scripts/_dbg-town-full-e2e.mjs +0 -104
  798. package/scripts/_dbg-town-gate.mjs +0 -44
  799. package/scripts/_dbg-town-ins-probe.mjs +0 -37
  800. package/scripts/_dbg-town-perf.mjs +0 -50
  801. package/scripts/_dbg-town-polish-shots.mjs +0 -82
  802. package/scripts/_dbg-town-realtime.mjs +0 -42
  803. package/scripts/_dbg-town-shot.py +0 -25
  804. package/scripts/_dbg-town-shot3.mjs +0 -17
  805. package/scripts/_dbg-town-truth.mjs +0 -37
  806. package/scripts/_dbg-town-truth2.mjs +0 -27
  807. package/scripts/_dbg-transform-audit.mjs +0 -98
  808. package/scripts/_dbg-trend-expand-test.mjs +0 -38
  809. package/scripts/_dbg-twindaq-focus.mjs +0 -81
  810. package/scripts/_dbg-ui-polish-shot.mjs +0 -43
  811. package/scripts/_dbg-ui-polish-verify1.mjs +0 -92
  812. package/scripts/_dbg-ui-polish-verify2.mjs +0 -50
  813. package/scripts/_dbg-ui-polish-verify3.mjs +0 -51
  814. package/scripts/_dbg-ui-polish-verify4.mjs +0 -50
  815. package/scripts/_dbg-ui-shot.mjs +0 -26
  816. package/scripts/_dbg-ui-shots.mjs +0 -28
  817. package/scripts/_dbg-ui-survey.py +0 -52
  818. package/scripts/_dbg-unify-shot.mjs +0 -43
  819. package/scripts/_dbg-uplink-probe.mjs +0 -36
  820. package/scripts/_dbg-wizard-preview-shot.mjs +0 -58
  821. package/scripts/_dbg-wizard-ui-e2e.mjs +0 -93
  822. package/scripts/_dbg-ws-probe.mjs +0 -86
  823. package/scripts/_dbg-ws-shot2.mjs +0 -23
  824. package/scripts/_dbg-wsdot-sanity.mjs +0 -25
  825. package/scripts/_dev-stack.mjs +0 -46
  826. package/scripts/_http-driver-probe.mjs +0 -30
  827. package/scripts/_mqtt-driver-probe.mjs +0 -30
  828. package/scripts/_newdriver-rest-probe.mjs +0 -100
  829. package/scripts/_node-state-probe.mjs +0 -5
  830. package/scripts/_opcua-driver-probe.mjs +0 -31
  831. package/scripts/_rtu-debug.mjs +0 -41
  832. package/scripts/_rtu-direct.mjs +0 -6
  833. package/scripts/_rtu-driver-probe.mjs +0 -53
  834. package/scripts/_spike-pitui.mjs +0 -116
  835. package/scripts/_tmp-args-probe.mjs +0 -20
  836. package/scripts/_tmp-cyc-entry.mjs +0 -8
  837. package/scripts/_tmp-cyc-main.mjs +0 -5
  838. package/scripts/_tmp-cyc-mod.mjs +0 -2
  839. package/scripts/_tmp-cycle-a.mjs +0 -6
  840. package/scripts/_tmp-cycle-b.mjs +0 -2
  841. package/scripts/_tmp-cycle-probe.mjs +0 -4
  842. package/scripts/_tmp-entry-variant.mjs +0 -2
  843. package/scripts/_tmp-help-probe.mjs +0 -19
  844. package/scripts/_tmp-help-probe2.mjs +0 -2
  845. package/scripts/_tmp-trace-preload.mjs +0 -1
  846. package/scripts/_wizard-shots.mjs +0 -90
  847. package/scripts/acceptance-suite.py +0 -207
  848. package/scripts/aml-agent-bridge.ts +0 -230
  849. package/scripts/aml-industrial-loop.ts +0 -232
  850. package/scripts/build-film-devices.mjs +0 -227
  851. package/scripts/collab-live-test.py +0 -177
  852. package/scripts/debug-mcp-http.ts +0 -64
  853. package/scripts/demo-lead-worker.ts +0 -256
  854. package/scripts/demo-modes.ts +0 -415
  855. package/scripts/demo-omp-channel.ts +0 -135
  856. package/scripts/design-preflight.mjs +0 -223
  857. package/scripts/design-verify-templates.mjs +0 -110
  858. package/scripts/design-verify.mjs +0 -170
  859. package/scripts/dev-window.cmd +0 -6
  860. package/scripts/device-line-restore.mjs +0 -34
  861. package/scripts/diag-lead-status.ts +0 -101
  862. package/scripts/e2e-a2a-steer-live.mjs +0 -193
  863. package/scripts/e2e-dual-drive-comm.ts +0 -259
  864. package/scripts/e2e-full-scenario.ts +0 -321
  865. package/scripts/e2e-harness-consistency.ts +0 -204
  866. package/scripts/e2e-harness-provider-task.mjs +0 -126
  867. package/scripts/e2e-line-live.mjs +0 -144
  868. package/scripts/e2e-memory-persistence.ts +0 -320
  869. package/scripts/e2e-omp-modes.ts +0 -274
  870. package/scripts/e2e-omp-realtime.ts +0 -258
  871. package/scripts/e2e-plc-scenario.mjs +0 -292
  872. package/scripts/e2e-real-scenario.mjs +0 -466
  873. package/scripts/e2e-tab-close.mjs +0 -136
  874. package/scripts/e2e-token-ui.mjs +0 -149
  875. package/scripts/final-soup-run.py +0 -192
  876. package/scripts/final-soup-watch.py +0 -83
  877. package/scripts/i18n-codemod.mjs +0 -173
  878. package/scripts/i18n-fix-en.py +0 -28
  879. package/scripts/i18n-fix-en2.py +0 -31
  880. package/scripts/i18n-merge.mjs +0 -191
  881. package/scripts/migrate-local-time.mjs +0 -123
  882. package/scripts/omp-real-test.py +0 -328
  883. package/scripts/team-plugins-api-smoke.mjs +0 -149
  884. package/scripts/test-a2a-relay.mjs +0 -222
  885. package/scripts/test-aml-integration.ts +0 -159
  886. package/scripts/test-aml-job.ts +0 -174
  887. package/scripts/test-aml-unit.ts +0 -184
  888. package/scripts/test-api-client.ts +0 -108
  889. package/scripts/test-api-suite.mjs +0 -271
  890. package/scripts/test-block-consumption.mjs +0 -194
  891. package/scripts/test-cmd-render.mjs +0 -218
  892. package/scripts/test-collab-omp.mjs +0 -192
  893. package/scripts/test-config-precedence.ts +0 -124
  894. package/scripts/test-context-governor.ts +0 -176
  895. package/scripts/test-daq-frames.ts +0 -180
  896. package/scripts/test-daq-minio.ts +0 -77
  897. package/scripts/test-dedup-logic.ts +0 -132
  898. package/scripts/test-e2e-collaboration.ts +0 -262
  899. package/scripts/test-e2e-monitor.ts +0 -192
  900. package/scripts/test-event-history.ts +0 -112
  901. package/scripts/test-exec-modes.ts +0 -316
  902. package/scripts/test-fifo-realtime.mjs +0 -193
  903. package/scripts/test-final-e2e.mjs +0 -290
  904. package/scripts/test-goal-summary.ts +0 -202
  905. package/scripts/test-harness-liveness.ts +0 -109
  906. package/scripts/test-harness-terminal.ts +0 -164
  907. package/scripts/test-header-trail.mjs +0 -95
  908. package/scripts/test-hitl.ts +0 -360
  909. package/scripts/test-koda-restyle.mjs +0 -105
  910. package/scripts/test-lane-raw.ts +0 -67
  911. package/scripts/test-lanes-history-render.mjs +0 -138
  912. package/scripts/test-loop-omp.mjs +0 -154
  913. package/scripts/test-mdlite.ts +0 -53
  914. package/scripts/test-memory-brief-chronicle.ts +0 -180
  915. package/scripts/test-memory-rrf-mmr.ts +0 -114
  916. package/scripts/test-mock-collab.mjs +0 -226
  917. package/scripts/test-modern-render.mjs +0 -174
  918. package/scripts/test-omp-terminal.mjs +0 -187
  919. package/scripts/test-plugin-ext.ts +0 -173
  920. package/scripts/test-prompts-loader.ts +0 -56
  921. package/scripts/test-real-scenario.mjs +0 -290
  922. package/scripts/test-stream-render.ts +0 -37
  923. package/scripts/test-task-drawer.mjs +0 -204
  924. package/scripts/test-task-invariants.mjs +0 -169
  925. package/scripts/test-town-3d.mjs +0 -121
  926. package/scripts/test-town-layout.mjs +0 -200
  927. package/scripts/test-town-page.mjs +0 -136
  928. package/scripts/test-town-scene-math.ts +0 -169
  929. package/scripts/test-town-twin.mjs +0 -121
  930. package/scripts/test-town-upload.mjs +0 -89
  931. package/scripts/test-town-user-flow.mjs +0 -619
  932. package/scripts/test-town-world.mjs +0 -76
  933. package/scripts/test-town-wuwa.mjs +0 -198
  934. package/scripts/test-user-isolation.mjs +0 -193
  935. package/scripts/test-workshop-entries.ts +0 -370
  936. package/scripts/test-workspace-api.ts +0 -329
  937. package/scripts/test-ws-aep.mjs +0 -187
  938. package/scripts/test-ws-protocol.ts +0 -134
  939. package/scripts/town-demo-seed.mjs +0 -75
  940. package/scripts/town-scene-clear.mjs +0 -56
  941. package/scripts/verify-exec-modes-report.ts +0 -248
  942. package/scripts/verify-lead-mail.ts +0 -188
  943. package/scripts/verify-page-smoke.mjs +0 -87
  944. package/scripts/ws-test.mjs +0 -176
  945. package/scripts/ws-test.py +0 -4
@@ -1,729 +1,743 @@
1
- /**
2
- * CodexAgentImpl — OpenAI Codex CLI(app-server)harness 的 AgentInterface 实现。
3
- *
4
- * 进程模型:每 Agent 一个 `codex app-server` 子进程(stdio NDJSON JSON-RPC v2,
5
- * lazy spawn 跨消息复用);thread/start 建会话,turn/start 驱动回合。
6
- *
7
- * - prompt/工具面与 omp 全引擎同源(prompt-builder / host-tool-bridge);
8
- * 工具经 stdio MCP 桥注入(config.toml 由 impl 装配 [mcp_servers.aw])
9
- * - 事件映射:item/agentMessage/delta → delta;item/started → 🔧 status;
10
- * turn/completed → artifact + done / error(codexErrorInfo 结构化)
11
- * - HITL:item/commandExecution|fileChange/requestApproval(server→client 请求)
12
- * → hitl-registry 登记 → respondHitl 应答(decision: accept/decline/cancel)
13
- * - steer:turn 运行中 → turn/steer;无 active turn → 'deferred'
14
- * - 上下文治理:thread/tokenUsage/updated 被动跟踪;越阈值 → thread/compact/start
15
- *
16
- * 协议权威:github.com/openai/codex codex-rs/app-server/README.md(v0.149 实测)。
17
- */
18
- import { createLogger } from '../logger'
19
- import { randomUUID } from 'node:crypto'
20
- import { join } from 'node:path'
21
- import { mkdirSync, writeFileSync, existsSync, readFileSync, copyFileSync } from 'node:fs'
22
- import { tmpdir } from 'node:os'
23
- import type { AgentEvent, AgentInterface, AgentInfo, AgentRunContext, AgentRunRequest } from './agent-interface'
24
- import type { AgentContextStats } from '../types/task'
25
- import { registerHarnessProcess, bindHarnessProcess, markHarnessProcessExit, killHarnessProcess } from './harness-process'
26
- import { peerPrompt, systemManual, toolArgsPreview, workerPrompt } from './prompt-builder'
27
- import { getHitlRegistry } from './hitl-registry'
28
- import { harnessSettings } from '../settings'
29
- import { StdioJsonRpcClient } from './adapters/stdio-jsonrpc'
30
- import { BaseAgentImpl } from './base-agent'
31
- import { generateMcpBridgeEnv } from './harness-env'
32
-
33
- const log = createLogger('workshop.codex')
34
-
35
- export interface CodexAgentConfig {
36
- /** codex 可执行文件(默认取 harness.codex_command 设置) */
37
- command?: string
38
- /** 额外 CLI 参数(app-server 之前) */
39
- args?: string[]
40
- cwd?: string
41
- /** 模型(如 gpt-5.2) */
42
- model?: string
43
- /** 审批策略(默认 on-request:沙箱内自由,越界请求审批 → HITL) */
44
- approvalPolicy?: 'untrusted' | 'on-request' | 'never'
45
- /** 沙箱(默认 workspace-write) */
46
- sandbox?: 'read-only' | 'workspace-write' | 'danger-full-access'
47
- /** CODEX_HOME(缺省进程环境;配置隔离/多账户时按 agent 指定;effort 未指定 home 时自动种子化) */
48
- codexHome?: string
49
- /** 思考 effort(model_reasoning_effort;需 CODEX_HOME 配置面,未指定 home 时自动种子化) */
50
- effort?: string
51
- /** 上下文窗口(usage 百分比计算) */
52
- contextWindow?: number
53
- /** 压缩阈值(0-1,默认 0.7) */
54
- compactThreshold?: number
55
- promptTimeoutMs?: number
56
- superviseTimeoutMs?: number
57
- systemPromptPrefix?: string
58
- scenarioPrompt?: string
59
- agentId?: string
60
- name?: string
61
- role?: 'lead' | 'worker'
62
- channelId?: string
63
- token?: string
64
- baseUrl?: string
65
- mcpBridgePath?: string
66
- }
67
-
68
- export class CodexAgentImpl extends BaseAgentImpl implements AgentInterface {
69
- private readonly config: CodexAgentConfig
70
- private agentInfo: AgentInfo | null = null
71
- private readonly bridgeCtx = {
72
- identity: { agentId: '', channelId: '', role: 'worker' as 'lead' | 'worker', name: 'agent' },
73
- state: this.toolState,
74
- getWorkspace: () => this.workspace,
75
- }
76
-
77
- private agentRole: 'lead' | 'worker' = 'worker'
78
-
79
- private client: StdioJsonRpcClient | null = null
80
- private clientStarting: Promise<void> | null = null
81
- private threadId: string | null = null
82
- private turnId: string | null = null
83
-
84
- // 回合状态
85
- private turnActive = false
86
- private deltaBuf = ''
87
- private deltaTimer: ReturnType<typeof setTimeout> | null = null
88
- private lastUsage: { input: number, at: number } | null = null
89
- private compacting = false
90
- private lastCompactAt = 0
91
- /** 待应答审批(approval request id → JSON-RPC id) */
92
- private pendingApprovals = new Map<string, { rpcId: string | number, timer: ReturnType<typeof setTimeout> | null }>()
93
-
94
- constructor(config: Record<string, unknown> = {}) {
95
- super({
96
- agentId: typeof config.agentId === 'string' ? config.agentId : '',
97
- name: typeof config.name === 'string' ? config.name : undefined,
98
- role: config.role === 'lead' ? 'lead' : 'worker',
99
- channelId: typeof config.channelId === 'string' ? config.channelId : '',
100
- })
101
- this.config = config as CodexAgentConfig
102
- }
103
-
104
- protected get harnessId(): string {
105
- return 'codex'
106
- }
107
-
108
- protected configRecord(): Record<string, unknown> {
109
- return this.config
110
- }
111
-
112
- async dispose(): Promise<void> {
113
- const client = this.client
114
- this.client = null
115
- this.threadId = null
116
- if (client) {
117
- const pid = client.pid
118
- await client.dispose().catch(() => {})
119
- if (pid) markHarnessProcessExit(pid, null)
120
- }
121
- for (const [id, p] of this.pendingApprovals) {
122
- if (p.timer) clearTimeout(p.timer)
123
- this.pendingApprovals.delete(id)
124
- }
125
- }
126
-
127
- getProcessInfo(): { pid: number, alive: boolean, command: string } | null {
128
- const client = this.client
129
- const pid = client?.pid
130
- if (!pid || !client) return null
131
- return { pid, alive: client.alive, command: 'codex app-server' }
132
- }
133
-
134
- killProcess(): void {
135
- const pid = this.client?.pid
136
- if (pid) killHarnessProcess(pid)
137
- else this.client?.kill()
138
- }
139
-
140
- reconcileProcess(): void {
141
- this.client?.reconcile()
142
- }
143
-
144
- getContextStats(): AgentContextStats | null {
145
- if (!this.lastUsage) return null
146
- const window = this.config.contextWindow ?? null
147
- return {
148
- usedTokens: this.lastUsage.input,
149
- contextWindow: window,
150
- percent: window && window > 0 ? Math.min(1, this.lastUsage.input / window) : null,
151
- compacting: this.compacting,
152
- }
153
- }
154
-
155
- /** 实时注入:turn 运行中 → turn/steer;否则 'deferred'(消息保持 pending) */
156
- async steer(text: string): Promise<'steer' | 'deferred'> {
157
- const client = this.client
158
- if (!client?.alive || !this.threadId || !this.turnActive) return 'deferred'
159
- try {
160
- await client.request('turn/steer', {
161
- threadId: this.threadId,
162
- input: [{ type: 'text', text }],
163
- }, 15_000)
164
- return 'steer'
165
- }
166
- catch {
167
- // 无 active turn / 引擎拒绝 → 消息保持 pending 由消费循环处理
168
- return 'deferred'
169
- }
170
- }
171
-
172
- /** HITL 应答:审批请求 → JSON-RPC 应答(decision) */
173
- async respondHitl(kind: string, id: string, outcome: {
174
- confirmed?: boolean
175
- cancelled?: boolean
176
- value?: string
177
- response?: string
178
- comment?: string
179
- }): Promise<void> {
180
- if (kind !== 'codex-approval') return
181
- const pending = this.pendingApprovals.get(id)
182
- if (!pending) throw new Error(`待办不存在或已处理: ${id}`)
183
- const client = this.client
184
- if (!client) throw new Error('codex 会话已关闭')
185
- const decision = outcome.cancelled === true
186
- ? 'cancel'
187
- : outcome.confirmed === true ? 'accept' : 'decline'
188
- client.respond(pending.rpcId, { decision })
189
- if (pending.timer) clearTimeout(pending.timer)
190
- this.pendingApprovals.delete(id)
191
- getHitlRegistry().resolve(kind, id, decision === 'cancel' ? 'cancelled' : 'answered')
192
- }
193
-
194
- /** 上下文治理(post-settle):越阈值 → thread/compact/start */
195
- async onTurnSettled(): Promise<void> {
196
- const client = this.client
197
- if (!client?.alive || !this.threadId || this.compacting) return
198
- const stats = this.getContextStats()
199
- const threshold = this.config.compactThreshold ?? 0.7
200
- if (!stats?.percent || stats.percent < threshold) return
201
- if (Date.now() - this.lastCompactAt < 5 * 60_000) return
202
- this.compacting = true
203
- this.lastCompactAt = Date.now()
204
- try {
205
- await client.request('thread/compact/start', { threadId: this.threadId }, 30_000)
206
- log.info(`[CodexAgent:${this.selfAgentId}] 上下文压缩已触发(percent=${(stats.percent * 100).toFixed(0)}%)`)
207
- }
208
- catch (err) {
209
- log.warn(`[CodexAgent:${this.selfAgentId}] compact 发起失败(放行):`, err instanceof Error ? err.message : err)
210
- }
211
- finally {
212
- this.compacting = false
213
- }
214
- }
215
-
216
- protected async* workerTurn(request: AgentRunRequest, ctx: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown> {
217
- const taskId = request.taskId ?? (request.message.metadata?.['x-aw-task-id'] as string | undefined)
218
- if (!taskId) return
219
- this.toolState.currentTaskId = taskId
220
- try {
221
- await this.ensureClient(ctx)
222
- const taskText = request.message.parts.map((p) => {
223
- if ('text' in p) return p.text
224
- if ('data' in p) return JSON.stringify(p.data)
225
- if ('url' in p) return p.url
226
- if ('raw' in p) return p.raw
227
- return ''
228
- }).join('\n')
229
- const prompt = workerPrompt({
230
- agentName: this.agentName,
231
- channelId: this.channelId,
232
- taskId,
233
- taskText,
234
- memory: request.memory,
235
- ctxPrefix: await this.contextPrefix(),
236
- manual: systemManual(),
237
- })
238
- yield* this.streamTurn(prompt, taskId, this.config.promptTimeoutMs ?? 600_000, ctx.signal)
239
- }
240
- finally {
241
- this.toolState.currentTaskId = null
242
- }
243
- }
244
-
245
- protected async* peerTurn(request: AgentRunRequest, ctx: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown> {
246
- await this.ensureClient(ctx)
247
- const msg = request.message
248
- const fromId = request.fromAgentId
249
- ?? (typeof msg.metadata?.['x-aw-from-label'] === 'string' ? msg.metadata['x-aw-from-label'] : undefined)
250
- ?? 'unknown'
251
- const requireReply = msg.metadata?.['x-aw-require-reply'] === 'true'
252
- const crossChannel = msg.metadata?.['x-aw-cross-channel'] === 'true'
253
- this.toolState.replyContext = requireReply && request.fromAgentId && !crossChannel
254
- ? { fromId: request.fromAgentId, messageId: msg.messageId }
255
- : null
256
- const msgText = msg.parts.map((p) => {
257
- if ('text' in p) return p.text
258
- if ('data' in p) return JSON.stringify(p.data)
259
- if ('url' in p) return p.url
260
- if ('raw' in p) return p.raw
261
- return ''
262
- }).join('\n')
263
- const prompt = peerPrompt({
264
- agentName: this.agentName,
265
- role: this.agentRole,
266
- channelId: this.channelId,
267
- ctxPrefix: await this.contextPrefix(),
268
- manual: systemManual(),
269
- memory: request.memory,
270
- fromId,
271
- messageId: msg.messageId,
272
- requireReply,
273
- isReply: typeof msg.metadata?.['x-aw-in-reply-to'] === 'string',
274
- crossChannel,
275
- fromChannel: typeof msg.metadata?.['x-aw-from-channel'] === 'string' ? String(msg.metadata['x-aw-from-channel']) : '',
276
- msgText,
277
- })
278
- yield* this.streamTurn(prompt, undefined, this.config.promptTimeoutMs ?? 600_000, ctx.signal)
279
- }
280
-
281
- // ===== 回合执行 =====
282
-
283
- /**
284
- * 流式回合:turn/start → 逐事件产出(delta/status)→ turn/completed 收口。
285
- * artifact 在 done 前注入(item/completed agentMessage 聚合文本)。
286
- */
287
- private async* streamTurn(prompt: string, taskId: string | undefined, timeoutMs: number, signal?: AbortSignal): AsyncGenerator<AgentEvent, void, unknown> {
288
- const client = this.client
289
- if (!client || !this.threadId) {
290
- yield { kind: 'error', error: { code: 'CODEX_NOT_READY', message: 'codex 会话未就绪' } }
291
- return
292
- }
293
- const queue: AgentEvent[] = []
294
- let isDone = false
295
- let resolveWait: (() => void) | null = null
296
- let lastActivity = Date.now()
297
- let agentText = ''
298
- this.turnActive = true
299
- this.turnId = null
300
-
301
- const enqueue = (e: AgentEvent): void => {
302
- if (e.kind === 'done' && !isDone) {
303
- if (agentText.trim()) {
304
- queue.push({
305
- kind: 'artifact',
306
- artifact: { artifactId: randomUUID(), name: 'output', parts: [{ text: agentText.trim() }] },
307
- lastChunk: true,
308
- totalChunks: 1,
309
- })
310
- }
311
- this.turnActive = false
312
- }
313
- if (e.kind === 'done' || e.kind === 'error') {
314
- isDone = true
315
- this.turnActive = false
316
- flushDelta()
317
- }
318
- queue.push(e)
319
- lastActivity = Date.now()
320
- resolveWait?.()
321
- resolveWait = null
322
- }
323
-
324
- const flushDelta = (): void => {
325
- if (this.deltaTimer) {
326
- clearTimeout(this.deltaTimer)
327
- this.deltaTimer = null
328
- }
329
- if (!this.deltaBuf) return
330
- const text = this.deltaBuf
331
- this.deltaBuf = ''
332
- queue.push({ kind: 'delta', delta: { text } })
333
- }
334
- const pushDelta = (text: string): void => {
335
- this.deltaBuf += text
336
- this.deltaTimer ??= setTimeout(() => {
337
- this.deltaTimer = null
338
- flushDelta()
339
- }, 50)
340
- }
341
-
342
- // 通知订阅(审批请求处理器已在 startClient 挂接,此处只处理回合通知)
343
- const unsub = client.onNotification((method, params) => {
344
- const p = (params ?? {}) as Record<string, unknown>
345
- lastActivity = Date.now()
346
- if (method === 'item/agentMessage/delta') {
347
- const delta = typeof p.delta === 'string' ? p.delta : ''
348
- if (delta) {
349
- this.turnActive = true
350
- pushDelta(delta)
351
- }
352
- return
353
- }
354
- if (method === 'turn/started') {
355
- const turn = p.turn as Record<string, unknown> | undefined
356
- this.turnId = typeof turn?.id === 'string' ? turn.id : this.turnId
357
- this.turnActive = true
358
- enqueue({ kind: 'status', status: { state: 'WORKING', timestamp: new Date().toISOString() } })
359
- return
360
- }
361
- if (method === 'item/started') {
362
- const item = p.item as Record<string, unknown> | undefined
363
- const t = String(item?.type ?? '')
364
- if (['commandExecution', 'mcpToolCall', 'fileChange', 'dynamicToolCall', 'webSearch', 'collabToolCall'].includes(t)) {
365
- const label = t === 'commandExecution'
366
- ? String(item?.command ?? 'command')
367
- : String(item?.tool ?? item?.title ?? t)
368
- enqueue({
369
- kind: 'status',
370
- status: {
371
- state: 'WORKING',
372
- message: {
373
- messageId: randomUUID(),
374
- contextId: this.channelId,
375
- role: 'ROLE_AGENT',
376
- parts: [{ text: `🔧 ${label}${toolArgsPreview(item?.input ?? item?.arguments ?? item?.command)}` }],
377
- },
378
- timestamp: new Date().toISOString(),
379
- },
380
- })
381
- }
382
- if (t === 'contextCompaction') this.compacting = true
383
- return
384
- }
385
- if (method === 'item/completed') {
386
- const item = p.item as Record<string, unknown> | undefined
387
- if (String(item?.type ?? '') === 'agentMessage' && typeof item?.text === 'string') {
388
- agentText += item.text
389
- }
390
- if (String(item?.type ?? '') === 'contextCompaction') this.compacting = false
391
- return
392
- }
393
- if (method === 'thread/tokenUsage/updated') {
394
- const usage = (p.usage ?? p.tokenUsage ?? p) as Record<string, unknown>
395
- const input = Number(usage.input_tokens ?? usage.inputTokens ?? usage.total_tokens ?? usage.totalTokens)
396
- if (Number.isFinite(input) && input > 0) this.lastUsage = { input, at: Date.now() }
397
- return
398
- }
399
- if (method === 'turn/completed') {
400
- const turn = (p.turn ?? {}) as Record<string, unknown>
401
- const status = String(turn.status ?? 'completed')
402
- if (status === 'failed') {
403
- const err = (turn.error ?? {}) as Record<string, unknown>
404
- const info = String(err.codexErrorInfo ?? '')
405
- enqueue({
406
- kind: 'error',
407
- error: {
408
- code: info ? `CODEX_${info}` : 'CODEX_LLM_ERROR',
409
- message: String(err.message ?? 'codex 回合失败'),
410
- },
411
- })
412
- }
413
- else {
414
- // completed / interrupted:中断按 done 收口(消息按已处理落账)
415
- enqueue({ kind: 'done', final: taskId ? { taskId } : undefined })
416
- }
417
- return
418
- }
419
- if (method === 'error') {
420
- enqueue({
421
- kind: 'error',
422
- error: { code: 'CODEX_ERROR', message: String(p.message ?? p.error ?? JSON.stringify(params).slice(0, 300)) },
423
- })
424
- }
425
- })
426
-
427
- // abort 传导
428
- const onAbort = (): void => {
429
- log.warn(`[CodexAgent:${this.selfAgentId}] run 被 abort → turn/interrupt,taskId=${taskId ?? '-'}`)
430
- void client.request('turn/interrupt', { threadId: this.threadId, ...(this.turnId ? { turnId: this.turnId } : {}) }, 15_000).catch(() => {})
431
- setTimeout(() => {
432
- if (!isDone) enqueue({ kind: 'done', final: taskId ? { taskId } : undefined })
433
- }, 5000)
434
- }
435
- if (signal?.aborted) onAbort()
436
- else signal?.addEventListener('abort', onAbort, { once: true })
437
-
438
- // 投递 turn
439
- try {
440
- await client.request('turn/start', {
441
- threadId: this.threadId,
442
- input: [{ type: 'text', text: prompt }],
443
- }, 60_000)
444
- }
445
- catch (err) {
446
- unsub()
447
- signal?.removeEventListener('abort', onAbort)
448
- this.turnActive = false
449
- yield {
450
- kind: 'error',
451
- error: {
452
- code: 'CODEX_PROMPT_FAILED',
453
- message: `codex turn/start 失败: ${err instanceof Error ? err.message : String(err)}`,
454
- },
455
- }
456
- return
457
- }
458
-
459
- try {
460
- while (!isDone || queue.length > 0) {
461
- if (queue.length === 0 && !isDone) {
462
- const remaining = timeoutMs - (Date.now() - lastActivity)
463
- if (remaining <= 0) {
464
- void client.request('turn/interrupt', { threadId: this.threadId }, 15_000).catch(() => {})
465
- enqueue({
466
- kind: 'error',
467
- error: { code: 'CODEX_TURN_STALLED', message: `回合停滞 ${Math.round(timeoutMs / 1000)}s 无事件,已中止` },
468
- })
469
- continue
470
- }
471
- await new Promise<void>((r) => {
472
- resolveWait = r
473
- setTimeout(() => {
474
- resolveWait = null
475
- r()
476
- }, remaining + 100)
477
- })
478
- }
479
- while (queue.length > 0) {
480
- yield queue.shift()!
481
- }
482
- }
483
- }
484
- finally {
485
- flushDelta()
486
- unsub()
487
- signal?.removeEventListener('abort', onAbort)
488
- this.turnActive = false
489
- this.turnId = null
490
- }
491
- }
492
-
493
- /** supervise 用:收齐整个回合的事件流(supervise 决策解析在调用方) */
494
- protected async collectTurnEvents(prompt: string, timeoutMs: number, signal?: AbortSignal): Promise<AgentEvent[]> {
495
- const events: AgentEvent[] = []
496
- for await (const e of this.streamTurn(prompt, undefined, timeoutMs, signal)) {
497
- events.push(e)
498
- if (e.kind === 'error') break
499
- }
500
- return events
501
- }
502
-
503
- // ===== HITL 登记 =====
504
-
505
- private registerApprovalHitl(rpcId: string | number, itemId: string, kindLabel: 'command' | 'file', p: Record<string, unknown>): void {
506
- const id = `codex-${itemId}`
507
- if (this.pendingApprovals.has(id)) return
508
- const title = kindLabel === 'command'
509
- ? `codex 命令审批:${String(p.command ?? '(未知命令)').slice(0, 200)}`
510
- : `codex 文件变更审批:${String(p.cwd ?? p.grantRoot ?? '')}`
511
- const registry = getHitlRegistry()
512
- registry.register({
513
- kind: 'codex-approval',
514
- id,
515
- agentId: this.selfAgentId,
516
- agentName: this.agentName,
517
- channelId: this.channelId,
518
- pid: this.client?.pid,
519
- method: 'confirm',
520
- title,
521
- detail: typeof p.reason === 'string' ? p.reason : undefined,
522
- createdAt: new Date().toISOString(),
523
- expiresAt: null,
524
- })
525
- const timeoutMs = harnessSettings().hitl_timeout_ms
526
- const timer = timeoutMs > 0
527
- ? setTimeout(() => {
528
- void this.respondHitl('codex-approval', id, { cancelled: true }).catch(() => {})
529
- registry.resolve('codex-approval', id, 'expired')
530
- }, timeoutMs)
531
- : null
532
- this.pendingApprovals.set(id, { rpcId, timer })
533
- }
534
-
535
- private registerUserInputHitl(rpcId: string | number, p: Record<string, unknown>): void {
536
- const id = `codex-input-${randomUUID().slice(0, 8)}`
537
- const questions = Array.isArray(p.questions) ? p.questions : []
538
- const first = (questions[0] ?? {}) as Record<string, unknown>
539
- const registry = getHitlRegistry()
540
- registry.register({
541
- kind: 'codex-approval',
542
- id,
543
- agentId: this.selfAgentId,
544
- agentName: this.agentName,
545
- channelId: this.channelId,
546
- pid: this.client?.pid,
547
- method: 'input',
548
- title: String(first.question ?? first.header ?? 'codex 提问'),
549
- detail: typeof p.reason === 'string' ? p.reason : undefined,
550
- createdAt: new Date().toISOString(),
551
- expiresAt: null,
552
- })
553
- const timeoutMs = harnessSettings().hitl_timeout_ms
554
- const timer = timeoutMs > 0
555
- ? setTimeout(() => {
556
- void this.respondUserInput(rpcId, id, { cancelled: true }).catch(() => {})
557
- }, timeoutMs)
558
- : null
559
- this.pendingApprovals.set(id, { rpcId, timer })
560
- }
561
-
562
- private async respondUserInput(rpcId: string | number, id: string, outcome: { cancelled?: boolean, value?: string }): Promise<void> {
563
- const pending = this.pendingApprovals.get(id)
564
- if (!pending) return
565
- const client = this.client
566
- if (!client) return
567
- if (outcome.cancelled) {
568
- client.respondError(rpcId, -32800, '人工取消')
569
- getHitlRegistry().resolve('codex-approval', id, 'cancelled')
570
- }
571
- else {
572
- client.respond(rpcId, { answers: [{ answer: outcome.value ?? '' }] })
573
- getHitlRegistry().resolve('codex-approval', id, 'answered')
574
- }
575
- if (pending.timer) clearTimeout(pending.timer)
576
- this.pendingApprovals.delete(id)
577
- }
578
-
579
- // ===== 客户端管理 =====
580
-
581
- private async ensureClient(ctx: AgentRunContext): Promise<void> {
582
- if (!this.workspace) this.workspace = ctx.workspace
583
- if (!this.agentInfo) {
584
- this.channelId = ctx.channelId
585
- this.agentRole = ctx.role
586
- this.refreshIdentity()
587
- }
588
- if (this.client?.alive && this.threadId) return
589
- if (this.client && !this.client.alive) {
590
- this.client = null
591
- this.threadId = null
592
- }
593
- this.clientStarting ??= this.startClient().finally(() => {
594
- this.clientStarting = null
595
- })
596
- await this.clientStarting
597
- }
598
-
599
- private async startClient(): Promise<void> {
600
- const command = this.config.command ?? harnessSettings().codex_command
601
- const client = new StdioJsonRpcClient({
602
- name: 'codex',
603
- command,
604
- args: [...(this.config.args ?? []), 'app-server'],
605
- cwd: this.config.cwd ?? process.cwd(),
606
- env: generateMcpBridgeEnv({
607
- agentId: this.selfAgentId,
608
- token: this.config.token,
609
- baseUrl: this.config.baseUrl,
610
- bridgePath: this.config.mcpBridgePath,
611
- extra: this.config.codexHome ? { CODEX_HOME: this.config.codexHome } : {},
612
- }).engineEnv,
613
- requestTimeoutMs: 60_000,
614
- })
615
- const pidRef = { pid: undefined as number | undefined }
616
- client.onExit((code) => {
617
- if (pidRef.pid) markHarnessProcessExit(pidRef.pid, code)
618
- this.threadId = null
619
- log.warn(`[CodexAgent:${this.selfAgentId}] codex app-server 退出(code=${code});下回合自动重生`)
620
- })
621
- await client.start()
622
- pidRef.pid = client.pid
623
- if (client.pid) {
624
- registerHarnessProcess(client.pid, { harness: 'codex', command, args: ['app-server'] })
625
- bindHarnessProcess(client.pid, { agentId: this.selfAgentId, channelId: this.channelId, name: this.agentName, role: this.agentRole })
626
- }
627
-
628
- // 握手
629
- await client.request('initialize', {
630
- clientInfo: { name: 'agentworkshop', title: 'AgentWorkShop', version: '0.8.0' },
631
- }, 30_000)
632
- client.notify('initialized', {})
633
-
634
- // MCP 桥装配(per-agent CODEX_HOME 的 config.toml [mcp_servers.aw])
635
- this.writeCodexHomeConfig()
636
-
637
- // 建会话
638
- const result = await client.request('thread/start', {
639
- ...(this.config.model ? { model: this.config.model } : {}),
640
- cwd: this.config.cwd ?? process.cwd(),
641
- approvalPolicy: this.config.approvalPolicy ?? 'on-request',
642
- sandbox: this.config.sandbox ?? 'workspace-write',
643
- }, 60_000) as Record<string, unknown>
644
- const thread = (result?.thread ?? result) as Record<string, unknown>
645
- this.threadId = typeof thread?.id === 'string' ? thread.id : null
646
- if (!this.threadId) throw new Error('codex thread/start 未返回 thread id')
647
-
648
- // 事件监听挂接(通知在 streamTurn 内按回合订阅;此处仅挂请求处理器)
649
- client.onRequest((req) => {
650
- if (req.method === 'item/commandExecution/requestApproval' || req.method === 'item/fileChange/requestApproval') {
651
- const p = (req.params ?? {}) as Record<string, unknown>
652
- this.registerApprovalHitl(req.id, String(p.itemId ?? randomUUID()), req.method === 'item/fileChange/requestApproval' ? 'file' : 'command', p)
653
- }
654
- else if (req.method === 'tool/requestUserInput') {
655
- const p = (req.params ?? {}) as Record<string, unknown>
656
- this.registerUserInputHitl(req.id, p)
657
- }
658
- else {
659
- client.respondError(req.id, -32601, `方法不存在: ${req.method}`)
660
- }
661
- })
662
-
663
- this.client = client
664
- }
665
-
666
- /**
667
- * per-agent CODEX_HOME config.toml:注册 MCP 桥(required=true,桥挂了宁可失败)。
668
- * 已有 config.toml(从全局目录种子化复制)→ 追加本段(保留用户的 provider/model
669
- * 配置,自定义网关/密钥不丢失);全新目录 → 独立写入。
670
- */
671
- private writeCodexHomeConfig(): void {
672
- let home = this.config.codexHome
673
- if (!home && this.config.effort) {
674
- // effort 需要配置文件面(model_reasoning_effort):自动种子化 per-agent CODEX_HOME
675
- // (拷贝全局凭据/网关配置,保登录与自定义 provider;追加 MCP 段 + 顶部 effort)
676
- home = join(tmpdir(), `aw-codex-${this.selfAgentId.slice(0, 8)}`)
677
- this.config.codexHome = home
678
- for (const f of ['auth.json', 'config.toml', 'cc-switch-model-catalog.json']) {
679
- try {
680
- const src = join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.codex', f)
681
- if (existsSync(src)) copyFileSync(src, join(home, f))
682
- }
683
- catch { /* 单文件缺失忽略 */ }
684
- }
685
- }
686
- if (!home) return
687
- try {
688
- mkdirSync(home, { recursive: true })
689
- const configFile = join(home, 'config.toml')
690
- const env = generateMcpBridgeEnv({ agentId: this.selfAgentId, token: this.config.token, baseUrl: this.config.baseUrl, bridgePath: this.config.mcpBridgePath })
691
- const envLines = Object.entries(env.bridgeEnv).map(([k, v]) => ` ${k} = "${v}"`).join('\n')
692
- const section = [
693
- ``,
694
- `[mcp_servers.aw]`,
695
- `command = ${JSON.stringify(process.execPath)}`,
696
- `args = [${JSON.stringify(join(process.env.AW_PACKAGE_ROOT ?? process.cwd(), 'server', 'harness', 'aw-mcp-bridge.mjs'))}]`,
697
- `required = true`,
698
- ``,
699
- `[mcp_servers.aw.env]`,
700
- envLines,
701
- ``,
702
- ].join('\n')
703
- // effort 走 TOML 顶层键(model_reasoning_effort):必须位于任何 [table] 之前 → 顶部插入
704
- const effortLine = this.config.effort
705
- ? `model_reasoning_effort = ${JSON.stringify(this.config.effort)}
706
- `
707
- : ''
708
- if (existsSync(configFile)) {
709
- const existing = readFileSync(configFile, 'utf-8')
710
- const withoutDup = this.config.effort
711
- ? existing.replace(/^model_reasoning_effort = .*\n?/m, '')
712
- : existing
713
- if (withoutDup.includes('[mcp_servers.aw]')) {
714
- if (effortLine && !withoutDup.startsWith(effortLine.trim())) {
715
- writeFileSync(configFile, effortLine + withoutDup, 'utf-8')
716
- }
717
- return
718
- }
719
- writeFileSync(configFile, effortLine + withoutDup + section, 'utf-8')
720
- }
721
- else {
722
- writeFileSync(configFile, effortLine + section, 'utf-8')
723
- }
724
- }
725
- catch (err) {
726
- log.warn(`[CodexAgent:${this.selfAgentId}] CODEX_HOME config 写入失败(信任全局配置):`, err instanceof Error ? err.message : err)
727
- }
728
- }
729
- }
1
+ /**
2
+ * CodexAgentImpl — OpenAI Codex CLI(app-server)harness 的 AgentInterface 实现。
3
+ *
4
+ * 进程模型:每 Agent 一个 `codex app-server` 子进程(stdio NDJSON JSON-RPC v2,
5
+ * lazy spawn 跨消息复用);thread/start 建会话,turn/start 驱动回合。
6
+ *
7
+ * - prompt/工具面与 omp 全引擎同源(prompt-builder / host-tool-bridge);
8
+ * 工具经 stdio MCP 桥注入(config.toml 由 impl 装配 [mcp_servers.aw])
9
+ * - 事件映射:item/agentMessage/delta → delta;item/started → 🔧 status;
10
+ * turn/completed → artifact + done / error(codexErrorInfo 结构化)
11
+ * - HITL:item/commandExecution|fileChange/requestApproval(server→client 请求)
12
+ * → hitl-registry 登记 → respondHitl 应答(decision: accept/decline/cancel)
13
+ * - steer:turn 运行中 → turn/steer;无 active turn → 'deferred'
14
+ * - 上下文治理:thread/tokenUsage/updated 被动跟踪;越阈值 → thread/compact/start
15
+ *
16
+ * 协议权威:github.com/openai/codex codex-rs/app-server/README.md(v0.149 实测)。
17
+ */
18
+ import { createLogger } from '../logger'
19
+ import { randomUUID } from 'node:crypto'
20
+ import { join } from 'node:path'
21
+ import { mkdirSync, writeFileSync, existsSync, readFileSync, copyFileSync } from 'node:fs'
22
+ import { tmpdir } from 'node:os'
23
+ import type { AgentEvent, AgentInterface, AgentInfo, AgentRunContext, AgentRunRequest } from './agent-interface'
24
+ import type { AgentContextStats } from '../types/task'
25
+ import { registerHarnessProcess, bindHarnessProcess, markHarnessProcessExit, killHarnessProcess } from './harness-process'
26
+ import { peerPrompt, systemManual, toolArgsPreview, workerPrompt } from './prompt-builder'
27
+ import { getHitlRegistry } from './hitl-registry'
28
+ import { harnessSettings } from '../settings'
29
+ import { StdioJsonRpcClient } from './adapters/stdio-jsonrpc'
30
+ import { BaseAgentImpl } from './base-agent'
31
+ import { generateMcpBridgeEnv } from './harness-env'
32
+
33
+ const log = createLogger('workshop.codex')
34
+
35
+ /**
36
+ * 默认回合停滞上限:整轮无任何事件(含推理模型的静默思考期)达到该时长才中止。
37
+ * 600s 会误杀健康的沉默推理(实测推理档静默 >10 分钟后被打断,任务 FAILED→重试→CANCELED);
38
+ * 事件到达即刷新计时,真实卡死仍会在该窗口内被发现。
39
+ */
40
+ const CODEX_TURN_STALL_MS = 1_800_000
41
+
42
+ export interface CodexAgentConfig {
43
+ /** codex 可执行文件(默认取 harness.codex_command 设置) */
44
+ command?: string
45
+ /** 额外 CLI 参数(app-server 之前) */
46
+ args?: string[]
47
+ cwd?: string
48
+ /** 模型(如 gpt-5.2) */
49
+ model?: string
50
+ /** 审批策略(默认 on-request:沙箱内自由,越界请求审批 → HITL) */
51
+ approvalPolicy?: 'untrusted' | 'on-request' | 'never'
52
+ /** 沙箱(默认 workspace-write) */
53
+ sandbox?: 'read-only' | 'workspace-write' | 'danger-full-access'
54
+ /** CODEX_HOME(缺省进程环境;配置隔离/多账户时按 agent 指定;effort 未指定 home 时自动种子化) */
55
+ codexHome?: string
56
+ /** 思考 effort(model_reasoning_effort;需 CODEX_HOME 配置面,未指定 home 时自动种子化) */
57
+ effort?: string
58
+ /** 上下文窗口(usage 百分比计算) */
59
+ contextWindow?: number
60
+ /** 压缩阈值(0-1,默认 0.7) */
61
+ compactThreshold?: number
62
+ /**
63
+ * 回合停滞上限(ms):整轮无任何事件(推理模型静默思考也不产 delta)达到该时长才中止。
64
+ * 默认 1800000(30 分钟):codex 0.154 的推理档在负载下可静默思考 >10 分钟,
65
+ * 600s 会把健康的沉默推理误杀为 CODEX_TURN_STALLED(任务 FAILED→重试→CANCELED)。
66
+ * 有事件(delta/status/工具轨迹)即刷新计时,不放大真实卡死的发现延迟。
67
+ */
68
+ promptTimeoutMs?: number
69
+ superviseTimeoutMs?: number
70
+ systemPromptPrefix?: string
71
+ scenarioPrompt?: string
72
+ agentId?: string
73
+ name?: string
74
+ role?: 'lead' | 'worker'
75
+ channelId?: string
76
+ token?: string
77
+ baseUrl?: string
78
+ mcpBridgePath?: string
79
+ }
80
+
81
+ export class CodexAgentImpl extends BaseAgentImpl implements AgentInterface {
82
+ private readonly config: CodexAgentConfig
83
+ private agentInfo: AgentInfo | null = null
84
+ // 不要重新声明 bridgeCtx / agentRole(由 BaseAgentImpl 持有)。
85
+ // 子类字段初始化器在 super() 之后执行,会用空 identity 遮蔽基类已装配好的 bridgeCtx,
86
+ // 使 host tool 桥的 agentId 恒为 '' → 按 agentId 的鉴权全部误判(节点绑定/工业工具)。
87
+ // 同理 agentRole 会被重置为 'worker',lead 身份丢失。
88
+
89
+ private client: StdioJsonRpcClient | null = null
90
+ private clientStarting: Promise<void> | null = null
91
+ private threadId: string | null = null
92
+ private turnId: string | null = null
93
+
94
+ // 回合状态
95
+ private turnActive = false
96
+ private deltaBuf = ''
97
+ private deltaTimer: ReturnType<typeof setTimeout> | null = null
98
+ private lastUsage: { input: number, at: number } | null = null
99
+ private compacting = false
100
+ private lastCompactAt = 0
101
+ /** 待应答审批(approval request id → JSON-RPC id) */
102
+ private pendingApprovals = new Map<string, { rpcId: string | number, timer: ReturnType<typeof setTimeout> | null }>()
103
+
104
+ constructor(config: Record<string, unknown> = {}) {
105
+ super({
106
+ agentId: typeof config.agentId === 'string' ? config.agentId : '',
107
+ name: typeof config.name === 'string' ? config.name : undefined,
108
+ role: config.role === 'lead' ? 'lead' : 'worker',
109
+ channelId: typeof config.channelId === 'string' ? config.channelId : '',
110
+ })
111
+ this.config = config as CodexAgentConfig
112
+ }
113
+
114
+ protected get harnessId(): string {
115
+ return 'codex'
116
+ }
117
+
118
+ protected configRecord(): Record<string, unknown> {
119
+ return this.config
120
+ }
121
+
122
+ async dispose(): Promise<void> {
123
+ const client = this.client
124
+ this.client = null
125
+ this.threadId = null
126
+ if (client) {
127
+ const pid = client.pid
128
+ await client.dispose().catch(() => {})
129
+ if (pid) markHarnessProcessExit(pid, null)
130
+ }
131
+ for (const [id, p] of this.pendingApprovals) {
132
+ if (p.timer) clearTimeout(p.timer)
133
+ this.pendingApprovals.delete(id)
134
+ }
135
+ }
136
+
137
+ getProcessInfo(): { pid: number, alive: boolean, command: string } | null {
138
+ const client = this.client
139
+ const pid = client?.pid
140
+ if (!pid || !client) return null
141
+ return { pid, alive: client.alive, command: 'codex app-server' }
142
+ }
143
+
144
+ killProcess(): void {
145
+ const pid = this.client?.pid
146
+ if (pid) killHarnessProcess(pid)
147
+ else this.client?.kill()
148
+ }
149
+
150
+ reconcileProcess(): void {
151
+ this.client?.reconcile()
152
+ }
153
+
154
+ getContextStats(): AgentContextStats | null {
155
+ if (!this.lastUsage) return null
156
+ const window = this.config.contextWindow ?? null
157
+ return {
158
+ usedTokens: this.lastUsage.input,
159
+ contextWindow: window,
160
+ percent: window && window > 0 ? Math.min(1, this.lastUsage.input / window) : null,
161
+ compacting: this.compacting,
162
+ }
163
+ }
164
+
165
+ /** 实时注入:turn 运行中 → turn/steer;否则 'deferred'(消息保持 pending) */
166
+ async steer(text: string): Promise<'steer' | 'deferred'> {
167
+ const client = this.client
168
+ if (!client?.alive || !this.threadId || !this.turnActive) return 'deferred'
169
+ try {
170
+ await client.request('turn/steer', {
171
+ threadId: this.threadId,
172
+ input: [{ type: 'text', text }],
173
+ }, 15_000)
174
+ return 'steer'
175
+ }
176
+ catch {
177
+ // 无 active turn / 引擎拒绝 → 消息保持 pending 由消费循环处理
178
+ return 'deferred'
179
+ }
180
+ }
181
+
182
+ /** HITL 应答:审批请求 → JSON-RPC 应答(decision) */
183
+ async respondHitl(kind: string, id: string, outcome: {
184
+ confirmed?: boolean
185
+ cancelled?: boolean
186
+ value?: string
187
+ response?: string
188
+ comment?: string
189
+ }): Promise<void> {
190
+ if (kind !== 'codex-approval') return
191
+ const pending = this.pendingApprovals.get(id)
192
+ if (!pending) throw new Error(`待办不存在或已处理: ${id}`)
193
+ const client = this.client
194
+ if (!client) throw new Error('codex 会话已关闭')
195
+ const decision = outcome.cancelled === true
196
+ ? 'cancel'
197
+ : outcome.confirmed === true ? 'accept' : 'decline'
198
+ client.respond(pending.rpcId, { decision })
199
+ if (pending.timer) clearTimeout(pending.timer)
200
+ this.pendingApprovals.delete(id)
201
+ getHitlRegistry().resolve(kind, id, decision === 'cancel' ? 'cancelled' : 'answered')
202
+ }
203
+
204
+ /** 上下文治理(post-settle):越阈值 → thread/compact/start */
205
+ async onTurnSettled(): Promise<void> {
206
+ const client = this.client
207
+ if (!client?.alive || !this.threadId || this.compacting) return
208
+ const stats = this.getContextStats()
209
+ const threshold = this.config.compactThreshold ?? 0.7
210
+ if (!stats?.percent || stats.percent < threshold) return
211
+ if (Date.now() - this.lastCompactAt < 5 * 60_000) return
212
+ this.compacting = true
213
+ this.lastCompactAt = Date.now()
214
+ try {
215
+ await client.request('thread/compact/start', { threadId: this.threadId }, 30_000)
216
+ log.info(`[CodexAgent:${this.selfAgentId}] 上下文压缩已触发(percent=${(stats.percent * 100).toFixed(0)}%)`)
217
+ }
218
+ catch (err) {
219
+ log.warn(`[CodexAgent:${this.selfAgentId}] compact 发起失败(放行):`, err instanceof Error ? err.message : err)
220
+ }
221
+ finally {
222
+ this.compacting = false
223
+ }
224
+ }
225
+
226
+ protected async* workerTurn(request: AgentRunRequest, ctx: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown> {
227
+ const taskId = request.taskId ?? (request.message.metadata?.['x-aw-task-id'] as string | undefined)
228
+ if (!taskId) return
229
+ this.toolState.currentTaskId = taskId
230
+ try {
231
+ await this.ensureClient(ctx)
232
+ const taskText = request.message.parts.map((p) => {
233
+ if ('text' in p) return p.text
234
+ if ('data' in p) return JSON.stringify(p.data)
235
+ if ('url' in p) return p.url
236
+ if ('raw' in p) return p.raw
237
+ return ''
238
+ }).join('\n')
239
+ const prompt = workerPrompt({
240
+ agentName: this.agentName,
241
+ channelId: this.channelId,
242
+ taskId,
243
+ taskText,
244
+ memory: request.memory,
245
+ ctxPrefix: await this.contextPrefix(),
246
+ manual: systemManual(),
247
+ })
248
+ yield* this.streamTurn(prompt, taskId, this.config.promptTimeoutMs ?? CODEX_TURN_STALL_MS, ctx.signal)
249
+ }
250
+ finally {
251
+ this.toolState.currentTaskId = null
252
+ }
253
+ }
254
+
255
+ protected async* peerTurn(request: AgentRunRequest, ctx: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown> {
256
+ await this.ensureClient(ctx)
257
+ const msg = request.message
258
+ const fromId = request.fromAgentId
259
+ ?? (typeof msg.metadata?.['x-aw-from-label'] === 'string' ? msg.metadata['x-aw-from-label'] : undefined)
260
+ ?? 'unknown'
261
+ const requireReply = msg.metadata?.['x-aw-require-reply'] === 'true'
262
+ const crossChannel = msg.metadata?.['x-aw-cross-channel'] === 'true'
263
+ this.toolState.replyContext = requireReply && request.fromAgentId && !crossChannel
264
+ ? { fromId: request.fromAgentId, messageId: msg.messageId }
265
+ : null
266
+ const msgText = msg.parts.map((p) => {
267
+ if ('text' in p) return p.text
268
+ if ('data' in p) return JSON.stringify(p.data)
269
+ if ('url' in p) return p.url
270
+ if ('raw' in p) return p.raw
271
+ return ''
272
+ }).join('\n')
273
+ const prompt = peerPrompt({
274
+ agentName: this.agentName,
275
+ role: this.agentRole,
276
+ channelId: this.channelId,
277
+ ctxPrefix: await this.contextPrefix(),
278
+ manual: systemManual(),
279
+ memory: request.memory,
280
+ fromId,
281
+ messageId: msg.messageId,
282
+ requireReply,
283
+ isReply: typeof msg.metadata?.['x-aw-in-reply-to'] === 'string',
284
+ crossChannel,
285
+ fromChannel: typeof msg.metadata?.['x-aw-from-channel'] === 'string' ? String(msg.metadata['x-aw-from-channel']) : '',
286
+ msgText,
287
+ })
288
+ yield* this.streamTurn(prompt, undefined, this.config.promptTimeoutMs ?? CODEX_TURN_STALL_MS, ctx.signal)
289
+ }
290
+
291
+ // ===== 回合执行 =====
292
+
293
+ /**
294
+ * 流式回合:turn/start → 逐事件产出(delta/status)→ turn/completed 收口。
295
+ * artifact 在 done 前注入(item/completed agentMessage 聚合文本)。
296
+ */
297
+ private async* streamTurn(prompt: string, taskId: string | undefined, timeoutMs: number, signal?: AbortSignal): AsyncGenerator<AgentEvent, void, unknown> {
298
+ const client = this.client
299
+ if (!client || !this.threadId) {
300
+ yield { kind: 'error', error: { code: 'CODEX_NOT_READY', message: 'codex 会话未就绪' } }
301
+ return
302
+ }
303
+ const queue: AgentEvent[] = []
304
+ let isDone = false
305
+ let resolveWait: (() => void) | null = null
306
+ let lastActivity = Date.now()
307
+ let agentText = ''
308
+ this.turnActive = true
309
+ this.turnId = null
310
+
311
+ const enqueue = (e: AgentEvent): void => {
312
+ if (e.kind === 'done' && !isDone) {
313
+ if (agentText.trim()) {
314
+ queue.push({
315
+ kind: 'artifact',
316
+ artifact: { artifactId: randomUUID(), name: 'output', parts: [{ text: agentText.trim() }] },
317
+ lastChunk: true,
318
+ totalChunks: 1,
319
+ })
320
+ }
321
+ this.turnActive = false
322
+ }
323
+ if (e.kind === 'done' || e.kind === 'error') {
324
+ isDone = true
325
+ this.turnActive = false
326
+ flushDelta()
327
+ }
328
+ queue.push(e)
329
+ lastActivity = Date.now()
330
+ resolveWait?.()
331
+ resolveWait = null
332
+ }
333
+
334
+ const flushDelta = (): void => {
335
+ if (this.deltaTimer) {
336
+ clearTimeout(this.deltaTimer)
337
+ this.deltaTimer = null
338
+ }
339
+ if (!this.deltaBuf) return
340
+ const text = this.deltaBuf
341
+ this.deltaBuf = ''
342
+ queue.push({ kind: 'delta', delta: { text } })
343
+ }
344
+ const pushDelta = (text: string): void => {
345
+ this.deltaBuf += text
346
+ this.deltaTimer ??= setTimeout(() => {
347
+ this.deltaTimer = null
348
+ flushDelta()
349
+ }, 50)
350
+ }
351
+
352
+ // 通知订阅(审批请求处理器已在 startClient 挂接,此处只处理回合通知)
353
+ const unsub = client.onNotification((method, params) => {
354
+ const p = (params ?? {}) as Record<string, unknown>
355
+ lastActivity = Date.now()
356
+ if (method === 'item/agentMessage/delta') {
357
+ const delta = typeof p.delta === 'string' ? p.delta : ''
358
+ if (delta) {
359
+ this.turnActive = true
360
+ pushDelta(delta)
361
+ }
362
+ return
363
+ }
364
+ if (method === 'turn/started') {
365
+ const turn = p.turn as Record<string, unknown> | undefined
366
+ this.turnId = typeof turn?.id === 'string' ? turn.id : this.turnId
367
+ this.turnActive = true
368
+ enqueue({ kind: 'status', status: { state: 'WORKING', timestamp: new Date().toISOString() } })
369
+ return
370
+ }
371
+ if (method === 'item/started') {
372
+ const item = p.item as Record<string, unknown> | undefined
373
+ const t = String(item?.type ?? '')
374
+ if (['commandExecution', 'mcpToolCall', 'fileChange', 'dynamicToolCall', 'webSearch', 'collabToolCall'].includes(t)) {
375
+ const label = t === 'commandExecution'
376
+ ? String(item?.command ?? 'command')
377
+ : String(item?.tool ?? item?.title ?? t)
378
+ enqueue({
379
+ kind: 'status',
380
+ status: {
381
+ state: 'WORKING',
382
+ message: {
383
+ messageId: randomUUID(),
384
+ contextId: this.channelId,
385
+ role: 'ROLE_AGENT',
386
+ parts: [{ text: `🔧 ${label}${toolArgsPreview(item?.input ?? item?.arguments ?? item?.command)}` }],
387
+ },
388
+ timestamp: new Date().toISOString(),
389
+ },
390
+ })
391
+ }
392
+ if (t === 'contextCompaction') this.compacting = true
393
+ return
394
+ }
395
+ if (method === 'item/completed') {
396
+ const item = p.item as Record<string, unknown> | undefined
397
+ if (String(item?.type ?? '') === 'agentMessage' && typeof item?.text === 'string') {
398
+ agentText += item.text
399
+ }
400
+ if (String(item?.type ?? '') === 'contextCompaction') this.compacting = false
401
+ return
402
+ }
403
+ if (method === 'thread/tokenUsage/updated') {
404
+ const usage = (p.usage ?? p.tokenUsage ?? p) as Record<string, unknown>
405
+ const input = Number(usage.input_tokens ?? usage.inputTokens ?? usage.total_tokens ?? usage.totalTokens)
406
+ if (Number.isFinite(input) && input > 0) this.lastUsage = { input, at: Date.now() }
407
+ return
408
+ }
409
+ if (method === 'turn/completed') {
410
+ const turn = (p.turn ?? {}) as Record<string, unknown>
411
+ const status = String(turn.status ?? 'completed')
412
+ if (status === 'failed') {
413
+ const err = (turn.error ?? {}) as Record<string, unknown>
414
+ const info = String(err.codexErrorInfo ?? '')
415
+ enqueue({
416
+ kind: 'error',
417
+ error: {
418
+ code: info ? `CODEX_${info}` : 'CODEX_LLM_ERROR',
419
+ message: String(err.message ?? 'codex 回合失败'),
420
+ },
421
+ })
422
+ }
423
+ else {
424
+ // completed / interrupted:中断按 done 收口(消息按已处理落账)
425
+ enqueue({ kind: 'done', final: taskId ? { taskId } : undefined })
426
+ }
427
+ return
428
+ }
429
+ if (method === 'error') {
430
+ enqueue({
431
+ kind: 'error',
432
+ error: { code: 'CODEX_ERROR', message: String(p.message ?? p.error ?? JSON.stringify(params).slice(0, 300)) },
433
+ })
434
+ }
435
+ })
436
+
437
+ // abort 传导
438
+ const onAbort = (): void => {
439
+ log.warn(`[CodexAgent:${this.selfAgentId}] run 被 abort → turn/interrupt,taskId=${taskId ?? '-'}`)
440
+ void client.request('turn/interrupt', { threadId: this.threadId, ...(this.turnId ? { turnId: this.turnId } : {}) }, 15_000).catch(() => {})
441
+ setTimeout(() => {
442
+ if (!isDone) enqueue({ kind: 'done', final: taskId ? { taskId } : undefined })
443
+ }, 5000)
444
+ }
445
+ if (signal?.aborted) onAbort()
446
+ else signal?.addEventListener('abort', onAbort, { once: true })
447
+
448
+ // 投递 turn
449
+ try {
450
+ await client.request('turn/start', {
451
+ threadId: this.threadId,
452
+ input: [{ type: 'text', text: prompt }],
453
+ }, 60_000)
454
+ }
455
+ catch (err) {
456
+ unsub()
457
+ signal?.removeEventListener('abort', onAbort)
458
+ this.turnActive = false
459
+ yield {
460
+ kind: 'error',
461
+ error: {
462
+ code: 'CODEX_PROMPT_FAILED',
463
+ message: `codex turn/start 失败: ${err instanceof Error ? err.message : String(err)}`,
464
+ },
465
+ }
466
+ return
467
+ }
468
+
469
+ try {
470
+ while (!isDone || queue.length > 0) {
471
+ if (queue.length === 0 && !isDone) {
472
+ const remaining = timeoutMs - (Date.now() - lastActivity)
473
+ if (remaining <= 0) {
474
+ void client.request('turn/interrupt', { threadId: this.threadId }, 15_000).catch(() => {})
475
+ enqueue({
476
+ kind: 'error',
477
+ error: { code: 'CODEX_TURN_STALLED', message: `回合停滞 ${Math.round(timeoutMs / 1000)}s 无事件,已中止` },
478
+ })
479
+ continue
480
+ }
481
+ await new Promise<void>((r) => {
482
+ resolveWait = r
483
+ setTimeout(() => {
484
+ resolveWait = null
485
+ r()
486
+ }, remaining + 100)
487
+ })
488
+ }
489
+ while (queue.length > 0) {
490
+ yield queue.shift()!
491
+ }
492
+ }
493
+ }
494
+ finally {
495
+ flushDelta()
496
+ unsub()
497
+ signal?.removeEventListener('abort', onAbort)
498
+ this.turnActive = false
499
+ this.turnId = null
500
+ }
501
+ }
502
+
503
+ /** supervise 用:收齐整个回合的事件流(supervise 决策解析在调用方) */
504
+ protected async collectTurnEvents(prompt: string, timeoutMs: number, signal?: AbortSignal): Promise<AgentEvent[]> {
505
+ const events: AgentEvent[] = []
506
+ for await (const e of this.streamTurn(prompt, undefined, timeoutMs, signal)) {
507
+ events.push(e)
508
+ if (e.kind === 'error') break
509
+ }
510
+ return events
511
+ }
512
+
513
+ // ===== HITL 登记 =====
514
+
515
+ private registerApprovalHitl(rpcId: string | number, itemId: string, kindLabel: 'command' | 'file', p: Record<string, unknown>): void {
516
+ const id = `codex-${itemId}`
517
+ if (this.pendingApprovals.has(id)) return
518
+ const title = kindLabel === 'command'
519
+ ? `codex 命令审批:${String(p.command ?? '(未知命令)').slice(0, 200)}`
520
+ : `codex 文件变更审批:${String(p.cwd ?? p.grantRoot ?? '')}`
521
+ const registry = getHitlRegistry()
522
+ registry.register({
523
+ kind: 'codex-approval',
524
+ id,
525
+ agentId: this.selfAgentId,
526
+ agentName: this.agentName,
527
+ channelId: this.channelId,
528
+ pid: this.client?.pid,
529
+ method: 'confirm',
530
+ title,
531
+ detail: typeof p.reason === 'string' ? p.reason : undefined,
532
+ createdAt: new Date().toISOString(),
533
+ expiresAt: null,
534
+ })
535
+ const timeoutMs = harnessSettings().hitl_timeout_ms
536
+ const timer = timeoutMs > 0
537
+ ? setTimeout(() => {
538
+ void this.respondHitl('codex-approval', id, { cancelled: true }).catch(() => {})
539
+ registry.resolve('codex-approval', id, 'expired')
540
+ }, timeoutMs)
541
+ : null
542
+ this.pendingApprovals.set(id, { rpcId, timer })
543
+ }
544
+
545
+ private registerUserInputHitl(rpcId: string | number, p: Record<string, unknown>): void {
546
+ const id = `codex-input-${randomUUID().slice(0, 8)}`
547
+ const questions = Array.isArray(p.questions) ? p.questions : []
548
+ const first = (questions[0] ?? {}) as Record<string, unknown>
549
+ const registry = getHitlRegistry()
550
+ registry.register({
551
+ kind: 'codex-approval',
552
+ id,
553
+ agentId: this.selfAgentId,
554
+ agentName: this.agentName,
555
+ channelId: this.channelId,
556
+ pid: this.client?.pid,
557
+ method: 'input',
558
+ title: String(first.question ?? first.header ?? 'codex 提问'),
559
+ detail: typeof p.reason === 'string' ? p.reason : undefined,
560
+ createdAt: new Date().toISOString(),
561
+ expiresAt: null,
562
+ })
563
+ const timeoutMs = harnessSettings().hitl_timeout_ms
564
+ const timer = timeoutMs > 0
565
+ ? setTimeout(() => {
566
+ void this.respondUserInput(rpcId, id, { cancelled: true }).catch(() => {})
567
+ }, timeoutMs)
568
+ : null
569
+ this.pendingApprovals.set(id, { rpcId, timer })
570
+ }
571
+
572
+ private async respondUserInput(rpcId: string | number, id: string, outcome: { cancelled?: boolean, value?: string }): Promise<void> {
573
+ const pending = this.pendingApprovals.get(id)
574
+ if (!pending) return
575
+ const client = this.client
576
+ if (!client) return
577
+ if (outcome.cancelled) {
578
+ client.respondError(rpcId, -32800, '人工取消')
579
+ getHitlRegistry().resolve('codex-approval', id, 'cancelled')
580
+ }
581
+ else {
582
+ client.respond(rpcId, { answers: [{ answer: outcome.value ?? '' }] })
583
+ getHitlRegistry().resolve('codex-approval', id, 'answered')
584
+ }
585
+ if (pending.timer) clearTimeout(pending.timer)
586
+ this.pendingApprovals.delete(id)
587
+ }
588
+
589
+ // ===== 客户端管理 =====
590
+
591
+ private async ensureClient(ctx: AgentRunContext): Promise<void> {
592
+ if (!this.workspace) this.workspace = ctx.workspace
593
+ if (!this.agentInfo) {
594
+ this.channelId = ctx.channelId
595
+ this.agentRole = ctx.role
596
+ this.refreshIdentity()
597
+ }
598
+ if (this.client?.alive && this.threadId) return
599
+ if (this.client && !this.client.alive) {
600
+ this.client = null
601
+ this.threadId = null
602
+ }
603
+ this.clientStarting ??= this.startClient().finally(() => {
604
+ this.clientStarting = null
605
+ })
606
+ await this.clientStarting
607
+ }
608
+
609
+ private async startClient(): Promise<void> {
610
+ const command = this.config.command ?? harnessSettings().codex_command
611
+ const client = new StdioJsonRpcClient({
612
+ name: 'codex',
613
+ command,
614
+ args: [...(this.config.args ?? []), 'app-server'],
615
+ cwd: this.config.cwd ?? process.cwd(),
616
+ env: generateMcpBridgeEnv({
617
+ agentId: this.selfAgentId,
618
+ token: this.config.token,
619
+ baseUrl: this.config.baseUrl,
620
+ bridgePath: this.config.mcpBridgePath,
621
+ extra: this.config.codexHome ? { CODEX_HOME: this.config.codexHome } : {},
622
+ }).engineEnv,
623
+ requestTimeoutMs: 60_000,
624
+ })
625
+ const pidRef = { pid: undefined as number | undefined }
626
+ client.onExit((code) => {
627
+ if (pidRef.pid) markHarnessProcessExit(pidRef.pid, code)
628
+ this.threadId = null
629
+ log.warn(`[CodexAgent:${this.selfAgentId}] codex app-server 退出(code=${code});下回合自动重生`)
630
+ })
631
+ await client.start()
632
+ pidRef.pid = client.pid
633
+ if (client.pid) {
634
+ registerHarnessProcess(client.pid, { harness: 'codex', command, args: ['app-server'] })
635
+ bindHarnessProcess(client.pid, { agentId: this.selfAgentId, channelId: this.channelId, name: this.agentName, role: this.agentRole })
636
+ }
637
+
638
+ // 握手
639
+ await client.request('initialize', {
640
+ clientInfo: { name: 'agentworkshop', title: 'AgentWorkShop', version: '0.8.0' },
641
+ }, 30_000)
642
+ client.notify('initialized', {})
643
+
644
+ // MCP 桥装配(per-agent CODEX_HOME 的 config.toml [mcp_servers.aw])
645
+ this.writeCodexHomeConfig()
646
+
647
+ // 建会话
648
+ const result = await client.request('thread/start', {
649
+ ...(this.config.model ? { model: this.config.model } : {}),
650
+ cwd: this.config.cwd ?? process.cwd(),
651
+ approvalPolicy: this.config.approvalPolicy ?? 'on-request',
652
+ sandbox: this.config.sandbox ?? 'workspace-write',
653
+ }, 60_000) as Record<string, unknown>
654
+ const thread = (result?.thread ?? result) as Record<string, unknown>
655
+ this.threadId = typeof thread?.id === 'string' ? thread.id : null
656
+ if (!this.threadId) throw new Error('codex thread/start 未返回 thread id')
657
+
658
+ // 事件监听挂接(通知在 streamTurn 内按回合订阅;此处仅挂请求处理器)
659
+ client.onRequest((req) => {
660
+ if (req.method === 'item/commandExecution/requestApproval' || req.method === 'item/fileChange/requestApproval') {
661
+ const p = (req.params ?? {}) as Record<string, unknown>
662
+ this.registerApprovalHitl(req.id, String(p.itemId ?? randomUUID()), req.method === 'item/fileChange/requestApproval' ? 'file' : 'command', p)
663
+ }
664
+ else if (req.method === 'tool/requestUserInput') {
665
+ const p = (req.params ?? {}) as Record<string, unknown>
666
+ this.registerUserInputHitl(req.id, p)
667
+ }
668
+ else {
669
+ client.respondError(req.id, -32601, `方法不存在: ${req.method}`)
670
+ }
671
+ })
672
+
673
+ this.client = client
674
+ }
675
+
676
+ /**
677
+ * per-agent CODEX_HOME config.toml:注册 MCP 桥(required=true,桥挂了宁可失败)。
678
+ * 已有 config.toml(从全局目录种子化复制)→ 追加本段(保留用户的 provider/model
679
+ * 配置,自定义网关/密钥不丢失);全新目录 → 独立写入。
680
+ *
681
+ * 无条件种子化(不再仅当 effort 配置时才挂桥):MCP 桥是 codex worker 的 host
682
+ * 工具面(complete_task/ops_log/…)唯一入口;不挂桥的实例模型只能拿自带 shell
683
+ * 乱翻工作区,永远调不到 complete_task → 任务停滞被看门狗回收
684
+ * (实测 codex 任务终态 CANCELED、交付物却只落在频道消息里的根因)。
685
+ */
686
+ private writeCodexHomeConfig(): void {
687
+ let home = this.config.codexHome
688
+ if (!home) {
689
+ // 自动种子化 per-agent CODEX_HOME(拷贝全局凭据/网关配置,保登录与自定义
690
+ // provider;追加 MCP 段 + 顶部 effort)
691
+ home = join(tmpdir(), `aw-codex-${this.selfAgentId.slice(0, 8)}`)
692
+ this.config.codexHome = home
693
+ for (const f of ['auth.json', 'config.toml', 'cc-switch-model-catalog.json']) {
694
+ try {
695
+ const src = join(process.env.HOME ?? process.env.USERPROFILE ?? '', '.codex', f)
696
+ if (existsSync(src)) copyFileSync(src, join(home, f))
697
+ }
698
+ catch { /* 单文件缺失忽略 */ }
699
+ }
700
+ }
701
+ try {
702
+ mkdirSync(home, { recursive: true })
703
+ const configFile = join(home, 'config.toml')
704
+ const env = generateMcpBridgeEnv({ agentId: this.selfAgentId, token: this.config.token, baseUrl: this.config.baseUrl, bridgePath: this.config.mcpBridgePath })
705
+ const envLines = Object.entries(env.bridgeEnv).map(([k, v]) => ` ${k} = "${v}"`).join('\n')
706
+ const section = [
707
+ ``,
708
+ `[mcp_servers.aw]`,
709
+ `command = ${JSON.stringify(process.execPath)}`,
710
+ `args = [${JSON.stringify(join(process.env.AW_PACKAGE_ROOT ?? process.cwd(), 'server', 'harness', 'aw-mcp-bridge.mjs'))}]`,
711
+ `required = true`,
712
+ ``,
713
+ `[mcp_servers.aw.env]`,
714
+ envLines,
715
+ ``,
716
+ ].join('\n')
717
+ // effort 走 TOML 顶层键(model_reasoning_effort):必须位于任何 [table] 之前 → 顶部插入
718
+ const effortLine = this.config.effort
719
+ ? `model_reasoning_effort = ${JSON.stringify(this.config.effort)}
720
+ `
721
+ : ''
722
+ if (existsSync(configFile)) {
723
+ const existing = readFileSync(configFile, 'utf-8')
724
+ const withoutDup = this.config.effort
725
+ ? existing.replace(/^model_reasoning_effort = .*\n?/m, '')
726
+ : existing
727
+ if (withoutDup.includes('[mcp_servers.aw]')) {
728
+ if (effortLine && !withoutDup.startsWith(effortLine.trim())) {
729
+ writeFileSync(configFile, effortLine + withoutDup, 'utf-8')
730
+ }
731
+ return
732
+ }
733
+ writeFileSync(configFile, effortLine + withoutDup + section, 'utf-8')
734
+ }
735
+ else {
736
+ writeFileSync(configFile, effortLine + section, 'utf-8')
737
+ }
738
+ }
739
+ catch (err) {
740
+ log.warn(`[CodexAgent:${this.selfAgentId}] CODEX_HOME config 写入失败(信任全局配置):`, err instanceof Error ? err.message : err)
741
+ }
742
+ }
743
+ }