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

# Dashboard

> Real-time call monitoring dashboard — Vite + React SPA bundled into a single HTML file embedded by both SDKs.

# Dashboard

Patter ships a built-in web dashboard for monitoring calls in real time. It tracks live calls, latency waterfalls, and per-component cost breakdowns, and is embedded in both the Python and TypeScript SDKs from a single source of truth.

## Architecture

The dashboard UI is a Vite + React 18 + TypeScript single-page app living at the repo root in `dashboard-app/`. It is bundled by [`vite-plugin-singlefile`](https://github.com/richardtallent/vite-plugin-singlefile) into one self-contained `dist/index.html` (\~190 KB, JS + CSS inlined) and copied into both SDKs as `ui.html`.

```
dashboard-app/                ← single source of truth (dev-only, never published)
├── src/
│   ├── App.tsx               # composes the dashboard
│   ├── components/           # Topbar, MetricsPanel, CallTable, LiveCallPanel,
│   │                         # LatencyPanel, CostPanel, PageHeader, ...
│   ├── hooks/                # useDashboardData, useTranscript (SSE-backed)
│   └── styles/               # tokens.css + dashboard.css
├── vite.config.ts            # singlefile plugin config
└── scripts/sync.mjs          # post-build copy to both SDKs

libraries/python/getpatter/dashboard/ui.html   ← synced artefact (committed)
libraries/typescript/src/dashboard/ui.html      ← synced artefact (committed)
```

At runtime each SDK loads the file as a string:

* **Python**: `importlib.resources.files("getpatter.dashboard").joinpath("ui.html").read_text()` — see `libraries/python/getpatter/dashboard/ui.py`.
* **TypeScript**: `readFileSync(join(__dirname, "ui.html"), "utf8")` — see `libraries/typescript/src/dashboard/ui.ts`.

The string is served from `GET /` by the embedded FastAPI / Express app. End users never touch Node — `ui.html` is checked into both packages so `pip install getpatter` and `npm install getpatter` work out of the box.

## Local development

The dashboard talks to a running SDK server over the existing `/api/dashboard/*` REST + SSE API. The Vite dev server proxies `/api` to `127.0.0.1:8000` so you can iterate on the UI against a real backend.

```bash theme={null}
# Terminal 1 — start any Patter agent on :8000
python my_agent.py                   # your Patter agent (Python or TS)

# Terminal 2 — Vite dev server with hot reload
cd dashboard-app
npm install
npm run dev                          # opens http://127.0.0.1:5173
```

`npm run dev` proxies `/api/*` and `/sse/*` to `http://127.0.0.1:8000`, so the SPA renders against whatever the running SDK reports.

## Build and sync into the SDKs

`npm run build && npm run sync` is the canonical pre-publish step:

```bash theme={null}
cd dashboard-app
npm run build      # tsc --noEmit && vite build → dist/index.html (~190 KB single file)
npm run sync       # copy dist/index.html into both SDKs as ui.html
```

`scripts/sync.mjs` copies the bundled file to:

* `libraries/python/getpatter/dashboard/ui.html` (shipped via `[tool.setuptools.package-data]`)
* `libraries/typescript/src/dashboard/ui.html` (copied to `dist/dashboard/ui.html` by `tsup`)

Both files are committed to the repo. CI rebuilds and re-syncs on every release tag, so a hand-edited `ui.html` will be overwritten — always edit `dashboard-app/src/`.

## Embedded dashboard

When running `serve()`, the dashboard is enabled by default at the root URL:

<CodeGroup>
  ```python Python theme={null}
  await phone.serve(agent=agent, port=8000, dashboard=True)
  # Dashboard: http://127.0.0.1:8000/
  ```

  ```typescript TypeScript theme={null}
  await phone.serve(agent, { port: 8000, dashboard: true });
  // Dashboard: http://127.0.0.1:8000/
  ```
</CodeGroup>

## Standalone dashboard

Run the dashboard as a separate process — useful when using the SDK as a tool (e.g. from LangGraph or Claude Code).

<CodeGroup>
  ```bash Python theme={null}
  pip install getpatter
  getpatter dashboard --port 8000
  ```

  ```bash TypeScript theme={null}
  npx getpatter dashboard --port 8000
  ```
</CodeGroup>

The standalone dashboard receives call data automatically from the SDK over HTTP.

## Features

* **Top metrics row** — Total Calls, Total Cost, Avg Duration, Avg Latency. Numerics in JetBrains Mono so columns align.
* **Call table** — every completed call with cost, latency, turn count, provider, voice mode.
* **Live-call right rail** — caller/callee, streaming transcript, **per-call latency waterfall** (STT, LLM first-token, TTS first-byte, total turn), and **cost breakdown** updating as the call progresses.
* **Call detail** — click any historical call for the full transcript, averaged + P95 latency waterfall, and cost breakdown.
* **Real-time updates** — Server-Sent Events on `/api/dashboard/events`; no polling.
* **Design system** — peach accent, dot-grid surfaces, JetBrains Mono numerics, matching the rest of the Patter brand.

## API endpoints

The SPA is a thin client over a stable REST + SSE API — useful for direct integrations.

| Endpoint                          | Description                               |
| --------------------------------- | ----------------------------------------- |
| `GET /`                           | Dashboard web UI (the bundled `ui.html`). |
| `GET /api/dashboard/calls`        | List calls (paginated).                   |
| `GET /api/dashboard/calls/:id`    | Single call detail.                       |
| `GET /api/dashboard/active`       | Active calls.                             |
| `GET /api/dashboard/aggregates`   | Aggregate stats.                          |
| `GET /api/dashboard/events`       | SSE event stream.                         |
| `GET /api/dashboard/export/calls` | Export as CSV (`?format=csv`) or JSON.    |
