Skip to main content

đŸ–Ĩī¸ Web UI Guide

Tresor includes an embedded single-page application accessible through any web browser. The web UI is served by the daemon itself on the configured bind_addr — no separate frontend deployment needed.

Access it at http://127.0.0.1:11510 (or whatever bind_addr you configured).

🔐 Authentication​

If you set admin_password in the config, the web UI shows a login screen with a password input field. Enter the password to obtain a session token. All dashboard operations require authentication.

The login screen features the Tresor logo and brand name. If no password is configured, the dashboard opens directly.

🎨 Theme​

The web UI supports dark and light themes. A theme toggle button in the sidebar lets you switch between modes. By default, the UI follows your browser's prefers-color-scheme setting. Theme preference is session-only (not persisted).

📑 Dashboard Tabs​

🔗 Downstreams​

The Downstreams tab displays all configured LLM provider endpoints.

Actions:

  • ➕ Add Downstream — Create a new provider endpoint with name, base URL, API key, and format selection (OpenAI/Anthropic/OpenAI Responses checkboxes)
  • âœī¸ Edit — All fields are editable.
  • đŸ”ĸ Add Model — Manually add model IDs to the downstream's output_model_ids list
  • 🔎 Fetch Models — Calls the provider's /models endpoint to auto-discover available models and add them with one click
  • đŸ—‘ī¸ Delete — Button on top-right corner. Remove the downstream entirely (cascade: removes downstream ID from rule match_downstreams arrays, deletes pointing aliases)

đŸˇī¸ Aliases​

The Aliases tab organizes model mappings into group cards. Each card represents an input model and shows all its alias options as clickable cards in a grid layout.

Actions:

  • ➕ Create Group — Define a new input model with its first alias option. Uses a tag-based model multi-select populated from the selected downstream's known models, plus a custom text input for arbitrary model IDs. A Regex checkbox lets you define the input model as a regular expression pattern (e.g., ^claude-.* to match all Claude models).
  • 📋 Add Option — Add another provider/model mapping to an existing group. Includes a Regex checkbox for pattern-based matching.
  • ⚡ Activate — Click on any inactive option card to hot-switch and make it the active one for its group (deactivates siblings)
  • đŸ—‘ī¸ Delete Option — Remove an individual alias option (auto-promotes sibling if deleting the active one)
  • đŸ’Ĩ Delete Group — Remove all aliases for an input model at once
  • 🔀 Drag-and-Drop Reorder — Drag a group's header to reorder groups vertically. Groups are displayed in group_order sequence; dragging a header to a new position updates the ordering on the server immediately. Groups with regex options show a purple "regex" badge in the header.

📏 Rules​

The Rules tab shows all routing rules in a table with enable/disable toggle switches.

Table columns:

ColumnContent
NameRule display name
Pattern PathURL path pattern
Pattern ModelOptional model filter
MatchColor-coded badges showing format/downstream filters (e.g. in:openai, out:anthropic, ds:OpenAI)
PipelinePlugin chain (shown as plugin1 → plugin2)
EnabledON/OFF status badge
ActionsEdit / Toggle / Delete buttons

Actions:

  • ➕ Create Rule — Define a new rule with name, path pattern, optional model filter, format filters (input format checkboxes, downstream format checkboxes, downstream multi-select)
  • âœī¸ Edit — Modify rule settings including format filters and a visual pipeline builder:
    • Format checkboxes for input and downstream format filters (OpenAI, Anthropic, OpenAI Responses)
    • Multi-select for matching downstreams
    • Select a plugin from a dropdown list
    • Configure plugin-specific options through dynamically generated fields (e.g., header key-value pairs for custom_header)
    • Each pipeline step is rendered as a card with the plugin description and config form
    • Add/remove steps with buttons
  • 🔄 Toggle Enable/Disable — Activate or deactivate a rule without deleting it
  • đŸ—‘ī¸ Delete — Remove the rule

🔌 Available Plugins​

The Available Plugins section is displayed below the rules table on the Rules tab. It shows all 13 available built-in plugins as a read-only reference:

ColumnContent
ID🔑 Plugin identifier (used in pipeline_config)
Description📝 What the plugin does
Config Schema📐 JSON schema for valid configuration options

The list includes format converters for all supported API formats (OpenAI Chat Completions, Anthropic Messages, OpenAI Responses API, and Google Gemini), header injection, and image extraction.

Use this section to look up plugin IDs and configuration options when building pipeline configs.

âš™ī¸ Settings​

