Documentation
¶
Overview ¶
Package codemode runs a model-written JavaScript script against a table of host tools and globals. It ports packages/codemode: the script runs in a QuickJS VM compiled to WebAssembly and hosted by wazero, and reaches the host only through one bridge function (docs/specs/builtin-codemode-tool-search.md).
Index ¶
- Constants
- Variables
- func CallInitiated(ctx context.Context)
- func McpStructuredContentSchema(schema json.RawMessage) json.RawMessage
- func QuickJSWasm() []byte
- func RenderDeclarations(options RenderDeclarationsOptions) string
- func RenderToolOutputType(raw json.RawMessage) string
- func RenderToolSample(tool Tool, inputMaxChars int) string
- func RenderToolSignature(tool Tool, inputMaxChars int) string
- func SchemaToType(schema json.RawMessage, maxChars int) string
- func ToCodemodeIdentifier(name string) string
- type Call
- type CallStatus
- type Error
- type ErrorKind
- type ExecuteOptions
- type OutputItem
- type ParsedSource
- type RenderDeclarationsOptions
- type Result
- type Sandbox
- type SandboxOptions
- type SourceError
- type SourceOptions
- type StoreWrites
- type Tool
Constants ¶
const ( MaxStoreValueChars = 256 * 1024 MaxStoreTotalChars = 1024 * 1024 )
The store limits the prelude enforces.
Ports packages/codemode/src/runtime/prelude-source.ts (MAX_STORE_VALUE_CHARS, MAX_STORE_TOTAL_CHARS).
const ( MaxOutputChars = 16 * 1024 * 1024 MaxOutputItems = 100_000 )
The output limits the prelude enforces: characters of text and base64 image data, and items, that one script may produce with `text()`, `image()`, and `console.*`. The host keeps all output until the script ends, so without a limit a script that prints in a loop grows the host's memory until it crashes. The item limit covers loops that print empty strings.
Ports packages/codemode/src/runtime/prelude-source.ts (MAX_OUTPUT_CHARS, MAX_OUTPUT_ITEMS).
const CodemodeOptionsPrefix = "// @options:"
CodemodeOptionsPrefix starts the optional first line of a script.
Ports packages/codemode/src/source.ts (CODEMODE_OPTIONS_PREFIX).
const CodemodeSourceGrammar = `` /* 184-byte string literal not displayed */
CodemodeSourceGrammar is the Lark grammar for providers with grammar-constrained tool input. It only fixes the shape of the options line; ParseCodemodeSource checks the options JSON and the code.
Ports packages/codemode/src/source.ts (CODEMODE_SOURCE_GRAMMAR).
const DefaultInputSchemaMaxChars = 16_000
DefaultInputSchemaMaxChars is the largest rendered input type, in characters, before it becomes `unknown`.
Ports packages/codemode/src/declarations.ts (DEFAULT_INPUT_SCHEMA_MAX_CHARS).
const McpTypescriptPreamble = `` /* 1543-byte string literal not displayed */
McpTypescriptPreamble holds TypeScript types for MCP results, from the MCP `CallToolResult` schema, so `CallToolResult<T>` declarations can refer to them.
Ports packages/codemode/src/declarations.ts (MCP_TYPESCRIPT_PREAMBLE).
Variables ¶
var PreludeSource string
PreludeSource is the JavaScript evaluated inside the VM before the script runs, embedded byte for byte.
Ports packages/codemode/src/runtime/prelude-source.ts (PRELUDE_SOURCE).
Functions ¶
func CallInitiated ¶
CallInitiated tells the host that the call ctx belongs to has initiated (see Tool.AwaitsInitiation). It is a no-op for a context the host did not create and for a second call.
func McpStructuredContentSchema ¶
func McpStructuredContentSchema(schema json.RawMessage) json.RawMessage
McpStructuredContentSchema returns the `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a `content` array of objects, boolean `isError`, and object `_meta`), the JSON text `true` when it declares none, or nil when the schema is not a `CallToolResult`. The result is compact JSON.
Ports packages/codemode/src/declarations.ts (mcpStructuredContentSchema).
func QuickJSWasm ¶
func QuickJSWasm() []byte
QuickJSWasm returns the embedded quickjs-wasi module (assets/PROVENANCE.md). The caller must not modify it.
func RenderDeclarations ¶
func RenderDeclarations(options RenderDeclarationsOptions) string
RenderDeclarations renders TypeScript declarations for the script-visible API: tools become members of `declare const tools`, globals `declare function` statements, and `ns.member` globals members of `declare const ns`.
Ports packages/codemode/src/declarations.ts (renderDeclarations).
func RenderToolOutputType ¶
func RenderToolOutputType(raw json.RawMessage) string
RenderToolOutputType returns the type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs McpTypescriptPreamble), the schema's type otherwise, and `unknown` without a schema.
Ports packages/codemode/src/declarations.ts (renderToolOutputType).
func RenderToolSample ¶
RenderToolSample renders the description followed by the tool's declaration, for tool listings and `ALL_TOOLS` entries.
Ports packages/codemode/src/declarations.ts (renderToolSample).
func RenderToolSignature ¶
RenderToolSignature renders one tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the name as the identifier scripts use. Input types longer than inputMaxChars (zero means DefaultInputSchemaMaxChars) render as `unknown`. Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`, which needs McpTypescriptPreamble.
Ports packages/codemode/src/declarations.ts (renderToolSignature).
func SchemaToType ¶
func SchemaToType(schema json.RawMessage, maxChars int) string
SchemaToType converts a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name, or one property per line with `//` comments when a property has a description; `Array<T>` for arrays. Local references (`#/$defs/...`, `#/definitions/...`) resolve against the schema; recursive and remote references render as `unknown`. A result longer than maxChars characters (zero means no limit) renders as `unknown`. A schema that is not valid JSON renders as `unknown`.
Ports packages/codemode/src/declarations.ts (schemaToType).
func ToCodemodeIdentifier ¶
ToCodemodeIdentifier returns the identifier a script uses for a tool: characters that are not valid in a JavaScript identifier become `_`.
Ports packages/codemode/src/identifier.ts.
Types ¶
type Call ¶
type Call struct {
Name string
Status CallStatus
DurationMs float64
}
Call records one tool call the script made (globals are not recorded).
type CallStatus ¶
type CallStatus string
CallStatus is the outcome of one nested tool call.
const ( CallOK CallStatus = "ok" CallError CallStatus = "error" CallCancelled CallStatus = "cancelled" )
The nested call outcomes.
type ErrorKind ¶
type ErrorKind string
ErrorKind classifies a failed execution.
const ( // ErrorScript: the script threw or failed to parse; Name and Stack come from the script's error. ErrorScript ErrorKind = "script" // ErrorTimeout: the overall deadline expired and the VM was stopped. ErrorTimeout ErrorKind = "timeout" // ErrorAborted: the caller's context ended or the sandbox was closed. ErrorAborted ErrorKind = "aborted" // ErrorSandbox: the VM failed outside the script's control (a wasm trap, a missing or corrupt wasm module). ErrorSandbox ErrorKind = "sandbox" )
The failure kinds.
type ExecuteOptions ¶
type ExecuteOptions struct {
// TimeoutMs overrides the sandbox default for this execution; zero keeps it.
TimeoutMs float64
// Store holds the values the script reads with load(key), each JSON text.
Store map[string]json.RawMessage
}
ExecuteOptions configures one execution.
type OutputItem ¶
type OutputItem struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
Data string `json:"data,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
OutputItem is one item of the script's output, in the order the script produced it: text() and console.* produce "text" items, image() "image" items. Data is base64.
type ParsedSource ¶
type ParsedSource struct {
// Code is the script with the options line replaced by an empty line, so line numbers are unchanged.
Code string
Options SourceOptions
}
ParsedSource is a script with its options line split off.
func ParseCodemodeSource ¶
func ParseCodemodeSource(input string) (ParsedSource, error)
ParseCodemodeSource splits an optional first-line `// @options: {...}` from the script. It fails with a *SourceError for empty input and invalid options.
Ports packages/codemode/src/source.ts (parseCodemodeSource).
type RenderDeclarationsOptions ¶
RenderDeclarationsOptions selects what RenderDeclarations renders.
type Result ¶
type Result struct {
OK bool
Value json.RawMessage
Output []OutputItem
Calls []Call
StoreWrites StoreWrites
// Error is set when OK is false.
Error *Error
}
Result is the outcome of one execution. Output is kept for failed executions too, up to the failure. exit() completes with a nil Value.
type Sandbox ¶
type Sandbox struct {
// contains filtered or unexported fields
}
Sandbox runs scripts in QuickJS VMs. Each Execute gets its own VM; the sandbox holds only the tool table and defaults. Close aborts in-flight executions.
Ports packages/codemode/src/runtime/host.ts (CodemodeSandbox).
func NewSandbox ¶
func NewSandbox(options SandboxOptions) (*Sandbox, error)
NewSandbox validates the globals and registers the tools.
func (*Sandbox) Close ¶
Close aborts in-flight executions (they finish with ErrorAborted and message "Sandbox closed"), waits for them to exit, and rejects new ones.
func (*Sandbox) Execute ¶
Execute runs code as an async function body: `return` and top-level `await` work. Script failures come back as a Result with OK false, never as an error; the error is for a closed sandbox. Cancelling ctx aborts the execution: the abort message is the context's cause. Execute returns after the execution's VM is closed and every goroutine it started has exited.
func (*Sandbox) RegisterTool ¶
RegisterTool fails if a tool with the same name is already registered.
func (*Sandbox) UnregisterTool ¶
UnregisterTool removes a tool and reports whether it existed.
type SandboxOptions ¶
type SandboxOptions struct {
Tools []Tool
// Globals are exposed as top-level identifiers instead of on tools; they behave like tools but are not recorded
// in Result.Calls. Names must be identifiers or <namespace>.<member> and may not shadow the built-in globals.
Globals []Tool
// TimeoutMs is the overall deadline per execution, including time in tools. Zero means the default,
// 300000; +Inf disables the deadline.
TimeoutMs float64
// MemoryLimitBytes is the most memory the QuickJS VM may allocate; allocations beyond it fail inside the script
// as `InternalError: out of memory`. Zero means no limit beyond the wasm32 address space.
MemoryLimitBytes uint32
// CacheDir holds wazero's on-disk compilation cache, which makes a later process start in tens of milliseconds
// instead of hundreds. Empty compiles in memory; a directory that cannot be used is ignored.
CacheDir string
// Wasm supplies the QuickJS wasm module. Nil means the embedded module (upstream: loadQuickJSWasm()).
Wasm func() ([]byte, error)
}
SandboxOptions configures NewSandbox.
type SourceError ¶
type SourceError struct{ Message string }
SourceError reports empty input or invalid options.
func (*SourceError) Error ¶
func (e *SourceError) Error() string
type SourceOptions ¶
type SourceOptions struct {
// MaxOutputTokens is the token budget for the script's output; nil means unset.
MaxOutputTokens *int64
// TimeoutMs is the hard deadline for the whole script in milliseconds; nil means unset.
TimeoutMs *int64
}
SourceOptions are the fields of the options line.
type StoreWrites ¶
type StoreWrites struct {
Set map[string]json.RawMessage
// Delete lists the keys stored as undefined.
Delete []string
}
StoreWrites are the keys the script changed with store(). Only successful executions report writes.
type Tool ¶
type Tool struct {
// Name is the tool's name. Scripts call tools as tools.<ToCodemodeIdentifier(Name)>(args) and tools["<Name>"](args).
// A global is called as <Name>(args) and must be an identifier or <namespace>.<member>.
Name string
// Description is a doc comment in RenderDeclarations and the entry text in ALL_TOOLS. Empty means none.
Description string
// InputSchema is the JSON Schema of the single argument, used only to render declarations. Nil means unknown.
InputSchema json.RawMessage
// OutputSchema is the JSON Schema of the resolved value, used only to render declarations. Nil means unknown.
OutputSchema json.RawMessage
// Spread makes a global receive all call arguments as an array instead of the first one.
Spread bool
// Signature is a TypeScript parameter list and return type that replaces the rendering from the schemas
// (globals only). Empty means none.
Signature string
// AwaitsInitiation makes the script's next tool call wait until Execute has initiated this one: until it calls
// CallInitiated with its context, or returns. Pi runs each call's synchronous prefix in call order, so two calls a script
// starts together reach a server in script order; a Go goroutine per call does not, and a tool whose prefix must keep the
// order (a request to a server) sets this and calls CallInitiated once the order is fixed.
AwaitsInitiation bool
// Execute runs the tool. args is what the script passed, after a JSON round trip.
Execute func(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
}
Tool is a host function a script can call.
Ports packages/codemode/src/types.ts (CodemodeTool). Go mechanics, not divergences: the arguments and the result are JSON text, the form in which they cross the VM boundary (a nil json.RawMessage is `undefined`), and the upstream ToolContext.signal is the ctx passed to Execute, cancelled when the script finishes, times out, is aborted or the sandbox closes.