Web Host Plugin
Fastify-based web server for serving resources, APIs, and WebSocket endpoints in TokenRing.
Overview
The @tokenring-ai/web-host
package provides a high-performance Fastify web server with WebSocket support and a pluggable resource registration system. It serves as the foundation for hosting web UIs, REST APIs, and real-time communication endpoints.
Key Features
- Fastify Server: High-performance HTTP/HTTPS server
- WebSocket Support: Built-in WebSocket capabilities via @fastify/websocket
- Resource Registration: Pluggable system for registering web resources
- Static File Serving: Serve static files and single-page applications
- Configurable Port: Flexible port configuration
Core Components
WebHostService
Central service managing the Fastify server and resource registration.
Key Methods:
registerResource(key: string, resource: WebResource)
- Register a web resourcestart(agentTeam: AgentTeam): Promise<void>
- Start the web serverstop(): Promise<void>
- Stop the web servergetServer(): FastifyInstance
- Get Fastify instance for advanced usage
Properties:
name
- Service name: "WebHostService"description
- Service descriptionport
- Server port (default: 3000)
WebResource Interface
Interface for pluggable web resources.
interface WebResource {
name: string;
register(server: FastifyInstance): Promise<void> | void;
}
Resources can register:
- HTTP routes (GET, POST, PUT, DELETE, etc.)
- WebSocket endpoints
- Static file directories
- Middleware
- Any Fastify plugin functionality
Usage Examples
Basic Setup
import { AgentTeam } from "@tokenring-ai/agent";
import { packageInfo } from "@tokenring-ai/web-host";
const team = new AgentTeam({
webHost: {
enabled: true,
port: 3000
}
});
await team.addPackages([packageInfo]);
// Server starts automatically and listens on port 3000
Registering Custom Resources
import { WebHostService } from "@tokenring-ai/web-host";
import type { WebResource } from "@tokenring-ai/web-host";
// Create a custom resource
const myResource: WebResource = {
name: "MyAPI",
async register(server) {
server.get("/api/hello", async () => {
return { hello: "world" };
});
server.post("/api/data", async (request, reply) => {
const data = request.body;
return { received: data };
});
}
};
// Register the resource
const webHost = team.services.getItemByType(WebHostService);
webHost.registerResource("myAPI", myResource);
Serving Static Files
import fastifyStatic from "@fastify/static";
import { join } from "path";
const staticResource: WebResource = {
name: "StaticFiles",
async register(server) {
await server.register(fastifyStatic, {
root: join(__dirname, "public"),
prefix: "/static/",
});
}
};
webHost.registerResource("static", staticResource);
WebSocket Endpoint
const wsResource: WebResource = {
name: "WebSocketAPI",
async register(server) {
server.get("/ws", { websocket: true }, (socket, req) => {
socket.on("message", (data) => {
console.log("Received:", data.toString());
socket.send(JSON.stringify({ echo: data.toString() }));
});
socket.on("close", () => {
console.log("Client disconnected");
});
});
}
};
webHost.registerResource("websocket", wsResource);
Single-Page Application
const spaResource: WebResource = {
name: "SPA",
async register(server) {
await server.register(fastifyStatic, {
root: join(__dirname, "dist"),
prefix: "/",
});
// Serve index.html for all routes (SPA routing)
server.setNotFoundHandler((request, reply) => {
reply.sendFile("index.html");
});
}
};
webHost.registerResource("spa", spaResource);
Configuration
WebHostConfigSchema:
{
port: number; // Server port (default: 3000)
enabled: boolean; // Enable/disable service (default: true)
}
AgentTeam Config:
const team = new AgentTeam({
webHost: {
enabled: true,
port: 8080
}
});
Advanced Usage
Accessing Fastify Instance
const webHost = team.services.getItemByType(WebHostService);
const server = webHost.getServer();
// Add custom plugins
await server.register(require("@fastify/cors"), {
origin: "*"
});
// Add hooks
server.addHook("onRequest", async (request, reply) => {
console.log(`${request.method} ${request.url}`);
});
Multiple Resources
// Register multiple resources
webHost.registerResource("api", apiResource);
webHost.registerResource("admin", adminResource);
webHost.registerResource("frontend", frontendResource);
// Resources are registered in order during server start
Integration with Other Packages
The web-host package is designed to work with:
@tokenring-ai/agent-api
- WebSocket API for agent communication@tokenring-ai/web-frontend
- React-based web UI- Custom web resources for specialized functionality
Dependencies
@tokenring-ai/agent
(^0.1.0): Agent system integration@tokenring-ai/utility
(^0.1.0): Keyed registryfastify
(^5.2.0): Web server framework@fastify/websocket
(^11.0.1): WebSocket support@fastify/static
(^8.0.2): Static file serving
License
MIT License - Copyright (c) 2025 Mark Dierolf