The Settings tab configures global gateway behavior. Changes take effect immediately (no restart needed) and are persisted to the YAML config file automatically. ✨

Outbound Proxy:

  • Proxy Mode dropdown: auto, env, windows, none
  • Contextual help text explains each mode's behavior

Proxy Authentication:

  • Add/remove API keys that client applications must present (Authorization: Bearer <key>)
  • Visual key editor with add/remove buttons
  • Leave empty to allow all traffic

Admin Password:

  • Change the admin password (enter new password + confirm)
  • Clear password to disable authentication entirely
  • Changing the password logs out the current session

Dashboard:

  • Default Tab selector: downstreams, aliases, rules, settings, about
  • Controls which tab is shown on page load or refresh

Retry:

  • Checkbox: "Retry on empty response"
  • Toggles automatic retry when the downstream returns HTTP 200 but produces no content
  • Tooltip explains that non-200 responses (4xx, 5xx) are never retried
  • Retries up to 3 times with exponential backoff
  • Thinking/reasoning-only responses are treated as empty
  • Disabled by default

📋 Logs​

The Logs tab shows real-time gateway request logs via Server-Sent Events (SSE). Entries are sorted newest first, so the most recent request appears at the top.

Table columns:

ColumnContent
TimeRequest timestamp
MethodHTTP method (GET, POST, etc.)
PathRequest path
ModelResolved model name (or input model if no alias)
DownstreamTarget provider name
AliasAlias group used (or "—")
StatusHTTP status code (color-coded: green < 400, amber 4xx, red 5xx)
DurationRequest latency
ErrorError message (if any)

Actions:

  • 🔍 Filter — A text input at the top of the logs table filters visible rows in real-time. Matches against model, path, downstream, status, error, alias group, and method.
  • ⏸ Pause — Temporarily stops rendering new log rows (keeps the SSE connection alive). Click â–ļ Resume to continue rendering.
  • đŸ—‘ī¸ Clear — Removes all entries from the table and in-memory buffer.
  • 🔴 Live indicator — Shows connection status: "Live" (green), "Paused" (amber), "Offline" (red), "Disconnected" (grey).
  • 🔎 Inspect — Click on any log row to view the captured raw request and response bodies (only available when capture_payloads: true is enabled in the config). The inspector shows the original client payload and the original downstream response before any plugin transformation runs. A Truncated badge appears if either body exceeded the 1 MiB capture limit.

Each inspect panel has a Raw tab and a Parsed tab. The Raw tab is a literal JSON view of the captured bytes. The Parsed tab reconstructs the body into a human-readable tree: system prompt, tools, messages, usage stats, and so on.

Parsed-view display order

For every format Tresor recognises, the Parsed tab does not mirror the raw JSON key order. The canonical sections are emitted in the order the model actually consumes the prompt:

  • Anthropic Messages: tools → system → messages (docs)
  • OpenAI Chat Completions: tools → system → messages — OpenAI doesn't document an explicit order, so we follow the convention used by major chat templates (e.g. Llama 3, Qwen): the system-role message is hoisted out of messages[], tools are injected at the top of that block, and the remaining messages render in array order.
  • OpenAI Responses: tools → instructions → input[] (Codex agent loop blog)
  • Gemini: systemInstruction → tools → contents — Google doesn't publish an explicit prompt-cache hierarchy, but their official request examples (e.g. the function_calling.sh shell snippet) use this top-level key order, and the caching guide recommends placing "large and common contents at the beginning of your prompt" for implicit cache hits.

A small banner with a ? tooltip appears at the top of the Parsed view for these formats so the order discrepancy is visible. Unrecognised top-level fields (operational controls like generationConfig, safetySettings, temperature) still show up under the canonical sections as pretty-printed JSON.

The SSE connection is only active while the Logs tab is visible; switching to another tab automatically disconnects it to save resources.

Payload Capture

Payload inspection requires capture_payloads: true in your config file. When enabled, Tresor stores the most recent 100 request/response bodies in memory (capped at ~1 MiB per direction). This feature is useful for debugging plugin pipelines or inspecting raw payloads, but adds a small per-request memory cost.

â„šī¸ About​

The About tab displays:

  • Tresor logo and tagline
  • Current binary version and build time
  • Links to the GitHub repository and documentation
  • Brief project description

💾 Persistence​

All changes made in the web UI are:

  1. ⚡ Applied immediately to the running daemon (no restart needed)
  2. đŸ’ŋ Persisted to the SQLite database
  3. 📝 Written back to the YAML config file atomically