@animalabs/agent-framework 0.23.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/README.md +212 -42
  2. package/dist/src/agent.d.ts +60 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +92 -12
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/server.d.ts.map +1 -1
  7. package/dist/src/api/server.js +14 -12
  8. package/dist/src/api/server.js.map +1 -1
  9. package/dist/src/code-execution/engine.d.ts +177 -0
  10. package/dist/src/code-execution/engine.d.ts.map +1 -0
  11. package/dist/src/code-execution/engine.js +494 -0
  12. package/dist/src/code-execution/engine.js.map +1 -0
  13. package/dist/src/code-execution/index.d.ts +5 -10
  14. package/dist/src/code-execution/index.d.ts.map +1 -1
  15. package/dist/src/code-execution/index.js +5 -9
  16. package/dist/src/code-execution/index.js.map +1 -1
  17. package/dist/src/code-execution/isolate/calls.d.ts +114 -0
  18. package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
  19. package/dist/src/code-execution/isolate/calls.js +145 -0
  20. package/dist/src/code-execution/isolate/calls.js.map +1 -0
  21. package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
  22. package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
  23. package/dist/src/code-execution/isolate/child-entry.js +5 -0
  24. package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
  25. package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
  26. package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
  27. package/dist/src/code-execution/isolate/child-main.js +132 -0
  28. package/dist/src/code-execution/isolate/child-main.js.map +1 -0
  29. package/dist/src/code-execution/isolate/child.d.ts +44 -0
  30. package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
  31. package/dist/src/code-execution/isolate/child.js +315 -0
  32. package/dist/src/code-execution/isolate/child.js.map +1 -0
  33. package/dist/src/code-execution/isolate/frames.d.ts +80 -0
  34. package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
  35. package/dist/src/code-execution/isolate/frames.js +210 -0
  36. package/dist/src/code-execution/isolate/frames.js.map +1 -0
  37. package/dist/src/code-execution/isolate/output.d.ts +68 -0
  38. package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
  39. package/dist/src/code-execution/isolate/output.js +143 -0
  40. package/dist/src/code-execution/isolate/output.js.map +1 -0
  41. package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
  42. package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
  43. package/dist/src/code-execution/isolate/prelude.js +401 -0
  44. package/dist/src/code-execution/isolate/prelude.js.map +1 -0
  45. package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
  46. package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
  47. package/dist/src/code-execution/isolate/protocol.js +150 -0
  48. package/dist/src/code-execution/isolate/protocol.js.map +1 -0
  49. package/dist/src/code-execution/isolate/render.d.ts +57 -0
  50. package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
  51. package/dist/src/code-execution/isolate/render.js +214 -0
  52. package/dist/src/code-execution/isolate/render.js.map +1 -0
  53. package/dist/src/code-execution/isolate/runner.d.ts +250 -0
  54. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
  55. package/dist/src/code-execution/isolate/runner.js +854 -0
  56. package/dist/src/code-execution/isolate/runner.js.map +1 -0
  57. package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
  58. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
  59. package/dist/src/code-execution/isolate/scripts.js +357 -0
  60. package/dist/src/code-execution/isolate/scripts.js.map +1 -0
  61. package/dist/src/code-execution/quickjs.wasm +0 -0
  62. package/dist/src/code-execution/tool-definition.d.ts +93 -43
  63. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  64. package/dist/src/code-execution/tool-definition.js +176 -142
  65. package/dist/src/code-execution/tool-definition.js.map +1 -1
  66. package/dist/src/deadline-timer.d.ts +3 -0
  67. package/dist/src/deadline-timer.d.ts.map +1 -1
  68. package/dist/src/deadline-timer.js +1 -1
  69. package/dist/src/deadline-timer.js.map +1 -1
  70. package/dist/src/framework.d.ts +1027 -440
  71. package/dist/src/framework.d.ts.map +1 -1
  72. package/dist/src/framework.js +4093 -2238
  73. package/dist/src/framework.js.map +1 -1
  74. package/dist/src/gate/event-gate.d.ts +28 -1
  75. package/dist/src/gate/event-gate.d.ts.map +1 -1
  76. package/dist/src/gate/event-gate.js +88 -10
  77. package/dist/src/gate/event-gate.js.map +1 -1
  78. package/dist/src/held-writes.d.ts +16 -3
  79. package/dist/src/held-writes.d.ts.map +1 -1
  80. package/dist/src/held-writes.js +16 -3
  81. package/dist/src/held-writes.js.map +1 -1
  82. package/dist/src/index.d.ts +6 -6
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +9 -8
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/mcpl/channel-registry.d.ts +471 -75
  87. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  88. package/dist/src/mcpl/channel-registry.js +1673 -337
  89. package/dist/src/mcpl/channel-registry.js.map +1 -1
  90. package/dist/src/mcpl/conversation-router.d.ts +12 -7
  91. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  92. package/dist/src/mcpl/conversation-router.js +12 -7
  93. package/dist/src/mcpl/conversation-router.js.map +1 -1
  94. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  95. package/dist/src/mcpl/convert-block.js +9 -5
  96. package/dist/src/mcpl/convert-block.js.map +1 -1
  97. package/dist/src/mcpl/inbound-source.d.ts +50 -0
  98. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  99. package/dist/src/mcpl/inbound-source.js +130 -0
  100. package/dist/src/mcpl/inbound-source.js.map +1 -1
  101. package/dist/src/mcpl/index.d.ts +2 -1
  102. package/dist/src/mcpl/index.d.ts.map +1 -1
  103. package/dist/src/mcpl/index.js +3 -2
  104. package/dist/src/mcpl/index.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +6 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  107. package/dist/src/mcpl/log-value.js +8 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -1
  109. package/dist/src/mcpl/modern-connection.d.ts +15 -6
  110. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  111. package/dist/src/mcpl/modern-connection.js +168 -53
  112. package/dist/src/mcpl/modern-connection.js.map +1 -1
  113. package/dist/src/mcpl/prose-grammar.d.ts +4 -5
  114. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
  115. package/dist/src/mcpl/prose-grammar.js +4 -5
  116. package/dist/src/mcpl/prose-grammar.js.map +1 -1
  117. package/dist/src/mcpl/protocol-family.d.ts +97 -10
  118. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  119. package/dist/src/mcpl/protocol-family.js +173 -16
  120. package/dist/src/mcpl/protocol-family.js.map +1 -1
  121. package/dist/src/mcpl/push-coalescer.d.ts +132 -14
  122. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  123. package/dist/src/mcpl/push-coalescer.js +227 -50
  124. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  125. package/dist/src/mcpl/push-handler.d.ts +6 -1
  126. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  127. package/dist/src/mcpl/push-handler.js +4 -1
  128. package/dist/src/mcpl/push-handler.js.map +1 -1
  129. package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
  130. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  131. package/dist/src/mcpl/reference-fetcher.js +4 -4
  132. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  133. package/dist/src/mcpl/server-connection.d.ts +50 -21
  134. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  135. package/dist/src/mcpl/server-connection.js +158 -74
  136. package/dist/src/mcpl/server-connection.js.map +1 -1
  137. package/dist/src/mcpl/tags.d.ts +24 -0
  138. package/dist/src/mcpl/tags.d.ts.map +1 -1
  139. package/dist/src/mcpl/tags.js +33 -0
  140. package/dist/src/mcpl/tags.js.map +1 -1
  141. package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
  142. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
  143. package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
  144. package/dist/src/mcpl/transport.d.ts +55 -7
  145. package/dist/src/mcpl/transport.d.ts.map +1 -1
  146. package/dist/src/mcpl/transport.js +163 -34
  147. package/dist/src/mcpl/transport.js.map +1 -1
  148. package/dist/src/mcpl/types.d.ts +22 -6
  149. package/dist/src/mcpl/types.d.ts.map +1 -1
  150. package/dist/src/mcpl/types.js.map +1 -1
  151. package/dist/src/module-registry.d.ts +4 -2
  152. package/dist/src/module-registry.d.ts.map +1 -1
  153. package/dist/src/module-registry.js +100 -13
  154. package/dist/src/module-registry.js.map +1 -1
  155. package/dist/src/modules/discord/index.d.ts.map +1 -1
  156. package/dist/src/modules/discord/index.js +8 -13
  157. package/dist/src/modules/discord/index.js.map +1 -1
  158. package/dist/src/modules/history/index.d.ts.map +1 -1
  159. package/dist/src/modules/history/index.js +27 -4
  160. package/dist/src/modules/history/index.js.map +1 -1
  161. package/dist/src/modules/history/semantic.d.ts +15 -3
  162. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  163. package/dist/src/modules/history/semantic.js +27 -5
  164. package/dist/src/modules/history/semantic.js.map +1 -1
  165. package/dist/src/modules/index.d.ts +1 -1
  166. package/dist/src/modules/index.d.ts.map +1 -1
  167. package/dist/src/modules/index.js.map +1 -1
  168. package/dist/src/modules/unknown-tool.d.ts +4 -1
  169. package/dist/src/modules/unknown-tool.d.ts.map +1 -1
  170. package/dist/src/modules/unknown-tool.js +4 -1
  171. package/dist/src/modules/unknown-tool.js.map +1 -1
  172. package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
  173. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  174. package/dist/src/modules/workspace/branch-intent.js +3 -1
  175. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  176. package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
  177. package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
  178. package/dist/src/modules/workspace/edit-plan.js +794 -0
  179. package/dist/src/modules/workspace/edit-plan.js.map +1 -0
  180. package/dist/src/modules/workspace/edit-text.d.ts +117 -0
  181. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
  182. package/dist/src/modules/workspace/edit-text.js +584 -0
  183. package/dist/src/modules/workspace/edit-text.js.map +1 -0
  184. package/dist/src/modules/workspace/effects.d.ts +5 -4
  185. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  186. package/dist/src/modules/workspace/effects.js +78 -25
  187. package/dist/src/modules/workspace/effects.js.map +1 -1
  188. package/dist/src/modules/workspace/index.d.ts +484 -61
  189. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/index.js +2173 -645
  191. package/dist/src/modules/workspace/index.js.map +1 -1
  192. package/dist/src/modules/workspace/observe.d.ts +213 -38
  193. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/observe.js +416 -36
  195. package/dist/src/modules/workspace/observe.js.map +1 -1
  196. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  197. package/dist/src/modules/workspace/reconcile.js +15 -8
  198. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  199. package/dist/src/modules/workspace/text.d.ts +32 -0
  200. package/dist/src/modules/workspace/text.d.ts.map +1 -0
  201. package/dist/src/modules/workspace/text.js +67 -0
  202. package/dist/src/modules/workspace/text.js.map +1 -0
  203. package/dist/src/modules/workspace/types.d.ts +210 -6
  204. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  205. package/dist/src/modules/workspace/types.js.map +1 -1
  206. package/dist/src/modules/workspace/watcher.d.ts +3 -2
  207. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  208. package/dist/src/modules/workspace/watcher.js.map +1 -1
  209. package/dist/src/operator-log.d.ts +52 -24
  210. package/dist/src/operator-log.d.ts.map +1 -1
  211. package/dist/src/operator-log.js.map +1 -1
  212. package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
  213. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  214. package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
  215. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  216. package/dist/src/recovery/offline-branch.d.ts +26 -1
  217. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  218. package/dist/src/recovery/offline-branch.js +164 -39
  219. package/dist/src/recovery/offline-branch.js.map +1 -1
  220. package/dist/src/recovery/recover-cli.js +23 -4
  221. package/dist/src/recovery/recover-cli.js.map +1 -1
  222. package/dist/src/send-tools.d.ts +11 -0
  223. package/dist/src/send-tools.d.ts.map +1 -0
  224. package/dist/src/send-tools.js +11 -0
  225. package/dist/src/send-tools.js.map +1 -0
  226. package/dist/src/tool-result-guard.d.ts +4 -3
  227. package/dist/src/tool-result-guard.d.ts.map +1 -1
  228. package/dist/src/tool-result-guard.js +5 -4
  229. package/dist/src/tool-result-guard.js.map +1 -1
  230. package/dist/src/tool-result-history.d.ts +1 -1
  231. package/dist/src/tool-result-history.js +1 -1
  232. package/dist/src/tune-out/coordinator.d.ts +21 -0
  233. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  234. package/dist/src/tune-out/coordinator.js +139 -37
  235. package/dist/src/tune-out/coordinator.js.map +1 -1
  236. package/dist/src/types/agent.d.ts +4 -0
  237. package/dist/src/types/agent.d.ts.map +1 -1
  238. package/dist/src/types/events.d.ts +62 -9
  239. package/dist/src/types/events.d.ts.map +1 -1
  240. package/dist/src/types/framework.d.ts +62 -58
  241. package/dist/src/types/framework.d.ts.map +1 -1
  242. package/dist/src/types/module.d.ts +40 -8
  243. package/dist/src/types/module.d.ts.map +1 -1
  244. package/dist/src/types/trace.d.ts +111 -10
  245. package/dist/src/types/trace.d.ts.map +1 -1
  246. package/dist/src/usage/types.d.ts +16 -0
  247. package/dist/src/usage/types.d.ts.map +1 -1
  248. package/dist/src/usage/usage-tracker.d.ts +14 -1
  249. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  250. package/dist/src/usage/usage-tracker.js +81 -41
  251. package/dist/src/usage/usage-tracker.js.map +1 -1
  252. package/package.json +6 -5
  253. package/src/agent.ts +93 -12
  254. package/src/api/server.ts +14 -12
  255. package/src/code-execution/engine.ts +595 -0
  256. package/src/code-execution/index.ts +5 -17
  257. package/src/code-execution/isolate/calls.ts +199 -0
  258. package/src/code-execution/isolate/child-entry.ts +5 -0
  259. package/src/code-execution/isolate/child-main.ts +132 -0
  260. package/src/code-execution/isolate/child.ts +327 -0
  261. package/src/code-execution/isolate/frames.ts +209 -0
  262. package/src/code-execution/isolate/output.ts +161 -0
  263. package/src/code-execution/isolate/prelude.ts +409 -0
  264. package/src/code-execution/isolate/protocol.ts +240 -0
  265. package/src/code-execution/isolate/render.ts +230 -0
  266. package/src/code-execution/isolate/runner.ts +911 -0
  267. package/src/code-execution/isolate/scripts.ts +479 -0
  268. package/src/code-execution/quickjs.wasm +0 -0
  269. package/src/code-execution/quickjs.wasm.LICENSES +149 -0
  270. package/src/code-execution/tool-definition.ts +236 -167
  271. package/src/deadline-timer.ts +1 -1
  272. package/src/framework.ts +4468 -2418
  273. package/src/gate/event-gate.ts +78 -11
  274. package/src/held-writes.ts +17 -3
  275. package/src/index.ts +30 -22
  276. package/src/mcpl/channel-registry.ts +1825 -368
  277. package/src/mcpl/conversation-router.ts +12 -7
  278. package/src/mcpl/convert-block.ts +9 -5
  279. package/src/mcpl/inbound-source.ts +131 -0
  280. package/src/mcpl/index.ts +4 -2
  281. package/src/mcpl/log-value.ts +9 -0
  282. package/src/mcpl/modern-connection.ts +162 -53
  283. package/src/mcpl/prose-grammar.ts +4 -5
  284. package/src/mcpl/protocol-family.ts +199 -21
  285. package/src/mcpl/push-coalescer.ts +306 -62
  286. package/src/mcpl/push-handler.ts +10 -2
  287. package/src/mcpl/reference-fetcher.ts +4 -4
  288. package/src/mcpl/server-connection.ts +180 -79
  289. package/src/mcpl/tags.ts +36 -0
  290. package/src/mcpl/tool-result-normalize.ts +2 -1
  291. package/src/mcpl/transport.ts +162 -33
  292. package/src/mcpl/types.ts +23 -6
  293. package/src/module-registry.ts +92 -13
  294. package/src/modules/discord/index.ts +8 -13
  295. package/src/modules/history/index.ts +25 -3
  296. package/src/modules/history/semantic.ts +29 -6
  297. package/src/modules/index.ts +1 -0
  298. package/src/modules/unknown-tool.ts +4 -1
  299. package/src/modules/workspace/branch-intent.ts +3 -1
  300. package/src/modules/workspace/edit-plan.ts +954 -0
  301. package/src/modules/workspace/edit-text.ts +618 -0
  302. package/src/modules/workspace/effects.ts +70 -19
  303. package/src/modules/workspace/index.ts +2247 -642
  304. package/src/modules/workspace/observe.ts +465 -56
  305. package/src/modules/workspace/reconcile.ts +14 -7
  306. package/src/modules/workspace/text.ts +68 -0
  307. package/src/modules/workspace/types.ts +211 -6
  308. package/src/modules/workspace/watcher.ts +3 -2
  309. package/src/operator-log.ts +47 -19
  310. package/src/recovery/discord-awareness-outbox.ts +1500 -356
  311. package/src/recovery/offline-branch.ts +189 -55
  312. package/src/recovery/recover-cli.ts +25 -4
  313. package/src/send-tools.ts +11 -0
  314. package/src/tool-result-guard.ts +6 -5
  315. package/src/tool-result-history.ts +1 -1
  316. package/src/tune-out/coordinator.ts +163 -42
  317. package/src/types/agent.ts +4 -0
  318. package/src/types/events.ts +62 -9
  319. package/src/types/framework.ts +62 -58
  320. package/src/types/module.ts +40 -8
  321. package/src/types/trace.ts +121 -15
  322. package/src/usage/types.ts +16 -0
  323. package/src/usage/usage-tracker.ts +86 -43
  324. package/dist/src/code-execution/py-runner.d.ts +0 -191
  325. package/dist/src/code-execution/py-runner.d.ts.map +0 -1
  326. package/dist/src/code-execution/py-runner.js +0 -655
  327. package/dist/src/code-execution/py-runner.js.map +0 -1
  328. package/dist/src/code-execution/runtime-py.d.ts +0 -50
  329. package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
  330. package/dist/src/code-execution/runtime-py.js +0 -677
  331. package/dist/src/code-execution/runtime-py.js.map +0 -1
  332. package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
  333. package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
  334. package/dist/src/mcpl/prose-stream-router.js +0 -291
  335. package/dist/src/mcpl/prose-stream-router.js.map +0 -1
  336. package/src/code-execution/py-runner.ts +0 -791
  337. package/src/code-execution/runtime-py.ts +0 -677
  338. package/src/mcpl/prose-stream-router.ts +0 -268
