Agent Router

A federated, multi-agent cockpit that spawns Gemini, Claude, and Codex in real PTYs and bridges them to a browser workspace.

https://github.com/davidbmar/agent-router  ·  private  ·  shipped

What it is

Agent Router is a local-first control plane for running multiple AI coding agents simultaneously. It isolates each agent (Gemini CLI, Claude Code, Codex) in its own pseudo-terminal (PTY) on the host machine, streams the output to a web-based terminal via WebSockets, and allows users to inject prompts or switch between agents seamlessly. It supports federation, allowing multiple router instances on different machines to share session visibility and prompt injection capabilities over HTTP.

Features

Quickstart

python3 -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn websockets ptyprocess pydantic
python3 server.py

Architecture

flowchart TD
    User[Browser User] -->|HTTP/WebSocket| FE[Static Frontend]
    FE -->|WS /ws/terminal/{id}| Server[FastAPI Server]
    Server -->|Manage| PTYMgr[PTY Manager]
    PTYMgr -->|Spawn| P1[PTY: Claude]
    PTYMgr -->|Spawn| P2[PTY: Gemini]
    PTYMgr -->|Spawn| P3[PTY: Codex]
    P1 -->|Read/Write| Agent1[Claude Code Process]
    P2 -->|Read/Write| Agent2[Gemini CLI Process]
    P3 -->|Read/Write| Agent3[Codex Process]
    Server -->|HTTP /api/*| PeerRouter[Peer Router Instance]
    PeerRouter -->|Proxy| PeerPTY[Peer PTY Session]

How it's built

The backend is built with FastAPI and uvicorn, using the `ptyprocess` library to manage real PTY sessions for each agent. A background thread reads PTY output into a deque buffer for history replay. The frontend is a zero-build static HTML application using xterm.js for terminal emulation, xterm-addon-fit for resizing, and SortableJS for draggable tabs. Federation is handled via HTTP APIs and peer discovery mechanisms including mDNS, Tailscale, and gossip protocols.

How it runs

sequenceDiagram
    participant U as User Browser
    participant S as FastAPI Server
    participant P as PTY Process
    participant A as AI Agent (e.g. Claude)
    
    U->>S: POST /api/sessions (Spawn Agent)
    S->>P: ptyprocess.spawn(Agent Command)
    P-->>S: PTY FD Created
    S-->>U: Session ID & Status
    
    U->>S: WebSocket Connect /ws/terminal/{id}
    S->>P: Attach Reader Thread
    loop Background Read
        P->>S: Read Output Chunk
        S->>U: WS Message (Output)
    end
    
    U->>S: WS Message (User Input/Prompt)
    S->>P: Write to PTY Master
    P->>A: Input Received
    A->>P: Generate Response
    P->>S: Output Available
    S->>U: WS Message (Response)

How to apply & reuse

Use Agent Router when you need to run multiple AI coding agents in parallel without context switching between terminal windows. It is ideal for coordinating complex tasks where one agent might handle backend logic while another handles frontend updates, or when you want to maintain persistent, 'warm' agent sessions that retain history across browser refreshes. The federation features allow scaling across multiple machines for heavy workloads.

At a glance

CapabilitiesPTY ManagementWebSocket StreamingHTTP API FederationPeer DiscoverySession PersistencePrompt Injection
Componentsserver.pydispatcher.pystatic/index.htmlARCHITECTURE.md.env.example
TechPythonFastAPIuvicornwebsocketsptyprocessHTML/JSxterm.jsSortableJS
Depends onClaude Code CLIGemini CLICodex CLIPython 3.8+
Integrates withTailscalemDNSRiff Switchboard
PatternsFederated SystemsPTY BridgingEvent-Driven UIPeer-to-Peer Gossip
Reuse tagsai-agentsterminal-emulatorfederated-learningdeveloper-toolspty-management

⚠ Needs attention