@nodetool-ai/agents 0.7.0-rc.22 → 0.8.1

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 (1554) hide show
  1. package/README.md +35 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/analysis/audio-dsp.d.ts +223 -0
  4. package/dist/analysis/audio-dsp.d.ts.map +1 -0
  5. package/dist/analysis/audio-dsp.js +642 -0
  6. package/dist/analysis/audio-dsp.js.map +1 -0
  7. package/dist/analysis/media-decode.d.ts +85 -0
  8. package/dist/analysis/media-decode.d.ts.map +1 -0
  9. package/dist/analysis/media-decode.js +199 -0
  10. package/dist/analysis/media-decode.js.map +1 -0
  11. package/dist/analysis/mediabunny-runtime.d.ts +15 -0
  12. package/dist/analysis/mediabunny-runtime.d.ts.map +1 -0
  13. package/dist/analysis/mediabunny-runtime.js +30 -0
  14. package/dist/analysis/mediabunny-runtime.js.map +1 -0
  15. package/dist/analysis/video-frames.d.ts +120 -0
  16. package/dist/analysis/video-frames.d.ts.map +1 -0
  17. package/dist/analysis/video-frames.js +288 -0
  18. package/dist/analysis/video-frames.js.map +1 -0
  19. package/dist/apify/assets.d.ts +80 -0
  20. package/dist/apify/assets.d.ts.map +1 -0
  21. package/dist/apify/assets.js +192 -0
  22. package/dist/apify/assets.js.map +1 -0
  23. package/dist/apify/catalog.d.ts +44 -0
  24. package/dist/apify/catalog.d.ts.map +1 -0
  25. package/dist/apify/catalog.js +108 -0
  26. package/dist/apify/catalog.js.map +1 -0
  27. package/dist/apify/client.d.ts +137 -0
  28. package/dist/apify/client.d.ts.map +1 -0
  29. package/dist/apify/client.js +346 -0
  30. package/dist/apify/client.js.map +1 -0
  31. package/dist/apify/errors.d.ts +85 -0
  32. package/dist/apify/errors.d.ts.map +1 -0
  33. package/dist/apify/errors.js +90 -0
  34. package/dist/apify/errors.js.map +1 -0
  35. package/dist/apify/normalize.d.ts +131 -0
  36. package/dist/apify/normalize.d.ts.map +1 -0
  37. package/dist/apify/normalize.js +202 -0
  38. package/dist/apify/normalize.js.map +1 -0
  39. package/dist/apify/policy.d.ts +136 -0
  40. package/dist/apify/policy.d.ts.map +1 -0
  41. package/dist/apify/policy.js +223 -0
  42. package/dist/apify/policy.js.map +1 -0
  43. package/dist/apify/run.d.ts +86 -0
  44. package/dist/apify/run.d.ts.map +1 -0
  45. package/dist/apify/run.js +158 -0
  46. package/dist/apify/run.js.map +1 -0
  47. package/dist/app-build/author.d.ts +67 -0
  48. package/dist/app-build/author.d.ts.map +1 -0
  49. package/dist/app-build/author.js +231 -0
  50. package/dist/app-build/author.js.map +1 -0
  51. package/dist/app-build/bridge.d.ts +130 -0
  52. package/dist/app-build/bridge.d.ts.map +1 -0
  53. package/dist/app-build/bridge.js +647 -0
  54. package/dist/app-build/bridge.js.map +1 -0
  55. package/dist/app-build/build-service.d.ts +66 -0
  56. package/dist/app-build/build-service.d.ts.map +1 -0
  57. package/dist/app-build/build-service.js +249 -0
  58. package/dist/app-build/build-service.js.map +1 -0
  59. package/dist/app-build/build.d.ts +115 -0
  60. package/dist/app-build/build.d.ts.map +1 -0
  61. package/dist/app-build/build.js +901 -0
  62. package/dist/app-build/build.js.map +1 -0
  63. package/dist/app-build/interactions.d.ts +20 -0
  64. package/dist/app-build/interactions.d.ts.map +1 -0
  65. package/dist/app-build/interactions.js +121 -0
  66. package/dist/app-build/interactions.js.map +1 -0
  67. package/dist/app-build/judge.d.ts +113 -0
  68. package/dist/app-build/judge.d.ts.map +1 -0
  69. package/dist/app-build/judge.js +318 -0
  70. package/dist/app-build/judge.js.map +1 -0
  71. package/dist/app-build/markdown.d.ts +10 -0
  72. package/dist/app-build/markdown.d.ts.map +1 -0
  73. package/dist/app-build/markdown.js +65 -0
  74. package/dist/app-build/markdown.js.map +1 -0
  75. package/dist/app-build/spec.d.ts +228 -0
  76. package/dist/app-build/spec.d.ts.map +1 -0
  77. package/dist/app-build/spec.js +651 -0
  78. package/dist/app-build/spec.js.map +1 -0
  79. package/dist/app-build/tool-loop.d.ts +84 -0
  80. package/dist/app-build/tool-loop.d.ts.map +1 -0
  81. package/dist/app-build/tool-loop.js +113 -0
  82. package/dist/app-build/tool-loop.js.map +1 -0
  83. package/dist/app-build/types.d.ts +215 -0
  84. package/dist/app-build/types.d.ts.map +1 -0
  85. package/dist/app-build/types.js +28 -0
  86. package/dist/app-build/types.js.map +1 -0
  87. package/dist/author-graph.d.ts +91 -0
  88. package/dist/author-graph.d.ts.map +1 -0
  89. package/dist/author-graph.js +319 -0
  90. package/dist/author-graph.js.map +1 -0
  91. package/dist/background-subtasks.d.ts +79 -0
  92. package/dist/background-subtasks.d.ts.map +1 -0
  93. package/dist/background-subtasks.js +139 -0
  94. package/dist/background-subtasks.js.map +1 -0
  95. package/dist/blender-gate.d.ts +21 -0
  96. package/dist/blender-gate.d.ts.map +1 -0
  97. package/dist/blender-gate.js +27 -0
  98. package/dist/blender-gate.js.map +1 -0
  99. package/dist/browser-gate.d.ts +28 -0
  100. package/dist/browser-gate.d.ts.map +1 -0
  101. package/dist/browser-gate.js +34 -0
  102. package/dist/browser-gate.js.map +1 -0
  103. package/dist/capabilities/adapters.d.ts +36 -0
  104. package/dist/capabilities/adapters.d.ts.map +1 -0
  105. package/dist/capabilities/adapters.js +44 -0
  106. package/dist/capabilities/adapters.js.map +1 -0
  107. package/dist/capabilities/agents.d.ts +78 -0
  108. package/dist/capabilities/agents.d.ts.map +1 -0
  109. package/dist/capabilities/agents.js +366 -0
  110. package/dist/capabilities/agents.js.map +1 -0
  111. package/dist/capabilities/agents.specs.d.ts +27 -0
  112. package/dist/capabilities/agents.specs.d.ts.map +1 -0
  113. package/dist/capabilities/agents.specs.js +243 -0
  114. package/dist/capabilities/agents.specs.js.map +1 -0
  115. package/dist/capabilities/analysis.d.ts +93 -0
  116. package/dist/capabilities/analysis.d.ts.map +1 -0
  117. package/dist/capabilities/analysis.js +812 -0
  118. package/dist/capabilities/analysis.js.map +1 -0
  119. package/dist/capabilities/analysis.specs.d.ts +39 -0
  120. package/dist/capabilities/analysis.specs.d.ts.map +1 -0
  121. package/dist/capabilities/analysis.specs.js +217 -0
  122. package/dist/capabilities/analysis.specs.js.map +1 -0
  123. package/dist/capabilities/apify.d.ts +34 -0
  124. package/dist/capabilities/apify.d.ts.map +1 -0
  125. package/dist/capabilities/apify.js +449 -0
  126. package/dist/capabilities/apify.js.map +1 -0
  127. package/dist/capabilities/apify.specs.d.ts +28 -0
  128. package/dist/capabilities/apify.specs.d.ts.map +1 -0
  129. package/dist/capabilities/apify.specs.js +232 -0
  130. package/dist/capabilities/apify.specs.js.map +1 -0
  131. package/dist/capabilities/apps.d.ts +40 -0
  132. package/dist/capabilities/apps.d.ts.map +1 -0
  133. package/dist/capabilities/apps.js +413 -0
  134. package/dist/capabilities/apps.js.map +1 -0
  135. package/dist/capabilities/apps.specs.d.ts +23 -0
  136. package/dist/capabilities/apps.specs.d.ts.map +1 -0
  137. package/dist/capabilities/apps.specs.js +236 -0
  138. package/dist/capabilities/apps.specs.js.map +1 -0
  139. package/dist/capabilities/args.d.ts +65 -0
  140. package/dist/capabilities/args.d.ts.map +1 -0
  141. package/dist/capabilities/args.js +218 -0
  142. package/dist/capabilities/args.js.map +1 -0
  143. package/dist/capabilities/assets.d.ts +45 -0
  144. package/dist/capabilities/assets.d.ts.map +1 -0
  145. package/dist/capabilities/assets.js +952 -0
  146. package/dist/capabilities/assets.js.map +1 -0
  147. package/dist/capabilities/assets.specs.d.ts +54 -0
  148. package/dist/capabilities/assets.specs.d.ts.map +1 -0
  149. package/dist/capabilities/assets.specs.js +291 -0
  150. package/dist/capabilities/assets.specs.js.map +1 -0
  151. package/dist/capabilities/background-generation.d.ts +14 -0
  152. package/dist/capabilities/background-generation.d.ts.map +1 -0
  153. package/dist/capabilities/background-generation.js +29 -0
  154. package/dist/capabilities/background-generation.js.map +1 -0
  155. package/dist/capabilities/browser.d.ts +30 -0
  156. package/dist/capabilities/browser.d.ts.map +1 -0
  157. package/dist/capabilities/browser.js +250 -0
  158. package/dist/capabilities/browser.js.map +1 -0
  159. package/dist/capabilities/browser.specs.d.ts +37 -0
  160. package/dist/capabilities/browser.specs.d.ts.map +1 -0
  161. package/dist/capabilities/browser.specs.js +173 -0
  162. package/dist/capabilities/browser.specs.js.map +1 -0
  163. package/dist/capabilities/code-grading.d.ts +68 -0
  164. package/dist/capabilities/code-grading.d.ts.map +1 -0
  165. package/dist/capabilities/code-grading.js +75 -0
  166. package/dist/capabilities/code-grading.js.map +1 -0
  167. package/dist/capabilities/code.d.ts +56 -0
  168. package/dist/capabilities/code.d.ts.map +1 -0
  169. package/dist/capabilities/code.js +327 -0
  170. package/dist/capabilities/code.js.map +1 -0
  171. package/dist/capabilities/code.specs.d.ts +22 -0
  172. package/dist/capabilities/code.specs.d.ts.map +1 -0
  173. package/dist/capabilities/code.specs.js +175 -0
  174. package/dist/capabilities/code.specs.js.map +1 -0
  175. package/dist/capabilities/collections.d.ts +44 -0
  176. package/dist/capabilities/collections.d.ts.map +1 -0
  177. package/dist/capabilities/collections.js +432 -0
  178. package/dist/capabilities/collections.js.map +1 -0
  179. package/dist/capabilities/collections.specs.d.ts +25 -0
  180. package/dist/capabilities/collections.specs.d.ts.map +1 -0
  181. package/dist/capabilities/collections.specs.js +299 -0
  182. package/dist/capabilities/collections.specs.js.map +1 -0
  183. package/dist/capabilities/compositions.d.ts +57 -0
  184. package/dist/capabilities/compositions.d.ts.map +1 -0
  185. package/dist/capabilities/compositions.js +384 -0
  186. package/dist/capabilities/compositions.js.map +1 -0
  187. package/dist/capabilities/compositions.specs.d.ts +22 -0
  188. package/dist/capabilities/compositions.specs.d.ts.map +1 -0
  189. package/dist/capabilities/compositions.specs.js +126 -0
  190. package/dist/capabilities/compositions.specs.js.map +1 -0
  191. package/dist/capabilities/concurrency.d.ts +12 -0
  192. package/dist/capabilities/concurrency.d.ts.map +1 -0
  193. package/dist/capabilities/concurrency.js +30 -0
  194. package/dist/capabilities/concurrency.js.map +1 -0
  195. package/dist/capabilities/costs.d.ts +20 -0
  196. package/dist/capabilities/costs.d.ts.map +1 -0
  197. package/dist/capabilities/costs.js +40 -0
  198. package/dist/capabilities/costs.js.map +1 -0
  199. package/dist/capabilities/costs.specs.d.ts +12 -0
  200. package/dist/capabilities/costs.specs.d.ts.map +1 -0
  201. package/dist/capabilities/costs.specs.js +35 -0
  202. package/dist/capabilities/costs.specs.js.map +1 -0
  203. package/dist/capabilities/dispatcher.d.ts +57 -0
  204. package/dist/capabilities/dispatcher.d.ts.map +1 -0
  205. package/dist/capabilities/dispatcher.js +117 -0
  206. package/dist/capabilities/dispatcher.js.map +1 -0
  207. package/dist/capabilities/documents.d.ts +25 -0
  208. package/dist/capabilities/documents.d.ts.map +1 -0
  209. package/dist/capabilities/documents.js +278 -0
  210. package/dist/capabilities/documents.js.map +1 -0
  211. package/dist/capabilities/documents.specs.d.ts +18 -0
  212. package/dist/capabilities/documents.specs.d.ts.map +1 -0
  213. package/dist/capabilities/documents.specs.js +201 -0
  214. package/dist/capabilities/documents.specs.js.map +1 -0
  215. package/dist/capabilities/email.d.ts +23 -0
  216. package/dist/capabilities/email.d.ts.map +1 -0
  217. package/dist/capabilities/email.js +226 -0
  218. package/dist/capabilities/email.js.map +1 -0
  219. package/dist/capabilities/email.specs.d.ts +16 -0
  220. package/dist/capabilities/email.specs.d.ts.map +1 -0
  221. package/dist/capabilities/email.specs.js +102 -0
  222. package/dist/capabilities/email.specs.js.map +1 -0
  223. package/dist/capabilities/entities.d.ts +52 -0
  224. package/dist/capabilities/entities.d.ts.map +1 -0
  225. package/dist/capabilities/entities.js +478 -0
  226. package/dist/capabilities/entities.js.map +1 -0
  227. package/dist/capabilities/entities.specs.d.ts +25 -0
  228. package/dist/capabilities/entities.specs.d.ts.map +1 -0
  229. package/dist/capabilities/entities.specs.js +247 -0
  230. package/dist/capabilities/entities.specs.js.map +1 -0
  231. package/dist/capabilities/example-timelines.d.ts +3 -0
  232. package/dist/capabilities/example-timelines.d.ts.map +1 -0
  233. package/dist/capabilities/example-timelines.js +191 -0
  234. package/dist/capabilities/example-timelines.js.map +1 -0
  235. package/dist/capabilities/example-timelines.specs.d.ts +5 -0
  236. package/dist/capabilities/example-timelines.specs.d.ts.map +1 -0
  237. package/dist/capabilities/example-timelines.specs.js +53 -0
  238. package/dist/capabilities/example-timelines.specs.js.map +1 -0
  239. package/dist/capabilities/files.d.ts +53 -0
  240. package/dist/capabilities/files.d.ts.map +1 -0
  241. package/dist/capabilities/files.js +1172 -0
  242. package/dist/capabilities/files.js.map +1 -0
  243. package/dist/capabilities/files.specs.d.ts +28 -0
  244. package/dist/capabilities/files.specs.d.ts.map +1 -0
  245. package/dist/capabilities/files.specs.js +259 -0
  246. package/dist/capabilities/files.specs.js.map +1 -0
  247. package/dist/capabilities/flow.d.ts +93 -0
  248. package/dist/capabilities/flow.d.ts.map +1 -0
  249. package/dist/capabilities/flow.js +285 -0
  250. package/dist/capabilities/flow.js.map +1 -0
  251. package/dist/capabilities/flow.specs.d.ts +25 -0
  252. package/dist/capabilities/flow.specs.d.ts.map +1 -0
  253. package/dist/capabilities/flow.specs.js +114 -0
  254. package/dist/capabilities/flow.specs.js.map +1 -0
  255. package/dist/capabilities/game-asset-source.d.ts +31 -0
  256. package/dist/capabilities/game-asset-source.d.ts.map +1 -0
  257. package/dist/capabilities/game-asset-source.js +81 -0
  258. package/dist/capabilities/game-asset-source.js.map +1 -0
  259. package/dist/capabilities/game.d.ts +12 -0
  260. package/dist/capabilities/game.d.ts.map +1 -0
  261. package/dist/capabilities/game.js +1262 -0
  262. package/dist/capabilities/game.js.map +1 -0
  263. package/dist/capabilities/game.specs.d.ts +3 -0
  264. package/dist/capabilities/game.specs.d.ts.map +1 -0
  265. package/dist/capabilities/game.specs.js +96 -0
  266. package/dist/capabilities/game.specs.js.map +1 -0
  267. package/dist/capabilities/gate-from-context.d.ts +39 -0
  268. package/dist/capabilities/gate-from-context.d.ts.map +1 -0
  269. package/dist/capabilities/gate-from-context.js +97 -0
  270. package/dist/capabilities/gate-from-context.js.map +1 -0
  271. package/dist/capabilities/gate-tools.d.ts +18 -0
  272. package/dist/capabilities/gate-tools.d.ts.map +1 -0
  273. package/dist/capabilities/gate-tools.js +66 -0
  274. package/dist/capabilities/gate-tools.js.map +1 -0
  275. package/dist/capabilities/generations.d.ts +79 -0
  276. package/dist/capabilities/generations.d.ts.map +1 -0
  277. package/dist/capabilities/generations.js +382 -0
  278. package/dist/capabilities/generations.js.map +1 -0
  279. package/dist/capabilities/generations.specs.d.ts +62 -0
  280. package/dist/capabilities/generations.specs.d.ts.map +1 -0
  281. package/dist/capabilities/generations.specs.js +230 -0
  282. package/dist/capabilities/generations.specs.js.map +1 -0
  283. package/dist/capabilities/google.d.ts +50 -0
  284. package/dist/capabilities/google.d.ts.map +1 -0
  285. package/dist/capabilities/google.js +246 -0
  286. package/dist/capabilities/google.js.map +1 -0
  287. package/dist/capabilities/google.specs.d.ts +52 -0
  288. package/dist/capabilities/google.specs.d.ts.map +1 -0
  289. package/dist/capabilities/google.specs.js +391 -0
  290. package/dist/capabilities/google.specs.js.map +1 -0
  291. package/dist/capabilities/html-text.d.ts +28 -0
  292. package/dist/capabilities/html-text.d.ts.map +1 -0
  293. package/dist/capabilities/html-text.js +76 -0
  294. package/dist/capabilities/html-text.js.map +1 -0
  295. package/dist/capabilities/index.d.ts +19 -0
  296. package/dist/capabilities/index.d.ts.map +1 -0
  297. package/dist/capabilities/index.js +14 -0
  298. package/dist/capabilities/index.js.map +1 -0
  299. package/dist/capabilities/invoke.d.ts +89 -0
  300. package/dist/capabilities/invoke.d.ts.map +1 -0
  301. package/dist/capabilities/invoke.js +214 -0
  302. package/dist/capabilities/invoke.js.map +1 -0
  303. package/dist/capabilities/jobs.d.ts +32 -0
  304. package/dist/capabilities/jobs.d.ts.map +1 -0
  305. package/dist/capabilities/jobs.js +123 -0
  306. package/dist/capabilities/jobs.js.map +1 -0
  307. package/dist/capabilities/jobs.specs.d.ts +20 -0
  308. package/dist/capabilities/jobs.specs.d.ts.map +1 -0
  309. package/dist/capabilities/jobs.specs.js +103 -0
  310. package/dist/capabilities/jobs.specs.js.map +1 -0
  311. package/dist/capabilities/js-scripts.d.ts +90 -0
  312. package/dist/capabilities/js-scripts.d.ts.map +1 -0
  313. package/dist/capabilities/js-scripts.js +700 -0
  314. package/dist/capabilities/js-scripts.js.map +1 -0
  315. package/dist/capabilities/js-scripts.specs.d.ts +50 -0
  316. package/dist/capabilities/js-scripts.specs.d.ts.map +1 -0
  317. package/dist/capabilities/js-scripts.specs.js +344 -0
  318. package/dist/capabilities/js-scripts.specs.js.map +1 -0
  319. package/dist/capabilities/lazy-tool.d.ts +42 -0
  320. package/dist/capabilities/lazy-tool.d.ts.map +1 -0
  321. package/dist/capabilities/lazy-tool.js +88 -0
  322. package/dist/capabilities/lazy-tool.js.map +1 -0
  323. package/dist/capabilities/local-browser.d.ts +24 -0
  324. package/dist/capabilities/local-browser.d.ts.map +1 -0
  325. package/dist/capabilities/local-browser.js +105 -0
  326. package/dist/capabilities/local-browser.js.map +1 -0
  327. package/dist/capabilities/media.d.ts +121 -0
  328. package/dist/capabilities/media.d.ts.map +1 -0
  329. package/dist/capabilities/media.js +2217 -0
  330. package/dist/capabilities/media.js.map +1 -0
  331. package/dist/capabilities/media.specs.d.ts +65 -0
  332. package/dist/capabilities/media.specs.d.ts.map +1 -0
  333. package/dist/capabilities/media.specs.js +779 -0
  334. package/dist/capabilities/media.specs.js.map +1 -0
  335. package/dist/capabilities/memory.d.ts +31 -0
  336. package/dist/capabilities/memory.d.ts.map +1 -0
  337. package/dist/capabilities/memory.js +403 -0
  338. package/dist/capabilities/memory.js.map +1 -0
  339. package/dist/capabilities/memory.specs.d.ts +55 -0
  340. package/dist/capabilities/memory.specs.d.ts.map +1 -0
  341. package/dist/capabilities/memory.specs.js +208 -0
  342. package/dist/capabilities/memory.specs.js.map +1 -0
  343. package/dist/capabilities/model3d.d.ts +29 -0
  344. package/dist/capabilities/model3d.d.ts.map +1 -0
  345. package/dist/capabilities/model3d.js +482 -0
  346. package/dist/capabilities/model3d.js.map +1 -0
  347. package/dist/capabilities/model3d.specs.d.ts +28 -0
  348. package/dist/capabilities/model3d.specs.d.ts.map +1 -0
  349. package/dist/capabilities/model3d.specs.js +305 -0
  350. package/dist/capabilities/model3d.specs.js.map +1 -0
  351. package/dist/capabilities/models.d.ts +138 -0
  352. package/dist/capabilities/models.d.ts.map +1 -0
  353. package/dist/capabilities/models.js +803 -0
  354. package/dist/capabilities/models.js.map +1 -0
  355. package/dist/capabilities/models.specs.d.ts +21 -0
  356. package/dist/capabilities/models.specs.d.ts.map +1 -0
  357. package/dist/capabilities/models.specs.js +141 -0
  358. package/dist/capabilities/models.specs.js.map +1 -0
  359. package/dist/capabilities/nodes.d.ts +26 -0
  360. package/dist/capabilities/nodes.d.ts.map +1 -0
  361. package/dist/capabilities/nodes.js +266 -0
  362. package/dist/capabilities/nodes.js.map +1 -0
  363. package/dist/capabilities/nodes.specs.d.ts +20 -0
  364. package/dist/capabilities/nodes.specs.d.ts.map +1 -0
  365. package/dist/capabilities/nodes.specs.js +106 -0
  366. package/dist/capabilities/nodes.specs.js.map +1 -0
  367. package/dist/capabilities/packs.d.ts +69 -0
  368. package/dist/capabilities/packs.d.ts.map +1 -0
  369. package/dist/capabilities/packs.js +246 -0
  370. package/dist/capabilities/packs.js.map +1 -0
  371. package/dist/capabilities/packs.specs.d.ts +27 -0
  372. package/dist/capabilities/packs.specs.d.ts.map +1 -0
  373. package/dist/capabilities/packs.specs.js +64 -0
  374. package/dist/capabilities/packs.specs.js.map +1 -0
  375. package/dist/capabilities/project-scope.d.ts +12 -0
  376. package/dist/capabilities/project-scope.d.ts.map +1 -0
  377. package/dist/capabilities/project-scope.js +19 -0
  378. package/dist/capabilities/project-scope.js.map +1 -0
  379. package/dist/capabilities/projects.d.ts +23 -0
  380. package/dist/capabilities/projects.d.ts.map +1 -0
  381. package/dist/capabilities/projects.js +206 -0
  382. package/dist/capabilities/projects.js.map +1 -0
  383. package/dist/capabilities/projects.specs.d.ts +23 -0
  384. package/dist/capabilities/projects.specs.d.ts.map +1 -0
  385. package/dist/capabilities/projects.specs.js +118 -0
  386. package/dist/capabilities/projects.specs.js.map +1 -0
  387. package/dist/capabilities/registry.d.ts +109 -0
  388. package/dist/capabilities/registry.d.ts.map +1 -0
  389. package/dist/capabilities/registry.js +445 -0
  390. package/dist/capabilities/registry.js.map +1 -0
  391. package/dist/capabilities/script-link.d.ts +22 -0
  392. package/dist/capabilities/script-link.d.ts.map +1 -0
  393. package/dist/capabilities/script-link.js +35 -0
  394. package/dist/capabilities/script-link.js.map +1 -0
  395. package/dist/capabilities/scripts.d.ts +43 -0
  396. package/dist/capabilities/scripts.d.ts.map +1 -0
  397. package/dist/capabilities/scripts.js +1789 -0
  398. package/dist/capabilities/scripts.js.map +1 -0
  399. package/dist/capabilities/scripts.specs.d.ts +40 -0
  400. package/dist/capabilities/scripts.specs.d.ts.map +1 -0
  401. package/dist/capabilities/scripts.specs.js +319 -0
  402. package/dist/capabilities/scripts.specs.js.map +1 -0
  403. package/dist/capabilities/serpapi.d.ts +42 -0
  404. package/dist/capabilities/serpapi.d.ts.map +1 -0
  405. package/dist/capabilities/serpapi.js +262 -0
  406. package/dist/capabilities/serpapi.js.map +1 -0
  407. package/dist/capabilities/serpapi.specs.d.ts +24 -0
  408. package/dist/capabilities/serpapi.specs.d.ts.map +1 -0
  409. package/dist/capabilities/serpapi.specs.js +174 -0
  410. package/dist/capabilities/serpapi.specs.js.map +1 -0
  411. package/dist/capabilities/settings.d.ts +48 -0
  412. package/dist/capabilities/settings.d.ts.map +1 -0
  413. package/dist/capabilities/settings.js +226 -0
  414. package/dist/capabilities/settings.js.map +1 -0
  415. package/dist/capabilities/settings.specs.d.ts +42 -0
  416. package/dist/capabilities/settings.specs.d.ts.map +1 -0
  417. package/dist/capabilities/settings.specs.js +126 -0
  418. package/dist/capabilities/settings.specs.js.map +1 -0
  419. package/dist/capabilities/shared.d.ts +35 -0
  420. package/dist/capabilities/shared.d.ts.map +1 -0
  421. package/dist/capabilities/shared.js +165 -0
  422. package/dist/capabilities/shared.js.map +1 -0
  423. package/dist/capabilities/shared.specs.d.ts +19 -0
  424. package/dist/capabilities/shared.specs.d.ts.map +1 -0
  425. package/dist/capabilities/shared.specs.js +134 -0
  426. package/dist/capabilities/shared.specs.js.map +1 -0
  427. package/dist/capabilities/sketches.d.ts +52 -0
  428. package/dist/capabilities/sketches.d.ts.map +1 -0
  429. package/dist/capabilities/sketches.js +1163 -0
  430. package/dist/capabilities/sketches.js.map +1 -0
  431. package/dist/capabilities/sketches.specs.d.ts +44 -0
  432. package/dist/capabilities/sketches.specs.d.ts.map +1 -0
  433. package/dist/capabilities/sketches.specs.js +392 -0
  434. package/dist/capabilities/sketches.specs.js.map +1 -0
  435. package/dist/capabilities/skills.d.ts +28 -0
  436. package/dist/capabilities/skills.d.ts.map +1 -0
  437. package/dist/capabilities/skills.js +269 -0
  438. package/dist/capabilities/skills.js.map +1 -0
  439. package/dist/capabilities/skills.specs.d.ts +17 -0
  440. package/dist/capabilities/skills.specs.d.ts.map +1 -0
  441. package/dist/capabilities/skills.specs.js +108 -0
  442. package/dist/capabilities/skills.specs.js.map +1 -0
  443. package/dist/capabilities/storyboards.d.ts +68 -0
  444. package/dist/capabilities/storyboards.d.ts.map +1 -0
  445. package/dist/capabilities/storyboards.js +2246 -0
  446. package/dist/capabilities/storyboards.js.map +1 -0
  447. package/dist/capabilities/storyboards.specs.d.ts +42 -0
  448. package/dist/capabilities/storyboards.specs.d.ts.map +1 -0
  449. package/dist/capabilities/storyboards.specs.js +418 -0
  450. package/dist/capabilities/storyboards.specs.js.map +1 -0
  451. package/dist/capabilities/threads.d.ts +25 -0
  452. package/dist/capabilities/threads.d.ts.map +1 -0
  453. package/dist/capabilities/threads.js +240 -0
  454. package/dist/capabilities/threads.js.map +1 -0
  455. package/dist/capabilities/threads.specs.d.ts +26 -0
  456. package/dist/capabilities/threads.specs.d.ts.map +1 -0
  457. package/dist/capabilities/threads.specs.js +108 -0
  458. package/dist/capabilities/threads.specs.js.map +1 -0
  459. package/dist/capabilities/timeline-audio-bake.d.ts +114 -0
  460. package/dist/capabilities/timeline-audio-bake.d.ts.map +1 -0
  461. package/dist/capabilities/timeline-audio-bake.js +188 -0
  462. package/dist/capabilities/timeline-audio-bake.js.map +1 -0
  463. package/dist/capabilities/timeline-bake.d.ts +21 -0
  464. package/dist/capabilities/timeline-bake.d.ts.map +1 -0
  465. package/dist/capabilities/timeline-bake.js +118 -0
  466. package/dist/capabilities/timeline-bake.js.map +1 -0
  467. package/dist/capabilities/timeline-isolate-subject.d.ts +157 -0
  468. package/dist/capabilities/timeline-isolate-subject.d.ts.map +1 -0
  469. package/dist/capabilities/timeline-isolate-subject.js +293 -0
  470. package/dist/capabilities/timeline-isolate-subject.js.map +1 -0
  471. package/dist/capabilities/timeline-native-media.d.ts +4 -0
  472. package/dist/capabilities/timeline-native-media.d.ts.map +1 -0
  473. package/dist/capabilities/timeline-native-media.js +920 -0
  474. package/dist/capabilities/timeline-native-media.js.map +1 -0
  475. package/dist/capabilities/timeline-track-object.d.ts +83 -0
  476. package/dist/capabilities/timeline-track-object.d.ts.map +1 -0
  477. package/dist/capabilities/timeline-track-object.js +195 -0
  478. package/dist/capabilities/timeline-track-object.js.map +1 -0
  479. package/dist/capabilities/timelines.d.ts +190 -0
  480. package/dist/capabilities/timelines.d.ts.map +1 -0
  481. package/dist/capabilities/timelines.js +2326 -0
  482. package/dist/capabilities/timelines.js.map +1 -0
  483. package/dist/capabilities/timelines.specs.d.ts +134 -0
  484. package/dist/capabilities/timelines.specs.d.ts.map +1 -0
  485. package/dist/capabilities/timelines.specs.js +1362 -0
  486. package/dist/capabilities/timelines.specs.js.map +1 -0
  487. package/dist/capabilities/types.d.ts +197 -0
  488. package/dist/capabilities/types.d.ts.map +1 -0
  489. package/dist/capabilities/types.js +19 -0
  490. package/dist/capabilities/types.js.map +1 -0
  491. package/dist/capabilities/ui.d.ts +38 -0
  492. package/dist/capabilities/ui.d.ts.map +1 -0
  493. package/dist/capabilities/ui.js +128 -0
  494. package/dist/capabilities/ui.js.map +1 -0
  495. package/dist/capabilities/ui.specs.d.ts +22 -0
  496. package/dist/capabilities/ui.specs.d.ts.map +1 -0
  497. package/dist/capabilities/ui.specs.js +59 -0
  498. package/dist/capabilities/ui.specs.js.map +1 -0
  499. package/dist/capabilities/video-production-acceptance.d.ts +27 -0
  500. package/dist/capabilities/video-production-acceptance.d.ts.map +1 -0
  501. package/dist/capabilities/video-production-acceptance.js +41 -0
  502. package/dist/capabilities/video-production-acceptance.js.map +1 -0
  503. package/dist/capabilities/video-production.d.ts +179 -0
  504. package/dist/capabilities/video-production.d.ts.map +1 -0
  505. package/dist/capabilities/video-production.js +1492 -0
  506. package/dist/capabilities/video-production.js.map +1 -0
  507. package/dist/capabilities/video-production.specs.d.ts +13 -0
  508. package/dist/capabilities/video-production.specs.d.ts.map +1 -0
  509. package/dist/capabilities/video-production.specs.js +256 -0
  510. package/dist/capabilities/video-production.specs.js.map +1 -0
  511. package/dist/capabilities/web.d.ts +86 -0
  512. package/dist/capabilities/web.d.ts.map +1 -0
  513. package/dist/capabilities/web.js +850 -0
  514. package/dist/capabilities/web.js.map +1 -0
  515. package/dist/capabilities/web.specs.d.ts +33 -0
  516. package/dist/capabilities/web.specs.d.ts.map +1 -0
  517. package/dist/capabilities/web.specs.js +286 -0
  518. package/dist/capabilities/web.specs.js.map +1 -0
  519. package/dist/capabilities/workflows.d.ts +58 -0
  520. package/dist/capabilities/workflows.d.ts.map +1 -0
  521. package/dist/capabilities/workflows.js +1530 -0
  522. package/dist/capabilities/workflows.js.map +1 -0
  523. package/dist/capabilities/workflows.specs.d.ts +63 -0
  524. package/dist/capabilities/workflows.specs.d.ts.map +1 -0
  525. package/dist/capabilities/workflows.specs.js +852 -0
  526. package/dist/capabilities/workflows.specs.js.map +1 -0
  527. package/dist/code-gen/analyze.d.ts +26 -0
  528. package/dist/code-gen/analyze.d.ts.map +1 -0
  529. package/dist/code-gen/analyze.js +79 -0
  530. package/dist/code-gen/analyze.js.map +1 -0
  531. package/dist/code-gen/port-types.d.ts +58 -0
  532. package/dist/code-gen/port-types.d.ts.map +1 -0
  533. package/dist/code-gen/port-types.js +115 -0
  534. package/dist/code-gen/port-types.js.map +1 -0
  535. package/dist/code-gen/prompt.d.ts +37 -0
  536. package/dist/code-gen/prompt.d.ts.map +1 -0
  537. package/dist/code-gen/prompt.js +129 -0
  538. package/dist/code-gen/prompt.js.map +1 -0
  539. package/dist/code-gen/sandbox-manifest.d.ts +120 -0
  540. package/dist/code-gen/sandbox-manifest.d.ts.map +1 -0
  541. package/dist/code-gen/sandbox-manifest.js +1023 -0
  542. package/dist/code-gen/sandbox-manifest.js.map +1 -0
  543. package/dist/code-gen/sandbox-prompt.d.ts +26 -0
  544. package/dist/code-gen/sandbox-prompt.d.ts.map +1 -0
  545. package/dist/code-gen/sandbox-prompt.js +126 -0
  546. package/dist/code-gen/sandbox-prompt.js.map +1 -0
  547. package/dist/code-planner.d.ts +72 -0
  548. package/dist/code-planner.d.ts.map +1 -0
  549. package/dist/code-planner.js +271 -0
  550. package/dist/code-planner.js.map +1 -0
  551. package/dist/codeact/action-diagnostics.d.ts +35 -0
  552. package/dist/codeact/action-diagnostics.d.ts.map +1 -0
  553. package/dist/codeact/action-diagnostics.js +147 -0
  554. package/dist/codeact/action-diagnostics.js.map +1 -0
  555. package/dist/codeact/capability-modules.d.ts +66 -0
  556. package/dist/codeact/capability-modules.d.ts.map +1 -0
  557. package/dist/codeact/capability-modules.js +278 -0
  558. package/dist/codeact/capability-modules.js.map +1 -0
  559. package/dist/codeact/chat-codeact.d.ts +104 -0
  560. package/dist/codeact/chat-codeact.d.ts.map +1 -0
  561. package/dist/codeact/chat-codeact.js +424 -0
  562. package/dist/codeact/chat-codeact.js.map +1 -0
  563. package/dist/codeact/codeact-executor.d.ts +247 -0
  564. package/dist/codeact/codeact-executor.d.ts.map +1 -0
  565. package/dist/codeact/codeact-executor.js +1176 -0
  566. package/dist/codeact/codeact-executor.js.map +1 -0
  567. package/dist/codeact/compact-ids.d.ts +28 -0
  568. package/dist/codeact/compact-ids.d.ts.map +1 -0
  569. package/dist/codeact/compact-ids.js +77 -0
  570. package/dist/codeact/compact-ids.js.map +1 -0
  571. package/dist/codeact/execute-code-contract.d.ts +97 -0
  572. package/dist/codeact/execute-code-contract.d.ts.map +1 -0
  573. package/dist/codeact/execute-code-contract.js +225 -0
  574. package/dist/codeact/execute-code-contract.js.map +1 -0
  575. package/dist/codeact/fabric-package.d.ts +29 -0
  576. package/dist/codeact/fabric-package.d.ts.map +1 -0
  577. package/dist/codeact/fabric-package.js +62 -0
  578. package/dist/codeact/fabric-package.js.map +1 -0
  579. package/dist/codeact/flow-package.d.ts +31 -0
  580. package/dist/codeact/flow-package.d.ts.map +1 -0
  581. package/dist/codeact/flow-package.js +80 -0
  582. package/dist/codeact/flow-package.js.map +1 -0
  583. package/dist/codeact/graph-dsl-package.d.ts +42 -0
  584. package/dist/codeact/graph-dsl-package.d.ts.map +1 -0
  585. package/dist/codeact/graph-dsl-package.js +100 -0
  586. package/dist/codeact/graph-dsl-package.js.map +1 -0
  587. package/dist/codeact/graph-model.d.ts +30 -0
  588. package/dist/codeact/graph-model.d.ts.map +1 -0
  589. package/dist/codeact/graph-model.js +408 -0
  590. package/dist/codeact/graph-model.js.map +1 -0
  591. package/dist/codeact/mcp-guest-contract.d.ts +66 -0
  592. package/dist/codeact/mcp-guest-contract.d.ts.map +1 -0
  593. package/dist/codeact/mcp-guest-contract.js +108 -0
  594. package/dist/codeact/mcp-guest-contract.js.map +1 -0
  595. package/dist/codeact/nodetool-api.d.ts +60 -0
  596. package/dist/codeact/nodetool-api.d.ts.map +1 -0
  597. package/dist/codeact/nodetool-api.js +2056 -0
  598. package/dist/codeact/nodetool-api.js.map +1 -0
  599. package/dist/codeact/prompt.d.ts +88 -0
  600. package/dist/codeact/prompt.d.ts.map +1 -0
  601. package/dist/codeact/prompt.js +326 -0
  602. package/dist/codeact/prompt.js.map +1 -0
  603. package/dist/codeact/sandbox-package-docs.d.ts +48 -0
  604. package/dist/codeact/sandbox-package-docs.d.ts.map +1 -0
  605. package/dist/codeact/sandbox-package-docs.js +55 -0
  606. package/dist/codeact/sandbox-package-docs.js.map +1 -0
  607. package/dist/codeact/sandbox-package-listing.d.ts +81 -0
  608. package/dist/codeact/sandbox-package-listing.d.ts.map +1 -0
  609. package/dist/codeact/sandbox-package-listing.js +101 -0
  610. package/dist/codeact/sandbox-package-listing.js.map +1 -0
  611. package/dist/codeact/sandbox-packages.d.ts +72 -0
  612. package/dist/codeact/sandbox-packages.d.ts.map +1 -0
  613. package/dist/codeact/sandbox-packages.js +230 -0
  614. package/dist/codeact/sandbox-packages.js.map +1 -0
  615. package/dist/codeact/timeline-package.d.ts +5 -0
  616. package/dist/codeact/timeline-package.d.ts.map +1 -0
  617. package/dist/codeact/timeline-package.js +10 -0
  618. package/dist/codeact/timeline-package.js.map +1 -0
  619. package/dist/codeact/tool-api.d.ts +197 -0
  620. package/dist/codeact/tool-api.d.ts.map +1 -0
  621. package/dist/codeact/tool-api.js +445 -0
  622. package/dist/codeact/tool-api.js.map +1 -0
  623. package/dist/codeact/tools-prelude.d.ts +32 -0
  624. package/dist/codeact/tools-prelude.d.ts.map +1 -0
  625. package/dist/codeact/tools-prelude.js +65 -0
  626. package/dist/codeact/tools-prelude.js.map +1 -0
  627. package/dist/constants.d.ts +47 -2
  628. package/dist/constants.d.ts.map +1 -1
  629. package/dist/constants.js +64 -2
  630. package/dist/constants.js.map +1 -1
  631. package/dist/custom-animation-bake.d.ts +57 -0
  632. package/dist/custom-animation-bake.d.ts.map +1 -0
  633. package/dist/custom-animation-bake.js +88 -0
  634. package/dist/custom-animation-bake.js.map +1 -0
  635. package/dist/dynamic-slots.d.ts +72 -0
  636. package/dist/dynamic-slots.d.ts.map +1 -0
  637. package/dist/dynamic-slots.js +0 -0
  638. package/dist/dynamic-slots.js.map +1 -0
  639. package/dist/evals/app-build-cases.d.ts +35 -0
  640. package/dist/evals/app-build-cases.d.ts.map +1 -0
  641. package/dist/evals/app-build-cases.js +722 -0
  642. package/dist/evals/app-build-cases.js.map +1 -0
  643. package/dist/evals/app-build-eval.d.ts +208 -0
  644. package/dist/evals/app-build-eval.d.ts.map +1 -0
  645. package/dist/evals/app-build-eval.js +518 -0
  646. package/dist/evals/app-build-eval.js.map +1 -0
  647. package/dist/evals/app-build-plan.d.ts +76 -0
  648. package/dist/evals/app-build-plan.d.ts.map +1 -0
  649. package/dist/evals/app-build-plan.js +140 -0
  650. package/dist/evals/app-build-plan.js.map +1 -0
  651. package/dist/evals/code-gen-cases.d.ts +13 -0
  652. package/dist/evals/code-gen-cases.d.ts.map +1 -0
  653. package/dist/evals/code-gen-cases.js +124 -0
  654. package/dist/evals/code-gen-cases.js.map +1 -0
  655. package/dist/evals/code-gen-eval.d.ts +109 -0
  656. package/dist/evals/code-gen-eval.d.ts.map +1 -0
  657. package/dist/evals/code-gen-eval.js +299 -0
  658. package/dist/evals/code-gen-eval.js.map +1 -0
  659. package/dist/evals/codeact-api-cases.d.ts +14 -0
  660. package/dist/evals/codeact-api-cases.d.ts.map +1 -0
  661. package/dist/evals/codeact-api-cases.js +29 -0
  662. package/dist/evals/codeact-api-cases.js.map +1 -0
  663. package/dist/evals/codeact-api-core.d.ts +23 -0
  664. package/dist/evals/codeact-api-core.d.ts.map +1 -0
  665. package/dist/evals/codeact-api-core.js +1411 -0
  666. package/dist/evals/codeact-api-core.js.map +1 -0
  667. package/dist/evals/codeact-api-surfaces.d.ts +25 -0
  668. package/dist/evals/codeact-api-surfaces.d.ts.map +1 -0
  669. package/dist/evals/codeact-api-surfaces.js +2191 -0
  670. package/dist/evals/codeact-api-surfaces.js.map +1 -0
  671. package/dist/evals/codeact-cases.d.ts +76 -0
  672. package/dist/evals/codeact-cases.d.ts.map +1 -0
  673. package/dist/evals/codeact-cases.js +151 -0
  674. package/dist/evals/codeact-cases.js.map +1 -0
  675. package/dist/evals/codeact-eval.d.ts +66 -0
  676. package/dist/evals/codeact-eval.d.ts.map +1 -0
  677. package/dist/evals/codeact-eval.js +250 -0
  678. package/dist/evals/codeact-eval.js.map +1 -0
  679. package/dist/evals/codeact-sandbox-pack-cases.d.ts +31 -0
  680. package/dist/evals/codeact-sandbox-pack-cases.d.ts.map +1 -0
  681. package/dist/evals/codeact-sandbox-pack-cases.js +219 -0
  682. package/dist/evals/codeact-sandbox-pack-cases.js.map +1 -0
  683. package/dist/evals/escalation-cases.d.ts +22 -0
  684. package/dist/evals/escalation-cases.d.ts.map +1 -0
  685. package/dist/evals/escalation-cases.js +343 -0
  686. package/dist/evals/escalation-cases.js.map +1 -0
  687. package/dist/evals/escalation.d.ts +92 -0
  688. package/dist/evals/escalation.d.ts.map +1 -0
  689. package/dist/evals/escalation.js +152 -0
  690. package/dist/evals/escalation.js.map +1 -0
  691. package/dist/evals/goal-judge.d.ts +51 -0
  692. package/dist/evals/goal-judge.d.ts.map +1 -0
  693. package/dist/evals/goal-judge.js +152 -0
  694. package/dist/evals/goal-judge.js.map +1 -0
  695. package/dist/evals/graph-e2e-cases.d.ts +21 -0
  696. package/dist/evals/graph-e2e-cases.d.ts.map +1 -0
  697. package/dist/evals/graph-e2e-cases.js +262 -0
  698. package/dist/evals/graph-e2e-cases.js.map +1 -0
  699. package/dist/evals/graph-e2e-eval.d.ts +202 -0
  700. package/dist/evals/graph-e2e-eval.d.ts.map +1 -0
  701. package/dist/evals/graph-e2e-eval.js +438 -0
  702. package/dist/evals/graph-e2e-eval.js.map +1 -0
  703. package/dist/evals/graph-planner-cases.d.ts +12 -0
  704. package/dist/evals/graph-planner-cases.d.ts.map +1 -0
  705. package/dist/evals/graph-planner-cases.js +256 -0
  706. package/dist/evals/graph-planner-cases.js.map +1 -0
  707. package/dist/evals/graph-planner-eval.d.ts +178 -0
  708. package/dist/evals/graph-planner-eval.d.ts.map +1 -0
  709. package/dist/evals/graph-planner-eval.js +495 -0
  710. package/dist/evals/graph-planner-eval.js.map +1 -0
  711. package/dist/evals/planner-tools.d.ts +21 -0
  712. package/dist/evals/planner-tools.d.ts.map +1 -0
  713. package/dist/evals/planner-tools.js +66 -0
  714. package/dist/evals/planner-tools.js.map +1 -0
  715. package/dist/evals/subtask-cases.d.ts +88 -0
  716. package/dist/evals/subtask-cases.d.ts.map +1 -0
  717. package/dist/evals/subtask-cases.js +322 -0
  718. package/dist/evals/subtask-cases.js.map +1 -0
  719. package/dist/evals/subtask-eval.d.ts +129 -0
  720. package/dist/evals/subtask-eval.d.ts.map +1 -0
  721. package/dist/evals/subtask-eval.js +397 -0
  722. package/dist/evals/subtask-eval.js.map +1 -0
  723. package/dist/evals/surfaces/app.d.ts +19 -0
  724. package/dist/evals/surfaces/app.d.ts.map +1 -0
  725. package/dist/evals/surfaces/app.js +341 -0
  726. package/dist/evals/surfaces/app.js.map +1 -0
  727. package/dist/evals/surfaces/creative-pipeline.d.ts +203 -0
  728. package/dist/evals/surfaces/creative-pipeline.d.ts.map +1 -0
  729. package/dist/evals/surfaces/creative-pipeline.js +909 -0
  730. package/dist/evals/surfaces/creative-pipeline.js.map +1 -0
  731. package/dist/evals/surfaces/game.d.ts +5 -0
  732. package/dist/evals/surfaces/game.d.ts.map +1 -0
  733. package/dist/evals/surfaces/game.js +42 -0
  734. package/dist/evals/surfaces/game.js.map +1 -0
  735. package/dist/evals/surfaces/js-script.d.ts +66 -0
  736. package/dist/evals/surfaces/js-script.d.ts.map +1 -0
  737. package/dist/evals/surfaces/js-script.js +407 -0
  738. package/dist/evals/surfaces/js-script.js.map +1 -0
  739. package/dist/evals/surfaces/memory.d.ts +34 -0
  740. package/dist/evals/surfaces/memory.d.ts.map +1 -0
  741. package/dist/evals/surfaces/memory.js +264 -0
  742. package/dist/evals/surfaces/memory.js.map +1 -0
  743. package/dist/evals/surfaces/model3d.d.ts +45 -0
  744. package/dist/evals/surfaces/model3d.d.ts.map +1 -0
  745. package/dist/evals/surfaces/model3d.js +346 -0
  746. package/dist/evals/surfaces/model3d.js.map +1 -0
  747. package/dist/evals/surfaces/script.d.ts +96 -0
  748. package/dist/evals/surfaces/script.d.ts.map +1 -0
  749. package/dist/evals/surfaces/script.js +709 -0
  750. package/dist/evals/surfaces/script.js.map +1 -0
  751. package/dist/evals/surfaces/sketch.d.ts +124 -0
  752. package/dist/evals/surfaces/sketch.d.ts.map +1 -0
  753. package/dist/evals/surfaces/sketch.js +1298 -0
  754. package/dist/evals/surfaces/sketch.js.map +1 -0
  755. package/dist/evals/surfaces/storyboard.d.ts +97 -0
  756. package/dist/evals/surfaces/storyboard.d.ts.map +1 -0
  757. package/dist/evals/surfaces/storyboard.js +693 -0
  758. package/dist/evals/surfaces/storyboard.js.map +1 -0
  759. package/dist/evals/surfaces/timeline.d.ts +416 -0
  760. package/dist/evals/surfaces/timeline.d.ts.map +1 -0
  761. package/dist/evals/surfaces/timeline.js +3267 -0
  762. package/dist/evals/surfaces/timeline.js.map +1 -0
  763. package/dist/evals/task-planner-cases.d.ts +57 -0
  764. package/dist/evals/task-planner-cases.d.ts.map +1 -0
  765. package/dist/evals/task-planner-cases.js +117 -0
  766. package/dist/evals/task-planner-cases.js.map +1 -0
  767. package/dist/evals/task-planner-eval.d.ts +101 -0
  768. package/dist/evals/task-planner-eval.d.ts.map +1 -0
  769. package/dist/evals/task-planner-eval.js +380 -0
  770. package/dist/evals/task-planner-eval.js.map +1 -0
  771. package/dist/evals/tool-loop-bridge.d.ts +57 -0
  772. package/dist/evals/tool-loop-bridge.d.ts.map +1 -0
  773. package/dist/evals/tool-loop-bridge.js +129 -0
  774. package/dist/evals/tool-loop-bridge.js.map +1 -0
  775. package/dist/evals/tool-loop-cases.d.ts +21 -0
  776. package/dist/evals/tool-loop-cases.d.ts.map +1 -0
  777. package/dist/evals/tool-loop-cases.js +401 -0
  778. package/dist/evals/tool-loop-cases.js.map +1 -0
  779. package/dist/evals/tool-loop-eval.d.ts +234 -0
  780. package/dist/evals/tool-loop-eval.d.ts.map +1 -0
  781. package/dist/evals/tool-loop-eval.js +373 -0
  782. package/dist/evals/tool-loop-eval.js.map +1 -0
  783. package/dist/evals/tool-loop-permission.d.ts +43 -0
  784. package/dist/evals/tool-loop-permission.d.ts.map +1 -0
  785. package/dist/evals/tool-loop-permission.js +76 -0
  786. package/dist/evals/tool-loop-permission.js.map +1 -0
  787. package/dist/game-examples.d.ts +447 -0
  788. package/dist/game-examples.d.ts.map +1 -0
  789. package/dist/game-examples.js +187 -0
  790. package/dist/game-examples.js.map +1 -0
  791. package/dist/graph-builder.d.ts +55 -3
  792. package/dist/graph-builder.d.ts.map +1 -1
  793. package/dist/graph-builder.js +159 -4
  794. package/dist/graph-builder.js.map +1 -1
  795. package/dist/graph-dsl-core.d.ts +25 -0
  796. package/dist/graph-dsl-core.d.ts.map +1 -0
  797. package/dist/graph-dsl-core.js +312 -0
  798. package/dist/graph-dsl-core.js.map +1 -0
  799. package/dist/graph-dsl.d.ts +30 -0
  800. package/dist/graph-dsl.d.ts.map +1 -0
  801. package/dist/graph-dsl.js +116 -0
  802. package/dist/graph-dsl.js.map +1 -0
  803. package/dist/host-binaries.d.ts +6 -0
  804. package/dist/host-binaries.d.ts.map +1 -0
  805. package/dist/host-binaries.js +6 -0
  806. package/dist/host-binaries.js.map +1 -0
  807. package/dist/host-binary-guard.d.ts +100 -0
  808. package/dist/host-binary-guard.d.ts.map +1 -0
  809. package/dist/host-binary-guard.js +205 -0
  810. package/dist/host-binary-guard.js.map +1 -0
  811. package/dist/host-modules/aws.d.ts +57 -0
  812. package/dist/host-modules/aws.d.ts.map +1 -0
  813. package/dist/host-modules/aws.js +309 -0
  814. package/dist/host-modules/aws.js.map +1 -0
  815. package/dist/host-modules/chrono.d.ts +15 -0
  816. package/dist/host-modules/chrono.d.ts.map +1 -0
  817. package/dist/host-modules/chrono.js +35 -0
  818. package/dist/host-modules/chrono.js.map +1 -0
  819. package/dist/host-modules/csv.d.ts +17 -0
  820. package/dist/host-modules/csv.d.ts.map +1 -0
  821. package/dist/host-modules/csv.js +64 -0
  822. package/dist/host-modules/csv.js.map +1 -0
  823. package/dist/host-modules/diff.d.ts +9 -0
  824. package/dist/host-modules/diff.d.ts.map +1 -0
  825. package/dist/host-modules/diff.js +26 -0
  826. package/dist/host-modules/diff.js.map +1 -0
  827. package/dist/host-modules/dispatcher.d.ts +41 -0
  828. package/dist/host-modules/dispatcher.d.ts.map +1 -0
  829. package/dist/host-modules/dispatcher.js +99 -0
  830. package/dist/host-modules/dispatcher.js.map +1 -0
  831. package/dist/host-modules/docx.d.ts +19 -0
  832. package/dist/host-modules/docx.d.ts.map +1 -0
  833. package/dist/host-modules/docx.js +120 -0
  834. package/dist/host-modules/docx.js.map +1 -0
  835. package/dist/host-modules/epub.d.ts +48 -0
  836. package/dist/host-modules/epub.d.ts.map +1 -0
  837. package/dist/host-modules/epub.js +100 -0
  838. package/dist/host-modules/epub.js.map +1 -0
  839. package/dist/host-modules/exif.d.ts +8 -0
  840. package/dist/host-modules/exif.d.ts.map +1 -0
  841. package/dist/host-modules/exif.js +19 -0
  842. package/dist/host-modules/exif.js.map +1 -0
  843. package/dist/host-modules/expr.d.ts +16 -0
  844. package/dist/host-modules/expr.d.ts.map +1 -0
  845. package/dist/host-modules/expr.js +18 -0
  846. package/dist/host-modules/expr.js.map +1 -0
  847. package/dist/host-modules/fabric.d.ts +46 -0
  848. package/dist/host-modules/fabric.d.ts.map +1 -0
  849. package/dist/host-modules/fabric.js +178 -0
  850. package/dist/host-modules/fabric.js.map +1 -0
  851. package/dist/host-modules/html.d.ts +51 -0
  852. package/dist/host-modules/html.d.ts.map +1 -0
  853. package/dist/host-modules/html.js +198 -0
  854. package/dist/host-modules/html.js.map +1 -0
  855. package/dist/host-modules/ics.d.ts +9 -0
  856. package/dist/host-modules/ics.d.ts.map +1 -0
  857. package/dist/host-modules/ics.js +35 -0
  858. package/dist/host-modules/ics.js.map +1 -0
  859. package/dist/host-modules/limits.d.ts +41 -0
  860. package/dist/host-modules/limits.d.ts.map +1 -0
  861. package/dist/host-modules/limits.js +76 -0
  862. package/dist/host-modules/limits.js.map +1 -0
  863. package/dist/host-modules/mammoth.d.ts +11 -0
  864. package/dist/host-modules/mammoth.d.ts.map +1 -0
  865. package/dist/host-modules/mammoth.js +29 -0
  866. package/dist/host-modules/mammoth.js.map +1 -0
  867. package/dist/host-modules/notion.d.ts +45 -0
  868. package/dist/host-modules/notion.d.ts.map +1 -0
  869. package/dist/host-modules/notion.js +128 -0
  870. package/dist/host-modules/notion.js.map +1 -0
  871. package/dist/host-modules/ocr.d.ts +25 -0
  872. package/dist/host-modules/ocr.d.ts.map +1 -0
  873. package/dist/host-modules/ocr.js +74 -0
  874. package/dist/host-modules/ocr.js.map +1 -0
  875. package/dist/host-modules/pdf.d.ts +21 -0
  876. package/dist/host-modules/pdf.d.ts.map +1 -0
  877. package/dist/host-modules/pdf.js +53 -0
  878. package/dist/host-modules/pdf.js.map +1 -0
  879. package/dist/host-modules/pdflib.d.ts +17 -0
  880. package/dist/host-modules/pdflib.d.ts.map +1 -0
  881. package/dist/host-modules/pdflib.js +138 -0
  882. package/dist/host-modules/pdflib.js.map +1 -0
  883. package/dist/host-modules/pptx.d.ts +19 -0
  884. package/dist/host-modules/pptx.d.ts.map +1 -0
  885. package/dist/host-modules/pptx.js +67 -0
  886. package/dist/host-modules/pptx.js.map +1 -0
  887. package/dist/host-modules/pptxgen.d.ts +13 -0
  888. package/dist/host-modules/pptxgen.d.ts.map +1 -0
  889. package/dist/host-modules/pptxgen.js +98 -0
  890. package/dist/host-modules/pptxgen.js.map +1 -0
  891. package/dist/host-modules/prepared-request.d.ts +41 -0
  892. package/dist/host-modules/prepared-request.d.ts.map +1 -0
  893. package/dist/host-modules/prepared-request.js +104 -0
  894. package/dist/host-modules/prepared-request.js.map +1 -0
  895. package/dist/host-modules/registry.d.ts +31 -0
  896. package/dist/host-modules/registry.d.ts.map +1 -0
  897. package/dist/host-modules/registry.js +193 -0
  898. package/dist/host-modules/registry.js.map +1 -0
  899. package/dist/host-modules/subtitle.d.ts +15 -0
  900. package/dist/host-modules/subtitle.d.ts.map +1 -0
  901. package/dist/host-modules/subtitle.js +45 -0
  902. package/dist/host-modules/subtitle.js.map +1 -0
  903. package/dist/host-modules/supabase.d.ts +42 -0
  904. package/dist/host-modules/supabase.d.ts.map +1 -0
  905. package/dist/host-modules/supabase.js +141 -0
  906. package/dist/host-modules/supabase.js.map +1 -0
  907. package/dist/host-modules/tfjs.d.ts +42 -0
  908. package/dist/host-modules/tfjs.d.ts.map +1 -0
  909. package/dist/host-modules/tfjs.js +186 -0
  910. package/dist/host-modules/tfjs.js.map +1 -0
  911. package/dist/host-modules/tokens.d.ts +17 -0
  912. package/dist/host-modules/tokens.d.ts.map +1 -0
  913. package/dist/host-modules/tokens.js +74 -0
  914. package/dist/host-modules/tokens.js.map +1 -0
  915. package/dist/host-modules/twilio.d.ts +34 -0
  916. package/dist/host-modules/twilio.d.ts.map +1 -0
  917. package/dist/host-modules/twilio.js +67 -0
  918. package/dist/host-modules/twilio.js.map +1 -0
  919. package/dist/host-modules/xlsx.d.ts +26 -0
  920. package/dist/host-modules/xlsx.d.ts.map +1 -0
  921. package/dist/host-modules/xlsx.js +323 -0
  922. package/dist/host-modules/xlsx.js.map +1 -0
  923. package/dist/host-modules/xml.d.ts +23 -0
  924. package/dist/host-modules/xml.d.ts.map +1 -0
  925. package/dist/host-modules/xml.js +38 -0
  926. package/dist/host-modules/xml.js.map +1 -0
  927. package/dist/host-modules/zip.d.ts +24 -0
  928. package/dist/host-modules/zip.d.ts.map +1 -0
  929. package/dist/host-modules/zip.js +70 -0
  930. package/dist/host-modules/zip.js.map +1 -0
  931. package/dist/index.d.ts +197 -60
  932. package/dist/index.d.ts.map +1 -1
  933. package/dist/index.js +153 -60
  934. package/dist/index.js.map +1 -1
  935. package/dist/js-sandbox-worker/host.d.ts +136 -0
  936. package/dist/js-sandbox-worker/host.d.ts.map +1 -0
  937. package/dist/js-sandbox-worker/host.js +482 -0
  938. package/dist/js-sandbox-worker/host.js.map +1 -0
  939. package/dist/js-sandbox-worker/interpreter.d.ts +276 -0
  940. package/dist/js-sandbox-worker/interpreter.d.ts.map +1 -0
  941. package/dist/js-sandbox-worker/interpreter.js +1201 -0
  942. package/dist/js-sandbox-worker/interpreter.js.map +1 -0
  943. package/dist/js-sandbox-worker/protocol.d.ts +168 -0
  944. package/dist/js-sandbox-worker/protocol.d.ts.map +1 -0
  945. package/dist/js-sandbox-worker/protocol.js +217 -0
  946. package/dist/js-sandbox-worker/protocol.js.map +1 -0
  947. package/dist/js-sandbox-worker/worker-entry.d.ts +26 -0
  948. package/dist/js-sandbox-worker/worker-entry.d.ts.map +1 -0
  949. package/dist/js-sandbox-worker/worker-entry.js +307 -0
  950. package/dist/js-sandbox-worker/worker-entry.js.map +1 -0
  951. package/dist/js-sandbox.d.ts +455 -15
  952. package/dist/js-sandbox.d.ts.map +1 -1
  953. package/dist/js-sandbox.js +1961 -309
  954. package/dist/js-sandbox.js.map +1 -1
  955. package/dist/js-script-app-runner.d.ts +9 -0
  956. package/dist/js-script-app-runner.d.ts.map +1 -0
  957. package/dist/js-script-app-runner.js +49 -0
  958. package/dist/js-script-app-runner.js.map +1 -0
  959. package/dist/js-script-sandbox.d.ts +33 -0
  960. package/dist/js-script-sandbox.d.ts.map +1 -0
  961. package/dist/js-script-sandbox.js +82 -0
  962. package/dist/js-script-sandbox.js.map +1 -0
  963. package/dist/jtbd/friction.d.ts +26 -0
  964. package/dist/jtbd/friction.d.ts.map +1 -0
  965. package/dist/jtbd/friction.js +169 -0
  966. package/dist/jtbd/friction.js.map +1 -0
  967. package/dist/jtbd/index.d.ts +6 -0
  968. package/dist/jtbd/index.d.ts.map +1 -0
  969. package/dist/jtbd/index.js +6 -0
  970. package/dist/jtbd/index.js.map +1 -0
  971. package/dist/jtbd/optimize.d.ts +71 -0
  972. package/dist/jtbd/optimize.d.ts.map +1 -0
  973. package/dist/jtbd/optimize.js +176 -0
  974. package/dist/jtbd/optimize.js.map +1 -0
  975. package/dist/jtbd/registry.d.ts +29 -0
  976. package/dist/jtbd/registry.d.ts.map +1 -0
  977. package/dist/jtbd/registry.js +451 -0
  978. package/dist/jtbd/registry.js.map +1 -0
  979. package/dist/jtbd/run.d.ts +70 -0
  980. package/dist/jtbd/run.d.ts.map +1 -0
  981. package/dist/jtbd/run.js +177 -0
  982. package/dist/jtbd/run.js.map +1 -0
  983. package/dist/jtbd/types.d.ts +141 -0
  984. package/dist/jtbd/types.d.ts.map +1 -0
  985. package/dist/jtbd/types.js +25 -0
  986. package/dist/jtbd/types.js.map +1 -0
  987. package/dist/model-prompting-skills.d.ts +45 -0
  988. package/dist/model-prompting-skills.d.ts.map +1 -0
  989. package/dist/model-prompting-skills.js +116 -0
  990. package/dist/model-prompting-skills.js.map +1 -0
  991. package/dist/network-guard.d.ts +50 -0
  992. package/dist/network-guard.d.ts.map +1 -0
  993. package/dist/network-guard.js +106 -0
  994. package/dist/network-guard.js.map +1 -0
  995. package/dist/normalize-model-properties.d.ts +26 -0
  996. package/dist/normalize-model-properties.d.ts.map +1 -0
  997. package/dist/normalize-model-properties.js +58 -0
  998. package/dist/normalize-model-properties.js.map +1 -0
  999. package/dist/output-format.d.ts +5 -1
  1000. package/dist/output-format.d.ts.map +1 -1
  1001. package/dist/output-format.js.map +1 -1
  1002. package/dist/parallel-task-executor.d.ts +68 -37
  1003. package/dist/parallel-task-executor.d.ts.map +1 -1
  1004. package/dist/parallel-task-executor.js +234 -203
  1005. package/dist/parallel-task-executor.js.map +1 -1
  1006. package/dist/prompts/background-subtask-prompt.d.ts +14 -0
  1007. package/dist/prompts/background-subtask-prompt.d.ts.map +1 -0
  1008. package/dist/prompts/background-subtask-prompt.js +64 -0
  1009. package/dist/prompts/background-subtask-prompt.js.map +1 -0
  1010. package/dist/prompts/product-knowledge.d.ts +3 -0
  1011. package/dist/prompts/product-knowledge.d.ts.map +1 -0
  1012. package/dist/prompts/product-knowledge.js +79 -0
  1013. package/dist/prompts/product-knowledge.js.map +1 -0
  1014. package/dist/prompts/read-only-search-prompt.d.ts +33 -0
  1015. package/dist/prompts/read-only-search-prompt.d.ts.map +1 -0
  1016. package/dist/prompts/read-only-search-prompt.js +109 -0
  1017. package/dist/prompts/read-only-search-prompt.js.map +1 -0
  1018. package/dist/prompts/sandbox-pack-catalog.d.ts +23 -0
  1019. package/dist/prompts/sandbox-pack-catalog.d.ts.map +1 -0
  1020. package/dist/prompts/sandbox-pack-catalog.js +40 -0
  1021. package/dist/prompts/sandbox-pack-catalog.js.map +1 -0
  1022. package/dist/prompts/security-monitor-prompt.d.ts +32 -0
  1023. package/dist/prompts/security-monitor-prompt.d.ts.map +1 -0
  1024. package/dist/prompts/security-monitor-prompt.js +99 -0
  1025. package/dist/prompts/security-monitor-prompt.js.map +1 -0
  1026. package/dist/prompts/workflow-authoring-knowledge.d.ts +77 -0
  1027. package/dist/prompts/workflow-authoring-knowledge.d.ts.map +1 -0
  1028. package/dist/prompts/workflow-authoring-knowledge.js +319 -0
  1029. package/dist/prompts/workflow-authoring-knowledge.js.map +1 -0
  1030. package/dist/run-policy.d.ts +25 -0
  1031. package/dist/run-policy.d.ts.map +1 -0
  1032. package/dist/run-policy.js +54 -0
  1033. package/dist/run-policy.js.map +1 -0
  1034. package/dist/sandbox-av-media.d.ts +33 -0
  1035. package/dist/sandbox-av-media.d.ts.map +1 -0
  1036. package/dist/sandbox-av-media.js +666 -0
  1037. package/dist/sandbox-av-media.js.map +1 -0
  1038. package/dist/sandbox-bootstrap-modules.d.ts +54 -0
  1039. package/dist/sandbox-bootstrap-modules.d.ts.map +1 -0
  1040. package/dist/sandbox-bootstrap-modules.js +104 -0
  1041. package/dist/sandbox-bootstrap-modules.js.map +1 -0
  1042. package/dist/sandbox-bytes.d.ts +43 -0
  1043. package/dist/sandbox-bytes.d.ts.map +1 -0
  1044. package/dist/sandbox-bytes.js +61 -0
  1045. package/dist/sandbox-bytes.js.map +1 -0
  1046. package/dist/sandbox-canvas-api.d.ts +30 -0
  1047. package/dist/sandbox-canvas-api.d.ts.map +1 -0
  1048. package/dist/sandbox-canvas-api.js +81 -0
  1049. package/dist/sandbox-canvas-api.js.map +1 -0
  1050. package/dist/sandbox-constants.d.ts +5 -0
  1051. package/dist/sandbox-constants.d.ts.map +1 -0
  1052. package/dist/sandbox-constants.js +13 -0
  1053. package/dist/sandbox-constants.js.map +1 -0
  1054. package/dist/sandbox-json-transport.d.ts +107 -0
  1055. package/dist/sandbox-json-transport.d.ts.map +1 -0
  1056. package/dist/sandbox-json-transport.js +324 -0
  1057. package/dist/sandbox-json-transport.js.map +1 -0
  1058. package/dist/sandbox-media-handle.d.ts +78 -0
  1059. package/dist/sandbox-media-handle.d.ts.map +1 -0
  1060. package/dist/sandbox-media-handle.js +114 -0
  1061. package/dist/sandbox-media-handle.js.map +1 -0
  1062. package/dist/sandbox-media-ref.d.ts +134 -0
  1063. package/dist/sandbox-media-ref.d.ts.map +1 -0
  1064. package/dist/sandbox-media-ref.js +442 -0
  1065. package/dist/sandbox-media-ref.js.map +1 -0
  1066. package/dist/sandbox-media.d.ts +177 -0
  1067. package/dist/sandbox-media.d.ts.map +1 -0
  1068. package/dist/sandbox-media.js +963 -0
  1069. package/dist/sandbox-media.js.map +1 -0
  1070. package/dist/sandbox-module-fixtures.d.ts +445 -0
  1071. package/dist/sandbox-module-fixtures.d.ts.map +1 -0
  1072. package/dist/sandbox-module-fixtures.js +214 -0
  1073. package/dist/sandbox-module-fixtures.js.map +1 -0
  1074. package/dist/sandbox-toolbelt.d.ts +13 -0
  1075. package/dist/sandbox-toolbelt.d.ts.map +1 -0
  1076. package/dist/sandbox-toolbelt.js +64 -0
  1077. package/dist/sandbox-toolbelt.js.map +1 -0
  1078. package/dist/security-monitor.d.ts +89 -0
  1079. package/dist/security-monitor.d.ts.map +1 -0
  1080. package/dist/security-monitor.js +307 -0
  1081. package/dist/security-monitor.js.map +1 -0
  1082. package/dist/serpapi/catalog.d.ts +101 -0
  1083. package/dist/serpapi/catalog.d.ts.map +1 -0
  1084. package/dist/serpapi/catalog.js +246 -0
  1085. package/dist/serpapi/catalog.js.map +1 -0
  1086. package/dist/serpapi/client.d.ts +81 -0
  1087. package/dist/serpapi/client.d.ts.map +1 -0
  1088. package/dist/serpapi/client.js +228 -0
  1089. package/dist/serpapi/client.js.map +1 -0
  1090. package/dist/serpapi/errors.d.ts +49 -0
  1091. package/dist/serpapi/errors.d.ts.map +1 -0
  1092. package/dist/serpapi/errors.js +64 -0
  1093. package/dist/serpapi/errors.js.map +1 -0
  1094. package/dist/serpapi/normalize.d.ts +58 -0
  1095. package/dist/serpapi/normalize.d.ts.map +1 -0
  1096. package/dist/serpapi/normalize.js +140 -0
  1097. package/dist/serpapi/normalize.js.map +1 -0
  1098. package/dist/skill-prompt.d.ts +27 -0
  1099. package/dist/skill-prompt.d.ts.map +1 -0
  1100. package/dist/skill-prompt.js +61 -0
  1101. package/dist/skill-prompt.js.map +1 -0
  1102. package/dist/step-executor.d.ts +90 -77
  1103. package/dist/step-executor.d.ts.map +1 -1
  1104. package/dist/step-executor.js +384 -690
  1105. package/dist/step-executor.js.map +1 -1
  1106. package/dist/subagent.d.ts +275 -0
  1107. package/dist/subagent.d.ts.map +1 -0
  1108. package/dist/subagent.js +444 -0
  1109. package/dist/subagent.js.map +1 -0
  1110. package/dist/supervisor/prompt.d.ts +12 -0
  1111. package/dist/supervisor/prompt.d.ts.map +1 -0
  1112. package/dist/supervisor/prompt.js +51 -0
  1113. package/dist/supervisor/prompt.js.map +1 -0
  1114. package/dist/supervisor/supervisor-agent.d.ts +72 -0
  1115. package/dist/supervisor/supervisor-agent.d.ts.map +1 -0
  1116. package/dist/supervisor/supervisor-agent.js +185 -0
  1117. package/dist/supervisor/supervisor-agent.js.map +1 -0
  1118. package/dist/supervisor/tools.d.ts +56 -0
  1119. package/dist/supervisor/tools.d.ts.map +1 -0
  1120. package/dist/supervisor/tools.js +83 -0
  1121. package/dist/supervisor/tools.js.map +1 -0
  1122. package/dist/supervisor/verdict-schema.d.ts +18 -0
  1123. package/dist/supervisor/verdict-schema.d.ts.map +1 -0
  1124. package/dist/supervisor/verdict-schema.js +58 -0
  1125. package/dist/supervisor/verdict-schema.js.map +1 -0
  1126. package/dist/system-skills.d.ts +68 -0
  1127. package/dist/system-skills.d.ts.map +1 -0
  1128. package/dist/system-skills.js +168 -0
  1129. package/dist/system-skills.js.map +1 -0
  1130. package/dist/task-executor.d.ts +90 -40
  1131. package/dist/task-executor.d.ts.map +1 -1
  1132. package/dist/task-executor.js +259 -282
  1133. package/dist/task-executor.js.map +1 -1
  1134. package/dist/task-planner.d.ts +18 -12
  1135. package/dist/task-planner.d.ts.map +1 -1
  1136. package/dist/task-planner.js +342 -328
  1137. package/dist/task-planner.js.map +1 -1
  1138. package/dist/timeline-preview/compare.d.ts +27 -0
  1139. package/dist/timeline-preview/compare.d.ts.map +1 -0
  1140. package/dist/timeline-preview/compare.js +71 -0
  1141. package/dist/timeline-preview/compare.js.map +1 -0
  1142. package/dist/timeline-preview/frames.d.ts +167 -0
  1143. package/dist/timeline-preview/frames.d.ts.map +1 -0
  1144. package/dist/timeline-preview/frames.js +646 -0
  1145. package/dist/timeline-preview/frames.js.map +1 -0
  1146. package/dist/timeline-preview/model3d.d.ts +67 -0
  1147. package/dist/timeline-preview/model3d.d.ts.map +1 -0
  1148. package/dist/timeline-preview/model3d.js +165 -0
  1149. package/dist/timeline-preview/model3d.js.map +1 -0
  1150. package/dist/timeline-preview/rasterize.d.ts +33 -0
  1151. package/dist/timeline-preview/rasterize.d.ts.map +1 -0
  1152. package/dist/timeline-preview/rasterize.js +83 -0
  1153. package/dist/timeline-preview/rasterize.js.map +1 -0
  1154. package/dist/timeline-preview/sheet.d.ts +38 -0
  1155. package/dist/timeline-preview/sheet.d.ts.map +1 -0
  1156. package/dist/timeline-preview/sheet.js +72 -0
  1157. package/dist/timeline-preview/sheet.js.map +1 -0
  1158. package/dist/tools/asset-persist.d.ts +29 -0
  1159. package/dist/tools/asset-persist.d.ts.map +1 -0
  1160. package/dist/tools/asset-persist.js +78 -0
  1161. package/dist/tools/asset-persist.js.map +1 -0
  1162. package/dist/tools/base-tool.d.ts +52 -5
  1163. package/dist/tools/base-tool.d.ts.map +1 -1
  1164. package/dist/tools/base-tool.js +180 -3
  1165. package/dist/tools/base-tool.js.map +1 -1
  1166. package/dist/tools/binary-output.d.ts +54 -0
  1167. package/dist/tools/binary-output.d.ts.map +1 -0
  1168. package/dist/tools/binary-output.js +127 -0
  1169. package/dist/tools/binary-output.js.map +1 -0
  1170. package/dist/tools/browser-tools.d.ts +5 -29
  1171. package/dist/tools/browser-tools.d.ts.map +1 -1
  1172. package/dist/tools/browser-tools.js +5 -205
  1173. package/dist/tools/browser-tools.js.map +1 -1
  1174. package/dist/tools/builtin-tools.d.ts +52 -0
  1175. package/dist/tools/builtin-tools.d.ts.map +1 -0
  1176. package/dist/tools/builtin-tools.js +276 -0
  1177. package/dist/tools/builtin-tools.js.map +1 -0
  1178. package/dist/tools/control-tool.d.ts +2 -5
  1179. package/dist/tools/control-tool.d.ts.map +1 -1
  1180. package/dist/tools/control-tool.js +18 -15
  1181. package/dist/tools/control-tool.js.map +1 -1
  1182. package/dist/tools/dataseo-tools.d.ts +34 -32
  1183. package/dist/tools/dataseo-tools.d.ts.map +1 -1
  1184. package/dist/tools/dataseo-tools.js +148 -233
  1185. package/dist/tools/dataseo-tools.js.map +1 -1
  1186. package/dist/tools/external-capability-tools.d.ts +36 -0
  1187. package/dist/tools/external-capability-tools.d.ts.map +1 -0
  1188. package/dist/tools/external-capability-tools.js +41 -0
  1189. package/dist/tools/external-capability-tools.js.map +1 -0
  1190. package/dist/tools/external-mcp-tools.d.ts +139 -0
  1191. package/dist/tools/external-mcp-tools.d.ts.map +1 -0
  1192. package/dist/tools/external-mcp-tools.js +552 -0
  1193. package/dist/tools/external-mcp-tools.js.map +1 -0
  1194. package/dist/tools/finish-step-tool.d.ts +1 -1
  1195. package/dist/tools/finish-step-tool.d.ts.map +1 -1
  1196. package/dist/tools/finish-step-tool.js +3 -3
  1197. package/dist/tools/finish-step-tool.js.map +1 -1
  1198. package/dist/tools/google-tools.d.ts +28 -39
  1199. package/dist/tools/google-tools.d.ts.map +1 -1
  1200. package/dist/tools/google-tools.js +51 -164
  1201. package/dist/tools/google-tools.js.map +1 -1
  1202. package/dist/tools/google-workspace-tools.d.ts +23 -0
  1203. package/dist/tools/google-workspace-tools.d.ts.map +1 -0
  1204. package/dist/tools/google-workspace-tools.js +26 -0
  1205. package/dist/tools/google-workspace-tools.js.map +1 -0
  1206. package/dist/tools/graph-validation-registry.d.ts +33 -0
  1207. package/dist/tools/graph-validation-registry.d.ts.map +1 -0
  1208. package/dist/tools/graph-validation-registry.js +54 -0
  1209. package/dist/tools/graph-validation-registry.js.map +1 -0
  1210. package/dist/tools/http-tools.d.ts +5 -53
  1211. package/dist/tools/http-tools.d.ts.map +1 -1
  1212. package/dist/tools/http-tools.js +5 -177
  1213. package/dist/tools/http-tools.js.map +1 -1
  1214. package/dist/tools/image-injection.d.ts +51 -0
  1215. package/dist/tools/image-injection.d.ts.map +1 -0
  1216. package/dist/tools/image-injection.js +85 -0
  1217. package/dist/tools/image-injection.js.map +1 -0
  1218. package/dist/tools/mcp-tool-support.d.ts +203 -0
  1219. package/dist/tools/mcp-tool-support.d.ts.map +1 -0
  1220. package/dist/tools/mcp-tool-support.js +536 -0
  1221. package/dist/tools/mcp-tool-support.js.map +1 -0
  1222. package/dist/tools/mcp-tools.d.ts +104 -390
  1223. package/dist/tools/mcp-tools.d.ts.map +1 -1
  1224. package/dist/tools/mcp-tools.js +128 -600
  1225. package/dist/tools/mcp-tools.js.map +1 -1
  1226. package/dist/tools/media-tools.d.ts +9 -272
  1227. package/dist/tools/media-tools.d.ts.map +1 -1
  1228. package/dist/tools/media-tools.js +11 -676
  1229. package/dist/tools/media-tools.js.map +1 -1
  1230. package/dist/tools/memory-tools.d.ts +36 -0
  1231. package/dist/tools/memory-tools.d.ts.map +1 -0
  1232. package/dist/tools/memory-tools.js +52 -0
  1233. package/dist/tools/memory-tools.js.map +1 -0
  1234. package/dist/tools/openai-tools.d.ts +28 -68
  1235. package/dist/tools/openai-tools.d.ts.map +1 -1
  1236. package/dist/tools/openai-tools.js +51 -181
  1237. package/dist/tools/openai-tools.js.map +1 -1
  1238. package/dist/tools/plan-builder-tools.d.ts +141 -7
  1239. package/dist/tools/plan-builder-tools.d.ts.map +1 -1
  1240. package/dist/tools/plan-builder-tools.js +159 -86
  1241. package/dist/tools/plan-builder-tools.js.map +1 -1
  1242. package/dist/tools/run-search-tool.d.ts +82 -0
  1243. package/dist/tools/run-search-tool.d.ts.map +1 -0
  1244. package/dist/tools/run-search-tool.js +121 -0
  1245. package/dist/tools/run-search-tool.js.map +1 -0
  1246. package/dist/tools/run-subtask-tool.d.ts +49 -0
  1247. package/dist/tools/run-subtask-tool.d.ts.map +1 -0
  1248. package/dist/tools/run-subtask-tool.js +88 -0
  1249. package/dist/tools/run-subtask-tool.js.map +1 -0
  1250. package/dist/tools/search-tools.d.ts +5 -36
  1251. package/dist/tools/search-tools.d.ts.map +1 -1
  1252. package/dist/tools/search-tools.js +5 -215
  1253. package/dist/tools/search-tools.js.map +1 -1
  1254. package/dist/tools/serp-providers/apify-provider.d.ts +18 -0
  1255. package/dist/tools/serp-providers/apify-provider.d.ts.map +1 -0
  1256. package/dist/tools/serp-providers/apify-provider.js +93 -0
  1257. package/dist/tools/serp-providers/apify-provider.js.map +1 -0
  1258. package/dist/tools/serp-providers/brave-provider.d.ts +34 -0
  1259. package/dist/tools/serp-providers/brave-provider.d.ts.map +1 -0
  1260. package/dist/tools/serp-providers/brave-provider.js +86 -0
  1261. package/dist/tools/serp-providers/brave-provider.js.map +1 -0
  1262. package/dist/tools/serp-providers/dataforseo-provider.d.ts +14 -1
  1263. package/dist/tools/serp-providers/dataforseo-provider.d.ts.map +1 -1
  1264. package/dist/tools/serp-providers/dataforseo-provider.js +0 -9
  1265. package/dist/tools/serp-providers/dataforseo-provider.js.map +1 -1
  1266. package/dist/tools/serp-providers/gemini-provider.d.ts +45 -0
  1267. package/dist/tools/serp-providers/gemini-provider.d.ts.map +1 -0
  1268. package/dist/tools/serp-providers/gemini-provider.js +148 -0
  1269. package/dist/tools/serp-providers/gemini-provider.js.map +1 -0
  1270. package/dist/tools/serp-providers/index.d.ts +61 -0
  1271. package/dist/tools/serp-providers/index.d.ts.map +1 -1
  1272. package/dist/tools/serp-providers/index.js +119 -3
  1273. package/dist/tools/serp-providers/index.js.map +1 -1
  1274. package/dist/tools/serp-providers/openai-provider.d.ts +58 -0
  1275. package/dist/tools/serp-providers/openai-provider.d.ts.map +1 -0
  1276. package/dist/tools/serp-providers/openai-provider.js +113 -0
  1277. package/dist/tools/serp-providers/openai-provider.js.map +1 -0
  1278. package/dist/tools/serp-providers/serpapi-provider.d.ts +9 -5
  1279. package/dist/tools/serp-providers/serpapi-provider.d.ts.map +1 -1
  1280. package/dist/tools/serp-providers/serpapi-provider.js +26 -44
  1281. package/dist/tools/serp-providers/serpapi-provider.js.map +1 -1
  1282. package/dist/tools/serp-tool-factory.d.ts +27 -0
  1283. package/dist/tools/serp-tool-factory.d.ts.map +1 -0
  1284. package/dist/tools/serp-tool-factory.js +56 -0
  1285. package/dist/tools/serp-tool-factory.js.map +1 -0
  1286. package/dist/tools/shared-tools.d.ts +33 -0
  1287. package/dist/tools/shared-tools.d.ts.map +1 -0
  1288. package/dist/tools/shared-tools.js +39 -0
  1289. package/dist/tools/shared-tools.js.map +1 -0
  1290. package/dist/tools/start-subtask-tool.d.ts +51 -0
  1291. package/dist/tools/start-subtask-tool.d.ts.map +1 -0
  1292. package/dist/tools/start-subtask-tool.js +189 -0
  1293. package/dist/tools/start-subtask-tool.js.map +1 -0
  1294. package/dist/tools/submit-code-tool.d.ts +159 -0
  1295. package/dist/tools/submit-code-tool.d.ts.map +1 -0
  1296. package/dist/tools/submit-code-tool.js +209 -0
  1297. package/dist/tools/submit-code-tool.js.map +1 -0
  1298. package/dist/tools/subtask-fields.d.ts +11 -0
  1299. package/dist/tools/subtask-fields.d.ts.map +1 -0
  1300. package/dist/tools/subtask-fields.js +11 -0
  1301. package/dist/tools/subtask-fields.js.map +1 -0
  1302. package/dist/tools/todo-tools.d.ts +15 -0
  1303. package/dist/tools/todo-tools.d.ts.map +1 -0
  1304. package/dist/tools/todo-tools.js +15 -0
  1305. package/dist/tools/todo-tools.js.map +1 -0
  1306. package/dist/tools/tool-permissions.d.ts +40 -0
  1307. package/dist/tools/tool-permissions.d.ts.map +1 -0
  1308. package/dist/tools/tool-permissions.js +52 -0
  1309. package/dist/tools/tool-permissions.js.map +1 -0
  1310. package/dist/tools/tool-search.d.ts +39 -0
  1311. package/dist/tools/tool-search.d.ts.map +1 -0
  1312. package/dist/tools/tool-search.js +108 -0
  1313. package/dist/tools/tool-search.js.map +1 -0
  1314. package/dist/tools/vector-tool-support.d.ts +15 -0
  1315. package/dist/tools/vector-tool-support.d.ts.map +1 -0
  1316. package/dist/tools/vector-tool-support.js +133 -0
  1317. package/dist/tools/vector-tool-support.js.map +1 -0
  1318. package/dist/tools/vector-tools.d.ts +13 -220
  1319. package/dist/tools/vector-tools.d.ts.map +1 -1
  1320. package/dist/tools/vector-tools.js +7 -578
  1321. package/dist/tools/vector-tools.js.map +1 -1
  1322. package/dist/tools/wait-subtasks-tool.d.ts +27 -0
  1323. package/dist/tools/wait-subtasks-tool.d.ts.map +1 -0
  1324. package/dist/tools/wait-subtasks-tool.js +66 -0
  1325. package/dist/tools/wait-subtasks-tool.js.map +1 -0
  1326. package/dist/tsconfig.tests.tmp.tsbuildinfo +1 -0
  1327. package/dist/types.d.ts +16 -31
  1328. package/dist/types.d.ts.map +1 -1
  1329. package/dist/types.js +8 -1
  1330. package/dist/types.js.map +1 -1
  1331. package/dist/utils/dag-scheduler.d.ts +85 -0
  1332. package/dist/utils/dag-scheduler.d.ts.map +1 -0
  1333. package/dist/utils/dag-scheduler.js +180 -0
  1334. package/dist/utils/dag-scheduler.js.map +1 -0
  1335. package/dist/utils/json-parser.d.ts +32 -1
  1336. package/dist/utils/json-parser.d.ts.map +1 -1
  1337. package/dist/utils/json-parser.js +145 -10
  1338. package/dist/utils/json-parser.js.map +1 -1
  1339. package/dist/utils/json-schema-validate.d.ts +29 -0
  1340. package/dist/utils/json-schema-validate.d.ts.map +1 -0
  1341. package/dist/utils/json-schema-validate.js +228 -0
  1342. package/dist/utils/json-schema-validate.js.map +1 -0
  1343. package/dist/utils/link-abort.d.ts +13 -0
  1344. package/dist/utils/link-abort.d.ts.map +1 -0
  1345. package/dist/utils/link-abort.js +23 -0
  1346. package/dist/utils/link-abort.js.map +1 -0
  1347. package/dist/utils/merge-generators.d.ts +58 -0
  1348. package/dist/utils/merge-generators.d.ts.map +1 -0
  1349. package/dist/utils/merge-generators.js +148 -0
  1350. package/dist/utils/merge-generators.js.map +1 -0
  1351. package/dist/utils/remove-base64-images.d.ts +0 -5
  1352. package/dist/utils/remove-base64-images.d.ts.map +1 -1
  1353. package/dist/utils/remove-base64-images.js.map +1 -1
  1354. package/dist/utils/step-failure.d.ts +20 -0
  1355. package/dist/utils/step-failure.d.ts.map +1 -0
  1356. package/dist/utils/step-failure.js +43 -0
  1357. package/dist/utils/step-failure.js.map +1 -0
  1358. package/dist/utils/think-tags.d.ts +16 -0
  1359. package/dist/utils/think-tags.d.ts.map +1 -0
  1360. package/dist/utils/think-tags.js +23 -0
  1361. package/dist/utils/think-tags.js.map +1 -0
  1362. package/dist/utils/type-guards.d.ts +26 -0
  1363. package/dist/utils/type-guards.d.ts.map +1 -0
  1364. package/dist/utils/type-guards.js +44 -0
  1365. package/dist/utils/type-guards.js.map +1 -0
  1366. package/dist/utils/ui-event-buffer.d.ts +18 -0
  1367. package/dist/utils/ui-event-buffer.d.ts.map +1 -0
  1368. package/dist/utils/ui-event-buffer.js +18 -0
  1369. package/dist/utils/ui-event-buffer.js.map +1 -0
  1370. package/dist/utils/wrap-generators-parallel.d.ts +0 -5
  1371. package/dist/utils/wrap-generators-parallel.d.ts.map +1 -1
  1372. package/dist/utils/wrap-generators-parallel.js +3 -6
  1373. package/dist/utils/wrap-generators-parallel.js.map +1 -1
  1374. package/dist/wasm-sandbox/host.d.ts +106 -0
  1375. package/dist/wasm-sandbox/host.d.ts.map +1 -0
  1376. package/dist/wasm-sandbox/host.js +409 -0
  1377. package/dist/wasm-sandbox/host.js.map +1 -0
  1378. package/dist/wasm-sandbox/workers.d.ts +43 -0
  1379. package/dist/wasm-sandbox/workers.d.ts.map +1 -0
  1380. package/dist/wasm-sandbox/workers.js +150 -0
  1381. package/dist/wasm-sandbox/workers.js.map +1 -0
  1382. package/dist/workspace-paths.d.ts +40 -0
  1383. package/dist/workspace-paths.d.ts.map +1 -0
  1384. package/dist/workspace-paths.js +102 -0
  1385. package/dist/workspace-paths.js.map +1 -0
  1386. package/dist/yt-dlp-gate.d.ts +19 -0
  1387. package/dist/yt-dlp-gate.d.ts.map +1 -0
  1388. package/dist/yt-dlp-gate.js +22 -0
  1389. package/dist/yt-dlp-gate.js.map +1 -0
  1390. package/package.json +112 -14
  1391. package/dist/agent-executor.d.ts +0 -62
  1392. package/dist/agent-executor.d.ts.map +0 -1
  1393. package/dist/agent-executor.js +0 -324
  1394. package/dist/agent-executor.js.map +0 -1
  1395. package/dist/agent-step-executor.d.ts +0 -28
  1396. package/dist/agent-step-executor.d.ts.map +0 -1
  1397. package/dist/agent-step-executor.js +0 -99
  1398. package/dist/agent-step-executor.js.map +0 -1
  1399. package/dist/agent-workflow-runner.d.ts +0 -31
  1400. package/dist/agent-workflow-runner.d.ts.map +0 -1
  1401. package/dist/agent-workflow-runner.js +0 -124
  1402. package/dist/agent-workflow-runner.js.map +0 -1
  1403. package/dist/agent.d.ts +0 -115
  1404. package/dist/agent.d.ts.map +0 -1
  1405. package/dist/agent.js +0 -587
  1406. package/dist/agent.js.map +0 -1
  1407. package/dist/base-agent.d.ts +0 -42
  1408. package/dist/base-agent.d.ts.map +0 -1
  1409. package/dist/base-agent.js +0 -29
  1410. package/dist/base-agent.js.map +0 -1
  1411. package/dist/graph-planner.d.ts +0 -56
  1412. package/dist/graph-planner.d.ts.map +0 -1
  1413. package/dist/graph-planner.js +0 -311
  1414. package/dist/graph-planner.js.map +0 -1
  1415. package/dist/multi-mode-agent.d.ts +0 -86
  1416. package/dist/multi-mode-agent.d.ts.map +0 -1
  1417. package/dist/multi-mode-agent.js +0 -476
  1418. package/dist/multi-mode-agent.js.map +0 -1
  1419. package/dist/prompts/graph-planner-prompt.d.ts +0 -48
  1420. package/dist/prompts/graph-planner-prompt.d.ts.map +0 -1
  1421. package/dist/prompts/graph-planner-prompt.js +0 -180
  1422. package/dist/prompts/graph-planner-prompt.js.map +0 -1
  1423. package/dist/reject-agentic-provider.d.ts +0 -21
  1424. package/dist/reject-agentic-provider.d.ts.map +0 -1
  1425. package/dist/reject-agentic-provider.js +0 -32
  1426. package/dist/reject-agentic-provider.js.map +0 -1
  1427. package/dist/simple-agent.d.ts +0 -29
  1428. package/dist/simple-agent.d.ts.map +0 -1
  1429. package/dist/simple-agent.js +0 -54
  1430. package/dist/simple-agent.js.map +0 -1
  1431. package/dist/sub-agent-planner.d.ts +0 -33
  1432. package/dist/sub-agent-planner.d.ts.map +0 -1
  1433. package/dist/sub-agent-planner.js +0 -203
  1434. package/dist/sub-agent-planner.js.map +0 -1
  1435. package/dist/team/db-task-board.d.ts +0 -54
  1436. package/dist/team/db-task-board.d.ts.map +0 -1
  1437. package/dist/team/db-task-board.js +0 -361
  1438. package/dist/team/db-task-board.js.map +0 -1
  1439. package/dist/team/edge-message-bus.d.ts +0 -51
  1440. package/dist/team/edge-message-bus.d.ts.map +0 -1
  1441. package/dist/team/edge-message-bus.js +0 -169
  1442. package/dist/team/edge-message-bus.js.map +0 -1
  1443. package/dist/team/edge-task-board.d.ts +0 -77
  1444. package/dist/team/edge-task-board.d.ts.map +0 -1
  1445. package/dist/team/edge-task-board.js +0 -140
  1446. package/dist/team/edge-task-board.js.map +0 -1
  1447. package/dist/team/index.d.ts +0 -16
  1448. package/dist/team/index.d.ts.map +0 -1
  1449. package/dist/team/index.js +0 -17
  1450. package/dist/team/index.js.map +0 -1
  1451. package/dist/team/message-bus.d.ts +0 -58
  1452. package/dist/team/message-bus.d.ts.map +0 -1
  1453. package/dist/team/message-bus.js +0 -151
  1454. package/dist/team/message-bus.js.map +0 -1
  1455. package/dist/team/task-board.d.ts +0 -106
  1456. package/dist/team/task-board.d.ts.map +0 -1
  1457. package/dist/team/task-board.js +0 -370
  1458. package/dist/team/task-board.js.map +0 -1
  1459. package/dist/team/team-executor.d.ts +0 -72
  1460. package/dist/team/team-executor.d.ts.map +0 -1
  1461. package/dist/team/team-executor.js +0 -466
  1462. package/dist/team/team-executor.js.map +0 -1
  1463. package/dist/team/team-tools.d.ts +0 -252
  1464. package/dist/team/team-tools.d.ts.map +0 -1
  1465. package/dist/team/team-tools.js +0 -412
  1466. package/dist/team/team-tools.js.map +0 -1
  1467. package/dist/team/types.d.ts +0 -198
  1468. package/dist/team/types.d.ts.map +0 -1
  1469. package/dist/team/types.js +0 -8
  1470. package/dist/team/types.js.map +0 -1
  1471. package/dist/tools/add-edge-tool.d.ts +0 -18
  1472. package/dist/tools/add-edge-tool.d.ts.map +0 -1
  1473. package/dist/tools/add-edge-tool.js +0 -92
  1474. package/dist/tools/add-edge-tool.js.map +0 -1
  1475. package/dist/tools/add-node-tool.d.ts +0 -22
  1476. package/dist/tools/add-node-tool.d.ts.map +0 -1
  1477. package/dist/tools/add-node-tool.js +0 -128
  1478. package/dist/tools/add-node-tool.js.map +0 -1
  1479. package/dist/tools/asset-tools.d.ts +0 -58
  1480. package/dist/tools/asset-tools.d.ts.map +0 -1
  1481. package/dist/tools/asset-tools.js +0 -191
  1482. package/dist/tools/asset-tools.js.map +0 -1
  1483. package/dist/tools/calculator-tool.d.ts +0 -24
  1484. package/dist/tools/calculator-tool.d.ts.map +0 -1
  1485. package/dist/tools/calculator-tool.js +0 -64
  1486. package/dist/tools/calculator-tool.js.map +0 -1
  1487. package/dist/tools/claude-code-tools.d.ts +0 -96
  1488. package/dist/tools/claude-code-tools.d.ts.map +0 -1
  1489. package/dist/tools/claude-code-tools.js +0 -463
  1490. package/dist/tools/claude-code-tools.js.map +0 -1
  1491. package/dist/tools/code-tools.d.ts +0 -26
  1492. package/dist/tools/code-tools.d.ts.map +0 -1
  1493. package/dist/tools/code-tools.js +0 -82
  1494. package/dist/tools/code-tools.js.map +0 -1
  1495. package/dist/tools/create-plan-tool.d.ts +0 -29
  1496. package/dist/tools/create-plan-tool.d.ts.map +0 -1
  1497. package/dist/tools/create-plan-tool.js +0 -355
  1498. package/dist/tools/create-plan-tool.js.map +0 -1
  1499. package/dist/tools/create-task-tool.d.ts +0 -28
  1500. package/dist/tools/create-task-tool.d.ts.map +0 -1
  1501. package/dist/tools/create-task-tool.js +0 -254
  1502. package/dist/tools/create-task-tool.js.map +0 -1
  1503. package/dist/tools/email-tools.d.ts +0 -76
  1504. package/dist/tools/email-tools.d.ts.map +0 -1
  1505. package/dist/tools/email-tools.js +0 -259
  1506. package/dist/tools/email-tools.js.map +0 -1
  1507. package/dist/tools/filesystem-tools.d.ts +0 -77
  1508. package/dist/tools/filesystem-tools.d.ts.map +0 -1
  1509. package/dist/tools/filesystem-tools.js +0 -334
  1510. package/dist/tools/filesystem-tools.js.map +0 -1
  1511. package/dist/tools/find-model-tool.d.ts +0 -25
  1512. package/dist/tools/find-model-tool.d.ts.map +0 -1
  1513. package/dist/tools/find-model-tool.js +0 -236
  1514. package/dist/tools/find-model-tool.js.map +0 -1
  1515. package/dist/tools/finish-graph-tool.d.ts +0 -23
  1516. package/dist/tools/finish-graph-tool.d.ts.map +0 -1
  1517. package/dist/tools/finish-graph-tool.js +0 -46
  1518. package/dist/tools/finish-graph-tool.js.map +0 -1
  1519. package/dist/tools/js-code-tool.d.ts +0 -30
  1520. package/dist/tools/js-code-tool.d.ts.map +0 -1
  1521. package/dist/tools/js-code-tool.js +0 -98
  1522. package/dist/tools/js-code-tool.js.map +0 -1
  1523. package/dist/tools/local-get-node-info-tool.d.ts +0 -19
  1524. package/dist/tools/local-get-node-info-tool.d.ts.map +0 -1
  1525. package/dist/tools/local-get-node-info-tool.js +0 -75
  1526. package/dist/tools/local-get-node-info-tool.js.map +0 -1
  1527. package/dist/tools/local-list-nodes-tool.d.ts +0 -19
  1528. package/dist/tools/local-list-nodes-tool.d.ts.map +0 -1
  1529. package/dist/tools/local-list-nodes-tool.js +0 -69
  1530. package/dist/tools/local-list-nodes-tool.js.map +0 -1
  1531. package/dist/tools/local-search-nodes-tool.d.ts +0 -21
  1532. package/dist/tools/local-search-nodes-tool.d.ts.map +0 -1
  1533. package/dist/tools/local-search-nodes-tool.js +0 -111
  1534. package/dist/tools/local-search-nodes-tool.js.map +0 -1
  1535. package/dist/tools/math-tools.d.ts +0 -156
  1536. package/dist/tools/math-tools.d.ts.map +0 -1
  1537. package/dist/tools/math-tools.js +0 -422
  1538. package/dist/tools/math-tools.js.map +0 -1
  1539. package/dist/tools/model-tools.d.ts +0 -25
  1540. package/dist/tools/model-tools.d.ts.map +0 -1
  1541. package/dist/tools/model-tools.js +0 -48
  1542. package/dist/tools/model-tools.js.map +0 -1
  1543. package/dist/tools/pdf-tools.d.ts +0 -152
  1544. package/dist/tools/pdf-tools.d.ts.map +0 -1
  1545. package/dist/tools/pdf-tools.js +0 -339
  1546. package/dist/tools/pdf-tools.js.map +0 -1
  1547. package/dist/tools/tool-registry.d.ts +0 -9
  1548. package/dist/tools/tool-registry.d.ts.map +0 -1
  1549. package/dist/tools/tool-registry.js +0 -17
  1550. package/dist/tools/tool-registry.js.map +0 -1
  1551. package/dist/tools/workspace-tools.d.ts +0 -58
  1552. package/dist/tools/workspace-tools.d.ts.map +0 -1
  1553. package/dist/tools/workspace-tools.js +0 -152
  1554. package/dist/tools/workspace-tools.js.map +0 -1
