@xyit/wellspring 0.0.0-stage → 1.1.0

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 (464) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +853 -2
  3. package/dist/agent/pending-asks.d.ts +20 -0
  4. package/dist/agent/pending-asks.js +70 -0
  5. package/dist/agent/pending-asks.js.map +1 -0
  6. package/dist/agent/task-registry.d.ts +14 -0
  7. package/dist/agent/task-registry.js +80 -0
  8. package/dist/agent/task-registry.js.map +1 -0
  9. package/dist/agent/tool-context.d.ts +30 -0
  10. package/dist/agent/tool-context.js +10 -0
  11. package/dist/agent/tool-context.js.map +1 -0
  12. package/dist/agent/usage.d.ts +40 -0
  13. package/dist/agent/usage.js +122 -0
  14. package/dist/agent/usage.js.map +1 -0
  15. package/dist/api/host/agent.d.ts +165 -0
  16. package/dist/api/host/agent.js +5 -0
  17. package/dist/api/host/agent.js.map +1 -0
  18. package/dist/api/host/events.d.ts +2 -0
  19. package/dist/api/host/events.js +6 -0
  20. package/dist/api/host/events.js.map +1 -0
  21. package/dist/api/host/exec.d.ts +36 -0
  22. package/dist/api/host/exec.js +10 -0
  23. package/dist/api/host/exec.js.map +1 -0
  24. package/dist/api/host/fs.d.ts +24 -0
  25. package/dist/api/host/fs.js +7 -0
  26. package/dist/api/host/fs.js.map +1 -0
  27. package/dist/api/host/hooks.d.ts +210 -0
  28. package/dist/api/host/hooks.js +401 -0
  29. package/dist/api/host/hooks.js.map +1 -0
  30. package/dist/api/host/host.d.ts +36 -0
  31. package/dist/api/host/host.js +53 -0
  32. package/dist/api/host/host.js.map +1 -0
  33. package/dist/api/host/http.d.ts +58 -0
  34. package/dist/api/host/http.js +6 -0
  35. package/dist/api/host/http.js.map +1 -0
  36. package/dist/api/host/index.d.ts +15 -0
  37. package/dist/api/host/index.js +20 -0
  38. package/dist/api/host/index.js.map +1 -0
  39. package/dist/api/host/models.d.ts +65 -0
  40. package/dist/api/host/models.js +8 -0
  41. package/dist/api/host/models.js.map +1 -0
  42. package/dist/api/host/network.d.ts +22 -0
  43. package/dist/api/host/network.js +7 -0
  44. package/dist/api/host/network.js.map +1 -0
  45. package/dist/api/host/plugin.d.ts +138 -0
  46. package/dist/api/host/plugin.js +6 -0
  47. package/dist/api/host/plugin.js.map +1 -0
  48. package/dist/api/host/plugins.d.ts +49 -0
  49. package/dist/api/host/plugins.js +6 -0
  50. package/dist/api/host/plugins.js.map +1 -0
  51. package/dist/api/host/pty.d.ts +55 -0
  52. package/dist/api/host/pty.js +21 -0
  53. package/dist/api/host/pty.js.map +1 -0
  54. package/dist/api/host/session.d.ts +5 -0
  55. package/dist/api/host/session.js +52 -0
  56. package/dist/api/host/session.js.map +1 -0
  57. package/dist/api/host/version.d.ts +2 -0
  58. package/dist/api/host/version.js +3 -0
  59. package/dist/api/host/version.js.map +1 -0
  60. package/dist/api/host/workspace.d.ts +38 -0
  61. package/dist/api/host/workspace.js +9 -0
  62. package/dist/api/host/workspace.js.map +1 -0
  63. package/dist/api/plugin/http-client.d.ts +42 -0
  64. package/dist/api/plugin/http-client.js +364 -0
  65. package/dist/api/plugin/http-client.js.map +1 -0
  66. package/dist/api/plugin/http-protocol.d.ts +152 -0
  67. package/dist/api/plugin/http-protocol.js +49 -0
  68. package/dist/api/plugin/http-protocol.js.map +1 -0
  69. package/dist/api/result/result.d.ts +16 -0
  70. package/dist/api/result/result.js +43 -0
  71. package/dist/api/result/result.js.map +1 -0
  72. package/dist/commands/agent-turn.d.ts +63 -0
  73. package/dist/commands/agent-turn.js +687 -0
  74. package/dist/commands/agent-turn.js.map +1 -0
  75. package/dist/commands/ask-prompt.d.ts +6 -0
  76. package/dist/commands/ask-prompt.js +49 -0
  77. package/dist/commands/ask-prompt.js.map +1 -0
  78. package/dist/commands/config.d.ts +2 -0
  79. package/dist/commands/config.js +283 -0
  80. package/dist/commands/config.js.map +1 -0
  81. package/dist/commands/conversation.d.ts +51 -0
  82. package/dist/commands/conversation.js +630 -0
  83. package/dist/commands/conversation.js.map +1 -0
  84. package/dist/commands/doctor.d.ts +2 -0
  85. package/dist/commands/doctor.js +77 -0
  86. package/dist/commands/doctor.js.map +1 -0
  87. package/dist/commands/exec-approval.d.ts +3 -0
  88. package/dist/commands/exec-approval.js +80 -0
  89. package/dist/commands/exec-approval.js.map +1 -0
  90. package/dist/commands/help.d.ts +2 -0
  91. package/dist/commands/help.js +35 -0
  92. package/dist/commands/help.js.map +1 -0
  93. package/dist/commands/key.d.ts +2 -0
  94. package/dist/commands/key.js +226 -0
  95. package/dist/commands/key.js.map +1 -0
  96. package/dist/commands/plugin.d.ts +2 -0
  97. package/dist/commands/plugin.js +190 -0
  98. package/dist/commands/plugin.js.map +1 -0
  99. package/dist/commands/session.d.ts +2 -0
  100. package/dist/commands/session.js +167 -0
  101. package/dist/commands/session.js.map +1 -0
  102. package/dist/commands/shared.d.ts +35 -0
  103. package/dist/commands/shared.js +66 -0
  104. package/dist/commands/shared.js.map +1 -0
  105. package/dist/commands/start.d.ts +2 -0
  106. package/dist/commands/start.js +75 -0
  107. package/dist/commands/start.js.map +1 -0
  108. package/dist/commands/stop.d.ts +2 -0
  109. package/dist/commands/stop.js +24 -0
  110. package/dist/commands/stop.js.map +1 -0
  111. package/dist/commands/version.d.ts +2 -0
  112. package/dist/commands/version.js +33 -0
  113. package/dist/commands/version.js.map +1 -0
  114. package/dist/config/codes.d.ts +13 -0
  115. package/dist/config/codes.js +15 -0
  116. package/dist/config/codes.js.map +1 -0
  117. package/dist/config/credentials.d.ts +67 -0
  118. package/dist/config/credentials.js +214 -0
  119. package/dist/config/credentials.js.map +1 -0
  120. package/dist/config/defaults.d.ts +5 -0
  121. package/dist/config/defaults.js +31 -0
  122. package/dist/config/defaults.js.map +1 -0
  123. package/dist/config/index.d.ts +5 -0
  124. package/dist/config/index.js +10 -0
  125. package/dist/config/index.js.map +1 -0
  126. package/dist/config/loader.d.ts +10 -0
  127. package/dist/config/loader.js +68 -0
  128. package/dist/config/loader.js.map +1 -0
  129. package/dist/config/providers.d.ts +30 -0
  130. package/dist/config/providers.js +97 -0
  131. package/dist/config/providers.js.map +1 -0
  132. package/dist/config/types.d.ts +75 -0
  133. package/dist/config/types.js +4 -0
  134. package/dist/config/types.js.map +1 -0
  135. package/dist/config/validate.d.ts +4 -0
  136. package/dist/config/validate.js +391 -0
  137. package/dist/config/validate.js.map +1 -0
  138. package/dist/display/markdown.d.ts +7 -0
  139. package/dist/display/markdown.js +116 -0
  140. package/dist/display/markdown.js.map +1 -0
  141. package/dist/display/tool-label.d.ts +6 -0
  142. package/dist/display/tool-label.js +81 -0
  143. package/dist/display/tool-label.js.map +1 -0
  144. package/dist/event/event.d.ts +27 -0
  145. package/dist/event/event.js +152 -0
  146. package/dist/event/event.js.map +1 -0
  147. package/dist/index.d.ts +2 -0
  148. package/dist/index.js +308 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/input/codes.d.ts +15 -0
  151. package/dist/input/codes.js +20 -0
  152. package/dist/input/codes.js.map +1 -0
  153. package/dist/input/commands.d.ts +10 -0
  154. package/dist/input/commands.js +65 -0
  155. package/dist/input/commands.js.map +1 -0
  156. package/dist/input/help.d.ts +8 -0
  157. package/dist/input/help.js +51 -0
  158. package/dist/input/help.js.map +1 -0
  159. package/dist/input/index.d.ts +6 -0
  160. package/dist/input/index.js +10 -0
  161. package/dist/input/index.js.map +1 -0
  162. package/dist/input/parse-options.d.ts +11 -0
  163. package/dist/input/parse-options.js +51 -0
  164. package/dist/input/parse-options.js.map +1 -0
  165. package/dist/input/parse.d.ts +3 -0
  166. package/dist/input/parse.js +119 -0
  167. package/dist/input/parse.js.map +1 -0
  168. package/dist/input/types.d.ts +17 -0
  169. package/dist/input/types.js +2 -0
  170. package/dist/input/types.js.map +1 -0
  171. package/dist/logger/elog4js.d.ts +65 -0
  172. package/dist/logger/elog4js.js +305 -0
  173. package/dist/logger/elog4js.js.map +1 -0
  174. package/dist/logger/logger.d.ts +37 -0
  175. package/dist/logger/logger.js +196 -0
  176. package/dist/logger/logger.js.map +1 -0
  177. package/dist/network/index.d.ts +2 -0
  178. package/dist/network/index.js +6 -0
  179. package/dist/network/index.js.map +1 -0
  180. package/dist/network/openai.d.ts +117 -0
  181. package/dist/network/openai.js +443 -0
  182. package/dist/network/openai.js.map +1 -0
  183. package/dist/network/proxy.d.ts +9 -0
  184. package/dist/network/proxy.js +72 -0
  185. package/dist/network/proxy.js.map +1 -0
  186. package/dist/network/web.d.ts +34 -0
  187. package/dist/network/web.js +152 -0
  188. package/dist/network/web.js.map +1 -0
  189. package/dist/platform/clipboard.d.ts +15 -0
  190. package/dist/platform/clipboard.js +82 -0
  191. package/dist/platform/clipboard.js.map +1 -0
  192. package/dist/platform/exec.d.ts +28 -0
  193. package/dist/platform/exec.js +95 -0
  194. package/dist/platform/exec.js.map +1 -0
  195. package/dist/platform/file.d.ts +38 -0
  196. package/dist/platform/file.js +197 -0
  197. package/dist/platform/file.js.map +1 -0
  198. package/dist/platform/index.d.ts +7 -0
  199. package/dist/platform/index.js +12 -0
  200. package/dist/platform/index.js.map +1 -0
  201. package/dist/platform/notification.d.ts +14 -0
  202. package/dist/platform/notification.js +82 -0
  203. package/dist/platform/notification.js.map +1 -0
  204. package/dist/platform/open-external.d.ts +10 -0
  205. package/dist/platform/open-external.js +105 -0
  206. package/dist/platform/open-external.js.map +1 -0
  207. package/dist/platform/os.d.ts +20 -0
  208. package/dist/platform/os.js +86 -0
  209. package/dist/platform/os.js.map +1 -0
  210. package/dist/platform/path.d.ts +32 -0
  211. package/dist/platform/path.js +154 -0
  212. package/dist/platform/path.js.map +1 -0
  213. package/dist/plugin/access-guard.d.ts +1 -0
  214. package/dist/plugin/access-guard.js +40 -0
  215. package/dist/plugin/access-guard.js.map +1 -0
  216. package/dist/plugin/agent-service.d.ts +25 -0
  217. package/dist/plugin/agent-service.js +809 -0
  218. package/dist/plugin/agent-service.js.map +1 -0
  219. package/dist/plugin/agent-tools.d.ts +12 -0
  220. package/dist/plugin/agent-tools.js +31 -0
  221. package/dist/plugin/agent-tools.js.map +1 -0
  222. package/dist/plugin/capabilities.d.ts +26 -0
  223. package/dist/plugin/capabilities.js +192 -0
  224. package/dist/plugin/capabilities.js.map +1 -0
  225. package/dist/plugin/console-guard.d.ts +2 -0
  226. package/dist/plugin/console-guard.js +52 -0
  227. package/dist/plugin/console-guard.js.map +1 -0
  228. package/dist/plugin/data-access.d.ts +15 -0
  229. package/dist/plugin/data-access.js +57 -0
  230. package/dist/plugin/data-access.js.map +1 -0
  231. package/dist/plugin/fs.d.ts +3 -0
  232. package/dist/plugin/fs.js +93 -0
  233. package/dist/plugin/fs.js.map +1 -0
  234. package/dist/plugin/host-alias.d.ts +2 -0
  235. package/dist/plugin/host-alias.js +57 -0
  236. package/dist/plugin/host-alias.js.map +1 -0
  237. package/dist/plugin/index.d.ts +7 -0
  238. package/dist/plugin/index.js +11 -0
  239. package/dist/plugin/index.js.map +1 -0
  240. package/dist/plugin/install.d.ts +17 -0
  241. package/dist/plugin/install.js +163 -0
  242. package/dist/plugin/install.js.map +1 -0
  243. package/dist/plugin/loader.d.ts +45 -0
  244. package/dist/plugin/loader.js +739 -0
  245. package/dist/plugin/loader.js.map +1 -0
  246. package/dist/plugin/manage.d.ts +31 -0
  247. package/dist/plugin/manage.js +271 -0
  248. package/dist/plugin/manage.js.map +1 -0
  249. package/dist/plugin/models-service.d.ts +15 -0
  250. package/dist/plugin/models-service.js +317 -0
  251. package/dist/plugin/models-service.js.map +1 -0
  252. package/dist/plugin/network-service.d.ts +10 -0
  253. package/dist/plugin/network-service.js +87 -0
  254. package/dist/plugin/network-service.js.map +1 -0
  255. package/dist/plugin/package-manager.d.ts +46 -0
  256. package/dist/plugin/package-manager.js +148 -0
  257. package/dist/plugin/package-manager.js.map +1 -0
  258. package/dist/plugin/paths.d.ts +6 -0
  259. package/dist/plugin/paths.js +15 -0
  260. package/dist/plugin/paths.js.map +1 -0
  261. package/dist/plugin/registry.d.ts +17 -0
  262. package/dist/plugin/registry.js +82 -0
  263. package/dist/plugin/registry.js.map +1 -0
  264. package/dist/plugin/runtime.d.ts +9 -0
  265. package/dist/plugin/runtime.js +43 -0
  266. package/dist/plugin/runtime.js.map +1 -0
  267. package/dist/plugin/scaffold.d.ts +13 -0
  268. package/dist/plugin/scaffold.js +132 -0
  269. package/dist/plugin/scaffold.js.map +1 -0
  270. package/dist/plugin/state.d.ts +6 -0
  271. package/dist/plugin/state.js +38 -0
  272. package/dist/plugin/state.js.map +1 -0
  273. package/dist/plugin/zip.d.ts +7 -0
  274. package/dist/plugin/zip.js +138 -0
  275. package/dist/plugin/zip.js.map +1 -0
  276. package/dist/sandbox/audit.d.ts +12 -0
  277. package/dist/sandbox/audit.js +20 -0
  278. package/dist/sandbox/audit.js.map +1 -0
  279. package/dist/sandbox/backends/bwrap.d.ts +28 -0
  280. package/dist/sandbox/backends/bwrap.js +197 -0
  281. package/dist/sandbox/backends/bwrap.js.map +1 -0
  282. package/dist/sandbox/backends/direct.d.ts +7 -0
  283. package/dist/sandbox/backends/direct.js +32 -0
  284. package/dist/sandbox/backends/direct.js.map +1 -0
  285. package/dist/sandbox/bridge-state.d.ts +13 -0
  286. package/dist/sandbox/bridge-state.js +12 -0
  287. package/dist/sandbox/bridge-state.js.map +1 -0
  288. package/dist/sandbox/index.d.ts +5 -0
  289. package/dist/sandbox/index.js +6 -0
  290. package/dist/sandbox/index.js.map +1 -0
  291. package/dist/sandbox/manager.d.ts +8 -0
  292. package/dist/sandbox/manager.js +325 -0
  293. package/dist/sandbox/manager.js.map +1 -0
  294. package/dist/sandbox/memory-limit.d.ts +44 -0
  295. package/dist/sandbox/memory-limit.js +193 -0
  296. package/dist/sandbox/memory-limit.js.map +1 -0
  297. package/dist/sandbox/plugin-client.d.ts +80 -0
  298. package/dist/sandbox/plugin-client.js +1601 -0
  299. package/dist/sandbox/plugin-client.js.map +1 -0
  300. package/dist/sandbox/plugin-host.d.ts +1 -0
  301. package/dist/sandbox/plugin-host.js +1001 -0
  302. package/dist/sandbox/plugin-host.js.map +1 -0
  303. package/dist/sandbox/protocol.d.ts +43 -0
  304. package/dist/sandbox/protocol.js +96 -0
  305. package/dist/sandbox/protocol.js.map +1 -0
  306. package/dist/sandbox/rpc-timeouts.d.ts +28 -0
  307. package/dist/sandbox/rpc-timeouts.js +15 -0
  308. package/dist/sandbox/rpc-timeouts.js.map +1 -0
  309. package/dist/sandbox/supervisor.d.ts +31 -0
  310. package/dist/sandbox/supervisor.js +114 -0
  311. package/dist/sandbox/supervisor.js.map +1 -0
  312. package/dist/sandbox/types.d.ts +124 -0
  313. package/dist/sandbox/types.js +17 -0
  314. package/dist/sandbox/types.js.map +1 -0
  315. package/dist/service/control.d.ts +32 -0
  316. package/dist/service/control.js +117 -0
  317. package/dist/service/control.js.map +1 -0
  318. package/dist/session/compress.d.ts +3 -0
  319. package/dist/session/compress.js +42 -0
  320. package/dist/session/compress.js.map +1 -0
  321. package/dist/session/index.d.ts +4 -0
  322. package/dist/session/index.js +8 -0
  323. package/dist/session/index.js.map +1 -0
  324. package/dist/session/registry.d.ts +4 -0
  325. package/dist/session/registry.js +12 -0
  326. package/dist/session/registry.js.map +1 -0
  327. package/dist/session/replay.d.ts +10 -0
  328. package/dist/session/replay.js +109 -0
  329. package/dist/session/replay.js.map +1 -0
  330. package/dist/session/session.d.ts +40 -0
  331. package/dist/session/session.js +108 -0
  332. package/dist/session/session.js.map +1 -0
  333. package/dist/session/store.d.ts +58 -0
  334. package/dist/session/store.js +382 -0
  335. package/dist/session/store.js.map +1 -0
  336. package/dist/session/types.d.ts +56 -0
  337. package/dist/session/types.js +3 -0
  338. package/dist/session/types.js.map +1 -0
  339. package/dist/workspace/index.d.ts +7 -0
  340. package/dist/workspace/index.js +17 -0
  341. package/dist/workspace/index.js.map +1 -0
  342. package/dist/workspace/registry.d.ts +25 -0
  343. package/dist/workspace/registry.js +293 -0
  344. package/dist/workspace/registry.js.map +1 -0
  345. package/package.json +73 -5
  346. package/scripts/build-node-pty.mjs +55 -0
  347. package/scripts/rewrite-dts.mjs +36 -0
  348. package/scripts/run-tests.mjs +41 -0
  349. package/scripts/verify-sandbox.ts +98 -0
  350. package/src/agent/pending-asks.ts +88 -0
  351. package/src/agent/task-registry.ts +108 -0
  352. package/src/agent/tool-context.ts +47 -0
  353. package/src/agent/usage.ts +170 -0
  354. package/src/api/host/agent.ts +162 -0
  355. package/src/api/host/events.ts +7 -0
  356. package/src/api/host/exec.ts +47 -0
  357. package/src/api/host/fs.ts +33 -0
  358. package/src/api/host/hooks.ts +635 -0
  359. package/src/api/host/host.ts +99 -0
  360. package/src/api/host/http.ts +79 -0
  361. package/src/api/host/index.ts +20 -0
  362. package/src/api/host/models.ts +81 -0
  363. package/src/api/host/network.ts +32 -0
  364. package/src/api/host/plugin.ts +158 -0
  365. package/src/api/host/plugins.ts +59 -0
  366. package/src/api/host/pty.ts +73 -0
  367. package/src/api/host/session.ts +61 -0
  368. package/src/api/host/version.ts +2 -0
  369. package/src/api/host/workspace.ts +51 -0
  370. package/src/api/plugin/http-client.ts +492 -0
  371. package/src/api/plugin/http-protocol.ts +231 -0
  372. package/src/api/result/result.ts +52 -0
  373. package/src/commands/agent-turn.ts +817 -0
  374. package/src/commands/ask-prompt.ts +52 -0
  375. package/src/commands/config.ts +306 -0
  376. package/src/commands/conversation.ts +777 -0
  377. package/src/commands/doctor.ts +92 -0
  378. package/src/commands/exec-approval.ts +91 -0
  379. package/src/commands/help.ts +41 -0
  380. package/src/commands/key.ts +281 -0
  381. package/src/commands/plugin.ts +222 -0
  382. package/src/commands/session.ts +179 -0
  383. package/src/commands/shared.ts +103 -0
  384. package/src/commands/start.ts +88 -0
  385. package/src/commands/stop.ts +24 -0
  386. package/src/commands/version.ts +40 -0
  387. package/src/config/codes.ts +17 -0
  388. package/src/config/credentials.ts +302 -0
  389. package/src/config/defaults.ts +32 -0
  390. package/src/config/index.ts +10 -0
  391. package/src/config/loader.ts +80 -0
  392. package/src/config/providers.ts +133 -0
  393. package/src/config/types.ts +88 -0
  394. package/src/config/validate.ts +458 -0
  395. package/src/display/markdown.ts +137 -0
  396. package/src/display/tool-label.ts +87 -0
  397. package/src/event/event.ts +171 -0
  398. package/src/index.ts +344 -0
  399. package/src/input/codes.ts +21 -0
  400. package/src/input/commands.ts +76 -0
  401. package/src/input/help.ts +60 -0
  402. package/src/input/index.ts +10 -0
  403. package/src/input/parse-options.ts +66 -0
  404. package/src/input/parse.ts +138 -0
  405. package/src/input/types.ts +19 -0
  406. package/src/logger/elog4js.ts +366 -0
  407. package/src/logger/logger.ts +251 -0
  408. package/src/network/index.ts +6 -0
  409. package/src/network/openai.ts +571 -0
  410. package/src/network/proxy.ts +80 -0
  411. package/src/network/web.ts +206 -0
  412. package/src/platform/clipboard.ts +107 -0
  413. package/src/platform/exec.ts +128 -0
  414. package/src/platform/file.ts +235 -0
  415. package/src/platform/index.ts +12 -0
  416. package/src/platform/notification.ts +108 -0
  417. package/src/platform/open-external.ts +132 -0
  418. package/src/platform/os.ts +101 -0
  419. package/src/platform/path.ts +214 -0
  420. package/src/plugin/access-guard.ts +46 -0
  421. package/src/plugin/agent-service.ts +969 -0
  422. package/src/plugin/agent-tools.ts +43 -0
  423. package/src/plugin/capabilities.ts +240 -0
  424. package/src/plugin/console-guard.ts +66 -0
  425. package/src/plugin/data-access.ts +70 -0
  426. package/src/plugin/fs.ts +109 -0
  427. package/src/plugin/host-alias.ts +61 -0
  428. package/src/plugin/index.ts +11 -0
  429. package/src/plugin/install.ts +213 -0
  430. package/src/plugin/loader.ts +952 -0
  431. package/src/plugin/manage.ts +338 -0
  432. package/src/plugin/models-service.ts +383 -0
  433. package/src/plugin/network-service.ts +102 -0
  434. package/src/plugin/package-manager.ts +214 -0
  435. package/src/plugin/paths.ts +19 -0
  436. package/src/plugin/registry.ts +103 -0
  437. package/src/plugin/runtime.ts +57 -0
  438. package/src/plugin/scaffold.ts +158 -0
  439. package/src/plugin/state.ts +52 -0
  440. package/src/plugin/zip.ts +156 -0
  441. package/src/sandbox/audit.ts +38 -0
  442. package/src/sandbox/backends/bwrap.ts +251 -0
  443. package/src/sandbox/backends/direct.ts +43 -0
  444. package/src/sandbox/bridge-state.ts +29 -0
  445. package/src/sandbox/index.ts +5 -0
  446. package/src/sandbox/manager.ts +406 -0
  447. package/src/sandbox/memory-limit.ts +245 -0
  448. package/src/sandbox/plugin-client.ts +1881 -0
  449. package/src/sandbox/plugin-host.ts +1282 -0
  450. package/src/sandbox/protocol.ts +142 -0
  451. package/src/sandbox/pty-bridge.py +154 -0
  452. package/src/sandbox/rpc-timeouts.ts +43 -0
  453. package/src/sandbox/supervisor.ts +172 -0
  454. package/src/sandbox/types.ts +149 -0
  455. package/src/service/control.ts +155 -0
  456. package/src/session/compress.ts +47 -0
  457. package/src/session/index.ts +8 -0
  458. package/src/session/registry.ts +17 -0
  459. package/src/session/replay.ts +132 -0
  460. package/src/session/session.ts +134 -0
  461. package/src/session/store.ts +468 -0
  462. package/src/session/types.ts +61 -0
  463. package/src/workspace/index.ts +21 -0
  464. package/src/workspace/registry.ts +356 -0