@@ -0,0 +1,401 @@
1
+ /**
2
+ * The guest's prelude: JavaScript the engine evaluates before a script, which
3
+ * builds what a script meets from the binding's two globals, `__host(name,
4
+ * argsJson)` and `__output(stream, text)`:
5
+ *
6
+ * - `tools[name](args)`, each tool by its exact name, answering one result
7
+ * shape, `{ content, structuredContent, isError }`. A refusal before
8
+ * dispatch rejects with an Error carrying the refusal's fields. Reading a
9
+ * name that isn't a tool throws at once, naming the close matches.
10
+ * At most MAX_CALLS_IN_FLIGHT are out at once, and one past them waits
11
+ * here, in the script's own memory, until one is answered.
12
+ * - `ALL_TOOLS`, each tool's name, description and input schema.
13
+ * - `text(value)` and `console.log/info/warn/error/debug(...)`, which write
14
+ * the script's output: a string as it is, anything else as JSON.
15
+ * - `wake_agent(payload)`, which asks the host to wake the agent.
16
+ * - `__run(src)`, which runs a script as the body of an async function, so it
17
+ * may `await` at its top level and `return` a value.
18
+ *
19
+ * Nothing here guards a boundary: the guest's whole world is this instance,
20
+ * and every call it makes is checked by the host. Built-ins aren't frozen, so a
21
+ * script that patches one breaks only itself: its calls and its ending are
22
+ * recorded outside the guest.
23
+ *
24
+ * Adapted from pi-codemode's guest prelude (`@earendil-works/pi-codemode`
25
+ * 1.3.0, `dist/runtime/prelude-source.js`): the tools proxy and its
26
+ * close-match error, the output helpers and the error formatting. Its licence,
27
+ * the LICENSE at the root of github.com/earendil-works/pi, which the package's
28
+ * `license: "MIT"` refers to:
29
+ *
30
+ * MIT License. Copyright (c) 2025 Mario Zechner. Permission is hereby granted,
31
+ * free of charge, to any person obtaining a copy of this software and
32
+ * associated documentation files (the "Software"), to deal in the Software
33
+ * without restriction, including without limitation the rights to use, copy,
34
+ * modify, merge, publish, distribute, sublicense, and/or sell copies of the
35
+ * Software, and to permit persons to whom the Software is furnished to do so,
36
+ * subject to the following conditions: The above copyright notice and this
37
+ * permission notice shall be included in all copies or substantial portions
38
+ * of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
39
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
41
+ * EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
42
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
43
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
44
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
45
+ */
46
+ import { MAX_CALLS_IN_FLIGHT } from './protocol.js';
47
+ import { cutOf } from './render.js';
48
+ /** The host call name `wake_agent()` uses. Parentheses can't be in a tool's name, so it never names a tool. */
49
+ export const WAKE_CALL_NAME = '(wake_agent)';
50
+ /**
51
+ * How many lines QuickJS's async function constructor puts before a script's
52
+ * first line, and the filename it gives the script's code: a script's frames
53
+ * read `<input>:N:C`, with its own line N less this.
54
+ */
55
+ export const SCRIPT_LINE_OFFSET = 2;
56
+ /**
57
+ * A frame of the script's own code, as QuickJS writes one in a stack: " at
58
+ * NAME (PLACE)", or " at PLACE" for a syntax error, its PLACE at the end
59
+ * and the script's, `<input>:LINE:COLUMN`, its LINE of at most ten digits, as
60
+ * QuickJS writes a line (a 32-bit integer). A NAME may hold any character but
61
+ * a line feed, which the stack's lines are split at, so `[^]` rather than
62
+ * `.`, which stops at a carriage return and U+2028 and U+2029 too. The
63
+ * guest's copy of the rule (errorText) is given these two patterns as they
64
+ * are.
65
+ */
66
+ export const SCRIPT_FRAME = /^\s+at\s[^]*<input>:\d{1,10}:\d+\)?$/;
67
+ /** A script frame's place, at its end: its line is renumbered as the agent wrote it. */
68
+ export const SCRIPT_PLACE = /<input>:(\d{1,10})(:\d+\)?)$/;
69
+ /**
70
+ * SCRIPT_FRAME as it reads a line within a whole stack, from the line's
71
+ * start (sticky) to the line feed or the stack's end that closes it, so that
72
+ * no string is made for the line: a line holds no line feed, so there `\s`
73
+ * is `[^\S\n]` and `[^]` is `[^\n]`. A test holds the two to one reading.
74
+ */
75
+ const SCRIPT_FRAME_IN_STACK = /[^\S\n]+at[^\S\n][^\n]*<input>:\d{1,10}:\d+\)?(?=\n|$)/y;
76
+ /**
77
+ * A failure's frames as the agent reads them, one per line: the script's own,
78
+ * numbered as the agent wrote its lines, leaving out the prelude's frames and
79
+ * the engine's native ones. QuickJS gives an Error's stack as its frames
80
+ * alone, and nothing here adds the failure's name and message to it, so the
81
+ * script's frames are the lines shaped as its frames are (SCRIPT_FRAME): a
82
+ * line of a stack the script or its Error.prepareStackTrace set is one if it
83
+ * is shaped so, and isn't otherwise. A function's name holding a line feed
84
+ * splits its frame in two, and each half is read on its own, so the frame is
85
+ * lost unless a half is itself shaped as a frame. Code the script compiles at
86
+ * run time is named `<input>` as the script is, so the rule takes its frames
87
+ * for the script's: an eval's read at its string's lines less two, and a
88
+ * Function constructor's at its body's own lines, plus one for each line
89
+ * break in its parameters, since the constructor puts its parameters and two
90
+ * lines before the body, as the prelude's AsyncFunction does. The prelude's
91
+ * errorText applies this rule in the guest, to an Error the script logs,
92
+ * leading with the name and message, while a string the script logs, an
93
+ * Error's `stack` among them, shows as QuickJS or the script wrote it; the
94
+ * child applies the rule here to every failure's stack. The two are one rule:
95
+ * the guest is given the pair of patterns as they are, and the walk here
96
+ * reads SCRIPT_FRAME as SCRIPT_FRAME_IN_STACK and renumbers a place itself,
97
+ * as SCRIPT_PLACE says, so a change to one has to be made to all three, and
98
+ * tests hold them together.
99
+ */
100
+ export function scriptFrames(stack, max = Infinity) {
101
+ // Two walks of the stack, a line at a time, making no string for a line
102
+ // that isn't a frame, or for a frame the cut doesn't keep: a stack the
103
+ // script set can be any length, as many lines as characters or one line as
104
+ // long as the stack, and beside it the child holds only what the cut keeps.
105
+ // The first walk measures the frames' text; the second takes what the cut
106
+ // keeps of it, all of it if it fits `max`, or else its first and last
107
+ // halves (bounded's cut, cutOf).
108
+ let length = -1;
109
+ eachFrame(stack, (start, place, line, rest, end) => {
110
+ length += 1 + (place - start) + LABEL_CHARS + digits(line) + (end - rest);
111
+ });
112
+ if (length < 0)
113
+ return '';
114
+ const fits = length <= max;
115
+ const half = fits ? length : Math.floor(max / 2);
116
+ const tailFrom = length - (fits ? 0 : half);
117
+ const head = [];
118
+ const tail = [];
119
+ let at = 0;
120
+ // The part of the frames' text from `at` that `text` gives from `from` to
121
+ // `to`: what of it falls in the head or the tail goes there.
122
+ const put = (text, from, to) => {
123
+ const n = to - from;
124
+ if (at < half)
125
+ head.push(text.slice(from, from + Math.min(n, half - at)));
126
+ if (at + n > tailFrom)
127
+ tail.push(text.slice(from + Math.max(0, tailFrom - at), to));
128
+ at += n;
129
+ };
130
+ eachFrame(stack, (start, place, line, rest, end) => {
131
+ if (at > 0)
132
+ put('\n', 0, 1);
133
+ put(stack, start, place);
134
+ const n = LABEL_CHARS + digits(line);
135
+ if (at < half || at + n > tailFrom)
136
+ put(`script:${line}`, 0, n);
137
+ else
138
+ at += n;
139
+ put(stack, rest, end);
140
+ });
141
+ return fits ? head.join('') : cutOf(head.join(''), tail.join(''), length);
142
+ }
143
+ /** `script:`, which a frame's place is renumbered with. */
144
+ const LABEL_CHARS = 7;
145
+ /** How many digits a whole number from 1 to 9,999,999,999 is written with. */
146
+ function digits(n) {
147
+ let count = 1;
148
+ for (let rest = n; rest >= 10; rest = Math.floor(rest / 10))
149
+ count += 1;
150
+ return count;
151
+ }
152
+ /**
153
+ * Each of the script's frames in `stack`, in order, as scriptFrames reads
154
+ * them, with no string made for a line: where its line starts, where its
155
+ * place starts, its place's line as the agent wrote it, where the rest of its
156
+ * place starts (`:COLUMN`, and a closing parenthesis), and where its line
157
+ * ends.
158
+ */
159
+ function eachFrame(stack, frame) {
160
+ for (let start = 0; start <= stack.length;) {
161
+ let end = stack.indexOf('\n', start);
162
+ if (end === -1)
163
+ end = stack.length;
164
+ SCRIPT_FRAME_IN_STACK.lastIndex = start;
165
+ if (SCRIPT_FRAME_IN_STACK.test(stack)) {
166
+ // A frame ends in its place, and no later `<input>:` fits in what
167
+ // follows it there. Its line has at most ten digits, so the number is
168
+ // exact and digits() ends, as it wouldn't on the Infinity that a few
169
+ // hundred digits parse to.
170
+ const place = stack.lastIndexOf('<input>:', end);
171
+ let line = 0;
172
+ let rest = place + 8;
173
+ for (let c = stack.charCodeAt(rest); c >= 48 && c <= 57; c = stack.charCodeAt(++rest))
174
+ line = line * 10 + (c - 48);
175
+ frame(start, place, Math.max(1, line - SCRIPT_LINE_OFFSET), rest, end);
176
+ }
177
+ start = end + 1;
178
+ }
179
+ }
180
+ /**
181
+ * The prelude, for these tools. The child, not the prelude, refuses a wake
182
+ * past the script's cap (child.ts). The tool list goes in as
183
+ * a JSON string the prelude parses, so a schema's `__proto__` key stays a key,
184
+ * as it would not in an object literal, and the prelude is one string the
185
+ * engine evaluates as global code.
186
+ */
187
+ export function preludeSource(tools) {
188
+ const toolsJson = JSON.stringify(tools.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema ?? null })));
189
+ return `(function (host, out, toolList) {
190
+ "use strict";
191
+ const stringify = JSON.stringify;
192
+ const ErrorCtor = Error;
193
+ const TypeErrorCtor = TypeError;
194
+ const scriptOffset = ${SCRIPT_LINE_OFFSET};
195
+
196
+ // QuickJS stacks list frames only: lead with "Name: message", as V8 does, and
197
+ // keep only the script's own frames, leaving out this prelude's, the
198
+ // engine's native ones and the line that started the script, each numbered
199
+ // as the agent wrote its lines. The child applies the same rule to every
200
+ // failure's stack (scriptFrames), reading each line in place.
201
+ const scriptFrame = ${SCRIPT_FRAME};
202
+ const scriptPlace = ${SCRIPT_PLACE};
203
+ function errorText(error) {
204
+ const head = error.message ? String(error.name) + ": " + String(error.message) : String(error.name);
205
+ const stack = typeof error.stack === "string" ? error.stack : "";
206
+ const frames = stack.split("\\n")
207
+ .filter((line) => scriptFrame.test(line))
208
+ .map((line) => line.replace(scriptPlace, (m, n, rest) => "script:" + Math.max(1, Number(n) - scriptOffset) + rest));
209
+ return [head, ...frames].join("\\n");
210
+ }
211
+
212
+ function format(value) {
213
+ if (typeof value === "string") return value;
214
+ if (value instanceof ErrorCtor) return errorText(value);
215
+ try {
216
+ const json = stringify(value);
217
+ return json === undefined ? String(value) : json;
218
+ } catch {
219
+ return String(value);
220
+ }
221
+ }
222
+
223
+ function write(stream, value) {
224
+ let rendered;
225
+ try {
226
+ rendered = format(value);
227
+ } catch (error) {
228
+ throw new TypeErrorCtor(error instanceof ErrorCtor ? error.message : String(error));
229
+ }
230
+ out(stream, rendered + "\\n");
231
+ }
232
+
233
+ // A refusal before dispatch arrives as its JSON, { name, message, ...fields }.
234
+ function asError(reason) {
235
+ if (reason instanceof ErrorCtor) return reason;
236
+ const fields = reason !== null && typeof reason === "object" ? reason : { message: String(reason) };
237
+ const error = new ErrorCtor(typeof fields.message === "string" ? fields.message : "the call was refused");
238
+ for (const key of Object.keys(fields)) {
239
+ if (key === "name" || key === "message" || key === "stack") continue;
240
+ Object.defineProperty(error, key, { value: fields[key], writable: true, enumerable: true, configurable: true });
241
+ }
242
+ if (typeof fields.name === "string" && fields.name) error.name = fields.name;
243
+ return error;
244
+ }
245
+
246
+ function toJson(name, args) {
247
+ let json;
248
+ try {
249
+ json = stringify(args);
250
+ } catch (error) {
251
+ throw new TypeErrorCtor(name + "'s arguments aren't JSON (" + (error instanceof ErrorCtor ? error.message : String(error)) + "); nothing was sent");
252
+ }
253
+ if (json === undefined) throw new TypeErrorCtor(name + "'s arguments aren't JSON; nothing was sent");
254
+ return json;
255
+ }
256
+
257
+ // At most maxInFlight of the script's tool calls are out at once. One past
258
+ // them waits here, in the script's own memory, until one is answered, and
259
+ // its place passes straight to it: never refused, only paced.
260
+ const maxInFlight = ${MAX_CALLS_IN_FLIGHT};
261
+ let inFlight = 0;
262
+ const waiting = [];
263
+ function release() {
264
+ const next = waiting.shift();
265
+ if (next) next();
266
+ else inFlight -= 1;
267
+ }
268
+ function call(name, args) {
269
+ let json;
270
+ try {
271
+ json = args === undefined ? "{}" : toJson(name, args);
272
+ } catch (error) {
273
+ return Promise.reject(error);
274
+ }
275
+ return new Promise((resolve, reject) => {
276
+ const go = () => {
277
+ let pending;
278
+ try {
279
+ pending = host(name, json);
280
+ } catch (error) {
281
+ release();
282
+ reject(asError(error));
283
+ return;
284
+ }
285
+ pending.then(
286
+ (value) => { release(); resolve(value); },
287
+ (reason) => { release(); reject(asError(reason)); },
288
+ );
289
+ };
290
+ if (inFlight < maxInFlight) {
291
+ inFlight += 1;
292
+ go();
293
+ } else {
294
+ waiting.push(go);
295
+ }
296
+ });
297
+ }
298
+
299
+ // wake_agent() takes no place among the calls in flight. The child refuses
300
+ // a payload too large, and a wake past the script's cap, before any goes out.
301
+ function wake(payload) {
302
+ let json;
303
+ try {
304
+ json = toJson("wake_agent()", payload === undefined ? null : payload);
305
+ } catch (error) {
306
+ return Promise.reject(error);
307
+ }
308
+ return host(${JSON.stringify(WAKE_CALL_NAME)}, json).then((value) => value, (reason) => { throw asError(reason); });
309
+ }
310
+
311
+ const tools = Object.create(null);
312
+ const allTools = [];
313
+ for (const { name, description, inputSchema } of toolList) {
314
+ if (name in tools) continue;
315
+ tools[name] = (args) => call(name, args);
316
+ allTools.push(Object.freeze({ name, description, inputSchema }));
317
+ }
318
+ Object.freeze(tools);
319
+ Object.freeze(allTools);
320
+
321
+ // A name that isn't a tool throws at once, naming the close matches, rather
322
+ // than failing later as "not a function". \`in\` still answers false.
323
+ const comparable = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
324
+ const names = allTools.map((tool) => tool.name);
325
+ const toolsProxy = new Proxy(tools, {
326
+ get(object, property, receiver) {
327
+ if (typeof property !== "string" || property in object || property in Object.prototype || property === "then" || property === "toJSON") {
328
+ return Reflect.get(object, property, receiver);
329
+ }
330
+ const wanted = comparable(property);
331
+ const exact = names.filter((name) => comparable(name) === wanted);
332
+ const close = exact.length > 0 ? exact : names.filter((name) => wanted && (comparable(name).includes(wanted) || wanted.includes(comparable(name))));
333
+ let message = "tools[" + stringify(property) + "] is not one of your tools.";
334
+ if (close.length > 0) message += " Did you mean " + close.slice(0, 5).map((name) => "tools[" + stringify(name) + "]").join(", ") + "?";
335
+ else if (names.length === 0) message += " You have no tools.";
336
+ else if (names.length <= 20) message += " Your tools: " + names.join(", ") + ".";
337
+ else message += " ALL_TOOLS lists them.";
338
+ message += " Nothing was sent.";
339
+ throw new TypeErrorCtor(message);
340
+ },
341
+ });
342
+
343
+ const consoleObject = {};
344
+ for (const level of ["log", "info", "debug"]) consoleObject[level] = (...args) => out(1, args.map(format).join(" ") + "\\n");
345
+ for (const level of ["warn", "error"]) consoleObject[level] = (...args) => out(2, args.map(format).join(" ") + "\\n");
346
+ Object.freeze(consoleObject);
347
+
348
+ const AsyncFunction = (async function () {}).constructor;
349
+ // The script's value, as the JSON text of what it returned, serialized here
350
+ // once: its toJSON and getters run once, and the engine serializes this text
351
+ // as a string, which runs no script code however often it's read. A value
352
+ // JSON can't hold, such as a function, a cycle or a BigInt, is its string form.
353
+ async function run(src) {
354
+ let value;
355
+ try {
356
+ const fn = new AsyncFunction(src);
357
+ value = await fn.call(undefined);
358
+ } catch (error) {
359
+ // An Error goes as it is, a syntax error's included: the child puts its
360
+ // frames as the agent reads them (scriptFrames). Anything else thrown,
361
+ // such as a plain object or a string, fails the script with its JSON or
362
+ // its string form as the message, so the agent reads what was thrown;
363
+ // its stack, made here, holds no frame of the script's.
364
+ if (error instanceof ErrorCtor) throw error;
365
+ const failure = new ErrorCtor(format(error));
366
+ failure.name = "";
367
+ throw failure;
368
+ }
369
+ if (value === undefined) return undefined;
370
+ let json;
371
+ try {
372
+ json = stringify(value);
373
+ } catch {
374
+ json = undefined;
375
+ }
376
+ if (json !== undefined) return json;
377
+ // Said as a string, so the agent reads that the value itself didn't come back.
378
+ let text;
379
+ try {
380
+ text = "JSON can't hold the returned value, so this is its string form: " + String(value);
381
+ } catch {
382
+ text = "JSON can't hold the returned value, and it has no string form";
383
+ }
384
+ return stringify(text);
385
+ }
386
+
387
+ Object.defineProperty(globalThis, "tools", { value: toolsProxy, enumerable: true });
388
+ Object.defineProperty(globalThis, "ALL_TOOLS", { value: allTools, enumerable: true });
389
+ Object.defineProperty(globalThis, "console", { value: consoleObject, enumerable: true, configurable: true });
390
+ Object.defineProperty(globalThis, "text", { value: (value) => write(1, value), enumerable: true });
391
+ Object.defineProperty(globalThis, "wake_agent", { value: wake, enumerable: true });
392
+ Object.defineProperty(globalThis, "__run", { value: run });
393
+ try { delete globalThis.__host; delete globalThis.__output; } catch {}
394
+ })(globalThis.__host, globalThis.__output, JSON.parse(${JSON.stringify(toolsJson)}));
395
+ `;
396
+ }
397
+ /** The one line `start` evaluates after the prelude: the script, as a string literal, handed to `__run`. */
398
+ export function scriptCall(script) {
399
+ return `await __run(${JSON.stringify(script)});`;
400
+ }
401
+ //# sourceMappingURL=prelude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prelude.js","sourceRoot":"","sources":["../../../../src/code-execution/isolate/prelude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * The messages between a script's parent and its child, and the checks that
3
+ * turn a decoded frame from the child into one of them. Every frame from a
4
+ * child is untrusted: the parent acts only on a
5
+ * message `decodeChildMessage` accepts, and any other ends the script as
6
+ * crashed.
7
+ */
8
+ import { countJsonValues } from './frames.js';
9
+ import type { PreludeTool } from './prelude.js';
10
+ export { countJsonValues };
11
+ /**
12
+ * The most tool calls a script has out at once, from the call until the
13
+ * script has its answer. One past them waits in the script, in its own memory,
14
+ * until one is answered, and is never refused, so a `Promise.all` over many
15
+ * calls still works, only paced, and what waits is the script's to hold. A
16
+ * child that sends more crashes its run. `wake_agent()` takes no place: its
17
+ * answer holds nothing, and its own cap bounds it.
18
+ */
19
+ export declare const MAX_CALLS_IN_FLIGHT = 16;
20
+ /**
21
+ * The most JSON a tool call's arguments may be, in UTF-8 bytes: room for a
22
+ * generated file of a few MB of ordinary text as one string (escaping takes
23
+ * more room for quotes, backslashes and control characters). With MAX_ARGUMENT_VALUES it bounds
24
+ * what the host holds for a call while it runs: its arguments' text and their
25
+ * parsed value, at most about twice these bytes each (a string the runtime
26
+ * keeps in two bytes a character) and about 92 bytes a value, the most a
27
+ * value cost in a parse under Node 24 and Bun 1.4.
28
+ */
29
+ export declare const MAX_ARGUMENT_BYTES: number;
30
+ /** The most values a tool call's arguments may hold: each object, array and element counts. */
31
+ export declare const MAX_ARGUMENT_VALUES = 100000;
32
+ /** The most JSON a `wake_agent()` payload may be, in UTF-8 bytes: a wake says what happened, and a longer result is written with a tool. */
33
+ export declare const MAX_WAKE_PAYLOAD_BYTES: number;
34
+ /** A cap as the tool's text says it, such as 4 MiB. */
35
+ export declare const capText: (bytes: number) => string;
36
+ /** A `wake_agent()` payload the host won't take, said to the script: nothing was sent. Null when it may go out. */
37
+ export declare function wakeRefusal(payloadJson: string): {
38
+ name: 'WakeRefused';
39
+ message: string;
40
+ bytes: number;
41
+ } | null;
42
+ /**
43
+ * The longest frame a child sends: a call frame carries its arguments escaped,
44
+ * at most six bytes for each of the 4 MiB the script may send, with room for
45
+ * its name and the rest. The child encodes its frames against it, and the
46
+ * parent refuses a longer one before its body is kept, so one frame being
47
+ * read costs the host at most this much as bytes, and its text and its parse
48
+ * up to twice as much again each.
49
+ */
50
+ export declare const MAX_CHILD_FRAME_BYTES: number;
51
+ /** A wake past the script's cap, said to the script: nothing was sent. */
52
+ export declare function wakeLimitRefusal(maxWakes: number): {
53
+ name: 'WakeRefused';
54
+ message: string;
55
+ };
56
+ /** A call's arguments the host won't take, said to the script: nothing was sent. Null when they may go out. */
57
+ export declare function argumentsRefusal(tool: string, argsJson: string): {
58
+ name: 'ArgumentsTooLarge';
59
+ message: string;
60
+ bytes: number;
61
+ } | null;
62
+ /** The error a script gets for a call whose result was too large for its memory: the call took effect. */
63
+ export declare const RESULT_TOO_LARGE = "ResultTooLarge";
64
+ /** Why a stop was asked for: by the agent, or at the script's limit. Only the parent knows it. */
65
+ export type StopReason = 'agent' | 'limit';
66
+ /** The first frame to the child: the script and everything it runs with. */
67
+ export interface StartMessage {
68
+ t: 'start';
69
+ script: string;
70
+ tools: PreludeTool[];
71
+ /** The WebAssembly memory's maximum: the child's budget. */
72
+ memoryMaxBytes: number;
73
+ maxStackBytes?: number;
74
+ /** The file whose appearance stops the script: its content says nothing. */
75
+ stopFile: string;
76
+ /** How often, at most, waiting output is flushed while the guest runs. */
77
+ flushMs: number;
78
+ /** The most wakes the script may send: the child refuses one past them itself. */
79
+ maxWakes: number;
80
+ /** The parent's pid: the child ends its process once its parent is another, its parent having gone. */
81
+ parentPid: number;
82
+ }
83
+ /**
84
+ * A tool call's answer, as the child decodes a result frame: `ok` resolves the
85
+ * guest's promise with the parsed `json`, otherwise rejects with it. The JSON
86
+ * stays bytes, for the engine to parse in the guest.
87
+ */
88
+ export type { ResultFrame as ResultMessage } from './frames.js';
89
+ import type { ResultFrame } from './frames.js';
90
+ /** A stop for a child whose guest is idle, waiting on calls; a computing guest sees the stop file instead. */
91
+ export interface StopMessage {
92
+ t: 'stop';
93
+ }
94
+ export type ParentMessage = StartMessage | ResultFrame | StopMessage;
95
+ /** The guest called a tool, or `wake_agent()`, by the prelude's call name. */
96
+ export interface CallMessage {
97
+ t: 'call';
98
+ id: number;
99
+ name: string;
100
+ /** The arguments as the guest's JSON text. */
101
+ args: string;
102
+ }
103
+ /** Output the guest wrote since the last such frame. */
104
+ export interface OutMessage {
105
+ t: 'out';
106
+ text: string;
107
+ }
108
+ /** An error as the guest describes it. */
109
+ export interface GuestError {
110
+ name: string;
111
+ message: string;
112
+ /** The script's frames, one per line, as the agent reads them (scriptFrames): the name and message aren't in it. */
113
+ stack?: string;
114
+ }
115
+ /**
116
+ * The engine settled a call's result, so its place is free. `unfit` when the
117
+ * result didn't fit the guest's memory, so the script got ResultTooLarge in
118
+ * its place. The parent's record counts a call as the script saw it.
119
+ */
120
+ export interface SeenMessage {
121
+ t: 'seen';
122
+ id: number;
123
+ unfit?: true;
124
+ }
125
+ /**
126
+ * How the script ended, as the child saw it. A crash is the parent's to see:
127
+ * the child can't report it. A stop's reason is the parent's too, since it
128
+ * asked for the stop.
129
+ */
130
+ export type EndMessage = {
131
+ t: 'end';
132
+ how: 'finished';
133
+ value?: string;
134
+ } | {
135
+ t: 'end';
136
+ how: 'failed';
137
+ error: GuestError;
138
+ stalled?: boolean;
139
+ } | {
140
+ t: 'end';
141
+ how: 'stopped';
142
+ };
143
+ export type ChildMessage = CallMessage | OutMessage | SeenMessage | EndMessage;
144
+ /**
145
+ * A frame from a child, as a message the parent may act on, or the reason it
146
+ * can't be one. Fields beyond those a message has are ignored.
147
+ */
148
+ export declare function decodeChildMessage(value: unknown): ChildMessage | {
149
+ invalid: string;
150
+ };
151
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../src/code-execution/isolate/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,QAAkB,CAAC;AAElD,+FAA+F;AAC/F,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,4IAA4I;AAC5I,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD,uDAAuD;AACvD,eAAO,MAAM,OAAO,UAAW,MAAM,KAAG,MAAgG,CAAC;AAEzI,mHAAmH;AACnH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ/G;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,QAAuC,CAAC;AAE1E,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAc3F;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBrI;AAED,0GAA0G;AAC1G,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,kGAAkG;AAClG,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,OAAO,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,uGAAuG;IACvG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,YAAY,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,8GAA8G;AAC9G,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;AAErE,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,KAAK,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,oHAAoH;IACpH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,IAAI,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACjE;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC;AAS/E;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CA0CrF"}