Robutler

TypeScript SDK Reference

Looking for the Python SDK? See the Python SDK Reference. For a side-by-side cross-language overview, see the Quickstart.

Install the SDK:

npm install webagents

The package targets Node.js ≥ 20 and modern browsers. ESM only.


BaseAgent

The core agent class. Processes UAMP events, manages skills, and exposes run / runStreaming interfaces.

import { BaseAgent } from 'webagents';

const agent = new BaseAgent({
  name: 'my-agent',
  instructions: 'You are a helpful assistant.',
  model: 'openai/gpt-4o',
  skills: [new MySkill()],
});

Constructor

new BaseAgent(config: AgentConfig) — see AgentConfig.

FieldTypeDescription
namestringAgent display name (default 'agent').
descriptionstringOptional human-readable description.
instructionsstringSystem prompt prepended to every run.
modelstringDefault LLM model (e.g. 'openai/gpt-4o').
skillsISkill[]Skill instances to load.
capabilitiesPartial<Capabilities>UAMP capabilities (modalities, audio formats, streaming).
maxToolIterationsnumberMax agentic loop iterations (default 50).

Methods

MethodSignatureDescription
run(messages: Message[], options?: RunOptions) => Promise<RunResponse>Single-turn execution.
runStreaming(messages: Message[], options?: RunOptions) => AsyncGenerator<StreamChunk>Streaming execution.
getCapabilities() => CapabilitiesGet aggregated agent capabilities.
addSkill(skill: ISkill) => voidAdd a skill at runtime.
removeSkill(name: string) => voidRemove a skill at runtime.
executeTool(name: string, params: Record<string, unknown>) => Promise<unknown>Execute a tool by name.
overrideTool(name: string) => voidMark a tool as client-executed.

Skill

Abstract base for skills. Skills bundle tools, hooks, prompts, handoffs, observers, and HTTP/WebSocket endpoints.

import { Skill, tool, hook } from 'webagents';
import type { Context, HookData, HookResult } from 'webagents';

class WeatherSkill extends Skill {
  readonly name = 'weather';

  @tool({ description: 'Get weather for a city' })
  async getWeather(params: { city: string }, ctx: Context): Promise<string> {
    return `Weather in ${params.city}: sunny`;
  }

  @hook({ lifecycle: 'before_run' })
  async onBeforeRun(data: HookData, ctx: Context): Promise<HookResult> {
    return {};
  }
}

Lifecycle

MethodDescription
initialize(agent: IAgent)Called when the skill is registered with an agent.
setAgent(agent: IAgent)Set the parent agent reference (auto-called by addSkill).
tools / hooks / handoffs / prompts / httpEndpoints / wsEndpointsRead-only registries populated by decorators.

Decorators

All decorators live in webagents/core and are re-exported from the package root.

@tool

Register a method as an LLM-callable tool.

@tool({
  name?: string,
  description?: string,
  parameters?: JSONSchema,
  provides?: string,
  scopes?: string[],
  enabled?: boolean,
})

@hook

Register a lifecycle hook.

@hook({
  lifecycle: 'before_run' | 'after_run' | 'before_toolcall' | 'after_toolcall' | 'on_error' | 'on_message' | 'on_chunk' | 'on_request' | 'on_connection',
  priority?: number,
  enabled?: boolean,
})

@prompt

Register a dynamic system-prompt contributor. Return value is appended to the system message.

@prompt({ priority?: number, scope?: string | string[] })

@handoff

Declare a UAMP handoff handler. Used by the router for capability-based routing.

@handoff({
  name: string,
  description?: string,
  priority?: number,
  scopes?: string[],
  subscribes?: (string | RegExp)[],
  produces?: string[],
})

Defaults: subscribes: ['input.text'], produces: ['response.delta'].

@observe

Register a non-consuming event observer.

@observe({ name: string, subscribes: (string | RegExp)[] })

@http

Register a Hono-style HTTP endpoint.

@http({
  path: string,
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',
  scopes?: string[],
  content_type?: string,
  auth?: 'public' | 'session' | 'agent',
  enabled?: boolean,
})

@websocket

Register a WebSocket endpoint.

@websocket({
  path: string,
  scopes?: string[],
  protocols?: string[],
  enabled?: boolean,
})

