yetone 740fc5738f gui: a calmer providers page
The gateway is a row like the providers below it, with its URL as a
copyable pill and the recent calls folded underneath. A provider row shows
only the agents pointed at it, as real logos, plus a + for the rest; the
grey smear of every agent is gone. The editor gains an Agents line (click
one to pick it a model here), lists the endpoints with a Test that reports
against each, and drops agents that speak only their own vendor's API
(Gemini CLI, Cursor). The add sheet's tiles are one line each, with a
filter, so every preset fits on one screen.

Also gives the usage tiles their own class; they had borrowed .tile from
the add sheet and made every preset name uppercase.
2026-09-23 03:27:43 +08:00
2026-09-23 01:11:20 +08:00
2026-09-23 03:27:43 +08:00
2026-09-23 03:16:33 +08:00
2026-09-23 03:16:33 +08:00

dial

One small dial for every coding agent's model.

dial is a single screen that lists each AI coding agent on your machine and the model it is set to. Click a value, pick a model. That is the whole app.

It lives in the menu bar: click the icon and a panel drops down; the same screen also opens as a normal window (dial, or Open dial in the tray menu), and there is a terminal version (dial tui) and a plain CLI.

  ◉ dial

  ▸ Claude Code   claude-fable-5-1[1m]                        ~/.claude/settings.json
    Codex         gpt-6-astra   effort medium
    Gemini CLI    gemini-3.1-pro
    OpenCode      anthropic/claude-sonnet-5   small anthropic/claude-haiku-4-5
    Pi            openrouter/z-ai/glm-5.2:batch
    Goose         anthropic/claude-sonnet-5
    Cursor        auto
    Copilot CLI   claude-fable-5

  ↑↓ agent  ·  ←→ field  ·  ↵ change  ·  s save profile  ·  p profiles  ·  q quit
  • One small binary. About 11 MB with the desktop app (it uses the system webview through Wails, nothing bundled), 7 MB for the terminal-only build. macOS, Linux and Windows.
  • Edits config files surgically. Only the one key you change is touched; comments, ordering and indentation in your settings.json, config.toml, opencode.jsonc or config.yaml survive intact. Writes are atomic.
  • One endpoint for every agent. dial runs a local gateway that speaks OpenAI chat completions, OpenAI Responses and the Anthropic Messages API, and forwards to whichever vendor serves the model. Codex, Claude Code, OpenCode and the rest all point at http://127.0.0.1:3425/v1 and pick from one catalog; the translation between APIs happens in dial, streaming and tool calls included.
  • Providers with one field. Pick a preset (Anthropic, OpenAI, Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, Mistral, Groq, xAI, OpenRouter, Together, Fireworks, SiliconFlow, AiHubMix, 302.AI, Ollama, LM Studio…), paste a key, done. Custom vendors need a name and a base URL. dial never reads keys from your shell environment.
  • Real model lists. With a key in hand dial asks the vendor which models it serves and offers exactly those; the models.dev catalog fills in names, reasoning efforts and the list for vendors that have none. Choose which models each provider exposes, or expose them all.
  • Profiles. Snapshot every agent's settings under a name and switch all of them back in one move.
  • Real logos, no framework. Plain HTML over the system webview; brand icons from lobehub/icons.

Agents

Agent File Fields
Claude Code ~/.claude/settings.json provider, model
Codex ~/.codex/config.toml provider, model, effort
Gemini CLI ~/.gemini/settings.json, ~/.gemini/.env auth, model
OpenCode ~/.config/opencode/opencode.json(c) model, small
Pi ~/.pi/agent/settings.json model
Goose ~/.config/goose/config.yaml model
Cursor CLI ~/.cursor/cli-config.json model
Copilot CLI ~/.copilot/settings.json model
Crush ~/.config/crush/crush.json large, small

Provider-scoped agents (OpenCode, Pi, Goose, Crush) take provider/model. Only agents that are installed or configured are shown.

Providers and the gateway

Every model an agent can pick is spelled provider/model and served by dial's gateway, so agents never hold vendor keys or vendor URLs. Add a provider, and its models appear in every agent's picker:

dial presets                          # the vendors dial knows, grouped: vendors, relays, local
dial provider add deepseek sk-…       # a preset needs only the key
dial provider add ollama              # local servers need none
dial provider add "My Relay" url=https://relay.example.com/v1 key=sk-… models=gpt-5.5,claude-sonnet-5
dial providers                        # host, key, exposed models, who uses what
dial provider deepseek                # one provider in detail
dial provider models deepseek         # re-fetch the vendor's list (add ids to choose which to expose)
dial provider test deepseek           # one tiny request per API, with latency
dial provider key deepseek sk-…       # replace the key
dial provider rm deepseek
dial models                           # the catalog agents see
dial claude deepseek/deepseek-chat    # use it

Custom providers take url= (an OpenAI-compatible base), anthropic= (an Anthropic-compatible base), or both, plus responses= when the vendor has a separate Responses endpoint, catalog= to borrow a models.dev list, and models= to name the models to expose. Anything a preset does not know can be overridden the same way.

The gateway listens on 127.0.0.1:3425 (DIAL_ADDR changes it) and starts with the app; dial serve runs it alone. It exposes:

Path API
/v1/chat/completions OpenAI chat completions
/v1/responses OpenAI Responses
/v1/messages Anthropic Messages
/v1/messages/count_tokens Anthropic token counting
/v1/models the catalog

Requests pass straight through when the vendor speaks the agent's API and are translated otherwise, streaming, tool calls and reasoning included. The bearer token is dial; the gateway only listens on loopback. DIAL_DEBUG=1 logs every call, and the Activity toggle in the app shows the recent ones.

Claude Code gets ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN and the model variables in the env block of settings.json; picking a native model (opus, sonnet…) removes them and restores whatever was there.

Codex gets a [model_providers.dial] table, model_catalog_json pointing at ~/.codex/dial-models.json (written from the catalog, so the models show in Codex's own list) and a valid model/effort; picking a native model removes all of that. Your ChatGPT sign-in is never touched. Codex reads its model list at start-up, so restart it after a switch.

OpenCode, Pi, Crush get a dial provider entry and dial/provider/model.

Gemini CLI switches auth between API key, Google account and Vertex; the API key goes to ~/.gemini/.env.

Install

go install github.com/yetone/dial@latest

or build locally:

make build            # ./dial with the desktop app (needs cgo + the platform webview)
make app              # macOS: dial.app, a menu bar app with no Dock icon
make cli              # terminal-only build, no cgo, cross-compiles anywhere
make release          # dist/: native app build + cli builds for every platform

Linux needs libgtk-3-dev and libwebkit2gtk-4.1-dev for the app build; Windows uses the WebView2 runtime that ships with the OS.

Developing

make dev

builds with -tags dev and opens the app with the UI served straight from internal/gui/assets: save app.css, app.js or index.html and the window reloads itself. With fswatch installed (brew install fswatch), a change to a Go file rebuilds and relaunches the app too. The dev build uses its own gateway port (DEV_ADDR, default 127.0.0.1:3426), so a dial you already run keeps serving your agents. Point it at a scratch home to keep your real agent configs out of it:

HOME=/tmp/dial-home XDG_CONFIG_HOME=/tmp/dial-home/.config make dev

DIAL_THEME=light|dark forces the palette and DIAL_DEBUG=1 prints what the gateway translates.

Use

dial                          # open the app: a window plus the menu bar icon
dial tray                     # menu bar icon only (use this in your login items)
dial tui                      # the same dial, in the terminal
dial ls                       # list every agent and its current settings
dial claude opus              # set a model (agent names accept prefixes: cc, oc, gem …)
dial codex gpt-5.6-sol
dial codex effort high        # other fields
dial codex xhigh              # bare effort levels are recognised too
dial codex deepseek/deepseek-chat   # any catalog model, through the gateway
dial claude moonshot/kimi-k2.5
dial gemini auth api-key
dial opencode anthropic/claude-sonnet-5
dial oc small anthropic/claude-haiku-4-5

dial save work                # snapshot everything as a profile
dial use work                 # switch back
dial profiles
dial rm work

dial sync                     # refresh the models.dev catalog and every live model list

In the app, click any value to open a filtered list; type to search or to enter something that is not listed; esc closes the panel. Profiles are the chips at the bottom: click to apply, × to delete, + save current to add. The Providers tab of the window lists your providers with the agents on each; click a row to change the key or the exposed models, Test it, or click an agent icon to point that agent at one of its models. Add provider shows the presets as tiles: pick one, paste the key.

Keys in the terminal dial:

Key Action
↑ ↓ choose agent
← → choose field (model, effort, small …)
↵ open the picker
type filter; enter accepts custom values
s save current setup as a profile
p apply or delete (ctrl+d) a profile
S sync the model catalog
q quit

Agents read their config at startup, so a running session keeps its model until you start a new one.

Files

  • ~/.config/dial/profiles.json — saved profiles
  • ~/.config/dial/providers.json — your providers, keys included (0600)
  • ~/.config/dial/stash.json — values dial replaced, restored on switch-back
  • ~/.cache/dial/models.json — models.dev catalog (OpenCode's cache at ~/.cache/opencode/models.json is used when present)
  • ~/.cache/dial/models/<provider>.json — model lists fetched from vendors

XDG_CONFIG_HOME and XDG_CACHE_HOME are respected.

S
Description
Every agent's model. One place. Codex on DeepSeek, Claude Code on Kimi, from the menu bar.
https://usemagpie.ai
Readme MIT
103 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 63.1%
JavaScript 31.8%
HTML 3.2%
CSS 1.7%