@ny4n/codemode 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +56 -7
  3. package/dist/declarations.d.ts +6 -21
  4. package/dist/declarations.d.ts.map +1 -1
  5. package/dist/declarations.js +100 -122
  6. package/dist/declarations.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/portable.d.ts +1 -1
  12. package/dist/portable.d.ts.map +1 -1
  13. package/dist/portable.js.map +1 -1
  14. package/dist/runtime/execution.d.ts +14 -2
  15. package/dist/runtime/execution.d.ts.map +1 -1
  16. package/dist/runtime/execution.js +158 -35
  17. package/dist/runtime/execution.js.map +1 -1
  18. package/dist/runtime/host.d.ts.map +1 -1
  19. package/dist/runtime/host.js +25 -11
  20. package/dist/runtime/host.js.map +1 -1
  21. package/dist/runtime/inline.d.ts.map +1 -1
  22. package/dist/runtime/inline.js +1 -0
  23. package/dist/runtime/inline.js.map +1 -1
  24. package/dist/runtime/prelude-source.d.ts +3 -1
  25. package/dist/runtime/prelude-source.d.ts.map +1 -1
  26. package/dist/runtime/prelude-source.js +16 -6
  27. package/dist/runtime/prelude-source.js.map +1 -1
  28. package/dist/runtime/protocol.d.ts +38 -3
  29. package/dist/runtime/protocol.d.ts.map +1 -1
  30. package/dist/runtime/protocol.js +6 -1
  31. package/dist/runtime/protocol.js.map +1 -1
  32. package/dist/runtime/remote.d.ts.map +1 -1
  33. package/dist/runtime/remote.js +5 -0
  34. package/dist/runtime/remote.js.map +1 -1
  35. package/dist/runtime/vm.d.ts +2 -0
  36. package/dist/runtime/vm.d.ts.map +1 -1
  37. package/dist/runtime/vm.js +131 -9
  38. package/dist/runtime/vm.js.map +1 -1
  39. package/dist/search.d.ts +33 -0
  40. package/dist/search.d.ts.map +1 -0
  41. package/dist/search.js +112 -0
  42. package/dist/search.js.map +1 -0
  43. package/dist/source.d.ts +2 -1
  44. package/dist/source.d.ts.map +1 -1
  45. package/dist/source.js +8 -2
  46. package/dist/source.js.map +1 -1
  47. package/dist/types.d.ts +102 -4
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js.map +1 -1
  50. package/package.json +6 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, MCP_TYPESCRIPT_PREAMBLE, mcpStructuredContentSchema, renderDeclarations, renderToolOutputType, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.js";
1
+ export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, renderDeclarations, renderToolOutputType, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.js";
2
2
  export { toCodemodeIdentifier } from "./identifier.js";
3
3
  export { CodemodeSandboxBase } from "./runtime/execution.js";
4
4
  export { CodemodeSandbox } from "./runtime/host.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,uBAAuB,EACvB,0BAA0B,EAE1B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACN,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAON,qBAAqB,EAErB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EAGnB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AAgBrB,OAAO,EAA2B,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export {\n\tDEFAULT_INPUT_SCHEMA_MAX_CHARS,\n\tMCP_TYPESCRIPT_PREAMBLE,\n\tmcpStructuredContentSchema,\n\ttype RenderDeclarationsOptions,\n\trenderDeclarations,\n\trenderToolOutputType,\n\trenderToolSample,\n\trenderToolSignature,\n\tschemaToType,\n} from \"./declarations.ts\";\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandboxBase } from \"./runtime/execution.ts\";\nexport { CodemodeSandbox } from \"./runtime/host.ts\";\nexport {\n\tDEFAULT_INTERRUPT_BUDGET,\n\tInlineCodemodeSandbox,\n\ttype InlineCodemodeSandboxOptions,\n} from \"./runtime/inline.ts\";\nexport {\n\tMAX_OUTPUT_CHARS,\n\tMAX_OUTPUT_ITEMS,\n\tMAX_STORE_TOTAL_CHARS,\n\tMAX_STORE_VALUE_CHARS,\n} from \"./runtime/prelude-source.ts\";\nexport {\n\ttype CodemodeRemote,\n\ttype CodemodeRemoteExchange,\n\ttype CodemodeRemoteMessage,\n\ttype CodemodeRemoteReply,\n\ttype CodemodeRemoteRequest,\n\ttype CodemodeServeOptions,\n\tRemoteCodemodeSandbox,\n\ttype RemoteCodemodeSandboxOptions,\n\tserveCodemodeRemote,\n} from \"./runtime/remote.ts\";\nexport {\n\tCODEMODE_OPTIONS_PREFIX,\n\tCODEMODE_SOURCE_GRAMMAR,\n\tCodemodeSourceError,\n\ttype CodemodeSourceOptions,\n\ttype ParsedCodemodeSource,\n\tparseCodemodeSource,\n} from \"./source.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeJsonSchema,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport { type CodemodeWasmModule, loadQuickJSWasm } from \"./wasm.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAE9B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACN,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAON,qBAAqB,EAErB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EAGnB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AAuBrB,OAAO,EAA2B,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export {\n\tDEFAULT_INPUT_SCHEMA_MAX_CHARS,\n\ttype RenderDeclarationsOptions,\n\trenderDeclarations,\n\trenderToolOutputType,\n\trenderToolSample,\n\trenderToolSignature,\n\tschemaToType,\n} from \"./declarations.ts\";\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandboxBase } from \"./runtime/execution.ts\";\nexport { CodemodeSandbox } from \"./runtime/host.ts\";\nexport {\n\tDEFAULT_INTERRUPT_BUDGET,\n\tInlineCodemodeSandbox,\n\ttype InlineCodemodeSandboxOptions,\n} from \"./runtime/inline.ts\";\nexport {\n\tMAX_OUTPUT_CHARS,\n\tMAX_OUTPUT_ITEMS,\n\tMAX_STORE_TOTAL_CHARS,\n\tMAX_STORE_VALUE_CHARS,\n} from \"./runtime/prelude-source.ts\";\nexport {\n\ttype CodemodeRemote,\n\ttype CodemodeRemoteExchange,\n\ttype CodemodeRemoteMessage,\n\ttype CodemodeRemoteReply,\n\ttype CodemodeRemoteRequest,\n\ttype CodemodeServeOptions,\n\tRemoteCodemodeSandbox,\n\ttype RemoteCodemodeSandboxOptions,\n\tserveCodemodeRemote,\n} from \"./runtime/remote.ts\";\nexport {\n\tCODEMODE_OPTIONS_PREFIX,\n\tCODEMODE_SOURCE_GRAMMAR,\n\tCodemodeSourceError,\n\ttype CodemodeSourceOptions,\n\ttype ParsedCodemodeSource,\n\tparseCodemodeSource,\n} from \"./source.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeDeclaredGlobal,\n\tCodemodeDeclaredTool,\n\tCodemodeDuring,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeHostCall,\n\tCodemodeJsonSchema,\n\tCodemodeOutcome,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeRun,\n\tCodemodeRunOptions,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport { type CodemodeWasmModule, loadQuickJSWasm } from \"./wasm.ts\";\n"]}