@@ -0,0 +1,687 @@
1
+ /*
2
+ * Agent 轮次:run 模式的工具循环
3
+ */
4
+ import { randomUUID } from "node:crypto";
5
+ import { emitAfterStep, emitAfterTurn, emitAgentAsk, emitAgentCallTool, emitAgentRunSync, emitAgentSubmit, emitBeforeStep, emitBeforeTurn, emitOnMessage, emitSessionStart, emitUserAnswer, } from "../api/host/hooks.js";
6
+ import { createAskId, cancelAsk, waitForAsk } from "../agent/pending-asks.js";
7
+ import { compactUsage, usageOf } from "../agent/usage.js";
8
+ import { toolLabel, toolSummary } from "../display/tool-label.js";
9
+ import { withAgentToolContext } from "../agent/tool-context.js";
10
+ import { Result } from "../api/result/result.js";
11
+ import { createMarkdownStream, renderMarkdown } from "../display/markdown.js";
12
+ import { lastSeq, lastTurnNumber, toChatMessages } from "../session/replay.js";
13
+ import { getSession } from "../session/registry.js";
14
+ /** 平台内置提问工具:模型用它向用户要信息,宿主等回答后再继续 */
15
+ const ASK_TOOL_NAME = "ask";
16
+ const ASK_QUESTION_LIMIT = 2000;
17
+ const ASK_OPTION_LIMIT = 10;
18
+ const ASK_ANSWER_LIMIT = 8000;
19
+ const ASK_TOOL_DESCRIPTION = "向用户提问并等待回答。用于缺少必要信息、需要在几个方案里选择或确认时。问题要简短、自包含,用用户看得懂的话;不要用它代替执行任务。如果你推荐某个选项,把它放第一个,并在标签后加「(推荐)」。";
20
+ const ASK_TOOL_SCHEMA = {
21
+ type: "function",
22
+ function: {
23
+ name: ASK_TOOL_NAME,
24
+ description: ASK_TOOL_DESCRIPTION,
25
+ parameters: {
26
+ type: "object",
27
+ additionalProperties: false,
28
+ required: ["question"],
29
+ properties: {
30
+ question: { type: "string", description: "要问用户的问题" },
31
+ options: {
32
+ type: "array",
33
+ items: { type: "string" },
34
+ description: "可选答案;推荐的选项放第一个并在标签后加「(推荐)」,用户也可以自由输入",
35
+ },
36
+ },
37
+ },
38
+ },
39
+ };
40
+ /** 推给界面的工具输出上限;完整内容仍写进会话 */
41
+ const TOOL_EVENT_RESULT_LIMIT = 4000;
42
+ function toolEventResult(text) {
43
+ if (text.length <= TOOL_EVENT_RESULT_LIMIT) {
44
+ return { result: text, truncated: false };
45
+ }
46
+ return { result: text.slice(0, TOOL_EVENT_RESULT_LIMIT), truncated: true };
47
+ }
48
+ function parseToolArguments(raw) {
49
+ try {
50
+ const value = JSON.parse(raw);
51
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
52
+ return value;
53
+ }
54
+ return {};
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ function toolCallParts(toolCalls) {
61
+ return toolCalls.map((call) => ({
62
+ type: "tool-call",
63
+ id: call.id,
64
+ name: call.name,
65
+ arguments: call.arguments,
66
+ }));
67
+ }
68
+ // 插件工具 → 模型 schema
69
+ function pluginToolSchema(tool) {
70
+ const entries = Object.entries(tool.introduction.params);
71
+ const required = [];
72
+ const properties = {};
73
+ for (const [name, spec] of entries) {
74
+ if (typeof spec === "string") {
75
+ required.push(name);
76
+ properties[name] = { type: "string", description: spec };
77
+ continue;
78
+ }
79
+ if (spec.optional !== true) {
80
+ required.push(name);
81
+ }
82
+ properties[name] = {
83
+ type: spec.type ?? "string",
84
+ ...(spec.description === undefined ? {} : { description: spec.description }),
85
+ ...(spec.enum === undefined ? {} : { enum: [...spec.enum] }),
86
+ ...(spec.items === undefined ? {} : { items: { ...spec.items } }),
87
+ };
88
+ }
89
+ return {
90
+ type: "function",
91
+ function: {
92
+ name: tool.name,
93
+ description: tool.introduction.content,
94
+ parameters: {
95
+ type: "object",
96
+ additionalProperties: false,
97
+ required,
98
+ properties,
99
+ },
100
+ },
101
+ };
102
+ }
103
+ /**
104
+ * 单步 usage:缓存/推理字段只在供应商报告时出现,inputTokens 同时是本步的上下文占用
105
+ */
106
+ function stepUsage(reply) {
107
+ return { ...usageOf(reply) };
108
+ }
109
+ export async function executeAgentTurn(params) {
110
+ const { ctx, client, store, session, input, model, system, stream, display } = params;
111
+ const turn = lastTurnNumber(session.events) + 1;
112
+ let seq = lastSeq(session.events) + 1;
113
+ const startedAt = Date.now();
114
+ await emitBeforeTurn({
115
+ sessionId: session.meta.id,
116
+ mode: "run",
117
+ turn,
118
+ input,
119
+ cwd: session.meta.workspace ?? session.meta.cwd,
120
+ });
121
+ await emitAgentRunSync({
122
+ sessionId: session.meta.id,
123
+ turn,
124
+ input,
125
+ cwd: session.meta.workspace ?? session.meta.cwd,
126
+ });
127
+ const events = [
128
+ { type: "turn/start", seq: seq++, time: startedAt, data: { turn, mode: "run" } },
129
+ {
130
+ type: "user/message",
131
+ seq: seq++,
132
+ time: Date.now(),
133
+ data: {
134
+ message: {
135
+ role: "user",
136
+ content: [{ type: "text", text: input }],
137
+ source: { kind: "cli" },
138
+ id: randomUUID(),
139
+ },
140
+ surfaceOp: "append",
141
+ },
142
+ },
143
+ ];
144
+ /*
145
+ * 本轮事件边产生边落盘:进程在流式过程中被停掉/重启时,至少留下已经开始的
146
+ * 这一轮(尤其是用户消息),下一轮不会突然「失忆」。
147
+ * persisted 记录已写入的条数,避免重复追加。
148
+ */
149
+ let persisted = 0;
150
+ const persistPending = async () => {
151
+ if (events.length <= persisted) {
152
+ return;
153
+ }
154
+ await store.appendTurn(session, events.slice(persisted));
155
+ persisted = events.length;
156
+ };
157
+ const pluginTools = ctx.agentTools.list();
158
+ // 插件可以自己提供同名工具覆盖内置 ask
159
+ const askToolBuiltin = ctx.agentTools.get(ASK_TOOL_NAME) === undefined;
160
+ const availableTools = [
161
+ ...pluginTools.map((record) => ({
162
+ name: record.tool.name,
163
+ description: record.tool.introduction.content,
164
+ })),
165
+ ...(askToolBuiltin ? [{ name: ASK_TOOL_NAME, description: ASK_TOOL_DESCRIPTION }] : []),
166
+ ];
167
+ const prompt = [];
168
+ if (system !== undefined && system.trim() !== "") {
169
+ prompt.push(system);
170
+ }
171
+ // 会话的第一轮:只触发一次,适合注入一次性的 system prompt
172
+ if (turn === 1) {
173
+ await emitSessionStart({
174
+ sessionId: session.meta.id,
175
+ mode: "run",
176
+ turn,
177
+ input,
178
+ cwd: session.meta.workspace ?? session.meta.cwd,
179
+ time: startedAt,
180
+ timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
181
+ model,
182
+ permission: params.permission ?? ctx.settings.sandbox.access,
183
+ tools: availableTools,
184
+ prompt,
185
+ });
186
+ }
187
+ await emitOnMessage({
188
+ sessionId: session.meta.id,
189
+ mode: "run",
190
+ turn,
191
+ role: "user",
192
+ phase: "before",
193
+ content: input,
194
+ prompt,
195
+ });
196
+ const messages = [];
197
+ const systemText = prompt
198
+ .map((item) => item.trim())
199
+ .filter((item) => item !== "")
200
+ .join("\n\n");
201
+ if (systemText !== "") {
202
+ messages.push({ role: "system", content: systemText });
203
+ }
204
+ messages.push(...toChatMessages(session.events), { role: "user", content: input });
205
+ // 模型入参已经拼好(不能再把本轮用户消息重复算进历史),此时把开头事件落盘
206
+ await persistPending();
207
+ const hostSession = getSession(session.meta.id);
208
+ hostSession?.begin();
209
+ const maxSteps = params.maxSteps ?? Number.POSITIVE_INFINITY;
210
+ let stepsExecuted = 0;
211
+ const toolDefinitions = pluginTools.map((record) => pluginToolSchema(record.tool));
212
+ if (askToolBuiltin) {
213
+ toolDefinitions.push(ASK_TOOL_SCHEMA);
214
+ }
215
+ let finalText = "";
216
+ let printedStepText = "";
217
+ let finalModel = model;
218
+ let inputTokens = null;
219
+ let outputTokens = null;
220
+ let cacheReadTokens = null;
221
+ let cacheWriteTokens = null;
222
+ let reasoningTokens = null;
223
+ /* 最后一次请求的 prompt tokens:本轮收尾时上下文里实际占用了多少 */
224
+ let contextTokens = null;
225
+ const streamed = display && stream;
226
+ const markdownEnabled = display && process.stdout.isTTY === true;
227
+ const fail = async (code) => {
228
+ events.push({
229
+ type: "turn/end",
230
+ seq: seq++,
231
+ time: Date.now(),
232
+ data: { turn, reason: { kind: "failed", code } },
233
+ });
234
+ await persistPending();
235
+ hostSession?.end();
236
+ await emitAfterTurn({
237
+ sessionId: session.meta.id,
238
+ mode: "run",
239
+ turn,
240
+ reason: "failed",
241
+ code,
242
+ });
243
+ if (streamed) {
244
+ ctx.elog.line();
245
+ }
246
+ return Result.error(code);
247
+ };
248
+ const runAskTool = async (rawArguments, askStep) => {
249
+ const args = parseToolArguments(rawArguments);
250
+ const rawQuestion = args["question"];
251
+ const question = typeof rawQuestion === "string" ? rawQuestion.trim().slice(0, ASK_QUESTION_LIMIT) : "";
252
+ if (question === "") {
253
+ return { content: "ask 工具缺少 question 参数", ok: false };
254
+ }
255
+ const options = [];
256
+ if (Array.isArray(args["options"])) {
257
+ for (const item of args["options"]) {
258
+ if (typeof item !== "string") {
259
+ continue;
260
+ }
261
+ const value = item.trim();
262
+ if (value === "") {
263
+ continue;
264
+ }
265
+ options.push(value.slice(0, 200));
266
+ if (options.length >= ASK_OPTION_LIMIT) {
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ const askId = createAskId();
272
+ const request = {
273
+ askId,
274
+ question,
275
+ ...(options.length === 0 ? {} : { options }),
276
+ };
277
+ const waiting = params.askUser === undefined ? waitForAsk({ askId, sessionId: session.meta.id }) : null;
278
+ try {
279
+ await emitAgentAsk({
280
+ sessionId: session.meta.id,
281
+ askId,
282
+ turn,
283
+ step: askStep,
284
+ question,
285
+ ...(options.length === 0 ? {} : { options }),
286
+ });
287
+ try {
288
+ params.onAsk?.(request);
289
+ }
290
+ catch {
291
+ return { content: "提问没有送达用户,已跳过。", ok: false };
292
+ }
293
+ const answer = params.askUser === undefined ? await waiting : await params.askUser(request);
294
+ if (answer !== null) {
295
+ await emitUserAnswer({
296
+ sessionId: session.meta.id,
297
+ askId,
298
+ answer: answer.slice(0, ASK_ANSWER_LIMIT),
299
+ });
300
+ }
301
+ if (answer === null) {
302
+ return {
303
+ content: "用户没有回答问题。请根据已有信息继续,或说明还需要哪些信息。",
304
+ ok: false,
305
+ };
306
+ }
307
+ const trimmed = answer.trim().slice(0, ASK_ANSWER_LIMIT);
308
+ if (trimmed === "") {
309
+ return { content: "用户跳过了这个问题。", ok: true };
310
+ }
311
+ return { content: `用户回答:${trimmed}`, ok: true };
312
+ }
313
+ finally {
314
+ cancelAsk(askId);
315
+ }
316
+ };
317
+ // 用户点了停止:在步与步之间收尾,不再发起新的模型调用或工具执行
318
+ let stopped = false;
319
+ // 用函数读,避免第一处判断把类型收窄成 false,后面的比较被判成恒假
320
+ const stopRequested = () => hostSession?.stopRequested === true;
321
+ for (let step = 1; step <= maxSteps; step += 1) {
322
+ if (stopRequested()) {
323
+ stopped = true;
324
+ break;
325
+ }
326
+ stepsExecuted = step;
327
+ params.onStep?.({ turn, step });
328
+ events.push({ type: "step/start", seq: seq++, time: Date.now(), data: { turn, step } });
329
+ await emitBeforeStep({
330
+ sessionId: session.meta.id,
331
+ mode: "run",
332
+ turn,
333
+ step,
334
+ input,
335
+ });
336
+ if (display && process.stdout.isTTY === true) {
337
+ ctx.elog.step(step, Number.isFinite(maxSteps) ? maxSteps : undefined);
338
+ }
339
+ const injected = hostSession?.take() ?? [];
340
+ for (const message of injected) {
341
+ const text = message.content.join("");
342
+ messages.push({ role: "user", content: text });
343
+ events.push({
344
+ type: "user/message",
345
+ seq: seq++,
346
+ time: Date.now(),
347
+ data: {
348
+ turn,
349
+ message: {
350
+ role: "user",
351
+ content: [{ type: "text", text }],
352
+ source: { kind: "plugin", type: message.type },
353
+ id: randomUUID(),
354
+ },
355
+ },
356
+ });
357
+ }
358
+ let agentStarted = false;
359
+ let markdownWrote = false;
360
+ let markdown = null;
361
+ const writeMarkdown = (output) => {
362
+ if (output === "") {
363
+ return;
364
+ }
365
+ const text = markdownWrote ? output : output.replace(/^\n+/, "");
366
+ if (text === "") {
367
+ return;
368
+ }
369
+ markdownWrote = true;
370
+ ctx.elog.stream(text);
371
+ };
372
+ const endAgent = () => {
373
+ if (!streamed || !agentStarted) {
374
+ return;
375
+ }
376
+ if (markdown !== null) {
377
+ writeMarkdown(markdown.finish().replace(/\n+$/, ""));
378
+ }
379
+ ctx.elog.line();
380
+ };
381
+ const streamResult = await client.chatStream(messages, {
382
+ model,
383
+ reasoning: params.reasoning,
384
+ ...(params.signal === undefined ? {} : { signal: params.signal }),
385
+ tools: toolDefinitions,
386
+ toolChoice: "auto",
387
+ onReasoning: (text) => {
388
+ params.onReasoning?.(text);
389
+ },
390
+ onText: (text) => {
391
+ params.onDelta?.(text);
392
+ if (!streamed) {
393
+ return;
394
+ }
395
+ if (!agentStarted) {
396
+ ctx.elog.agentStart();
397
+ agentStarted = true;
398
+ if (markdownEnabled) {
399
+ markdown = createMarkdownStream();
400
+ }
401
+ }
402
+ if (markdown !== null) {
403
+ writeMarkdown(markdown.push(text));
404
+ }
405
+ else {
406
+ ctx.elog.stream(text);
407
+ }
408
+ },
409
+ });
410
+ if (!streamResult.isSuccess()) {
411
+ return await fail(streamResult.getCode() ?? "openai.request-failed");
412
+ }
413
+ const data = streamResult.getData();
414
+ if (data === null) {
415
+ return await fail("openai.request-failed");
416
+ }
417
+ finalModel = data.reply.model;
418
+ if (data.reply.text !== "") {
419
+ finalText = data.reply.text;
420
+ }
421
+ if (data.interrupted === true) {
422
+ /*
423
+ * 用户停止:这一次模型调用被信号打断,收到的正文已经记进 finalText。
424
+ * 本轮就地收尾——不执行这次返回的工具调用,也不再进入下一步。
425
+ */
426
+ stopped = true;
427
+ }
428
+ if (data.reply.inputTokens !== null) {
429
+ inputTokens = (inputTokens ?? 0) + data.reply.inputTokens;
430
+ // 最后一次请求的 prompt tokens 就是当时占用的上下文
431
+ contextTokens = data.reply.inputTokens;
432
+ }
433
+ if (data.reply.outputTokens !== null) {
434
+ outputTokens = (outputTokens ?? 0) + data.reply.outputTokens;
435
+ }
436
+ if (data.reply.cacheReadTokens !== undefined && data.reply.cacheReadTokens !== null) {
437
+ cacheReadTokens = (cacheReadTokens ?? 0) + data.reply.cacheReadTokens;
438
+ }
439
+ if (data.reply.cacheWriteTokens !== undefined && data.reply.cacheWriteTokens !== null) {
440
+ cacheWriteTokens = (cacheWriteTokens ?? 0) + data.reply.cacheWriteTokens;
441
+ }
442
+ if (data.reply.reasoningTokens !== undefined && data.reply.reasoningTokens !== null) {
443
+ reasoningTokens = (reasoningTokens ?? 0) + data.reply.reasoningTokens;
444
+ }
445
+ const parts = [];
446
+ if (data.reasoning !== "") {
447
+ parts.push({ type: "reasoning", text: data.reasoning });
448
+ }
449
+ if (data.reply.text !== "") {
450
+ parts.push({ type: "text", text: data.reply.text });
451
+ }
452
+ parts.push(...toolCallParts(data.toolCalls));
453
+ const assistant = {
454
+ role: "assistant",
455
+ content: parts,
456
+ source: { kind: "model", provider: "openai", model: data.reply.model },
457
+ id: data.reply.id,
458
+ };
459
+ events.push({
460
+ type: "assistant/message",
461
+ seq: seq++,
462
+ time: Date.now(),
463
+ data: {
464
+ turn,
465
+ step,
466
+ message: assistant,
467
+ usage: stepUsage(data.reply),
468
+ stream: data.chunks,
469
+ },
470
+ });
471
+ if (data.reply.text !== "") {
472
+ await emitOnMessage({
473
+ sessionId: session.meta.id,
474
+ mode: "run",
475
+ turn,
476
+ role: "assistant",
477
+ phase: "after",
478
+ content: data.reply.text,
479
+ prompt,
480
+ });
481
+ }
482
+ endAgent();
483
+ // 非流式(管道/--no-stream)也按步打印模型输出,让工具调用和消息交替出现(参考 Harness)
484
+ if (display && !streamed && data.reply.text !== "") {
485
+ ctx.elog.agent(markdownEnabled ? renderMarkdown(data.reply.text) : data.reply.text);
486
+ printedStepText = data.reply.text;
487
+ }
488
+ if (data.toolCalls.length === 0) {
489
+ await emitAfterStep({
490
+ sessionId: session.meta.id,
491
+ mode: "run",
492
+ turn,
493
+ step,
494
+ reply: data.reply.text,
495
+ });
496
+ // 最终回答已经生成:先落盘,进程在收尾前退出也不会丢
497
+ await persistPending();
498
+ break;
499
+ }
500
+ const assistantForApi = {
501
+ role: "assistant",
502
+ content: data.reply.text === "" ? null : data.reply.text,
503
+ tool_calls: data.toolCalls.map((call) => ({
504
+ id: call.id,
505
+ type: "function",
506
+ function: { name: call.name, arguments: call.arguments },
507
+ })),
508
+ };
509
+ messages.push(assistantForApi);
510
+ for (const call of data.toolCalls) {
511
+ events.push({
512
+ type: "tool/call",
513
+ seq: seq++,
514
+ time: Date.now(),
515
+ data: {
516
+ turn,
517
+ step,
518
+ callId: call.id,
519
+ name: call.name,
520
+ arguments: call.arguments,
521
+ },
522
+ });
523
+ await emitAgentCallTool({
524
+ sessionId: session.meta.id,
525
+ turn,
526
+ step,
527
+ callId: call.id,
528
+ name: call.name,
529
+ arguments: call.arguments,
530
+ });
531
+ params.onTool?.({
532
+ id: call.id,
533
+ name: call.name,
534
+ phase: "start",
535
+ arguments: call.arguments,
536
+ });
537
+ const args = parseToolArguments(call.arguments);
538
+ ctx.elog.toolCall(toolLabel(call.name), toolSummary(call.name, args));
539
+ let toolContent = "";
540
+ let toolOk = false;
541
+ if (askToolBuiltin && call.name === ASK_TOOL_NAME) {
542
+ const outcome = await runAskTool(call.arguments, step);
543
+ toolContent = outcome.content;
544
+ toolOk = outcome.ok;
545
+ }
546
+ else if (ctx.agentTools.get(call.name) !== undefined) {
547
+ const record = ctx.agentTools.get(call.name);
548
+ if (record === undefined) {
549
+ toolContent = `未知工具:${call.name}`;
550
+ }
551
+ else {
552
+ try {
553
+ const result = await withAgentToolContext({
554
+ sessionId: session.meta.id,
555
+ turn,
556
+ step,
557
+ workspaceDir: session.meta.workspace ?? session.meta.cwd,
558
+ permission: params.permission ?? ctx.settings.sandbox.access,
559
+ allowExec: params.allowExec === true,
560
+ approveExec: params.approveExec === undefined
561
+ ? undefined
562
+ : async (request) => await params.approveExec({
563
+ ...request,
564
+ sessionId: session.meta.id,
565
+ turn,
566
+ step,
567
+ }),
568
+ elog: ctx.elog,
569
+ }, async () => await record.tool.call(args));
570
+ toolContent =
571
+ typeof result.data["content"] === "string"
572
+ ? result.data["content"]
573
+ : result.success
574
+ ? JSON.stringify(result.data)
575
+ : `工具失败:${JSON.stringify(result.data)}`;
576
+ toolOk = result.success;
577
+ }
578
+ catch (error) {
579
+ const message = error instanceof Error ? error.message : String(error);
580
+ toolContent = `工具执行失败:${message}`;
581
+ }
582
+ }
583
+ }
584
+ else {
585
+ toolContent = `未知工具:${call.name}`;
586
+ }
587
+ if (!toolOk) {
588
+ const firstLine = toolContent.split("\n")[0] ?? "";
589
+ ctx.elog.toolResult(`失败:${firstLine.slice(0, 160)}`);
590
+ }
591
+ const toolEvent = toolEventResult(toolContent);
592
+ params.onTool?.({
593
+ id: call.id,
594
+ name: call.name,
595
+ phase: "end",
596
+ ok: toolOk,
597
+ result: toolEvent.result,
598
+ ...(toolEvent.truncated ? { truncated: true } : {}),
599
+ });
600
+ events.push({
601
+ type: "tool/result",
602
+ seq: seq++,
603
+ time: Date.now(),
604
+ data: {
605
+ turn,
606
+ step,
607
+ callId: call.id,
608
+ name: call.name,
609
+ content: toolContent,
610
+ },
611
+ });
612
+ messages.push({
613
+ role: "tool",
614
+ tool_call_id: call.id,
615
+ content: toolContent,
616
+ });
617
+ }
618
+ await emitAfterStep({
619
+ sessionId: session.meta.id,
620
+ mode: "run",
621
+ turn,
622
+ step,
623
+ reply: data.reply.text,
624
+ });
625
+ events.push({
626
+ type: "step/end",
627
+ seq: seq++,
628
+ time: Date.now(),
629
+ data: { turn, step, reason: "completed" },
630
+ });
631
+ // 一步的工具调用与结果都齐了,checkpoint 一次
632
+ await persistPending();
633
+ if (stopRequested()) {
634
+ stopped = true;
635
+ break;
636
+ }
637
+ }
638
+ if (finalText === "") {
639
+ finalText = stopped ? "(已停止)" : "(达到最大步数,未生成最终回答)";
640
+ }
641
+ hostSession?.end();
642
+ await emitAgentSubmit({
643
+ sessionId: session.meta.id,
644
+ result: finalText,
645
+ });
646
+ events.push({
647
+ type: "turn/end",
648
+ seq: seq++,
649
+ time: Date.now(),
650
+ data: { turn, reason: { kind: stopped ? "stopped" : "completed" } },
651
+ });
652
+ await persistPending();
653
+ await emitAfterTurn({
654
+ sessionId: session.meta.id,
655
+ mode: "run",
656
+ turn,
657
+ reason: stopped ? "cancelled" : "completed",
658
+ code: null,
659
+ });
660
+ if (!streamed && display && finalText !== printedStepText) {
661
+ // 只有兜底文案(例如达到最大步数)或最后一步没有正文时才需要补打
662
+ ctx.elog.agent(markdownEnabled ? renderMarkdown(finalText) : finalText);
663
+ }
664
+ const usage = inputTokens === null &&
665
+ outputTokens === null &&
666
+ cacheReadTokens === null &&
667
+ cacheWriteTokens === null
668
+ ? null
669
+ : compactUsage({
670
+ inputTokens,
671
+ outputTokens,
672
+ cacheReadTokens,
673
+ cacheWriteTokens,
674
+ reasoningTokens,
675
+ contextTokens,
676
+ });
677
+ return Result.successWithData({
678
+ sessionId: session.meta.id,
679
+ mode: "run",
680
+ turn,
681
+ steps: stepsExecuted,
682
+ reply: finalText,
683
+ model: finalModel,
684
+ usage,
685
+ });
686
+ }
687
+ //# sourceMappingURL=agent-turn.js.map