Robutler

WebUI Skill

Serves a compiled React web UI for agent interaction in the browser.

TypeScript: Coming soon. The WebUI skill bundles a React SPA and is Python-only today (webagents.agents.skills.local.webui). Track parity in the parity matrix. TypeScript agents can serve the same UI by registering a static-file @http handler that returns the built dist/ assets.

Overview

The WebUI skill mounts a React single-page application at /ui that provides:

  • Agent List Sidebar - Browse and switch between available agents
  • Chat Interface - Conversational UI with markdown rendering
  • Agent Details - View agent configuration and status
  • Real-time Communication - Live updates via daemon connection

Requirements

The React app must be built before the skill can serve it:

# Build using CLI
webagents ui --build

# Or manually
cd webagents/cli/webui
pnpm install
pnpm build

Configuration

// WebUISkill is Python-only today. Equivalent TypeScript pattern:
// register a static @http handler that serves the built dist/ folder.
import { Skill, http } from 'webagents';
import { readFile } from 'node:fs/promises';
import { join, extname } from 'node:path';

class WebUIStubSkill extends Skill {
  readonly name = 'webui';
  private readonly distDir = '/path/to/webui/dist';

  @http({ path: '/ui/:rest*', method: 'GET' })
  async serve(req: Request): Promise<Response> {
    const url = new URL(req.url);
    const rel = url.pathname.replace(/^\/ui\/?/, '') || 'index.html';
    const file = join(this.distDir, rel);
    try {
      const body = await readFile(file);
      return new Response(body, {
        headers: { 'content-type': contentType(rel) },
      });
    } catch {
      const index = await readFile(join(this.distDir, 'index.html'));
      return new Response(index, { headers: { 'content-type': 'text/html' } });
    }
  }
}

function contentType(name: string): string {
  return ({ '.js': 'text/javascript', '.css': 'text/css', '.html': 'text/html' } as Record<string, string>)[extname(name)] ?? 'application/octet-stream';
}

Options

OptionTypeDefaultDescription
titlestring"WebAgents Dashboard"Display title for the UI

Commands

CommandDescription
/uiGet the URL for the web UI
/ui/statusCheck WebUI build and mount status

/ui

Returns the URL to access the web interface:

/ui

**WebAgents Dashboard:** http://localhost:8765/ui

/ui/status

Returns detailed status information:

{
  "mounted": true,
  "dist_path": "/path/to/webagents/cli/webui/dist",
  "dist_exists": true,
  "index_exists": true,
  "assets_exist": true,
  "build_time": "2024-01-15T10:30:00"
}

CLI Commands

CommandDescription
webagents uiStart development server
webagents ui --buildBuild production assets
webagents ui --port 5173Use custom port for dev server

Development Mode

# Terminal 1: Start daemon
webagents daemon start --dev

# Terminal 2: Start Vite dev server with hot reload
webagents ui --port 5173

The Vite dev server proxies API requests to the daemon at localhost:8765.

Production Build

# Build assets
webagents ui --build

# Restart daemon to serve built assets
webagents daemon restart

Accessing the UI

Once the daemon is running with built assets:

# Start daemon (if not running)
webagents daemon start

# Open browser
open http://localhost:8765/ui

Or from the REPL:

> /ui
**WebAgents Dashboard:** http://localhost:8765/ui

Architecture

webagents/
├── cli/
│   └── webui/           # React application source
│       ├── src/         # React components, hooks, etc.
│       │   ├── components/
│       │   ├── hooks/
│       │   └── App.tsx
│       ├── dist/        # Built output (gitignored)
│       └── package.json
└── agents/
    └── skills/
        └── local/
            └── webui/
                └── skill.py  # WebUI skill

Routes Served

RouteContent
/uiReact SPA (index.html)
/ui/*React SPA (SPA routing)
/ui/assets/*Static files (JS, CSS, images)

All /ui/* routes return index.html to support client-side routing.

React Application

The web UI is built with:

  • React 18 - UI framework
  • Vite - Build tool and dev server
  • TailwindCSS - Styling
  • React Query - Data fetching
  • React Router - Client-side routing

Features

  • Markdown rendering with syntax highlighting
  • Dark/light theme support
  • Responsive design
  • Keyboard shortcuts
  • Session persistence

Development

Prerequisites

# Install pnpm if needed
npm install -g pnpm

# Install dependencies
cd webagents/cli/webui
pnpm install

Development Workflow

# Start Vite dev server (hot reload)
pnpm dev

# Run type checking
pnpm typecheck

# Run linting
pnpm lint

# Build for production
pnpm build

# Preview production build
pnpm preview

Environment Variables

Create .env.local for development:

# API endpoint (defaults to localhost:8765)
VITE_API_URL=http://localhost:8765

Troubleshooting

"WebUI dist not found"

Build the React app:

webagents ui --build

"Agent has no app attribute"

The Python skill requires the agent to have a Starlette app attribute. This is automatically provided when running through webagentsd or using:

// In TypeScript, the Hono app is created by `serve()` or `createAgentApp()`.
// Static @http handlers are registered automatically — no flag needed.
import { serve } from 'webagents';
await serve(agent, { port: 8765 });

Assets 404

Ensure the build completed successfully:

ls webagents/cli/webui/dist/assets/

Should show JavaScript and CSS files.

Blank Page

Check browser console for errors. Common issues:

  • API endpoint not accessible
  • CORS configuration
  • Build errors

Port Already in Use

# Check what's using the port
lsof -i :8765

# Use different port
webagents daemon start --port 8766

API Integration

The WebUI communicates with the daemon via:

EndpointMethodDescription
/api/agentsGETList agents
/api/agents/{id}GETGet agent details
/api/agents/{id}/chatPOSTSend message
/api/agents/{id}/streamSSEStream responses

See the Server API documentation for details.

On this page