@@ -10,6 +10,6 @@ export { DEFAULT_INTERRUPT_BUDGET, InlineCodemodeSandbox, type InlineCodemodeSan
10
10
  export { MAX_OUTPUT_CHARS, MAX_OUTPUT_ITEMS, MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS, } from "./runtime/prelude-source.ts";
11
11
  export type { HostToWorkerMessage, VmStartData, WorkerToHostMessage } from "./runtime/protocol.ts";
12
12
  export { type CodemodeRemote, type CodemodeRemoteExchange, type CodemodeRemoteMessage, type CodemodeRemoteReply, type CodemodeRemoteRequest, type CodemodeServeOptions, RemoteCodemodeSandbox, type RemoteCodemodeSandboxOptions, serveCodemodeRemote, } from "./runtime/remote.ts";
13
- export type { CodemodeCall, CodemodeCallStatus, CodemodeError, CodemodeErrorKind, CodemodeExecuteOptions, CodemodeJsonSchema, CodemodeOutputItem, CodemodeResult, CodemodeSandboxBaseOptions, CodemodeStoreWrites, CodemodeTool, CodemodeToolContext, } from "./types.ts";
13
+ export type { CodemodeCall, CodemodeCallStatus, CodemodeDeclaredGlobal, CodemodeDeclaredTool, CodemodeDuring, CodemodeError, CodemodeErrorKind, CodemodeExecuteOptions, CodemodeHostCall, CodemodeJsonSchema, CodemodeOutcome, CodemodeOutputItem, CodemodeResult, CodemodeRun, CodemodeRunOptions, CodemodeSandboxBaseOptions, CodemodeStoreWrites, CodemodeTool, CodemodeToolContext, } from "./types.ts";
14
14
  export type { CodemodeWasmModule } from "./wasm.ts";
15
15
  //# sourceMappingURL=portable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../src/portable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACN,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,4BAA4B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../src/portable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACN,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,4BAA4B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"portable.js","sourceRoot":"","sources":["../src/portable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACN,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAON,qBAAqB,EAErB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC","sourcesContent":["/**\n * Sandboxes that need no Node built-ins: `InlineCodemodeSandbox` runs the VM on the calling thread\n * and `RemoteCodemodeSandbox` runs it in another isolate. Neither imports `node:*` modules, so this\n * entry works in Cloudflare Workers, Durable Objects, and browsers. `CodemodeSandbox`, which uses\n * worker threads, stays in the main entry.\n */\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandboxBase } from \"./runtime/execution.ts\";\nexport {\n\tDEFAULT_INTERRUPT_BUDGET,\n\tInlineCodemodeSandbox,\n\ttype InlineCodemodeSandboxOptions,\n} from \"./runtime/inline.ts\";\nexport {\n\tMAX_OUTPUT_CHARS,\n\tMAX_OUTPUT_ITEMS,\n\tMAX_STORE_TOTAL_CHARS,\n\tMAX_STORE_VALUE_CHARS,\n} from \"./runtime/prelude-source.ts\";\nexport type { HostToWorkerMessage, VmStartData, WorkerToHostMessage } from \"./runtime/protocol.ts\";\nexport {\n\ttype CodemodeRemote,\n\ttype CodemodeRemoteExchange,\n\ttype CodemodeRemoteMessage,\n\ttype CodemodeRemoteReply,\n\ttype CodemodeRemoteRequest,\n\ttype CodemodeServeOptions,\n\tRemoteCodemodeSandbox,\n\ttype RemoteCodemodeSandboxOptions,\n\tserveCodemodeRemote,\n} from \"./runtime/remote.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeJsonSchema,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport type { CodemodeWasmModule } from \"./wasm.ts\";\n"]}
1
+ {"version":3,"file":"portable.js","sourceRoot":"","sources":["../src/portable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACN,wBAAwB,EACxB,qBAAqB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAON,qBAAqB,EAErB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC","sourcesContent":["/**\n * Sandboxes that need no Node built-ins: `InlineCodemodeSandbox` runs the VM on the calling thread\n * and `RemoteCodemodeSandbox` runs it in another isolate. Neither imports `node:*` modules, so this\n * entry works in Cloudflare Workers, Durable Objects, and browsers. `CodemodeSandbox`, which uses\n * worker threads, stays in the main entry.\n */\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandboxBase } from \"./runtime/execution.ts\";\nexport {\n\tDEFAULT_INTERRUPT_BUDGET,\n\tInlineCodemodeSandbox,\n\ttype InlineCodemodeSandboxOptions,\n} from \"./runtime/inline.ts\";\nexport {\n\tMAX_OUTPUT_CHARS,\n\tMAX_OUTPUT_ITEMS,\n\tMAX_STORE_TOTAL_CHARS,\n\tMAX_STORE_VALUE_CHARS,\n} from \"./runtime/prelude-source.ts\";\nexport type { HostToWorkerMessage, VmStartData, WorkerToHostMessage } from \"./runtime/protocol.ts\";\nexport {\n\ttype CodemodeRemote,\n\ttype CodemodeRemoteExchange,\n\ttype CodemodeRemoteMessage,\n\ttype CodemodeRemoteReply,\n\ttype CodemodeRemoteRequest,\n\ttype CodemodeServeOptions,\n\tRemoteCodemodeSandbox,\n\ttype RemoteCodemodeSandboxOptions,\n\tserveCodemodeRemote,\n} from \"./runtime/remote.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeDeclaredGlobal,\n\tCodemodeDeclaredTool,\n\tCodemodeDuring,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeHostCall,\n\tCodemodeJsonSchema,\n\tCodemodeOutcome,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeRun,\n\tCodemodeRunOptions,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport type { CodemodeWasmModule } from \"./wasm.ts\";\n"]}
@@ -1,4 +1,4 @@
1
- import type { CodemodeError, CodemodeExecuteOptions, CodemodeResult, CodemodeSandboxBaseOptions, CodemodeTool } from "../types.ts";
1
+ import type { CodemodeError, CodemodeExecuteOptions, CodemodeResult, CodemodeRun, CodemodeRunOptions, CodemodeSandboxBaseOptions, CodemodeTool } from "../types.ts";
2
2
  import { type HostToWorkerMessage, type VmStartData } from "./protocol.ts";
3
3
  /** Callbacks a launcher uses to report what its VM does. */
4
4
  export interface VmEvents {
@@ -10,7 +10,7 @@ export interface VmEvents {
10
10
  /** The host's handle on a running VM. */
11
11
  export interface VmChannel {
12
12
  post(message: HostToWorkerMessage): void;
13
- /** Stops the VM. Called once, after the execution has its result. */
13
+ /** Requests VM shutdown. Called once; may resolve before a worker or remote VM actually exits. */
14
14
  stop(): Promise<void>;
15
15
  }
16
16
  /**
@@ -48,6 +48,18 @@ export declare class CodemodeSandboxBase {
48
48
  * The script can use `store(key, value)` and `load(key)` on `options.store`.
49
49
  */
50
50
  execute(code: string, options?: CodemodeExecuteOptions): Promise<CodemodeResult>;
51
+ /**
52
+ * Run `code` deterministically, with the caller answering its calls: the same script, start time, seed, tools,
53
+ * globals, and store, answered with the same results in the same `seq` order, makes the same calls with the same
54
+ * arguments and produces the same output, on any VM with the same fingerprint. A host can therefore replay it
55
+ * after a restart. The VM runs in UTC, its clock reads `startedAt` and then the `now` of the result being
56
+ * processed, its randomness comes from `seed`, and `WeakRef` and `FinalizationRegistry` do not exist.
57
+ *
58
+ * The sandbox's own tools and globals are not used: the run declares its own, and every call goes to
59
+ * `options.onCall`. Never rejects for script failures; abort through `options.signal` to end the run with an
60
+ * error the script cannot catch.
61
+ */
62
+ start(code: string, options: CodemodeRunOptions): CodemodeRun;
51
63
  /** Aborts in-flight executions (they resolve with `kind: "aborted"`) and rejects new ones. */
52
64
  close(): Promise<void>;
53
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/runtime/execution.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAGX,aAAa,EACb,sBAAsB,EAEtB,cAAc,EACd,0BAA0B,EAE1B,YAAY,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,mBAAmB,EAExB,KAAK,WAAW,EAEhB,MAAM,eAAe,CAAC;AAgBvB,4DAA4D;AAC5D,MAAM,WAAW,QAAQ;IACxB,kGAAkG;IAClG,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,gGAAgG;IAChG,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CACpC;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACzB,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACzC,qEAAqE;IACrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAEjG,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD;AAkRD;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,OAAO,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAkBlE;IAED,iEAAiE;IACjE,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAGrC;IAED,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpC;IAED,IAAI,KAAK,IAAI,YAAY,EAAE,CAE1B;IAED,IAAI,OAAO,IAAI,YAAY,EAAE,CAE5B;IAED;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAcnF;IAED,8FAA8F;IACxF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CACD"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/runtime/execution.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAMX,aAAa,EACb,sBAAsB,EAGtB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,0BAA0B,EAE1B,YAAY,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,mBAAmB,EAExB,KAAK,WAAW,EAEhB,MAAM,eAAe,CAAC;AAgBvB,4DAA4D;AAC5D,MAAM,WAAW,QAAQ;IACxB,kGAAkG;IAClG,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,gGAAgG;IAChG,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CACpC;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACzB,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACzC,kGAAkG;IAClG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAEjG,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD;AA6WD;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,OAAO,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAOlE;IAED,iEAAiE;IACjE,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAGrC;IAED,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpC;IAED,IAAI,KAAK,IAAI,YAAY,EAAE,CAE1B;IAED,IAAI,OAAO,IAAI,YAAY,EAAE,CAE5B;IAED;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAgBnF;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAoC5D;IAED,8FAA8F;IACxF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CACD"}
@@ -14,8 +14,8 @@
14
14
  * results go back through {@link VmChannel.post}. Replies produced before the launcher has
15
15
  * returned its channel are queued and flushed when it arrives.
16
16
  * 3. The first terminal event wins: `done`, `crash`, a launcher failure, the deadline, or an abort.
17
- * `finish()` aborts pending tool calls, stops the channel, and resolves the result once the
18
- * channel reports it stopped. Later events are ignored.
17
+ * `finish()` aborts pending tool calls, asks the channel to stop, and resolves the result once
18
+ * that request completes. A worker or remote VM may exit later. Later events are ignored.
19
19
  *
20
20
  * The launcher, not this class, is responsible for actually stopping a running VM: a worker is
21
21
  * terminated, an in-thread VM is interrupted and disposed, and a remote VM is told to stop at its
@@ -94,6 +94,26 @@ function parseScriptError(json) {
94
94
  }
95
95
  return { kind: "script", name, message, stack };
96
96
  }
97
+ /** Checks global names: identifiers or `namespace.member`, not shadowing a built-in global or each other. */
98
+ function checkGlobals(globals) {
99
+ const names = new Set();
100
+ const namespaces = new Set();
101
+ for (const global of globals) {
102
+ const parts = global.name.split(".");
103
+ if (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {
104
+ throw new Error(`Invalid global name "${global.name}"`);
105
+ }
106
+ if (names.has(global.name))
107
+ throw new Error(`Global "${global.name}" is already registered`);
108
+ if (parts.length === 2)
109
+ namespaces.add(parts[0]);
110
+ names.add(global.name);
111
+ }
112
+ for (const name of namespaces) {
113
+ if (names.has(name))
114
+ throw new Error(`Global "${name}" conflicts with the namespace "${name}"`);
115
+ }
116
+ }
97
117
  /** One script run in its own VM. */
98
118
  class Execution {
99
119
  promise;
@@ -101,20 +121,23 @@ class Execution {
101
121
  channel;
102
122
  /** Replies produced before the launcher returned the channel. */
103
123
  unsent = [];
104
- tools;
105
- globals;
124
+ executors;
125
+ control;
126
+ /** Result numbers `deliver()` used. */
127
+ delivered = new Set();
106
128
  signal;
107
129
  timer;
108
130
  output = [];
109
131
  calls = [];
110
132
  pending = new Map();
133
+ /** Whether the execution has its outcome. */
111
134
  finished = false;
112
135
  constructor(options) {
113
136
  this.promise = new Promise((resolve) => {
114
137
  this.resolveResult = resolve;
115
138
  });
116
- this.tools = options.tools;
117
- this.globals = options.globals;
139
+ this.executors = options.executors;
140
+ this.control = options.control;
118
141
  this.signal = options.signal;
119
142
  if (Number.isFinite(options.timeoutMs)) {
120
143
  this.timer = setTimeout(() => {
@@ -133,17 +156,15 @@ class Execution {
133
156
  return;
134
157
  const data = {
135
158
  code: options.code,
136
- tools: [...options.tools.values()].map((tool) => ({
159
+ tools: options.tools.map((tool) => ({
137
160
  name: tool.name,
138
- jsName: toCodemodeIdentifier(tool.name),
161
+ jsName: tool.jsName ?? toCodemodeIdentifier(tool.name),
139
162
  description: tool.description ?? "",
140
163
  })),
141
- globals: [...options.globals.values()].map((global) => ({
142
- name: global.name,
143
- spread: global.spread === true,
144
- })),
164
+ globals: options.globals.map((global) => ({ name: global.name, spread: global.spread === true })),
145
165
  memoryLimitBytes: options.memoryLimitBytes,
146
166
  store: options.store,
167
+ ...(options.deterministic ? { deterministic: options.deterministic } : {}),
147
168
  };
148
169
  const events = {
149
170
  message: (message) => this.receive(message),
@@ -161,6 +182,47 @@ class Execution {
161
182
  this.finish({ kind: "sandbox", message: errorMessage(error) });
162
183
  });
163
184
  }
185
+ /** `CodemodeRun.deliver()`. */
186
+ deliver(seq, now, id, outcome) {
187
+ if (this.finished)
188
+ return;
189
+ if (!Number.isFinite(now))
190
+ throw new Error(`The clock value of result ${seq} is not a finite number`);
191
+ if (!Number.isInteger(seq) || seq < 1 || this.delivered.has(seq)) {
192
+ throw new Error(`Result number ${seq} is not a positive integer used once`);
193
+ }
194
+ const pending = this.pending.get(id);
195
+ if (pending === undefined)
196
+ throw new Error(`Call ${id} is not waiting for a result`);
197
+ if (!outcome.ok && outcome.properties !== undefined) {
198
+ const { properties } = outcome;
199
+ if (typeof properties !== "object" || properties === null || Array.isArray(properties)) {
200
+ throw new Error(`The properties of result ${seq} are not an object`);
201
+ }
202
+ }
203
+ // Serialized before anything is recorded, so a value JSON cannot hold leaves the call waiting for another answer.
204
+ const payload = outcome.ok
205
+ ? outcome.value === undefined
206
+ ? undefined
207
+ : JSON.stringify(outcome.value)
208
+ : outcome.message;
209
+ const properties = !outcome.ok && outcome.properties !== undefined ? JSON.stringify(outcome.properties) : undefined;
210
+ this.delivered.add(seq);
211
+ this.pending.delete(id);
212
+ if (pending.record) {
213
+ pending.record.status = outcome.ok ? "ok" : "error";
214
+ pending.record.durationMs = performance.now() - pending.startedAt;
215
+ }
216
+ this.post({
217
+ type: "result",
218
+ id,
219
+ ok: outcome.ok,
220
+ payload,
221
+ seq,
222
+ now,
223
+ ...(properties === undefined ? {} : { properties }),
224
+ });
225
+ }
164
226
  abort(message) {
165
227
  this.finish({ kind: "aborted", message });
166
228
  return this.promise;
@@ -201,7 +263,16 @@ class Execution {
201
263
  case "call":
202
264
  if (this.pending.has(message.id))
203
265
  throw new BridgeError(`duplicate call id ${message.id}`);
204
- void this.handleCall(message);
266
+ if (this.control)
267
+ this.forwardCall(message, this.control);
268
+ else
269
+ void this.handleCall(message);
270
+ break;
271
+ case "started":
272
+ this.control?.onStarted?.(message.fingerprint);
273
+ break;
274
+ case "idle":
275
+ this.control?.onIdle?.(message.seq, message.issued);
205
276
  break;
206
277
  case "done":
207
278
  this.handleDone(message);
@@ -214,11 +285,21 @@ class Execution {
214
285
  handleDone(message) {
215
286
  // Decode everything before finish(), which must not throw once it starts.
216
287
  if (!message.ok) {
217
- this.finish(parseScriptError(message.error));
288
+ this.finish(parseScriptError(message.error), undefined, undefined, message.during);
218
289
  return;
219
290
  }
220
291
  const value = message.value === undefined ? undefined : parseBridgeJson(message.value, "return value");
221
- this.finish(undefined, value, parseStoreWrites(message.writes));
292
+ this.finish(undefined, value, parseStoreWrites(message.writes), message.during);
293
+ }
294
+ /** A host-controlled run: record the call and hand it to the caller, which answers with `deliver()`. */
295
+ forwardCall(message, control) {
296
+ const { id, name, target } = message;
297
+ const args = message.args === undefined ? undefined : parseBridgeJson(message.args, "call arguments");
298
+ const record = target === "tool" ? { name, status: "cancelled", durationMs: 0 } : undefined;
299
+ if (record)
300
+ this.calls.push(record);
301
+ this.pending.set(id, { record, startedAt: performance.now(), controller: new AbortController() });
302
+ control.onCall({ id, target, name, args });
222
303
  }
223
304
  async handleCall(message) {
224
305
  const { id, name } = message;
@@ -231,7 +312,7 @@ class Execution {
231
312
  let status;
232
313
  let reply;
233
314
  try {
234
- const tool = (isTool ? this.tools : this.globals).get(name);
315
+ const tool = (isTool ? this.executors.tools : this.executors.globals).get(name);
235
316
  if (!tool)
236
317
  throw new Error(`Unknown ${isTool ? "tool" : "global"} "${name}"`);
237
318
  const args = message.args === undefined ? undefined : JSON.parse(message.args);
@@ -253,7 +334,7 @@ class Execution {
253
334
  }
254
335
  this.post(reply);
255
336
  }
256
- finish(error, value, writes) {
337
+ finish(error, value, writes, during) {
257
338
  if (this.finished)
258
339
  return;
259
340
  this.finished = true;
@@ -267,14 +348,16 @@ class Execution {
267
348
  }
268
349
  this.pending.clear();
269
350
  this.unsent = [];
351
+ const ended = during === undefined ? {} : { during: { seq: during.seq, issued: during.issued } };
270
352
  const result = error
271
- ? { ok: false, error, output: this.output, calls: this.calls }
353
+ ? { ok: false, error, output: this.output, calls: this.calls, ...ended }
272
354
  : {
273
355
  ok: true,
274
356
  value,
275
357
  output: this.output,
276
358
  calls: this.calls,
277
359
  storeWrites: writes ?? { set: {}, delete: [] },
360
+ ...ended,
278
361
  };
279
362
  if (!this.channel) {
280
363
  this.resolveResult(result);
@@ -309,22 +392,9 @@ export class CodemodeSandboxBase {
309
392
  this.launch = launch;
310
393
  for (const tool of options.tools ?? [])
311
394
  this.registerTool(tool);
312
- const namespaces = new Set();
313
- for (const global of options.globals ?? []) {
314
- const parts = global.name.split(".");
315
- if (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {
316
- throw new Error(`Invalid global name "${global.name}"`);
317
- }
318
- if (this.globalsByName.has(global.name))
319
- throw new Error(`Global "${global.name}" is already registered`);
320
- if (parts.length === 2)
321
- namespaces.add(parts[0]);
395
+ checkGlobals(options.globals ?? []);
396
+ for (const global of options.globals ?? [])
322
397
  this.globalsByName.set(global.name, global);
323
- }
324
- for (const name of namespaces) {
325
- if (this.globalsByName.has(name))
326
- throw new Error(`Global "${name}" conflicts with the namespace "${name}"`);
327
- }
328
398
  }
329
399
  /** Throws if a tool with the same name is already registered. */
330
400
  registerTool(tool) {
@@ -349,10 +419,12 @@ export class CodemodeSandboxBase {
349
419
  execute(code, options = {}) {
350
420
  if (this.closed)
351
421
  return Promise.reject(new Error("Sandbox is closed"));
422
+ const tools = new Map(this.toolsByName);
352
423
  const execution = new Execution({
353
424
  code,
354
- tools: new Map(this.toolsByName),
355
- globals: this.globalsByName,
425
+ tools: [...tools.values()],
426
+ globals: [...this.globalsByName.values()],
427
+ executors: { tools, globals: this.globalsByName },
356
428
  timeoutMs: options.timeoutMs ?? this.timeoutMs,
357
429
  signal: options.signal,
358
430
  memoryLimitBytes: this.memoryLimitBytes,
@@ -362,6 +434,57 @@ export class CodemodeSandboxBase {
362
434
  this.running.add(execution);
363
435
  return execution.promise.finally(() => this.running.delete(execution));
364
436
  }
437
+ /**
438
+ * Run `code` deterministically, with the caller answering its calls: the same script, start time, seed, tools,
439
+ * globals, and store, answered with the same results in the same `seq` order, makes the same calls with the same
440
+ * arguments and produces the same output, on any VM with the same fingerprint. A host can therefore replay it
441
+ * after a restart. The VM runs in UTC, its clock reads `startedAt` and then the `now` of the result being
442
+ * processed, its randomness comes from `seed`, and `WeakRef` and `FinalizationRegistry` do not exist.
443
+ *
444
+ * The sandbox's own tools and globals are not used: the run declares its own, and every call goes to
445
+ * `options.onCall`. Never rejects for script failures; abort through `options.signal` to end the run with an
446
+ * error the script cannot catch.
447
+ */
448
+ start(code, options) {
449
+ if (this.closed)
450
+ throw new Error("Sandbox is closed");
451
+ if (!Number.isFinite(options.startedAt) || options.startedAt < 0) {
452
+ throw new Error("startedAt must be a non-negative number of milliseconds since the epoch");
453
+ }
454
+ if (!Number.isInteger(options.seed) || options.seed < 0 || options.seed > 0xffffffff) {
455
+ throw new Error("seed must be a 32-bit unsigned integer");
456
+ }
457
+ const tools = options.tools ?? [];
458
+ if (new Set(tools.map((tool) => tool.name)).size !== tools.length)
459
+ throw new Error("Tool names must be unique");
460
+ const scriptNames = tools.map((tool) => tool.jsName ?? toCodemodeIdentifier(tool.name));
461
+ if (new Set(scriptNames).size !== tools.length)
462
+ throw new Error("Tool script names must be unique");
463
+ const globals = options.globals ?? [];
464
+ checkGlobals(globals);
465
+ const execution = new Execution({
466
+ code,
467
+ tools,
468
+ globals,
469
+ executors: { tools: new Map(), globals: new Map() },
470
+ timeoutMs: options.timeoutMs ?? Number.POSITIVE_INFINITY,
471
+ signal: options.signal,
472
+ memoryLimitBytes: this.memoryLimitBytes,
473
+ store: serializeStore(options.store),
474
+ deterministic: { startedAt: options.startedAt, seed: options.seed },
475
+ control: { onStarted: options.onStarted, onCall: options.onCall, onIdle: options.onIdle },
476
+ launch: this.launch,
477
+ });
478
+ this.running.add(execution);
479
+ const result = execution.promise.finally(() => this.running.delete(execution));
480
+ return {
481
+ result,
482
+ deliver: (seq, now, id, outcome) => execution.deliver(seq, now, id, outcome),
483
+ get finished() {
484
+ return execution.finished;
485
+ },
486
+ };
487
+ }
365
488
  /** Aborts in-flight executions (they resolve with `kind: "aborted"`) and rejects new ones. */
366
489
  async close() {
367
490
  this.closed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/runtime/execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host side of an execution, shared by every place a VM can run.\n *\n * The host owns everything the script must not influence: the tool table, call records, output,\n * the deadline, the caller's abort signal, and the decoding of what the VM reports. The VM itself\n * runs somewhere a {@link VmLauncher} decides: a worker thread (`CodemodeSandbox`), the calling\n * thread (`InlineCodemodeSandbox`), or another isolate reached over RPC (`RemoteCodemodeSandbox`).\n * The two sides only exchange the messages in `protocol.ts`, so the launchers differ in transport\n * and termination, not in behavior.\n *\n * Lifecycle of one execution:\n * 1. The constructor arms the deadline and abort listener, then asks the launcher for a channel.\n * 2. Messages from the VM arrive through {@link VmEvents.message}; tool calls run here and their\n * results go back through {@link VmChannel.post}. Replies produced before the launcher has\n * returned its channel are queued and flushed when it arrives.\n * 3. The first terminal event wins: `done`, `crash`, a launcher failure, the deadline, or an abort.\n * `finish()` aborts pending tool calls, stops the channel, and resolves the result once the\n * channel reports it stopped. Later events are ignored.\n *\n * The launcher, not this class, is responsible for actually stopping a running VM: a worker is\n * terminated, an in-thread VM is interrupted and disposed, and a remote VM is told to stop at its\n * next exchange.\n */\nimport { toCodemodeIdentifier } from \"../identifier.ts\";\nimport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeExecuteOptions,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n} from \"../types.ts\";\nimport {\n\ttype HostToWorkerMessage,\n\tisWorkerToHostMessage,\n\ttype VmStartData,\n\ttype WorkerToHostMessage,\n} from \"./protocol.ts\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst RESERVED_GLOBALS: ReadonlySet<string> = new Set([\n\t\"tools\",\n\t\"ALL_TOOLS\",\n\t\"console\",\n\t\"text\",\n\t\"image\",\n\t\"exit\",\n\t\"globalThis\",\n\t\"store\",\n\t\"load\",\n]);\n\n/** Callbacks a launcher uses to report what its VM does. */\nexport interface VmEvents {\n\t/** A message from the VM. Validated here, so launchers can pass through anything they receive. */\n\tmessage(message: unknown): void;\n\t/** The VM failed or stopped outside the bridge, for example a worker exit or a remote error. */\n\tfailure(error: CodemodeError): void;\n}\n\n/** The host's handle on a running VM. */\nexport interface VmChannel {\n\tpost(message: HostToWorkerMessage): void;\n\t/** Stops the VM. Called once, after the execution has its result. */\n\tstop(): Promise<void>;\n}\n\n/**\n * Starts a VM for one execution. Rejections become `sandbox` errors with the rejection's message.\n * The VM may start reporting messages before the returned promise settles.\n */\nexport type VmLauncher = (data: VmStartData, events: VmEvents) => VmChannel | Promise<VmChannel>;\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction serializeStore(store: Readonly<Record<string, unknown>> | undefined): Record<string, string> {\n\tconst serialized: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(store ?? {})) {\n\t\tconst json = JSON.stringify(value);\n\t\tif (json !== undefined) serialized[key] = json;\n\t}\n\treturn serialized;\n}\n\n/**\n * The prelude that serializes values for the host runs in the same VM as the script, so a script\n * that patches built-ins (for example `Array.prototype.toJSON`) can make it send malformed data.\n * Payloads that do not decode throw this error, and the execution fails as a sandbox error.\n */\nclass BridgeError extends Error {}\n\nfunction parseBridgeJson(json: string, what: string): unknown {\n\ttry {\n\t\treturn JSON.parse(json);\n\t} catch {\n\t\tthrow new BridgeError(`${what} is not valid JSON`);\n\t}\n}\n\nfunction parseStoreWrites(json: string): CodemodeStoreWrites {\n\tconst entries = parseBridgeJson(json, \"store writes\");\n\tif (!Array.isArray(entries)) throw new BridgeError(\"store writes are not an array\");\n\tconst writes: CodemodeStoreWrites = { set: {}, delete: [] };\n\tfor (const entry of entries) {\n\t\tif (\n\t\t\t!Array.isArray(entry) ||\n\t\t\ttypeof entry[0] !== \"string\" ||\n\t\t\t(entry.length === 2 ? typeof entry[1] !== \"string\" : entry.length !== 1)\n\t\t) {\n\t\t\tthrow new BridgeError(\"store writes contain a malformed entry\");\n\t\t}\n\t\tconst [key, value] = entry as [string, string?];\n\t\tif (value === undefined) writes.delete.push(key);\n\t\telse writes.set[key] = parseBridgeJson(value, `store value for ${JSON.stringify(key)}`);\n\t}\n\treturn writes;\n}\n\nfunction parseScriptError(json: string): CodemodeError {\n\tconst parsed = parseBridgeJson(json, \"script error\");\n\tif (typeof parsed !== \"object\" || parsed === null) throw new BridgeError(\"script error is not an object\");\n\tconst { name, message, stack } = parsed as Record<string, unknown>;\n\tif (\n\t\ttypeof message !== \"string\" ||\n\t\t(name !== undefined && typeof name !== \"string\") ||\n\t\t(stack !== undefined && typeof stack !== \"string\")\n\t) {\n\t\tthrow new BridgeError(\"script error is malformed\");\n\t}\n\treturn { kind: \"script\", name, message, stack };\n}\n\ninterface PendingCall {\n\trecord: CodemodeCall | undefined;\n\tstartedAt: number;\n\tcontroller: AbortController;\n}\n\ninterface ExecutionOptions {\n\tcode: string;\n\ttools: ReadonlyMap<string, CodemodeTool>;\n\tglobals: ReadonlyMap<string, CodemodeTool>;\n\ttimeoutMs: number;\n\tsignal: AbortSignal | undefined;\n\tmemoryLimitBytes: number | undefined;\n\tstore: Record<string, string>;\n\tlaunch: VmLauncher;\n}\n\n/** One script run in its own VM. */\nclass Execution {\n\treadonly promise: Promise<CodemodeResult>;\n\tprivate resolveResult!: (result: CodemodeResult) => void;\n\tprivate channel: VmChannel | undefined;\n\t/** Replies produced before the launcher returned the channel. */\n\tprivate unsent: HostToWorkerMessage[] = [];\n\tprivate readonly tools: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly globals: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly signal: AbortSignal | undefined;\n\tprivate readonly timer: ReturnType<typeof setTimeout> | undefined;\n\tprivate readonly output: CodemodeOutputItem[] = [];\n\tprivate readonly calls: CodemodeCall[] = [];\n\tprivate readonly pending = new Map<number, PendingCall>();\n\tprivate finished = false;\n\n\tconstructor(options: ExecutionOptions) {\n\t\tthis.promise = new Promise<CodemodeResult>((resolve) => {\n\t\t\tthis.resolveResult = resolve;\n\t\t});\n\t\tthis.tools = options.tools;\n\t\tthis.globals = options.globals;\n\t\tthis.signal = options.signal;\n\n\t\tif (Number.isFinite(options.timeoutMs)) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.finish({ kind: \"timeout\", message: `Execution timed out after ${options.timeoutMs} ms` });\n\t\t\t}, options.timeoutMs);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tif (options.signal.aborted) {\n\t\t\t\tthis.onAbort();\n\t\t\t} else {\n\t\t\t\toptions.signal.addEventListener(\"abort\", this.onAbort, { once: true });\n\t\t\t}\n\t\t}\n\t\tif (this.finished) return;\n\n\t\tconst data: VmStartData = {\n\t\t\tcode: options.code,\n\t\t\ttools: [...options.tools.values()].map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tjsName: toCodemodeIdentifier(tool.name),\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t})),\n\t\t\tglobals: [...options.globals.values()].map((global) => ({\n\t\t\t\tname: global.name,\n\t\t\t\tspread: global.spread === true,\n\t\t\t})),\n\t\t\tmemoryLimitBytes: options.memoryLimitBytes,\n\t\t\tstore: options.store,\n\t\t};\n\t\tconst events: VmEvents = {\n\t\t\tmessage: (message) => this.receive(message),\n\t\t\tfailure: (error) => this.finish(error),\n\t\t};\n\t\tnew Promise<VmChannel>((resolve) => resolve(options.launch(data, events))).then(\n\t\t\t(channel) => {\n\t\t\t\tif (this.finished) {\n\t\t\t\t\tvoid channel.stop().catch(() => undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.channel = channel;\n\t\t\t\tfor (const message of this.unsent.splice(0)) channel.post(message);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: errorMessage(error) });\n\t\t\t},\n\t\t);\n\t}\n\n\tabort(message: string): Promise<CodemodeResult> {\n\t\tthis.finish({ kind: \"aborted\", message });\n\t\treturn this.promise;\n\t}\n\n\tprivate readonly onAbort = (): void => {\n\t\tconst reason: unknown = this.signal?.reason;\n\t\tthis.finish({ kind: \"aborted\", message: reason instanceof Error ? reason.message : \"Execution aborted\" });\n\t};\n\n\tprivate post(message: HostToWorkerMessage): void {\n\t\tif (this.channel) this.channel.post(message);\n\t\telse this.unsent.push(message);\n\t}\n\n\t/** An exception here would escape into the launcher's transport and leave the execution unsettled. */\n\tprivate receive(message: unknown): void {\n\t\ttry {\n\t\t\tthis.handleMessage(message);\n\t\t} catch (error) {\n\t\t\tthis.finish({\n\t\t\t\tkind: \"sandbox\",\n\t\t\t\tmessage:\n\t\t\t\t\terror instanceof BridgeError\n\t\t\t\t\t\t? `Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.`\n\t\t\t\t\t\t: `Sandbox host failed: ${errorMessage(error)}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleMessage(message: unknown): void {\n\t\tif (this.finished) return;\n\t\tif (!isWorkerToHostMessage(message)) throw new BridgeError(\"unknown message from the worker\");\n\t\tswitch (message.type) {\n\t\t\tcase \"output\":\n\t\t\t\tthis.output.push(message.item);\n\t\t\t\tbreak;\n\t\t\tcase \"call\":\n\t\t\t\tif (this.pending.has(message.id)) throw new BridgeError(`duplicate call id ${message.id}`);\n\t\t\t\tvoid this.handleCall(message);\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tthis.handleDone(message);\n\t\t\t\tbreak;\n\t\t\tcase \"crash\":\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: message.message });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleDone(message: Extract<WorkerToHostMessage, { type: \"done\" }>): void {\n\t\t// Decode everything before finish(), which must not throw once it starts.\n\t\tif (!message.ok) {\n\t\t\tthis.finish(parseScriptError(message.error));\n\t\t\treturn;\n\t\t}\n\t\tconst value = message.value === undefined ? undefined : parseBridgeJson(message.value, \"return value\");\n\t\tthis.finish(undefined, value, parseStoreWrites(message.writes));\n\t}\n\n\tprivate async handleCall(message: Extract<WorkerToHostMessage, { type: \"call\" }>): Promise<void> {\n\t\tconst { id, name } = message;\n\t\tconst isTool = message.target === \"tool\";\n\t\tconst record: CodemodeCall | undefined = isTool ? { name, status: \"cancelled\", durationMs: 0 } : undefined;\n\t\tif (record) this.calls.push(record);\n\t\tconst pending: PendingCall = { record, startedAt: performance.now(), controller: new AbortController() };\n\t\tthis.pending.set(id, pending);\n\n\t\tlet status: CodemodeCallStatus;\n\t\tlet reply: HostToWorkerMessage;\n\t\ttry {\n\t\t\tconst tool = (isTool ? this.tools : this.globals).get(name);\n\t\t\tif (!tool) throw new Error(`Unknown ${isTool ? \"tool\" : \"global\"} \"${name}\"`);\n\t\t\tconst args: unknown = message.args === undefined ? undefined : JSON.parse(message.args);\n\t\t\tconst value = await tool.execute(args, { signal: pending.controller.signal });\n\t\t\treply = { type: \"result\", id, ok: true, payload: value === undefined ? undefined : JSON.stringify(value) };\n\t\t\tstatus = \"ok\";\n\t\t} catch (error) {\n\t\t\treply = { type: \"result\", id, ok: false, payload: errorMessage(error) };\n\t\t\tstatus = \"error\";\n\t\t}\n\n\t\t// Already cancelled by finish(): the record keeps \"cancelled\" and the\n\t\t// VM is gone or going.\n\t\tif (!this.pending.delete(id)) return;\n\t\tif (record) {\n\t\t\trecord.status = status;\n\t\t\trecord.durationMs = performance.now() - pending.startedAt;\n\t\t}\n\t\tthis.post(reply);\n\t}\n\n\tprivate finish(error: CodemodeError | undefined, value?: unknown, writes?: CodemodeStoreWrites): void {\n\t\tif (this.finished) return;\n\t\tthis.finished = true;\n\t\tclearTimeout(this.timer);\n\t\tthis.signal?.removeEventListener(\"abort\", this.onAbort);\n\n\t\tconst now = performance.now();\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tif (pending.record) pending.record.durationMs = now - pending.startedAt;\n\t\t\tpending.controller.abort();\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.unsent = [];\n\n\t\tconst result: CodemodeResult = error\n\t\t\t? { ok: false, error, output: this.output, calls: this.calls }\n\t\t\t: {\n\t\t\t\t\tok: true,\n\t\t\t\t\tvalue,\n\t\t\t\t\toutput: this.output,\n\t\t\t\t\tcalls: this.calls,\n\t\t\t\t\tstoreWrites: writes ?? { set: {}, delete: [] },\n\t\t\t\t};\n\t\tif (!this.channel) {\n\t\t\tthis.resolveResult(result);\n\t\t\treturn;\n\t\t}\n\t\tthis.channel\n\t\t\t.stop()\n\t\t\t.catch(() => undefined)\n\t\t\t.then(() => this.resolveResult(result));\n\t}\n}\n\n/**\n * Tool table, defaults, and in-flight executions; the behavior every sandbox shares. Subclasses\n * only choose where the VM runs by passing a {@link VmLauncher}.\n *\n * The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`, the output helpers\n * `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the configured globals; nothing\n * else (no timers, `fetch`, `process`, `require`, modules). Each `execute()` gets its own VM; the\n * sandbox only holds the tool table and defaults. `close()` aborts in-flight executions.\n */\nexport class CodemodeSandboxBase {\n\tprivate readonly toolsByName = new Map<string, CodemodeTool>();\n\tprivate readonly globalsByName = new Map<string, CodemodeTool>();\n\tprivate readonly timeoutMs: number;\n\tprivate readonly memoryLimitBytes: number | undefined;\n\tprivate readonly launch: VmLauncher;\n\tprivate readonly running = new Set<Execution>();\n\tprivate closed = false;\n\n\tconstructor(options: CodemodeSandboxBaseOptions, launch: VmLauncher) {\n\t\tthis.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.memoryLimitBytes = options.memoryLimitBytes;\n\t\tthis.launch = launch;\n\t\tfor (const tool of options.tools ?? []) this.registerTool(tool);\n\t\tconst namespaces = new Set<string>();\n\t\tfor (const global of options.globals ?? []) {\n\t\t\tconst parts = global.name.split(\".\");\n\t\t\tif (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {\n\t\t\t\tthrow new Error(`Invalid global name \"${global.name}\"`);\n\t\t\t}\n\t\t\tif (this.globalsByName.has(global.name)) throw new Error(`Global \"${global.name}\" is already registered`);\n\t\t\tif (parts.length === 2) namespaces.add(parts[0]);\n\t\t\tthis.globalsByName.set(global.name, global);\n\t\t}\n\t\tfor (const name of namespaces) {\n\t\t\tif (this.globalsByName.has(name)) throw new Error(`Global \"${name}\" conflicts with the namespace \"${name}\"`);\n\t\t}\n\t}\n\n\t/** Throws if a tool with the same name is already registered. */\n\tregisterTool(tool: CodemodeTool): void {\n\t\tif (this.toolsByName.has(tool.name)) throw new Error(`Tool \"${tool.name}\" is already registered`);\n\t\tthis.toolsByName.set(tool.name, tool);\n\t}\n\n\tunregisterTool(name: string): boolean {\n\t\treturn this.toolsByName.delete(name);\n\t}\n\n\tget tools(): CodemodeTool[] {\n\t\treturn [...this.toolsByName.values()];\n\t}\n\n\tget globals(): CodemodeTool[] {\n\t\treturn [...this.globalsByName.values()];\n\t}\n\n\t/**\n\t * `code` is an async function body: `return` and top-level `await` work.\n\t * Never rejects for script failures; those come back as `{ ok: false }`.\n\t * The script can use `store(key, value)` and `load(key)` on `options.store`.\n\t */\n\texecute(code: string, options: CodemodeExecuteOptions = {}): Promise<CodemodeResult> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Sandbox is closed\"));\n\t\tconst execution = new Execution({\n\t\t\tcode,\n\t\t\ttools: new Map(this.toolsByName),\n\t\t\tglobals: this.globalsByName,\n\t\t\ttimeoutMs: options.timeoutMs ?? this.timeoutMs,\n\t\t\tsignal: options.signal,\n\t\t\tmemoryLimitBytes: this.memoryLimitBytes,\n\t\t\tstore: serializeStore(options.store),\n\t\t\tlaunch: this.launch,\n\t\t});\n\t\tthis.running.add(execution);\n\t\treturn execution.promise.finally(() => this.running.delete(execution));\n\t}\n\n\t/** Aborts in-flight executions (they resolve with `kind: \"aborted\"`) and rejects new ones. */\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tawait Promise.all([...this.running].map((execution) => execution.abort(\"Sandbox closed\")));\n\t}\n}\n"]}
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/runtime/execution.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host side of an execution, shared by every place a VM can run.\n *\n * The host owns everything the script must not influence: the tool table, call records, output,\n * the deadline, the caller's abort signal, and the decoding of what the VM reports. The VM itself\n * runs somewhere a {@link VmLauncher} decides: a worker thread (`CodemodeSandbox`), the calling\n * thread (`InlineCodemodeSandbox`), or another isolate reached over RPC (`RemoteCodemodeSandbox`).\n * The two sides only exchange the messages in `protocol.ts`, so the launchers differ in transport\n * and termination, not in behavior.\n *\n * Lifecycle of one execution:\n * 1. The constructor arms the deadline and abort listener, then asks the launcher for a channel.\n * 2. Messages from the VM arrive through {@link VmEvents.message}; tool calls run here and their\n * results go back through {@link VmChannel.post}. Replies produced before the launcher has\n * returned its channel are queued and flushed when it arrives.\n * 3. The first terminal event wins: `done`, `crash`, a launcher failure, the deadline, or an abort.\n * `finish()` aborts pending tool calls, asks the channel to stop, and resolves the result once\n * that request completes. A worker or remote VM may exit later. Later events are ignored.\n *\n * The launcher, not this class, is responsible for actually stopping a running VM: a worker is\n * terminated, an in-thread VM is interrupted and disposed, and a remote VM is told to stop at its\n * next exchange.\n */\nimport { toCodemodeIdentifier } from \"../identifier.ts\";\nimport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeDeclaredGlobal,\n\tCodemodeDeclaredTool,\n\tCodemodeDuring,\n\tCodemodeError,\n\tCodemodeExecuteOptions,\n\tCodemodeOutcome,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeRun,\n\tCodemodeRunOptions,\n\tCodemodeSandboxBaseOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n} from \"../types.ts\";\nimport {\n\ttype HostToWorkerMessage,\n\tisWorkerToHostMessage,\n\ttype VmStartData,\n\ttype WorkerToHostMessage,\n} from \"./protocol.ts\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst RESERVED_GLOBALS: ReadonlySet<string> = new Set([\n\t\"tools\",\n\t\"ALL_TOOLS\",\n\t\"console\",\n\t\"text\",\n\t\"image\",\n\t\"exit\",\n\t\"globalThis\",\n\t\"store\",\n\t\"load\",\n]);\n\n/** Callbacks a launcher uses to report what its VM does. */\nexport interface VmEvents {\n\t/** A message from the VM. Validated here, so launchers can pass through anything they receive. */\n\tmessage(message: unknown): void;\n\t/** The VM failed or stopped outside the bridge, for example a worker exit or a remote error. */\n\tfailure(error: CodemodeError): void;\n}\n\n/** The host's handle on a running VM. */\nexport interface VmChannel {\n\tpost(message: HostToWorkerMessage): void;\n\t/** Requests VM shutdown. Called once; may resolve before a worker or remote VM actually exits. */\n\tstop(): Promise<void>;\n}\n\n/**\n * Starts a VM for one execution. Rejections become `sandbox` errors with the rejection's message.\n * The VM may start reporting messages before the returned promise settles.\n */\nexport type VmLauncher = (data: VmStartData, events: VmEvents) => VmChannel | Promise<VmChannel>;\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction serializeStore(store: Readonly<Record<string, unknown>> | undefined): Record<string, string> {\n\tconst serialized: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(store ?? {})) {\n\t\tconst json = JSON.stringify(value);\n\t\tif (json !== undefined) serialized[key] = json;\n\t}\n\treturn serialized;\n}\n\n/**\n * The prelude that serializes values for the host runs in the same VM as the script, so a script\n * that patches built-ins (for example `Array.prototype.toJSON`) can make it send malformed data.\n * Payloads that do not decode throw this error, and the execution fails as a sandbox error.\n */\nclass BridgeError extends Error {}\n\nfunction parseBridgeJson(json: string, what: string): unknown {\n\ttry {\n\t\treturn JSON.parse(json);\n\t} catch {\n\t\tthrow new BridgeError(`${what} is not valid JSON`);\n\t}\n}\n\nfunction parseStoreWrites(json: string): CodemodeStoreWrites {\n\tconst entries = parseBridgeJson(json, \"store writes\");\n\tif (!Array.isArray(entries)) throw new BridgeError(\"store writes are not an array\");\n\tconst writes: CodemodeStoreWrites = { set: {}, delete: [] };\n\tfor (const entry of entries) {\n\t\tif (\n\t\t\t!Array.isArray(entry) ||\n\t\t\ttypeof entry[0] !== \"string\" ||\n\t\t\t(entry.length === 2 ? typeof entry[1] !== \"string\" : entry.length !== 1)\n\t\t) {\n\t\t\tthrow new BridgeError(\"store writes contain a malformed entry\");\n\t\t}\n\t\tconst [key, value] = entry as [string, string?];\n\t\tif (value === undefined) writes.delete.push(key);\n\t\telse writes.set[key] = parseBridgeJson(value, `store value for ${JSON.stringify(key)}`);\n\t}\n\treturn writes;\n}\n\nfunction parseScriptError(json: string): CodemodeError {\n\tconst parsed = parseBridgeJson(json, \"script error\");\n\tif (typeof parsed !== \"object\" || parsed === null) throw new BridgeError(\"script error is not an object\");\n\tconst { name, message, stack } = parsed as Record<string, unknown>;\n\tif (\n\t\ttypeof message !== \"string\" ||\n\t\t(name !== undefined && typeof name !== \"string\") ||\n\t\t(stack !== undefined && typeof stack !== \"string\")\n\t) {\n\t\tthrow new BridgeError(\"script error is malformed\");\n\t}\n\treturn { kind: \"script\", name, message, stack };\n}\n\ninterface PendingCall {\n\trecord: CodemodeCall | undefined;\n\tstartedAt: number;\n\tcontroller: AbortController;\n}\n\n/** Checks global names: identifiers or `namespace.member`, not shadowing a built-in global or each other. */\nfunction checkGlobals(globals: readonly CodemodeDeclaredGlobal[]): void {\n\tconst names = new Set<string>();\n\tconst namespaces = new Set<string>();\n\tfor (const global of globals) {\n\t\tconst parts = global.name.split(\".\");\n\t\tif (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {\n\t\t\tthrow new Error(`Invalid global name \"${global.name}\"`);\n\t\t}\n\t\tif (names.has(global.name)) throw new Error(`Global \"${global.name}\" is already registered`);\n\t\tif (parts.length === 2) namespaces.add(parts[0]);\n\t\tnames.add(global.name);\n\t}\n\tfor (const name of namespaces) {\n\t\tif (names.has(name)) throw new Error(`Global \"${name}\" conflicts with the namespace \"${name}\"`);\n\t}\n}\n\n/** Callbacks of a host-controlled run: its calls go to the caller, which answers them with `deliver()`. */\ntype Control = Pick<CodemodeRunOptions, \"onStarted\" | \"onCall\" | \"onIdle\">;\n\ninterface ExecutionOptions {\n\tcode: string;\n\ttools: readonly CodemodeDeclaredTool[];\n\tglobals: readonly CodemodeDeclaredGlobal[];\n\t/** Run the script's calls; unused when `control` is set. */\n\texecutors: { tools: ReadonlyMap<string, CodemodeTool>; globals: ReadonlyMap<string, CodemodeTool> };\n\ttimeoutMs: number;\n\tsignal: AbortSignal | undefined;\n\tmemoryLimitBytes: number | undefined;\n\tstore: Record<string, string>;\n\tdeterministic?: { startedAt: number; seed: number };\n\tcontrol?: Control;\n\tlaunch: VmLauncher;\n}\n\n/** One script run in its own VM. */\nclass Execution {\n\treadonly promise: Promise<CodemodeResult>;\n\tprivate resolveResult!: (result: CodemodeResult) => void;\n\tprivate channel: VmChannel | undefined;\n\t/** Replies produced before the launcher returned the channel. */\n\tprivate unsent: HostToWorkerMessage[] = [];\n\tprivate readonly executors: ExecutionOptions[\"executors\"];\n\tprivate readonly control: Control | undefined;\n\t/** Result numbers `deliver()` used. */\n\tprivate readonly delivered = new Set<number>();\n\tprivate readonly signal: AbortSignal | undefined;\n\tprivate readonly timer: ReturnType<typeof setTimeout> | undefined;\n\tprivate readonly output: CodemodeOutputItem[] = [];\n\tprivate readonly calls: CodemodeCall[] = [];\n\tprivate readonly pending = new Map<number, PendingCall>();\n\t/** Whether the execution has its outcome. */\n\tfinished = false;\n\n\tconstructor(options: ExecutionOptions) {\n\t\tthis.promise = new Promise<CodemodeResult>((resolve) => {\n\t\t\tthis.resolveResult = resolve;\n\t\t});\n\t\tthis.executors = options.executors;\n\t\tthis.control = options.control;\n\t\tthis.signal = options.signal;\n\n\t\tif (Number.isFinite(options.timeoutMs)) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.finish({ kind: \"timeout\", message: `Execution timed out after ${options.timeoutMs} ms` });\n\t\t\t}, options.timeoutMs);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tif (options.signal.aborted) {\n\t\t\t\tthis.onAbort();\n\t\t\t} else {\n\t\t\t\toptions.signal.addEventListener(\"abort\", this.onAbort, { once: true });\n\t\t\t}\n\t\t}\n\t\tif (this.finished) return;\n\n\t\tconst data: VmStartData = {\n\t\t\tcode: options.code,\n\t\t\ttools: options.tools.map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tjsName: tool.jsName ?? toCodemodeIdentifier(tool.name),\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t})),\n\t\t\tglobals: options.globals.map((global) => ({ name: global.name, spread: global.spread === true })),\n\t\t\tmemoryLimitBytes: options.memoryLimitBytes,\n\t\t\tstore: options.store,\n\t\t\t...(options.deterministic ? { deterministic: options.deterministic } : {}),\n\t\t};\n\t\tconst events: VmEvents = {\n\t\t\tmessage: (message) => this.receive(message),\n\t\t\tfailure: (error) => this.finish(error),\n\t\t};\n\t\tnew Promise<VmChannel>((resolve) => resolve(options.launch(data, events))).then(\n\t\t\t(channel) => {\n\t\t\t\tif (this.finished) {\n\t\t\t\t\tvoid channel.stop().catch(() => undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.channel = channel;\n\t\t\t\tfor (const message of this.unsent.splice(0)) channel.post(message);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: errorMessage(error) });\n\t\t\t},\n\t\t);\n\t}\n\n\t/** `CodemodeRun.deliver()`. */\n\tdeliver(seq: number, now: number, id: number, outcome: CodemodeOutcome): void {\n\t\tif (this.finished) return;\n\t\tif (!Number.isFinite(now)) throw new Error(`The clock value of result ${seq} is not a finite number`);\n\t\tif (!Number.isInteger(seq) || seq < 1 || this.delivered.has(seq)) {\n\t\t\tthrow new Error(`Result number ${seq} is not a positive integer used once`);\n\t\t}\n\t\tconst pending = this.pending.get(id);\n\t\tif (pending === undefined) throw new Error(`Call ${id} is not waiting for a result`);\n\t\tif (!outcome.ok && outcome.properties !== undefined) {\n\t\t\tconst { properties } = outcome;\n\t\t\tif (typeof properties !== \"object\" || properties === null || Array.isArray(properties)) {\n\t\t\t\tthrow new Error(`The properties of result ${seq} are not an object`);\n\t\t\t}\n\t\t}\n\t\t// Serialized before anything is recorded, so a value JSON cannot hold leaves the call waiting for another answer.\n\t\tconst payload = outcome.ok\n\t\t\t? outcome.value === undefined\n\t\t\t\t? undefined\n\t\t\t\t: JSON.stringify(outcome.value)\n\t\t\t: outcome.message;\n\t\tconst properties =\n\t\t\t!outcome.ok && outcome.properties !== undefined ? JSON.stringify(outcome.properties) : undefined;\n\t\tthis.delivered.add(seq);\n\t\tthis.pending.delete(id);\n\t\tif (pending.record) {\n\t\t\tpending.record.status = outcome.ok ? \"ok\" : \"error\";\n\t\t\tpending.record.durationMs = performance.now() - pending.startedAt;\n\t\t}\n\t\tthis.post({\n\t\t\ttype: \"result\",\n\t\t\tid,\n\t\t\tok: outcome.ok,\n\t\t\tpayload,\n\t\t\tseq,\n\t\t\tnow,\n\t\t\t...(properties === undefined ? {} : { properties }),\n\t\t});\n\t}\n\n\tabort(message: string): Promise<CodemodeResult> {\n\t\tthis.finish({ kind: \"aborted\", message });\n\t\treturn this.promise;\n\t}\n\n\tprivate readonly onAbort = (): void => {\n\t\tconst reason: unknown = this.signal?.reason;\n\t\tthis.finish({ kind: \"aborted\", message: reason instanceof Error ? reason.message : \"Execution aborted\" });\n\t};\n\n\tprivate post(message: HostToWorkerMessage): void {\n\t\tif (this.channel) this.channel.post(message);\n\t\telse this.unsent.push(message);\n\t}\n\n\t/** An exception here would escape into the launcher's transport and leave the execution unsettled. */\n\tprivate receive(message: unknown): void {\n\t\ttry {\n\t\t\tthis.handleMessage(message);\n\t\t} catch (error) {\n\t\t\tthis.finish({\n\t\t\t\tkind: \"sandbox\",\n\t\t\t\tmessage:\n\t\t\t\t\terror instanceof BridgeError\n\t\t\t\t\t\t? `Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.`\n\t\t\t\t\t\t: `Sandbox host failed: ${errorMessage(error)}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleMessage(message: unknown): void {\n\t\tif (this.finished) return;\n\t\tif (!isWorkerToHostMessage(message)) throw new BridgeError(\"unknown message from the worker\");\n\t\tswitch (message.type) {\n\t\t\tcase \"output\":\n\t\t\t\tthis.output.push(message.item);\n\t\t\t\tbreak;\n\t\t\tcase \"call\":\n\t\t\t\tif (this.pending.has(message.id)) throw new BridgeError(`duplicate call id ${message.id}`);\n\t\t\t\tif (this.control) this.forwardCall(message, this.control);\n\t\t\t\telse void this.handleCall(message);\n\t\t\t\tbreak;\n\t\t\tcase \"started\":\n\t\t\t\tthis.control?.onStarted?.(message.fingerprint);\n\t\t\t\tbreak;\n\t\t\tcase \"idle\":\n\t\t\t\tthis.control?.onIdle?.(message.seq, message.issued);\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tthis.handleDone(message);\n\t\t\t\tbreak;\n\t\t\tcase \"crash\":\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: message.message });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleDone(message: Extract<WorkerToHostMessage, { type: \"done\" }>): void {\n\t\t// Decode everything before finish(), which must not throw once it starts.\n\t\tif (!message.ok) {\n\t\t\tthis.finish(parseScriptError(message.error), undefined, undefined, message.during);\n\t\t\treturn;\n\t\t}\n\t\tconst value = message.value === undefined ? undefined : parseBridgeJson(message.value, \"return value\");\n\t\tthis.finish(undefined, value, parseStoreWrites(message.writes), message.during);\n\t}\n\n\t/** A host-controlled run: record the call and hand it to the caller, which answers with `deliver()`. */\n\tprivate forwardCall(message: Extract<WorkerToHostMessage, { type: \"call\" }>, control: Control): void {\n\t\tconst { id, name, target } = message;\n\t\tconst args = message.args === undefined ? undefined : parseBridgeJson(message.args, \"call arguments\");\n\t\tconst record: CodemodeCall | undefined =\n\t\t\ttarget === \"tool\" ? { name, status: \"cancelled\", durationMs: 0 } : undefined;\n\t\tif (record) this.calls.push(record);\n\t\tthis.pending.set(id, { record, startedAt: performance.now(), controller: new AbortController() });\n\t\tcontrol.onCall({ id, target, name, args });\n\t}\n\n\tprivate async handleCall(message: Extract<WorkerToHostMessage, { type: \"call\" }>): Promise<void> {\n\t\tconst { id, name } = message;\n\t\tconst isTool = message.target === \"tool\";\n\t\tconst record: CodemodeCall | undefined = isTool ? { name, status: \"cancelled\", durationMs: 0 } : undefined;\n\t\tif (record) this.calls.push(record);\n\t\tconst pending: PendingCall = { record, startedAt: performance.now(), controller: new AbortController() };\n\t\tthis.pending.set(id, pending);\n\n\t\tlet status: CodemodeCallStatus;\n\t\tlet reply: HostToWorkerMessage;\n\t\ttry {\n\t\t\tconst tool = (isTool ? this.executors.tools : this.executors.globals).get(name);\n\t\t\tif (!tool) throw new Error(`Unknown ${isTool ? \"tool\" : \"global\"} \"${name}\"`);\n\t\t\tconst args: unknown = message.args === undefined ? undefined : JSON.parse(message.args);\n\t\t\tconst value = await tool.execute(args, { signal: pending.controller.signal });\n\t\t\treply = { type: \"result\", id, ok: true, payload: value === undefined ? undefined : JSON.stringify(value) };\n\t\t\tstatus = \"ok\";\n\t\t} catch (error) {\n\t\t\treply = { type: \"result\", id, ok: false, payload: errorMessage(error) };\n\t\t\tstatus = \"error\";\n\t\t}\n\n\t\t// Already cancelled by finish(): the record keeps \"cancelled\" and the\n\t\t// VM is gone or going.\n\t\tif (!this.pending.delete(id)) return;\n\t\tif (record) {\n\t\t\trecord.status = status;\n\t\t\trecord.durationMs = performance.now() - pending.startedAt;\n\t\t}\n\t\tthis.post(reply);\n\t}\n\n\tprivate finish(\n\t\terror: CodemodeError | undefined,\n\t\tvalue?: unknown,\n\t\twrites?: CodemodeStoreWrites,\n\t\tduring?: CodemodeDuring,\n\t): void {\n\t\tif (this.finished) return;\n\t\tthis.finished = true;\n\t\tclearTimeout(this.timer);\n\t\tthis.signal?.removeEventListener(\"abort\", this.onAbort);\n\n\t\tconst now = performance.now();\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tif (pending.record) pending.record.durationMs = now - pending.startedAt;\n\t\t\tpending.controller.abort();\n\t\t}\n\t\tthis.pending.clear();\n\t\tthis.unsent = [];\n\n\t\tconst ended = during === undefined ? {} : { during: { seq: during.seq, issued: during.issued } };\n\t\tconst result: CodemodeResult = error\n\t\t\t? { ok: false, error, output: this.output, calls: this.calls, ...ended }\n\t\t\t: {\n\t\t\t\t\tok: true,\n\t\t\t\t\tvalue,\n\t\t\t\t\toutput: this.output,\n\t\t\t\t\tcalls: this.calls,\n\t\t\t\t\tstoreWrites: writes ?? { set: {}, delete: [] },\n\t\t\t\t\t...ended,\n\t\t\t\t};\n\t\tif (!this.channel) {\n\t\t\tthis.resolveResult(result);\n\t\t\treturn;\n\t\t}\n\t\tthis.channel\n\t\t\t.stop()\n\t\t\t.catch(() => undefined)\n\t\t\t.then(() => this.resolveResult(result));\n\t}\n}\n\n/**\n * Tool table, defaults, and in-flight executions; the behavior every sandbox shares. Subclasses\n * only choose where the VM runs by passing a {@link VmLauncher}.\n *\n * The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`, the output helpers\n * `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the configured globals; nothing\n * else (no timers, `fetch`, `process`, `require`, modules). Each `execute()` gets its own VM; the\n * sandbox only holds the tool table and defaults. `close()` aborts in-flight executions.\n */\nexport class CodemodeSandboxBase {\n\tprivate readonly toolsByName = new Map<string, CodemodeTool>();\n\tprivate readonly globalsByName = new Map<string, CodemodeTool>();\n\tprivate readonly timeoutMs: number;\n\tprivate readonly memoryLimitBytes: number | undefined;\n\tprivate readonly launch: VmLauncher;\n\tprivate readonly running = new Set<Execution>();\n\tprivate closed = false;\n\n\tconstructor(options: CodemodeSandboxBaseOptions, launch: VmLauncher) {\n\t\tthis.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.memoryLimitBytes = options.memoryLimitBytes;\n\t\tthis.launch = launch;\n\t\tfor (const tool of options.tools ?? []) this.registerTool(tool);\n\t\tcheckGlobals(options.globals ?? []);\n\t\tfor (const global of options.globals ?? []) this.globalsByName.set(global.name, global);\n\t}\n\n\t/** Throws if a tool with the same name is already registered. */\n\tregisterTool(tool: CodemodeTool): void {\n\t\tif (this.toolsByName.has(tool.name)) throw new Error(`Tool \"${tool.name}\" is already registered`);\n\t\tthis.toolsByName.set(tool.name, tool);\n\t}\n\n\tunregisterTool(name: string): boolean {\n\t\treturn this.toolsByName.delete(name);\n\t}\n\n\tget tools(): CodemodeTool[] {\n\t\treturn [...this.toolsByName.values()];\n\t}\n\n\tget globals(): CodemodeTool[] {\n\t\treturn [...this.globalsByName.values()];\n\t}\n\n\t/**\n\t * `code` is an async function body: `return` and top-level `await` work.\n\t * Never rejects for script failures; those come back as `{ ok: false }`.\n\t * The script can use `store(key, value)` and `load(key)` on `options.store`.\n\t */\n\texecute(code: string, options: CodemodeExecuteOptions = {}): Promise<CodemodeResult> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Sandbox is closed\"));\n\t\tconst tools = new Map(this.toolsByName);\n\t\tconst execution = new Execution({\n\t\t\tcode,\n\t\t\ttools: [...tools.values()],\n\t\t\tglobals: [...this.globalsByName.values()],\n\t\t\texecutors: { tools, globals: this.globalsByName },\n\t\t\ttimeoutMs: options.timeoutMs ?? this.timeoutMs,\n\t\t\tsignal: options.signal,\n\t\t\tmemoryLimitBytes: this.memoryLimitBytes,\n\t\t\tstore: serializeStore(options.store),\n\t\t\tlaunch: this.launch,\n\t\t});\n\t\tthis.running.add(execution);\n\t\treturn execution.promise.finally(() => this.running.delete(execution));\n\t}\n\n\t/**\n\t * Run `code` deterministically, with the caller answering its calls: the same script, start time, seed, tools,\n\t * globals, and store, answered with the same results in the same `seq` order, makes the same calls with the same\n\t * arguments and produces the same output, on any VM with the same fingerprint. A host can therefore replay it\n\t * after a restart. The VM runs in UTC, its clock reads `startedAt` and then the `now` of the result being\n\t * processed, its randomness comes from `seed`, and `WeakRef` and `FinalizationRegistry` do not exist.\n\t *\n\t * The sandbox's own tools and globals are not used: the run declares its own, and every call goes to\n\t * `options.onCall`. Never rejects for script failures; abort through `options.signal` to end the run with an\n\t * error the script cannot catch.\n\t */\n\tstart(code: string, options: CodemodeRunOptions): CodemodeRun {\n\t\tif (this.closed) throw new Error(\"Sandbox is closed\");\n\t\tif (!Number.isFinite(options.startedAt) || options.startedAt < 0) {\n\t\t\tthrow new Error(\"startedAt must be a non-negative number of milliseconds since the epoch\");\n\t\t}\n\t\tif (!Number.isInteger(options.seed) || options.seed < 0 || options.seed > 0xffffffff) {\n\t\t\tthrow new Error(\"seed must be a 32-bit unsigned integer\");\n\t\t}\n\t\tconst tools = options.tools ?? [];\n\t\tif (new Set(tools.map((tool) => tool.name)).size !== tools.length) throw new Error(\"Tool names must be unique\");\n\t\tconst scriptNames = tools.map((tool) => tool.jsName ?? toCodemodeIdentifier(tool.name));\n\t\tif (new Set(scriptNames).size !== tools.length) throw new Error(\"Tool script names must be unique\");\n\t\tconst globals = options.globals ?? [];\n\t\tcheckGlobals(globals);\n\t\tconst execution = new Execution({\n\t\t\tcode,\n\t\t\ttools,\n\t\t\tglobals,\n\t\t\texecutors: { tools: new Map(), globals: new Map() },\n\t\t\ttimeoutMs: options.timeoutMs ?? Number.POSITIVE_INFINITY,\n\t\t\tsignal: options.signal,\n\t\t\tmemoryLimitBytes: this.memoryLimitBytes,\n\t\t\tstore: serializeStore(options.store),\n\t\t\tdeterministic: { startedAt: options.startedAt, seed: options.seed },\n\t\t\tcontrol: { onStarted: options.onStarted, onCall: options.onCall, onIdle: options.onIdle },\n\t\t\tlaunch: this.launch,\n\t\t});\n\t\tthis.running.add(execution);\n\t\tconst result = execution.promise.finally(() => this.running.delete(execution));\n\t\treturn {\n\t\t\tresult,\n\t\t\tdeliver: (seq, now, id, outcome) => execution.deliver(seq, now, id, outcome),\n\t\t\tget finished() {\n\t\t\t\treturn execution.finished;\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Aborts in-flight executions (they resolve with `kind: \"aborted\"`) and rejects new ones. */\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tawait Promise.all([...this.running].map((execution) => execution.abort(\"Sandbox closed\")));\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAiC,MAAM,gBAAgB,CAAC;AAgEpF;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,mBAAmB;IACvD,YAAY,OAAO,GAAE,sBAA2B,EAE/C;CACD"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAiC,MAAM,gBAAgB,CAAC;AAyEpF;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,mBAAmB;IACvD,YAAY,OAAO,GAAE,sBAA2B,EAE/C;CACD"}