Skip to main content

HTTP Dashboard

Symphony provides an optional HTTP observability interface for monitoring agent activity in real-time.

Enabling the Dashboard

Enable the HTTP server using the --port flag or configuration:
./bin/symphony --port 4000 ./WORKFLOW.md
Source: config.ex:348-362 (elixir/lib/symphony_elixir/…)

Accessing the Dashboard

Once enabled, access the dashboard at:
http://127.0.0.1:4000/
The dashboard displays:
  • Active agent count and capacity
  • Token throughput (tokens per second)
  • Total runtime and token consumption
  • Rate limit status
  • Running agents with detailed status
  • Retry queue for failed agents
  • Links to Linear project and dashboard URL
Source: http_server.ex:410-434 (elixir/lib/symphony_elixir/…)

Terminal Dashboard

Symphony also renders a live status dashboard directly in the terminal:
╭─ SYMPHONY STATUS
│ Agents: 3/10
│ Throughput: 1,234 tps
│ Runtime: 15m 42s
│ Tokens: in 45,678 | out 23,456 | total 69,134
│ Rate Limits: claude-sonnet-4.5 | primary 4,950/5,000 reset 60s | secondary n/a | credits unlimited
│ Project: https://linear.app/project/your-project/issues
│ Dashboard: http://127.0.0.1:4000/
│ Next refresh: 25s
├─ Running

│   ID       STAGE          PID      AGE / TURN   TOKENS     SESSION        EVENT
│   ──────────────────────────────────────────────────────────────────────────────
│ ● ABC-123  agent_working  12345    5m 12s / 3   12,345     sess...abc123  turn completed (completed)
│ ● DEF-456  agent_working  12346    2m 45s / 1   8,901      sess...def456  command output streaming

├─ Backoff queue

│  ↻ GHI-789 attempt=2 in 45.123s error=agent exited: :timeout
╰─
Source: status_dashboard.ex:125-141 (elixir/lib/symphony_elixir/…)

API Endpoints

Symphony exposes several JSON API endpoints for programmatic monitoring.

GET /api/v1/state

Returns the current orchestrator state including all running and retrying agents.
curl http://127.0.0.1:4000/api/v1/state
Source: http_server.ex:234-292 (elixir/lib/symphony_elixir/…)
The /api/v1/state endpoint uses a configurable snapshot timeout (default: 15 seconds). If the orchestrator doesn’t respond in time, an error payload is returned.

GET /api/v1/:issue_identifier

Retrieve detailed status for a specific issue.
curl http://127.0.0.1:4000/api/v1/ABC-123
Source: http_server.ex:253-332 (elixir/lib/symphony_elixir/…) Status Values:
  • running - Agent is actively working on the issue
  • retrying - Agent failed and is scheduled for retry
Returns 404 if the issue is not found in the orchestrator state.

POST /api/v1/refresh

Trigger an immediate refresh of the Linear issue polling cycle.
curl -X POST http://127.0.0.1:4000/api/v1/refresh
Source: http_server.ex:237-245 (elixir/lib/symphony_elixir/…) Returns:
  • 202 Accepted - Refresh request queued successfully
  • 503 Service Unavailable - Orchestrator is not responding

Observability Configuration

Configure dashboard refresh behavior in WORKFLOW.md:
observability:
  dashboard_enabled: true
  refresh_ms: 1000            # Poll orchestrator every 1 second
  render_interval_ms: 16      # Render at ~60fps
Source: config.ex:133-149 (elixir/lib/symphony_elixir/…)

Configuration Options

OptionDefaultDescription
dashboard_enabledtrueEnable terminal dashboard rendering
refresh_ms1000Milliseconds between orchestrator polls
render_interval_ms16Minimum milliseconds between terminal renders
The terminal dashboard uses throttling to prevent excessive rendering. Even if data changes rapidly, renders are limited by render_interval_ms.

HTTP Server Details

Server Configuration

# Default host binding
@default_server_host "127.0.0.1"

# Request limits
@max_header_bytes 8_192      # 8 KB
@max_body_bytes 1_048_576    # 1 MB
@recv_timeout_ms 1_000       # 1 second
@accept_timeout_ms 100       # 100 milliseconds
Source: http_server.ex:10-13 (elixir/lib/symphony_elixir/…)

Error Responses

The HTTP server returns structured error responses:
Status CodeError CodeDescription
400bad_requestMalformed HTTP request
404not_foundRoute not found
404issue_not_foundIssue not in orchestrator state
405method_not_allowedHTTP method not supported
413headers_too_largeRequest headers exceed limit
413body_too_largeRequest body exceeds limit
503orchestrator_unavailableOrchestrator not responding
Source: http_server.ex:247-267 (elixir/lib/symphony_elixir/…)

Metrics and Telemetry

Token Metrics

Symphony tracks cumulative token consumption across all agents:
  • Input Tokens - Total tokens sent to Codex
  • Output Tokens - Total tokens generated by Codex
  • Total Tokens - Sum of input and output
  • Throughput (TPS) - Tokens per second, calculated over a rolling 5-second window
Source: status_dashboard.ex:486-523 (elixir/lib/symphony_elixir/…)

Runtime Tracking

Runtime is tracked per agent and aggregated:
  • Per-agent runtime in seconds
  • Total runtime across all agents
  • Turn count per agent
Source: http_server.ex:345-362 (elixir/lib/symphony_elixir/…)

Rate Limit Monitoring

Symphony captures and displays rate limit information from Codex:
{
  "limit_id": "claude-sonnet-4.5",
  "primary": {
    "remaining": 4950,
    "limit": 5000,
    "reset_in_seconds": 60
  },
  "secondary": {
    "remaining": 980,
    "limit": 1000,
    "reset_in_seconds": 45
  },
  "credits": {
    "unlimited": false,
    "has_credits": true,
    "balance": 1000000.50
  }
}
Source: status_dashboard.ex:917-935 (elixir/lib/symphony_elixir/…)
Rate limit data is provided by Codex through the app-server protocol and may vary based on the model and account type.

Build docs developers (and LLMs) love