@pricing

Attach pricing metadata to a tool. The payments skill's before_toolcall hook reads this and pre-authorizes the charge.

@pricing({
  creditsPerCall?: number,
  lock?: number | ((params) => number),
  settle?: (result, params) => number,
  reason?: string,
  onSuccess?: (result, ctx) => void | Promise<void>,
  onFail?: (error, ctx) => void | Promise<void>,
})

@command and @widget are Python-only today. See the parity matrix for status.


Server

createAgentApp(agent, config?)

Create a Hono HTTP app + WebSocket upgrade handler for an agent.

import { createAgentApp } from 'webagents';

const { app, handleUpgrade } = createAgentApp(agent, { cors: true });

Returns { app: Hono, handleUpgrade(req, socket, head) }.

serve(agent, config?)

Start a Node.js HTTP server (Hono via @hono/node-server, or Bun if detected). Wires UAMP, Completions, A2A, ACP, Realtime endpoints.

import { serve } from 'webagents';

await serve(agent, {
  port: 8080,
  hostname: '0.0.0.0',
  cors: true,
  logging: true,
});

createFetchHandler(agent, options?)

Standard fetch handler for serverless / edge deployments (Cloudflare Workers, Vercel Edge, Deno Deploy).

import { createFetchHandler } from 'webagents';

export default {
  fetch: createFetchHandler(agent),
};

WebAgentsServer

Multi-agent server with rate limiting, extension loading, and dynamic agents.

import { WebAgentsServer } from 'webagents';

const server = new WebAgentsServer({
  agents: [agent1, agent2],
  rateLimit: { perMinute: 60 },
});

await server.listen({ port: 8080 });

Context

Available inside tools, hooks, prompts, and handoffs.

interface Context {
  session: SessionState;
  auth: AuthInfo;
  payment: PaymentInfo;
  client_capabilities?: Capabilities;
  agent_capabilities?: Capabilities;
  metadata: Record<string, unknown>;
  signal?: AbortSignal;
  get(key: string): unknown;
  set(key: string, value: unknown): void;
  hasScope(scope: string): boolean;
}

Router

MessageRouter routes UAMP events through the skill graph using capability-based subscriptions.

import { MessageRouter } from 'webagents';

const router = new MessageRouter();
router.addHandler({ subscribes: ['input.text'], produces: ['response.delta'], handler });
await router.dispatch(event, context);

Sinks

Output adapters for different transports:

ClassDescription
WebSocketSinkWebSocket transport.
SSESinkServer-Sent Events.
WebStreamSinkWeb Streams API.
CallbackSinkCustom callback function.
BufferSinkIn-memory buffer (testing).

Daemon

Background process manager — the runtime behind the webagents and robutler CLIs.

import { WebAgentsDaemon } from 'webagents/daemon';

const daemon = new WebAgentsDaemon({ port: 8080, enableCron: true });
daemon.registerAgent(agent);
await daemon.start();

UAMP Types

Key exports from webagents/uamp:

TypeDescription
CapabilitiesAgent capabilities declaration.
Modality`'text'
AudioFormatAudio codec hint ('pcm16', 'opus', …).
MessageUAMP message envelope.
ContentItemMultimodal content item (text/audio/image/video/file).
ToolDefinitionTool schema for LLM.
ToolCallTool invocation record.
UsageStatsToken usage statistics.
ClientEvent / ServerEventEvent envelopes for the realtime/UAMP transports.

Crypto

JWKS / JWT utilities for AOAuth.

import { JWKSManager } from 'webagents';

const jwks = new JWKSManager({ jwksCacheTtl: 3600 });
const payload = await jwks.verifyJwt(token);

Skill Imports

Per-skill subpath exports keep tree-shaking honest:

import { AuthSkill } from 'webagents/skills/auth';
import { PaymentSkill } from 'webagents/skills/payments';
import { PortalDiscoverySkill } from 'webagents/skills/discovery';
import { NLISkill } from 'webagents/skills/nli';
import { OpenAPISkill } from 'webagents/skills/openapi';
import { MCPSkill } from 'webagents/skills/mcp';
import { SlackSkill } from 'webagents/skills/messaging/slack';

The complete subpath catalogue is declared under exports in webagents/typescript/package.json.

On this page