> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentium.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Admin API

> Dynamically create, update, and delete agents, teams, and workflows at runtime via REST or Socket.IO.

# Admin API

The `@agentium/admin` package provides CRUD endpoints for dynamically managing agents, teams, and workflows at runtime. Entities are persisted to a storage backend and automatically hydrated into the live registry on server restart.

***

## Architecture

```mermaid theme={null}
flowchart LR
    Client -->|"POST /admin/agents"| AdminRouter
    Client -->|"admin.agent.create"| AdminGateway
    AdminRouter --> EntityFactory
    AdminGateway --> EntityFactory
    AdminRouter --> ConfigStore
    AdminGateway --> ConfigStore
    EntityFactory -->|"new Agent(...)"| Registry
    ConfigStore -->|"persist"| Storage
    Storage -->|"hydrate on boot"| EntityFactory
```

* **AdminRouter** — Express router with REST CRUD endpoints
* **AdminGateway** — Socket.IO event handlers with real-time broadcasts
* **ConfigStore** — Persists serializable blueprints to any `StorageDriver`
* **EntityFactory** — Resolves blueprints into live `Agent`/`Team` instances via `modelRegistry`
* **Hydration** — On startup, reads all saved configs and re-creates entities into the registry

***

## Installation

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install @agentium/admin
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={null}
    pnpm add @agentium/admin
    ```
  </Tab>
</Tabs>

***

## Quick Start (Express)

```typescript theme={null}
import express from "express";
import { SqliteStorage } from "@agentium/core";
import { createAgentRouter } from "@agentium/transport";
import { createAdminRouter } from "@agentium/admin";

const app = express();
app.use(express.json());

const { router, hydrate } = createAdminRouter({
  storage: new SqliteStorage("agentium.db"),
  toolkits: [
    new CalculatorToolkit(),
    new DuckDuckGoToolkit(),
    new GitHubToolkit({ token: process.env.GITHUB_TOKEN }),
  ],
  // explicit entries override toolkit tools with the same name
  toolLibrary: { customTool: myCustomTool },
});

await hydrate(); // re-create persisted entities on startup

app.use("/admin", router);            // CRUD management
app.use("/api", createAgentRouter()); // auto-discovers from registry

app.listen(3000);
```

## Quick Start (Socket.IO)

```typescript theme={null}
import { Server } from "socket.io";
import { SqliteStorage } from "@agentium/core";
import { createAgentGateway } from "@agentium/transport";
import { createAdminGateway } from "@agentium/admin";

const io = new Server(httpServer);

const { hydrate } = createAdminGateway({
  io,
  storage: new SqliteStorage("agentium.db"),
  toolkits: [new CalculatorToolkit(), new DuckDuckGoToolkit()],
  namespace: "/agentium-admin",
});

await hydrate();

createAgentGateway({ io }); // auto-discovers from registry
```

***

## AdminOptions

<ParamField body="storage" type="StorageDriver" required>
  Storage backend for persisting blueprints. Any `StorageDriver` works: `InMemoryStorage`, `SqliteStorage`, `PostgresStorage`, `MongoDBStorage`.
</ParamField>

<ParamField body="toolLibrary" type="Record<string, ToolDef>">
  Named tools available for agent creation. Users reference tools by key name in blueprints.
  Explicit entries override any toolkit tools with the same name.
</ParamField>

<ParamField body="toolkits" type="Toolkit[]">
  Toolkit instances whose tools are automatically registered in the tool library.
  Pass any built-in toolkit (e.g., `CalculatorToolkit`, `GitHubToolkit`) and all their tools become
  available for agent creation. A `GET /tools` endpoint and `admin.tools.list` event are provided
  for the UI to discover available tools.
</ParamField>

<ParamField body="middleware" type="RequestHandler[]">
  Express middleware applied to all admin routes (e.g., authentication).
</ParamField>

***

## Hydration

Call `hydrate()` once at startup to re-create all persisted entities into the live registry:

```typescript theme={null}
const counts = await hydrate();
console.log(counts);
// { agents: 3, teams: 1, workflows: 0 }
```

This reads all saved blueprints from storage, resolves them via `EntityFactory` (model providers, tools, team members), and creates live instances that auto-register into the global registry. Existing entities with the same name are skipped.

***

## Tool Discovery

The admin layer exposes endpoints and events so the UI can list all available tools before creating agents.

### REST

```bash theme={null}
# List all available tools
curl http://localhost:3000/admin/tools
```

```json theme={null}
[
  { "name": "calculate", "description": "Evaluate a math expression", "parameters": ["expression"] },
  { "name": "duckduckgo_search", "description": "Search the web", "parameters": ["query", "maxResults"] },
  { "name": "github_list_repos", "description": "List repositories", "parameters": ["owner"] }
]
```

```bash theme={null}
# Get a single tool's detail
curl http://localhost:3000/admin/tools/calculate
```

### Socket.IO

```typescript theme={null}
socket.emit("admin.tools.list", {}, (res) => {
  console.log(res.data);
  // [{ name: "calculate", description: "...", parameters: [...] }, ...]
});

