llmz 0.9.0 → 1.0.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 (231) hide show
  1. package/DOCS.md +230 -1796
  2. package/ERRORS.md +98 -0
  3. package/README.md +96 -582
  4. package/dist/chat/chat.d.ts +63 -0
  5. package/dist/chat/component.d.ts +31 -0
  6. package/dist/chat/component.default.d.ts +58 -0
  7. package/dist/chat/response.d.ts +15 -0
  8. package/dist/compiler/compiler.d.ts +2 -7
  9. package/dist/compiler/plugins/dynamic-code.d.ts +7 -0
  10. package/dist/compiler/plugins/replace-comment.d.ts +2 -3
  11. package/dist/compiler/plugins/return-async.d.ts +5 -4
  12. package/dist/compiler/plugins/termination.d.ts +8 -0
  13. package/dist/compiler/plugins/tool-resolution.d.ts +4 -0
  14. package/dist/compiler/plugins/variable-extraction.d.ts +2 -8
  15. package/dist/component-BpMVZYOa.cjs +649 -0
  16. package/dist/component-C27qu6Zv.js +614 -0
  17. package/dist/context.d.ts +70 -377
  18. package/dist/custom-client-BDkgBR2w.js +1631 -0
  19. package/dist/custom-client-MytucGI-.cjs +1708 -0
  20. package/dist/custom-client.d.ts +12 -2
  21. package/dist/errors/catalog.d.ts +287 -0
  22. package/dist/errors/hooks.d.ts +2 -0
  23. package/dist/errors-H4JJFH3S.js +620 -0
  24. package/dist/errors-IhnTKUp7.cjs +871 -0
  25. package/dist/errors.d.ts +18 -36
  26. package/dist/execute-BYI_U5sR.js +1943 -0
  27. package/dist/execute-DLas4V2n.cjs +1944 -0
  28. package/dist/{exit-DUM96DN1.cjs → exit-BUgJ5qi5.cjs} +38 -28
  29. package/dist/{exit-CDdxDBRT.js → exit-CPNk3vbz.js} +37 -27
  30. package/dist/exit.d.ts +19 -16
  31. package/dist/index.cjs +176 -1237
  32. package/dist/index.d.ts +25 -28
  33. package/dist/index.js +137 -1213
  34. package/dist/index.workerd.js +8427 -10771
  35. package/dist/inspect.d.ts +18 -4
  36. package/dist/inspection.d.ts +38 -0
  37. package/dist/native-Bm6L9zOb.cjs +212 -0
  38. package/dist/native-DvTH9vFe.js +177 -0
  39. package/dist/objects.d.ts +2 -57
  40. package/dist/prompts/native.d.ts +2 -0
  41. package/dist/prompts/prompt.d.ts +10 -101
  42. package/dist/quickjs-variant-DJwYDSsb.cjs +1073 -0
  43. package/dist/quickjs-variant-DlPi9-Sx.js +984 -0
  44. package/dist/result.d.ts +30 -861
  45. package/dist/runtime/execute.d.ts +3 -2
  46. package/dist/runtime/execution-activity.d.ts +11 -0
  47. package/dist/runtime/execution-diagnostics.d.ts +11 -0
  48. package/dist/runtime/execution-report.d.ts +48 -0
  49. package/dist/runtime/fixtures/chat.d.ts +8 -0
  50. package/dist/runtime/fixtures/long-search.d.ts +1 -1
  51. package/dist/runtime/fixtures/native-client.d.ts +33 -0
  52. package/dist/runtime/fixtures/protocol-languages.d.ts +1 -1
  53. package/dist/runtime/generate.d.ts +23 -20
  54. package/dist/runtime/inspection-values.d.ts +14 -0
  55. package/dist/runtime/inspection-values.test.d.ts +1 -0
  56. package/dist/runtime/interruption-control-flow.test.d.ts +1 -0
  57. package/dist/runtime/interruption-settings.test.d.ts +1 -0
  58. package/dist/runtime/javascript-api.d.ts +59 -0
  59. package/dist/runtime/javascript-api.test.d.ts +1 -0
  60. package/dist/runtime/native-review.test.d.ts +1 -0
  61. package/dist/runtime/native-tools.d.ts +18 -0
  62. package/dist/runtime/native-tools.test.d.ts +1 -0
  63. package/dist/runtime/object-memory.test.d.ts +1 -0
  64. package/dist/runtime/single-tool.test.d.ts +1 -0
  65. package/dist/runtime/token-budget.d.ts +22 -0
  66. package/dist/runtime/token-budget.test.d.ts +1 -0
  67. package/dist/runtime/tool-wrapper.d.ts +4 -5
  68. package/dist/runtime/traces.test.d.ts +1 -0
  69. package/dist/runtime/truncation.test.d.ts +1 -0
  70. package/dist/runtime/types.d.ts +39 -31
  71. package/dist/runtime/variable-recovery.test.d.ts +1 -0
  72. package/dist/runtime/vm-context.d.ts +6 -1
  73. package/dist/runtime/worker-completion.test.d.ts +1 -0
  74. package/dist/runtime-names.d.ts +4 -0
  75. package/dist/schema-Aer_W7Al.js +45 -0
  76. package/dist/schema-DBkjo0b7.cjs +68 -0
  77. package/dist/schema.d.ts +10 -0
  78. package/dist/schema.test.d.ts +1 -0
  79. package/dist/session/compactor.d.ts +51 -0
  80. package/dist/session/compactor.test.d.ts +1 -0
  81. package/dist/session/history.d.ts +36 -0
  82. package/dist/session/history.test.d.ts +1 -0
  83. package/dist/session/json.d.ts +3 -0
  84. package/dist/session/json.test.d.ts +1 -0
  85. package/dist/session/memory-codec.d.ts +9 -0
  86. package/dist/session/memory-codec.test.d.ts +1 -0
  87. package/dist/session/memory-render.d.ts +15 -0
  88. package/dist/session/memory-render.test.d.ts +1 -0
  89. package/dist/session/memory.d.ts +112 -0
  90. package/dist/session/memory.test.d.ts +1 -0
  91. package/dist/session/messages.d.ts +17 -0
  92. package/dist/session/messages.test.d.ts +1 -0
  93. package/dist/session/serialization.d.ts +34 -0
  94. package/dist/session/serialization.test.d.ts +1 -0
  95. package/dist/session/session-memory.test.d.ts +1 -0
  96. package/dist/session/session.d.ts +117 -0
  97. package/dist/session/session.test.d.ts +1 -0
  98. package/dist/{transcript.d.ts → session/transcript.d.ts} +4 -8
  99. package/dist/session/transcript.test.d.ts +1 -0
  100. package/dist/{tool-Bv8N4IPj.js → tool--gK91eez.js} +144 -92
  101. package/dist/{tool-Dy6AJpJH.cjs → tool-Da_F-N-5.cjs} +146 -94
  102. package/dist/tool.d.ts +25 -17
  103. package/dist/truncate-BSoH2-nY.js +79 -0
  104. package/dist/truncate-nV3Mxr6-.cjs +102 -0
  105. package/dist/truncate.d.ts +24 -0
  106. package/dist/truncate.test.d.ts +1 -0
  107. package/dist/types.d.ts +27 -9
  108. package/dist/{typings-3lsqCbkn.cjs → typings-C1ihexWE.cjs} +38 -193
  109. package/dist/{typings-CrBa7Tyy.js → typings-D9_aC8aq.js} +38 -175
  110. package/dist/typings-formatter.d.ts +1 -1
  111. package/dist/typings.d.ts +3 -0
  112. package/dist/{uniq-BYQ7GWwb.js → uniq-DfUeSNaX.js} +2 -2
  113. package/dist/{uniq-G872RWmE.cjs → uniq-DiXgysNV.cjs} +6 -18
  114. package/dist/{_baseIteratee-P_firB7b.js → utils-BOFzb8Ok.js} +1134 -16
  115. package/dist/{_baseIteratee-CF4qP2a8.cjs → utils-CTlsXvdj.cjs} +1281 -84
  116. package/dist/vm/drivers/node.d.ts +1 -1
  117. package/dist/vm/drivers/quickjs.d.ts +1 -1
  118. package/dist/vm/errors.d.ts +4 -4
  119. package/dist/vm/index.d.ts +3 -4
  120. package/dist/vm/instrument.d.ts +14 -6
  121. package/dist/vm/member-proxy.d.ts +4 -0
  122. package/dist/vm/member-proxy.test.d.ts +1 -0
  123. package/dist/vm/memory.test.d.ts +1 -0
  124. package/dist/vm/return-semantics.test.d.ts +1 -0
  125. package/dist/vm/types.d.ts +18 -3
  126. package/dist/{vm-BLsHw1da.js → vm-8jxt8PTK.js} +1162 -180
  127. package/dist/{vm-D6s1zF6M.cjs → vm-XuVPuW3Y.cjs} +1195 -207
  128. package/package.json +13 -6
  129. package/dist/_baseForOwn-BfWDTL8L.cjs +0 -53
  130. package/dist/_baseForOwn-CFhWe_W6.js +0 -48
  131. package/dist/_getPrototype-CG7Dxrrz.js +0 -6
  132. package/dist/_getPrototype-DQDlNVVM.cjs +0 -10
  133. package/dist/_overArg-C5Hy7oCi.cjs +0 -196
  134. package/dist/_overArg-CRYbj1NH.js +0 -155
  135. package/dist/chat.d.ts +0 -401
  136. package/dist/common-BlRFtdf2.js +0 -807
  137. package/dist/common-BnvrDnIT.cjs +0 -860
  138. package/dist/compiler/plugins/track-tool-calls.d.ts +0 -33
  139. package/dist/compiler-C-OI9sim.cjs +0 -547
  140. package/dist/compiler-CW1VjQsn.js +0 -473
  141. package/dist/component-C6Agl2ns.cjs +0 -73
  142. package/dist/component-DGG7d_Mz.js +0 -44
  143. package/dist/component.d.ts +0 -88
  144. package/dist/component.default.d.ts +0 -278
  145. package/dist/custom-client-ChuZ63zp.js +0 -2658
  146. package/dist/custom-client-DAsGRnYc.cjs +0 -2729
  147. package/dist/dual-modes-DDkoCp3R.js +0 -3006
  148. package/dist/dual-modes-DPXiuvNe.cjs +0 -3090
  149. package/dist/errors-C962uJdS.cjs +0 -220
  150. package/dist/errors-Cg1G0Awu.js +0 -161
  151. package/dist/example-format.d.ts +0 -8
  152. package/dist/example.d.ts +0 -45
  153. package/dist/execute-BWcdv9so.js +0 -1059
  154. package/dist/execute-DM2-7y86.cjs +0 -1060
  155. package/dist/exit-parser.d.ts +0 -39
  156. package/dist/handlers.d.ts +0 -10
  157. package/dist/hoist.d.ts +0 -2
  158. package/dist/isEmpty-BhJRCqIF.js +0 -52
  159. package/dist/isEmpty-LY533Wmh.cjs +0 -57
  160. package/dist/isPlainObject-CSxXVKCk.cjs +0 -56
  161. package/dist/isPlainObject-D39AzPO2.js +0 -51
  162. package/dist/jsx-CIgdGGVs.js +0 -52
  163. package/dist/jsx-owqxrquU.cjs +0 -75
  164. package/dist/jsx.d.ts +0 -11
  165. package/dist/message-stream/index.d.ts +0 -9
  166. package/dist/message-stream/instructions.d.ts +0 -30
  167. package/dist/message-stream/normalizer.d.ts +0 -21
  168. package/dist/message-stream/parser.d.ts +0 -89
  169. package/dist/message-stream/registry.d.ts +0 -14
  170. package/dist/message-stream/replayable.d.ts +0 -27
  171. package/dist/message-stream/response-parser.d.ts +0 -24
  172. package/dist/message-stream/sanitize.d.ts +0 -10
  173. package/dist/message-stream/stream.d.ts +0 -54
  174. package/dist/message-stream/types.d.ts +0 -97
  175. package/dist/message-stream/validator.d.ts +0 -23
  176. package/dist/prompts/chat-mode/protocol.d.ts +0 -2
  177. package/dist/prompts/chat-mode/system.d.ts +0 -2
  178. package/dist/prompts/chat-mode/system.md.d.ts +0 -2
  179. package/dist/prompts/chat-mode/user.d.ts +0 -2
  180. package/dist/prompts/chat-mode/user.md.d.ts +0 -2
  181. package/dist/prompts/code-examples.d.ts +0 -2
  182. package/dist/prompts/common.d.ts +0 -7
  183. package/dist/prompts/dual-modes.d.ts +0 -2
  184. package/dist/prompts/execution-history.d.ts +0 -6
  185. package/dist/prompts/execution-state.d.ts +0 -3
  186. package/dist/prompts/protocol-basics.d.ts +0 -5
  187. package/dist/prompts/protocol.d.ts +0 -31
  188. package/dist/prompts/worker-mode/protocol.d.ts +0 -2
  189. package/dist/prompts/worker-mode/system.d.ts +0 -2
  190. package/dist/prompts/worker-mode/system.md.d.ts +0 -2
  191. package/dist/prompts/worker-mode/user.d.ts +0 -2
  192. package/dist/prompts/worker-mode/user.md.d.ts +0 -2
  193. package/dist/quickjs-variant-BYhMBpwU.js +0 -45
  194. package/dist/quickjs-variant-CsIwTVFC.cjs +0 -56
  195. package/dist/rolldown-runtime-EAsCxrDo.js +0 -14
  196. package/dist/runtime/fixtures/qwen-protocol-failures.d.ts +0 -29
  197. package/dist/runtime/interpret-result.d.ts +0 -22
  198. package/dist/snapshots.d.ts +0 -249
  199. package/dist/stack-traces-BIE_5Xwf.js +0 -21
  200. package/dist/stack-traces-ntw_qhoy.cjs +0 -26
  201. package/dist/truncator-CLkouTCO.cjs +0 -276
  202. package/dist/truncator-DZqEqnpD.js +0 -253
  203. package/dist/truncator.d.ts +0 -118
  204. package/dist/utils-3ESwP3yg.cjs +0 -1075
  205. package/dist/utils-UBeAFeEI.js +0 -950
  206. /package/dist/{citations.d.ts → chat/citations.d.ts} +0 -0
  207. /package/dist/{citations.test.d.ts → chat/citations.test.d.ts} +0 -0
  208. /package/dist/{component.default.test.d.ts → chat/component.default.test.d.ts} +0 -0
  209. /package/dist/{compiler/plugins/track-tool-calls.test.d.ts → chat/component.test.d.ts} +0 -0
  210. /package/dist/{example.test.d.ts → chat/response.test.d.ts} +0 -0
  211. /package/dist/{exit-parser.test.d.ts → compiler/plugins/dynamic-code.test.d.ts} +0 -0
  212. /package/dist/{handlers.test.d.ts → compiler/plugins/tool-resolution.test.d.ts} +0 -0
  213. /package/dist/{hoist.test.d.ts → errors/catalog.test.d.ts} +0 -0
  214. /package/dist/{message-stream/instructions.test.d.ts → exit.test.d.ts} +0 -0
  215. /package/dist/{message-stream/normalizer.test.d.ts → inspection.test.d.ts} +0 -0
  216. /package/dist/{message-stream/parser.test.d.ts → prompts/native.test.d.ts} +0 -0
  217. /package/dist/{message-stream/response-parser.test.d.ts → result.test.d.ts} +0 -0
  218. /package/dist/{message-stream/stream.test.d.ts → runtime/chat-delivery.test.d.ts} +0 -0
  219. /package/dist/{message-stream/validator.test.d.ts → runtime/compatibility-regressions.test.d.ts} +0 -0
  220. /package/dist/{prompts/adherence.test.d.ts → runtime/context-registration.test.d.ts} +0 -0
  221. /package/dist/{prompts/catalogue-examples.test.d.ts → runtime/error-recovery.test.d.ts} +0 -0
  222. /package/dist/{prompts/code-examples.test.d.ts → runtime/errors.test.d.ts} +0 -0
  223. /package/dist/{prompts/common.test.d.ts → runtime/execution-activity.test.d.ts} +0 -0
  224. /package/dist/{prompts/concrete-patterns.test.d.ts → runtime/execution-diagnostics.test.d.ts} +0 -0
  225. /package/dist/{prompts/long-search.test.d.ts → runtime/execution-report.test.d.ts} +0 -0
  226. /package/dist/{prompts/protocol-simple.test.d.ts → runtime/execution-safety.test.d.ts} +0 -0
  227. /package/dist/{prompts/protocol.test.d.ts → runtime/exit-control-flow.test.d.ts} +0 -0
  228. /package/dist/{prompts/sections.test.d.ts → runtime/fixtures/long-search.test.d.ts} +0 -0
  229. /package/dist/runtime/{interpret-result.test.d.ts → generate.test.d.ts} +0 -0
  230. /package/dist/{transcript.test.d.ts → runtime/hook-provenance.test.d.ts} +0 -0
  231. /package/dist/{truncator.test.d.ts → runtime/inspection-hook.test.d.ts} +0 -0