@@ -1,27 +1,79 @@
1
1
  /**
2
2
  * Shared sandboxed JavaScript execution engine.
3
3
  *
4
- * Used by both the MiniJSAgentTool (agent tool) and the CodeNode (workflow node).
4
+ * Used by the CodeAct executor (agent actions) and the CodeNode (workflow node).
5
5
  * Runs user code in an isolated QuickJS WebAssembly context — the guest has its
6
6
  * own heap inside the WASM instance, so there is a real memory/CPU boundary
7
7
  * between host and guest (unlike Node's `node:vm`, which shares the V8 heap).
8
8
  *
9
9
  * The exposed surface is a small curated one: vanilla JavaScript plus a handful
10
- * of bridge functions (`fetch`, `workspace`, `getSecret`, `uuid`, `sleep`,
11
- * `assetToSandbox`, `sandboxToAsset`, `console`). Library-powered helpers
12
- * (lodash, dayjs, cheerio, csv-parse,
13
- * validator) are intentionally NOT exposed here — use the dedicated workflow
14
- * nodes instead (lib.datetime.*, lib.html.*, lib.data.ParseCSV,
15
- * lib.validate.*, etc.). Keeping the sandbox lib-free makes snippet behaviour
16
- * identical between dev and packaged Electron, and avoids shipping those
17
- * packages into the user-code surface.
10
+ * of bridge functions (`fetch`, `workspace`, `getSecret`, `sleep`,
11
+ * `assetToSandbox`, `sandboxToAsset`, `crypto`, `console`, `progress`,
12
+ * `format`, `image`, `canvas`) and a few pure guest-side helpers
13
+ * (`toBase64`, `fromBase64`, `toHex`, `fromHex`,
14
+ * `parallelMap`, `createCanvas`). `crypto`
15
+ * covers `randomUUID`, `getRandomValues`, `digest`, and `hmac`
16
+ * (WebCrypto-backed); `workspace` covers text and binary reads/writes plus
17
+ * `stat`, `mkdir`, and `remove`; `progress` forwards a percentage and label to
18
+ * the host caller (rate-limited); `console.*` appends to the run's `logs`
19
+ * array and, when the caller set {@link RunSandboxOptions.onLog}, forwards
20
+ * each line live (capped); `format` exposes host `Intl` number, date,
21
+ * relative-time and list formatting, which QuickJS itself does not ship.
22
+ * Every quantitative limit (fetch calls, response body, output size,
23
+ * guest heap, stack, fetch timeout) is overridable per invocation through
24
+ * `RunSandboxOptions.limits`, clamped to hard ceilings.
25
+ *
26
+ * The guest imports nothing by default — without `RunSandboxOptions.modules`
27
+ * every specifier is denied by name, so user code cannot `import`/`require`
28
+ * anything. With it, the run's resolved sandbox packages and their intra-pack
29
+ * siblings are the only importable modules (see {@link createGuestModuleHost}),
30
+ * and dynamic `import()` stays denied.
31
+ *
32
+ * **Every library the sandbox offers is an importable module.** Some are guest
33
+ * modules the compiler admitted (js-yaml, date-fns); the rest are *host
34
+ * modules* — papaparse, cheerio, exceljs, fflate and friends — which run on the
35
+ * host behind a generated ESM facade over a per-run dispatcher
36
+ * (`host-modules/`), because they need Node builtins the guest lacks or carry a
37
+ * limit the guest could not enforce. Either way the guest writes `import`, and
38
+ * the pack has to be installed. The remaining globals — `fetch`,
39
+ * `workspace`, `getSecret`, the asset bridges, `format.*` (Intl), `crypto.*`
40
+ * (WebCrypto), `image.*`/`canvas.*` — are not libraries: they are the
41
+ * capabilities the node granted this run.
42
+ *
43
+ * The sandbox is fully asynchronous. Every host bridge call returns a real
44
+ * promise, and a bridge call starts its host-side work the moment it is
45
+ * invoked — not when it is awaited — so `Promise.all` (and `allSettled`,
46
+ * `race`, `any`) over bridge calls runs them in parallel on the host. Five
47
+ * fetches under `Promise.all` take one round trip, not five. `parallelMap`
48
+ * is the bounded form of that fan-out. `sleep` is the only timer: the
49
+ * timer globals (`setTimeout` and friends) are deleted inside the user-code
50
+ * module (see {@link wrapCode}), because timer callbacks would run outside
51
+ * the never-reject/abort-guard conventions every bridge follows.
18
52
  */
