Documentation

User guide and developer references.

Developer Guide

Runtime

The runtime is the contract between your module and the app: which exports it reads, when it calls them, and what it hands you when it does.

⚠
Extension code runs with the same browser privileges as the app. The loader checks the manifest shape and a SHA-256 of the source. It does not sandbox anything.

How a turn runs

Every hook below only fires for extensions that are enabled for the active persona. Hooks run one extension at a time and are awaited. A hook that throws is logged and skipped, and the turn continues.

  1. 1onBeforeUserMessageSend runs with the outgoing text. It can rewrite the message or block it with an alert.
  2. 2getPromptContributions is collected from every enabled extension and merged into the system prompt. Each extension's promptState is rendered into the Current Toys and Player Information sections at the same time. Silent scenario-arrival turns skip this step.
  3. 3For each model round: onBeforeLLMRequest runs, then the request is sent. Streamed text triggers onAfterAssistantChunk.
  4. 4For each tool call the model makes: onAfterToolCall, then executeTool on the owning extension, then onAfterToolResult. The result goes back to the model and a new round starts.
  5. 5When the final reply is complete, onAfterAssistantMessage runs once.

A turn usually has one round. Tool calls add rounds. Instructions you emit with ctx.runtime.emitPromptInstruction during a round are attached to the next round of the same turn.

Reference pages

API versioning

Set apiVersion in the manifest to the version you wrote against. New extensions should use v7. Every version since v1 still loads, and a manifest that asks for a newer version than the app supports is rejected at load time.

v1

Manifest, useExtension(), and browser-side tools.

v2

promptState for the Current Toys and Player Information prompt sections.

v3

Prompt contributions, lifecycle hooks, variables, memories, chat, persona, media, image artifacts, and toy emergency stop.

v4

Chat footer drawer: manifest.chatFooter and FooterComponent.

v5

runtime.emergencyStop() so any extension can trigger the same toy stop as the top-bar button.

v6

Fullscreen overlay slot (manifest.overlay and OverlayComponent), chat.sendMessage(), chat.runTurn(), and ui.toast().

v7

The Patterns system for the app's built-in toy extensions (manifest.supportsPatterns, patternCapabilities, getPatternSink).

The loader does not read getPatternSink from JS modules yet, so a JS extension gains nothing new in v7. Declaring v7 is still correct for new work.