@@ -1,11 +1,55 @@
1
- import { t as __commonJSMin } from "./rolldown-runtime-EAsCxrDo.js";
2
- import { B as isSymbol, I as isFunction, M as baseAssignValue, t as baseIteratee } from "./_baseIteratee-P_firB7b.js";
3
- import { t as baseForOwn } from "./_baseForOwn-CFhWe_W6.js";
4
- import { t as cleanStackTrace } from "./stack-traces-BIE_5Xwf.js";
5
- import { a as InvalidCodeError, c as SnapshotSignal, n as CodeExecutionError, s as Signals, u as VMSignal } from "./errors-Cg1G0Awu.js";
6
- import { n as compile, t as Identifiers } from "./compiler-CW1VjQsn.js";
7
- import { n as getQuickJSVariant } from "./quickjs-variant-BYhMBpwU.js";
1
+ import { A as keys, B as baseAssignValue, J as __commonJSMin, V as isFunction, W as isSymbol, h as baseIteratee } from "./utils-BOFzb8Ok.js";
2
+ import { B as UnknownToolError, H as isLLMzError, N as ReservedIdentifierError, o as AssignmentError, r as VMSignal, s as CodeExecutionError, t as Signals, v as InvalidCodeError } from "./errors-H4JJFH3S.js";
3
+ import { a as cloneMemoryValue, d as TERMINATION_BINDING_NAMES, l as RESERVED_RUNTIME_NAMES, n as getQuickJSVariant, o as decodeMemoryValue, u as RUNTIME_BINDING_NAMES } from "./quickjs-variant-DlPi9-Sx.js";
4
+ import MagicString from "magic-string";
5
+ import { parse } from "acorn";
8
6
  import { newQuickJSWASMModuleFromVariant, shouldInterruptAfterDeadline } from "quickjs-emscripten-core";
7
+ //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_createBaseFor.js
8
+ /**
9
+ * Creates a base function for methods like `_.forIn` and `_.forOwn`.
10
+ *
11
+ * @private
12
+ * @param {boolean} [fromRight] Specify iterating from right to left.
13
+ * @returns {Function} Returns the new base function.
14
+ */
15
+ function createBaseFor(fromRight) {
16
+ return function(object, iteratee, keysFunc) {
17
+ var index = -1, iterable = Object(object), props = keysFunc(object), length = props.length;
18
+ while (length--) {
19
+ var key = props[fromRight ? length : ++index];
20
+ if (iteratee(iterable[key], key, iterable) === false) break;
21
+ }
22
+ return object;
23
+ };
24
+ }
25
+ //#endregion
26
+ //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseFor.js
27
+ /**
28
+ * The base implementation of `baseForOwn` which iterates over `object`
29
+ * properties returned by `keysFunc` and invokes `iteratee` for each property.
30
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
31
+ *
32
+ * @private
33
+ * @param {Object} object The object to iterate over.
34
+ * @param {Function} iteratee The function invoked per iteration.
35
+ * @param {Function} keysFunc The function to get the keys of `object`.
36
+ * @returns {Object} Returns `object`.
37
+ */
38
+ var baseFor = createBaseFor();
39
+ //#endregion
40
+ //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseForOwn.js
41
+ /**
42
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
43
+ *
44
+ * @private
45
+ * @param {Object} object The object to iterate over.
46
+ * @param {Function} iteratee The function invoked per iteration.
47
+ * @returns {Object} Returns `object`.
48
+ */
49
+ function baseForOwn(object, iteratee) {
50
+ return object && baseFor(object, iteratee, keys);
51
+ }
52
+ //#endregion
9
53
  //#region ../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseGt.js
10
54
  /**
11
55
  * The base implementation of `_.gt` which doesn't coerce arguments.
@@ -2204,13 +2248,599 @@ var require_source_node = /* @__PURE__ */ __commonJSMin(((exports) => {
2204
2248
  exports.SourceNode = SourceNode;
2205
2249
  }));
2206
2250
  //#endregion
2207
- //#region src/vm/errors.ts
2251
+ //#region src/compiler/ast.ts
2208
2252
  var import_source_map = (/* @__PURE__ */ __commonJSMin(((exports) => {
2209
2253
  exports.SourceMapGenerator = require_source_map_generator().SourceMapGenerator;
2210
2254
  exports.SourceMapConsumer = require_source_map_consumer().SourceMapConsumer;
2211
2255
  exports.SourceNode = require_source_node().SourceNode;
2212
2256
  })))();