19
- import { addSerializer, expose, loadQuickJs } from "@sebastianwessel/quickjs";
20
- // The variant package uses a `default` export. With `esModuleInterop` this
21
- // typechecks as a namespace, so reach through `.default` explicitly.
53
+ import { loadQuickJs } from "@sebastianwessel/quickjs";
54
+ import { SANDBOX_CAPABILITY_DISPATCH_GLOBAL, SANDBOX_WASM_DISPATCH_GLOBAL } from "@nodetool-ai/protocol";
55
+ import { createSandboxHostDispatcher } from "./host-modules/dispatcher.js";
56
+ import { EXPOSED_BRIDGE_NAMES, MAX_ENGINE_TIMEOUT_MS, NO_INPUT_STREAM_MESSAGE, registerTypedArraySerializers, runInterpreter, SANDBOX_CAPABILITY_BRIDGE_BINDING, SANDBOX_INPUT_TAKE_BINDING, SANDBOX_STREAM_OPEN_BINDING, SANDBOX_WASM_BRIDGE_BINDING } from "./js-sandbox-worker/interpreter.js";
57
+ import { SANDBOX_SERIALIZE_MAX_DEPTH, toGuestBytes, toGuestBytesDeep } from "./sandbox-bytes.js";
58
+ import { isBoolean, isFunction, isNonEmptyString, isNumber, isObjectLike, isRecord, isString } from "./utils/type-guards.js";
59
+ import { createSandboxMediaStore, isSandboxMediaHandle, MAX_RUN_MEDIA_BYTES } from "./sandbox-media-handle.js";
60
+ import { createMediaRefBridge, looksLikeMediaRef, mimeForRef, remapMediaRef, resolveRefBytes } from "./sandbox-media-ref.js";
61
+ import { createSandboxWasmDispatcher } from "./wasm-sandbox/host.js";
62
+ import { runInWorker } from "./js-sandbox-worker/host.js";
63
+ import { assertFetchUrlAllowed, assertResolvedHostAllowed } from "./network-guard.js";
64
+ import { GUEST_GLOBALS_JSON_BINDING, GUEST_GLOBALS_SIDECAR_BINDING, GUEST_MARSHAL_GLOBAL } from "./sandbox-json-transport.js";
65
+ import { MAX_RANDOM_BYTES } from "./sandbox-constants.js";
66
+ import { deriveBridgeShape, precheckCloneSafety, SANDBOX_DISPATCHER_BINDINGS } from "./js-sandbox-worker/protocol.js";
22
67
  import * as quickJsVariantModule from "@jitl/quickjs-ng-wasmfile-release-sync";