socket.emit("admin.tools.get", { name: "calculate" }, (res) => {
  console.log(res.data);
  // { name: "calculate", description: "...", parameters: ["expression"] }
});
```

### Using `collectToolkitTools`

You can also manually build a tool library from toolkits:

```typescript theme={null}
import { collectToolkitTools, CalculatorToolkit, DuckDuckGoToolkit } from "@agentium/core";

const toolLibrary = collectToolkitTools([
  new CalculatorToolkit(),
  new DuckDuckGoToolkit(),
]);
// { calculate: ToolDef, duckduckgo_search: ToolDef }
```

***

## Toolkit Configuration (Dynamic Credentials)

The admin layer includes a complete toolkit configuration system. Users can configure toolkit
credentials (API keys, tokens, connection strings) through the UI without restarting the server.

### How it works

1. **Toolkit Catalog** — Lists all available toolkit types and what config fields they need
2. **Toolkit Configs** — CRUD operations to save/update/delete credentials per toolkit instance
3. **Secret Masking** — API keys are never returned in plain text; responses mask secret fields
4. **Dynamic Instantiation** — When a config is saved with `enabled: true`, the toolkit is
   immediately created and its tools become available for agent creation
5. **Hydration** — On startup, `hydrate()` re-creates all enabled toolkit instances from storage

### REST Example

```bash theme={null}
# 1. Browse available toolkit types
curl http://localhost:3000/admin/toolkit-catalog
# [{ id: "github", name: "GitHub", configFields: [{ name: "token", secret: true, ... }], ... }]

# 2. Configure a toolkit with credentials
curl -X POST http://localhost:3000/admin/toolkit-configs \
  -H "Content-Type: application/json" \
  -d '{
    "toolkitId": "github",
    "instanceName": "my-github",
    "config": { "token": "ghp_your_real_token_here" },
    "enabled": true
  }'
# Response: { toolkitId: "github", instanceName: "my-github", config: { token: "ghp_****..." }, enabled: true }

# 3. Tools are now available — create an agent that uses them
curl -X POST http://localhost:3000/admin/agents \
  -H "Content-Type: application/json" \
  -d '{ "name": "coder", "provider": "openai", "model": "gpt-4o", "tools": ["github_list_repos", "github_get_issue"] }'
```

### Socket.IO Example

```typescript theme={null}
// Browse the catalog
socket.emit("admin.toolkit-catalog.list", {}, (res) => {
  console.log(res.data);
  // [{ id: "github", name: "GitHub", configFields: [...], requiresCredentials: true }]
});

// Save credentials
socket.emit("admin.toolkit-config.create", {
  toolkitId: "slack",
  instanceName: "my-slack",
  config: { token: "xoxb-your-bot-token" },
  enabled: true,
}, (res) => {
  console.log(res.data.config.token); // "xoxb**************"
});

// List configured toolkits (secrets masked)
socket.emit("admin.toolkit-config.list", {}, (res) => {
  console.log(res.data);
});
```
