Browser UI

Local, loopback-only browser UI for exploring sessions, evals, and token usage.

thirdeye ui launches a local browser UI as a richer alternative to the CLI for exploring sessions, visualizing traces, tagging events, authoring evals, and watching token spend over time. The server is opt-in, binds loopback only, and reads/writes the same <thirdeye_home>/ tree the CLI uses.

thirdeye
tags
bugreviewauditexemplarrefactormigration
Ask
4 sessions
sessionplatformcwdstartedeventsstatus
a3f2c8b1claudethrdi-web2026-05-22 14:0847open
91e4d20acodexthirdeye2026-05-22 11:0391closed
7d12c9b3claudewbcli-web2026-05-21 18:4123closed
4e0f6b88codexworkbench2026-05-20 09:1412closed

Live preview — not interactive. The real UI streams open sessions via SSE and persists filters in localStorage.

The preview above mirrors the sessions list at / — saved-views sidebar, filter form with the tag multi-select, the Ask panel, the eval batch bar, and the sessions table. Click a session id in the real UI to drill into its event tree.

Install

The Homebrew package includes the browser UI and all of its dependencies:

brew install duncanmckinnon/tap/thirdeye

For Python installations, the UI ships as an optional extra so the default pip install thrdi stays lean:

pip install 'thrdi[ui]'

Using pipx? Inject the deps into the existing thrdi venv:

pipx inject thrdi starlette uvicorn jinja2

Launch

thirdeye ui                        # http://127.0.0.1:8765 by default
thirdeye ui --port 9000            # pick a port
thirdeye ui --host 127.0.0.1       # interface to bind (loopback only)
thirdeye ui --no-browser           # don't auto-open the browser

The CLI opens your default browser unless --no-browser is passed. Ctrl-C stops the server.

If the extra isn't installed, thirdeye ui prints a hint and exits with status 1:

The 'ui' extra is required. Install it with: pip install 'thrdi[ui]'

What you can do

Browse sessions

The list at / shows every recorded session across every platform, with filters for platform, cwd, status (open / closed / stale), date range, and a tag multi-select drawn from every tag in your history. Defaults to the last 7 days, newest first. The active filter persists in localStorage, so navigating away and back keeps your view.

Ask panel (agentic filters)

Both / and /search carry an Ask textarea. Type a natural-language description — "find sessions about the workbench plan", "long-lasting claude runs this week" — pick a CLI agent (claude / codex / gemini), and submit.

The agent receives a grounded vocabulary block (your platforms, cwds, tags) plus the bundled thirdeye-filter skill and returns a structured JSON envelope. The UI auto-fills the existing filter form with the proposed values — review or tweak any field, then hit Search / Filter to run. No auto-execute, no separate Run button to learn.

Saved filter views

From /, name a filter combination and pin it to the sidebar. Saved views persist on disk at <thirdeye_home>/views/sessions.json and are manageable from the CLI too:

thirdeye views list --page sessions
thirdeye views save my-view --page sessions
thirdeye views delete my-view --page sessions

Session view

Each session view renders the event stream as a collapsible tree, color-coded by event type (user, assistant, tool call, tool result, etc.). Click any event to expand its full JSON payload in the side pane. Tag any event inline — tags hit the same per-session store the CLI uses, so thirdeye search --tag <name> picks them up immediately.

Live-tail open sessions

Sessions that are still receiving events stream new entries into the tree in real time via Server-Sent Events. No refresh needed.

Search across sessions

Substring search with the same filters as thirdeye search. Each hit links straight to the event in its session.

Usage charts

/usage renders daily tokens-over-time (stacked input / output) and sessions-per-day charts via vendored Chart.js, plus totals cards. Filter by platform / since / until. Per-session usage at /sessions/<id>/usage keeps the existing per-turn detail view.

Author and run evals

Browse, edit, and create eval definitions (YAML rubrics) in the browser. Dispatch a run against any single session, or select multiple sessions on / and dispatch a batch of runs in one click. Each run gets a unique run_id; the same definition can be re-run on the same session.

Two complementary cross-cuts ship in the UI:

  • /evals/defs/<name>/results — every run of one definition across every session it's been applied to. Sortable, with verdict / agent / started-at / duration and a link to each run's findings. Useful for tracking how one rubric grades across your history.
  • /sessions/<id>/evals/<def_name> — every run of one definition on one session. Renders the definition's full directive text plus a table of every run on that session, with parsed columns: run id, verdict, one column per score key seen across runs (with for absent), findings count, duration, started, agent. Useful for comparing iterations of the same rubric on a single session.

Keyboard shortcuts

Inside the session tree:

KeyAction
/ Move between sibling events.
Collapse the focused node (or jump to its parent if already collapsed).
Expand the focused node.
EnterOpen the focused event in the side pane.

Security model

  • The server binds 127.0.0.1 by default and refuses to listen on other interfaces unless --host is overridden explicitly.
  • No authentication. The UI is intended for local use on a trusted workstation. Don't expose it over a network or tunnel it without adding your own auth layer in front.
  • All reads and writes operate on the same <thirdeye_home>/ tree the CLI uses (THIRDEYE_HOME env var, default ~/.thirdeye/).

Troubleshooting

  • ModuleNotFoundError: starlette — a Python installation is missing the ui extra. Run pip install 'thrdi[ui]' (or pipx inject thrdi starlette uvicorn jinja2). Homebrew installs already include it.
  • OSError: [Errno 48] Address already in use — another process holds the port. Pass --port with a free port, or stop the other process.
  • Browser didn't open — pass --no-browser to suppress the auto-open and copy the printed URL manually. On headless machines, always use --no-browser.
  • Live tail isn't updating — confirm the session is still open (the session header shows status). Closed sessions render the full timeline but don't stream. Some restrictive corporate proxies break SSE; running the browser on the same host as the server avoids the proxy entirely.
  • 404 on a session ID — IDs accept any unique prefix. If you typed an ambiguous prefix the 404 page lists the closest matches; click one to disambiguate.