Robutler

Agent Overview

BaseAgent is the core class for creating AI agents in WebAgents. It uses a flexible, skill-based architecture so you can add exactly the capabilities you need. Agents speak the OpenAI Chat Completions dialect natively, so existing clients work out of the box. The skill system adds platform features like authentication, payments, discovery, and multi-agent collaboration.

  • Build an agent with a few lines of code
  • Add capabilities via skills (tools, hooks, prompts, handoffs)
  • Serve OpenAI-compatible endpoints with a single function call

Creating Agents

Basic Agent

import { BaseAgent } from 'webagents';

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

New to WebAgents? Check out the Quickstart for a complete walkthrough.

Agent with Skills

import { BaseAgent } from 'webagents';
import { PortalDiscoverySkill } from 'webagents/skills/discovery';
import { SessionSkill } from 'webagents/skills/session';

const agent = new BaseAgent({
  name: 'advanced-assistant',
  instructions: 'You are an advanced assistant with memory',
  model: 'openai/gpt-4o',
  skills: [
    new SessionSkill({ maxMessages: 50 }),
    new PortalDiscoverySkill(),
  ],
});

Explore available skills in the Skills Overview or learn to create custom skills.

Smart Model Parameter

The model parameter accepts a provider-prefixed string. The correct LLM skill is provisioned automatically.

import { BaseAgent } from 'webagents';
import { OpenAILLMSkill } from 'webagents/skills/llm';

new BaseAgent({ model: 'openai/gpt-4o' });        // OpenAI GPT-4o
new BaseAgent({ model: 'anthropic/claude-3-5' }); // Anthropic Claude
new BaseAgent({ model: 'xai/grok-2' });           // xAI Grok
new BaseAgent({ model: 'google/gemini-1.5-pro' });

new BaseAgent({
  skills: [
    new OpenAILLMSkill({
      apiKey: process.env.OPENAI_API_KEY,
      defaultModel: 'gpt-4o',
      temperature: 0.7,
    }),
  ],
});

See LLM Skills for more configuration options.

Running Agents

Basic Conversation

const response = await agent.run([
  { role: 'user', content: 'Hello!' },
]);
console.log(response.content);

Streaming Response

for await (const chunk of agent.runStreaming([
  { role: 'user', content: 'Tell me a story' },
])) {
  process.stdout.write(chunk.delta ?? '');
}

With Tools

Attach additional tools per request using the OpenAI function-calling format:

const response = await agent.run(
  [{ role: 'user', content: 'Calculate 42 * 17' }],
  {
    tools: [
      {
        type: 'function',
        function: {
          name: 'calculator',
          description: 'Calculate math expressions',
          parameters: { /* JSON schema */ },
        },
      },
    ],
  },
);

Agent Capabilities

Skills

Skills provide modular capabilities:

  • LLM Skills — Language model providers (OpenAI, Anthropic, Google, xAI, …)
  • Memory / Storage Skills — Conversation persistence and context management
  • Platform Skills — Robutler platform integration (auth, payments, discovery)
  • Ecosystem Skills — Third-party integrations (OpenAI workflows, database, n8n)

Tools

Tools are executable functions that extend agent capabilities:

import { Skill, tool } from 'webagents';

class MySkill extends Skill {
  readonly name = 'my-skill';

  @tool({ description: 'Tool description' })
  async myFunction(params: { value: string }): Promise<string> {
    return `Result: ${params.value}`;
  }
}

See Tools for examples and best practices.

Hooks

Lifecycle hooks enable event-driven behavior during request processing:

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

class MySkill extends Skill {
  readonly name = 'my-skill';

  @hook({ lifecycle: 'on_message' })
  async processMessage(data: HookData, ctx: Context) {
    return data;
  }
}

Learn about hooks and the agent lifecycle.

Handoffs

Handoffs enable agents to delegate completions to specialized handlers or remote agents:

import { Skill, handoff } from 'webagents';
import type { ClientEvent } from 'webagents';

class SpecializedSkill extends Skill {
  readonly name = 'specialized';

  @handoff({
    name: 'math_expert',
    description: 'Use for advanced mathematical problems',
    priority: 15,
  })
  async *mathCompletion(events: ClientEvent[]) {
    for await (const chunk of this.specializedMathLLM(events)) {
      yield chunk;
    }
  }
}

Context Management

Agents maintain a unified context object throughout execution. Skills read and write to this structure — contextvars in Python, an explicit Context parameter in TypeScript — and both are async-safe.

import { tool } from 'webagents';
import type { Context } from 'webagents';

class MySkill extends Skill {
  readonly name = 'my-skill';

  @tool({ description: 'Inspect context' })
  async whoami(_: Record<string, never>, ctx: Context) {
    return {
      userId: ctx.auth?.userId,
      streaming: ctx.metadata.stream === true,
    };
  }
}

Agent Registration

Register agents with the server to make them available via HTTP endpoints:

import { serve } from 'webagents';

await serve(agent, { port: 8000 });

// Or compose multiple agents:
import { WebAgentsServer } from 'webagents';
const server = new WebAgentsServer({ agents: [agent1, agent2] });
await server.listen({ port: 8000 });

Best Practices

  1. Start Simple — Begin with a basic agent, add skills as you go.
  2. Use Dependencies — Some skills auto-require others (e.g. payments depends on auth).
  3. Scope Appropriately — Use tool scopes (scope/scopes) for access control.
  4. Test Thoroughly — Treat skills as units; test hooks and tools independently.
  5. Monitor Performance — Track usage and latency. Payments will use context.usage.

Next Steps

  • Quickstart — Build your first agent in 5 minutes
  • Skills — Explore available skills and create custom ones
  • Agent Lifecycle — Understand the complete request processing flow
  • Server Deployment — Deploy your agents to production
  • Contributing — Contribute to the WebAgents ecosystem

On this page