Commit Graph
40 Commits
Author SHA1 Message Date
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
Arvak 84ef25805e web: MAGPIE_WEB_KEY keeps the page's key across runs — for magpie web kept running as a service, where a new key each start signs every browser out; with it the cookie outlives the browser session too (400 days, Chrome's most). Unset, each run makes its own key in a session cookie, as before. A key under 16 characters is refused. (#109) 2026-09-27 17:26:32 +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 ce8d0e065c devin: served straight through Devin's API, not the CLI over ACP — each request goes to the GetChatMessage RPC the devin CLI itself uses, with its sign-in: the conversation as it is, the caller's tools, images and all, and the reply streamed back text, thinking and tool calls as they come. A family's name is sent as its variant at the effort asked for; Adaptive and Fusion, which the API doesn't serve, are no longer listed. The instructions go at the head of the first message, as Kiro's do, since Devin turns away Claude Code's own in its system field. Tested live from a sandbox: Claude Code and OpenCode on Opus 5.5, SWE-2 and GPT-6 Sol list, read and write files through several tool rounds; images and a tool round trip answered on Claude, SWE, GPT and Gemini models 2026-09-27 15:30:24 +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 e0cc477990 providers: an Anthropic base URL given as .../v1 or .../v1/messages, as StepFun's docs show it, is taken as its root — magpie asks the root's /v1/messages, so the version went twice and every message was a 404 with nothing to say why, while the model list, asked at both, still answered; StepFun and StepFun (China) are presets, Step Plan or pay as you go 2026-09-27 08:39:08 +08:00
yetone 55afcdd4bb agents: Qoder CN — qoderclicn, the China site's build of Qoder's CLI, is the same CLI with its own accounts and its settings in $QODERCN_CONFIG_DIR, ~/.qoder-cn by default; magpie wires it as it does Qoder, a magpie custom provider with every magpie model and model.name/model.reasoningEffort, as its own agent 2026-09-27 08:05:12 +08:00
yetone cae88f031c agents: Qoder — magpie's models in Qoder's CLI (1.1) as a "magpie" custom provider in ~/.qoder/settings.json ($QODER_CONFIG_DIR): picking magpie/<model> or a routing group writes the provider, with every magpie model, its context, output, images and the efforts it takes, and makes it model.name; the effort is model.reasoningEffort. The comments and entries of the user's settings stay, and stepping out of magpie takes its provider away and puts back the model the user had. Qoder offers custom providers only to a signed-in account whose plan has BYOK. It asks every model for enable_thinking, which OpenAI's API refuses, so that is dropped for openai.com. Tested live: magpie → settings.json → qodercli -p → magpie's gateway → upstream, the reply streamed back 2026-09-27 06:28:14 +08:00
yetone 0f7e90b4f2 agents: Cline — its CLI's model and effort can be one of magpie's. A provider of Cline's own is refused when a session starts (cline/cline#14180), so magpie takes Cline's built-in openai-compatible provider and makes it the one in use: the gateway, magpie's token, the model, a User-Agent that names Cline (its requests say only AI SDK), and the effort under reasoning.effort. What the user had there, and the provider in use, are stashed and put back when magpie steps out. Tested live with Cline 3.0.65 against a sandbox gateway: the turn comes back and the usage is Cline's 2026-09-27 06:08:58 +08:00
yetone 7a3c434610 agents: Alma — magpie wires it through Alma's local API (localhost:23001, while Alma runs): choosing one of magpie's models for Alma adds a provider named magpie there (OpenAI type, the gateway's /v1, key magpie), offers magpie's models in it and makes the model Alma's default chat model, the rest of Alma's settings and its other providers left as they are; the list is kept current as magpie's catalog changes, and going back to Alma's own takes magpie's provider out. Asked on Discord 2026-09-26 19:18:51 +08:00
Erick Guan f399af82d1 gateway: /v1/models says whether a model reasons and at which levels (#80)
The OpenAI-compatible model serializer omitted catalog efforts, so endpoint consumers saw reasoning models as incapable. Include reasoning support and effective effort levels for both individual models and routing groups.
2026-09-26 11:54:05 +08:00
yetone c0cbf90eeb agent(zcode): ZCode is an agent — its provider field puts every magpie model in ZCode's own model picker, as a provider named magpie in ~/.zcode/v2/config.json (kind anthropic, asked at the gateway's /v1/messages), kept in step with the catalog like OpenCode's list, and taken out again when cleared; its requests are known by the ZCode/ User-Agent (#72) 2026-09-25 23:53:59 +08:00
yetone 032bcfc8b0 provider: the Grok subscription is called Grok (SuperGrok) — the plan xAI sells, so it reads as the account it signs into; Grok Build stays the name of the agent, the grok CLI the subscription runs through 2026-09-25 18:33:21 +08:00
yetone f7112a9e9d agents: Grok Build — xAI's grok CLI — is an agent: its model is set in ~/.grok/config.toml ($GROK_HOME), and a model through magpie adds the catalog there as [model."magpie/…"] tables pointed at the gateway with magpie's own key, so a request never carries the user's xAI sign-in and the catalog joins Grok's own models in /model; its effort is [models] default_reasoning_effort, its requests are known by grok-shell; the Grok subscription is called Grok Build too 2026-09-25 18:26:50 +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 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 b72985a9cc agent: add Hermes Agent (#49) — magpie adds itself to ~/.hermes/config.yaml ($HERMES_HOME) as the provider "magpie" under providers (the gateway as chat completions, the catalog as its models) and points model.provider at it, with the model in model.default; the provider and model the user had are stashed and put back when they pick one of Hermes's own or go back to the default. Hermes sends its own User-Agent only from a recent release on, so the entry sets it for the gateway's usage view 2026-09-25 09:08:08 +08:00
jimyag 6b8e125df3 fix(provider): preserve Codex import headers (#46)
* fix(provider): preserve Codex import headers

Copy fixed Codex provider headers into imported providers, including entries that match a preset. Compare headers when detecting duplicates or merging keys so reimports and distinct relay accounts retain their request configuration.

Signed-off-by: jimyag <git@jimyag.com>

* fix(provider): keep Codex preset identity on import

Import fixed headers only for custom providers, matching the existing Alma importer and preset request-shape rule. Cover a preset-host Codex entry so its preset and header behavior remain explicit.

Signed-off-by: jimyag <git@jimyag.com>

* fix(provider): normalize headers before import comparison

Compare headers as they are stored so importing a Codex provider again does not report a duplicate when source values contain surrounding whitespace.

Signed-off-by: jimyag <git@jimyag.com>

* fix(gateway): retain Devin reply channel while awaiting

The response reader can delete a pending call before its caller looks up the channel, causing intermittent no such call errors. Return the reply channel from send so await can receive even after the reader removes the pending entry.

Signed-off-by: jimyag <git@jimyag.com>

* Revert "fix(gateway): retain Devin reply channel while awaiting"

This reverts commit 6278c793b9b4f45dc09106168269915007abffe5.

Signed-off-by: jimyag <git@jimyag.com>

---------

Signed-off-by: jimyag <git@jimyag.com>
2026-09-25 08:32:29 +08:00
jimyagandjimyag 00b173682f provider: Codex is one of the apps magpie imports providers from (#45)
Each [model_providers.<id>] table in ~/.codex/config.toml (or $CODEX_HOME) becomes a provider — its base_url, wire_api and bearer token, with the models the top level and the profiles pick for it and their model catalogs; magpie's own table and catalog are left out, as are sub-tables such as http_headers. Claude Code's settings are read from $CLAUDE_CONFIG_DIR when it is set.

Co-authored-by: jimyag <jimyag@users.noreply.github.com>
2026-09-25 07:31:30 +08:00
hanhotfox cd0eccfa58 agent: add Devin (#43)
* agent: add Devin — model via agent.model in config.json, subscription via devin acp over ACP

* gateway: surface devin acp read errors to waiters

* providers: fix devin sign-in exchange; account editor and picker fixes

* gateway: scope the devin deny rules and copy credentials when a link can't be made

* gateway: note devin never rewrites credentials.toml during a session
2026-09-25 07:16:21 +08:00
yetone d8ee8d1af3 community: magpie has a Discord — the site links it from the header, the footer and a card above the download, Settings has a Community row that opens it, and the README a badge and a Community section 2026-09-25 01:22:16 +08:00
yetone 41931e2895 agent: omp (oh-my-pi) — its model picked in magpie like any agent's; a model through magpie adds magpie as a keyless provider in ~/.omp/agent/models.yml with the catalog as its models, and sets config.yml's modelRoles.default to magpie/<provider>/<model>; its other roles and the rest of both files stay as they are, comments too, and default takes magpie's entry out unless another role still uses it (#34) 2026-09-24 22:36:15 +08:00
yetone be1b3967f4 agent: Command Code — its model picked in magpie like any agent's; a model through magpie adds magpie as a keyless provider in ~/.commandcode/providers.json with the catalog as its models, and sets settings.json's model to magpie/<provider>/<model>; its own models stay as they are, and default takes magpie's entry out; Command Code still wants its own sign-in (#32) 2026-09-24 21:44:09 +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 96e44c67d5 agents: DeepSeek Harness (dsh) — its model picked in magpie like any other agent's: dsh's own V4 Pro and Flash, or any model magpie serves, which puts the gateway in ~/.dsh/config.yaml with the whole catalog in dsh's /model; the TUI, dsh -p and dsh web all start on it, the user's own entries stay, one magpie replaced comes back when it's set back to default, and a DeepSeek endpoint set in dsh's settings, which dsh puts over it, is pointed out (#27) 2026-09-24 20:22:22 +08:00
yetone 545506e875 provider: an import link can name the vendor's own icon
magpie://import now takes icon=<https picture>: the vendor's logo, PNG,
JPEG, GIF, WebP, ICO or SVG. It is fetched once, when the user opens the
confirm dialog — never at parse time — into magpie's icons folder, and
falls back to the catalog's logo or a plain mark when the fetch fails.
An explicit icon= wins over whatever catalog or preset gave.

The fetch is guarded on the way out: https only, at most 1 MB, the type
checked, and the host is resolved at connect time with loopback, private,
link-local and reserved addresses refused, so a name that points back at
the user's own machine (or a DNS-rebinding trick) never connects. The
page and the dialog never load a remote picture themselves.

IconURL is a carrier between parsing and that fetch only; Save drops it,
so it never reaches providers.json.
2026-09-24 17:13:03 +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 cd4f97e326 "Every agent's model": magpie is not only for coding agents 2026-09-24 02:30:23 +08:00
yetone 6c99ab01ef Open source under MIT; the site shows third-party models in every agent
The site leads with what magpie is for: Codex on DeepSeek, Claude Code on
Kimi. New screenshots (Codex's picker, the panel, Providers), a diagram of
the gateway, shared subscriptions, a light/dark/system theme switch, a new
OG image, and links to the source.
2026-09-24 02:16:29 +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 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 7cdbce8a3c gui: Gateway tab with connect docs; accounts in the providers page
The gateway gets its own tab: status and URL, a connect card with the base
URL, key and a model id as copy buttons, and a highlighted snippet in
shell, curl, Python or Node for each of the four APIs; then every model id
and the recent calls. Providers rows show signed-in accounts (ChatGPT Pro,
GitHub) with an editor for their model picks, and a note explains why a
signed-in Claude Code is not listed.
2026-09-23 15:25:06 +08:00
yetone 0f96a5fb74 gateway: serve the Gemini API; Gemini CLI can use every catalog model
Gemini CLI only speaks Google's API, so its picker stopped at Google's
models. The gateway now serves /v1beta/models/{model}:generateContent,
:streamGenerateContent (alt=sse), :countTokens and GET /v1beta/models,
translating to whatever the provider speaks: contents/parts, function
calls and responses (ids kept, names matched otherwise), inline images,
thinking config, tool config, structured-output asks, Gemini's uppercase
schema types, and usageMetadata on the way back.

Picking a catalog model for Gemini CLI points GOOGLE_GEMINI_BASE_URL at
the gateway with the gateway token as GEMINI_API_KEY, switches auth to
API key and names the model; a native model or Default puts the earlier
auth, key and model back. The auth pill reads "dial" while routed.

`dial gemini auth …` now resolves a field by its label too.
2026-09-23 14:51:43 +08:00
yetone 3a5f00ac71 Add make dev with live reload; align the window header with the traffic lights; make the profiles hint readable 2026-09-23 00:31:26 +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