Package
One package, one entry point.
npm i actionwire.
Everything ships in actionwire. It is ESM only and has one runtime dependency, @cfworker/json-schema, used to validate tool input against your schema. It never calls eval or new Function, so the widget runs on pages that forbid runtime code generation.
import {
createAssistant, // mount the widget
createAgentBridge, // headless: no user interface
createWebMCPSource, // read the tools on the page
openAICompatible, // talk to your model endpoint
AgentError, // every failure, with a code
} from 'actionwire';Types come from the same place: Activity, AgentAdapter, AgentTurn, Assistant, AssistantOptions, AssistantState, BridgeOptions, Confirmation, ConfirmationPolicy, ErrorCode, Json, Message, MountedAssistant, TimelineItem, ToolCall, ToolDefinition, ToolResult, ToolSnapshot, ToolSource, and ToolStatus.
The package is marked sideEffects: false, so a bundler drops whatever you do not import. Using only the headless bridge leaves the widget out of your build.
How they fit
The bridge is the only place that runs a tool. The widget renders state and sends user input. It holds no WebMCP logic and no model logic.
Pick a layer
Widget
createAssistant. You want a chat panel and you want it to look finished.
Headless
createAgentBridge. You render the interface yourself.
Tool source
ToolSource. You supply the tools instead of the browser.
Layers inside the package
The source keeps four layers, in src/core, src/webmcp, src/agent, and src/widget. They import in one direction only, and a lint rule enforces it. See Architecture.