# Dashboard (/observe/dashboard)

The dashboard (the "observer") ships inside the `cuelo` package and is served
by the engine itself.

| Command       | Where                                            |
| ------------- | ------------------------------------------------ |
| `cuelo start` | `http://127.0.0.1:4141`, same port as the API    |
| `cuelo dev`   | `http://127.0.0.1:4142` (`--ui-port`, `--no-ui`) |
| `cuelo call`  | opens the call page against the running agent    |

## Calls [#calls]

The home page shows totals for recent calls (TTFB p50 and p95, barge-in rate,
calls per day over 14 days) and a searchable, filterable list of calls with
duration and median TTFB. Live calls update as they happen.

## A call [#a-call]

Each call has three tabs.

### Overview [#overview]

The whole-call player: both audio channels on one timeline with waveforms,
the transcript under it, and markers for interruptions, backchannels and tool
calls. Click any line to jump there. The summary, models and token counts sit
alongside.

### Latency [#latency]

Per-turn breakdown of `ttfb` into `vad_tail`, `finalize`, `llm_ttft` and
`tts_ttfa`, with p50 and p90 for the call. Also tool time per tool,
interruptions, barge-in rate, premature turn ends and flagged turns.

### Events [#events]

Every engine event in order, filterable by kind: transcripts, controller
signals, policy decisions, LLM, TTS and tool events, errors.

## Talk [#talk]

The Talk page (`/demo`) is a browser client for the Realtime API with a
workbench around it:

- **Presets** to start from: a curious companion, a support line with a sample tool, or blank.
- An editor for **instructions**, **tools** (OpenAI JSON format, run in the
  browser as client tools) and **voice**. Changes apply to a live call with
  **Apply**.
- **Speak first**: sends `response.create` on connect.
- **Live events**: controller signals and decisions as they happen.
- **Latency** for each turn as it lands, and a protocol **log**.

## Keys [#keys]

When the engine has [API keys](/ship/security), the dashboard asks for
one on its first refused request and keeps it in the browser. It sends the key
as `x-api-key` on requests and as a WebSocket subprotocol on calls.

## Developing the dashboard [#developing-the-dashboard]

The dashboard is a Vite and React app in `observer/`. Run `pnpm dev` there with
an engine on `:4141`, and it proxies `/api` and `/v1`. `make cuelo` embeds the
production build in the CLI, and `make dist` bundles it into the wheel.