2213
- const handleErrorQuickJS = (err, code, _consumer, traces, variables, lines_executed, userCodeStartLine, currentToolCall) => {
2257
+ const TS_SMELL = /(^|[^:]):\s*(string|number|boolean|any|unknown|void)\b|\bas\s+(const\b|[A-Z])|\binterface\s+[A-Z]|^\s*type\s+[A-Z]|[a-zA-Z)\]]!\.|<(string|number|boolean)[,>]/m;
2258
+ function parseScript(code, opts) {
2259
+ try {
2260
+ return parse(code, {
2261
+ ecmaVersion: "latest",
2262
+ sourceType: "script",
2263
+ locations: true,
2264
+ allowReturnOutsideFunction: true,
2265
+ allowAwaitOutsideFunction: true,
2266
+ ...opts,
2267
+ onComment: opts === null || opts === void 0 ? void 0 : opts.comments
2268
+ });
2269
+ } catch (err) {
2270
+ if (err instanceof SyntaxError && TS_SMELL.test(code)) err.message += ". The code must be plain JavaScript: do not use TypeScript syntax (type annotations, \"as\" casts, generics, interfaces or type aliases).";
2271
+ throw err;
2272
+ }
2273
+ }
2274
+ /**
2275
+ * Depth-first pre-order walk. `ancestors` is ordered outermost → innermost and
2276
+ * excludes `node` itself; `parent` is `ancestors[ancestors.length - 1]`.
2277
+ */
2278
+ function walk(root, enter) {
2279
+ const ancestors = [];
2280
+ const visit = (node) => {
2281
+ enter(node, ancestors[ancestors.length - 1] ?? null, ancestors);
2282
+ ancestors.push(node);
2283
+ for (const key of Object.keys(node)) {
2284
+ if (key === "loc") continue;
2285
+ const value = node[key];
2286
+ if (Array.isArray(value)) {
2287
+ for (const child of value) if (isNode(child)) visit(child);
2288
+ } else if (isNode(value)) visit(value);
2289
+ }
2290
+ ancestors.pop();
2291
+ };
2292
+ visit(root);
2293
+ }
2294
+ const isNode = (value) => !!value && typeof value === "object" && typeof value.type === "string";
2295
+ const isStatementContainer = (node) => !!node && (node.type === "Program" || node.type === "BlockStatement" || node.type === "StaticBlock");
2296
+ /**
2297
+ * The statement that contains `node`: the outermost ancestor (or the node
2298
+ * itself) whose parent is a statement container.
2299
+ */
2300
+ function enclosingStatement(node, ancestors) {
2301
+ const chain = [...ancestors, node];
2302
+ for (let i = chain.length - 1; i > 0; i--) if (isStatementContainer(chain[i - 1])) return chain[i];
2303
+ return null;
2304
+ }
2305
+ /** The innermost node whose range contains [start, end] */
2306
+ function innermostContaining(ast, start, end) {
2307
+ let best = null;
2308
+ walk(ast, (node) => {
2309
+ if (node.start <= start && node.end >= end) {
2310
+ if (!best || node.start >= best.start && node.end <= best.end) best = node;
2311
+ }
2312
+ });
2313
+ return best;
2314
+ }
2315
+ //#endregion
2316
+ //#region src/compiler/plugins/async-wrapper.ts
2317
+ const Open = "async function __fn__() {";
2318
+ const Close = "}";
2319
+ const USER_CODE_START_MARKER = "/* __LLMZ_USER_CODE_START__ */";
2320
+ const USER_CODE_END_MARKER = "/* __LLMZ_USER_CODE_END__ */";
2321
+ /**
2322
+ * Wraps user code in an async function so top-level `await` and `return` parse,
2323
+ * and so plugins can target the `__fn__` declaration. The wrapper is removed
2324
+ * after transformation — drivers re-wrap the bare statements themselves.
2325
+ */
2326
+ const AsyncWrapper = {
2327
+ preProcessing: (code) => {
2328
+ return `"use strict";
2329
+ ${Open}
2330
+ ${USER_CODE_START_MARKER}
2331
+ ${code}
2332
+ ${USER_CODE_END_MARKER}
2333
+ ${Close}
2334
+ `.trim();
2335
+ },
2336
+ postProcessing: (code) => {
2337
+ code = code.slice(code.indexOf(Open) + 25);
2338
+ code = code.slice(0, code.lastIndexOf(Close));
2339
+ code = code.replace(USER_CODE_START_MARKER, "").replace(USER_CODE_END_MARKER, "");
2340
+ return code.trimEnd();
2341
+ }
2342
+ };
2343
+ //#endregion
2344
+ //#region src/compiler/plugins/dynamic-code.ts
2345
+ const DYNAMIC_GLOBALS = /* @__PURE__ */ new Set([
2346
+ "eval",
2347
+ "Function",
2348
+ "AsyncFunction",
2349
+ "GeneratorFunction",
2350
+ "AsyncGeneratorFunction"
2351
+ ]);
2352
+ const GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
2353
+ "globalThis",
2354
+ "global",
2355
+ "window",
2356
+ "self"
2357
+ ]);
2358
+ const INVOCATION_METHODS = /* @__PURE__ */ new Set([
2359
+ "call",
2360
+ "apply",
2361
+ "bind"
2362
+ ]);
2363
+ function propertyName(node) {
2364
+ if (!node.computed && node.property.type === "Identifier") return node.property.name;
2365
+ if (node.property.type === "Literal" && typeof node.property.value === "string") return node.property.value;
2366
+ }
2367
+ function isConstructorAccess(node) {
2368
+ return node.type === "MemberExpression" && propertyName(node) === "constructor";
2369
+ }
2370
+ function isReference(node, parent) {
2371
+ if (!parent) return true;
2372
+ if (parent.type === "MemberExpression" && parent.property === node && !parent.computed) return false;
2373
+ if (parent.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand) return false;
2374
+ return parent.type !== "VariableDeclarator" || parent.id !== node;
2375
+ }
2376
+ /**
2377
+ * Dynamically generated source bypasses the VM's control-flow instrumentation.
2378
+ * Reject identifiable entry points and constructor aliases. This is a language
2379
+ * restriction, not a security boundary against reflective JavaScript escapes.
2380
+ */
2381
+ function rejectDynamicCode(ast) {
2382
+ const constructorAliases = /* @__PURE__ */ new Set();
2383
+ const globalAliases = new Set(GLOBAL_OBJECTS);
2384
+ const aliasAssignments = [];
2385
+ const reject = () => {
2386
+ throw new Error("Dynamic code generation is not supported in run_javascript. Write JavaScript directly; do not use eval, Function, or async/generator function constructors.");
2387
+ };
2388
+ walk(ast, (node, parent) => {
2389
+ if (node.type === "Identifier" && DYNAMIC_GLOBALS.has(node.name) && isReference(node, parent)) reject();
2390
+ if (node.type === "MemberExpression" && node.object.type === "Identifier" && GLOBAL_OBJECTS.has(node.object.name) && DYNAMIC_GLOBALS.has(propertyName(node) ?? "")) reject();
2391
+ if (node.type === "VariableDeclarator" && node.init) {
2392
+ if (node.id.type === "Identifier") aliasAssignments.push({
2393
+ name: node.id.name,
2394
+ value: node.init
2395
+ });
2396
+ if (node.id.type === "ObjectPattern") for (const property of node.id.properties) {
2397
+ var _property$key, _property$key2, _property$key3, _property$value;
2398
+ if ((property.computed ? (_property$key = property.key) === null || _property$key === void 0 ? void 0 : _property$key.value : ((_property$key2 = property.key) === null || _property$key2 === void 0 ? void 0 : _property$key2.name) ?? ((_property$key3 = property.key) === null || _property$key3 === void 0 ? void 0 : _property$key3.value)) === "constructor" && ((_property$value = property.value) === null || _property$value === void 0 ? void 0 : _property$value.type) === "Identifier") constructorAliases.add(property.value.name);
2399
+ }
2400
+ }
2401
+ if (node.type === "AssignmentExpression" && node.left.type === "Identifier") aliasAssignments.push({
2402
+ name: node.left.name,
2403
+ value: node.right
2404
+ });
2405
+ });
2406
+ let changed = true;
2407
+ while (changed) {
2408
+ changed = false;
2409
+ for (const { name, value } of aliasAssignments) {
2410
+ const fromAlias = value.type === "Identifier" && constructorAliases.has(value.name);
2411
+ if (!constructorAliases.has(name) && (isConstructorAccess(value) || fromAlias)) {
2412
+ constructorAliases.add(name);
2413
+ changed = true;
2414
+ }
2415
+ if (value.type === "Identifier" && globalAliases.has(value.name) && !globalAliases.has(name)) {
2416
+ globalAliases.add(name);
2417
+ changed = true;
2418
+ }
2419
+ }
2420
+ }
2421
+ walk(ast, (node) => {
2422
+ var _node$init;
2423
+ if (node.type === "MemberExpression" && node.object.type === "Identifier" && globalAliases.has(node.object.name) && DYNAMIC_GLOBALS.has(propertyName(node) ?? "")) reject();
2424
+ if (node.type === "VariableDeclarator" && node.id.type === "ObjectPattern" && ((_node$init = node.init) === null || _node$init === void 0 ? void 0 : _node$init.type) === "Identifier" && globalAliases.has(node.init.name)) {
2425
+ if (node.id.properties.some((property) => {
2426
+ var _property$key4, _property$key5, _property$key6;
2427
+ const key = property.computed ? (_property$key4 = property.key) === null || _property$key4 === void 0 ? void 0 : _property$key4.value : ((_property$key5 = property.key) === null || _property$key5 === void 0 ? void 0 : _property$key5.name) ?? ((_property$key6 = property.key) === null || _property$key6 === void 0 ? void 0 : _property$key6.value);
2428
+ return DYNAMIC_GLOBALS.has(key);
2429
+ })) reject();
2430
+ }
2431
+ if (node.type !== "CallExpression" && node.type !== "NewExpression") return;
2432
+ let callee = node.callee;
2433
+ while (callee.type === "MemberExpression" && INVOCATION_METHODS.has(propertyName(callee) ?? "")) callee = callee.object;
2434
+ if (isConstructorAccess(callee) || callee.type === "Identifier" && constructorAliases.has(callee.name)) reject();
2435
+ });
2436
+ }
2437
+ //#endregion
2438
+ //#region src/compiler/plugins/line-tracking.ts
2439
+ const LineTrackingFnIdentifier = "__track__";
2440
+ const TRACKED_TYPES = /* @__PURE__ */ new Set([
2441
+ "FunctionDeclaration",
2442
+ "MethodDefinition",
2443
+ "ReturnStatement",
2444
+ "AwaitExpression",
2445
+ "ForOfStatement",
2446
+ "CallExpression",
2447
+ "UnaryExpression",
2448
+ "VariableDeclaration",
2449
+ "AssignmentExpression"
2450
+ ]);
2451
+ const SKIPPED_PARENT_TYPES = /* @__PURE__ */ new Set([
2452
+ "ArrowFunctionExpression",
2453
+ "Property",
2454
+ "AwaitExpression",
2455
+ "UnaryExpression",
2456
+ "ReturnStatement",
2457
+ "ForOfStatement",
2458
+ "ForStatement",
2459
+ "ForInStatement",
2460
+ "VariableDeclaration",
2461
+ "BinaryExpression",
2462
+ "LogicalExpression"
2463
+ ]);
2464
+ /**
2465
+ * Inserts a `__track__(<line>)` call before the statement containing each
2466
+ * tracked node — at most one per source line.
2467
+ */
2468
+ function applyLineTracking(ctx) {
2469
+ const trackedLines = /* @__PURE__ */ new Set();
2470
+ walk(ctx.ast, (node, parent, ancestors) => {
2471
+ if (!parent || !node.loc) return;
2472
+ if (!TRACKED_TYPES.has(node.type) && parent.type !== "BlockStatement") return;
2473
+ const line = node.loc.start.line;
2474
+ if (trackedLines.has(line) || SKIPPED_PARENT_TYPES.has(parent.type)) return;
2475
+ const statement = enclosingStatement(node, ancestors);
2476
+ if (!statement) return;
2477
+ trackedLines.add(line);
2478
+ ctx.ms.appendLeft(statement.start, `${LineTrackingFnIdentifier}(${line});`);
2479
+ });
2480
+ }
2481
+ //#endregion
2482
+ //#region src/compiler/plugins/replace-comment.ts
2483
+ const CommentFnIdentifier = "__comment__";
2484
+ const MARKER_TAGS = [USER_CODE_START_MARKER, USER_CODE_END_MARKER].map((m) => m.replace(/\/\*|\*\/|\s/g, ""));
2485
+ /** Blanks a range, keeping newlines so line numbers are preserved */
2486
+ const blank = (ctx, start, end) => {
2487
+ ctx.ms.update(start, end, ctx.code.slice(start, end).replace(/[^\n]/g, " "));
2488
+ };
2489
+ /**
2490
+ * Replaces comments at statement position with `__comment__("<text>", <line>)`
2491
+ * calls so the agent's inline "thinking" comments show up as traces at runtime.
2492
+ * Comments inside expressions and the user-code markers are blanked.
2493
+ */
2494
+ function applyCommentReplacement(ctx) {
2495
+ for (const comment of ctx.comments) {
2496
+ const text = comment.value.trim();
2497
+ if (MARKER_TAGS.some((tag) => text.includes(tag))) {
2498
+ blank(ctx, comment.start, comment.end);
2499
+ continue;
2500
+ }
2501
+ const container = innermostContaining(ctx.ast, comment.start, comment.end);
2502
+ if (isStatementContainer(container)) {
2503
+ const newlines = ctx.code.slice(comment.start, comment.end).replace(/[^\n]/g, "");
2504
+ ctx.ms.update(comment.start, comment.end, `;${CommentFnIdentifier}(${JSON.stringify(text)}, ${comment.loc.start.line});${newlines}`);
2505
+ } else blank(ctx, comment.start, comment.end);
2506
+ }
2507
+ }
2508
+ //#endregion
2509
+ //#region src/compiler/plugins/return-async.ts
2510
+ /**
2511
+ * Awaits the last expression without changing whether the program returns it.
2512
+ * The isolated VM cannot return a pending Promise:
2513
+ * - `return expr` → `return await (expr)`
2514
+ * - a trailing `call()` / `await call()` statement → `await (…)`
2515
+ *
2516
+ * Discarded values must stay discarded, especially terminal decision receipts.
2517
+ *
2518
+ * The prefix must be applied before, and the suffix after, all other edits so
2519
+ * they wrap around the tool-call instrumentation.
2520
+ */
2521
+ function planLastLineInstrumentation(ast) {
2522
+ const fn = ast.body.find((node) => {
2523
+ var _id;
2524
+ return node.type === "FunctionDeclaration" && ((_id = node.id) === null || _id === void 0 ? void 0 : _id.name) === "__fn__";
2525
+ });
2526
+ if (!fn) return null;
2527
+ const statements = fn.body.body;
2528
+ const last = statements[statements.length - 1];
2529
+ if (!last) return null;
2530
+ if (last.type === "ReturnStatement") {
2531
+ if (!last.argument) return null;
2532
+ return {
2533
+ prefixPos: last.argument.start,
2534
+ prefix: "await (",
2535
+ suffixPos: last.argument.end,
2536
+ suffix: ")"
2537
+ };
2538
+ }
2539
+ if (last.type === "ExpressionStatement" && (last.expression.type === "CallExpression" || last.expression.type === "AwaitExpression")) return {
2540
+ prefixPos: last.expression.start,
2541
+ prefix: "await (",
2542
+ suffixPos: last.expression.end,
2543
+ suffix: ")"
2544
+ };
2545
+ return null;
2546
+ }
2547
+ //#endregion
2548
+ //#region src/compiler/plugins/termination.ts
2549
+ const TerminationGuardIdentifier = "__llmz_guard";
2550
+ const TerminationCheckpointIdentifier = "__llmz_checkpoint";
2551
+ const FUNCTIONS = /* @__PURE__ */ new Set([
2552
+ "FunctionDeclaration",
2553
+ "FunctionExpression",
2554
+ "ArrowFunctionExpression"
2555
+ ]);
2556
+ const INTERNAL_CALLS = /* @__PURE__ */ new Set([
2557
+ "__var__",
2558
+ "__track__",
2559
+ "__comment__"
2560
+ ]);
2561
+ /**
2562
+ * A terminal host call unwinds ordinary JavaScript. User error handlers must not
2563
+ * consume that control flow, and async continuations must check before resuming.
2564
+ */
2565
+ function applyTerminationGuards(ctx) {
2566
+ const suffixes = [];
2567
+ const wrapper = ctx.ast.body.find((node) => {
2568
+ var _id;
2569
+ return node.type === "FunctionDeclaration" && ((_id = node.id) === null || _id === void 0 ? void 0 : _id.name) === "__fn__";
2570
+ });
2571
+ const guard = `${TerminationGuardIdentifier}();`;
2572
+ const wrap = (node, prefix) => {
2573
+ ctx.ms.appendLeft(node.start, prefix);
2574
+ suffixes.unshift(() => ctx.ms.appendRight(node.end, ")"));
2575
+ };
2576
+ const isCaptureGetter = (node, parent) => (parent === null || parent === void 0 ? void 0 : parent.type) === "CallExpression" && parent.callee.name === "__var__" && parent.arguments[1] === node;
2577
+ walk(ctx.ast, (node, parent, ancestors) => {
2578
+ if (isCaptureGetter(node, parent) || ancestors.some((ancestor, index) => isCaptureGetter(ancestor, ancestors[index - 1] ?? null))) return;
2579
+ if (node.type === "CallExpression" && node.callee.type === "Identifier" && INTERNAL_CALLS.has(node.callee.name)) return;
2580
+ if (node.type === "CatchClause") {
2581
+ ctx.ms.appendLeft(node.body.start + 1, guard);
2582
+ return;
2583
+ }
2584
+ if (node.type === "TryStatement" && node.finalizer) ctx.ms.appendLeft(node.finalizer.start + 1, guard);
2585
+ if (FUNCTIONS.has(node.type)) {
2586
+ if (node === wrapper) return;
2587
+ if (node.body.type === "BlockStatement") ctx.ms.appendLeft(node.body.start + 1, guard);
2588
+ else wrap(node.body, `(${TerminationGuardIdentifier}(), `);
2589
+ }
2590
+ if (node.type === "AssignmentPattern") wrap(node.right, `(${TerminationGuardIdentifier}(), `);
2591
+ if ([
2592
+ "AwaitExpression",
2593
+ "CallExpression",
2594
+ "NewExpression",
2595
+ "TaggedTemplateExpression"
2596
+ ].includes(node.type)) {
2597
+ wrap(node, `(${TerminationGuardIdentifier}(), ${TerminationCheckpointIdentifier}(`);
2598
+ suffixes.unshift(() => ctx.ms.appendRight(node.end, ")"));
2599
+ }
2600
+ if (node.type === "AssignmentExpression" || node.type === "UpdateExpression" || node.type === "UnaryExpression" && node.operator === "delete") wrap(node, `(${TerminationGuardIdentifier}(), `);
2601
+ });
2602
+ return () => suffixes.forEach((apply) => apply());
2603
+ }
2604
+ //#endregion
2605
+ //#region src/compiler/plugins/tool-resolution.ts
2606
+ const MissingToolIdentifier = "__llmz_missing_tool";
2607
+ /** Diagnose missing free callables at the lookup, before evaluating their arguments. */
2608
+ function applyToolResolution({ ast, ms }) {
2609
+ const declared = /* @__PURE__ */ new Set();
2610
+ const collect = (pattern) => {
2611
+ walk(pattern, (node) => {
2612
+ if (node.type === "Identifier") declared.add(node.name);
2613
+ });
2614
+ };
2615
+ walk(ast, (node) => {
2616
+ if (node.type === "VariableDeclarator") collect(node.id);
2617
+ else if ([
2618
+ "FunctionDeclaration",
2619
+ "FunctionExpression",
2620
+ "ArrowFunctionExpression"
2621
+ ].includes(node.type)) {
2622
+ if (node.id) collect(node.id);
2623
+ for (const param of node.params) collect(param);
2624
+ } else if (node.type === "CatchClause" && node.param) collect(node.param);
2625
+ else if (node.type === "ClassDeclaration" && node.id) collect(node.id);
2626
+ });
2627
+ walk(ast, (node) => {
2628
+ if (node.type !== "CallExpression" || node.optional || node.callee.type !== "Identifier") return;
2629
+ const name = node.callee.name;
2630
+ if (declared.has(name) || name.startsWith("__")) return;
2631
+ ms.overwrite(node.callee.start, node.callee.end, `(typeof ${name} === "undefined" ? ${MissingToolIdentifier}(${JSON.stringify(name)}) : ${name})`);
2632
+ });
2633
+ }
2634
+ //#endregion
2635
+ //#region src/compiler/plugins/variable-extraction.ts
2636
+ const VariableTrackingFnIdentifier = "__var__";
2637
+ const FUNCTION_TYPES = /* @__PURE__ */ new Set([
2638
+ "FunctionDeclaration",
2639
+ "FunctionExpression",
2640
+ "ArrowFunctionExpression"
2641
+ ]);
2642
+ const RESERVED = RESERVED_RUNTIME_NAMES;
2643
+ function names(id) {
2644
+ if (!id) return [];
2645
+ if (id.type === "Identifier") return [id.name];
2646
+ if (id.type === "RestElement") return names(id.argument);
2647
+ if (id.type === "AssignmentPattern") return names(id.left);
2648
+ if (id.type === "ObjectPattern") return id.properties.flatMap((prop) => names(prop.type === "RestElement" ? prop.argument : prop.value));
2649
+ if (id.type === "ArrayPattern") return id.elements.flatMap(names);
2650
+ return [];
2651
+ }
2652
+ function rootName(node) {
2653
+ if (node.type === "Identifier") return node.name;
2654
+ if (node.type === "MemberExpression") return rootName(node.object);
2655
+ }
2656
+ /** Capture only session-level bindings, and record completed writes without changing expression values. */
2657
+ function applyVariableTracking(ctx, variables, deferSuffixes = false) {
2658
+ const suffixes = [];
2659
+ const wrapper = ctx.ast.body.find((node) => {
2660
+ var _node$id;
2661
+ return node.type === "FunctionDeclaration" && ((_node$id = node.id) === null || _node$id === void 0 ? void 0 : _node$id.name) === "__fn__";
2662
+ });
2663
+ const root = (wrapper === null || wrapper === void 0 ? void 0 : wrapper.body) ?? ctx.ast;
2664
+ const scopes = /* @__PURE__ */ new Map();
2665
+ const sessionDeclarations = /* @__PURE__ */ new Set();
2666
+ const varBindings = /* @__PURE__ */ new Set();
2667
+ const scope = (node) => {
2668
+ if (!scopes.has(node)) scopes.set(node, /* @__PURE__ */ new Set());
2669
+ return scopes.get(node);
2670
+ };
2671
+ const owner = (ancestors, isVar = false) => [...ancestors].reverse().find((node) => node === root || node.type === "Program" || node.type === "StaticBlock" || FUNCTION_TYPES.has(node.type) || !isVar && (node.type === "BlockStatement" || node.type === "SwitchStatement" || node.type === "CatchClause" || node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement")) ?? root;
2672
+ walk(ctx.ast, (node, parent, ancestors) => {
2673
+ let declared = [];
2674
+ if (node.type === "VariableDeclarator") {
2675
+ declared = names(node.id);
2676
+ const bindingScope = owner(ancestors, (parent === null || parent === void 0 ? void 0 : parent.kind) === "var");
2677
+ for (const name of declared) scope(bindingScope).add(name);
2678
+ if (bindingScope === root) {
2679
+ sessionDeclarations.add(node);
2680
+ for (const name of declared.filter((name) => !name.startsWith("__"))) {
2681
+ variables.add(name);
2682
+ if ((parent === null || parent === void 0 ? void 0 : parent.kind) === "var") varBindings.add(name);
2683
+ }
2684
+ }
2685
+ } else if (FUNCTION_TYPES.has(node.type)) {
2686
+ declared = node.params.flatMap(names);
2687
+ if (node.id) declared.push(node.id.name);
2688
+ for (const name of declared) scope(node).add(name);
2689
+ } else if (node.type === "CatchClause" && node.param) {
2690
+ declared = names(node.param);
2691
+ for (const name of declared) scope(node).add(name);
2692
+ }
2693
+ for (const name of declared) if (RESERVED.has(name)) throw new ReservedIdentifierError(name, "variable", false, `${name} is reserved for runtime memory`);
2694
+ });
2695
+ const eligible = (name, ancestors) => {
2696
+ if (name.startsWith("__")) return false;
2697
+ for (const ancestor of [...ancestors].reverse()) {
2698
+ var _scopes$get;
2699
+ if (ancestor === root) return true;
2700
+ if ((_scopes$get = scopes.get(ancestor)) === null || _scopes$get === void 0 ? void 0 : _scopes$get.has(name)) return false;
2701
+ }
2702
+ return true;
2703
+ };
2704
+ const wrap = (node, bindingNames, kind = "assignment") => {
2705
+ if (!bindingNames.length) return;
2706
+ ctx.ms.appendLeft(node.start, bindingNames.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}), (`).join(""));
2707
+ suffixes.unshift(() => ctx.ms.appendRight(node.end, bindingNames.map(() => `), ${JSON.stringify(kind)})`).join("")));
2708
+ };
2709
+ const varGetters = [...varBindings].map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}), undefined, "initialize");`).join("");
2710
+ const entry = root.body.find((node) => !node.directive);
2711
+ if (entry && varGetters) ctx.ms.appendLeft(entry.start, varGetters);
2712
+ walk(ctx.ast, (node, parent, ancestors) => {
2713
+ if (node.type === "VariableDeclaration" && parent === root && node.kind !== "var") {
2714
+ const declared = node.declarations.flatMap((declaration) => names(declaration.id)).filter((name) => variables.has(name));
2715
+ ctx.ms.appendLeft(node.start, declared.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}), undefined, "initialize");`).join(""));
2716
+ }
2717
+ if (node.type === "VariableDeclarator" && sessionDeclarations.has(node)) {
2718
+ const declared = names(node.id).filter((name) => variables.has(name) && eligible(name, ancestors));
2719
+ if (node.init) wrap(node.init, declared);
2720
+ else if (parent && parent.kind !== "var") {
2721
+ const trackers = declared.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`).join("");
2722
+ ctx.ms.appendRight(parent.end, `${ctx.code[parent.end - 1] === ";" ? "" : ";"}${trackers}`);
2723
+ }
2724
+ }
2725
+ if ((node.type === "ForOfStatement" || node.type === "ForInStatement") && node.left.type === "VariableDeclaration") {
2726
+ const declared = node.left.declarations.filter((declaration) => sessionDeclarations.has(declaration)).flatMap((declaration) => names(declaration.id)).filter((name) => eligible(name, ancestors));
2727
+ if (declared.length) {
2728
+ const trackers = declared.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`).join("");
2729
+ ctx.ms.appendLeft(node.body.start, `{${trackers}`);
2730
+ suffixes.unshift(() => ctx.ms.appendRight(node.body.end, "}"));
2731
+ }
2732
+ }
2733
+ if (node.type === "AssignmentExpression" || node.type === "UpdateExpression" || node.type === "UnaryExpression" && node.operator === "delete") {
2734
+ const target = node.left ?? node.argument;
2735
+ const roots = target.type === "MemberExpression" ? [rootName(target)].filter(Boolean) : names(target);
2736
+ for (const name of roots) if (RESERVED.has(name)) throw new AssignmentError(`${name} is read-only runtime memory`);
2737
+ const tracked = [...new Set(roots)].filter((name) => eligible(name, ancestors));
2738
+ const kind = target.type === "MemberExpression" ? "mutation" : "assignment";
2739
+ if ([
2740
+ "||=",
2741
+ "&&=",
2742
+ "??="
2743
+ ].includes(node.operator)) {
2744
+ if (target.type === "Identifier" && tracked.length) {
2745
+ const name = tracked[0];
2746
+ const operator = node.operator.slice(0, -1);
2747
+ const lineBreaks = ctx.code.slice(target.end, node.right.start).replace(/[^\n]/g, "");
2748
+ ctx.ms.appendLeft(node.start, "(");
2749
+ ctx.ms.overwrite(target.end, node.right.start, ` ${operator} ${lineBreaks}`);
2750
+ ctx.ms.appendLeft(node.right.start, `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}), (${name} = (`);
2751
+ suffixes.unshift(() => ctx.ms.appendRight(node.end, `)), "assignment"))`));
2752
+ }
2753
+ return;
2754
+ }
2755
+ wrap(node, tracked, kind);
2756
+ }
2757
+ });
2758
+ const finish = () => suffixes.forEach((apply) => apply());
2759
+ if (!deferSuffixes) finish();
2760
+ return finish;
2761
+ }
2762
+ //#endregion
2763
+ //#region src/compiler/compiler.ts
2764
+ const Identifiers = {
2765
+ ConsoleObjIdentifier: "console",
2766
+ LineTrackingFnIdentifier,
2767
+ VariableTrackingFnIdentifier,
2768
+ CommentFnIdentifier
2769
+ };
2770
+ /**
2771
+ * Compiles the agent's generated JavaScript for VM execution:
2772
+ *
2773
+ * 1. wraps it in an async `__fn__` so top-level `await`/`return` parse
2774
+ * 2. instruments it in a single parse + text-edit pass:
2775
+ * line tracking, last-line awaiting, comment tracing and variable tracking
2776
+ * 3. unwraps it — the VM drivers re-wrap the bare statements themselves
2777
+ *
2778
+ * All edits preserve line numbers 1:1 with the wrapped source, so positions
2779
+ * reported at runtime map straight back to the user code.
2780
+ */
2781
+ function compile(code) {
2782
+ try {
2783
+ return compileProgram(code);
2784
+ } catch (cause) {
2785
+ if (isLLMzError(cause)) throw cause;
2786
+ throw new InvalidCodeError(cause instanceof Error ? cause.message : String(cause), code, { cause });
2787
+ }
2788
+ }
2789
+ function compileProgram(code) {
2790
+ const wrapped = AsyncWrapper.preProcessing(code);
2791
+ const comments = [];
2792
+ const ast = parseScript(wrapped, { comments });
2793
+ rejectDynamicCode(ast);
2794
+ const variables = /* @__PURE__ */ new Set();
2795
+ const lastLine = planLastLineInstrumentation(ast);
2796
+ const msMarkers = new MagicString(wrapped);
2797
+ if (lastLine) {
2798
+ msMarkers.appendLeft(lastLine.prefixPos, lastLine.prefix);
2799
+ msMarkers.appendRight(lastLine.suffixPos, lastLine.suffix);
2800
+ }
2801
+ const codeWithMarkers = msMarkers.toString();
2802
+ const ms = new MagicString(wrapped);
2803
+ const ctx = {
2804
+ code: wrapped,
2805
+ ms,
2806
+ ast,
2807
+ comments
2808
+ };
2809
+ applyToolResolution(ctx);
2810
+ applyLineTracking(ctx);
2811
+ if (lastLine) ms.appendLeft(lastLine.prefixPos, lastLine.prefix);
2812
+ const finishVariableTracking = applyVariableTracking(ctx, variables, true);
2813
+ applyCommentReplacement(ctx);
2814
+ finishVariableTracking();
2815
+ if (lastLine) ms.appendRight(lastLine.suffixPos, lastLine.suffix);
2816
+ const instrumented = ms.toString();
2817
+ const terminationSource = new MagicString(instrumented);
2818
+ applyTerminationGuards({
2819
+ code: instrumented,
2820
+ ms: terminationSource,
2821
+ ast: parseScript(instrumented),
2822
+ comments: []
2823
+ })();
2824
+ const firstMap = ms.generateMap({
2825
+ hires: true,
2826
+ source: "<anonymous>"
2827
+ });
2828
+ const secondMap = terminationSource.generateMap({
2829
+ hires: true,
2830
+ source: "<instrumented>"
2831
+ });
2832
+ const map = import_source_map.SourceMapGenerator.fromSourceMap(new import_source_map.SourceMapConsumer(JSON.parse(secondMap.toString())));
2833
+ map.applySourceMap(new import_source_map.SourceMapConsumer(JSON.parse(firstMap.toString())), "<instrumented>");
2834
+ return {
2835
+ code: AsyncWrapper.postProcessing(terminationSource.toString()),
2836
+ codeWithMarkers,
2837
+ map: map.toJSON(),
2838
+ variables
2839
+ };
2840
+ }
2841
+ //#endregion
2842
+ //#region src/vm/errors.ts
2843
+ const handleErrorQuickJS = (err, code, _consumer, traces, variables, lines_executed, userCodeStartLine, recordTrace) => {
2214
2844
  err = Signals.maybeDeserializeError(err);
2215
2845
  const lines = code.split("\n");
2216
2846
  const stackTrace = err.stack || "";
@@ -2235,9 +2865,9 @@ const handleErrorQuickJS = (err, code, _consumer, traces, variables, lines_execu
2235
2865
  column: whiteSpacesCount
2236
2866
  });
2237
2867
  }
2238
- return formatError(err, lines, matches, traces, variables, lines_executed, currentToolCall, code);
2868
+ return formatError(err, lines, matches, traces, variables, lines_executed, code, recordTrace);
2239
2869
  };
2240
- const handleErrorNode = (err, code, consumer, traces, variables, _lines_executed, currentToolCall) => {
2870
+ const handleErrorNode = (err, code, consumer, recordTrace, variables, _lines_executed, lastExecutedLine) => {
2241
2871
  err = Signals.maybeDeserializeError(err);
2242
2872
  const lines = code.split("\n");
2243
2873
  const stackTrace = err.stack || "";
@@ -2260,32 +2890,39 @@ const handleErrorNode = (err, code, consumer, traces, variables, _lines_executed
2260
2890
  column: Math.min(minColumn, Number(x[2]))
2261
2891
  };
2262
2892
  });
2893
+ if (!matches.length && lastExecutedLine !== void 0) {
2894
+ const sourceLine = lines[lastExecutedLine - LINE_OFFSET] ?? "";
2895
+ matches.push({
2896
+ line: lastExecutedLine,
2897
+ column: sourceLine.length - sourceLine.trimStart().length
2898
+ });
2899
+ }
2263
2900
  const { debugUserCode, truncatedCode } = buildDebugCode(lines, matches);
2264
- if (err instanceof VMSignal) {
2901
+ if (VMSignal.is(err)) {
2265
2902
  err.stack = debugUserCode;
2266
2903
  err.truncatedCode = truncatedCode;
2267
2904
  err.variables = mapValues(variables, (getter) => isFunction(getter) ? getter() : getter);
2268
- err.toolCall = currentToolCall;
2269
2905
  throw err;
2270
2906
  } else {
2271
2907
  var _matches$, _matches$2;
2272
- traces.push({
2908
+ recordTrace({
2273
2909
  type: "code_execution_exception",
2274
2910
  position: [((_matches$ = matches[0]) === null || _matches$ === void 0 ? void 0 : _matches$.line) ?? 0, ((_matches$2 = matches[0]) === null || _matches$2 === void 0 ? void 0 : _matches$2.column) ?? 0],
2275
2911
  message: err.message,
2276
2912
  stackTrace: debugUserCode,
2277
2913
  started_at: Date.now()
2278
2914
  });
2279
- throw new CodeExecutionError(err.message, code, debugUserCode);
2915
+ const originalErrorName = CodeExecutionError.is(err) ? err.originalErrorName : err.name;
2916
+ throw new CodeExecutionError(err.message, code, debugUserCode, originalErrorName, err);
2280
2917
  }
2281
2918
  };
2282
2919
  const handleCatch = (err, traces, variables, lines_executed) => {
2283
2920
  err = Signals.maybeDeserializeError(err);
2284
2921
  return {
2285
- success: err instanceof VMSignal ? true : false,
2922
+ success: VMSignal.is(err) ? true : false,
2286
2923
  variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
2287
2924
  error: err,
2288
- signal: err instanceof VMSignal ? err : void 0,
2925
+ signal: VMSignal.is(err) ? err : void 0,
2289
2926
  traces,
2290
2927
  lines_executed: Array.from(lines_executed)
2291
2928
  };
@@ -2315,18 +2952,16 @@ function buildDebugCode(lines, matches) {
2315
2952
  } else appendCode(` ${paddedLineNumber} | ${line}\n`);
2316
2953
  }
2317
2954
  return {
2318
- debugUserCode: cleanStackTrace(debugUserCode).trim(),
2319
- truncatedCode: cleanStackTrace(truncatedCode).trim()
2955
+ debugUserCode: debugUserCode.trim(),
2956
+ truncatedCode: truncatedCode.trim()
2320
2957
  };
2321
2958
  }
2322
- function formatError(err, lines, matches, traces, variables, lines_executed, currentToolCall, code) {
2959
+ function formatError(err, lines, matches, traces, variables, lines_executed, code, recordTrace) {
2323
2960
  const { debugUserCode, truncatedCode } = buildDebugCode(lines, matches);
2324
- if (err instanceof VMSignal) {
2325
- const signalError = err;
2326
- signalError.stack = debugUserCode;
2327
- signalError.truncatedCode = truncatedCode;
2328
- signalError.variables = mapValues(variables, (getter) => isFunction(getter) ? getter() : getter);
2329
- signalError.toolCall = currentToolCall;
2961
+ if (VMSignal.is(err)) {
2962
+ err.stack = debugUserCode;
2963
+ err.truncatedCode = truncatedCode;
2964
+ err.variables = mapValues(variables, (getter) => isFunction(getter) ? getter() : getter);
2330
2965
  return {
2331
2966
  success: true,
2332
2967
  variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
@@ -2335,14 +2970,15 @@ function formatError(err, lines, matches, traces, variables, lines_executed, cur
2335
2970
  };
2336
2971
  } else {
2337
2972
  var _matches$3, _matches$4;
2338
- traces.push({
2973
+ recordTrace({
2339
2974
  type: "code_execution_exception",
2340
2975
  position: [((_matches$3 = matches[0]) === null || _matches$3 === void 0 ? void 0 : _matches$3.line) ?? 0, ((_matches$4 = matches[0]) === null || _matches$4 === void 0 ? void 0 : _matches$4.column) ?? 0],
2341
2976
  message: err.message,
2342
2977
  stackTrace: debugUserCode,
2343
2978
  started_at: Date.now()
2344
2979
  });
2345
- const codeError = new CodeExecutionError(err.message, code, debugUserCode);
2980
+ const originalErrorName = CodeExecutionError.is(err) ? err.originalErrorName : err.name;
2981
+ const codeError = new CodeExecutionError(err.message, code, debugUserCode, originalErrorName, err);
2346
2982
  const deserializedError = Signals.maybeDeserializeError(codeError);
2347
2983
  return {
2348
2984
  success: false,
@@ -2354,21 +2990,48 @@ function formatError(err, lines, matches, traces, variables, lines_executed, cur
2354
2990
  }
2355
2991
  }
2356
2992
  //#endregion
2993
+ //#region src/vm/types.ts
2994
+ /** Host-only lifecycle hook; symbols are not copied into the generated program's globals. */
2995
+ const VM_PROGRAM_COMPLETE = Symbol("llmz.programComplete");
2996
+ const VM_TERMINATION = Symbol("llmz.termination");
2997
+ const VM_ON_ERROR = Symbol("llmz.onError");
2998
+ //#endregion
2357
2999
  //#region src/vm/instrument.ts
2358
3000
  const USER_CODE_MARKER_TAG_START = "__LLMZ_USER_CODE_START__";
2359
3001
  const USER_CODE_MARKER_TAG_END = "__LLMZ_USER_CODE_END__";
2360
3002
  const NO_TRACKING = [
2361
3003
  Identifiers.CommentFnIdentifier,
2362
- Identifiers.ToolCallTrackerFnIdentifier,
2363
- Identifiers.ToolTrackerRetIdentifier,
2364
3004
  Identifiers.VariableTrackingFnIdentifier,
2365
- Identifiers.ConsoleObjIdentifier
3005
+ Identifiers.ConsoleObjIdentifier,
3006
+ TerminationCheckpointIdentifier,
3007
+ TerminationGuardIdentifier
2366
3008
  ];
2367
- function instrumentContext(context, transformed, traces, variables, lines_executed, consumer, userCodeStartLine) {
2368
- const state = { currentToolCall: void 0 };
3009
+ function instrumentContext(context, transformed, recordTrace, variables, lines_executed, consumer, userCodeStartLine, memoryNames = []) {
3010
+ const state = {
3011
+ lastExecutedLine: void 0,
3012
+ memoryNames: /* @__PURE__ */ new Set([...memoryNames, ...transformed.variables]),
3013
+ variableWrites: [],
3014
+ captureErrors: []
3015
+ };
3016
+ context[MissingToolIdentifier] = (name) => {
3017
+ var _context$VM_ON_ERROR;
3018
+ const error = new UnknownToolError(name, Object.keys(context).filter((key) => !key.startsWith("__") && typeof context[key] === "function"));
3019
+ (_context$VM_ON_ERROR = context[VM_ON_ERROR]) === null || _context$VM_ON_ERROR === void 0 || _context$VM_ON_ERROR.call(context, error);
3020
+ throw error;
3021
+ };
3022
+ context[TerminationGuardIdentifier] = () => {
3023
+ var _context$VM_TERMINATI;
3024
+ return (_context$VM_TERMINATI = context[VM_TERMINATION]) === null || _context$VM_TERMINATI === void 0 ? void 0 : _context$VM_TERMINATI.check();
3025
+ };
3026
+ context[TerminationCheckpointIdentifier] = (value) => {
3027
+ var _context$VM_TERMINATI2;
3028
+ if (value instanceof Promise) Promise.prototype.then.call(value, void 0, () => {});
3029
+ (_context$VM_TERMINATI2 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI2 === void 0 || _context$VM_TERMINATI2.check();
3030
+ return value;
3031
+ };
2369
3032
  context[Identifiers.CommentFnIdentifier] = (comment, line) => {
2370
3033
  if (comment.includes(USER_CODE_MARKER_TAG_START) || comment.includes(USER_CODE_MARKER_TAG_END)) return;
2371
- traces.push({
3034
+ recordTrace({
2372
3035
  type: "comment",
2373
3036
  comment,
2374
3037
  line,
@@ -2381,35 +3044,33 @@ function instrumentContext(context, transformed, traces, variables, lines_execut
2381
3044
  column: 0
2382
3045
  }).line ?? line;
2383
3046
  const userCodeLine = Math.max(1, mappedLine - userCodeStartLine);
3047
+ state.lastExecutedLine = userCodeLine;
2384
3048
  lines_executed.set(userCodeLine, (lines_executed.get(userCodeLine) ?? 0) + 1);
2385
3049
  };
2386
- context[Identifiers.VariableTrackingFnIdentifier] = (name, getter) => {
2387
- if (NO_TRACKING.includes(name)) return;
3050
+ context[Identifiers.VariableTrackingFnIdentifier] = (name, getter, result, kind = "assignment") => {
3051
+ if (NO_TRACKING.includes(name) || !state.memoryNames.has(name)) return result;
3052
+ if (kind !== "initialize" && kind !== "read") state.variableWrites.push({
3053
+ name,
3054
+ timestamp: Date.now(),
3055
+ kind
3056
+ });
2388
3057
  variables[name] = () => {
2389
3058
  try {
2390
- const value = getter();
2391
- if (typeof value === "function") return "[[non-primitive]]";
2392
- return value;
2393
- } catch {
2394
- return "[[non-primitive]]";
3059
+ return getter();
3060
+ } catch (err) {
3061
+ if (!state.captureErrors.some((entry) => entry.name === name)) state.captureErrors.push({
3062
+ name,
3063
+ reason: err instanceof Error ? err.message : String(err)
3064
+ });
3065
+ return;
2395
3066
  }
2396
3067
  };
2397
- };
2398
- context[Identifiers.ToolCallTrackerFnIdentifier] = (callId, type, outputOrError) => {
2399
- const temp = Signals.maybeDeserializeError(outputOrError === null || outputOrError === void 0 ? void 0 : outputOrError.message);
2400
- if (type === "end" && temp instanceof SnapshotSignal && (temp === null || temp === void 0 ? void 0 : temp.toolCall)) {
2401
- var _transformed$toolCall;
2402
- state.currentToolCall = {
2403
- ...temp.toolCall,
2404
- assignment: (_transformed$toolCall = transformed.toolCalls.get(callId)) === null || _transformed$toolCall === void 0 ? void 0 : _transformed$toolCall.assignment
2405
- };
2406
- }
3068
+ return result;
2407
3069
  };
2408
3070
  context[Identifiers.ConsoleObjIdentifier] = { log: (...args) => {
2409
- const message = args.shift();
2410
- traces.push({
3071
+ recordTrace({
2411
3072
  type: "log",
2412
- message,
3073
+ message: args.shift(),
2413
3074
  args,
2414
3075
  started_at: Date.now()
2415
3076
  });
@@ -2424,14 +3085,44 @@ function findUserCodeStartLine(transformed) {
2424
3085
  }
2425
3086
  return -1;
2426
3087
  }
3088
+ /** Drop unsupported captures explicitly instead of presenting lossy placeholders as data. */
3089
+ function finalizeMemoryCapture(result, state) {
3090
+ for (const [name, value] of Object.entries(result.variables)) try {
3091
+ result.variables[name] = cloneMemoryValue(value);
3092
+ } catch (err) {
3093
+ if (!state.captureErrors.some((entry) => entry.name === name)) state.captureErrors.push({
3094
+ name,
3095
+ reason: err instanceof Error ? err.message : String(err)
3096
+ });
3097
+ }
3098
+ for (const failure of state.captureErrors) {
3099
+ var _result$signal;
3100
+ delete result.variables[failure.name];
3101
+ if ((_result$signal = result.signal) === null || _result$signal === void 0 ? void 0 : _result$signal.variables) delete result.signal.variables[failure.name];
3102
+ }
3103
+ if (result.success && !result.signal) try {
3104
+ result.return_value = cloneMemoryValue(result.return_value);
3105
+ } catch (err) {
3106
+ if (!state.captureErrors.some((entry) => entry.name === "$return")) state.captureErrors.push({
3107
+ name: "$return",
3108
+ reason: err instanceof Error ? err.message : String(err)
3109
+ });
3110
+ result.return_value = void 0;
3111
+ }
3112
+ return {
3113
+ ...result,
3114
+ variableWrites: state.variableWrites,
3115
+ captureErrors: state.captureErrors
3116
+ };
3117
+ }
2427
3118
  //#endregion
2428
3119
  //#region src/vm/drivers/node.ts
2429
3120
  var NodeDriver = class {
2430
3121
  async execute(ctx) {
2431
- const { transformed, consumer, context, traces, code, lines_executed, variables } = ctx;
2432
- const state = instrumentContext(context, transformed, traces, variables, lines_executed, consumer, 0);
3122
+ const { transformed, consumer, context, traces, recordTrace, code, lines_executed, variables } = ctx;
3123
+ const state = instrumentContext(context, transformed, recordTrace, variables, lines_executed, consumer, findUserCodeStartLine(transformed), ctx.memoryNames);
2433
3124
  const AsyncFunction = async function() {}.constructor;
2434
- return await (async () => {
3125
+ return finalizeMemoryCapture(await (async () => {
2435
3126
  const descriptors = Object.getOwnPropertyDescriptors(context);
2436
3127
  const topLevelProperties = Object.keys(descriptors).filter((x) => !NO_TRACKING.includes(x) && descriptors[x] && typeof descriptors[x].value !== "function" && typeof descriptors[x].value !== "object");
2437
3128
  const __report = (name, value) => {
@@ -2439,21 +3130,59 @@ var NodeDriver = class {
2439
3130
  };
2440
3131
  context.__report = __report;
2441
3132
  const reportAll = topLevelProperties.map((x) => `__report("${x}", ${x})`).join(";");
2442
- const wrapper = `"use strict"; try { ${`let __${Identifiers.LineTrackingFnIdentifier} = ${Identifiers.LineTrackingFnIdentifier}; ${Identifiers.LineTrackingFnIdentifier} = function(line) { ${reportAll}; __${Identifiers.LineTrackingFnIdentifier}(line);}`};${transformed.code} } finally { ${reportAll} };`;
2443
- return await AsyncFunction(...Object.keys(context), wrapper)(...Object.values(context));
3133
+ const assigner = `let __${Identifiers.LineTrackingFnIdentifier} = ${Identifiers.LineTrackingFnIdentifier}; ${Identifiers.LineTrackingFnIdentifier} = function(line) { ${reportAll}; __${Identifiers.LineTrackingFnIdentifier}(line);}`;
3134
+ const trackInputs = ctx.memoryNames.map((name) => `${Identifiers.VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}), undefined, "read");`).join("");
3135
+ const bindings = Object.keys(context);
3136
+ const protectedBindings = bindings.filter((name) => RESERVED_RUNTIME_NAMES.has(name)).map((name) => `const ${name} = __llmz_binding_${bindings.indexOf(name)};`).join("");
3137
+ const parameters = bindings.map((name, index) => RESERVED_RUNTIME_NAMES.has(name) ? `__llmz_binding_${index}` : name);
3138
+ const wrapper = `"use strict"; ${protectedBindings} try { ${assigner};${trackInputs}${transformed.code} } finally { ${reportAll} };`;
3139
+ const fn = AsyncFunction(...parameters, wrapper);
3140
+ try {
3141
+ return await fn(...Object.values(context));
3142
+ } finally {
3143
+ var _context$VM_PROGRAM_C;
3144
+ (_context$VM_PROGRAM_C = context[VM_PROGRAM_COMPLETE]) === null || _context$VM_PROGRAM_C === void 0 || _context$VM_PROGRAM_C.call(context);
3145
+ }
2444
3146
  })().then((res) => {
3147
+ var _context$VM_TERMINATI, _context$VM_TERMINATI2, _context$VM_TERMINATI3;
3148
+ const signal = (_context$VM_TERMINATI = context[VM_TERMINATION]) === null || _context$VM_TERMINATI === void 0 || (_context$VM_TERMINATI2 = _context$VM_TERMINATI.getSignal) === null || _context$VM_TERMINATI2 === void 0 ? void 0 : _context$VM_TERMINATI2.call(_context$VM_TERMINATI);
3149
+ if (signal) throw signal;
3150
+ if ((_context$VM_TERMINATI3 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI3 === void 0 ? void 0 : _context$VM_TERMINATI3.isTerminated()) res = void 0;
2445
3151
  res = Signals.maybeDeserializeError(res);
2446
3152
  return {
2447
3153
  success: true,
2448
3154
  variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
2449
- signal: res instanceof VMSignal ? res : void 0,
3155
+ signal: VMSignal.is(res) ? res : void 0,
2450
3156
  lines_executed: Array.from(lines_executed),
2451
3157
  return_value: res
2452
3158
  };
2453
- }).catch((err) => handleErrorNode(err, code, consumer, traces, variables, lines_executed, state.currentToolCall)).catch((err) => handleCatch(err, traces, variables, lines_executed));
3159
+ }).catch((err) => {
3160
+ var _context$VM_TERMINATI4, _context$VM_TERMINATI5, _context$VM_TERMINATI6;
3161
+ const signal = (_context$VM_TERMINATI4 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI4 === void 0 || (_context$VM_TERMINATI5 = _context$VM_TERMINATI4.getSignal) === null || _context$VM_TERMINATI5 === void 0 ? void 0 : _context$VM_TERMINATI5.call(_context$VM_TERMINATI4);
3162
+ if (signal) return handleErrorNode(signal, code, consumer, recordTrace, variables, lines_executed, state.lastExecutedLine);
3163
+ if ((_context$VM_TERMINATI6 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI6 === void 0 ? void 0 : _context$VM_TERMINATI6.isTerminated()) return {
3164
+ success: true,
3165
+ variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
3166
+ lines_executed: Array.from(lines_executed)
3167
+ };
3168
+ return handleErrorNode(err, code, consumer, recordTrace, variables, lines_executed, state.lastExecutedLine);
3169
+ }).catch((err) => handleCatch(err, traces, variables, lines_executed)), state);
2454
3170
  }
2455
3171
  };
2456
3172
  //#endregion
3173
+ //#region src/vm/member-proxy.ts
3174
+ /** Host-only metadata lets QuickJS install the same missing-member behavior in its own realm. */
3175
+ const MISSING_MEMBER = Symbol("llmz.missingMember");
3176
+ /** Only registered own members are callable; inherited Object methods are not API members. */
3177
+ function withMissingMember(target, missing) {
3178
+ Object.defineProperty(target, MISSING_MEMBER, { value: missing });
3179
+ Object.freeze(target);
3180
+ return new Proxy(target, { get(object, key, receiver) {
3181
+ if (typeof key === "string" && !Object.hasOwn(object, key)) return missing(key);
3182
+ return Reflect.get(object, key, receiver);
3183
+ } });
3184
+ }
3185
+ //#endregion
2457
3186
  //#region src/vm/drivers/quickjs.ts
2458
3187
  let _quickJSModule;
2459
3188
  let _loadedVariant;
@@ -2467,9 +3196,27 @@ const loadQuickJSModule = () => {
2467
3196
  };
2468
3197
  var QuickJSDriver = class {
2469
3198
  async execute(ctx) {
2470
- const { transformed, consumer, context, traces, signal, timeout, code, lines_executed, variables } = ctx;
3199
+ const { transformed, consumer, context, traces, recordTrace, signal, timeout, code, lines_executed, variables } = ctx;
2471
3200
  const userCodeStartLine = findUserCodeStartLine(transformed);
2472
- const state = instrumentContext(context, transformed, traces, variables, lines_executed, consumer, userCodeStartLine);
3201
+ const state = instrumentContext(context, transformed, recordTrace, variables, lines_executed, consumer, userCodeStartLine, ctx.memoryNames);
3202
+ const isTerminated = () => {
3203
+ var _context$VM_TERMINATI;
3204
+ return ((_context$VM_TERMINATI = context[VM_TERMINATION]) === null || _context$VM_TERMINATI === void 0 ? void 0 : _context$VM_TERMINATI.isTerminated()) ?? false;
3205
+ };
3206
+ const shouldStopJobs = () => {
3207
+ var _context$VM_TERMINATI2, _context$VM_TERMINATI3;
3208
+ return isTerminated() && !((_context$VM_TERMINATI2 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI2 === void 0 || (_context$VM_TERMINATI3 = _context$VM_TERMINATI2.getSignal) === null || _context$VM_TERMINATI3 === void 0 ? void 0 : _context$VM_TERMINATI3.call(_context$VM_TERMINATI2));
3209
+ };
3210
+ const terminalResult = () => {
3211
+ var _context$VM_TERMINATI4, _context$VM_TERMINATI5;
3212
+ const interruption = (_context$VM_TERMINATI4 = context[VM_TERMINATION]) === null || _context$VM_TERMINATI4 === void 0 || (_context$VM_TERMINATI5 = _context$VM_TERMINATI4.getSignal) === null || _context$VM_TERMINATI5 === void 0 ? void 0 : _context$VM_TERMINATI5.call(_context$VM_TERMINATI4);
3213
+ if (interruption) return finalizeMemoryCapture(handleErrorQuickJS(interruption, code, consumer, traces, variables, lines_executed, userCodeStartLine, recordTrace), state);
3214
+ return finalizeMemoryCapture({
3215
+ success: true,
3216
+ variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
3217
+ lines_executed: Array.from(lines_executed)
3218
+ }, state);
3219
+ };
2473
3220
  const runtime = (await loadQuickJSModule()).newRuntime();
2474
3221
  runtime.setMemoryLimit(134217728);
2475
3222
  const timeoutHandler = shouldInterruptAfterDeadline(Date.now() + timeout);
@@ -2481,36 +3228,45 @@ var QuickJSDriver = class {
2481
3228
  const trackedProperties = /* @__PURE__ */ new Set();
2482
3229
  const referenceProperties = /* @__PURE__ */ new Set();
2483
3230
  const pendingPromises = [];
2484
- const toVmValue = (value) => {
3231
+ const variableGetters = /* @__PURE__ */ new Map();
3232
+ let captureValue;
3233
+ const objectConstructor = vm.getProp(vm.global, "Object");
3234
+ const freezeFunction = vm.getProp(objectConstructor, "freeze");
3235
+ objectConstructor.dispose();
3236
+ const preserveHostFreeze = (hostValue, handle, preserveFrozen) => {
3237
+ if (!preserveFrozen || !Object.isFrozen(hostValue)) return handle;
3238
+ const frozen = vm.callFunction(freezeFunction, vm.undefined, handle);
3239
+ if ("error" in frozen) {
3240
+ const error = vm.dump(frozen.error);
3241
+ frozen.error.dispose();
3242
+ handle.dispose();
3243
+ throw new Error(error.message);
3244
+ }
3245
+ frozen.value.dispose();
3246
+ return handle;
3247
+ };
3248
+ const toVmValue = (value, preserveFrozen = false) => {
2485
3249
  if (typeof value === "string") return vm.newString(value);
2486
3250
  else if (typeof value === "number") return vm.newNumber(value);
2487
3251
  else if (typeof value === "boolean") return value ? vm.true : vm.false;
2488
3252
  else if (value === null) return vm.null;
2489
3253
  else if (value === void 0) return vm.undefined;
2490
3254
  else if (Array.isArray(value)) {
2491
- const items = value.map((item) => {
2492
- if (typeof item === "string") return JSON.stringify(item);
2493
- else if (typeof item === "number" || typeof item === "boolean") return String(item);
2494
- else if (item === null) return "null";
2495
- else if (item === void 0) return "undefined";
2496
- else if (typeof item === "object") return JSON.stringify(item);
2497
- return "undefined";
3255
+ const array = vm.newArray();
3256
+ value.forEach((item, index) => {
3257
+ const handle = toVmValue(item, preserveFrozen);
3258
+ vm.setProp(array, index, handle);
3259
+ disposeIfNeeded(handle);
2498
3260
  });
2499
- const result = vm.evalCode(`[${items.join(",")}]`);
2500
- if ("error" in result) {
2501
- var _result$error;
2502
- (_result$error = result.error) === null || _result$error === void 0 || _result$error.dispose();
2503
- return vm.undefined;
2504
- }
2505
- return result.value;
3261
+ return preserveHostFreeze(value, array, preserveFrozen);
2506
3262
  } else if (typeof value === "object") {
2507
3263
  const obj = vm.newObject();
2508
3264
  for (const [k, v] of Object.entries(value)) if (typeof v !== "function") {
2509
- const propHandle = toVmValue(v);
3265
+ const propHandle = toVmValue(v, preserveFrozen);
2510
3266
  vm.setProp(obj, k, propHandle);
2511
3267
  disposeIfNeeded(propHandle);
2512
3268
  }
2513
- return obj;
3269
+ return preserveHostFreeze(value, obj, preserveFrozen);
2514
3270
  }
2515
3271
  return vm.undefined;
2516
3272
  };
@@ -2524,36 +3280,94 @@ var QuickJSDriver = class {
2524
3280
  const result = fn(...args);
2525
3281
  if (result && typeof result.then === "function") {
2526
3282
  const promise = vm.newPromise();
3283
+ const hostPromise = Promise.resolve(result).then((value) => cloneMemoryValue(value));
3284
+ hostPromise.catch(() => {});
2527
3285
  pendingPromises.push({
2528
- hostPromise: result,
3286
+ hostPromise,
2529
3287
  deferredPromise: promise
2530
3288
  });
2531
3289
  promise.settled.then(() => {
2532
- if (runtime.alive) runtime.executePendingJobs();
3290
+ if (runtime.alive && !shouldStopJobs()) runtime.executePendingJobs();
2533
3291
  });
2534
3292
  return promise.handle;
2535
3293
  }
2536
- return toVmValue(result);
3294
+ return toVmValue(cloneMemoryValue(result));
2537
3295
  } catch (err) {
2538
- const serialized = err instanceof Error ? err.message : String(err);
2539
- throw new Error(serialized);
3296
+ return { error: guestError(vm, err) };
2540
3297
  }
2541
3298
  };
2542
3299
  };
2543
3300
  try {
2544
- bridgeContextToVM(context, vm, trackedProperties, referenceProperties, toVmValue, disposeIfNeeded, bridgeFunction);
2545
- setupVariableTrackingBridge(vm, variables);
3301
+ captureValue = setupMemoryCapture(vm);
3302
+ bridgeContextToVM(context, vm, trackedProperties, referenceProperties, toVmValue, disposeIfNeeded, bridgeFunction, captureValue);
3303
+ setupVariableTrackingBridge(vm, variables, variableGetters, state, captureValue);
3304
+ vm.evalCode(`(() => {
3305
+ const then = Promise.prototype.then;
3306
+ const check = globalThis.${TerminationGuardIdentifier};
3307
+ globalThis.${TerminationCheckpointIdentifier} = (value) => {
3308
+ if (value instanceof Promise) {
3309
+ then.call(value, undefined, () => {});
3310
+ }
3311
+ check();
3312
+ return value;
3313
+ };
3314
+ })()`).unwrap().dispose();
3315
+ const complete = vm.newFunction("__llmz_program_complete", () => {
3316
+ var _context$VM_PROGRAM_C;
3317
+ (_context$VM_PROGRAM_C = context[VM_PROGRAM_COMPLETE]) === null || _context$VM_PROGRAM_C === void 0 || _context$VM_PROGRAM_C.call(context);
3318
+ return vm.undefined;
3319
+ });
3320
+ vm.setProp(vm.global, "__llmz_program_complete", complete);
3321
+ complete.dispose();
3322
+ for (const name of ctx.memoryNames) {
3323
+ const tracked = vm.evalCode(`${Identifiers.VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => globalThis[${JSON.stringify(name)}], undefined, "read");`);
3324
+ if ("error" in tracked) {
3325
+ var _tracked$error;
3326
+ (_tracked$error = tracked.error) === null || _tracked$error === void 0 || _tracked$error.dispose();
3327
+ } else tracked.value.dispose();
3328
+ }
3329
+ const protect = vm.evalCode(`(() => {
3330
+ function freeze(value) {
3331
+ if (value && (typeof value === 'object' || typeof value === 'function') && !Object.isFrozen(value)) {
3332
+ Object.values(value).forEach(freeze);
3333
+ Object.freeze(value);
3334
+ }
3335
+ return value;
3336
+ }
3337
+ for (const name of ${JSON.stringify([
3338
+ ...RUNTIME_BINDING_NAMES,
3339
+ ...TERMINATION_BINDING_NAMES,
3340
+ "__llmz_program_complete"
3341
+ ])}) {
3342
+ if (Object.prototype.hasOwnProperty.call(globalThis, name)) {
3343
+ Object.defineProperty(globalThis, name, {
3344
+ value: freeze(globalThis[name]),
3345
+ writable: false,
3346
+ configurable: false,
3347
+ });
3348
+ }
3349
+ }
3350
+ })()`);
3351
+ if ("error" in protect) {
3352
+ const error = vm.dump(protect.error);
3353
+ protect.error.dispose();
3354
+ throw new Error(error.message);
3355
+ }
3356
+ protect.value.dispose();
2546
3357
  const scriptCode = buildScriptCode(transformed.code);
2547
3358
  const copyBackContextFromVM = () => {
2548
3359
  for (const key of trackedProperties) {
2549
3360
  if (referenceProperties.has(key)) continue;
2550
3361
  try {
2551
- const valueResult = vm.evalCode(`globalThis['${key}']`);
2552
- const vmValue = vm.dump(valueResult.unwrap());
2553
- valueResult.unwrap().dispose();
3362
+ const handle = vm.evalCode(`globalThis['${key}']`).unwrap();
2554
3363
  try {
2555
- context[key] = vmValue;
2556
- } catch {}
3364
+ const vmValue = ctx.memoryNames.includes(key) ? captureValue(handle) : vm.dump(handle);
3365
+ try {
3366
+ context[key] = vmValue;
3367
+ } catch {}
3368
+ } finally {
3369
+ handle.dispose();
3370
+ }
2557
3371
  } catch {}
2558
3372
  }
2559
3373
  };
@@ -2567,7 +3381,11 @@ var QuickJSDriver = class {
2567
3381
  throw new Error("Execution failed");
2568
3382
  }
2569
3383
  execResult.value.dispose();
2570
- await this._pumpEventLoop(runtime, vm, pendingPromises, signal, toVmValue, disposeIfNeeded);
3384
+ await this._pumpEventLoop(runtime, vm, pendingPromises, signal, toVmValue, disposeIfNeeded, shouldStopJobs);
3385
+ if (isTerminated()) {
3386
+ copyBackContextFromVM();
3387
+ return terminalResult();
3388
+ }
2571
3389
  const errorResult = vm.evalCode("globalThis.__llmz_error");
2572
3390
  const errorValue = vm.dump(errorResult.unwrap());
2573
3391
  errorResult.unwrap().dispose();
@@ -2584,11 +3402,14 @@ var QuickJSDriver = class {
2584
3402
  const errorStack = vm.dump(errorStackResult.unwrap()) || "";
2585
3403
  errorStackResult.unwrap().dispose();
2586
3404
  const deserializedError = Signals.maybeDeserializeError(errorValue);
2587
- if (deserializedError instanceof VMSignal) {
3405
+ if (VMSignal.is(deserializedError)) {
2588
3406
  deserializedError.stack = errorStack;
2589
3407
  throw deserializedError;
2590
3408
  }
2591
3409
  const error = new Error(errorValue);
3410
+ const errorNameResult = vm.evalCode("globalThis.__llmz_error_name");
3411
+ error.name = vm.dump(errorNameResult.unwrap()) || "Error";
3412
+ errorNameResult.unwrap().dispose();
2592
3413
  error.stack = errorStack;
2593
3414
  throw error;
2594
3415
  }
@@ -2598,23 +3419,35 @@ var QuickJSDriver = class {
2598
3419
  resultSetResult.unwrap().dispose();
2599
3420
  let returnValue = void 0;
2600
3421
  if (resultSet) {
2601
- const resultResult = vm.evalCode("globalThis.__llmz_result");
2602
- returnValue = vm.dump(resultResult.unwrap());
2603
- resultResult.unwrap().dispose();
3422
+ const resultHandle = vm.evalCode("globalThis.__llmz_result").unwrap();
3423
+ try {
3424
+ returnValue = captureValue(resultHandle);
3425
+ } catch (err) {
3426
+ state.captureErrors.push({
3427
+ name: "$return",
3428
+ reason: err instanceof Error ? err.message : String(err)
3429
+ });
3430
+ } finally {
3431
+ resultHandle.dispose();
3432
+ }
2604
3433
  }
2605
3434
  returnValue = Signals.maybeDeserializeError(returnValue);
2606
- return {
3435
+ return finalizeMemoryCapture({
2607
3436
  success: true,
2608
3437
  variables: mapValues(variables, (getter) => isFunction(getter) ? getter() : getter),
2609
- signal: returnValue instanceof VMSignal ? returnValue : void 0,
3438
+ signal: VMSignal.is(returnValue) ? returnValue : void 0,
2610
3439
  lines_executed: Array.from(lines_executed),
2611
- return_value: returnValue
2612
- };
3440
+ return_value: returnValue,
3441
+ variableWrites: state.variableWrites,
3442
+ captureErrors: state.captureErrors
3443
+ }, state);
2613
3444
  } catch (err) {
3445
+ runtime.setInterruptHandler(shouldInterruptAfterDeadline(Date.now() + 1e3));
3446
+ if (isTerminated()) return terminalResult();
2614
3447
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
2615
3448
  const reason = signal.reason;
2616
3449
  const abortError = reason instanceof Error ? reason : new Error(reason ? String(reason) : "Execution was aborted");
2617
- return handleErrorQuickJS(abortError, code, consumer, traces, variables, lines_executed, userCodeStartLine, ctx.currentToolCall ?? state.currentToolCall);
3450
+ return finalizeMemoryCapture(handleErrorQuickJS(abortError, code, consumer, traces, variables, lines_executed, userCodeStartLine, recordTrace), state);
2618
3451
  }
2619
3452
  await Promise.all(pendingPromises.map(async ({ hostPromise, deferredPromise }) => {
2620
3453
  try {
@@ -2629,8 +3462,13 @@ var QuickJSDriver = class {
2629
3462
  errValue.dispose();
2630
3463
  }
2631
3464
  })).catch(() => {});
2632
- return handleErrorQuickJS(err, code, consumer, traces, variables, lines_executed, userCodeStartLine, ctx.currentToolCall ?? state.currentToolCall);
3465
+ return finalizeMemoryCapture(handleErrorQuickJS(err, code, consumer, traces, variables, lines_executed, userCodeStartLine, recordTrace), state);
2633
3466
  } finally {
3467
+ var _context$VM_PROGRAM_C2;
3468
+ (_context$VM_PROGRAM_C2 = context[VM_PROGRAM_COMPLETE]) === null || _context$VM_PROGRAM_C2 === void 0 || _context$VM_PROGRAM_C2.call(context);
3469
+ for (const { deferredPromise } of pendingPromises) deferredPromise.dispose();
3470
+ for (const getter of variableGetters.values()) getter.dispose();
3471
+ freezeFunction.dispose();
2634
3472
  try {
2635
3473
  vm.dispose();
2636
3474
  } catch {}
@@ -2639,16 +3477,17 @@ var QuickJSDriver = class {
2639
3477
  } catch {}
2640
3478
  }
2641
3479
  }
2642
- async _pumpEventLoop(runtime, vm, pendingPromises, signal, toVmValue, disposeIfNeeded) {
3480
+ async _pumpEventLoop(runtime, vm, pendingPromises, signal, toVmValue, disposeIfNeeded, shouldStopJobs) {
2643
3481
  const maxIterations = 1e3;
2644
3482
  let iteration = 0;
2645
3483
  while (iteration < maxIterations) {
3484
+ if (shouldStopJobs()) break;
2646
3485
  let hasJobs = false;
2647
3486
  const maxJobs = 1e4;
2648
3487
  for (let i = 0; i < maxJobs; i++) {
2649
3488
  var _runtime$executePendi;
2650
3489
  const pending = (_runtime$executePendi = runtime.executePendingJobs) === null || _runtime$executePendi === void 0 ? void 0 : _runtime$executePendi.call(runtime, -1);
2651
- if ((pending === void 0 ? 0 : pending.unwrap()) <= 0) break;
3490
+ if ((pending === void 0 ? 0 : pending.unwrap()) <= 0 || shouldStopJobs()) break;
2652
3491
  hasJobs = true;
2653
3492
  }
2654
3493
  const currentPromises = [...pendingPromises];
@@ -2656,7 +3495,7 @@ var QuickJSDriver = class {
2656
3495
  if (currentPromises.length > 0) {
2657
3496
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
2658
3497
  const reason = signal.reason;
2659
- const abortMessage = reason instanceof Error ? `${reason.name}: ${reason.message}` : reason ? String(reason) : "Execution was aborted";
3498
+ const abortMessage = describeAbortReason(reason);
2660
3499
  for (const { deferredPromise } of currentPromises) {
2661
3500
  const errValue = vm.newString(abortMessage);
2662
3501
  deferredPromise.reject(errValue);
@@ -2669,7 +3508,7 @@ var QuickJSDriver = class {
2669
3508
  if (signal) {
2670
3509
  abortListener = () => {
2671
3510
  const reason = signal.reason;
2672
- const abortMessage = reason instanceof Error ? `${reason.name}: ${reason.message}` : reason ? String(reason) : "Execution was aborted";
3511
+ const abortMessage = describeAbortReason(reason);
2673
3512
  for (const { deferredPromise } of currentPromises) {
2674
3513
  const errValue = vm.newString(abortMessage);
2675
3514
  deferredPromise.reject(errValue);
@@ -2681,17 +3520,18 @@ var QuickJSDriver = class {
2681
3520
  }
2682
3521
  try {
2683
3522
  await Promise.all(currentPromises.map(async ({ hostPromise, deferredPromise }) => {
2684
- if (signal === null || signal === void 0 ? void 0 : signal.aborted) return;
3523
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || shouldStopJobs()) return;
2685
3524
  try {
2686
3525
  const value = await hostPromise;
2687
- if (signal === null || signal === void 0 ? void 0 : signal.aborted) return;
3526
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || shouldStopJobs()) return;
2688
3527
  const vmValue = toVmValue(value);
2689
3528
  deferredPromise.resolve(vmValue);
2690
3529
  disposeIfNeeded(vmValue);
2691
3530
  } catch (err) {
2692
- if (signal === null || signal === void 0 ? void 0 : signal.aborted) return;
2693
- const serialized = err instanceof Error ? err.message : String(err);
2694
- const createErrorResult = vm.evalCode(`new Error(${JSON.stringify(serialized)})`);
3531
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || shouldStopJobs()) return;
3532
+ const message = err instanceof Error ? err.message : String(err);
3533
+ const serialized = err instanceof Error ? Signals.serializeError(err) : message;
3534
+ const createErrorResult = vm.evalCode(`Object.assign(new Error(${JSON.stringify(message)}), { __llmz_error: ${JSON.stringify(serialized)} })`);
2695
3535
  if ("error" in createErrorResult) {
2696
3536
  const errValue = vm.newString(serialized);
2697
3537
  deferredPromise.reject(errValue);
@@ -2705,9 +3545,10 @@ var QuickJSDriver = class {
2705
3545
  }));
2706
3546
  } finally {
2707
3547
  if (signal && abortListener) signal.removeEventListener("abort", abortListener);
3548
+ if (shouldStopJobs()) currentPromises.forEach(({ deferredPromise }) => deferredPromise.dispose());
2708
3549
  }
2709
- runtime.executePendingJobs();
2710
- if (signal === null || signal === void 0 ? void 0 : signal.aborted) break;
3550
+ if (!shouldStopJobs()) runtime.executePendingJobs();
3551
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || shouldStopJobs()) break;
2711
3552
  }
2712
3553
  if (!hasJobs && pendingPromises.length === 0) break;
2713
3554
  iteration++;
@@ -2715,13 +3556,13 @@ var QuickJSDriver = class {
2715
3556
  if (iteration >= maxIterations) throw new Error("Maximum event loop iterations exceeded");
2716
3557
  }
2717
3558
  };
2718
- function bridgeContextToVM(context, vm, trackedProperties, referenceProperties, toVmValue, disposeIfNeeded, bridgeFunction) {
3559
+ function bridgeContextToVM(context, vm, trackedProperties, referenceProperties, toVmValue, disposeIfNeeded, bridgeFunction, captureValue) {
2719
3560
  for (const [key, value] of Object.entries(context)) {
2720
3561
  const descriptor = Object.getOwnPropertyDescriptor(context, key);
2721
3562
  if (descriptor && (descriptor.get || descriptor.set)) {
2722
3563
  referenceProperties.add(key);
2723
3564
  trackedProperties.add(key);
2724
- bridgeGetterSetter(vm, key, void 0, descriptor, context, toVmValue);
3565
+ bridgeGetterSetter(vm, key, void 0, descriptor, context, toVmValue, captureValue);
2725
3566
  continue;
2726
3567
  }
2727
3568
  if (typeof value === "function") {
@@ -2758,18 +3599,25 @@ function bridgeContextToVM(context, vm, trackedProperties, referenceProperties,
2758
3599
  }
2759
3600
  vm.setProp(vm.global, key, objHandle);
2760
3601
  objHandle.dispose();
2761
- for (const { prop, descriptor } of getterSetterProps) bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue);
3602
+ for (const { prop, descriptor } of getterSetterProps) bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue, captureValue);
3603
+ const missing = value[MISSING_MEMBER];
3604
+ if (missing) {
3605
+ trackedProperties.delete(key);
3606
+ installMemberProxy(vm, key, bridgeFunction(missing));
3607
+ }
2762
3608
  if (Object.isSealed(value)) {
2763
- var _sealResult$error;
2764
3609
  const sealResult = vm.evalCode(`Object.seal(globalThis['${key}']);`);
2765
- if ("error" in sealResult) (_sealResult$error = sealResult.error) === null || _sealResult$error === void 0 || _sealResult$error.dispose();
2766
- else sealResult.value.dispose();
3610
+ if ("error" in sealResult) {
3611
+ var _sealResult$error;
3612
+ (_sealResult$error = sealResult.error) === null || _sealResult$error === void 0 || _sealResult$error.dispose();
3613
+ } else sealResult.value.dispose();
2767
3614
  }
2768
3615
  if (!Object.isExtensible(value)) {
2769
- var _preventResult$error;
2770
3616
  const preventResult = vm.evalCode(`Object.preventExtensions(globalThis['${key}']);`);
2771
- if ("error" in preventResult) (_preventResult$error = preventResult.error) === null || _preventResult$error === void 0 || _preventResult$error.dispose();
2772
- else preventResult.value.dispose();
3617
+ if ("error" in preventResult) {
3618
+ var _preventResult$error;
3619
+ (_preventResult$error = preventResult.error) === null || _preventResult$error === void 0 || _preventResult$error.dispose();
3620
+ } else preventResult.value.dispose();
2773
3621
  }
2774
3622
  } else {
2775
3623
  trackedProperties.add(key);
@@ -2779,8 +3627,43 @@ function bridgeContextToVM(context, vm, trackedProperties, referenceProperties,
2779
3627
  }
2780
3628
  }
2781
3629
  }
2782
- function bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue) {
2783
- var _result$error2;
3630
+ function installMemberProxy(vm, key, missing) {
3631
+ const factory = vm.evalCode("(function(target, missing) { return new Proxy(target, { get(object, key, receiver) { if (typeof key === \"string\" && !Object.prototype.hasOwnProperty.call(object, key)) { return missing(key); } return Reflect.get(object, key, receiver); } }); })");
3632
+ if ("error" in factory) {
3633
+ var _factory$error;
3634
+ (_factory$error = factory.error) === null || _factory$error === void 0 || _factory$error.dispose();
3635
+ throw new Error("Could not create the API member proxy.");
3636
+ }
3637
+ const missingHandle = vm.newFunction("missingMember", missing);
3638
+ const target = vm.getProp(vm.global, key);
3639
+ try {
3640
+ const result = vm.callFunction(factory.value, vm.undefined, target, missingHandle);
3641
+ if ("error" in result) {
3642
+ var _result$error;
3643
+ (_result$error = result.error) === null || _result$error === void 0 || _result$error.dispose();
3644
+ throw new Error("Could not install the API member proxy.");
3645
+ }
3646
+ vm.setProp(vm.global, key, result.value);
3647
+ result.value.dispose();
3648
+ } finally {
3649
+ target.dispose();
3650
+ factory.value.dispose();
3651
+ missingHandle.dispose();
3652
+ }
3653
+ }
3654
+ /** Preserve readable guest messages and host error types without serializing Error as a string. */
3655
+ function guestError(vm, cause) {
3656
+ const error = cause instanceof Error ? cause : new Error(String(cause));
3657
+ const handle = vm.newError({
3658
+ name: error.name,
3659
+ message: error.message
3660
+ });
3661
+ const details = vm.newString(Signals.serializeError(error));
3662
+ vm.setProp(handle, "__llmz_error", details);
3663
+ details.dispose();
3664
+ return handle;
3665
+ }
3666
+ function bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue, captureValue) {
2784
3667
  const target = prop ? `${key}` : "globalThis";
2785
3668
  const propName = prop ?? key;
2786
3669
  const prefix = prop ? `${key}_${prop}` : key;
@@ -2788,9 +3671,9 @@ function bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue) {
2788
3671
  if (descriptor.get) {
2789
3672
  const getterBridge = vm.newFunction(`get_${propName}`, () => {
2790
3673
  try {
2791
- return toVmValue(prop ? context[key][prop] : context[key]);
3674
+ return toVmValue(prop ? context[key][prop] : context[key], true);
2792
3675
  } catch (err) {
2793
- throw new Error(err instanceof Error ? err.message : String(err));
3676
+ return { error: guestError(vm, err) };
2794
3677
  }
2795
3678
  });
2796
3679
  const getterName = `__getter_${prefix}__`;
@@ -2802,12 +3685,12 @@ function bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue) {
2802
3685
  if (descriptor.set) {
2803
3686
  const setterBridge = vm.newFunction(`set_${propName}`, (valueHandle) => {
2804
3687
  try {
2805
- const jsValue = vm.dump(valueHandle);
3688
+ const jsValue = captureValue(valueHandle);
2806
3689
  if (prop) context[key][prop] = jsValue;
2807
3690
  else context[key] = jsValue;
2808
3691
  return vm.undefined;
2809
3692
  } catch (err) {
2810
- throw new Error(err instanceof Error ? err.message : String(err));
3693
+ return { error: guestError(vm, err) };
2811
3694
  }
2812
3695
  });
2813
3696
  const setterName = `__setter_${prefix}__`;
@@ -2824,31 +3707,131 @@ function bridgeGetterSetter(vm, key, prop, descriptor, context, toVmValue) {
2824
3707
  });
2825
3708
  `;
