Commit Graph

  • 33ea9a58ab warm-up: the 5-hour windows can start at a time of day (预热是重置之后发,时间不一定是我想要的…早上六点发送一个请求,这样就可以做到一天三个五小时) — Settings has "Codex daily warm-up" and "Claude Code daily warm-up" under the warm-ups, Off or On with a time field (06:00 to begin with, local time, codexWarmAt / claudeWarmAt); each day at that time every signed-in account of that kind whose 5-hour window isn't running is sent the warm-up's one tiny request, once a day an account, the day kept in codex-warmup.json / claude-warmup.json so a restart doesn't send it again; a machine asleep then sends it on waking up to an hour late and leaves the day be after that; a failed one is tried again within the hour. It works with the reset warm-up off, weekly or on; with "Weekly and 5-hour" a window that would still be running at the time isn't started on its reset, so the windows follow one another from it (06, 11, 16, 21, then 06 again) instead of drifting round the clock. The warm-up loop looks at the wall clock every minute, running as before every 5 and at once when the time comes yetone 2026-09-28 18:45:56 +08:00
  • 44cd8fac4c sessions: OpenCode's and Pi's sessions are listed too (貌似没有opencode和pi的session,能支持一下么) — Usage → Sessions, magpie sessions and the TUI read OpenCode's opencode.db (or $OPENCODE_DB) read-only, or its older storage/ JSON files when there is no database, under $XDG_DATA_HOME/opencode or ~/.local/share/opencode, a subagent's session counted under the one that started it; and Pi's JSONL sessions under $PI_CODING_AGENT_DIR or ~/.pi/agent, plus $PI_CODING_AGENT_SESSION_DIR or settings.json's sessionDir, a forked session not counting again what it copied from its parent. Each gets its title, folder, times, tokens per model with cache reads and writes, cost, and a resume command (opencode --session <id>, pi --session <id>); the folders note names only the agents that are there yetone 2026-09-28 18:41:32 +08:00
  • 33ffb48f50 tray: clicked, the bird flaps as the header logo does on hover (一定要用应用里的那个 Magpie icon 被 hover 的动画效果) — the frames were a bend of the outline of my own; now build/icon/gen.go draws app.css's .logo.wag itself: the bird cut into body, tail and wing by index.html's clip paths, each turned about the same origin through the same keyframes, cubic-bezier(.3, 0, .3, 1) between each two, the whole bobbing about its feet, over the same .9s — 29 frames played 30ms apart. Checked against Chrome's own rendering of the logo paused at the same 29 moments: at most 0.7% of pixels differ, all of them at anti-aliased edges yetone 2026-09-28 18:43:55 +08:00
  • e8eb7078db provider: ZCode's and WorkBuddy's plans list the models their apps offer now, not a list written into magpie (我觉得一定有API来查询动态的模型列表) — ZCode's come from its built-in provider config, which zcode.z.ai names (/api/v1/client/configs → a release on cdn-zcode.z.ai) and ZCode also ships and caches: the later revision of those is read, as ZCode does, the coding plan's models taken from its providerRules and builtinProviderModelRules (bigmodel.cn's plan its own), and each one's context, output limit and images from the modelRules that match it; WorkBuddy's come from its product config, GET /v3/config signed as a chat, asked with the CLI's User-Agent (CLI/<v> WorkBuddy/<v>; a bare WorkBuddy/<v> gets CodeBuddy IDE's config), its cli agent's models with their names, input and output limits and images — Kimi-K2.8-Preview is there now, and Auto is 256k. The written-in lists are what shows before the first read. Tested live against both with the accounts signed in here yetone 2026-09-28 18:26:04 +08:00
  • 23e9c0bba3 agent: Cindy's global build is found too (Magpie在Cindy里面显示的图标不对) — its data is in CindyGlobal, one cindy-<account>.db per signed-in account, where magpie only looked in Cindy/cindy-local-v1.db, so the row said Magpie wasn't added when it was; both folders are looked in and every account's database read, read-only as before. The icon itself is Cindy's: it takes no icon on import and draws its own logos only for providers it knows by id or host, a first-letter badge for any other yetone 2026-09-28 18:22:11 +08:00
  • 9946d4cc85 usage: a Codex reset used is the one that runs out first, and its button says so (hover 的时候详细说明一下,不然用户不敢点,怕用掉了保质期最长的那个) — magpie named no credit when it spent one, leaving the vendor to choose; now it reads the account's credits and names the one to go first (credit_id, as Codex's own client does), one that never runs out last, and spends none when it can't tell which that is. The button's tooltip says it uses the one running out first, and when, and that it asks first; the confirmation and magpie quota reset say which too yetone 2026-09-28 18:22:28 +08:00
  • a1ca00d31b routing: a request shows the reasoning its model was actually sent at (显示意图路由实际的推理强度 #144) — the trace keeps the effort the agent asked for and, on each try, the one sent upstream after the turn's pick and fitting to the model's levels (picked marks the turn's pick), so the Routing list reads "Fake · m-big · high", its tooltip says what the agent asked for, and the request's story adds "The turn's pick replaced the medium Codex asked for."; usage.jsonl records the sent effort too, and the Usage session list shows where magpie routed a session's calls and at what reasoning ("→ m-big · high +1", with a Routed line per model and effort in its detail) yetone 2026-09-28 18:07:53 +08:00
  • def870f026 provider: ZCode's and WorkBuddy's plans aren't asked for a model list they don't have — with no list of their own to fetch, a refresh asked their endpoints' /models as if they were keyed APIs, unsigned, and each start logged "zcode: https://api.z.ai/models: 404" and "workbuddy: https://copilot.tencent.com/v2/v1/models: 404"; a plan without a list gives its own models now and asks nothing yetone 2026-09-28 18:10:13 +08:00
  • 10d4e98e19 provider: ~/.gemini/oauth_creds.json is Gemini CLI's only when Gemini CLI's OAuth client minted it (#143) — a sign-in whose ID token names another client (Antigravity's) can't be refreshed as Gemini CLI's and is no longer listed as its account; agy keeps its sign-in in the system keyring, not there, so a personal account Google turns away from Gemini CLI is now told to add itself under Antigravity in magpie yetone 2026-09-28 17:54:12 +08:00
  • 502246c563 usage: a Codex account's rate-limit resets are on its card, so they don't go unused (可能把 resets card 在里边反应出来么?免得我们忘了用) — wham/usage's rate_limit_reset_credits count, and from /wham/rate-limit-reset-credits when the first of those left runs out, show as "↺ 2 resets · until Sat 22:30" under a hairline on the tray's Usage card, under the account's windows in the window's Usage view, and in magpie quota / accounts and the TUI (nothing when there are none, no date when none expire); "Use one…" asks first — which account, that its windows start again at once, that it can't be undone, and that there is nothing to start again when no window has been used — then spends one with a fresh redeem_request_id on that account (POST /api/usage/codex-reset, or magpie quota reset [<account>] [--yes]), says what came of it in words and reads the usage again; the account signed in now is found from Codex's own auth.json, not only the list magpie keeps. panel: a section's account count is a quiet rounded pill by its name, not a bare 2 at the far end (那个 2 是没有仔细打磨), the "N accounts" kept as its tooltip yetone 2026-09-28 18:01:02 +08:00
  • b12c8a4d0c provider tests: a signed-in test's home is Windows' home too — os.UserHomeDir reads USERPROFILE there, not HOME, so #145's Windows fixture path was looked for under the real profile yetone 2026-09-28 18:01:17 +08:00
  • 70f2153463 test: 修正跨平台测试路径并补充下拉菜单回归 (#145) SadWood 2026-09-28 18:00:38 +08:00
  • 663e9c861a agent: Cindy is an agent row (Cindy 的支持应该放在 Agent 里) — magpie can't write Cindy's providers, so its row is Cindy's own import link, cindy://provider/import, which opens Cindy to add magpie as one custom provider (Claude Code, Codex and Pi endpoints, keyed magpie-cindy so its use is counted as Cindy's) for the user to confirm there; the row says whether Cindy has it already, read from Cindy's database read-only; magpie cindy add does the same from the terminal, and the TUI leaves out an agent with nothing to pick yetone 2026-09-28 17:58:48 +08:00
  • f416609a02 gui: an agent with nothing to pick no longer blanks the Agent view — its fields went out as null rather than an empty list (Go's nil slice), and the view's first fields.some threw "null is not an object (evaluating 'a.fields.some')", so none of the agents were drawn; fields is always a list now yetone 2026-09-28 17:56:41 +08:00
  • 33a645b99d providers: every row's key pill is one width, so its dot lines up down the list whatever it says (#146 did it for labels up to 120px) — a plan or key name too long for it ends in … and the tooltip says it whole yetone 2026-09-28 17:53:33 +08:00
  • ab3291964d dev: a backend restart no longer shows "502 Bad Gateway" — the shell asks a read cut off in flight again, of the backend that comes up, and only a write, which may have landed, still fails (Image #14) yetone 2026-09-28 17:51:00 +08:00
  • a2cd79da96 fix(gui): align provider status dots on providers page (#146) elonnzhang 2026-09-28 17:49:50 +08:00
  • b552027932 panel: a balance shows its provider's logo before its name (这里也要有Provider的Icon), the generic one for a provider without; the footer is even to the eye (底栏的上下间距是一致的吗) — its rule was a pixel of the space above and the panel's rim takes about one off the space below, 7 against 5 on the Mac, so it's 1+5 over and 7 under now; and a picker comes and goes like an iOS menu (Modal Selector的弹出跟关闭都要有丝滑的动画) — it grows out of the button's middle from .94 on a quick-to-answer curve with a long soft settle and no bounce, .42s, shown at once as it fades in over .18s, and closing leaves its likeness (scrolled and typed as it was, no ids, inert) to fade and sink back toward the button over .22s while the real one is put back at once; under reduced motion it only fades in yetone 2026-09-28 17:49:05 +08:00
  • 1ae838fc98 gateway: no Add to Cindy — the Gateway view's connect card no longer has a button for one app, which read as an advert and showed whether or not Cindy was installed; the link, its strings and the cindy:// allowance on /api/open go with it yetone 2026-09-28 17:45:35 +08:00
  • ea6a5f53e7 agent: the Windows-only WSL test builds again — wslList returns the names and whether wsl.exe answered, and the test took it as the names alone yetone 2026-09-28 17:43:10 +08:00
  • 6294dd0ac5 provider: WorkBuddy usage shows up — send a WorkBuddy User-Agent and read string capacities (workbuddy 订阅的usage能显示出来吗) yetone 2026-09-28 17:40:12 +08:00
  • 23f1db6dba panel: the model's logo on a row's hover comes in on the row's spring (这里的icon出现的时候的动画有点太突兀了 / 像iOS的动画一样丝滑) — its box opens from nothing to a real width measured as the pointer comes onto the row, not a grid column going 0fr→1fr, which WebKit doesn't lay out frame by frame, so the logo jumped to its size over the words; the logo sits against the words and fades and grows in from their side a beat behind the box, .46s open, and goes first on the way out, .36s; the box's padding is counted in its width now, so the leftmost disc's ring is whole; none of it moves under reduced motion yetone 2026-09-28 17:39:05 +08:00
  • e6e09aa348 panel: nothing is shaved at an edge (竟然有裁边 / 上面这个border也被裁掉了) — the model's logo on a row's hover comes in as its column opens from nothing to its own width, so a stack of three is as whole as one, with its clip padded past the discs' rings; and the tab's view, which scrolls and so clips at its own top, has the 2px the card's ring outside its box needs, taken from the gap under the tabs. usage: an account's last allowance read is kept (quotas.json beside magpie's settings) and shown in place of one that can't be read for a reason that says nothing about the account — Anthropic rate limiting its usage endpoint, a 5xx, a timeout — across restarts too, with its windows that have reset since starting again from nothing and a tooltip saying when it was read; a reading that comes back is used at once, and a sign-in gone bad is still said (因为rate limit获取不到用量的情况下,能否先暂时用上一次获取到的用量顶替着) yetone 2026-09-28 17:34:06 +08:00
  • f8be98bc8a gui: a dialog's head and buttons stay put and only the fields between them scroll — openModal lays an editor out as head, body, bar (the fields moved into .ebody, the only part that scrolls, and a re-render keeps its place), and the head and the button bar are the same 48px with what's in them centred, so they sit the same above and below (上边栏跟下边栏要固定着,只有内容区可以上下滚动 / 上下间距要保持一致) yetone 2026-09-28 17:30:36 +08:00
  • 5741e3fc95 provider: WorkBuddy credits are at /billing/meter/... — not /v2 yetone 2026-09-28 17:11:41 +08:00
  • 9661b8f302 gui(routing): on a wide window the request list and Accounts and keys sit side by side at the same width — they were 1.25fr to 1fr, the left wider than the right (reported by @duanckham on X) yetone 2026-09-28 17:28:14 +08:00
  • f6301b0837 panel: a shut agent row is its 36px again — the opening part now always there sat in a second grid row under the row's 9px row gap, so every row had a strip beneath it and its line sat high (每个Item的上下间距竟然不一致); the tab card glides — the panel's height changing on a tab was taken for a resize and the card put still, cutting its glide off, so now only the bar's width changing puts it; and a row opens and closes on a critically damped spring fitted to a cubic-bezier (.25,.3,.1,1), .48s open and .4s shut, with the panel's edge on the same curve and time: it sets off gently, settles without a tail, what's inside comes down into place as it clears and is gone first when it shuts (展开有点突兀,折叠有点油腻 / 像iOS动画一样) yetone 2026-09-28 17:24:13 +08:00
  • 3f3cdff119 stats: magpie counts its users — once a day a running app or magpie serve sends PostHog (the Magpie project) one "magpie active" event under a random id made up on this computer (~/.config/magpie/install-id), with the version, the system and the architecture and nothing else, no person profile kept; off in Settings → Privacy → Count me as a user, or with DO_NOT_TRACK=1 or MAGPIE_NO_STATS=1, and never from a build from source; the README says what goes yetone 2026-09-28 17:23:39 +08:00
  • 7dff31fc46 agent: a WSL distro that isn't running is never started to be looked at — any access to its files through \\wsl.localhost starts it — so only running distros (wsl.exe -l --running -q) are probed, once each, and those Codex is in are kept in wsl.json beside magpie's settings (not the stash, which profiles and backups carry) with their fields as last read; a stopped one stays listed as magpie last saw it, with a notice saying so, no path, and nothing checked, synced or migrated, so the minute's list, Detected and Current never open it; picking a value is the user asking, so it starts the distro with wsl.exe -d <distro> -e true first (opening a stopped distro's files is aborted rather than waited for) and then writes, keeping what it wrote at once; a distro no longer installed is forgotten, and one without Codex isn't kept. Tested on the Windows box with a throwaway Alpine distro: listed while running, then after wsl --terminate listed with its last model and effort by magpie ls and magpie codex@wsl:<distro> with wsl -l -v still showing it Stopped, then a model set on it started it, wrote its config and updated wsl.json yetone 2026-09-28 17:21:57 +08:00
  • 52b3ad3a9e agent: on Windows, Codex installed in a WSL distro is an agent of its own, codex@wsl:<distro> ("Codex · WSL Ubuntu") — the distros are listed with wsl.exe -l -q (UTF-16LE, or UTF-8 under WSL_UTF8), each asked once through proc for its $HOME, its ~/.codex, a codex on its PATH and its default route, and shown only where Codex is; its files are Codex's own reading and writing (codexIn, at a place rather than a home) through \\wsl.localhost\<distro> (\\wsl$ before that), with the catalog path written in as the distro spells it and what was there stashed under the distro's agent; the gateway written in is 127.0.0.1 when .wslconfig has networkingMode=mirrored and otherwise the Windows host by the distro's default route, with a notice that NAT needs the gateway beyond loopback and through Windows' firewall and that mirrored is the way; its requests stay counted as Codex's, and a profile key is split at its last dot for distro names like Ubuntu-24.04. Nothing runs off Windows. Kimi CLI isn't an agent magpie has yet, so there is no Kimi in WSL. Tested on a Windows box under NAT with a throwaway Alpine distro: detected (the real distros without Codex left out), a magpie model set and reset from the CLI and a test binary, the catalog read inside WSL at /root/.codex; mirrored networking tested only in unit tests yetone 2026-09-28 17:08:57 +08:00
  • 0984edaa03 cursor: the Run goes to the agent API Cursor's server config names for the account — ServerConfigService/GetServerConfig on api2.cursor.sh, whose agentUrlConfig cursor-agent reads to pick agentUrl in privacy mode (which the Run always asks for) and agentnUrl otherwise — asked once a token, kept by the token's hash so another account asks again, asked afresh and the Run tried once more after a region error, and the global agentn.global.api5.cursor.sh while the config can't be had (retried after a minute), as a team served in one region only was turned away by the global API with 'This region is not yet available for your team'; Cursor's errors have words of their own, no longer Devin's: an unauthenticated or expired sign-in says to sign in to Cursor again in magpie, a region or team restriction says so plainly with a 403 and doesn't ask for a sign-in; and Cursor's expanded ids (grok-4.7-low … grok-4.7-xhigh-fast, Claude with and without thinking, gpt-5.5-extra-high) are offered as one model a family, with the efforts it really has, named as Cursor names its default without the effort and holding what the least of its variants holds, fast and thinking families of their own (GPT-5.5 is 1M, GPT-5.5 Fast isn't said to be) and a family of one kept as Cursor's id — the list saved stays Cursor's own, and the gateway turns model and effort (and Codex's Fast) back into the variant at that effort, Cursor's default for one between those it has, else the nearest, while any of Cursor's own ids still goes as it is yetone 2026-09-28 17:13:18 +08:00
  • 4df6cd14ac provider: a Claude account's Fable week is read and routed on (#139) — /api/oauth/usage gives a week's allowance per model only in its limits[] array, which readClaudeWindows didn't parse, so magpie accounts, magpie quota and the app never showed Fable's, often the first to run out on Max, and routing went on sending Fable requests to an account whose Fable week was used up. Each weekly_scoped item with a scope.model.display_name is now a window "7 days · <name>", counted in percent, renewing at resets_at, a week long and counting only its model (the name lowercased, spaces and dots as dashes, so "Fable" counts every claude-fable-*), which Allowance.For and Full already weigh against that model alone, as they do the Opus and Sonnet weeks; one without a scope (seven_day again) or one for a model seven_day_opus/seven_day_sonnet already told is left out. Claude Code's rate_limit_event names the same window seven_day_overage_included, its "Fable limit" (in 2.1.283's bundle, for its allowlist Fable, Fable 5, Fable 5.1); claudeKinds takes it too, so the Fable week stays known while the usage endpoint turns magpie away. Reported by Cyb3rN8 2026-09-28 17:10:27 +08:00
  • 44acea90db gateway: a subagent Codex's MultiAgentV2 spawns from a magpie-served lead gets its task (#141) — a namespaced call (spawn_agent, send_message, followup_task) now carries "encrypted_function_args": [], since Codex reads a call without that list as sealed and handed spawn_agent's plain message on as encrypted_content, which OpenAI could not decrypt for a gpt-6 subagent; and the agent_message item V2 hands a subagent its task in, and agents their messages to each other, is read as the receiving agent's user turn instead of being dropped, so a magpie-served subagent no longer started with nothing to do (an item with no content adds no turn). Top-level calls and the other encoders are as before. Checked end to end with Codex 0.155.1 and features.multi_agent_v2=true in a sandbox HOME against a scripted upstream: before, the subagent's request held only the environment context; after, it holds "Message Type: NEW_TASK … Payload: …" and answers it. Patch and tests by relus-cy, who found and reported both gaps 2026-09-28 17:03:33 +08:00
  • 25aae87511 panel: things move as they change — the tab picked has a card that glides to it; an agent's effort is a drawn slider whose knob and fill glide from stop to stop; a row opens and closes by easing its height, the panel's edge moving with it over the same time and curve; hovering an agent brings in its model's logo beside the name; Add provider scrolls the window to the sheet it opens; and a reply that isn't JSON shows its own words rather than WebKit's "The string did not match the expected pattern" (切换Tab不是丝滑的左右滑动 / 这又是啥报错 / 展开折叠也要有丝滑的动画 / hover显示模型图标 / 自动滚动到展开内容顶部) yetone 2026-09-28 17:08:27 +08:00
  • 3dabb56ac9 sessions: history by day in the CLI and the TUI — magpie sessions lists the latest Claude Code and Codex sessions (when, agent, folder, first prompt, tokens, cost; --limit, --json with the resume commands), and with --days N|today|all (stats alone is 7) prints the range's totals (tokens, list-price cost, cache read and hit rate, active time and on how many days), a line a day with its tokens, cost, cache read, active time and a bar, then the top models and folders; --model and --folder narrow either, matched exactly, by base name or by a unique part, an unknown one naming those there are. The TUI gets a sessions page after usage (5; the library is 6 now) with the ranges today, 7, 30, 90 days and all (←→, t w m A), M and f to pick a model or a folder from those the range has, x to clear them, the totals, and a chart of the days in block characters, a week a column when the days don't fit, of tokens or, with c, cost. Both sum sessions.StatsFor as GET /api/sessions/stats does, through Stats.Sum, which rolls the days up under a model and a folder as the app's view does — active time not kept by model, so none under one yetone 2026-09-28 17:05:26 +08:00
  • 82b0239dd0 fix: keep session filter menus open while scrolling (#140) Leon Zhao 2026-09-28 16:56:10 +08:00
  • acd00dc4fb panel: an open agent's effort is the effort picker's slider — its name and level over a thin track with a dot per stop, the ends named under it; a level shows at once, the row's bars with it, and is written after in order, so the agent's slow config write no longer holds the control for a second and a half (巨卡 / 变成之前的那种滑轨样式) yetone 2026-09-28 16:51:53 +08:00
  • add95706d3 panel: the tabs lose their grey track — only the tab picked is a card, the others plain text on the panel (能否去掉背景的灰色) yetone 2026-09-28 16:48:52 +08:00
  • b990735823 agent: RTK isn't given to OpenCode 2 — rtk init --opencode writes a plugin shaped for OpenCode 1 (a named export, no default {id, effect|setup}), which OpenCode 2 refuses to load with 'Plugin must export a default definition with an id and an effect or setup function' (rtk-ai/rtk#4311, still so in rtk 0.50.0); with opencode --version at 2 or later the Library shows 'Not for OpenCode 2' and won't switch it on, while a plugin already there can still be switched off and taken out (ARNO) yetone 2026-09-28 16:35:26 +08:00
  • 5f73e4f4fc agent: OpenCode's magpie models name the reasoning levels each really has as variants ({level: {reasoningEffort: level}}, an empty set for a model without any) — OpenCode 2 otherwise makes low, medium and high of its own for every openai-compatible model (packages/core/src/variant.ts), so a model with none/high/max or none at all was offered levels it doesn't take; OpenCode 1 merges the same variants as before (kkgg) yetone 2026-09-28 16:35:25 +08:00
  • e753cbafc5 panel: as drawn in A and C, strictly — the tabs stay put above what scrolls; an agent's line is its icon, name, model in words, its effort as three bars (faint when default) and a chevron that turns down when open, all in fixed columns; open, it shows a Model field with its label and a segmented effort control under the name; Show N more sits left, as a quiet line; the footer is one hairline over even padding, with when usage was fetched on its left on the Usage tab; usage vendors are small caps headings with their accounts or plan on the right, each account a card with its reset times under it and a ring per window, balances two to a row (你没有严格按照设计稿来实现呀 / 底栏中上下间距竟然都不一致) yetone 2026-09-28 16:34:56 +08:00
  • 9687f3d297 provider: WorkBuddy is a subscription — Tencent's CodeBuddy plan, signed in as WorkBuddy does, its own account read too yetone 2026-09-28 16:31:06 +08:00
  • 3bc9a744c8 Fix Settings segmented controls replaying thumb animations (#135) Ns2Kracy 2026-09-28 16:25:04 +08:00
  • b9a240864b settings: a theme picked while the window's state was on its way stays picked — coming back to the window reads its state, which can take seconds, and a read that a change of settings overtook put the old theme back when it came in, the picker showing the new (Light chosen, still dark); such a read now keeps the settings the page has. Saves go one after another, each sending what the page was drawn with plus its own choice over those before it: two quick ones (a theme, then the language) each sent the page as drawn, the second undoing the first, and their answers could land in either order yetone 2026-09-28 16:18:57 +08:00
  • ebc33c721b tray: a click on the bird flaps it — the wing beats twice and the tail flicks up once, 16 frames over about half a second (build/icon/gen.go tray-flap bends the outline about the tail's root and the shoulder, eased, so it stays one line); and the usage beside it no longer sits hard against it, a thin space between (Image #13: 图标与用量之间没有任何的间距) yetone 2026-09-28 16:15:40 +08:00
  • ec10f99113 panel: three tabs — Agents, Usage, Profiles, the one last open kept; an agent is one quiet line, its model in words and its effort as bars, that opens in place to its pickers (one at a time); usage is each vendor's accounts as cards under its name, a ring per window (amber from 90%) with the plan and when each window starts again under the account, balances as figures two to a row; the Usage tab only when there is usage to show, and the window view is as it was (A+C) yetone 2026-09-28 16:09:53 +08:00
  • 9e0fbd6ef7 ui: a segmented control's thumb slides only when it is the one picked — where a thumb was is kept per control, known by its place, not per set of options: every Off/On on Settings had the same, so a click on one, or opening the page, slid the others in from where it had been yetone 2026-09-28 16:03:36 +08:00
  • 3472235772 panel: usage rows all the same height — the account over one quiet line (when the plan ends, when its fullest window starts again, or what went wrong), its windows' names and shares over their bars in two columns, a hairline between accounts; reset times per window and long errors move to the tooltips, and a balance spans both columns, right-aligned, so its label isn't cut (还是乱呀) yetone 2026-09-28 15:52:33 +08:00
  • 29c706d1e7 provider: Tencent Cloud Token Plan is a preset — TokenHub's coding subscription (its general and Hy plans on one sk-tp- key, from console.cloud.tencent.com/tokenhub/tokenplan), served at its own endpoints under api.lkeap.cloud.tencent.com/plan: v3 for chat completions and anthropic for messages, no Responses (its Codex page asks for wire_api chat); models.dev lists only its Hy models, so the preset gives the plan's (tc-code-latest, GLM 5–5.3, Kimi K3 and K2.7 Code, DeepSeek V4, MiniMax M3 and M2.7, hy4-preview, hy3) until the plan's own list is fetched, and an entry imported at those endpoints is the preset yetone 2026-09-28 15:41:23 +08:00
  • a285354560 panel: usage lines up — every account's windows sit in two columns shared down the list, each a name and share over its bar with when it starts again under it; one window takes the last column, a balance too, and what went wrong spans both, over two lines at most (Wey Gu: 有点点乱) yetone 2026-09-28 15:36:09 +08:00
  • 23847a8a56 library: hundreds of skills no longer make the Skills tab crawl — they're grouped by the GitHub repository they came from (owner/repo, how many, an Update N for those a check found changed, which agents have all or some of them, and a link to the repository), those on this computer in a group of their own, each group folded to its heading line and opened with a click, remembered in the browser; with more than 40 skills from several places the groups start folded. A filter over the skills (name, description, repository) shows when there are more than 8, opening the groups that have matches, and a filter or a fold draws only the groups again, not the page. Every row was drawn with a chip for each agent, 4400 icons for 400 skills, and each redraw, scroll and hover laid out and painted all of them: a row out of view is now skipped by the browser (content-visibility) and an agent's icon is made once and copied rather than made afresh (and probed) for every chip. On 400 skills from 6 repositories and 100 local ones, drawing the tab went from 131ms to 17ms folded (55ms with every group open), a pointer sweeping the list from 1.4–1.65s of main-thread work to 0.4s (0.67s all open), and a 6000px scroll from 0.65–0.71s to 0.29s (0.49s) yetone 2026-09-28 15:35:08 +08:00
  • cd373b19fb panel: the agents' names have their room back — since a row's squares sat side by side (af840b0) the pickers grew by Codex's second square, and on the tray's panel every name was cut to its first two letters (Co…, Ge…, Op…); there the pickers keep the width they had and the model's column gives the square its room yetone 2026-09-28 15:24:59 +08:00
  • 35fca05b95 provider: a Devin subscription's own token limits are what agents are told — devin models list gives each variant max_context_tokens and max_output_tokens, and magpie parsed neither, taking the window and the reply cap from models.dev by bare id instead: swe-2's 262000/128000 were written as nothing at all, glm-5.2 at 1M where Devin gives 200K, gpt-5.4 at 922K where Devin gives 272K, grok-4-7's replies at 500K where Devin gives 100K, and gemini-3-8-flash at 1M/65536 from the one provider spelling it that way where Devin gives 1048576/65535 (215 of the 277 variants magpie serves were wrong). The CLI list's numbers are parsed and used, a family's taken from the variant its id follows, a variant without numbers from its family, and models.dev kept for what Devin's list doesn't name or a variant fetched before it was given its family's; a saved list takes Devin's numbers over what an older magpie wrote. Checked against Devin's own model configs, 277 of 277 variants now carry the subscription's numbers (#133) minuque 2026-09-28 15:15:26 +08:00
  • 7931723d79 cli: 新增 magpie webdav,在终端里开启、修改和触发 WebDAV 同步 / add magpie webdav to turn on, change and run WebDAV sync from the terminal (#127) AronnaxandClaude Opus 5.5 2026-09-28 14:54:04 +08:00
  • f3db861b63 agents: Codex's sign-in picker shows each choice's whole explanation, under its name, rather than cut off after a few words; the Chinese reads which one is the default and what the Codex app shows yetone 2026-09-28 14:40:32 +08:00
  • af840b012f agents: a row's small squares sit side by side — Codex's sign-in square wrapped under its subagents one (the extras column held one); the squares share one cell, the column as wide as the row with the most yetone 2026-09-28 14:37:09 +08:00
  • 91aacfba1c tray: the menu bar's usage says what the panel does — a subscription's quotas are served stale while they refresh behind, and the menu bar, reading them every few minutes, showed each refresh only a tick later (53% beside a panel's 57%); it reads them again the moment a refresh lands yetone 2026-09-28 14:16:42 +08:00
  • 6e677aabb6 codex: a thread started with magpie as Codex's provider opens again, and Codex can be kept in its API state (#129) — signed in to ChatGPT, a magpie model is routed with openai_base_url (c3931c9), and moving there from magpie as the provider (an older magpie's wiring, or one made while the account had used its allowance up, bd5bf42) took [model_providers.magpie] away, so the Codex app, which resumes a thread on the provider it was started on, said "Model provider magpie not found" for every one of them and came back signed in to ChatGPT. The table now stays once written, a base-URL wiring writes it too, and a sync puts back one an older magpie took away. Codex gets a sign-in field (magpie codex login api, a small square beside its pickers): api keeps magpie as Codex's provider while it is signed in, the app in its API state with magpie's models only; ChatGPT, the default, is as before yetone 2026-09-28 14:10:44 +08:00
  • d53f90e746 gateway: Codex's namespaced tools reach a model magpie serves — spawn_agent, wait_agent and the rest of collaboration come inside a Responses namespace, which was dropped whole; each of its functions is offered as <namespace>__<name> (cut to 64 with a hash when longer), a past call with a namespace is read back under that name, and a call to one goes back to Codex with its name and namespace, streamed or not (#130) yetoneandrelus-cy 2026-09-28 14:01:27 +08:00
  • 4eead4d4e0 agents: the effort picked for Cline and Qoder is the one they use — Cline's reasoning is written {enabled:true,effort} ({enabled:false} for none), as its own pickers leave an enabled false that drops an effort beside it, and such a one reads as none; Cline's VS Code extension (4.x), which takes its provider, model, base URL and key from globalState.json and secrets.json before providers.json, has those set too where they are, stashed and put back on the way out, and $CLINE_DATA_DIR is honoured. Qoder (1.1.6x) keeps each model's effort in model.preferences and moves model.reasoningEffort there once: magpie sets the model's preference (a model id with dots too), carries the effort in use to a model with none of its own, and keeps reasoningEffort for older Qoders. Cline's desktop app keeps its composer's model and effort in its web view's storage, which magpie leaves alone; its notice says to pick there yetone 2026-09-28 13:40:50 +08:00
  • e02d3f28d7 library: a project's agents can have some of the library's skills as the project's own — under Skills, In projects takes a folder (the system's picker in the app, a typed path anywhere) and each of its skills gets agents' chips; magpie links the skill into <project>/.claude/skills for Claude Code and <project>/.agents/skills for Codex, Gemini CLI, OpenCode, Pi, Cursor and Copilot (the agents documented to read it; MiMo Code, Crush, ZCode, DeepSeek Harness and oh-my-pi aren't, so they're left out), or copies it when the project asks for copies, a copy made again whenever the library's skill changes (updates included). What it places is listed between magpie's marks in the project's .gitignore, made if there was none; taking a skill or the project away removes only what magpie placed, its lines and the folders it made once empty, and a folder of the same name that isn't magpie's is left as it is and said so. The home folder, or one whose project skills folder is an agent's own, can't be added yetone 2026-09-28 13:33:37 +08:00
  • 87a8330115 ui: Hide emails, once on, is a shade darker and no more — the purple fill and ring made a page tool the loudest thing on Routing and Usage; its struck eye and its words already say it is on yetone 2026-09-28 13:29:54 +08:00
  • 4cbd96a3e4 gateway: a model Claude Code names that magpie doesn't serve goes to the one it is set to use for that tier — claude-haiku-4-5-… for a title or a small task goes to its haiku tier's model, opus and sonnet to theirs, a name of no tier to its main model, rather than to some provider that happens to list the name and wasn't picked for it. Other agents, and ids magpie shows, are sent as asked yetone 2026-09-28 13:25:25 +08:00
  • 41cbe54a14 library: which skills from GitHub have changed there can be checked — Check for updates asks GitHub for the last commit to each skill's folder (one request per folder, a repository's skills together; once GitHub limits requests the rest are left unknown, each skill's trouble its own) and a changed one carries an Update available pill whose tooltip has the commit's summary and date, a click opening the changes on GitHub; Update N fetches just those. The library keeps a hash of a skill's files as fetched and, once a check finds GitHub's files to be the same, the commit they're at, so a later check needs only the API; a skill installed before this is compared by its files, the repository fetched once yetone 2026-09-28 13:09:56 +08:00
  • c5e7955937 i18n: tokens reads token in Chinese on the usage tiles as well — a second entry for it, the routing rules', said tokens and won yetone 2026-09-28 13:06:24 +08:00
  • e3984b2442 sessions: history by day — the Sessions view gets a range (today, 7, 30, 90 days or all), model and folder pickers, tiles for the range's cost, tokens, cache read and active time, and a daily bar chart of tokens or cost (weekly past 92 days). Each session file's cached reading now keeps its usage per local date and model, a message counted on the day of its timestamp, so a session that runs past midnight splits across both days and a file read on from where it stopped adds only what's new; Claude Code's repeated usage for one message moves with it to its last block's day. Totals come from every session file in the range, not the latest 200 the list shows: GET /api/sessions/stats?days=N returns each day's rows by agent, folder and model with their cost, so the view filters without asking again, and files last written before the range aren't read at all. Active time is the sum of gaps under five minutes between one line and the next in a session's main file (subagents run alongside it, so theirs aren't added), credited to the later line's day. The cache is version 2 and records the time zone, a change of which reads the files again; the list no longer drops the cached readings of files it doesn't show, only of files that are gone, and changed files are parsed in parallel. On 4000 synthetic files (880MB, 180 days) a cold read takes 0.74s, a warm one 22ms, a reload from the 4.7MB cache 49ms yetone 2026-09-28 13:04:20 +08:00
  • c4596cf615 library: an agent's chip on a skill or MCP server row can be clicked again and again without waiting — each click lights or dims it at once, a row writes one list at a time and sends the clicks made meanwhile together, so the agents end up as last clicked; a chip clicked a second time no longer drew the whole page again (its handler, carried over from the redrawn chips, looked at a row no longer on the page), which made the window blink and the chips fold and spread under the pointer. A write magpie refuses takes back that row's clicks and says why, and coming back to the window redraws the page only when the library changed meanwhile yetone 2026-09-28 12:53:37 +08:00
  • 33d72cef30 gateway: ids made in one clock tick are still unique (#128) Jeremy Levartovsky 2026-09-28 14:42:58 +10:00
  • 112471fb2d cursor: a model is put in Cursor's pool by its family — the server lists grok-4.8, the CLI asks for grok-4.8-high-fast, and the exact match put that one in Other Models; case and cursor- no longer matter, and a bare composer is Cursor's too. The pools read Cursor 模型 / 其他模型 in Chinese yetone 2026-09-28 12:04:43 +08:00
  • 4425be9262 fix(gateway): 按模型匹配 Cursor 路由额度 (#125) SadWood 2026-09-28 12:03:58 +08:00
  • dd1d68f6a6 provider: deduplicate saved login reads (#126) elonnzhangandyetone 2026-09-28 12:01:17 +08:00
  • 8ad73e8bfc accounts: a slow or hanging agent CLI no longer holds the providers page (#123) — its timeout now ends the call (a CLI that is a script running node left node holding the output, and the call waited for it however long, the 10s timeouts notwithstanding: a CLI's pipes are closed 2s after); a CLI never answered before is waited for 3s, once, then served as nobody signed in until its answer comes behind; and a CLI saying nobody is signed in is kept like any answer, where before it wasn't and every start waited for it again. Tried with cursor-agent and devin hanging 20s and the network black-holed: the first providers call went from 40.6s to 6s on a first start, and to 13ms on the next yetone 2026-09-28 11:20:12 +08:00
  • 31169a17f6 agent: fx (fx.sh, Vercel Labs' coding agent) — its model picked in magpie like any agent's; a model through magpie adds magpie to ~/.fx/settings.json as a keyless provider of fx's own (openai-chat-completions at the gateway, auth none) with the catalog as its model_metadata, the model in use first so fx's 256-model limit never cuts it, and sets provider magpie and models.magpie; its own models stay as they are, and default takes magpie's entry out. fx sends no effort to such a provider, so there is none to pick. Tested live from a sandbox: fx 0.0.11 listed magpie's models and read and wrote files through several tool rounds on DeepSeek yetone 2026-09-28 11:17:20 +08:00
  • 2b2a7bf83f sync: a WebDAV server that answers 403 for what isn't there (a Synology, PROPFIND too) no longer fails the first sync as if the account couldn't write in the folder — magpie's own folder in it is looked for, and when it isn't there a 403 to reading the backup is no backup yet and one to writing it is made as a 404 is yetone 2026-09-28 10:51:05 +08:00
  • 880c755a2a gateway page: opened from a page that already had the providers, it is drawn from them at once rather than left as empty cards until the new list is in (#123) — the skeletons were only for a first load, so coming from Providers showed blank cards for as long as /api/providers took. And Claude Code's sign-in, asked of claude auth status (up to 5s) every 30s under a lock on that path, is served from the last answer while it is asked again behind it yetone 2026-09-28 10:47:42 +08:00
  • 01ffafadec providers: ClinePass is a preset — Cline's $9.99 plan for open coding models (GLM, Kimi, DeepSeek, MiMo, MiniMax, Qwen), served at the Cline API with a Cline key; the API lists its pay-as-you-go models and not the plan's, so a preset can say what its plan's ids start with (only those of the list are kept) and which they are (given when the list has none) yetone 2026-09-28 10:28:20 +08:00
  • b1fa0c5dfa gateway: to the key magpie-claude-desktop, /v1/models lists every model by an id Claude Desktop takes — anthropic/<id> for one that doesn't say claude, sonnet, opus, haiku or anthropic — so its Test connection passes and its models can be picked from the list yetone 2026-09-28 10:24:56 +08:00
  • c887c041f9 devin: a pinned variant has its family's window — claude-opus-5-5-high and the rest were listed with none, so Claude Code, not seeing 1M, took them for 200K and magpie gave them no [1m] mark; a list fetched before is read with the windows too yetone 2026-09-28 10:24:55 +08:00
  • e1f784430b gateway: Claude Desktop's third-party gateway reaches any of magpie's models — it takes only ids that say claude, sonnet, opus, haiku or anthropic, so a model asked for as anthropic/<its id> is served as <its id> when nothing answers to the id as it stands; count_tokens and /v1/models/<id> read it the same, an id with a slash in it is found at /v1/models/<id>, and GET/HEAD /api/hello answers the gateway's probe yetone 2026-09-28 10:17:05 +08:00
  • ddf2ef83f5 panel: a meter in the tray's panel turns used or left when clicked, as the Usage page's do, and says so when pointed at — the one setting for every meter and the menu bar (#124) yetone 2026-09-28 10:11:42 +08:00
  • c6dc08e105 sync: an address at OpenList's or Alist's /dav/ says to go into one of its storages, naming them — the list of storages there takes no folder (MKCOL 405, as if it were there) and no file (PUT 404), so a first sync failed with a bare HTTP 404; a folder in the address that isn't there says so. Tried on OpenList 4.2.6 yetone 2026-09-28 10:10:03 +08:00
  • 920bc04d48 sync: a WebDAV 403 says why rather than blaming the password — a folder in the address the server hasn't got (a Synology answers 403 for a shared folder not made), one the account may only read, or one it may not use, told apart by looking at that folder; only a 401 is the user name or password yetone 2026-09-28 09:31:10 +08:00
  • e31a6a15b0 usage: the menu bar's usage is refreshed as often as asked — every 1, 3, 5, 10 or 30 minutes, 3 as before — and reads as used or left as the Usage page does; that choice is a setting now rather than the browser's, so the page, the panel and the menu bar agree, and Settings has it too; a browser's choice from before is carried over once (#122) yetone 2026-09-28 09:27:49 +08:00
  • 0686bdffa7 accounts: a magpie just started no longer holds every page and request for cursor-agent and devin — who their CLIs say is signed in is kept on disk (cli-identity.json), served at once on the next start and asked again behind it; only a first look ever, or one after a sign-in or out, waits for the CLI. The window's first read went from ~4s to ~0.15s here with both signed in, and the gateway page shows its skeleton, not blank cards, while the state loads (#123) yetone 2026-09-28 09:21:24 +08:00
  • 316803e260 warm-up: Claude accounts too — a Claude window, the 5-hour one and the weekly one, starts at the account's first request after it resets, so with Claude Code warm-up on (Settings: off, weekly, or weekly and 5-hour) the magpie serving the gateway sends each account one "hi" as its window starts over, through Claude Code itself (Haiku, none of its tools, settings or MCP servers, nothing kept on disk), a saved account with its own sign-in; once per reset, kept in claude-warmup.json, as Codex's is yetone 2026-09-28 06:31:40 +08:00
  • 1324b61fac quota: a relay's balance can be told by a sub2api panel, and one that tells none says so — a balance token that is a JWT (a sub2api panel's login token, for GET /api/v1/user/profile) is sent as a Bearer, a new-api access token still as it is, and the editor says which goes there; magpie quota <provider> on one with no balance endpoint gives a line saying it isn't configured and how, --json included, rather than an empty list, and an unknown name is an error yetone 2026-09-28 03:28:17 +08:00
  • c547e29fae accounts: a Claude or Codex account removed from magpie is left alone — its sign-ins are no longer saved from the agent nor kept renewed in the background, until it's brought back; before, removing it only kept it out of the providers while magpie went on copying and refreshing the sign-in (#121) yetone 2026-09-28 02:27:36 +08:00
  • 4778cd021c claude subscription: the bridge's runs keep no sessions on disk — Claude Code is started with --no-session-persistence, as each run's conversation lives in its process and is never resumed from a file, so its throwaway magpie-claude- folders no longer pile up among the user's projects (or get imported from there by other agents); the ones left before are swept once from Claude Code's projects folder, only those named after a magpie-claude-<digits> folder in the temp directory (#121) yetone 2026-09-28 02:25:19 +08:00
  • 2d0058b9b9 providers: the context window field offers its usual sizes under it, one click each — 128K, 200K, 256K, 1M — and, where models take more than they are said to, each one's own most: Codex's GPT-6 and GPT-5.6 are said to hold 272K and take 872K when asked, a size nobody remembers, so one chip sets it for every such model (#120). The most is read from max_context_window in the list ChatGPT gives and in Codex CLI's cache yetone 2026-09-28 01:53:08 +08:00
  • de59782fba providers: Jev through Vercel's AI Gateway and Cloudflare's Workers AI — two presets, Jev · Vercel AI Gateway and Jev · Cloudflare Workers AI, route groups and pick their effort as TypeSafe's own does, each asked its own way: Vercel's evaluation-model with the model in a header, a noul asked as a boolean and a confidence taken from the probabilities; Workers AI's run of typesafe/jev at the account its API token works in, found once, out of Cloudflare's envelope. A key is checked by the gateway's free call (Vercel's credits, Cloudflare's accounts) yetone 2026-09-28 01:43:07 +08:00
  • 74cbac06ec gateway: the page is left as it is when nothing on it changed — coming back to the window no longer wipes it to placeholders and redraws, which put the reader back at the top; a reload draws again only what changed (the calls alone when only they did) and keeps where the reader was. The model list folds away under its heading, with its count, so Recent calls sits under Connect; the fold is remembered. Asked on Discord yetone 2026-09-28 01:21:26 +08:00
  • 6c9a0aa4d7 agents: OpenHanako — magpie is a provider there, chat completions at the gateway's /v1 under the key magpie-hanako with every model it serves, their windows, output, images and reasoning said; picking one makes it the primary agent's chat model, and default puts back the one it had and removes the provider, marked deleted as OpenHanako marks one it removes. While OpenHanako runs it goes through its local API (server-info.json's port and token), which reloads at once; otherwise into provider-catalog.json and agents/<id>/config.yaml for its next start. Asked on Discord; checked with OpenHanako's own provider registry and model manager, which list magpie's models and resolve the chat model to the gateway yetone 2026-09-28 01:12:46 +08:00
  • 24a57f8c69 providers: a subscription's editor has the Context window field too (#120) — only an API provider's editor had it, so the 872K a Codex account's models take couldn't be set where the account is edited; it saves with the account, and the agents are told it over the 272K Codex's backend reports yetone 2026-09-28 00:47:18 +08:00
  • 8b8a9e5a7a gateway: a passed-through request's reasoning effort is fitted to the model's levels, and one asking "none" that the upstream refuses with the levels it takes is asked again at low — Qoder's permission check asks "none", which Command Code turned away yetone 2026-09-28 00:39:22 +08:00
  • aee0d1c221 claude subscription: a parked Claude Code run is let go once its conversation moves on — a turn answered by another provider, or on another model, changes the conversation, so the run it left idle never matched again and sat for twenty minutes, one more with every switch back; now a turn that finds no run to resume retires the owner's idle runs whose conversation it has carried past yetone 2026-09-28 00:39:21 +08:00
  • 315a19b6e2 providers: test that a subscription's context window set in its editor reaches the models agents are told of (#120) — Codex's 272K from the ChatGPT backend gives way to the 872K a user sets on the Codex account, through the account's save yetone 2026-09-28 00:28:53 +08:00
  • 98efe400b5 gateway: Add to Cindy — Cindy (makecindy/cindy) takes a provider only through its import link, confirmed in Cindy, so the Gateway view's connect card has a button that opens cindy://provider/import with magpie as a custom provider: the gateway for Claude Code on Messages, Codex on Responses and Pi on Chat Completions, each listing the gateway's models, under the key magpie-cindy so Cindy's calls are known as Cindy's. Checked against Cindy's own parser (all three engines in its preview) and its model fetcher (the sandbox gateway's 30 models on each endpoint) yetone 2026-09-28 00:26:04 +08:00
  • eb0d4418fe claude subscription: a one-off ask — a lone message and no tools, as an agent's title or topic or the router's classifier sends — lets its Claude Code go once answered, rather than keeping it 20 minutes for a next turn that doesn't come; up to six such ~150 MB processes sat idle beside an agent that only used another provider for its own turns yetone 2026-09-28 00:13:24 +08:00
  • 521747465a usage: every window says when it starts again, on the clock — "resets 14:30 · in 3h", "tomorrow 09:00", "Fri 00:06" or "Oct 13 00:06" — under its bar on the Usage page, under its meter in the panel, and in the TUI whatever its use (not only once nearly spent) and magpie quota, rather than only in a tooltip yetone 2026-09-28 00:07:47 +08:00
  • 3fe606e4b3 providers: account usage no longer writes its map from two goroutines at once — an account fetched less than a minute ago went into the map the other accounts' fetches were still writing to, which Go answers with a fatal concurrent map writes, not a panic anything recovers from; LoginUsage and Grok's copy of it now write that hit under the lock their fetches use (#119) Zhizhen HeandClaude Code 2026-09-27 23:32:15 +08:00