68
+ /**
69
+ * The variant package is CJS with a `default` export, so `ns.default` is the
70
+ * variant at runtime.
71
+ */
72
+ // SAFETY: TypeScript's CJS interop synthesizes `default` as the whole module
73
+ // object, contradicting the package's own `.d.ts`, which declares it as the
74
+ // `QuickJSSyncVariant` this reads.
23
75
  const quickJsVariant = quickJsVariantModule.default;
24
- import { Scope } from "quickjs-emscripten-core";
76
+ import { importNodeBuiltin } from "@nodetool-ai/config";
25
77
  // ---------------------------------------------------------------------------
26
78
  // Constants
27
79
  // ---------------------------------------------------------------------------
@@ -34,44 +86,102 @@ export const MAX_RESPONSE_BODY_SIZE = 1_000_000;
34
86
  export const GUEST_MEMORY_LIMIT = 64 * 1024 * 1024;
35
87
  /** Guest stack cap — protects against deeply recursive code. */
36
88
  export const GUEST_STACK_LIMIT = 512 * 1024;
89
+ /** Per-request wall-clock cap for the fetch bridge. */
90
+ export const FETCH_TIMEOUT_MS = 15_000;
91
+ /** Redirect hops the fetch bridge follows before giving up. */
92
+ export const MAX_FETCH_REDIRECTS = 5;
93
+ /** Locale used by the `format` bridge when the caller names none. */
94
+ export const DEFAULT_FORMAT_LOCALE = "en-US";
95
+ export { MAX_RANDOM_BYTES };
96
+ /** Progress reports forwarded to the host per run; further calls are dropped. */
97
+ export const MAX_PROGRESS_CALLS = 1000;
98
+ /** Console lines forwarded to {@link RunSandboxOptions.onLog} per run. */
99
+ export const MAX_CONSOLE_LOGS = 1000;
100
+ /** Longest console line forwarded to the host. A collected line is not truncated on its own. */
101
+ export const MAX_CONSOLE_LOG_CHARS = 4000;
102
+ /**
103
+ * Console lines the run's `logs` array collects. Forwarding was capped and
104
+ * collection was not: guest strings are not charged to the QuickJS heap, so a
105
+ * `console.log` in a hot loop grew host memory for the length of the action.
106
+ */
107
+ export const MAX_COLLECTED_CONSOLE_LOGS = 5000;
108
+ /** Characters the run's `logs` array collects in total, across every line. */
109
+ export const MAX_COLLECTED_CONSOLE_CHARS = 512 * 1024;
110
+ /** The single line that closes a collected log the caps cut. */
111
+ export const CONSOLE_LOGS_CUT_NOTICE = `[console output cut: at most ${MAX_COLLECTED_CONSOLE_LOGS} lines / ` +
112
+ `${MAX_COLLECTED_CONSOLE_CHARS} characters are kept per run]`;
113
+ /**
114
+ * Emitted values a run may deliver. Unlike progress reports, emits are never
115
+ * dropped or rate-limited — every value reaches the host in call order — so the
116
+ * cap is enforced by throwing in the guest rather than by ignoring the call.
117
+ */
118
+ export const MAX_EMIT_CALLS = 10_000;
119
+ /** Minimum gap between two forwarded progress reports. */
120
+ export const PROGRESS_MIN_INTERVAL_MS = 100;
121
+ /** Longest progress message forwarded to the host. */
122
+ export const MAX_PROGRESS_MESSAGE_CHARS = 500;
123
+ /**
124
+ * Headroom added to the engine's own wall-clock abort when a {@link SandboxClock}
125
+ * is in play. The clock only stops the *guest's* budget; this bounds how long a
126
+ * run may stay suspended in total, so a prompt nobody ever answers still ends.
127
+ */
128
+ export const DEFAULT_SUSPEND_ALLOWANCE_MS = 30 * 60 * 1000;
129
+ /**
130
+ * Suspension allowance a run with an input stream gets by default.
131
+ *
132
+ * Effectively unbounded, deliberately: a streaming body legitimately lives as
133
+ * long as its upstream produces, and the run's own cancellation is the lifetime
134
+ * bound. A stream that never ends is the upstream's bug, surfaced by the
135
+ * runner — not a reason to kill a correct consumer. A caller that wants a
136
+ * shorter leash passes {@link RunSandboxOptions.suspendAllowanceMs}.
137
+ */
138
+ export const INPUT_STREAM_SUSPEND_ALLOWANCE_MS = MAX_ENGINE_TIMEOUT_MS;
139
+ /**
140
+ * What the guest is told when it calls `stream` in a run that has no input
141
+ * stream behind it. Shared by the host bridge and the guest prelude so both
142
+ * paths say the same thing — the prelude lives with the interpreter, so the
143
+ * message does too.
144
+ */
145
+ export { NO_INPUT_STREAM_MESSAGE } from "./js-sandbox-worker/interpreter.js";
146
+ /**
147
+ * Normalize a declared secret scope: a list of non-empty names, or `null` for
148
+ * an unscoped run. An empty declared list stays empty — it denies everything.
149
+ */
150
+ function resolveSecretScope(scope) {
151
+ if (!Array.isArray(scope))
152
+ return null;
153
+ return scope
154
+ .filter((name) => typeof name === "string" && name !== "")
155
+ .map((name) => name.trim())
156
+ .filter((name) => name !== "");
157
+ }
158
+ function clampLimit(value, fallback, min, max) {
159
+ if (value == null || !Number.isFinite(value))
160
+ return fallback;
161
+ return Math.min(Math.max(Math.floor(value), min), max);
162
+ }
163
+ /** Apply defaults and ceilings to a caller-supplied {@link SandboxLimits}. */
164
+ export function resolveSandboxLimits(limits) {
165
+ return {
166
+ maxFetchCalls: clampLimit(limits?.maxFetchCalls, MAX_FETCH_CALLS, 0, 100),
167
+ maxResponseBodyBytes: clampLimit(limits?.maxResponseBodyBytes, MAX_RESPONSE_BODY_SIZE, 1024, 50 * 1024 * 1024),
168
+ maxOutputSize: clampLimit(limits?.maxOutputSize, MAX_OUTPUT_SIZE, 1024, 10 * 1024 * 1024),
169
+ memoryLimitBytes: clampLimit(limits?.memoryLimitBytes, GUEST_MEMORY_LIMIT, 1024 * 1024, 512 * 1024 * 1024),
170
+ runMediaBytes: clampLimit(limits?.runMediaBytes, MAX_RUN_MEDIA_BYTES, 1024 * 1024, 2 * 1024 * 1024 * 1024),
171
+ stackLimitBytes: clampLimit(limits?.stackLimitBytes, GUEST_STACK_LIMIT, 16 * 1024, 8 * 1024 * 1024),
172
+ fetchTimeoutMs: clampLimit(limits?.fetchTimeoutMs, FETCH_TIMEOUT_MS, 100, 120_000),
173
+ // Not clamped — these are capability switches, not magnitudes. Both
174
+ // resolve to the restrictive value unless the host explicitly opts out.
175
+ allowPrivateNetwork: limits?.allowPrivateNetwork === true,
176
+ userAgent: limits?.userAgent ?? "",
177
+ filesystemAccess: limits?.filesystemAccess === "host" ? "host" : "workspace",
178
+ secretScope: resolveSecretScope(limits?.secretScope)
179
+ };
180
+ }
37
181
  // ---------------------------------------------------------------------------