2826
3709
  const result = vm.evalCode(definePropertyCode);
2827
- if ("error" in result) (_result$error2 = result.error) === null || _result$error2 === void 0 || _result$error2.dispose();
2828
- else result.value.dispose();
3710
+ if ("error" in result) {
3711
+ var _result$error2;
3712
+ (_result$error2 = result.error) === null || _result$error2 === void 0 || _result$error2.dispose();
3713
+ } else result.value.dispose();
2829
3714
  }
2830
- function setupVariableTrackingBridge(vm, variables) {
2831
- const varTrackFnHandle = vm.newFunction(Identifiers.VariableTrackingFnIdentifier, (nameHandle, getterHandle) => {
2832
- const name = vm.getString(nameHandle);
2833
- if (NO_TRACKING.includes(name)) return;
3715
+ function setupMemoryCapture(vm) {
3716
+ const installed = vm.evalCode(`
3717
+ globalThis.__llmz_encode_memory = function encode(value, seen = new Set()) {
3718
+ if (value === undefined) {
3719
+ return ['undefined'];
3720
+ }
3721
+ if (Object.is(value, -0)) {
3722
+ return ['negative-zero'];
3723
+ }
3724
+ if (value === null || typeof value === 'boolean' || typeof value === 'string') {
3725
+ return ['value', value];
3726
+ }
3727
+ if (typeof value === 'number' && Number.isFinite(value)) {
3728
+ return ['value', value];
3729
+ }
3730
+ if (!value || typeof value !== 'object') {
3731
+ throw new Error('Unsupported memory value: ' + typeof value);
3732
+ }
3733
+ if (seen.has(value)) {
3734
+ throw new Error('Cyclic values cannot be retained in memory');
3735
+ }
3736
+ const plainObject = Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null;
3737
+ if (!Array.isArray(value) && !plainObject) {
3738
+ throw new Error('Only plain objects and arrays can be retained in memory');
3739
+ }
3740
+ if (Object.getOwnPropertySymbols(value).length) {
3741
+ throw new Error('Symbol properties cannot be retained in memory');
3742
+ }
3743
+ seen.add(value);
3744
+ try {
3745
+ if (Array.isArray(value)) {
3746
+ if (Object.keys(value).length !== value.length) {
3747
+ throw new Error('Sparse arrays and custom array properties are unsupported');
3748
+ }
3749
+ const items = [];
3750
+ for (let index = 0; index < value.length; index++) {
3751
+ const descriptor = Object.getOwnPropertyDescriptor(value, index);
3752
+ if (!descriptor || descriptor.get || descriptor.set) {
3753
+ throw new Error('Array accessor properties cannot be retained in memory');
3754
+ }
3755
+ items.push(encode(descriptor.value, seen));
3756
+ }
3757
+ return ['array', items];
3758
+ }
3759
+ const entries = [];
3760
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
3761
+ if (descriptor.get || descriptor.set || !descriptor.enumerable) {
3762
+ throw new Error('Accessor and non-enumerable properties cannot be retained in memory');
3763
+ }
3764
+ entries.push([key, encode(descriptor.value, seen)]);
3765
+ }
3766
+ return ['object', entries];
3767
+ } finally {
3768
+ seen.delete(value);
3769
+ }
3770
+ };
3771
+ `);
3772
+ if ("error" in installed) {
3773
+ const error = vm.dump(installed.error);
3774
+ installed.error.dispose();
3775
+ throw new Error(error.message);
3776
+ }
3777
+ installed.value.dispose();
3778
+ return (handle) => {
3779
+ const encoder = vm.getProp(vm.global, "__llmz_encode_memory");
2834
3780
  try {
2835
- const valueResult = vm.callFunction(getterHandle, vm.undefined);
2836
- if ("error" in valueResult) {
2837
- var _valueResult$error;
2838
- variables[name] = "[[non-primitive]]";
2839
- (_valueResult$error = valueResult.error) === null || _valueResult$error === void 0 || _valueResult$error.dispose();
2840
- return;
3781
+ const encoded = vm.callFunction(encoder, vm.undefined, handle);
3782
+ if ("error" in encoded) {
3783
+ const error = vm.dump(encoded.error);
3784
+ encoded.error.dispose();
3785
+ throw new Error(error.message);
2841
3786
  }
2842
- const value = vm.dump(valueResult.value);
2843
- valueResult.value.dispose();
2844
- if (typeof value === "function" || typeof value === "string" && value.includes("=>")) variables[name] = "[[non-primitive]]";
2845
- else variables[name] = value;
2846
- } catch {
2847
- variables[name] = "[[non-primitive]]";
3787
+ try {
3788
+ return decodeMemoryValue(vm.dump(encoded.value));
3789
+ } finally {
3790
+ encoded.value.dispose();
3791
+ }
3792
+ } finally {
3793
+ encoder.dispose();
2848
3794
  }
3795
+ };
3796
+ }
3797
+ function setupVariableTrackingBridge(vm, variables, getters, state, capture) {
3798
+ const tracker = vm.newFunction(Identifiers.VariableTrackingFnIdentifier, (nameHandle, getterHandle, resultHandle, kindHandle) => {
3799
+ var _getters$get;
3800
+ const name = vm.getString(nameHandle);
3801
+ if (NO_TRACKING.includes(name) || !state.memoryNames.has(name)) return (resultHandle === null || resultHandle === void 0 ? void 0 : resultHandle.dup()) ?? vm.undefined;
3802
+ const kind = kindHandle ? vm.dump(kindHandle) : "assignment";
3803
+ if (kind !== "initialize" && kind !== "read") state.variableWrites.push({
3804
+ name,
3805
+ timestamp: Date.now(),
3806
+ kind: kind === "mutation" ? "mutation" : "assignment"
3807
+ });
3808
+ (_getters$get = getters.get(name)) === null || _getters$get === void 0 || _getters$get.dispose();
3809
+ getters.set(name, getterHandle.dup());
3810
+ variables[name] = () => {
3811
+ try {
3812
+ const result = vm.callFunction(getters.get(name), vm.undefined);
3813
+ if ("error" in result) {
3814
+ const error = vm.dump(result.error);
3815
+ result.error.dispose();
3816
+ throw new Error(error.message);
3817
+ }
3818
+ try {
3819
+ return capture(result.value);
3820
+ } finally {
3821
+ result.value.dispose();
3822
+ }
3823
+ } catch (err) {
3824
+ if (!state.captureErrors.some((entry) => entry.name === name)) state.captureErrors.push({
3825
+ name,
3826
+ reason: err instanceof Error ? err.message : String(err)
3827
+ });
3828
+ return;
3829
+ }
3830
+ };
3831
+ return (resultHandle === null || resultHandle === void 0 ? void 0 : resultHandle.dup()) ?? vm.undefined;
2849
3832
  });
2850
- vm.setProp(vm.global, Identifiers.VariableTrackingFnIdentifier, varTrackFnHandle);
2851
- varTrackFnHandle.dispose();
3833
+ vm.setProp(vm.global, Identifiers.VariableTrackingFnIdentifier, tracker);
3834
+ tracker.dispose();
2852
3835
  }
2853
3836
  function buildScriptCode(transformedCode) {
2854
3837
  return `
@@ -2867,12 +3850,19 @@ ${transformedCode}
2867
3850
  globalThis.__llmz_result = await __fn__();
2868
3851
  globalThis.__llmz_result_set = true;
2869
3852
  } catch (err) {
2870
- globalThis.__llmz_error = typeof err === 'string' ? err : String(err.message || err || '');
3853
+ globalThis.__llmz_error = typeof err === 'string' ? err : String(err.__llmz_error || err.message || err || '');
3854
+ globalThis.__llmz_error_name = typeof err?.name === 'string' ? err.name : 'Error';
2871
3855
  globalThis.__llmz_error_stack = '' + (err.stack || '');
3856
+ } finally {
3857
+ __llmz_program_complete();
2872
3858
  }
2873
3859
  })();
2874
3860
  `.trim();
2875
3861
  }
3862
+ function describeAbortReason(reason) {
3863
+ if (reason instanceof Error) return `${reason.name}: ${reason.message}`;
3864
+ return reason ? String(reason) : "Execution was aborted";
3865
+ }
2876
3866
  //#endregion
2877
3867
  //#region src/vm/index.ts
2878
3868
  const MAX_VM_EXECUTION_TIME = 6e4;
@@ -2884,27 +3874,20 @@ const isWorkerd = () => {
2884
3874
  var _navigator;
2885
3875
  return typeof navigator !== "undefined" && ((_navigator = navigator) === null || _navigator === void 0 ? void 0 : _navigator.userAgent) === "Cloudflare-Workers";
2886
3876
  };
2887
- /**
2888
- * Pre-warms the VM so the first execution doesn't pay the QuickJS WASM
2889
- * instantiation cost. Fire-and-forget: called as soon as the model starts
2890
- * writing a `■run` block, so the module loads while the code is still being
2891
- * generated. No-op when the QuickJS driver is disabled or already loaded.
2892
- */
2893
- const warmupVM = () => {
2894
- if (useQuickJS()) loadQuickJSModule().catch(() => {});
2895
- };
2896
- async function runAsyncFunction(context, code, traces = [], signal = null, timeout = MAX_VM_EXECUTION_TIME) {
3877
+ async function runAsyncFunction(context, code, traces = [], signal = null, timeout = MAX_VM_EXECUTION_TIME, memoryNames, recordTrace = (trace) => {
3878
+ traces.push(trace);
3879
+ }) {
2897
3880
  const transformed = (() => {
2898
3881
  try {
2899
3882
  return compile(code);
2900
3883
  } catch (err) {
2901
- traces.push({
3884
+ recordTrace({
2902
3885
  type: "invalid_code_exception",
2903
3886
  message: (err === null || err === void 0 ? void 0 : err.message) ?? "Unknown error",
2904
3887
  code,
2905
3888
  started_at: Date.now()
2906
3889
  });
2907
- throw new InvalidCodeError(err.message, code);
3890
+ throw isLLMzError(err) ? err : new InvalidCodeError(err.message, code, { cause: err });
2908
3891
  }
2909
3892
  })();
2910
3893
  const lines_executed = /* @__PURE__ */ new Map();
@@ -2918,22 +3901,21 @@ async function runAsyncFunction(context, code, traces = [], signal = null, timeo
2918
3901
  file: transformed.map.file
2919
3902
  });
2920
3903
  context ??= {};
3904
+ memoryNames ??= Object.keys(context).filter((name) => {
3905
+ if (name.startsWith("__") || RESERVED_RUNTIME_NAMES.has(name)) return false;
3906
+ try {
3907
+ cloneMemoryValue(context[name]);
3908
+ return true;
3909
+ } catch {
3910
+ return false;
3911
+ }
3912
+ });
3913
+ memoryNames = memoryNames.filter((name) => !transformed.variables.has(name) && !RESERVED_RUNTIME_NAMES.has(name) && !name.startsWith("__"));
2921
3914
  for (const name of Array.from(transformed.variables)) delete context[name];
2922
- let driver;
3915
+ let driver = new NodeDriver();
2923
3916
  if (useQuickJS()) try {
3917
+ await loadQuickJSModule();
2924
3918
  driver = new QuickJSDriver();
2925
- return await driver.execute({
2926
- transformed,
2927
- consumer,
2928
- context,
2929
- traces,
2930
- signal,
2931
- timeout,
2932
- code,
2933
- lines_executed,
2934
- variables,
2935
- currentToolCall: void 0
2936
- });
2937
3919
  } catch (quickjsError) {
2938
3920
  const variant = getQuickJSVariant();
2939
3921
  const debugInfo = {
@@ -2950,7 +3932,7 @@ async function runAsyncFunction(context, code, traces = [], signal = null, timeo
2950
3932
  console.error("QuickJS failed to load and the node driver is unavailable on Cloudflare Workers.");
2951
3933
  console.error("Debug info:", JSON.stringify(debugInfo, null, 2));
2952
3934
  if (quickjsError instanceof Error) {
2953
- quickjsError.debugInfo = debugInfo;
3935
+ Object.assign(quickjsError, { debugInfo });
2954
3936
  throw quickjsError;
2955
3937
  }
2956
3938
  throw new Error(`QuickJS failed to load on Cloudflare Workers: ${debugInfo.error}`);
@@ -2959,19 +3941,19 @@ async function runAsyncFunction(context, code, traces = [], signal = null, timeo
2959
3941
  console.warn("Error:", (quickjsError === null || quickjsError === void 0 ? void 0 : quickjsError.message) || quickjsError);
2960
3942
  console.warn("Debug info:", JSON.stringify(debugInfo, null, 2));
2961
3943
  }
2962
- driver = new NodeDriver();
2963
3944
  return await driver.execute({
2964
3945
  transformed,
3946
+ memoryNames,
2965
3947
  consumer,
2966
3948
  context,
2967
3949
  traces,
3950
+ recordTrace,
2968
3951
  signal,
2969
3952
  timeout,
2970
3953
  code,
2971
3954
  lines_executed,
2972
- variables,
2973
- currentToolCall: void 0
3955
+ variables
2974
3956
  });
2975
3957
  }
2976
3958
  //#endregion
2977
- export { runAsyncFunction, warmupVM };
3959
+ export { compile as a, VM_TERMINATION as i, VM_ON_ERROR as n, VM_PROGRAM_COMPLETE as r, runAsyncFunction, withMissingMember as t };