Skip to main content

Admin Socket.IO Gateway

The createAdminGateway() function attaches admin CRUD event handlers to a Socket.IO server. All operations use acknowledgement callbacks for request-response, and mutations are broadcast to all connected clients in real time.

Setup

import { Server } from "socket.io";
import { SqliteStorage } from "@radaros/core";
import { createAdminGateway } from "@radaros/admin";

const io = new Server(httpServer);

const { hydrate } = createAdminGateway({
  io,
  storage: new SqliteStorage("radaros.db"),
  toolkits: [new CalculatorToolkit(), new DuckDuckGoToolkit()],
  namespace: "/radaros-admin",
  authMiddleware: (socket, next) => {
    const token = socket.handshake.auth?.token;
    if (!token || !validateToken(token)) return next(new Error("Unauthorized"));
    next();
  },
});

await hydrate();

AdminGatewayOptions

io
Server
required
Socket.IO server instance.
storage
StorageDriver
required
Storage backend for persisting blueprints.
toolLibrary
Record<string, ToolDef>
Named tools available for agent creation. Explicit entries override toolkit tools.
toolkits
Toolkit[]
Toolkit instances whose tools are automatically collected into the tool library.
namespace
string
default:"/radaros-admin"
Socket.IO namespace for admin events.
authMiddleware
(socket, next) => void
Socket.IO middleware for authentication.

Events

Agent Events

EventPayloadResponse
admin.agent.create{ name, provider, model, instructions?, tools?, temperature? }{ ok, data }
admin.agent.list{}{ ok, data: AgentBlueprint[] }
admin.agent.get{ name }{ ok, data }
admin.agent.update{ name, ...fields }{ ok, data }
admin.agent.delete{ name }{ ok, data: { deleted } }

Team Events

EventPayloadResponse
admin.team.create{ name, mode, provider, model, members, instructions? }{ ok, data }
admin.team.list{}{ ok, data: TeamBlueprint[] }
admin.team.get{ name }{ ok, data }
admin.team.update{ name, ...fields }{ ok, data }
admin.team.delete{ name }{ ok, data: { deleted } }

Workflow Events

EventPayloadResponse
admin.workflow.create{ name, description? }{ ok, data }
admin.workflow.list{}{ ok, data: WorkflowBlueprint[] }
admin.workflow.delete{ name }{ ok, data: { deleted } }

Tools

EventPayloadResponse
admin.tools.list{}{ ok, data: [{ name, description, parameters }] }
admin.tools.get{ name }{ ok, data: { name, description, parameters } }

Toolkit Catalog

EventPayloadResponse
admin.toolkit-catalog.list{}{ ok, data: ToolkitMeta[] }
admin.toolkit-catalog.get{ id }{ ok, data: ToolkitMeta }

Toolkit Configs (Credentials)

EventPayloadResponse
admin.toolkit-config.create{ toolkitId, instanceName, config, enabled? }{ ok, data: MaskedConfig }
admin.toolkit-config.list{}{ ok, data: MaskedConfig[] }
admin.toolkit-config.get{ instanceName }{ ok, data: MaskedConfig }
admin.toolkit-config.update{ instanceName, config?, enabled? }{ ok, data: MaskedConfig }
admin.toolkit-config.delete{ instanceName }{ ok, data: { deleted } }

Registry

EventPayloadResponse
admin.registry.list{}{ ok, data: { agents, teams, workflows } }

Broadcast Events

When entities are created, updated, or deleted, the gateway broadcasts to all connected clients on the admin namespace:
Broadcast EventPayload
admin.agent.createdAgentBlueprint
admin.agent.updatedAgentBlueprint
admin.agent.deleted{ name }
admin.team.createdTeamBlueprint
admin.team.updatedTeamBlueprint
admin.team.deleted{ name }
admin.workflow.createdWorkflowBlueprint
admin.workflow.deleted{ name }
admin.toolkit-config.createdMaskedToolkitConfig
admin.toolkit-config.updatedMaskedToolkitConfig
admin.toolkit-config.deleted{ instanceName }
This enables real-time UI updates — when one user creates an agent, all other connected users see it appear immediately.

Client Example

const socket = io("http://localhost:3000/radaros-admin", {
  auth: { token: "my-admin-token" },
});

// Create an agent
socket.emit("admin.agent.create", {
  name: "researcher",
  provider: "openai",
  model: "gpt-4o",
  instructions: "You research topics thoroughly.",
  tools: ["webSearch"],
}, (res) => {
  if (res.ok) {
    console.log("Created:", res.data.name);
  } else {
    console.error("Error:", res.error);
  }
});

// List all agents
socket.emit("admin.agent.list", {}, (res) => {
  console.log("Agents:", res.data);
});

// Discover available tools (for agent builder UI)
socket.emit("admin.tools.list", {}, (res) => {
  console.log("Available tools:", res.data);
  // [{ name: "calculate", description: "...", parameters: ["expression"] }, ...]
});

// Listen for real-time updates from other users
socket.on("admin.agent.created", (agent) => {
  console.log("New agent:", agent.name);
});

socket.on("admin.team.created", (team) => {
  console.log("New team:", team.name, "with members:", team.members);
});

Full Flow: Create Agents, Build Team, Run

const admin = io("http://localhost:3000/radaros-admin");
const agent = io("http://localhost:3000/radaros");

// Step 1: Create agents
await new Promise((resolve) => {
  admin.emit("admin.agent.create", {
    name: "researcher", provider: "openai", model: "gpt-4o",
    tools: ["webSearch"],
  }, resolve);
});

await new Promise((resolve) => {
  admin.emit("admin.agent.create", {
    name: "writer", provider: "openai", model: "gpt-4o-mini",
  }, resolve);
});

// Step 2: Build a team from those agents
await new Promise((resolve) => {
  admin.emit("admin.team.create", {
    name: "content-team", mode: "coordinate",
    provider: "openai", model: "gpt-4o",
    members: ["researcher", "writer"],
  }, resolve);
});

// Step 3: Run the team via the transport gateway
agent.emit("team.run", {
  name: "content-team",
  input: "Write a blog post about AI agents",
});

agent.on("agent.done", ({ output }) => {
  console.log("Result:", output.text);
});