codemode

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 25 Imported by: 0

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

View Source
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).

View Source
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).

View Source
const CodemodeOptionsPrefix = "// @options:"

CodemodeOptionsPrefix starts the optional first line of a script.

Ports packages/codemode/src/source.ts (CODEMODE_OPTIONS_PREFIX).

View Source
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).

View Source
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).

View Source
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

View Source
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

func CallInitiated(ctx context.Context)

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

func RenderToolSample(tool Tool, inputMaxChars int) string

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

func RenderToolSignature(tool Tool, inputMaxChars int) string

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

func ToCodemodeIdentifier(name string) string

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 Error

type Error struct {
	Kind    ErrorKind
	Name    string
	Message string
	Stack   string
}

Error describes a failed execution.

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

type RenderDeclarationsOptions struct {
	Tools   []Tool
	Globals []Tool
}

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

func (s *Sandbox) Close() error

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

func (s *Sandbox) Execute(ctx context.Context, code string, options ExecuteOptions) (Result, error)

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) Globals

func (s *Sandbox) Globals() []Tool

Globals lists the registered globals in registration order.

func (*Sandbox) RegisterTool

func (s *Sandbox) RegisterTool(tool Tool) error

RegisterTool fails if a tool with the same name is already registered.

func (*Sandbox) Tools

func (s *Sandbox) Tools() []Tool

Tools lists the registered tools in registration order.

func (*Sandbox) UnregisterTool

func (s *Sandbox) UnregisterTool(name string) bool

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL