Commit Graph
39 Commits
Author SHA1 Message Date
yetone 261f0594de web: magpie web's usage tells of MAGPIE_WEB_KEY, which keeps one key across runs and browsers signed in for 400 days (#113) 2026-09-27 20:28:39 +08:00
yetone 90fd780eef grok: served straight through the Responses API the grok CLI talks to, not the CLI run behind the gateway — each request goes to cli-chat-proxy.grok.com with the CLI's sign-in and version, as the CLI's own do: the conversation as it is, the caller's tools, images and all, relayed to a Responses client and translated for the rest. The models are the backend's own list, with each one's context window and efforts, and Grok searches the web by itself. A further account signs with its own home. Tested live from a sandbox: Claude Code and OpenCode on grok-4.7 list, read and write files through several tool rounds; an image and a web search answered 2026-09-27 19:41:12 +08:00
yetone e173710982 backup: the library goes with a backup and a WebDAV sync — the instructions, MCP servers and skills with their files, a fifth part, ticked by default (magpie backup/restore --no-library). A backup without keys leaves the servers' secret env and headers empty and a restore fills them from the servers kept here; a skill's file over 2 MB, or past 32 MB in all, stays behind; a path that climbs out of its skill is refused. What it replaces is kept with the library's backups. Tested from a sandbox: exported without keys, changed and removed things, imported — the server back with the local key kept, the skill back as files, run.sh still executable 2026-09-27 17:24:53 +08:00
yetone 59e4f417b2 web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102 2026-09-27 16:21:26 +08:00
yetone 16c2588432 cli: magpie <agent> <model> says what the config reads after it — the model under the provider it is named by (OpenCode's magpie-relay/… rather than a magpie/… the config has no provider for) — and (unchanged) when it read that already, where it printed the id asked for under magpie/ as if written. Asked on Discord 2026-09-27 15:33:49 +08:00
yetone 0669c450e3 settings: Open at login starts magpie in the tray when you log in, so agents find the gateway from the start — a launch agent on the Mac, the user's Run value on Windows, an autostart entry on Linux, which is where whether it's on is read from too (magpie autostart [on|off] in the terminal) 2026-09-27 12:44:39 +08:00
smallnest 03a01a548d agent: MiMo Code — Xiaomi's fork of OpenCode, sharing its config shape (#98)
* agent: MiMo Code — a terminal coding assistant that is Xiaomi's fork of OpenCode, whose config keeps OpenCode's shape: its own mimocode.json(c) under ~/.config/mimocode, its auth beside it, and a magpie provider block with npm/@ai-sdk/openai-compatible, model and small_model fields. opencode() becomes openCodeLike() for the two to share it, and magpieProviderJSON splits shape from the catalog id (magpieProviderJSONFor), so a visibility narrowed on mimocode (magpie visible mimocode …) narrows its list and leaves OpenCode's alone. The library gives it the same instructions, MCP servers (its mcp key) and skills as OpenCode, except the shared skills go into its own skills/ folder: it reads Claude Code's skills only behind a flag, though it reads its CLAUDE.md like OpenCode, and the page says so. Its requests are told by the mimocode/ User-Agent. Checked against XiaomiMiMo/MiMo-Code

* icon: MiMo Code's own favicon, from packages/ui/src/assets/favicon — its frame with the bottom bar, in the monochrome the app masks to the text colour
2026-09-27 08:42:44 +08:00
yetone 47e12df418 models: a provider's model can go by a name of the user's, and offer only some of its reasoning levels — Claude Opus 5.5 · Claude Code can be Opus 5.5, and a model with six levels can offer just low, medium and high. Both are kept in settings.json by provider/model (modelNames, modelEfforts), apart from the vendor's list, so a Refresh, a restart or an upgrade leaves them, and the same model from another provider keeps its own; a provider renamed takes them along. They are applied where the catalog is made, so the gateway's /v1/models, the lists magpie writes into the agents (Codex's model catalog, ZCode, Pi, OpenCode, OMP …) and magpie's own pages all show them, and a change rewrites the agents' lists as any other change of the catalog does. Only what is shown changes: the id, where requests go, and the levels the vendor is asked at stay as they were; a found routing group keeps the model's own name. The provider's editor has Names & levels under its models — a name typed in place, a tick per level, Restore default — and the terminal has magpie model name <provider/model> <name>|--reset and magpie model efforts <provider/model> low,medium,high|--reset. Issue #92 2026-09-26 23:23:45 +08:00
yetone 7b69b22a76 quota: what is left of every subscription, plan and key balance, for scripts and agents — magpie quota [<provider>] [--json] prints each window's use and remaining percent and when it starts again, and each key's balance; the gateway answers the same at GET /v1/magpie/quotas (only to this machine, as it names the accounts), so an agent can pick where to send its work (#85) 2026-09-26 17:22:00 +08:00
yetone 73be42eca8 models: each agent can be shown only some of them — a provider or group gets a family (magpie provider set relay-x family=relay), and magpie visible zcode relay shows zcode only that family's models (or named providers and groups): in the files magpie writes for it and in what /v1/models answers it, told apart by its User-Agent; magpie models zcode lists what it is shown and what is kept from it, and magpie visible zcode all shows it everything again. A model kept from an agent is still served when asked for by name. Asked for on Discord 2026-09-26 16:02:29 +08:00
yetone 530734ff46 library: magpie library from the command line, and the app writes the library into the agents when it starts — there was no library command (status, sync, instructions get/set/agents, mcp add/agents/rm, skill agents/rm now), and Sync ran only from the page's button, so an agent installed or a file edited since kept what it had until the Library page was visited 2026-09-26 01:38:37 +08:00
yetone 04302b1e63 agent(codex): a Codex taken off magpie behind its back says so, with Apply again — something else rewriting config.toml (another switcher, an installer, a profile of its own) left the row showing a magpie model while Codex asked OpenAI for it, and the user blamed magpie; magpie now remembers what it set on each agent (applied.json) and tells three kinds of drift apart: the wiring gone (the provider table, catalog or base URL, or a profile overriding them), a magpie model replaced by one of Codex's own, and a Codex used since with none of its requests reaching the gateway (history.jsonl against when the gateway last saw it — an old process on an old config). A drifted row carries a coral Apply again pill on its name's line (a badge on the logo in the panel), the reason in its tooltip, Keep current settings in the row menu; the window asks /api/drift every 15s, so it shows without a reload 2026-09-26 01:05:19 +08:00
yetone 4c67d069d0 sync: magpie's setup kept the same on every computer through WebDAV (坚果云, Nextcloud, a NAS…) — Settings has Sync and backup: the providers with their keys, groups and icons, the settings, the profiles and each agent's models go to the server as one file sealed with a passphrase, so the server never sees them; the magpie serving the gateway looks every three minutes, sends what changed here and brings in what changed elsewhere, a removal too; a part changed on both sides goes to the newer one, and the copy it replaced is kept in the sync folder with a note saying what was replaced; the proxy and the window size stay each computer's own, and a computer set not to send keys never strips them from the server; Export and Import carry the same file by hand (#28) 2026-09-25 19:52:37 +08:00
yetone a1e546d4a1 provider: saved accounts are kept signed in — a Claude or ChatGPT account saved in magpie but not the one the agent is on was refreshed only when used or its usage looked at, and smart routing leaves the ones waiting their turn idle for days; the magpie serving the gateway now renews each such sign-in about once a day (hourly check, so a machine that slept catches up), never the agent's own; a refresh the vendor refuses (400/401) marks the account signed out — the account list says to add it again, magpie accounts too — and one that succeeds clears it; magpie accounts refresh renews them all now, for cron or launchd; a switch waits for a refresh in flight, so the agent is never handed a refresh token being spent (#53) 2026-09-25 19:22:37 +08:00
yetone 637b2458ee provider + gateway: Google sign-ins — Gemini CLI's and Antigravity's — are subscriptions of magpie's, so any agent can use their models (#4); Gemini CLI's own login in ~/.gemini is read as it is, or an account is signed in from magpie with Google's OAuth, its token refreshed in memory, and each request goes to Code Assist wrapped as the app wraps it, with the project Code Assist set the account up with; Google now serves Gemini CLI's sign-in only to Code Assist Standard and Enterprise, which need a Cloud project, named with magpie accounts project or GOOGLE_CLOUD_PROJECT in ~/.gemini/.env and said so where the account is shown; Google may suspend an Antigravity account used outside Antigravity, so magpie says that and asks before adding one 2026-09-25 15:53:33 +08:00
yetone cedc86db68 agents: the Agents list, in the window and the tray panel, is in the order you put it in and shows only the agents you want — an agent's logo is its handle: drag it to move the row, click it (or right-click the row) for Move up, Move down and Hide, or Alt+↑/↓ from the keyboard; a hidden agent folds away at the bottom under "N hidden" (in the fold with the unused ones, "Show N more"), and Show brings it back, kept in view even while nothing is set on it. The order and who is hidden live in magpie's settings.json (agentOrder, agentsHidden, agentsShown), never in an agent's files; an agent installed later follows the ordered ones in magpie's own order. magpie ls and the TUI keep the order too and list a hidden agent last, dimmed and marked, rather than dropping it, so nothing goes missing from a listing; magpie agents lists them all as before 2026-09-25 15:02:31 +08:00
yetone dd7d4875d7 profiles: a saved profile keeps the Library's setup too, and switching to it switches that as well (#29) — which agents get each MCP server and skill, and the instructions (the shared text, the agents it is written to, what each gets besides), so moving from one profile to another left the tools and the instructions as they were and only the models followed. A profile keeps them under "library" beside its agent.field keys; the servers and skills themselves stay in the library, a profile only names them. Applying one sets the models as before, then gives each server and skill to the agents it names and puts the instructions back, written into the agents as any Library change is, their files and the library's own instructions kept aside first; one removed from the library since is skipped and said so, one added since keeps its agents (the profile knows nothing of it, and switching it off would lose it for good). A profile saved before, or while the library was empty, carries none and leaves the library as it is. magpie profiles, the TUI and the panel's chips say what a profile gives out (+ library: 2 servers, 1 skill, instructions) 2026-09-25 14:23:56 +08:00
yetone b3705cbb5a cli: routing groups are made, changed and removed from the terminal too (#55), where only the Routing view could — magpie groups lists them, yours then those magpie found (a removed one named with how to bring it back, a member no provider serves now marked so, the agents set to each); magpie group add <name> models=<m1>,<m2> routing=smart|order|rotate|usage stays=auto|session|turn|off makes one, its id taken from the name and numbered past one taken as the Routing view does; magpie group set <id> k=v… changes name, routing, stays and the models — models= the whole list in order, models+= and models-= one at a time — and changing one magpie found makes it yours; magpie group rm hides one magpie found, for magpie group restore to bring back; magpie group <id> shows one. Each saves through the same code the Routing view's does, so the file holds the same group and agents' model lists follow the change. A model is its provider/model id as magpie models lists it, or a bare model id one provider serves; one no provider serves, or several do, says which it could mean, and a routing or stays value magpie has none of says the ones it has, where the saved group would have quietly gone back to the default 2026-09-25 14:06:15 +08:00
yetone 09c635cf03 agents: a model through magpie tells Pi, Crush, omp and Codex how much it holds, and a provider added, edited or removed reaches the model lists agents keep in files of their own — the catalog carried no context window, so Pi took every model through magpie for a 128K one (a CLIProxyAPI's gpt-5.5 holds 922K) and Crush for a 200K one; each model now carries models.dev's input limit, else its context, looked up by bare id as most of the providers serving it give it (a proxy's "openai/gpt-5.4", "gpt-5.4(high)", "glm-4.6:free" find it too; a group holds the least of its members'). And those lists were written only when a model was picked: Codex's magpie-models.json, Pi's models.json, OpenCode's, Crush's, Command Code's, omp's and Hermes' provider blocks and dsh's llm-deepseek entry kept the catalog as it was then, so a provider added later never showed. Saving a provider, a vendor's list fetched anew or models.dev synced now rewrites each one magpie wrote, where it differs, and the app does once at start-up; a Codex signed in to ChatGPT, which asks the gateway, kept its cached list under the backend's ETag, which a change of magpie's never changed — the ETag (and a reply's X-Models-Etag) now carries a tag of magpie's models, and a cache from before a change is aged so the next Codex asks again 2026-09-25 12:32:14 +08:00
yetone 6648a8a2ec cli: a model typed as another agent spells it is put the way this one does — magpie/copilot/gpt-6 for Codex, which names catalog models copilot/gpt-6, and copilot/gpt-6 for Pi, which names them magpie/copilot/gpt-6 — rather than written as it is, where Codex took it for one of OpenAI's own and asked OpenAI for it; a magpie/… model the catalog doesn't have is refused, and a model the agent's picker doesn't list is still taken as it is 2026-09-25 05:34:44 +08:00
yetone 9467970b0e cli: magpie accounts lists each subscription with its allowance — every window's share used, what is left and when it resets, like the window's cards; magpie accounts [agent] --json gives the same for scripts (#39) 2026-09-25 00:13:51 +08:00
yetone efbe5660b0 backup: everything set up in magpie carried to another machine in one file — magpie backup writes the providers with their keys (or none, with --no-keys), the pictures picked for them, the settings, the profiles and every agent's model, sealed with a passphrase (AES-256-GCM, PBKDF2-SHA256) so nothing in it reads without it; magpie restore puts it in, replacing providers by id, keeping the keys already there for one that came without, and setting models only for the agents installed there; subscriptions stay with the machine they were signed in on (#28) 2026-09-24 20:34:15 +08:00
yetone 20948e596f gateway: a Grok subscription (SuperGrok, X Premium+) works like a Cursor one — magpie runs the signed-in Grok Build CLI in a home of its own (none of the user's hooks, skills, rules or MCP servers; only search_tool/use_tool, reaching magpie's MCP tools), borrowing the user's token through magpie grok-token without touching their sign-in; the add sheet has a Grok tile that signs in with grok login's device code 2026-09-24 17:35:36 +08:00
yetone b19f3dbabe provider: add a Claude or ChatGPT subscription from magpie itself — it opens the vendor's sign-in, takes the account when it comes back and lists it with the others, one click from being in use; magpie accounts add <agent> on the command line (#15) 2026-09-24 14:26:37 +08:00
yetone 435d65882b gateway: fallback — when a provider is out of quota, rate limited or down, a request goes to the next model you listed for it, before any of the reply is sent; set it in the provider editor or with magpie provider fallback 2026-09-24 14:04:42 +08:00
yetone 5da0d0d973 provider: several Claude Code and Codex subscriptions — magpie remembers each account it sees signed in, and switches the agent between them in the editor or with magpie accounts (#15) 2026-09-24 13:55:25 +08:00
yetone 1f72ac82f0 net: requests go through a proxy — Settings → Proxy, or the environment's, or the system's (#8) 2026-09-24 12:48:01 +08:00
yetone 14663c3a65 agent: Claude Code's opus, sonnet, haiku and fable tiers can each take their own model (#3)
Through magpie, each tier follows the main model until it is given one of
its own (ANTHROPIC_DEFAULT_*_MODEL; haiku also sets ANTHROPIC_SMALL_FAST_MODEL).
The GUI shows them under one tiers menu; the CLI takes magpie claude haiku <model>.
2026-09-24 12:38:41 +08:00
yetone 4bd3f3a4b5 import: magpie://import links add a provider after the user confirms
A vendor or relay can hand out a ready-made provider as a link. The app
registers the magpie scheme (Info.plist on macOS, HKCU on Windows, a
.desktop handler on Linux), a second launch hands the link to the running
one, and the window shows what the link would add, with the hosts the
prompts and key would go to, before anything is saved. `magpie import`
does the same in a terminal.
2026-09-24 12:17:45 +08:00
yetone 75cb192647 Desktop app for Windows and Linux
The Windows app cross-compiles (WebView2, no cgo) as a GUI program with an
icon, version info and a DPI-aware manifest; run from a terminal with a
command it borrows the console. The Linux app links GTK 3 and WebKitGTK
4.1. Off the Mac the app updates its own binary from its own build:
downloaded in the background, swapped in on restart or quit, and the
relaunched process waits for the old one before taking the gateway. The
window leaves room for traffic lights only on a Mac.
2026-09-24 03:22:02 +08:00
yetone 8a746c025b "every agent's model" in the app too, not only coding agents 2026-09-24 02:31:21 +08:00
yetone 73ef0e5276 usemagpie.ai, and a magpie that updates itself
site/ is the website: a static page plus a worker that turns the newest
release of yetone/magpie-releases into an update feed (/api/latest, with
every file's SHA-256), stable download links and an install script.

The app asks the feed at start-up and every six hours, downloads a newer
version in the background, and installs it on Restart to Update or on
quit. A download must match its checksum and be signed by the same team
as the app it replaces. `magpie update` does the same from a terminal and
replaces a bare binary in place.
2026-09-24 01:57:50 +08:00
yetone 702477525a Claude subscription as a provider; model lists fetched, never compiled in
A signed-in Claude Code is now offered as a provider (claude/…) like Codex
and Copilot. Anthropic classifies another agent's system prompt as
third-party traffic even over Claude Code's OAuth, so magpie drives the
real local claude binary for every generation: the caller's tools are
bridged in over MCP (magpie claude-mcp-helper), and tool results resume
the same Claude Code turn. Token counting is estimated locally so the
OAuth token takes no side path.

No model list is compiled in any more. The built-in catalog, preset
defaults and Claude Code's alias list are gone; the picker shows the
models.dev catalog (refreshed in the background when stale) layered with
each vendor's own /models answer, and signed-in accounts fetch theirs at
start-up. Whether a model rejects temperature/top_p now comes from
models.dev rather than a name prefix.

The gateway retries a Chat request on the Responses endpoint when the
model is Responses-only, and remembers that. Recent calls keep the first
256 KB of request and response bodies, viewable in the call list. The
Usage tab shows subscription allowances (Claude, Codex, Copilot) as the
vendors report them.
2026-09-24 00:20:59 +08:00
yetone 1f44812457 agent: rewrite the wiring an older dial left behind
On start-up magpie now renames what dial wrote into the agents' files: a
model spelled dial/… becomes magpie/… (which also writes the magpie
provider entry), and the dial provider entry, Codex's [model_providers.dial]
table and dial-models.json, and Claude Code's bearer token go. Once nothing
says dial it changes nothing.
2026-09-24 00:17:32 +08:00
yetone 402a96c39d Rename dial to magpie, with a magpie for a logo
The product, module path (github.com/yetone/magpie), binaries, env vars
(MAGPIE_ADDR, MAGPIE_DEV_UI, MAGPIE_THEME, MAGPIE_DEBUG), config and cache
folders (~/.config/magpie, ~/.cache/magpie), bundle id (com.yetone.magpie),
gateway provider id and token, and every UI string now say magpie.

On first run magpie copies ~/.config/dial and ~/.cache/dial to the new
folders when they don't exist yet (copy, not move, so a still-running dial
keeps working; the old folders can be deleted by hand later).

The logo is a small round magpie in profile: one path for the header and
the tray, and the app tile adds the white belly and the blue-green tail.
The header mark is drawn in ink rather than the accent colour, which
fought the text in light mode.
2026-09-23 23:55:11 +08:00
yetone 0b1626be6d agents: a Default entry that puts an agent back the way it shipped
Setting a field to nothing now means the agent's own default: dial's
wiring (gateway provider, model catalog, env) comes out and the key is
removed, so Codex is back on OpenAI's catalog and Claude Code on
Anthropic's. The picker lists it first; the CLI takes `dial <agent>
default`. Also the vendor icon inside a field pill was 22px, not 14px:
the row icon rule outranked it.
2026-09-23 14:37:42 +08:00
yetone 30c489a000 usage: a token statistics page
The gateway now records every call's token counts (read from the provider's
own usage block, in both the translated and the pass-through paths) with the
calling agent taken from the client's User-Agent, into
~/.config/dial/usage.jsonl. A Usage tab sums them by period, agent and
model, with a per-hour/day/week timeline and cost at models.dev list
prices; dial usage does the same in the terminal.

Also nudges the window header 1pt up so the brand sits level with the
traffic lights, and lets ?view= open the window on a tab.
2026-09-23 03:16:33 +08:00
yetone 8fb93f8fc2 Make dial a local LLM gateway with preset providers and one catalog
dial now serves OpenAI chat completions, OpenAI Responses and the
Anthropic Messages API on 127.0.0.1:3425 and forwards each request to the
vendor that serves the model, translating between the APIs when the vendor
speaks a different one (streaming, tool calls and reasoning included).
Every agent points at that one URL; models are spelled provider/model.

Providers are added from presets (vendors, relays, local servers) with
just an API key, or as custom OpenAI/Anthropic-compatible endpoints.
Keys live in ~/.config/dial/providers.json; nothing is read from the
shell environment. Each provider chooses which of its models to expose.

Agents get gateway wiring instead of vendor-specific tables: Claude Code
via the env block, Codex via a dial model provider plus a model catalog
file, OpenCode/Pi/Crush via a dial provider entry; native settings are
stashed and restored when a native model is picked again.

The Providers page shows the gateway, each provider with the agents on it,
an inline editor with model chips, and an add sheet of preset tiles.
CLI: dial presets | providers | provider add|key|models|test|rm | models | serve.
2026-09-22 22:43:51 +08:00
yetoneandClaude 0a234ce41d dial: one dial for every coding agent's model
Wails v3 tray panel and window, TUI and CLI. Switches model, effort and
provider for Claude Code, Codex, Gemini CLI, OpenCode, Pi, Goose, Cursor,
Copilot CLI and Crush with format-preserving config edits. Providers page
and registry, stored keys, live vendor model lists, profiles.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-22 21:47:29 +08:00