Skip to content

Script Engine

The Script Engine enables AI to execute JavaScript / TypeScript code in the browser, extending AI capabilities from “file read/write” to “arbitrary computation”. Scripts interact with the UI, read/write the virtual file system, and call host-registered functions through rtcAgent.* — all within a carefully designed sandbox.

💡 Design Philosophy: LLM creativity lives in the logic layer — data processing, control flow, and rtcAgent call composition. The sandbox restricts “side effects” (storage/network/DOM), not “expressiveness” (language/data structures/logic). This layer is fully open.

RestrictedOpen
GoalPrevent LLM hallucinations from misusing platform APIsUnleash LLM’s logical creativity
MeansAST static blocking + permission confirmationFull language features + pure-computation standard library
Threat ModelLLM hallucinations causing misuse (e.g., accidentally calling platform APIs)Not a malicious code injection scenario

AI interacts with the engine via the script tool, which has three execution modes:

ActionFunctionRequired ParametersUse Case
📁 saveSave script to file systemname, codeCreate reusable scripts
▶️ runExecute a saved scriptnameRun previously written scripts
💬 evalExecute inline code directlycodeOne-off computations, quick validation

Scripts are stored in Markdown + YAML frontmatter format, balancing readability and metadata management:

The saved file format looks like this:

SectionContentPurpose
YAML frontmattername, description, createdAtMetadata storage for management
Code blocksTypeScript / JavaScript source codeThe actual code to execute

📌 During execution, pure code is extracted from code blocks; frontmatter is only used for management. If there are no code blocks, the entire file content is executed as code.

Scripts have access to the following APIs during execution:

Through rtcAgent.*, all registered Function Groups are accessible, enabling full UI operation capabilities:

MethodFunctionDescription
rtcAgent.callFunction()Call a registered functionTriggers any Function Group registered by the host
rtcAgent.readFile()Read fileOperates on the virtual file system
rtcAgent.writeFile()Write fileOperates on the virtual file system
rtcAgent.listDir()List directoryOperates on the virtual file system

💡 Through chained calls like rtcAgent.task.create(), scripts can operate on any registered functional module.

The sandbox explicitly injects the following standard libraries, making the API surface auditable:

CategoryAvailable Global Objects/Functions
Language constructorsPromise, Date, Math, JSON, Array, Object, String, Number, Boolean, Error
Data structuresMap, Set, WeakMap, WeakSet, RegExp, Symbol, BigInt
Error subclassesTypeError, RangeError, ReferenceError, SyntaxError, URIError, AggregateError
Parsing & encodingparseInt, parseFloat, isNaN, isFinite, encodeURIComponent, decodeURIComponent, encodeURI, decodeURI, atob, btoa
Utility functionsstructuredClone
Special valuesNaN, Infinity, undefined
URL parsingURL, URLSearchParams
consolelog, warn, error (hijacked version — output is simultaneously collected for the AI)

The sandbox blocks “gray-area APIs” like setTimeout and crypto.randomUUID. To let scripts still use these common features, the system registers an rtcAgent.system.* tool group by default:

FunctionFeatureWrapped Platform API
rtcAgent.system.delay(ms)Pause execution for specified millisecondssetTimeout
rtcAgent.system.uuid(count?)Generate UUID v4 (supports batch)crypto.randomUUID
rtcAgent.system.now()Get current timestamp (milliseconds)Date.now
rtcAgent.system.random(opts?)Generate random numbers (supports range/integer)Math.random
rtcAgent.system.time(format?)Get formatted time (iso/locale/ts)Date

📌 These tools follow the standard FunctionDef specification. AI discovers them through virtual documentation, using the same approach as user-defined Function Groups.

Script security uses a two-layer defense: AST compile-time blocking + runtime permission confirmation.

The sandbox statically blocks the following categories of APIs during Babel transformation:

CategoryBlocked TargetsAlternative
🗄️ Storage APIslocalStorage, sessionStorage, indexedDB, caches, cookieStorertcAgent.readFile / writeFile
🌐 Network APIsfetch, XMLHttpRequest, WebSocket, EventSource, BroadcastChannelrtcAgent.callFunction
🖥️ DOM / Browserwindow, self, document, navigator, location, history, alert, confirm, promptrtcAgent (UI goes through Function registration)
🔄 Metaprogramming / Escapeeval, Function, globalThis, globalNo alternative needed
👷 WorkersWorker, SharedWorker, ServiceWorker, importScriptsNo alternative needed
⏱️ TimerssetTimeout, setIntervalrtcAgent.system.delay
🧠 Shared memorySharedArrayBuffer, AtomicsNo alternative needed
📦 CJS globalsrequire, module, exports, __dirname, __filenameNo alternative needed
🔗 Prototype chain escape.constructor, .__proto__ (including string index form)No alternative needed
📥 Dynamic importimport(...)No alternative needed
🔁 Infinite loopswhile, do...while, for(;;)for…of / bounded for / array iteration methods

Smart Detection: If an identifier has a local binding (e.g., the user declared a same-named variable const fetch = ...), it won’t be incorrectly blocked. TypeScript type annotations (e.g., const fn: Function) also don’t trigger blocking.

ConstraintDescription
🔐 PermissionsConfirmation required in all modes except bypass
⏱️ TimeoutDefault 30 seconds, configurable
⏭️ Timeout behaviorStops waiting, does not terminate the script (script continues running in the background)
🔒 Scope isolationCompile-time injection of whitelisted bindings; script cannot access unauthorized globals
🔐 this bindingExecutes in "use strict" mode, preventing this from escaping

After script execution, the engine collects the complete execution results and returns them to the AI:

FieldSourcePurpose
resultScript return valueAI obtains computation results
logsconsole.logAI reviews debug information
warningsconsole.warnAI identifies potential issues
errorsconsole.errorAI handles error conditions

💡 console is a hijacked version — output is displayed normally to the user while also being collected and returned to the AI, allowing the AI to “see” the script’s execution process.

Scripts fully support asynchronous programming:

FeatureDescription
async / awaitFully supported
Execution wrapperScripts are wrapped in an async IIFE for execution
PromiseThe sandbox provides the Promise constructor
rtcAgent callsHost API calls natively support async