38
182
  // Engine bootstrap — one WASM module shared by every invocation.
39
183
  // ---------------------------------------------------------------------------
40
184
  let enginePromise = null;
41
- let serializersRegistered = false;
42
- function registerTypedArraySerializers() {
43
- if (serializersRegistered)
44
- return;
45
- serializersRegistered = true;
46
- // Map every typed-array class to a native Uint8Array on the host side.
47
- // The guest returns `new Uint8Array([...])` (or friends); without this,
48
- // the library's generic object serializer produces a plain object with
49
- // numeric keys, which downstream code (CodeNode's normalizeOutput) would
50
- // miss when detecting binary values.
51
- const typedArrayNames = [
52
- "Uint8Array",
53
- "Int8Array",
54
- "Uint8ClampedArray",
55
- "Int16Array",
56
- "Uint16Array",
57
- "Int32Array",
58
- "Uint32Array",
59
- "Float32Array",
60
- "Float64Array"
61
- ];
62
- for (const name of typedArrayNames) {
63
- addSerializer(name, (ctx, handle) => {
64
- const bufferHandle = ctx.getProp(handle, "buffer");
65
- try {
66
- const ab = ctx.getArrayBuffer(bufferHandle);
67
- return Uint8Array.from(ab.value);
68
- }
69
- finally {
70
- bufferHandle.dispose();
71
- }
72
- });
73
- }
74
- }
75
185
  function getEngine() {
76
186
  registerTypedArraySerializers();
77
187
  if (!enginePromise) {
@@ -80,31 +190,82 @@ function getEngine() {
80
190
  return enginePromise;
81
191
  }
82
192
  /**
83
- * Marker key placed on an object to signal a sandboxed error. A host async
84
- * function that would normally `throw` instead resolves with one of these
85
- * objects; a prelude inside the guest rewraps them as real guest-side errors.
193
+ * The guest engine can fail in two ways that never reach `runInSandbox`'s own
194
+ * `await`, and both used to end the same way: the host process died, the tool
195
+ * call it was serving returned *nothing*, and the agent driving it saw a turn
196
+ * that simply stopped. A missing result is worse than any error — there is
197
+ * nothing to read and nothing to retry.
198
+ *
199
+ * 1. An Emscripten `abort()` (the `list_empty(&rt->gc_obj_list)` assertion in
200
+ * `JS_FreeRuntime`) surfaces as a `RuntimeError` from the WASM module.
201
+ * 2. A marshaling failure — most often guest OOM while a host return value is
202
+ * being written into the guest — throws inside a promise continuation the
203
+ * library created and never catches, so it lands as an unhandled rejection.
86
204
  *
87
- * This indirection exists because the current `@sebastianwessel/quickjs`
88
- * runtime leaks handles whenever a host-backed guest Promise is *rejected*,
89
- * tripping an internal assertion (`list_empty(&rt->gc_obj_list)`) in
90
- * quickjs-ng when the runtime is freed. Routing failures through a resolved
91
- * tagged value sidesteps the leak while preserving the guest-visible
92
- * behaviour (the user still gets a thrown Error with name + message).
205
+ * `guardHostProcess` races the run against those escapes. A rejection that
206
+ * looks like the engine's fails the run; anything else is re-thrown on the next
207
+ * tick so a genuine host bug still crashes the way it should.
93
208
  */
94
- const SANDBOX_ERROR_MARKER = "__nodetool_sandbox_error__";
95
- function neverReject(fn) {
96
- return async (...args) => {
97
- try {
98
- return await fn(...args);
99
- }
100
- catch (e) {
101
- return {
102
- [SANDBOX_ERROR_MARKER]: true,
103
- name: e instanceof Error ? e.name : "Error",
104
- message: e instanceof Error ? e.message : String(e)
105
- };
106
- }
107
- };
209
+ function isEngineFailure(error) {
210
+ const name = error?.constructor?.name ?? "";
211
+ const message = String(error?.message ?? error);
212
+ const stack = String(error?.stack ?? "");
213
+ return (name.startsWith("QuickJS") ||
214
+ message.includes("Assertion failed") ||
215
+ message.includes("gc_obj_list") ||
216
+ /\bAborted\(/.test(message) ||
217
+ stack.includes("quickjs"));
218
+ }
219
+ /** The agent-facing translation of an engine failure. */
220
+ export function describeEngineFailure(error) {
221
+ const message = String(error?.message ?? error);
222
+ if (/gc_obj_list|Assertion failed|\bAborted\(/.test(message)) {
223
+ return ("The JavaScript sandbox runtime aborted while cleaning up, so this " +
224
+ "action produced no result. It is usually triggered by moving a large " +
225
+ "amount of binary data across the sandbox boundary in one run. Retry " +
226
+ "with smaller pieces — process one image at a time, or hand large " +
227
+ "payloads between steps as assets instead of as bytes.");
228
+ }
229
+ if (/out of memory/i.test(message)) {
230
+ return ("The JavaScript sandbox ran out of guest memory, so this action " +
231
+ "produced no result. Retry with less data held live at once.");
232
+ }
233
+ return message;
234
+ }
235
+ async function guardHostProcess(run) {
236
+ // `process` is a Node global; the browser bundle (the in-process fallback
237
+ // path there) has none, and there is no host process to guard against an
238
+ // engine abort escaping as an unhandled rejection anyway.
239
+ const nodeProcess = globalThis.process;
240
+ if (!nodeProcess?.on || !nodeProcess?.off) {
241
+ return run;
242
+ }
243
+ let onRejection;
244
+ const escaped = new Promise((_resolve, reject) => {
245
+ onRejection = (reason) => {
246
+ if (isEngineFailure(reason)) {
247
+ reject(reason instanceof Error ? reason : new Error(String(reason)));
248
+ return;
249
+ }
250
+ // Not ours. Restore the default "unhandled rejection crashes the
251
+ // process" behaviour rather than silently swallowing someone's bug.
252
+ setImmediate(() => {
253
+ throw reason;
254
+ });
255
+ };
256
+ nodeProcess.on("unhandledRejection", onRejection);
257
+ });
258
+ try {
259
+ return await Promise.race([run, escaped]);
260
+ }
261
+ finally {
262
+ if (onRejection)
263
+ nodeProcess.off("unhandledRejection", onRejection);
264
+ // The loser of the race stays pending forever; make sure neither promise
265
+ // can later re-trigger the default handler.
266
+ void escaped.catch(() => { });
267
+ void run.then?.(() => { }, () => { });
268
+ }
108
269
  }
109
270
  // ---------------------------------------------------------------------------
110
271
  // Helpers
@@ -114,12 +275,157 @@ export function truncate(text, max) {
114
275
  return text;
115
276
  return text.slice(0, max) + "\n...[truncated]";
116
277
  }
278
+ /**
279
+ * Load `node:fs/promises` via a bundler-hidden import so a browser/edge bundle
280
+ * never tries to resolve it. The `workspace.*` bridge is wired only when a
281
+ * `ProcessingContext` is present, and these loaders run only when guest code
282
+ * actually calls `workspace.read/write/list` — off-Node that path throws
283
+ * (`importNodeBuiltin` resolves `null`), which `neverReject` surfaces to the
284
+ * guest as a normal error.
285
+ */
286
+ async function loadFsPromises() {
287
+ const fs = await importNodeBuiltin("node:fs/promises");
288
+ if (!fs)
289
+ throw new Error("workspace file access requires a Node.js runtime");
290
+ return fs;
291
+ }
292
+ async function loadNodePath() {
293
+ const nodePath = await importNodeBuiltin("node:path");
294
+ if (!nodePath) {
295
+ throw new Error("workspace file access requires a Node.js runtime");
296
+ }
297
+ return nodePath;
298
+ }
299
+ /**
300
+ * Verify a workspace path's real (symlink-resolved) location stays within the
301
+ * real workspace root before an fs operation. resolveWorkspacePath only checks
302
+ * containment lexically, so an in-workspace symlink pointing outside the root
303
+ * would otherwise be dereferenced (arbitrary host file read/write). For a write
304
+ * to a not-yet-existing file, the parent directory is checked instead. Throws
305
+ * on an escape.
306
+ *
307
+ * TOCTOU: the realpath check and the fs op that follows it are separate awaits,
308
+ * and guest bridge calls run concurrently (Promise.all), so an in-workspace
309
+ * symlink could be swapped to point outside between this check and the caller's
310
+ * read/write. Keeping this the last step before the op narrows the window but
311
+ * does not close it — a full fix needs fd-based ops (O_NOFOLLOW / openat), which
312
+ * node:fs/promises does not expose. Accepted as low-risk: it needs a local
313
+ * attacker racing a symlink swap inside the workspace, and both surfaces here
314
+ * (Code node, CodeAct actions) run first-party or already-trusted code.
315
+ */
316
+ async function assertWorkspaceContained(context, fs, nodePath, fullPath, isWrite) {
317
+ const within = async (root, candidate) => {
318
+ try {
319
+ const realRoot = await fs.realpath(root);
320
+ const realCandidate = await fs.realpath(candidate);
321
+ if (realRoot === realCandidate)
322
+ return true;
323
+ const rel = nodePath.relative(realRoot, realCandidate);
324
+ return rel !== "" && !rel.startsWith("..") && !nodePath.isAbsolute(rel);
325
+ }
326
+ catch {
327
+ return false;
328
+ }
329
+ };
330
+ const root = context.resolveWorkspacePath(".");
331
+ if (await within(root, fullPath))
332
+ return;
333
+ if (isWrite) {
334
+ // Target may not exist yet — lstat detects a dangling symlink entry, and
335
+ // otherwise the nearest existing ancestor must be inside the workspace.
336
+ // Walking up covers writes and mkdirs that create several levels at once;
337
+ // path segments that don't exist yet cannot be symlinks, so nothing along
338
+ // the way can redirect the write.
339
+ try {
340
+ await fs.lstat(fullPath);
341
+ // Exists (real file or symlink) but failed containment → outside root.
342
+ }
343
+ catch {
344
+ let dir = nodePath.dirname(fullPath);
345
+ for (;;) {
346
+ let exists = true;
347
+ try {
348
+ await fs.lstat(dir);
349
+ }
350
+ catch {
351
+ exists = false;
352
+ }
353
+ if (exists) {
354
+ if (await within(root, dir))
355
+ return;
356
+ break;
357
+ }
358
+ const parent = nodePath.dirname(dir);
359
+ if (parent === dir)
360
+ break;
361
+ dir = parent;
362
+ }
363
+ }
364
+ }
365
+ throw new Error(`workspace path resolves outside the workspace: ${fullPath}`);
366
+ }
367
+ /**
368
+ * The media engine behind the `image` and `canvas` bridges. Loaded on first
369
+ * use like the host modules, and for the same reasons — the canvas backend
370
+ * (Skia on Node) is heavy, and nothing that never draws should pay for it.
371
+ * Unlike those, the import is intra-package, so every bundler resolves it.
372
+ */
373
+ async function loadSandboxMedia() {
374
+ return import("./sandbox-media.js");
375
+ }
376
+ /** Audio/video adapters are loaded only when a run uses those namespaces. */
377
+ async function loadSandboxAvMedia() {
378
+ return import("./sandbox-av-media.js");
379
+ }
380
+ /**
381
+ * Read a fetch Response body into a Uint8Array bounded by `maxBytes`. Aborts the
382
+ * transfer via `controller` once the cap is exceeded so an oversized/fast
383
+ * response cannot buffer unbounded host memory.
384
+ */
385
+ async function readBodyCapped(response, controller, maxBytes) {
386
+ if (!response.body) {
387
+ // No stream (e.g. empty body) — fall back, then clamp.
388
+ const buf = new Uint8Array(await response.arrayBuffer());
389
+ return buf.length > maxBytes ? buf.slice(0, maxBytes) : buf;
390
+ }
391
+ const reader = response.body.getReader();
392
+ const chunks = [];
393
+ let total = 0;
394
+ try {
395
+ for (;;) {
396
+ const { done, value } = await reader.read();
397
+ if (done)
398
+ break;
399
+ if (!value)
400
+ continue;
401
+ chunks.push(value);
402
+ total += value.byteLength;
403
+ if (total >= maxBytes) {
404
+ controller.abort();
405
+ break;
406
+ }
407
+ }
408
+ }
409
+ catch {
410
+ // Aborted or network error mid-read — return what we have.
411
+ }
412
+ const out = new Uint8Array(Math.min(total, maxBytes));
413
+ let offset = 0;
414
+ for (const c of chunks) {
415
+ if (offset >= out.length)
416
+ break;
417
+ const take = Math.min(c.byteLength, out.length - offset);
418
+ out.set(c.subarray(0, take), offset);
419
+ offset += take;
420
+ }
421
+ return out;
422
+ }
117
423
  function formatArg(arg) {
118
424
  if (arg === null)
119
425
  return "null";
120
426
  if (arg === undefined)
121
427
  return "undefined";
122
- if (typeof arg === "string")
428
+ if (isString(arg))
123
429
  return arg;
124
430
  try {
125
431
  return JSON.stringify(arg, null, 2);
@@ -129,15 +435,20 @@ function formatArg(arg) {
129
435
  }
130
436
  }
131
437
  function isTypedArray(value) {
132
- if (!value || typeof value !== "object")
438
+ if (!isObjectLike(value))
133
439
  return false;
134
440
  const name = value.constructor?.name;
135
- return name === "Uint8Array" || name === "Buffer" ||
136
- name === "Int8Array" || name === "Uint8ClampedArray" ||
137
- name === "Int16Array" || name === "Uint16Array" ||
138
- name === "Int32Array" || name === "Uint32Array" ||
139
- name === "Float32Array" || name === "Float64Array" ||
140
- name === "ArrayBuffer";
441
+ return (name === "Uint8Array" ||
442
+ name === "Buffer" ||
443
+ name === "Int8Array" ||
444
+ name === "Uint8ClampedArray" ||
445
+ name === "Int16Array" ||
446
+ name === "Uint16Array" ||
447
+ name === "Int32Array" ||
448
+ name === "Uint32Array" ||
449
+ name === "Float32Array" ||
450
+ name === "Float64Array" ||
451
+ name === "ArrayBuffer");
141
452
  }
142
453
  function toNativeUint8Array(value) {
143
454
  const v = value;
@@ -147,54 +458,128 @@ function toNativeUint8Array(value) {
147
458
  arr[i] = v[i] ?? 0;
148
459
  return arr;
149
460
  }
461
+ const DIGEST_ALGORITHMS = {
462
+ "SHA-1": "SHA-1",
463
+ SHA1: "SHA-1",
464
+ "SHA-256": "SHA-256",
465
+ SHA256: "SHA-256",
466
+ "SHA-384": "SHA-384",
467
+ SHA384: "SHA-384",
468
+ "SHA-512": "SHA-512",
469
+ SHA512: "SHA-512"
470
+ };
471
+ function normalizeDigestAlgorithm(algorithm) {
472
+ const key = String(algorithm ?? "")
473
+ .trim()
474
+ .toUpperCase();
475
+ const resolved = DIGEST_ALGORITHMS[key];
476
+ if (!resolved) {
477
+ throw new Error(`crypto: unsupported algorithm "${String(algorithm)}" (use SHA-1, SHA-256, SHA-384 or SHA-512)`);
478
+ }
479
+ return resolved;
480
+ }
481
+ /** Accept a guest string or byte-like value as host bytes. */
482
+ function coerceBytesInput(value, label) {
483
+ if (isString(value))
484
+ return new TextEncoder().encode(value);
485
+ if (value instanceof Uint8Array)
486
+ return Uint8Array.from(value);
487
+ if (isTypedArray(value))
488
+ return toNativeUint8Array(value);
489
+ if (Array.isArray(value))
490
+ return Uint8Array.from(value.map(Number));
491
+ if (isObjectLike(value) && isNumber(value.length)) {
492
+ return toNativeUint8Array(value);
493
+ }
494
+ throw new Error(`crypto: ${label} must be a string or Uint8Array`);
495
+ }
496
+ function webCryptoSubtle() {
497
+ const subtle = globalThis.crypto?.subtle;
498
+ if (!subtle) {
499
+ throw new Error("crypto: WebCrypto (crypto.subtle) is not available");
500
+ }
501
+ return subtle;
502
+ }
503
+ /** Depth ceiling for the binary-preserving walk — guards pathological nesting. */
504
+ const SERIALIZE_MAX_DEPTH = 32;
505
+ /**
506
+ * True if a typed array sits anywhere inside `value`. Cycle-safe: a revisited
507
+ * object reports false, which drops the value onto the JSON path, where
508
+ * `JSON.stringify` throws on the cycle and the caller falls back to `String` —
509
+ * the behavior cyclic values already had.
510
+ */
511
+ function containsTypedArray(value, depth = 0, seen = new WeakSet()) {
512
+ if (isTypedArray(value))
513
+ return true;
514
+ if (!isObjectLike(value))
515
+ return false;
516
+ if (depth >= SERIALIZE_MAX_DEPTH)
517
+ return false;
518
+ const obj = value;
519
+ if (seen.has(obj))
520
+ return false;
521
+ seen.add(obj);
522
+ const values = Array.isArray(value)
523
+ ? value
524
+ : Object.values(value);
525
+ return values.some((v) => containsTypedArray(v, depth + 1, seen));
526
+ }
527
+ /**
528
+ * Rebuild `value`, converting every typed array at any depth to a native
529
+ * Uint8Array and leaving everything else structurally intact.
530
+ */
531
+ function convertTypedArraysDeep(value, depth = 0, seen = new WeakSet()) {
532
+ if (isTypedArray(value))
533
+ return toNativeUint8Array(value);
534
+ if (!isObjectLike(value))
535
+ return value;
536
+ if (depth >= SERIALIZE_MAX_DEPTH)
537
+ return value;
538
+ const obj = value;
539
+ if (seen.has(obj))
540
+ return null;
541
+ seen.add(obj);
542
+ if (Array.isArray(value)) {
543
+ return value.map((v) => convertTypedArraysDeep(v, depth + 1, seen));
544
+ }
545
+ const out = {};
546
+ for (const [k, v] of Object.entries(value)) {
547
+ out[k] = convertTypedArraysDeep(v, depth + 1, seen);
548
+ }
549
+ return out;
550
+ }
150
551
  /**
151
552
  * Recursively serialize a value returned from the sandbox, converting typed
152
553
  * arrays to native Uint8Array and enforcing output size limits.
153
554
  */
154
- export function serializeResult(result) {
555
+ export function serializeResult(result, maxOutputSize = MAX_OUTPUT_SIZE) {
155
556
  if (result === undefined)
156
557
  return null;
157
558
  if (result === null)
158
559
  return null;
159
- if (typeof result === "string" ||
160
- typeof result === "number" ||
161
- typeof result === "boolean") {
162
- if (typeof result === "string" && result.length > MAX_OUTPUT_SIZE) {
163
- return truncate(result, MAX_OUTPUT_SIZE);
560
+ if (isString(result) || isNumber(result) || isBoolean(result)) {
561
+ if (isString(result) && result.length > maxOutputSize) {
562
+ return truncate(result, maxOutputSize);
164
563
  }
165
564
  return result;
166
565
  }
167
566
  if (isTypedArray(result)) {
168
567
  return toNativeUint8Array(result);
169
568
  }
170
- if (typeof result === "object") {
171
- let hasBinary = false;
172
- if (Array.isArray(result)) {
173
- hasBinary = result.some(isTypedArray);
174
- }
175
- else {
176
- for (const v of Object.values(result)) {
177
- if (isTypedArray(v)) {
178
- hasBinary = true;
179
- break;
180
- }
181
- }
182
- }
183
- if (hasBinary) {
184
- if (Array.isArray(result)) {
185
- return result.map(v => isTypedArray(v) ? toNativeUint8Array(v) : v);
186
- }
187
- const obj = result;
188
- const out = {};
189
- for (const [k, v] of Object.entries(obj)) {
190
- out[k] = isTypedArray(v) ? toNativeUint8Array(v) : v;
191
- }
192
- return out;
569
+ if (isObjectLike(result)) {
570
+ // The scan and the rebuild are both deep. They used to look one level in,
571
+ // so a typed array nested any deeper fell through to the JSON path below —
572
+ // and `JSON.stringify(new Uint8Array([137, 80]))` is `{"0":137,"1":80}`,
573
+ // which is lossy and indistinguishable from a user's own integer map. The
574
+ // streaming path hit this every time: `genProcess` returns an array of
575
+ // yielded objects, so the bytes are always at depth 2.
576
+ if (containsTypedArray(result)) {
577
+ return convertTypedArraysDeep(result);
193
578
  }
194
579
  try {
195
580
  const json = JSON.stringify(result);
196
- if (json.length > MAX_OUTPUT_SIZE) {
197
- return truncate(json, MAX_OUTPUT_SIZE);
581
+ if (json.length > maxOutputSize) {
582
+ return truncate(json, maxOutputSize);
198
583
  }
199
584
  return JSON.parse(json);
200
585
  }
@@ -233,50 +618,253 @@ export function cleanStack(stack) {
233
618
  *
234
619
  * @param context Optional ProcessingContext — when provided, enables
235
620
  * `workspace.*` and `getSecret()` APIs.
621
+ * @param signal Optional external cancellation. Aborts in-flight host
622
+ * operations and makes `sleep` return immediately.
623
+ * @param limits Optional per-invocation limit overrides, clamped by
624
+ * {@link resolveSandboxLimits}.
625
+ * @param onProgress Optional sink for guest `progress()` calls. Without one the
626
+ * guest function is a no-op.
627
+ * @param onLog Optional sink for guest `console.*` calls. Without one the
628
+ * lines still land in {@link SandboxResult}'s `getLogs`.
629
+ * @param onEmit Optional sink for guest `emit()` calls. Without one the values
630
+ * are collected and handed back through `getEmitted`.
631
+ * @param streams Optional input bridges behind the guest `stream` global.
632
+ * Without an `onTakeInput` every `stream` call throws
633
+ * {@link NO_INPUT_STREAM_MESSAGE}.
634
+ * @param resolveMediaRef Optional host loader for media refs when this run
635
+ * has no ProcessingContext (chat). `image.*` uses it so a
636
+ * generation result can go straight into the next op.
236
637
  */
237
- export function buildSandbox(context) {
638
+ export function buildSandbox(context, signal, limits, onProgress, onLog, onEmit, streams, resolveMediaRef, promoteMedia, resolveHost) {
238
639
  const logs = [];
640
+ const resolvedLimits = resolveSandboxLimits(limits);
239
641
  let fetchCount = 0;
642
+ let forwardedLogs = 0;
643
+ let collectedChars = 0;
644
+ let collectionCut = false;
645
+ // Bounded by count and by bytes; the cut is noted once, then nothing more
646
+ // is kept. A line that does not fit whole keeps the head that does.
647
+ const collectLog = (entry) => {
648
+ if (collectionCut)
649
+ return;
650
+ const remaining = MAX_COLLECTED_CONSOLE_CHARS - collectedChars;
651
+ if (logs.length < MAX_COLLECTED_CONSOLE_LOGS && entry.length <= remaining) {
652
+ logs.push(entry);
653
+ collectedChars += entry.length;
654
+ return;
655
+ }
656
+ if (logs.length < MAX_COLLECTED_CONSOLE_LOGS && remaining > 0) {
657
+ logs.push(entry.slice(0, remaining));
658
+ }
659
+ collectionCut = true;
660
+ logs.push(CONSOLE_LOGS_CUT_NOTICE);
661
+ };
662
+ const pushConsole = (level, prefix, args) => {
663
+ const line = args.map(formatArg).join(" ");
664
+ collectLog(prefix + line);
665
+ if (!onLog || signal?.aborted)
666
+ return;
667
+ if (forwardedLogs >= MAX_CONSOLE_LOGS)
668
+ return;
669
+ forwardedLogs++;
670
+ const message = line.length > MAX_CONSOLE_LOG_CHARS
671
+ ? line.slice(0, MAX_CONSOLE_LOG_CHARS)
672
+ : line;
673
+ try {
674
+ onLog(level, message);
675
+ }
676
+ catch {
677
+ // A failing host sink must not take the guest run down with it.
678
+ }
679
+ };
240
680
  const console = {
241
681
  log: (...args) => {
242
- logs.push(args.map(formatArg).join(" "));
682
+ pushConsole("log", "", args);
243
683
  },
244
684
  warn: (...args) => {
245
- logs.push("[warn] " + args.map(formatArg).join(" "));
685
+ pushConsole("warn", "[warn] ", args);
246
686
  },
247
687
  error: (...args) => {
248
- logs.push("[error] " + args.map(formatArg).join(" "));
688
+ pushConsole("error", "[error] ", args);
249
689
  },
250
690
  info: (...args) => {
251
- logs.push("[info] " + args.map(formatArg).join(" "));
691
+ pushConsole("info", "[info] ", args);
252
692
  }
253
693
  };
694
+ // The literal check above answers a hostname with "not an IP"; this one
695
+ // resolves it, so `metadata.example.com` → 169.254.169.254 is refused
696
+ // before a socket opens, on the first request and on every redirect hop.
697
+ // Node only: off Node the default resolver has no `dns` and answers
698
+ // nothing, and the browser's own network layer is the boundary there. One
699
+ // lookup per hostname per run — the guard is a layer, not the boundary (the
700
+ // socket resolves again), so re-resolving every call buys no rebinding
701
+ // protection and would cost a round trip per parallel fetch.
702
+ const onNodeHost = isString(globalThis.process?.versions?.node);
703
+ const resolvedHosts = new Map();
704
+ const assertHostResolvesAllowed = async (target) => {
705
+ if (!onNodeHost || resolvedLimits.allowPrivateNetwork)
706
+ return;
707
+ const host = new URL(target).hostname;
708
+ let pending = resolvedHosts.get(host);
709
+ if (pending === undefined) {
710
+ pending =
711
+ resolveHost === undefined
712
+ ? assertResolvedHostAllowed(target, "fetch")
713
+ : assertResolvedHostAllowed(target, "fetch", resolveHost);
714
+ resolvedHosts.set(host, pending);
715
+ }
716
+ await pending;
717
+ };
254
718
  const sandboxedFetch = async (url, options) => {
255
719
  fetchCount++;
256
- if (fetchCount > MAX_FETCH_CALLS) {
257
- throw new Error(`Fetch limit exceeded (max ${MAX_FETCH_CALLS} requests per execution)`);
720
+ if (fetchCount > resolvedLimits.maxFetchCalls) {
721
+ throw new Error(`Fetch limit exceeded (max ${resolvedLimits.maxFetchCalls} requests per execution)`);
258
722
  }
259
- if (typeof url !== "string" || !url) {
723
+ if (!isNonEmptyString(url)) {
260
724
  throw new Error("fetch: url must be a non-empty string");
261
725
  }
726
+ // SSRF guard: untrusted guest code must not reach loopback, link-local
727
+ // (incl. cloud metadata 169.254.169.254), or private ranges, nor non-http
728
+ // schemes. This is the literal check; the resolved-address check follows.
729
+ // DNS rebinding between the check and the socket is out of scope.
730
+ // The host can waive the address check for a node that replaces a trusted
731
+ // `lib.http` node; the scheme check is never waived.
732
+ assertFetchUrlAllowed(url, resolvedLimits.allowPrivateNetwork);
733
+ await assertHostResolvesAllowed(url);
262
734
  const controller = new AbortController();
263
- const timer = setTimeout(() => controller.abort(), 15_000);
735
+ const timer = setTimeout(() => controller.abort(), resolvedLimits.fetchTimeoutMs);
736
+ // Cancelling the run kills an in-flight request rather than waiting out
737
+ // the per-request timeout.
738
+ const onExternalAbort = () => controller.abort();
739
+ if (signal?.aborted)
740
+ controller.abort();
741
+ else
742
+ signal?.addEventListener("abort", onExternalAbort, { once: true });
264
743
  try {
265
744
  const fetchOptions = {
266
745
  method: options?.method ?? "GET",
267
746
  signal: controller.signal
268
747
  };
269
- if (options?.headers && typeof options.headers === "object") {
270
- fetchOptions.headers = options.headers;
748
+ const requestHeaders = {};
749
+ // Host default first so a guest-set User-Agent still wins.
750
+ if (resolvedLimits.userAgent) {
751
+ requestHeaders["User-Agent"] = resolvedLimits.userAgent;
752
+ }
753
+ if (isObjectLike(options?.headers)) {
754
+ Object.assign(requestHeaders, options.headers);
755
+ }
756
+ if (Object.keys(requestHeaders).length > 0) {
757
+ fetchOptions.headers = requestHeaders;
271
758
  }
272
759
  if (options?.body !== undefined) {
273
- fetchOptions.body =
274
- typeof options.body === "string"
275
- ? options.body
276
- : JSON.stringify(options.body);
760
+ const body = options.body;
761
+ if (isString(body)) {
762
+ fetchOptions.body = body;
763
+ }
764
+ else if (isTypedArray(body)) {
765
+ // Binary request body. A guest Uint8Array reaches the host as a
766
+ // native one via the typed-array serializers, but normalize anyway
767
+ // so a numeric-keyed object is sent as raw bytes, not as JSON.
768
+ // SAFETY: `BodyInit`'s view member is pinned to a plain
769
+ // ArrayBuffer; these bytes are copied out of the guest heap by
770
+ // `toNativeUint8Array`, never off a SharedArrayBuffer.
771
+ fetchOptions.body = toNativeUint8Array(body);
772
+ }
773
+ else {
774
+ fetchOptions.body = JSON.stringify(body);
775
+ }
776
+ }
777
+ // Follow redirects manually on Node so the SSRF guard runs on every hop's
778
+ // resolved Location, not just the initial URL — otherwise an allowed
779
+ // public URL that 302s to http://169.254.169.254/ or an internal host
780
+ // bypasses the guard entirely. In a browser redirect:"manual" yields an
781
+ // opaque response whose Location is unreadable, and cross-origin bodies
782
+ // are CORS-blocked anyway, so the browser keeps the single redirect:
783
+ // "follow" call with only the already-run initial-URL check.
784
+ const onNode = isString(globalThis.process?.versions?.node);
785
+ let response;
786
+ if (!onNode) {
787
+ response = await fetch(url, { ...fetchOptions, redirect: "follow" });
277
788
  }
278
- const response = await fetch(url, fetchOptions);
279
- const rawBytes = new Uint8Array(await response.arrayBuffer());
789
+ else {
790
+ const dropContentHeaders = (h) => {
791
+ const out = {};
792
+ for (const [k, v] of Object.entries(h)) {
793
+ const lk = k.toLowerCase();
794
+ if (lk === "content-length" || lk === "content-type")
795
+ continue;
796
+ out[k] = v;
797
+ }
798
+ return out;
799
+ };
800
+ // Credential headers must not cross to a different origin — this
801
+ // mirrors Node's native redirect:"follow", which strips them per the
802
+ // fetch spec. Guest code sets headers from getSecret(...), so a
803
+ // redirect to an attacker origin would otherwise exfiltrate them.
804
+ const dropSensitiveHeaders = (h) => {
805
+ const out = {};
806
+ for (const [k, v] of Object.entries(h)) {
807
+ const lk = k.toLowerCase();
808
+ if (lk === "authorization" ||
809
+ lk === "cookie" ||
810
+ lk === "proxy-authorization") {
811
+ continue;
812
+ }
813
+ out[k] = v;
814
+ }
815
+ return out;
816
+ };
817
+ let currentUrl = url;
818
+ let method = fetchOptions.method ?? "GET";
819
+ let body = fetchOptions.body;
820
+ let headers = { ...requestHeaders };
821
+ let hops = 0;
822
+ for (;;) {
823
+ response = await fetch(currentUrl, {
824
+ ...fetchOptions,
825
+ method,
826
+ body,
827
+ headers: Object.keys(headers).length ? headers : undefined,
828
+ redirect: "manual"
829
+ });
830
+ const status = response.status;
831
+ if (status < 300 || status >= 400)
832
+ break;
833
+ const location = response.headers.get("location");
834
+ if (!location)
835
+ break; // 3xx without Location — treat as final.
836
+ if (hops++ >= MAX_FETCH_REDIRECTS) {
837
+ throw new Error("fetch: too many redirects");
838
+ }
839
+ const nextUrl = new URL(location, currentUrl).toString();
840
+ // Re-run the guard on the resolved target BEFORE the next request.
841
+ assertFetchUrlAllowed(nextUrl, resolvedLimits.allowPrivateNetwork);
842
+ await assertHostResolvesAllowed(nextUrl);
843
+ // Strip credential headers on a cross-origin hop (origin includes
844
+ // scheme, host and port); keep them on same-origin redirects.
845
+ if (new URL(nextUrl).origin !== new URL(currentUrl).origin) {
846
+ headers = dropSensitiveHeaders(headers);
847
+ }
848
+ // Method/body rewrite per the HTTP spec + browser behavior:
849
+ // 303 always → GET; 301/302 on a non-GET/HEAD → GET (what browsers
850
+ // do); 307/308 preserve method and body.
851
+ if (status === 303 ||
852
+ ((status === 301 || status === 302) &&
853
+ method !== "GET" &&
854
+ method !== "HEAD")) {
855
+ method = "GET";
856
+ body = undefined;
857
+ headers = dropContentHeaders(headers);
858
+ }
859
+ // Free the redirect response's socket before the next hop.
860
+ await response.body?.cancel().catch(() => { });
861
+ currentUrl = nextUrl;
862
+ }
863
+ }
864
+ // Read the body under a hard byte cap so a large/fast response can't OOM
865
+ // the shared host heap (the guest's 64MB WASM limit does not apply to
866
+ // these host-side bytes). Aborts the transfer once the cap is exceeded.
867
+ const rawBytes = await readBodyCapped(response, controller, resolvedLimits.maxResponseBodyBytes);
280
868
  const ok = response.ok;
281
869
  const status = response.status;
282
870
  const statusText = response.statusText;
@@ -286,8 +874,9 @@ export function buildSandbox(context) {
286
874
  if (cachedText === null) {
287
875
  const decoded = new TextDecoder().decode(rawBytes);
288
876
  cachedText =
289
- decoded.length > MAX_RESPONSE_BODY_SIZE
290
- ? decoded.slice(0, MAX_RESPONSE_BODY_SIZE) + "...[truncated]"
877
+ decoded.length > resolvedLimits.maxResponseBodyBytes
878
+ ? decoded.slice(0, resolvedLimits.maxResponseBodyBytes) +
879
+ "...[truncated]"
291
880
  : decoded;
292
881
  }
293
882
  return cachedText;
@@ -299,6 +888,11 @@ export function buildSandbox(context) {
299
888
  catch {
300
889
  parsedJson = undefined;
301
890
  }
891
+ // Plain data only — no methods. A function in a bridge result cannot
892
+ // cross the worker boundary (`postMessage` refuses it), so the guest
893
+ // prelude's fetch wrapper builds `text()`/`bytes()`/`arrayBuffer()` over
894
+ // these fields instead. The body is already fully buffered and capped
895
+ // here, so shipping it eagerly costs no extra read.
302
896
  return {
303
897
  ok,
304
898
  status,
@@ -306,57 +900,342 @@ export function buildSandbox(context) {
306
900
  headers,
307
901
  body: getText(),
308
902
  json: parsedJson,
309
- text: async () => getText(),
310
- arrayBuffer: async () => rawBytes.buffer.slice(rawBytes.byteOffset, rawBytes.byteOffset + rawBytes.byteLength),
311
- bytes: async () => rawBytes
903
+ bodyBytes: toGuestBytes(rawBytes)
312
904
  };
313
905
  }
314
906
  finally {
315
907
  clearTimeout(timer);
908
+ signal?.removeEventListener("abort", onExternalAbort);
909
+ }
910
+ };
911
+ // WebCrypto exists in both Node >= 20 and browsers, so no node:crypto import
912
+ // is needed and the sandbox stays browser-safe. `getRandomValues` is the one
913
+ // synchronous member: it clamps instead of throwing, since a host throw does
914
+ // not go through the never-reject convention.
915
+ const sandboxCrypto = {
916
+ randomUUID: () => globalThis.crypto.randomUUID(),
917
+ getRandomValues: (length) => {
918
+ const requested = Number(length);
919
+ const size = Number.isFinite(requested)
920
+ ? Math.min(Math.max(Math.floor(requested), 0), MAX_RANDOM_BYTES)
921
+ : 0;
922
+ const bytes = new Uint8Array(size);
923
+ if (size > 0)
924
+ globalThis.crypto.getRandomValues(bytes);
925
+ return toGuestBytes(bytes);
926
+ },
927
+ digest: async (algorithm, data) => {
928
+ const algo = normalizeDigestAlgorithm(algorithm);
929
+ const bytes = coerceBytesInput(data, "data");
930
+ const digest = await webCryptoSubtle().digest(algo, bytes);
931
+ return toGuestBytes(new Uint8Array(digest));
932
+ },
933
+ hmac: async (algorithm, key, data) => {
934
+ const algo = normalizeDigestAlgorithm(algorithm);
935
+ const keyBytes = coerceBytesInput(key, "key");
936
+ const dataBytes = coerceBytesInput(data, "data");
937
+ const subtle = webCryptoSubtle();
938
+ const cryptoKey = await subtle.importKey("raw", keyBytes, { name: "HMAC", hash: algo }, false, ["sign"]);
939
+ const signature = await subtle.sign("HMAC", cryptoKey, dataBytes);
940
+ return toGuestBytes(new Uint8Array(signature));
316
941
  }
317
942
  };
318
- const uuid = () => crypto.randomUUID();
943
+ /**
944
+ * The one place a secret leaves the host.
945
+ *
946
+ * The scope check sits here rather than in the guest prelude because a
947
+ * prelude is guest code: it can be shadowed, and a check the guest could
948
+ * remove is documentation, not a boundary. `nodetool.secrets.get` and the
949
+ * bare `getSecret` global both land here, so there is no second route.
950
+ */
951
+ const secretScope = resolvedLimits.secretScope;
952
+ const assertSecretInScope = (name) => {
953
+ if (secretScope === null)
954
+ return;
955
+ if (secretScope.includes(name))
956
+ return;
957
+ throw new Error(secretScope.length === 0
958
+ ? `getSecret("${name}"): this node declares no secrets, so it can read none`
959
+ : `getSecret("${name}"): this node may read only ${secretScope
960
+ .map((allowed) => `"${allowed}"`)
961
+ .join(", ")}`);
962
+ };
319
963
  const getSecret = context
320
964
  ? async (name) => {
965
+ assertSecretInScope(name);
321
966
  return (await context.getSecret(name)) ?? undefined;
322
967
  }
323
- : async (_name) => {
968
+ : async (name) => {
969
+ assertSecretInScope(name);
324
970
  return undefined;
325
971
  };
326
- const workspace = context
327
- ? {
328
- read: async (path) => {
329
- const fullPath = context.resolveWorkspacePath(path);
330
- const { readFile } = await import("node:fs/promises");
331
- return readFile(fullPath, "utf-8");
332
- },
333
- write: async (path, content) => {
334
- const fullPath = context.resolveWorkspacePath(path);
335
- const { writeFile, mkdir } = await import("node:fs/promises");
336
- const { dirname } = await import("node:path");
337
- await mkdir(dirname(fullPath), { recursive: true });
338
- await writeFile(fullPath, content, "utf-8");
339
- },
340
- list: async (path) => {
341
- const fullPath = context.resolveWorkspacePath(path);
342
- const { readdir } = await import("node:fs/promises");
343
- return readdir(fullPath);
344
- }
345
- }
346
- : {
347
- read: async (_path) => {
348
- throw new Error("workspace.read is not available without a context");
349
- },
350
- write: async (_path, _content) => {
351
- throw new Error("workspace.write is not available without a context");
352
- },
353
- list: async (_path) => {
354
- throw new Error("workspace.list is not available without a context");
972
+ /** What `workspace.stat` answers for a path that is not there. */
973
+ const MISSING_STAT = {
974
+ exists: false,
975
+ size: 0,
976
+ isDirectory: false,
977
+ isFile: false,
978
+ isSymlink: false,
979
+ modifiedMs: 0,
980
+ createdMs: 0,
981
+ accessedMs: 0
982
+ };
983
+ /**
984
+ * Resolve a guest path under the configured filesystem scope.
985
+ *
986
+ * `"workspace"` (the default) is the pre-existing behavior: resolve against
987
+ * the workspace root, then verify the symlink-resolved location is still
988
+ * inside it. `"host"` skips containment and expands `~`, matching what the
989
+ * `lib.os` nodes have always done. Host mode is reachable only when the host
990
+ * passes `filesystemAccess: "host"` — guest code cannot ask for it.
991
+ */
992
+ const resolveGuestPath = async (ctx, path, isWrite) => {
993
+ const nodePath = await loadNodePath();
994
+ if (resolvedLimits.filesystemAccess === "host") {
995
+ const os = await importNodeBuiltin("node:os");
996
+ if (!os) {
997
+ throw new Error("host filesystem access requires a Node.js runtime");
355
998
  }
356
- };
999
+ const expanded = path === "~"
1000
+ ? os.homedir()
1001
+ : path.startsWith("~/")
1002
+ ? nodePath.join(os.homedir(), path.slice(2))
1003
+ : path;
1004
+ return nodePath.resolve(expanded);
1005
+ }
1006
+ const fullPath = ctx.resolveWorkspacePath(path);
1007
+ const fs = await loadFsPromises();
1008
+ await assertWorkspaceContained(ctx, fs, nodePath, fullPath, isWrite);
1009
+ return fullPath;
1010
+ };
1011
+ /**
1012
+ * The guest's `workspace.*` API.
1013
+ *
1014
+ * Three shapes, picked once: no context at all (every call explains itself),
1015
+ * `filesystemAccess: "host"` (the `lib.os` escape hatch — real paths, no
1016
+ * containment, host opt-in only), and the normal case, which goes through
1017
+ * `context.workspace` and therefore works the same whether the run's
1018
+ * workspace is a folder or a prefix in object storage.
1019
+ */
1020
+ const hostFsWorkspace = (ctx) => ({
1021
+ read: async (path) => {
1022
+ const fs = await loadFsPromises();
1023
+ return fs.readFile(await resolveGuestPath(ctx, path, false), "utf-8");
1024
+ },
1025
+ write: async (path, content) => {
1026
+ const fs = await loadFsPromises();
1027
+ const nodePath = await loadNodePath();
1028
+ const fullPath = await resolveGuestPath(ctx, path, true);
1029
+ await fs.mkdir(nodePath.dirname(fullPath), { recursive: true });
1030
+ await fs.writeFile(fullPath, content, "utf-8");
1031
+ },
1032
+ list: async (path) => {
1033
+ const fs = await loadFsPromises();
1034
+ return fs.readdir(await resolveGuestPath(ctx, path, false));
1035
+ },
1036
+ readBytes: async (path) => {
1037
+ const fs = await loadFsPromises();
1038
+ const fullPath = await resolveGuestPath(ctx, path, false);
1039
+ return toGuestBytes(new Uint8Array(await fs.readFile(fullPath)));
1040
+ },
1041
+ writeBytes: async (path, data) => {
1042
+ const bytes = data instanceof Uint8Array ? data : toNativeUint8Array(data);
1043
+ const fs = await loadFsPromises();
1044
+ const nodePath = await loadNodePath();
1045
+ const fullPath = await resolveGuestPath(ctx, path, true);
1046
+ await fs.mkdir(nodePath.dirname(fullPath), { recursive: true });
1047
+ await fs.writeFile(fullPath, bytes);
1048
+ },
1049
+ stat: async (path) => {
1050
+ const fs = await loadFsPromises();
1051
+ const fullPath = await resolveGuestPath(ctx, path, true);
1052
+ let info;
1053
+ try {
1054
+ info = await fs.lstat(fullPath);
1055
+ }
1056
+ catch {
1057
+ return MISSING_STAT;
1058
+ }
1059
+ return {
1060
+ exists: true,
1061
+ size: info.size,
1062
+ isDirectory: info.isDirectory(),
1063
+ isFile: info.isFile(),
1064
+ isSymlink: info.isSymbolicLink(),
1065
+ modifiedMs: info.mtimeMs,
1066
+ createdMs: info.birthtimeMs,
1067
+ accessedMs: info.atimeMs
1068
+ };
1069
+ },
1070
+ root: async () => ctx.resolveWorkspacePath("."),
1071
+ copy: async (src, dest) => {
1072
+ const fs = await loadFsPromises();
1073
+ const nodePath = await loadNodePath();
1074
+ const fullSrc = await resolveGuestPath(ctx, src, false);
1075
+ const fullDest = await resolveGuestPath(ctx, dest, true);
1076
+ await fs.mkdir(nodePath.dirname(fullDest), { recursive: true });
1077
+ await fs.copyFile(fullSrc, fullDest);
1078
+ },
1079
+ move: async (src, dest) => {
1080
+ const fs = await loadFsPromises();
1081
+ const nodePath = await loadNodePath();
1082
+ const fullSrc = await resolveGuestPath(ctx, src, true);
1083
+ const fullDest = await resolveGuestPath(ctx, dest, true);
1084
+ await fs.mkdir(nodePath.dirname(fullDest), { recursive: true });
1085
+ await fs.rename(fullSrc, fullDest);
1086
+ },
1087
+ mkdir: async (path) => {
1088
+ const fs = await loadFsPromises();
1089
+ await fs.mkdir(await resolveGuestPath(ctx, path, true), {
1090
+ recursive: true
1091
+ });
1092
+ },
1093
+ remove: async (path) => {
1094
+ const fs = await loadFsPromises();
1095
+ const fullPath = await resolveGuestPath(ctx, path, true);
1096
+ const info = await fs.lstat(fullPath);
1097
+ if (info.isDirectory()) {
1098
+ // rmdir refuses a non-empty directory, which is the point.
1099
+ await fs.rmdir(fullPath);
1100
+ }
1101
+ else {
1102
+ await fs.rm(fullPath, { recursive: false });
1103
+ }
1104
+ }
1105
+ });
1106
+ const backedWorkspace = (ws) => ({
1107
+ read: async (path) => {
1108
+ const text = await ws.readText(path);
1109
+ if (text === null)
1110
+ throw new Error(`ENOENT: no such file: ${path}`);
1111
+ return text;
1112
+ },
1113
+ write: async (path, content) => {
1114
+ await ws.write(path, content);
1115
+ },
1116
+ // Names only, like readdir — the guest joins them onto the path it asked
1117
+ // about, which is how the pre-existing scripts use this.
1118
+ list: async (path) => (await ws.list(path)).map((entry) => entry.name),
1119
+ readBytes: async (path) => {
1120
+ const bytes = await ws.read(path);
1121
+ if (bytes === null)
1122
+ throw new Error(`ENOENT: no such file: ${path}`);
1123
+ return toGuestBytes(bytes);
1124
+ },
1125
+ writeBytes: async (path, data) => {
1126
+ const bytes = data instanceof Uint8Array ? data : toNativeUint8Array(data);
1127
+ await ws.write(path, bytes);
1128
+ },
1129
+ // A missing path is an answer, not a failure: guest code asking
1130
+ // "does this exist?" should not have to wrap the call in try/catch.
1131
+ stat: async (path) => {
1132
+ let info;
1133
+ try {
1134
+ info = await ws.stat(path);
1135
+ }
1136
+ catch {
1137
+ return MISSING_STAT;
1138
+ }
1139
+ if (!info)
1140
+ return MISSING_STAT;
1141
+ return {
1142
+ exists: true,
1143
+ size: info.size,
1144
+ isDirectory: info.isDirectory,
1145
+ isFile: !info.isDirectory,
1146
+ // Nothing reachable through a workspace is a symlink: an object store
1147
+ // cannot hold one, and the local backend refuses to follow one out of
1148
+ // the root.
1149
+ isSymlink: false,
1150
+ modifiedMs: info.modifiedAt,
1151
+ createdMs: info.modifiedAt,
1152
+ accessedMs: info.modifiedAt
1153
+ };
1154
+ },
1155
+ /**
1156
+ * The base for relative paths. A real directory when the workspace has
1157
+ * one; otherwise `/workspace`, which every workspace path accepts as its
1158
+ * own root, so a script that joins onto it keeps working.
1159
+ */
1160
+ root: async () => ws.localDir ?? "/workspace",
1161
+ copy: async (src, dest) => {
1162
+ await ws.copy(src, dest);
1163
+ },
1164
+ move: async (src, dest) => {
1165
+ await ws.move(src, dest);
1166
+ },
1167
+ mkdir: async (path) => {
1168
+ await ws.mkdir(path);
1169
+ },
1170
+ remove: async (path) => {
1171
+ // One file or one empty directory — guest code cannot delete a whole
1172
+ // subtree in a single call, in any filesystem mode.
1173
+ const info = await ws.stat(path);
1174
+ if (info?.isDirectory) {
1175
+ const children = await ws.list(path);
1176
+ if (children.length > 0) {
1177
+ throw new Error(`ENOTEMPTY: directory not empty: ${path}`);
1178
+ }
1179
+ await ws.deleteAll(path);
1180
+ return;
1181
+ }
1182
+ if (!(await ws.delete(path))) {
1183
+ throw new Error(`ENOENT: no such file: ${path}`);
1184
+ }
1185
+ }
1186
+ });
1187
+ const unavailable = (api) => async () => {
1188
+ throw new Error(`workspace.${api} is not available without a context`);
1189
+ };
1190
+ const workspace = !context
1191
+ ? {
1192
+ read: unavailable("read"),
1193
+ write: unavailable("write"),
1194
+ list: unavailable("list"),
1195
+ readBytes: unavailable("readBytes"),
1196
+ writeBytes: unavailable("writeBytes"),
1197
+ stat: unavailable("stat"),
1198
+ root: unavailable("root"),
1199
+ copy: unavailable("copy"),
1200
+ move: unavailable("move"),
1201
+ mkdir: unavailable("mkdir"),
1202
+ remove: unavailable("remove")
1203
+ }
1204
+ : resolvedLimits.filesystemAccess === "host"
1205
+ ? hostFsWorkspace(context)
1206
+ : context.workspace
1207
+ ? backedWorkspace(context.workspace)
1208
+ : {
1209
+ read: unavailable("read"),
1210
+ write: unavailable("write"),
1211
+ list: unavailable("list"),
1212
+ readBytes: unavailable("readBytes"),
1213
+ writeBytes: unavailable("writeBytes"),
1214
+ stat: unavailable("stat"),
1215
+ root: unavailable("root"),
1216
+ copy: unavailable("copy"),
1217
+ move: unavailable("move"),
1218
+ mkdir: unavailable("mkdir"),
1219
+ remove: unavailable("remove")
1220
+ };
357
1221
  const sleep = (ms) => {
358
1222
  const capped = Math.min(ms, 5000);
359
- return new Promise((resolve) => setTimeout(resolve, capped));
1223
+ // Resolve immediately on cancellation: a sleeping script is the common
1224
+ // case for "still running after Stop", and waiting out the nap before the
1225
+ // next bridge call can reject it wastes up to 5s per sleep.
1226
+ return new Promise((resolve) => {
1227
+ if (signal?.aborted)
1228
+ return resolve();
1229
+ const timer = setTimeout(() => {
1230
+ signal?.removeEventListener("abort", onAbort);
1231
+ resolve();
1232
+ }, capped);
1233
+ function onAbort() {
1234
+ clearTimeout(timer);
1235
+ resolve();
1236
+ }
1237
+ signal?.addEventListener("abort", onAbort, { once: true });
1238
+ });
360
1239
  };
361
1240
  const assetToSandbox = context
362
1241
  ? async (assetId, path) => {
@@ -372,6 +1251,512 @@ export function buildSandbox(context) {
372
1251
  : async (_path) => {
373
1252
  throw new Error("sandboxToAsset is not available without a context");
374
1253
  };
1254
+ // Fire-and-forget progress reporting. Synchronous like console.log: it never
1255
+ // throws, so it needs no never-reject wrapper. A guest that spams it cannot
1256
+ // flood the host — reports closer together than PROGRESS_MIN_INTERVAL_MS are
1257
+ // dropped, and the run has a lifetime cap.
1258
+ let progressCalls = 0;
1259
+ let lastProgressAt = 0;
1260
+ const progress = (percent, message) => {
1261
+ if (!onProgress || signal?.aborted)
1262
+ return;
1263
+ if (progressCalls >= MAX_PROGRESS_CALLS)
1264
+ return;
1265
+ const now = Date.now();
1266
+ if (progressCalls > 0 && now - lastProgressAt < PROGRESS_MIN_INTERVAL_MS) {
1267
+ return;
1268
+ }
1269
+ const raw = Number(percent);
1270
+ const clamped = Number.isFinite(raw) ? Math.min(Math.max(raw, 0), 100) : 0;
1271
+ const text = message === undefined || message === null
1272
+ ? undefined
1273
+ : String(message).slice(0, MAX_PROGRESS_MESSAGE_CHARS);
1274
+ progressCalls++;
1275
+ lastProgressAt = now;
1276
+ try {
1277
+ onProgress(clamped, text);
1278
+ }
1279
+ catch {
1280
+ // A failing host sink must not take the guest run down with it.
1281
+ }
1282
+ };
1283
+ // Output delivery. The opposite of `progress` in every respect: awaitable, so
1284
+ // the guest gets backpressure from a slow consumer, and never rate-limited or
1285
+ // dropped — an output value the host silently discards is data loss, not a
1286
+ // missed progress tick. Both throw into the guest rather than failing quietly.
1287
+ let emitCalls = 0;
1288
+ const emitted = [];
1289
+ const outputs = new Map();
1290
+ const handleName = (fn, name) => {
1291
+ if (!isString(name)) {
1292
+ throw new TypeError(`${fn}: name must be a string`);
1293
+ }
1294
+ return name;
1295
+ };
1296
+ const emit = async (name, value) => {
1297
+ const handle = handleName("emit", name);
1298
+ if (emitCalls >= MAX_EMIT_CALLS) {
1299
+ throw new Error(`emit: this run may emit at most ${MAX_EMIT_CALLS} values (MAX_EMIT_CALLS)`);
1300
+ }
1301
+ emitCalls++;
1302
+ const marshaled = serializeResult(value, resolvedLimits.maxOutputSize);
1303
+ if (onEmit) {
1304
+ // Awaited, so the guest's promise resolves only once the host has taken
1305
+ // the value — and a sink that throws unwinds the guest's `emit` call.
1306
+ await onEmit(handle, marshaled);
1307
+ return;
1308
+ }
1309
+ emitted.push({ name: handle, value: marshaled });
1310
+ };
1311
+ const output = async (name, value) => {
1312
+ const handle = handleName("output", name);
1313
+ if (outputs.has(handle)) {
1314
+ throw new Error(`output "${handle}" was already set`);
1315
+ }
1316
+ outputs.set(handle, serializeResult(value, resolvedLimits.maxOutputSize));
1317
+ };
1318
+ // Input delivery, the mirror of `emit`: the guest pulls one value at a time
1319
+ // and the host answers from the inbox it owns. Backpressure is free — an item
1320
+ // nobody asked for stays upstream.
1321
+ const takeInput = async (name) => {
1322
+ if (!streams?.onTakeInput) {
1323
+ throw new Error(NO_INPUT_STREAM_MESSAGE);
1324
+ }
1325
+ if (name !== null && !isString(name)) {
1326
+ throw new TypeError("stream: name must be a string");
1327
+ }
1328
+ // Waiting on upstream is not the guest executing, so it must not spend the
1329
+ // guest's timeout budget. The clock stops until the value (or EOS) lands.
1330
+ const resume = streams.clock?.suspend();
1331
+ try {
1332
+ const take = await streams.onTakeInput(name);
1333
+ if (take.done)
1334
+ return { done: true };
1335
+ return {
1336
+ done: false,
1337
+ handle: take.handle,
1338
+ value: toGuestBytesDeep(take.value)
1339
+ };
1340
+ }
1341
+ finally {
1342
+ resume?.();
1343
+ }
1344
+ };
1345
+ // Synchronous and never throwing, which is what lets the guest read it as a
1346
+ // plain boolean: an awaitable answer would make `if (stream.open(h))` true on
1347
+ // a pending promise. `null` is the one non-answer — this run has no input
1348
+ // stream at all — and the prelude turns it into the thrown error.
1349
+ const streamOpen = (name) => {
1350
+ if (!streams?.onTakeInput)
1351
+ return null;
1352
+ if (!isString(name) || !streams.onStreamOpen)
1353
+ return false;
1354
+ try {
1355
+ return streams.onStreamOpen(name) === true;
1356
+ }
1357
+ catch {
1358
+ // A host probe that throws answers "closed" rather than taking the run
1359
+ // down: the take itself is where a broken inbox must surface.
1360
+ return false;
1361
+ }
1362
+ };
1363
+ // QuickJS ships no Intl, so locale-aware formatting has to come from the
1364
+ // host. Async + never-reject like the other bridges: a bad locale or option
1365
+ // surfaces in the guest as a thrown Error with Intl's own message.
1366
+ const format = {
1367
+ number: async (value, options) => {
1368
+ const num = Number(value);
1369
+ if (!Number.isFinite(num)) {
1370
+ throw new Error("format.number: value must be a finite number");
1371
+ }
1372
+ const opts = options ?? {};
1373
+ return new Intl.NumberFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, {
1374
+ style: opts.style,
1375
+ currency: opts.currency,
1376
+ minimumFractionDigits: opts.minimumFractionDigits,
1377
+ maximumFractionDigits: opts.maximumFractionDigits,
1378
+ useGrouping: opts.useGrouping
1379
+ }).format(num);
1380
+ },
1381
+ date: async (epochMs, options) => {
1382
+ const ms = Number(epochMs);
1383
+ if (!Number.isFinite(ms)) {
1384
+ throw new Error("format.date: epochMs must be a finite number of milliseconds");
1385
+ }
1386
+ const opts = options ?? {};
1387
+ const dateStyle = opts.dateStyle;
1388
+ const timeStyle = opts.timeStyle;
1389
+ return new Intl.DateTimeFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, {
1390
+ // Intl falls back to a date-only default when neither style is given.
1391
+ dateStyle: dateStyle ?? (timeStyle ? undefined : "medium"),
1392
+ timeStyle,
1393
+ timeZone: opts.timeZone
1394
+ }).format(new Date(ms));
1395
+ },
1396
+ relativeTime: async (value, unit, options) => {
1397
+ const num = Number(value);
1398
+ if (!Number.isFinite(num)) {
1399
+ throw new Error("format.relativeTime: value must be a finite number");
1400
+ }
1401
+ const opts = options ?? {};
1402
+ return new Intl.RelativeTimeFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE).format(num, unit);
1403
+ },
1404
+ list: async (items, options) => {
1405
+ if (!Array.isArray(items)) {
1406
+ throw new Error("format.list: items must be an array of strings");
1407
+ }
1408
+ const opts = options ?? {};
1409
+ return new Intl.ListFormat(opts.locale ?? DEFAULT_FORMAT_LOCALE, { type: opts.type }).format(items.map((i) => String(i)));
1410
+ }
1411
+ };
1412
+ // Bytes media transforms produced and the guest only carries around. Lives for the
1413
+ // run, then goes; nothing here is durable until something promotes it.
1414
+ const mediaStore = createSandboxMediaStore(resolvedLimits.runMediaBytes);
1415
+ let runAvMediaPromise;
1416
+ const loadRunAvMedia = () => {
1417
+ runAvMediaPromise ??= loadSandboxAvMedia().then((media) => ({
1418
+ audioOps: media.createAudioBridge(signal, resolvedLimits.runMediaBytes),
1419
+ videoOps: media.createVideoBridge(signal, resolvedLimits.runMediaBytes)
1420
+ }));
1421
+ return runAvMediaPromise;
1422
+ };
1423
+ // Media bridges. The engine (`sandbox-media.ts`) is imported on first use
1424
+ // like every other library-backed bridge, and picks its canvas backend from
1425
+ // the runtime — `@napi-rs/canvas` on Node, `OffscreenCanvas` in the browser
1426
+ // runner. Bytes come back tagged for the guest prelude to revive, so the
1427
+ // guest-visible API is `Uint8Array` in and `Uint8Array` out.
1428
+ const withGuestBytes = (fn) => {
1429
+ return async (...args) => toGuestBytesDeep(await fn(...args));
1430
+ };
1431
+ const mediaMember = (pick) => withGuestBytes(async (...args) => pick(await loadSandboxMedia())(...args));
1432
+ // `image.*` trades in handles, not bytes. On the way in, every handle and
1433
+ // every media ref buried anywhere in the arguments is replaced by the bytes
1434
+ // it names — resolved host-side, so an `asset://` a generator produced goes
1435
+ // straight into the next operation without being pulled through the guest.
1436
+ // On the way out, encoded bytes become a handle instead of a base64 payload.
1437
+ // A chain (resize → adjust → composite) therefore moves nothing across the
1438
+ // boundary but small objects.
1439
+ //
1440
+ // `info` and `decode` are the deliberate exceptions: they exist to tell the
1441
+ // guest what is *in* an image, so their results stay plain data. `decode`
1442
+ // still hands over real pixels, which is the one call that has to.
1443
+ const loadMediaRef = async (where, value, maxBytes = resolvedLimits.runMediaBytes) => {
1444
+ const ref = remapMediaRef(value);
1445
+ if (context) {
1446
+ return resolveRefBytes(where, ref, context, (path) => resolveGuestPath(context, path, false), maxBytes);
1447
+ }
1448
+ if (resolveMediaRef) {
1449
+ const bytes = await resolveMediaRef(where, ref);
1450
+ if (bytes.length > maxBytes) {
1451
+ throw new Error(`${where}: media input is ${bytes.length} bytes, over the ` +
1452
+ `${maxBytes} byte remaining run media limit`);
1453
+ }
1454
+ return bytes;
1455
+ }
1456
+ const label = ref.uri || ref.asset_id || "this media ref";
1457
+ throw new Error(`${where}: cannot resolve ${label} in this run. Pass a media ` +
1458
+ `handle or a generation result (its asset_uri).`);
1459
+ };
1460
+ const resolveMediaArgs = async (where, value,
1461
+ // `image.*` wants a ref flattened to bytes it can operate on. `media.*`
1462
+ // takes refs *as* refs — that is its whole job — so it resolves handles
1463
+ // only, or `media.bytes(assetRef)` would be handed bytes and no longer
1464
+ // have a ref to read.
1465
+ resolveRefs, depth = 0, expectedType, budget = { used: 0 }) => {
1466
+ if (depth >= SANDBOX_SERIALIZE_MAX_DEPTH)
1467
+ return value;
1468
+ const accountBytes = (bytes) => {
1469
+ if (bytes.byteLength > resolvedLimits.runMediaBytes - budget.used) {
1470
+ throw new Error(`${where}: aggregate media input exceeds the ` +
1471
+ `${resolvedLimits.runMediaBytes} byte run media limit`);
1472
+ }
1473
+ budget.used += bytes.byteLength;
1474
+ return bytes;
1475
+ };
1476
+ // Matched on the marker, not on store membership: a handle from an
1477
+ // earlier run must report *that*, rather than falling through to the ref
1478
+ // path and blaming the uri it happens to carry.
1479
+ if (isSandboxMediaHandle(value)) {
1480
+ const bytes = mediaStore.resolve(value, expectedType);
1481
+ if (!bytes)
1482
+ throw new Error(`${where}: media handle has no bytes`);
1483
+ return accountBytes(bytes);
1484
+ }
1485
+ if (value instanceof Uint8Array || ArrayBuffer.isView(value)) {
1486
+ return accountBytes(value);
1487
+ }
1488
+ if (Array.isArray(value)) {
1489
+ const resolved = [];
1490
+ for (const item of value) {
1491
+ const result = await resolveMediaArgs(where, item, resolveRefs, depth + 1, expectedType, budget);
1492
+ resolved.push(result);
1493
+ }
1494
+ return resolved;
1495
+ }
1496
+ if (resolveRefs && looksLikeMediaRef(value)) {
1497
+ if (expectedType && isObjectLike(value)) {
1498
+ const declared = value.type;
1499
+ if ((declared === "image" ||
1500
+ declared === "audio" ||
1501
+ declared === "video") &&
1502
+ declared !== expectedType) {
1503
+ throw new Error(`${where}: expected ${expectedType} media, but received ${declared}`);
1504
+ }
1505
+ }
1506
+ const remainingBytes = resolvedLimits.runMediaBytes - budget.used;
1507
+ return accountBytes(await loadMediaRef(where, value, remainingBytes));
1508
+ }
1509
+ if (isObjectLike(value)) {
1510
+ const record = value;
1511
+ const out = {};
1512
+ for (const [k, v] of Object.entries(record)) {
1513
+ out[k] = await resolveMediaArgs(where, v, resolveRefs, depth + 1, expectedType, budget);
1514
+ }
1515
+ return out;
1516
+ }
1517
+ return value;
1518
+ };
1519
+ const defaultMediaMime = (type) => type === "image"
1520
+ ? "image/png"
1521
+ : type === "audio"
1522
+ ? "audio/wav"
1523
+ : "video/mp4";
1524
+ const mediaMimeForValue = (value, expectedType) => {
1525
+ if (isSandboxMediaHandle(value)) {
1526
+ return (mediaStore.entry(value, expectedType)?.mimeType ??
1527
+ defaultMediaMime(expectedType));
1528
+ }
1529
+ const record = isRecord(value) ? value : undefined;
1530
+ const declared = record?.mimeType ?? record?.mime_type;
1531
+ const ref = remapMediaRef(value);
1532
+ if (isString(declared))
1533
+ ref.mimeType = declared;
1534
+ return mimeForRef(ref, defaultMediaMime(expectedType));
1535
+ };
1536
+ const sniffMediaMime = (type, bytes, fallback) => {
1537
+ const ascii = (start, length) => String.fromCharCode(...bytes.subarray(start, start + length));
1538
+ if (type === "image") {
1539
+ if (bytes.length >= 8 && ascii(1, 3) === "PNG")
1540
+ return "image/png";
1541
+ if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8)
1542
+ return "image/jpeg";
1543
+ if (bytes.length >= 6 && ascii(0, 3) === "GIF")
1544
+ return "image/gif";
1545
+ if (bytes.length >= 12 &&
1546
+ ascii(0, 4) === "RIFF" &&
1547
+ ascii(8, 4) === "WEBP")
1548
+ return "image/webp";
1549
+ return fallback;
1550
+ }
1551
+ if (type === "audio") {
1552
+ if (bytes.length >= 12 &&
1553
+ ascii(0, 4) === "RIFF" &&
1554
+ ascii(8, 4) === "WAVE")
1555
+ return "audio/wav";
1556
+ if (bytes.length >= 4 && ascii(0, 4) === "fLaC")
1557
+ return "audio/flac";
1558
+ if (bytes.length >= 4 && ascii(0, 4) === "OggS")
1559
+ return "audio/ogg";
1560
+ if ((bytes.length >= 3 && ascii(0, 3) === "ID3") ||
1561
+ (bytes.length >= 2 && bytes[0] === 0xff && (bytes[1] & 0xe0) === 0xe0))
1562
+ return "audio/mpeg";
1563
+ if (bytes.length >= 12 && ascii(4, 4) === "ftyp")
1564
+ return "audio/mp4";
1565
+ return fallback;
1566
+ }
1567
+ if (bytes.length >= 12 && ascii(0, 4) === "RIFF" && ascii(8, 4) === "AVI ")
1568
+ return "video/x-msvideo";
1569
+ if (bytes.length >= 4 && bytes[0] === 0x1a && bytes[1] === 0x45) {
1570
+ return ascii(0, Math.min(bytes.length, 64)).includes("webm")
1571
+ ? "video/webm"
1572
+ : "video/x-matroska";
1573
+ }
1574
+ if (bytes.length >= 12 && ascii(4, 4) === "ftyp") {
1575
+ return ascii(8, 4) === "qt " ? "video/quicktime" : "video/mp4";
1576
+ }
1577
+ return fallback;
1578
+ };
1579
+ /** An `image.*` op: handles/refs in, a handle out. */
1580
+ const imageMember = (name, pick) => {
1581
+ const where = `image.${name}`;
1582
+ return async (...args) => {
1583
+ const resolved = (await resolveMediaArgs(where, args, true, 0, "image"));
1584
+ const result = await pick(await loadSandboxMedia())(...resolved);
1585
+ if (result instanceof Uint8Array) {
1586
+ const media = await loadSandboxMedia();
1587
+ const info = (await media.imageOps.info(result));
1588
+ const meta = {
1589
+ mimeType: info.format ? `image/${info.format}` : "image/png"
1590
+ };
1591
+ if (info.width !== undefined)
1592
+ meta.width = info.width;
1593
+ if (info.height !== undefined)
1594
+ meta.height = info.height;
1595
+ return mediaStore.put(result, meta);
1596
+ }
1597
+ return toGuestBytesDeep(result);
1598
+ };
1599
+ };
1600
+ const image = {
1601
+ /**
1602
+ * The one door from a handle back to real bytes, and deliberately the only
1603
+ * one. Every other op keeps the payload host-side, so a body that reaches
1604
+ * for this is saying it will read the bytes itself — the cost is explicit
1605
+ * at the call site instead of hidden in every hop. It needs no
1606
+ * ProcessingContext, so a Code node that really does parse an encoded image
1607
+ * works exactly as it did.
1608
+ */
1609
+ bytes: async (value) => {
1610
+ const resolved = await resolveMediaArgs("image.bytes", value, true, 0, "image");
1611
+ const media = await loadSandboxMedia();
1612
+ return toGuestBytes(media.asImageBytes(resolved, "image.bytes"));
1613
+ },
1614
+ /**
1615
+ * Handle → durable asset. Bytes stay on the host; the guest gets a ref.
1616
+ */
1617
+ toAsset: async (value, options) => {
1618
+ const sourceMime = mediaMimeForValue(value, "image");
1619
+ const resolved = await resolveMediaArgs("image.toAsset", value, true, 0, "image");
1620
+ const media = await loadSandboxMedia();
1621
+ const bytes = media.asImageBytes(resolved, "image.toAsset");
1622
+ const mimeType = sniffMediaMime("image", bytes, sourceMime);
1623
+ const assetOptions = { mimeType, ...options };
1624
+ if (promoteMedia) {
1625
+ return promoteMedia("image", bytes, assetOptions);
1626
+ }
1627
+ if (context) {
1628
+ return mediaRefBridge.toImage(bytes, assetOptions);
1629
+ }
1630
+ throw new Error("image.toAsset: cannot save an asset in this run. Use " +
1631
+ "nodetool.media.toImage from a chat action, or media.toImage " +
1632
+ "from a Code node.");
1633
+ },
1634
+ info: imageMember("info", (m) => m.imageOps.info),
1635
+ decode: imageMember("decode", (m) => m.imageOps.decode),
1636
+ stats: imageMember("stats", (m) => m.imageOps.stats),
1637
+ blank: imageMember("blank", (m) => m.imageOps.blank),
1638
+ pad: imageMember("pad", (m) => m.imageOps.pad),
1639
+ grid: imageMember("grid", (m) => m.imageOps.grid),
1640
+ resize: imageMember("resize", (m) => m.imageOps.resize),
1641
+ crop: imageMember("crop", (m) => m.imageOps.crop),
1642
+ rotate: imageMember("rotate", (m) => m.imageOps.rotate),
1643
+ flip: imageMember("flip", (m) => m.imageOps.flip),
1644
+ adjust: imageMember("adjust", (m) => m.imageOps.adjust),
1645
+ composite: imageMember("composite", (m) => m.imageOps.composite),
1646
+ convert: imageMember("convert", (m) => m.imageOps.convert)
1647
+ };
1648
+ const requireMediaBytes = (where, value) => {
1649
+ if (value instanceof Uint8Array)
1650
+ return value;
1651
+ if (ArrayBuffer.isView(value)) {
1652
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1653
+ }
1654
+ throw new Error(`${where}: expected media bytes, a media handle, or a media ref`);
1655
+ };
1656
+ const avMember = (namespace, name, inputTypes, outputType, pick) => {
1657
+ const where = `${namespace}.${name}`;
1658
+ return async (...args) => {
1659
+ const budget = { used: 0 };
1660
+ const resolved = [];
1661
+ for (let index = 0; index < args.length; index += 1) {
1662
+ resolved.push(await resolveMediaArgs(where, args[index], true, 0, inputTypes[index], budget));
1663
+ }
1664
+ const result = await pick(await loadRunAvMedia())(...resolved);
1665
+ if (outputType && result instanceof Uint8Array) {
1666
+ const sourceType = inputTypes[0] ?? outputType;
1667
+ const sourceMime = mediaMimeForValue(args[0], sourceType);
1668
+ return mediaStore.put(result, {
1669
+ type: outputType,
1670
+ mimeType: sniffMediaMime(outputType, result, outputType === sourceType
1671
+ ? sourceMime
1672
+ : defaultMediaMime(outputType))
1673
+ });
1674
+ }
1675
+ return toGuestBytesDeep(result);
1676
+ };
1677
+ };
1678
+ const avBytes = (namespace) => async (value) => {
1679
+ const where = `${namespace}.bytes`;
1680
+ const resolved = await resolveMediaArgs(where, value, true, 0, namespace);
1681
+ return toGuestBytes(requireMediaBytes(where, resolved));
1682
+ };
1683
+ const avToAsset = (type) => async (value, options) => {
1684
+ const where = `${type}.toAsset`;
1685
+ const sourceMime = mediaMimeForValue(value, type);
1686
+ const resolved = await resolveMediaArgs(where, value, true, 0, type);
1687
+ const bytes = requireMediaBytes(where, resolved);
1688
+ const mimeType = sniffMediaMime(type, bytes, sourceMime);
1689
+ const assetOptions = { mimeType, ...options };
1690
+ if (promoteMedia) {
1691
+ return promoteMedia(type, bytes, assetOptions);
1692
+ }
1693
+ if (context) {
1694
+ return type === "audio"
1695
+ ? mediaRefBridge.toAudio(bytes, assetOptions)
1696
+ : mediaRefBridge.toVideo(bytes, assetOptions);
1697
+ }
1698
+ throw new Error(`${where}: cannot save an asset in this run. Use media.to${type === "audio" ? "Audio" : "Video"} from a Code node.`);
1699
+ };
1700
+ const audio = {
1701
+ bytes: avBytes("audio"),
1702
+ toAsset: avToAsset("audio"),
1703
+ info: avMember("audio", "info", ["audio"], undefined, (m) => m.audioOps.info),
1704
+ normalize: avMember("audio", "normalize", ["audio"], "audio", (m) => m.audioOps.normalize),
1705
+ trim: avMember("audio", "trim", ["audio"], "audio", (m) => m.audioOps.trim),
1706
+ concat: avMember("audio", "concat", ["audio"], "audio", (m) => m.audioOps.concat),
1707
+ mix: avMember("audio", "mix", ["audio"], "audio", (m) => m.audioOps.mix),
1708
+ reverse: avMember("audio", "reverse", ["audio"], "audio", (m) => m.audioOps.reverse),
1709
+ fadeIn: avMember("audio", "fadeIn", ["audio"], "audio", (m) => m.audioOps.fadeIn),
1710
+ fadeOut: avMember("audio", "fadeOut", ["audio"], "audio", (m) => m.audioOps.fadeOut),
1711
+ repeat: avMember("audio", "repeat", ["audio"], "audio", (m) => m.audioOps.repeat)
1712
+ };
1713
+ const video = {
1714
+ bytes: avBytes("video"),
1715
+ toAsset: avToAsset("video"),
1716
+ info: avMember("video", "info", ["video"], undefined, (m) => m.videoOps.info),
1717
+ trim: avMember("video", "trim", ["video"], "video", (m) => m.videoOps.trim),
1718
+ resize: avMember("video", "resize", ["video"], "video", (m) => m.videoOps.resize),
1719
+ rotate: avMember("video", "rotate", ["video"], "video", (m) => m.videoOps.rotate),
1720
+ addAudio: avMember("video", "addAudio", ["video", "audio"], "video", (m) => m.videoOps.addAudio),
1721
+ extractAudio: avMember("video", "extractAudio", ["video"], "audio", (m) => m.videoOps.extractAudio),
1722
+ extractFrame: avMember("video", "extractFrame", ["video"], "image", (m) => m.videoOps.extractFrame)
1723
+ };
1724
+ const canvas = {
1725
+ render: imageMember("render", (m) => m.renderCanvas),
1726
+ measureText: mediaMember((m) => m.measureCanvasText)
1727
+ };
1728
+ // Media refs in and out. Unlike the transform namespaces, this one needs a
1729
+ // ProcessingContext — it resolves `asset://`, storage keys and package assets
1730
+ // through the host's own resolver — so without one every member throws.
1731
+ // `media.*` reads files, so it resolves paths through the same
1732
+ // `resolveGuestPath` `workspace.*` uses — one containment rule, one
1733
+ // `filesystemAccess` scope, no second scheme to keep in step.
1734
+ const mediaRefBridge = createMediaRefBridge(context, context
1735
+ ? {
1736
+ resolvePath: (path) => resolveGuestPath(context, path, false)
1737
+ }
1738
+ : {});
1739
+ // A media handle is accepted wherever `media.*` takes a ref or bytes. The
1740
+ // last step of a chain promotes the result with the matching `media.to*`
1741
+ // call. Only this promotion writes to storage; intermediates never do. The
1742
+ // wrapped members share one signature, so they are held under that type and
1743
+ // only the assembled `media` object claims the bridge's shape.
1744
+ const mediaMembers = Object.fromEntries(Object.entries(mediaRefBridge).map(([name, fn]) => [
1745
+ name,
1746
+ async (...args) => fn(...(await resolveMediaArgs(`media.${name}`, args, false)))
1747
+ ]));
1748
+ const promoteTypedHandle = (name, promote) => async (value, options) => {
1749
+ if (isSandboxMediaHandle(value)) {
1750
+ return promote(value, options);
1751
+ }
1752
+ return mediaMembers[name](value, options);
1753
+ };
1754
+ const media = {
1755
+ ...mediaMembers,
1756
+ toImage: promoteTypedHandle("toImage", image.toAsset),
1757
+ toAudio: promoteTypedHandle("toAudio", audio.toAsset),
1758
+ toVideo: promoteTypedHandle("toVideo", video.toAsset)
1759
+ };
375
1760
  const sandbox = {
376
1761
  // Core JS globals are native in QuickJS; we still reflect them in the
377
1762
  // descriptor so callers that inspect `sandbox.JSON` / `sandbox.Math`
@@ -412,33 +1797,81 @@ export function buildSandbox(context) {
412
1797
  TextDecoder: globalThis.TextDecoder,
413
1798
  URL: globalThis.URL,
414
1799
  URLSearchParams: globalThis.URLSearchParams,
415
- // Async primitives blocked — use sleep() instead.
1800
+ // Timer globals blocked — use sleep() for delays and Promise.all /
1801
+ // parallelMap for concurrency. The engine re-installs host-backed timers
1802
+ // on every evaluation, so the real deletion happens in wrapCode; these
1803
+ // entries keep the manifest's blocked list truthful.
416
1804
  setTimeout: undefined,
1805
+ clearTimeout: undefined,
417
1806
  setInterval: undefined,
1807
+ clearInterval: undefined,
1808
+ setImmediate: undefined,
1809
+ clearImmediate: undefined,
418
1810
  // Bridge functions — the only non-native surface the sandbox exposes.
419
1811
  fetch: sandboxedFetch,
420
- uuid,
1812
+ crypto: sandboxCrypto,
421
1813
  sleep,
422
1814
  getSecret,
423
1815
  workspace,
424
1816
  assetToSandbox,
425
1817
  sandboxToAsset,
426
- __maxIter: MAX_LOOP_ITERATIONS
1818
+ progress,
1819
+ emit,
1820
+ output,
1821
+ // Behind the `stream` global the prelude builds; never reachable by name,
1822
+ // which is why they are not in EXPOSED_BRIDGE_NAMES.
1823
+ [SANDBOX_INPUT_TAKE_BINDING]: takeInput,
1824
+ [SANDBOX_STREAM_OPEN_BINDING]: streamOpen,
1825
+ format,
1826
+ image,
1827
+ audio,
1828
+ video,
1829
+ canvas,
1830
+ media,
1831
+ __maxIter: MAX_LOOP_ITERATIONS,
1832
+ // The run's declared secret scope, so `nodetool.secrets.list()` can answer
1833
+ // without a host call. Reading it is not the check — `getSecret` is.
1834
+ __secretScope: secretScope === null ? null : [...secretScope]
1835
+ };
1836
+ return {
1837
+ sandbox,
1838
+ getLogs: () => logs,
1839
+ getOutputs: () => outputs.size > 0 ? Object.fromEntries(outputs) : undefined,
1840
+ getEmitted: () => (emitted.length > 0 ? [...emitted] : undefined)
427
1841
  };
428
- return { sandbox, getLogs: () => logs };
429
1842
  }
430
1843
  // ---------------------------------------------------------------------------
431
1844
  // Code execution
432
1845
  // ---------------------------------------------------------------------------
433
1846
  /**
434
- * Wrap user code as the default export of an ES module with a top-level-awaited
435
- * async IIFE body, so `return <value>` inside the snippet becomes the module's
436
- * default export and `await` at the top level works.
1847
+ * User-code wrapping and the guest module loader live with the interpreter:
1848
+ * the worker path evaluates the same entry module and resolves through the
1849
+ * same loader, and a second copy of either would be a second security policy.
437
1850
  */
438
- export function wrapCode(code) {
439
- return `export default await (async () => {
440
- ${code}
441
- })();`;
1851
+ export { BLOCKED_TIMER_GLOBALS, buildEntryModule, createGuestModuleHost, DELETED_GUEST_GLOBALS, EXPOSED_BRIDGE_NAMES, SANDBOX_CAPABILITY_BRIDGE_BINDING, SANDBOX_HOST_BRIDGE_BINDING, SANDBOX_INPUT_TAKE_BINDING, SANDBOX_STREAM_OPEN_BINDING, SANDBOX_WASM_BRIDGE_BINDING, wrapCode } from "./js-sandbox-worker/interpreter.js";
1852
+ export function createSandboxClock() {
1853
+ let depth = 0;
1854
+ let openedAt = 0;
1855
+ let accumulated = 0;
1856
+ return {
1857
+ suspend() {
1858
+ if (depth === 0)
1859
+ openedAt = Date.now();
1860
+ depth++;
1861
+ let resumed = false;
1862
+ return () => {
1863
+ if (resumed)
1864
+ return;
1865
+ resumed = true;
1866
+ depth--;
1867
+ if (depth === 0)
1868
+ accumulated += Date.now() - openedAt;
1869
+ };
1870
+ },
1871
+ suspendedMs() {
1872
+ return depth > 0 ? accumulated + (Date.now() - openedAt) : accumulated;
1873
+ }
1874
+ };
442
1875
  }
443
1876
  const IDENTIFIER_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
444
1877
  /** Overwrite the contents of `target` with the contents of `source` in place. */
@@ -451,47 +1884,77 @@ function replaceInPlace(target, source) {
451
1884
  }
452
1885
  return;
453
1886
  }
454
- if (target && typeof target === "object") {
1887
+ if (isObjectLike(target)) {
455
1888
  const t = target;
456
1889
  for (const key of Object.keys(t))
457
1890
  delete t[key];
458
- if (source && typeof source === "object" && !Array.isArray(source)) {
1891
+ if (isRecord(source)) {
459
1892
  const s = source;
460
1893
  for (const [k, v] of Object.entries(s))
461
1894
  t[k] = v;
462
1895
  }
463
1896
  }
464
1897
  }
1898
+ /**
1899
+ * Globals the guest prelude defines rather than the host marshals. All but
1900
+ * `stream` are pure — no host call behind them; `stream` is built here because
1901
+ * an async iterable cannot cross the bridge, so the prelude wraps the two
1902
+ * private input bindings into one.
1903
+ */
1904
+ export const GUEST_HELPER_NAMES = [
1905
+ "toBase64",
1906
+ "fromBase64",
1907
+ "toHex",
1908
+ "fromHex",
1909
+ "parallelMap",
1910
+ "createCanvas",
1911
+ "stream"
1912
+ ];
1913
+ /**
1914
+ * A dispatcher's entry point as a bare function, or nothing when the run
1915
+ * declared no such modules — which is what decides whether the guest gets the
1916
+ * binding at all.
1917
+ */
1918
+ function dispatchCallOf(dispatcher) {
1919
+ if (dispatcher === undefined)
1920
+ return undefined;
1921
+ return async (moduleKey, exportName, args) => dispatcher.call(moduleKey, exportName, args);
1922
+ }
465
1923
  /** Names that should never be reassigned via `globals` — core sandbox APIs. */
466
- const RESERVED_SANDBOX_NAMES = new Set([
467
- "console",
468
- "fetch",
469
- "uuid",
470
- "sleep",
471
- "getSecret",
472
- "workspace",
473
- "assetToSandbox",
474
- "sandboxToAsset",
475
- "__maxIter"
1924
+ export const RESERVED_SANDBOX_NAMES = new Set([
1925
+ ...EXPOSED_BRIDGE_NAMES,
1926
+ ...GUEST_HELPER_NAMES,
1927
+ SANDBOX_WASM_BRIDGE_BINDING,
1928
+ SANDBOX_WASM_DISPATCH_GLOBAL,
1929
+ SANDBOX_CAPABILITY_BRIDGE_BINDING,
1930
+ SANDBOX_CAPABILITY_DISPATCH_GLOBAL,
1931
+ SANDBOX_INPUT_TAKE_BINDING,
1932
+ SANDBOX_STREAM_OPEN_BINDING,
1933
+ GUEST_MARSHAL_GLOBAL,
1934
+ GUEST_GLOBALS_JSON_BINDING,
1935
+ GUEST_GLOBALS_SIDECAR_BINDING
476
1936
  ]);
477
1937
  /**
478
- * Names injected as bridge bindings into the QuickJS guest. The rest of the
479
- * `buildSandbox` record (JSON, Math, Date, URL, etc.) is deliberately NOT
480
- * marshaled — QuickJS already provides native implementations, and re-exposing
481
- * host versions creates thousands of handles that slow execution and leak on
482
- * teardown.
1938
+ * Combine a guest error's name and message the way the report reads best:
1939
+ * include the name when it carries signal (`ExecutionTimeout`), drop it when
1940
+ * it is `Error` or already inside the message.
483
1941
  */
484
- const EXPOSED_BRIDGE_NAMES = [
485
- "console",
486
- "fetch",
487
- "uuid",
488
- "sleep",
489
- "getSecret",
490
- "workspace",
491
- "assetToSandbox",
492
- "sandboxToAsset",
493
- "__maxIter"
494
- ];
1942
+ function combineGuestError(name, message) {
1943
+ return name &&
1944
+ name !== "Error" &&
1945
+ !message.toLowerCase().includes(name.toLowerCase())
1946
+ ? `${name}: ${message}`
1947
+ : message || name;
1948
+ }
1949
+ /** Warn once per process when the worker path silently falls back in-process. */
1950
+ let warnedWorkerFallback = false;
1951
+ function noteWorkerFallback(reason) {
1952
+ if (warnedWorkerFallback)
1953
+ return;
1954
+ warnedWorkerFallback = true;
1955
+ console.warn(`sandbox: running in-process (${reason}); a CPU-bound guest will block ` +
1956
+ "this thread until its timeout");
1957
+ }
495
1958
  /**
496
1959
  * Execute JavaScript code inside a QuickJS WebAssembly sandbox.
497
1960
  *
@@ -499,11 +1962,57 @@ const EXPOSED_BRIDGE_NAMES = [
499
1962
  * handler / memory limiter, so runaway user code can't exhaust host resources.
500
1963
  */
501
1964
  export async function runInSandbox(options) {
502
- const { code, context, timeoutMs = DEFAULT_TIMEOUT_MS, globals } = options;
1965
+ const { code, context, timeoutMs = DEFAULT_TIMEOUT_MS, globals, signal, limits, onProgress, onLog, onEmit, onTakeInput, onStreamOpen, clock, modules, capabilities, wasmPool, resolveMediaRef, promoteMedia, resolveHost } = options;
1966
+ const resolvedLimits = resolveSandboxLimits(limits);
1967
+ // A streaming run needs a clock whether or not the caller brought one: the
1968
+ // time it spends parked on upstream is not its own execution.
1969
+ const activeClock = clock ?? (onTakeInput ? createSandboxClock() : undefined);
1970
+ const suspendAllowanceMs = options.suspendAllowanceMs ??
1971
+ (onTakeInput
1972
+ ? INPUT_STREAM_SUSPEND_ALLOWANCE_MS
1973
+ : DEFAULT_SUSPEND_ALLOWANCE_MS);
503
1974
  if (!code.trim()) {
504
1975
  return { success: false, error: "No code provided", logs: [] };
505
1976
  }
506
- const { sandbox, getLogs } = buildSandbox(context);
1977
+ // The dispatcher is built first: it reads every declared WASM binary, so a
1978
+ // module the catalog could not honour is reported here rather than as a
1979
+ // broken facade the guest imports.
1980
+ let wasm;
1981
+ let hostModules;
1982
+ const wasmOptions = {};
1983
+ if (wasmPool !== undefined)
1984
+ wasmOptions.pool = wasmPool;
1985
+ if (signal !== undefined)
1986
+ wasmOptions.signal = signal;
1987
+ const hostOptions = {};
1988
+ if (signal !== undefined)
1989
+ hostOptions.signal = signal;
1990
+ try {
1991
+ wasm = modules
1992
+ ? createSandboxWasmDispatcher(modules.modules, wasmOptions)
1993
+ : undefined;
1994
+ hostModules = modules
1995
+ ? createSandboxHostDispatcher(modules.modules, hostOptions)
1996
+ : undefined;
1997
+ }
1998
+ catch (error) {
1999
+ return {
2000
+ success: false,
2001
+ error: error instanceof Error ? error.message : String(error),
2002
+ logs: []
2003
+ };
2004
+ }
2005
+ if (signal?.aborted) {
2006
+ return { success: false, error: "Execution cancelled", logs: [] };
2007
+ }
2008
+ const streams = {};
2009
+ if (onTakeInput !== undefined)
2010
+ streams.onTakeInput = onTakeInput;
2011
+ if (onStreamOpen !== undefined)
2012
+ streams.onStreamOpen = onStreamOpen;
2013
+ if (activeClock !== undefined)
2014
+ streams.clock = activeClock;
2015
+ const { sandbox, getLogs, getOutputs, getEmitted } = buildSandbox(context, signal, resolvedLimits, onProgress, onLog, onEmit, streams, resolveMediaRef, promoteMedia, resolveHost);
507
2016
  // User-supplied globals (dynamic inputs from CodeNode etc.) layer on top of
508
2017
  // the core surface, but must not clobber the bridge functions themselves.
509
2018
  const userGlobals = {};
@@ -519,136 +2028,279 @@ export async function runInSandbox(options) {
519
2028
  // Identify object-typed globals whose contents should be synced back to the
520
2029
  // host after the guest runs. Primitives are passed by value and need no sync.
521
2030
  const syncTargetNames = Object.entries(userGlobals)
522
- .filter(([, v]) => v !== null && typeof v === "object")
2031
+ .filter(([, v]) => isObjectLike(v))
523
2032
  .map(([k]) => k);
2033
+ // Write the extracted object-global snapshots back into the caller's own
2034
+ // objects. Both paths end here: node:vm shared the host heap, QuickJS does
2035
+ // not, and a worker makes the separation literal. CodeNode relies on this to
2036
+ // make its `state` object persist across invocations.
2037
+ const writeBackGlobals = (extracted) => {
2038
+ if (!extracted)
2039
+ return;
2040
+ for (const name of syncTargetNames) {
2041
+ const hostValue = userGlobals[name];
2042
+ const guestValue = extracted[name];
2043
+ if (isObjectLike(hostValue) && isObjectLike(guestValue)) {
2044
+ replaceInPlace(hostValue, guestValue);
2045
+ }
2046
+ }
2047
+ };
2048
+ // Off the main thread whenever possible. A CPU-bound guest blocks whichever
2049
+ // thread runs it; on the server's main thread that freeze takes the whole
2050
+ // event loop — including the websocket `stop` frame that would have
2051
+ // cancelled the run — down with it. On a worker, abort is `terminate()`,
2052
+ // immediate for spinning and parked guests alike; the logs and emitted
2053
+ // values survive because they accumulate on this side of the port.
2054
+ //
2055
+ // Streaming runs stay in-process: the synchronous `stream.open` probe is
2056
+ // served from a worker-local mirror that must be seeded with the handle
2057
+ // names, which this signature does not carry. Those runs park on takes and
2058
+ // yield the thread constantly, so the freeze this path exists for cannot
2059
+ // build up there.
2060
+ const env = typeof globalThis.process?.env === "object"
2061
+ ? globalThis.process.env
2062
+ : undefined;
2063
+ const workerRequired = env?.NODETOOL_SANDBOX_WORKER === "require";
2064
+ let workerUnavailable = null;
2065
+ // A chosen or designed fallback is quiet; an environmental one warns once.
2066
+ let fallbackByDesign = false;
2067
+ if (env?.NODETOOL_SANDBOX_INPROC === "1") {
2068
+ workerUnavailable = "NODETOOL_SANDBOX_INPROC=1";
2069
+ fallbackByDesign = true;
2070
+ }
2071
+ else if (onTakeInput !== undefined || onStreamOpen !== undefined) {
2072
+ workerUnavailable = "the run streams inputs";
2073
+ fallbackByDesign = true;
2074
+ }
2075
+ else {
2076
+ const safety = precheckCloneSafety(userGlobals);
2077
+ if (!safety.ok) {
2078
+ workerUnavailable = safety.reason;
2079
+ }
2080
+ }
2081
+ if (workerUnavailable === null) {
2082
+ const dispatcherKinds = [];
2083
+ const dispatch = { ...sandbox };
2084
+ const bindDispatcher = (kind, call) => {
2085
+ if (call === undefined)
2086
+ return;
2087
+ dispatch[SANDBOX_DISPATCHER_BINDINGS[kind]] = call;
2088
+ dispatcherKinds.push(kind);
2089
+ };
2090
+ bindDispatcher("wasm", dispatchCallOf(wasm));
2091
+ bindDispatcher("host", dispatchCallOf(hostModules));
2092
+ bindDispatcher("capability", dispatchCallOf(capabilities));
2093
+ for (const [name, value] of Object.entries(userGlobals)) {
2094
+ if (isFunction(value))
2095
+ dispatch[name] = value;
2096
+ }
2097
+ const workerRun = {
2098
+ runId: globalThis.crypto.randomUUID(),
2099
+ code,
2100
+ timeoutMs,
2101
+ limits: resolvedLimits,
2102
+ suspendAllowanceMs,
2103
+ hasClock: activeClock !== undefined,
2104
+ engineTimeoutMs: activeClock !== undefined
2105
+ ? Math.min(timeoutMs + suspendAllowanceMs, MAX_ENGINE_TIMEOUT_MS)
2106
+ : timeoutMs,
2107
+ streamOpenSeed: null,
2108
+ bridgeShape: deriveBridgeShape({
2109
+ bridges: sandbox,
2110
+ dispatchers: dispatcherKinds,
2111
+ globals: userGlobals
2112
+ })
2113
+ };
2114
+ if (modules !== undefined)
2115
+ workerRun.modules = modules;
2116
+ if (capabilities?.facades !== undefined) {
2117
+ workerRun.capabilityFacades = capabilities.facades;
2118
+ }
2119
+ const workerOptions = {
2120
+ run: workerRun,
2121
+ dispatch,
2122
+ // Console and progress already reach their accumulators through the
2123
+ // RPC'd bridges; the push channel exists for a worker that has nothing
2124
+ // else to say, which this integration does not use.
2125
+ onLog: () => { },
2126
+ onProgress: () => { }
2127
+ };
2128
+ if (signal !== undefined)
2129
+ workerOptions.signal = signal;
2130
+ if (activeClock !== undefined) {
2131
+ workerOptions.suspendedMs = () => activeClock.suspendedMs();
2132
+ }
2133
+ const message = await runInWorker(workerOptions);
2134
+ if (message === null) {
2135
+ workerUnavailable = "no sandbox worker could be started here";
2136
+ }
2137
+ else {
2138
+ writeBackGlobals(message.syncedGlobals);
2139
+ const logs = getLogs();
2140
+ // Cancellation wins over whatever the guest was doing when the interrupt
2141
+ // handler cut it — the in-process race has the same rule. The interrupted
2142
+ // guest's own error (`InternalError: interrupted`) is an implementation
2143
+ // detail, not a result.
2144
+ if (signal?.aborted === true) {
2145
+ return {
2146
+ success: false,
2147
+ error: "Execution cancelled",
2148
+ logs,
2149
+ emitted: getEmitted()
2150
+ };
2151
+ }
2152
+ if (message.failure === "cancelled") {
2153
+ return {
2154
+ success: false,
2155
+ error: "Execution cancelled",
2156
+ logs,
2157
+ emitted: getEmitted()
2158
+ };
2159
+ }
2160
+ if (message.failure === "worker") {
2161
+ return {
2162
+ success: false,
2163
+ error: describeEngineFailure(new Error(message.errorMessage ?? "the sandbox worker failed")),
2164
+ logs: logs.length > 0 ? logs : undefined,
2165
+ emitted: getEmitted()
2166
+ };
2167
+ }
2168
+ if (!message.evalOk) {
2169
+ return {
2170
+ success: false,
2171
+ error: combineGuestError(message.errorName ?? "", message.errorMessage ?? ""),
2172
+ stack: message.errorStack
2173
+ ? cleanStack(message.errorStack)
2174
+ : undefined,
2175
+ logs: logs.length > 0 ? logs : undefined,
2176
+ emitted: getEmitted()
2177
+ };
2178
+ }
2179
+ return {
2180
+ success: true,
2181
+ result: serializeResult(message.data, resolvedLimits.maxOutputSize),
2182
+ logs: logs.length > 0 ? logs : undefined,
2183
+ outputs: getOutputs(),
2184
+ emitted: getEmitted()
2185
+ };
2186
+ }
2187
+ }
2188
+ if (workerRequired) {
2189
+ return {
2190
+ success: false,
2191
+ error: `the sandbox worker path is required (NODETOOL_SANDBOX_WORKER=require) but unavailable: ${workerUnavailable}`,
2192
+ logs: []
2193
+ };
2194
+ }
2195
+ if (!fallbackByDesign) {
2196
+ noteWorkerFallback(workerUnavailable);
2197
+ }
524
2198
  try {
525
2199
  const { runSandboxed } = await getEngine();
526
- const evalResponse = await runSandboxed(async ({ ctx, evalCode }) => {
527
- const bridges = {};
528
- for (const name of EXPOSED_BRIDGE_NAMES) {
529
- bridges[name] = sandbox[name];
530
- }
531
- // Wrap every async bridge in a never-reject adapter (see
532
- // SANDBOX_ERROR_MARKER above). The guest prelude rewraps them back into
533
- // throwing functions before user code runs.
534
- bridges.fetch = neverReject(bridges.fetch);
535
- bridges.sleep = neverReject(bridges.sleep);
536
- bridges.getSecret = neverReject(bridges.getSecret);
537
- bridges.assetToSandbox = neverReject(bridges.assetToSandbox);
538
- bridges.sandboxToAsset = neverReject(bridges.sandboxToAsset);
539
- const ws = bridges.workspace;
540
- bridges.workspace = {
541
- read: neverReject(ws.read),
542
- write: neverReject(ws.write),
543
- list: neverReject(ws.list)
544
- };
545
- Object.assign(bridges, userGlobals);
546
- // `expose` manages its own internal Scope; the second arg is unused.
547
- const disposable = new Scope();
548
- try {
549
- expose(ctx, disposable, bridges);
550
- }
551
- finally {
552
- disposable.dispose();
553
- }
554
- // Block dynamic code generation and re-wrap the never-reject bridges as
555
- // throwing guest-side functions. Direct eval in QuickJS can't be neutered
556
- // by overwriting `globalThis.eval` (QuickJS still resolves the builtin),
557
- // but a plain `delete` removes the binding entirely so any reference
558
- // throws ReferenceError — same for `Function`.
559
- await evalCode(`const __marker = "${SANDBOX_ERROR_MARKER}";
560
- const __wrap = (fn) => async (...args) => {
561
- const r = await fn(...args);
562
- if (r && r[__marker]) {
563
- const e = new Error(r.message);
564
- e.name = r.name;
565
- throw e;
566
- }
567
- return r;
568
- };
569
- globalThis.fetch = __wrap(globalThis.fetch);
570
- globalThis.sleep = __wrap(globalThis.sleep);
571
- globalThis.getSecret = __wrap(globalThis.getSecret);
572
- globalThis.assetToSandbox = __wrap(globalThis.assetToSandbox);
573
- globalThis.sandboxToAsset = __wrap(globalThis.sandboxToAsset);
574
- const __ws = globalThis.workspace;
575
- globalThis.workspace = {
576
- read: __wrap(__ws.read),
577
- write: __wrap(__ws.write),
578
- list: __wrap(__ws.list)
579
- };
580
- delete globalThis.eval;
581
- delete globalThis.Function;
582
- export default true;`, "sandbox-init");
583
- const userResult = await evalCode(wrapCode(code), "user-code");
584
- // Sync mutable globals back to the host. node:vm shared the host heap,
585
- // so `state.counter++` in user code mutated the caller's object directly.
586
- // With QuickJS the guest heap is isolated, so after user code runs we
587
- // extract the current values of the object-typed user globals and
588
- // replace the contents of the host-side objects in place. CodeNode
589
- // relies on this to make its `state` object persist across invocations.
590
- if (userResult.ok && syncTargetNames.length > 0) {
591
- const extractor = `export default {${syncTargetNames
592
- .map((n) => `${n}: (typeof ${n} !== 'undefined' && ${n} !== null) ? ${n} : null`)
593
- .join(", ")}};`;
594
- const syncResp = await evalCode(extractor, "sandbox-sync");
595
- if (syncResp.ok && syncResp.data && typeof syncResp.data === "object") {
596
- const extracted = syncResp.data;
597
- for (const name of syncTargetNames) {
598
- const hostValue = userGlobals[name];
599
- const guestValue = extracted[name];
600
- if (hostValue !== null &&
601
- typeof hostValue === "object" &&
602
- guestValue !== null &&
603
- typeof guestValue === "object") {
604
- replaceInPlace(hostValue, guestValue);
605
- }
606
- }
607
- }
608
- }
609
- return userResult;
610
- }, {
611
- executionTimeout: timeoutMs,
612
- memoryLimit: GUEST_MEMORY_LIMIT,
613
- maxStackSize: GUEST_STACK_LIMIT
2200
+ // The dispatchers stay on this side of the boundary — the interpreter only
2201
+ // ever sees a call function, which is as true of a worker's RPC proxy as it
2202
+ // is of the real dispatcher here.
2203
+ const interpreterParams = {
2204
+ runSandboxed,
2205
+ code,
2206
+ sandbox,
2207
+ globals: userGlobals,
2208
+ syncTargetNames,
2209
+ timeoutMs,
2210
+ limits: resolvedLimits,
2211
+ suspendAllowanceMs,
2212
+ hasClock: activeClock !== undefined,
2213
+ wasmCall: dispatchCallOf(wasm),
2214
+ hostCall: dispatchCallOf(hostModules),
2215
+ capabilityCall: dispatchCallOf(capabilities),
2216
+ modules,
2217
+ capabilityFacades: capabilities?.facades
2218
+ };
2219
+ // The interpreter cannot hold either host object: neither an AbortSignal
2220
+ // nor a clock survives a thread boundary, so both arrive as a probe.
2221
+ if (signal !== undefined) {
2222
+ interpreterParams.isAborted = () => signal.aborted;
2223
+ }
2224
+ if (activeClock !== undefined) {
2225
+ interpreterParams.suspendedMs = () => activeClock.suspendedMs();
2226
+ }
2227
+ const sandboxRun = runInterpreter(interpreterParams).then((outcome) => {
2228
+ // The write-back runs as soon as the guest is done, even when
2229
+ // cancellation already won the race below — an orphaned run still owns
2230
+ // the answer it computed.
2231
+ writeBackGlobals(outcome.syncedGlobals);
2232
+ return outcome;
2233
+ });
2234
+ // Return as soon as cancellation lands. The bridges above make a guest that
2235
+ // awaits anything unwind almost immediately; this race additionally covers
2236
+ // a CPU-bound guest, which QuickJS gives us no way to interrupt early — the
2237
+ // orphaned run still winds down on its own execution timeout.
2238
+ const cancellation = new Promise((resolve) => {
2239
+ if (!signal)
2240
+ return;
2241
+ signal.addEventListener("abort", () => resolve(null), { once: true });
614
2242
  });
2243
+ const raced = await guardHostProcess(Promise.race([sandboxRun, cancellation]));
2244
+ if (raced === null) {
2245
+ return {
2246
+ success: false,
2247
+ error: "Execution cancelled",
2248
+ logs: getLogs(),
2249
+ emitted: getEmitted()
2250
+ };
2251
+ }
2252
+ const evalResponse = raced;
615
2253
  const logs = getLogs();
616
2254
  if (!evalResponse.ok) {
617
- // Include the error name alongside the message when the name carries
618
- // useful signal (e.g. `ExecutionTimeout` for the library's wall-clock
619
- // abort). `Error` is redundant, so omit it.
620
- const name = evalResponse.error.name;
621
- const message = evalResponse.error.message;
622
- const combined = name && name !== "Error" && !message.toLowerCase().includes(name.toLowerCase())
623
- ? `${name}: ${message}`
624
- : message || name;
2255
+ const combined = combineGuestError(evalResponse.error.name, evalResponse.error.message);
625
2256
  return {
626
2257
  success: false,
627
2258
  error: combined,
628
2259
  stack: evalResponse.error.stack
629
2260
  ? cleanStack(evalResponse.error.stack)
630
2261
  : undefined,
631
- logs: logs.length > 0 ? logs : undefined
2262
+ logs: logs.length > 0 ? logs : undefined,
2263
+ // Emitted values were delivered while the guest still ran, so they
2264
+ // stand. Recorded `output` finals do not: the run has no answer.
2265
+ emitted: getEmitted()
632
2266
  };
633
2267
  }
634
2268
  return {
635
2269
  success: true,
636
- result: serializeResult(evalResponse.data),
637
- logs: logs.length > 0 ? logs : undefined
2270
+ result: serializeResult(evalResponse.data, resolvedLimits.maxOutputSize),
2271
+ logs: logs.length > 0 ? logs : undefined,
2272
+ outputs: getOutputs(),
2273
+ emitted: getEmitted()
638
2274
  };
639
2275
  }
640
2276
  catch (e) {
641
- // Host-side failures (engine load error, marshaling bug, etc.). Guest-side
642
- // errors go through evalResponse.ok=false above.
2277
+ // Host-side failures (engine load error, marshaling bug, an aborted
2278
+ // runtime). Guest-side errors go through evalResponse.ok=false above.
2279
+ // An engine failure is reported in terms the caller can act on: the raw
2280
+ // Emscripten assertion text tells an agent nothing it can retry against.
643
2281
  const logs = getLogs();
644
- const errorMessage = e instanceof Error ? e.message : String(e);
2282
+ const errorMessage = describeEngineFailure(e);
645
2283
  const errorStack = e instanceof Error ? cleanStack(e.stack ?? "") : undefined;
646
2284
  return {
647
2285
  success: false,
648
2286
  error: errorMessage,
649
2287
  stack: errorStack,
650
- logs: logs.length > 0 ? logs : undefined
2288
+ logs: logs.length > 0 ? logs : undefined,
2289
+ emitted: getEmitted()
651
2290
  };
652
2291
  }
653
2292
  }
2293
+ // ---------------------------------------------------------------------------
2294
+ // Guest preludes for tool-bridged hosts
2295
+ // ---------------------------------------------------------------------------
2296
+ /**
2297
+ * Re-exported here because `./js-sandbox` is the one browser-safe subpath
2298
+ * export of this package: `nodetool.code.Code` (packages/code-nodes) is
2299
+ * bundled for the in-browser runner and must reach these prelude strings
2300
+ * without importing the package index, which drags the whole toolbelt —
2301
+ * native canvas, IMAP, execution — into a web build. Both modules are pure
2302
+ * strings over leaf imports.
2303
+ */
2304
+ export { TOOLS_PRELUDE } from "./codeact/tools-prelude.js";
2305
+ export { NODETOOL_API_PRELUDE_FULL } from "./codeact/nodetool-api.js";
654
2306
  //# sourceMappingURL=js-sandbox.js.map