Commit Graph
62 Commits
Author SHA1 Message Date
elonnzhang 3ffebeebb6 provider: custom request headers for custom providers
Extra HTTP headers, typed by the user, ride on every request magpie makes
to a plain key+URL provider — forwarded calls, connectivity tests, and
model-list fetches — applied after the auth headers. Presets and signed-in
agent accounts ignore them. Editable in the GUI (with a JSON value mode) and
via the CLI as header.X-Foo=bar.
2026-09-24 12:50:51 +08:00
yetone 2a90ed1030 usage: the page no longer waits on subscription quotas — they load on their own, in parallel, stale-while-revalidate (#6) 2026-09-24 12:49:51 +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 fa0ff18643 gui: Settings → Tray icon chooses whether a click opens the quick panel or the main window (#7) 2026-09-24 12:43:21 +08:00
yetone d77e14701b provider: a signed-out Claude Code account goes away, and any account can be removed (#9)
Logging out of Claude Code can leave its credentials behind; claude auth status
now decides. Removing a Claude, Codex or Copilot account hides it from magpie
(the agent stays signed in); Add it back, or magpie provider add <id>, restores it.
2026-09-24 12:42:14 +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 4069e955c1 site: import links need 0.1.8 2026-09-24 12:21:32 +08:00
yetone 3d4d4b9c2b site: Add to magpie docs, the /import landing page and badges
usemagpie.ai/docs/import explains import links, with a link builder and
buttons to copy; usemagpie.ai/import#… turns the fragment into a
magpie:// link and offers the download. install.sh registers the scheme
on Linux.
2026-09-24 12:17:47 +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 084480beec provider: OpenCode Go and Zen presets, with the session header OpenCode requires (#2)
OpenCode's gateway turns away requests that do not name their conversation
in x-opencode-session ('Request is missing x-opencode-session and cannot be
routed efficiently'), and magpie never sent it. Requests to opencode.ai now
carry the agent's own session id (OpenCode's x-session-affinity, Pi's,
Codex's session_id, Claude Code's) or, when the agent sends none, an id
derived from the conversation's first user message, stable across turns;
the provider test sends one too. OpenCode's docs ask exactly this of
third-party clients, along with their own User-Agent, which magpie already
sends.
2026-09-24 11:49:06 +08:00
yetone 1786bc3c3d agent: Pi offers xhigh and max for models that have them
Pi shows xhigh and max only for models whose thinkingLevelMap names them,
and magpie wrote just "reasoning", so a model whose top level is max (GLM-5.3,
DeepSeek) stopped at high and a max setting was sent as high (#5). Checked on
the wire: --thinking max sent reasoning_effort high before, max after. Picking
the model or thinking level in magpie again rewrites Pi's models.json.
2026-09-24 11:15:59 +08:00
yetone 24f9edafa1 gateway: relay developer messages to Chat Completions backends as system
Pi sends the developer role to reasoning models; relayed unchanged, DeepSeek
rejected every request (422 unknown variant `developer`), so Pi got no reply
at any thinking level above off (#1). Every backend, OpenAI included, accepts
system.
2026-09-24 10:10:37 +08:00
yetone 489c9fa431 site: screenshots keep their shape on narrow screens 2026-09-24 03:59:12 +08:00
yetone 2789e8ee67 gui: import sync 2026-09-24 03:37:14 +08:00
yetone 2bc760d86a gui: on Windows, show the window once its webview has loaded
Wails' 3s visibility fallback calls into WebView2 before a slow first
start has made the controller, and crashes on the nil pointer.
2026-09-24 03:36:50 +08:00
yetone 1e0d034ce5 gui: log the webview's errors
Wails exits on some WebView2 errors after handing them to the error
handler; the default one said nothing.
2026-09-24 03:31:31 +08:00
yetone 01e1971a7b site: downloads for Windows and Linux
The download button follows the visitor's OS, a platform list sits under
the final call to action, /download/{windows,linux}[-arm64] redirect to
the builds, and install.sh installs the Linux desktop app, with a menu
entry, when WebKitGTK 4.1 is present.
2026-09-24 03:22:02 +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 b98af9acc6 site: the GitHub link no longer switches the theme
It shares the .theme style with the theme button, so the click handler
went on both. The handler and the tooltip now bind to button.theme only.
2026-09-24 03:04:09 +08:00
yetone 7198ba218d Revert "site: reshoot the panel, picker and providers on the current build"
This reverts commit 82e25aa2d7.
2026-09-24 02:56:46 +08:00
yetone 82e25aa2d7 site: reshoot the panel, picker and providers on the current build
The screenshots still showed the row's + and an older control column. New
shots, dark and light, off a throwaway demo config (the same DeepSeek/Kimi/
GLM/Qwen/MiniMax/OpenRouter/Anthropic/Gemini set). The panel is a hair taller
now, so its height goes 470 -> 476.
2026-09-24 02:54:41 +08:00
yetone 1fcd539f29 agents: keep the tray panel's control-sized pills
The lined-up columns only suit the wide window: in the narrow menu bar
panel a solo control spanning both columns is what keeps a long model id
readable, so scope the fill to body.window and leave the panel as it was.
2026-09-24 02:44:02 +08:00
yetone 07533b7f02 agents: line the model and setting controls up in two columns
The controls hugged their text and right-aligned, so a model pill sat in
a different place on every row and the chevrons never lined up. They now
fill a fixed two-column grid — model (or large model) on the left, the
second setting on the right — so every chip and chevron lines up down the
list. A single control keeps the left column, so the model always sits in
the same place.
2026-09-24 02:40:29 +08:00
yetone 86c7fee4d5 providers: drop the + and the agents that only could use a provider
The Agents field is now a summary of who is on the provider: point a new
agent at it from the Agent tab's picker instead. Removes the row's +, the
editor's list of capable agents, canUse, and the strings they used.
2026-09-24 02:40:29 +08:00
yetone 4115d443c1 providers: a plain edit lists only the agents actually on it
The Agents field listed every agent that could use the provider, most of
them sitting there doing nothing until clicked. A normal edit now shows
just the agents pointed at it, and hides the row when there are none; the
ones that could be added stay behind the row's +, which opens the same
editor in an add mode.
2026-09-24 02:36:06 +08:00
yetone 912b3a79ce site: the ChatGPT plan is a provider too 2026-09-24 02:33:19 +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 cd4f97e326 "Every agent's model": magpie is not only for coding agents 2026-09-24 02:30:23 +08:00
yetone b3aa852326 site: back to "Every coding agent's model. One place." 2026-09-24 02:29:18 +08:00
yetone 45b25253d2 site: no purple; the gateway card and OG image stay black and white 2026-09-24 02:28:03 +08:00
yetone 0ecc7b6218 providers: 鱼鱼连线 with a region switch, and a ui polish pass
A relay with several endpoints is one preset now: a Region selector
(Auto / Global / China Mainland) swaps the provider's base URLs, and the
endpoints list follows the choice. AiHubMix's key page moves to
console.aihubmix.com/token.

The rest is a pass over the gateway, usage and provider views: a copy
button that answers on itself, a cache hit rate in the usage tiles, the
chart's peak and last date no longer overlap, the tabs sit level with
the logo, the provider key column holds a line, pickers opened from the
editor show above its modal, and buttons drop the native webkit look so
their labels centre.
2026-09-24 02:27:11 +08:00
yetone 9f678458b9 catalog: ask a relay for its chat models without the anthropic header
OpenRouter serves a second, namespaced catalogue from /v1/models as
soon as it sees anthropic-version, so sending that header on the chat
fetch cached ids like anthropic/xiaomi/mimo-v2.6-pro-ultraspeed[1m]
that the chat endpoint then rejected. Send it only when the fetch is
for the Anthropic protocol, where the official API requires it.
2026-09-24 02:27:06 +08:00
yetone 4b251650b8 site: the gateway card is light in light mode 2026-09-24 02:18:17 +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 28688e2463 site: the feed survives GitHub's API limits, from SHA256SUMS alone 2026-09-24 02:03:07 +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 0bcb2cc26c release: a v* tag dispatches the build to yetone/magpie-releases 2026-09-24 01:09:59 +08:00
yetone 3b0cf9a965 logo: a round magpie in black and white, drawn from one SVG 2026-09-24 01:09:59 +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 9e3e338e63 logo: a kingfisher
The gateway glyph is gone. The mark is now a kingfisher in profile, facing
the wordmark: big head, dagger beak, short tail, one line for the wing, the
eye a hole. The header draws it in ink rather than the accent, which fought
the text in light mode. The icon generator rasterizes the same SVG path
(flattened cubics, even-odd fill), and the app tile is kingfisher blue.
2026-09-23 23:25:07 +08:00
yetone 4ae45965ef gui: list age reads "3h ago", not "3h0m0s ago" 2026-09-23 19:14:56 +08:00
yetone 9d85f6bfb8 make dev: Ctrl-C ends the loop; dialog never wider than the window
fswatch swallows SIGINT, so the shell went round again instead of
exiting; a trap now stops the child and leaves. The loop also kills
only its own dial-dev rather than every one on the machine.

The editor grid's 1fr column had an auto minimum, so a long endpoint
error pushed the dialog past the window edge.
2026-09-23 19:14:26 +08:00
yetone 50db5ccbed gui: provider editor as a dialog; one easing for every motion
The editor no longer unfolds under a row: it lifts over the page as a
dialog with a blurred backdrop, closed by Escape, the backdrop or Cancel.
Its head names the provider and links to its site, so it stands alone.

Motion, kept restrained: a single ease (quick start, soft landing), pills
with one thumb that glides to the chosen option (nav, appearance,
language, usage period, the editor's API switch), views that settle in,
buttons that give under the press, and a theme change that crossfades
instead of snapping. Reduced-motion users get none of it.
2026-09-23 16:19:47 +08:00
yetone c05e83fc07 gui: settings page — theme, language, about; deeper panel palette
A gear in the header opens Preferences: appearance (system/light/dark)
and language (system/English/中文), applied at once and kept in
~/.config/dial/settings.json. The About card shows the version, config
folder (copy/open) and gateway URL. Every visible string goes through
t() with a Chinese table in i18n.js.

The panel gets a tonal ladder of its own (bg, card, pill) with hairline
edges and a legible --faint, instead of the pale flat wash.
2026-09-23 16:12:22 +08:00
yetone a404ebe8dd gui: quieter, column-aligned agent rows on a tinted panel 2026-09-23 15:47:55 +08:00
yetone 045f7f3077 gui: breathing room between section labels and cards 2026-09-23 15:27:22 +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 9174a6510b provider: signed-in agents (Codex, Copilot) become providers
A Codex (ChatGPT) or Copilot login is a subscription with models behind
it, so dial offers it as a provider: every other agent can use its models
through the gateway. The agent's own credential file is read each time,
tokens are refreshed the way the agent does it, and only the model picks
are stored. Claude Code is found but deliberately not offered (Anthropic's
terms), and the CLI and API say so.

The gateway signs upstream requests through the provider (Sign/Prepare),
translates non-streaming requests for backends that only stream, and now
recognises an event stream by its body when the vendor sends no
Content-Type, which is what the ChatGPT backend does.
2026-09-23 15:25:05 +08:00