Commit Graph

  • 597d16358b gui: the header's refresh reads again what the page shown draws, and no longer looks for a newer magpie (evilgaoshu, #844: 顶部刷新按钮按直觉应该是「刷新当前页面」,检查更新是低频操作,不必占用顶部一个常驻按钮) — the round ↻ refreshed the model lists and checked for an update whatever page was shown. Now on Agents it looks for the agents on this computer again: POST /api/agents/rescan (agent.Rescan forgets the answers kept a while because asking was slow: Cursor Private Inference's apps folder, WSL's distro list and failed probes, Alma's server) and draws the list, Install another agent and the CLI versions afresh, so one just installed or removed, or changed outside magpie, shows at once. On Usage it reads the page now, the allowances too (as its Refresh now); in the panel, Agents rescans, Allowances reads the allowances and Usage the requests; on Providers and every other page it refreshes the model lists as before. Its tooltip says what it reads on the page shown (zh, ja, de strings). A newer magpie is looked for by magpie's own timer and Settings › About's Check, as before. TestRescanLooksAgain (an app installed after magpie looked is found only after the half minute without it) and refresh-page.test.cjs (WebKit, en and zh, window and panel: tooltip per page, Agents rescans and a new agent shows and leaves Install another agent, Usage reads the allowances afresh, Providers syncs, never an update check, no click moves the page) fail on the old code; sync-update.test.cjs, which asserted the old update check, is replaced by it. sync-spin, update-hide, update-check, click-scroll, gui-ja, gui-de, usage-card-refresh and agent-update-all pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 09:26:30 +08:00
  • 5268a3308e agent, gui: an agent whose CLI is gone while its settings are left says so, and Install another agent offers it again (evilgaoshu, #843: 卸载了 DeepSeek Harness,但 ~/.dsh 还在,Agents 页面依然把它当作已安装列出来,也不会出现在 Install another agent 里) — an agent was here when its config or folder was, so dsh, uninstalled with ~/.dsh kept, was listed as installed, and Install another agent left out every agent listed. Agent.CLIMissing: its folder or config is here, its CLI isn't, neither on PATH nor where users' tools go (proc.FindTool, as #839's Claude Code is found on Windows); only for an agent that is its CLI and has an install command magpie knows, not one whose folder an app or editor extension keeps too (Codex, Claude Code, Gemini CLI, OpenCode, Cline, Goose), nor a WSL one. Its row stays, settings kept and nothing deleted, with "CLI not found" where its version goes (its tooltip names the folder and points to the install command), and Install another agent lists it, marked "CLI not found" under its name. dsh now has its npm package, @deepseek-ai/dsh, so it is offered with npm install -g @deepseek-ai/dsh, and its version and updates show like the other CLIs'. zh, ja, de strings. TestCLIMissing (dsh with ~/.dsh and no dsh is missing and offered; codex's folder, an agent not here, a WSL one aren't; dsh in ~/.local/bin off PATH isn't) fails on the old code; agent-cli-missing.test.cjs (WebKit, en and zh: the row's note, its height kept, Install another agent lists it with its command) fails on the old code. agent-update-all, agent-layout, agent-start-pick, click-scroll, gui-ja, gui-de and import-row pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 09:25:01 +08:00
  • 37f2a2851f gui: a Usage card has a refresh of its own, left of its "Updated" time, that reads that card alone (Hu9956, #840: 在更新时间左侧加一个刷新按钮,鼠标悬停在套餐卡片上时显示,可以单独刷新某个套餐的用量,不用刷新全部) — only the page's Refresh read the allowances again, every card at once. Each card now has a ↻ that opens left of "Updated 3 min ago" (or of a failed reading's reason, or under a balance) as the card is hovered; at rest the line starts where the card's others do. A click POSTs /api/usage/quotas/refresh?provider=&user=: provider.RefreshUsage reads that subscription account, plan key or balance key again (a Claude account by running Claude Code's own /usage, as the page's Refresh does) and puts it in place in the caches, the other cards not asked and kept as they were read; the button turns while it reads. zh, ja, de strings. TestRefreshOneCard (two keys of one relay and another provider: a refresh asks that key alone, the others keep their figures) and the plugin case in TestPluginUsage (one account of three read) fail on the old code; usage-card-refresh.test.cjs (WebKit, en and zh: aligned at rest, left of the time when hovered, a click reads that card alone, turns meanwhile, doesn't scroll; a failed card's own button) fails on the old code. usage-quota-head, usage-checkin, click-scroll, quota-read-at, balance-parts, claude-usage-asked, gui-ja and gui-de pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 08:59:41 +08:00
  • 1b025b3fad gateway: ClinePass's DeepSeek models can be pinned to DeepSeek's own API (White Immortal on Discord: clinepass 针对deepseek的模型能否提供一键钉住deepseek官方上游) — Cline's AI gateway serves a model from whichever host it picks, so a DeepSeek model's prompt cache was hit or missed by chance. A Cline provider's editor now has Upstream: DeepSeek models only from DeepSeek's own API (provider.PinUpstream, off by default; zh, ja, de strings); on, every Chat request to it for a DeepSeek model (cline-pass/deepseek-…, not Cline's free ones) carries providerOptions.gateway.only ["deepseek"], as ClinePass + ProviderPin sets it (linux.do/t/topic/2918145), added at the body's end so the cached prefix doesn't change, also when built from a Messages or Responses request. A body naming providerOptions itself goes as sent. TestClinePinsDeepSeek fails on the old code (no providerOptions on chat, messages, responses); clinepass-pin.test.cjs (WebKit, en and zh). provider-price-rate and click-scroll pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. Not tried with a real ClinePass key (none on this machine). yetone 2026-10-05 08:58:47 +08:00
  • 3ec6b4da27 gateway, gui: a provider's keys can be routed by weight, a key weighing 3 taking three requests for every one a key weighing 1 takes (dengtongcai, #841) — Routing already spread requests over a provider's keys in order, in turn, least used first or by pace, but never in a set proportion: two team keys meant to split 75/25 could only go evenly or one after the other. Routing now has By weight (routing "weight") for a provider with keys: each key that's on shows its weight and its share beside it in the editor (Weight 3 · 75%), a click edits it in place and posts keys/weight (provider.SetKeyWeight, 1 to 1000; none or 0 counts as 1, kept out of the file), and providers.json takes it as "weight" on each of keys (keyWeight for the first). The gateway picks as NGINX's smooth weighted round robin does (weighted.go): 3, 1 and 4 go round in every 8 requests in that ratio, never bunched; the others follow in their order for failover. A key resting after a failure is left out of the round while it rests, the others taking its share by their weights, and goes last. A conversation still stays with its key as Stays says (cache-warm across turns by default, within a turn always), and a request kept so is counted against the key that took it, not the one the round picked, so new conversations make up the share; Stays Off gives the ratio request by request. The weight goes with its key through Make first, the editor's Save, backups and WebDAV sync. The Routing page offers By weight for key pools and explains a pick by it; sink (Goes to the back) is off for it as for In turn. zh, ja, de strings. TestWeightedKeys (3:1:4 exact in each of 50 rounds of 8 through perKey and route; with one resting the other two 75/25 and the resting one last; a kept request made up by the next picks) and TestSetKeyWeight fail on the old code (no Weighted); key-weight.test.cjs (WebKit, en and zh: By weight shows the weights and shares, a click sets one and the shares redraw, Smart hides them, no scroll) fails on the old code (no By weight). key-import, panel-routing, routing-save, rate-limited-sink, routing-reset-deadline, account-arrange, gui-ja, gui-de and click-scroll pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 08:50:57 +08:00
  • 456f77f15e gateway: an effort raised mid-thread starts the thread again at it, only a lower one goes as an effort update (Lutra-Fs, #617) — the backend gives a configuration_update up a fraction of the reasoning the same effort at the top gets. Lutra-Fs measured it on chatgpt.com's Codex backend without magpie (gpt-6.1-sol: low / high / xhigh at the top 328 / 826 / 3350 reasoning tokens, low updated to xhigh 802); with the owner's real Codex Pro account, direct to the backend, one hard prompt, 2 samples each: low 410 / 669, xhigh 6214 / 14304, low updated to xhigh 3106 / 2070, xhigh updated to low 327 / 458. An update down reasons as the lower effort does; an update up about a quarter of what was asked. With MAGPIE_EFFORT_UPDATES=on, an effort above the thread's own now starts it again at the top (the cache lost once for each level up, as a group's auto effort loses it), and one at or below it goes as an update, keeping the cache. Compaction already starts a thread again at the effort asked, its history no longer the last one and more, which is what Codex CLI does after a compaction. TestEffortChangeKeepsTheCache fails on the old code (sent low with u:high). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 08:38:15 +08:00
  • 4660fd69f5 provider: Copilot's Auto pick is served to a Student plan, its session read as VS Code's is (infinitr0us, #256) — /auto picked gpt-5.6-luna and Copilot refused magpie the request (The requested model is not supported.) while VS Code 1.140's Copilot Chat 0.68 was served it on the same account. magpie sent Auto's Copilot-Session-Token with no X-GitHub-Api-Version, which Copilot Chat sends on every request (2026-01-09), and Copilot reads the session only with one: without it the request is a model picked by hand, which the plan is refused for the pick. The editors' sign-in now sends Copilot's API that version and Copilot Chat 0.68 / VS Code 1.140.0 as its client (copilotAPIHeaders; GitHub's own API keeps no version); /models/session's 2025-10-01 is set after them. Copilot then holds the session to its pick (Requested model not available for session for another model, or a session let go): such a session is let go and the request sent with one asked anew, not noted as a refusal. With the owner's real Copilot account (Individual): without the version, the session token was ignored (any model served with it); with it, /auto's gpt-6-luna was served on /responses with its session through ResolveAuto and Sign, and another model with that session answered 400 not available for session; claude-haiku-4.5 on chat and messages, gpt-4.1 streamed, gemini-3.8-flash and gpt-5.4-mini on responses answered 200 with the new headers, and /models lists the same models. TestCopilotAutoPickServed fails on the old code (served gpt-4.1, the fallback). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 07:55:24 +08:00
  • 73d1466ff7 gui: an agent not connected says the model it is on, or Default, on every row, and its picker lists its own models with magpie's (EZN7L2C3, #834: 这里似乎需要统一) — not connected, Claude Code's row said its model while every other agent's said Pick a model, which listed magpie's models alone, and Claude Code's list had lost the one picked. Now each such row's button says what the agent is on (GPT-5.4, or 默认 with the agent's icon) and opens the same list as when connected: Default, the agent's own models and magpie's; a magpie model picked connects the agent and starts it on it, one of its own is just set. A field that isn't a model (a provider) still offers magpie's models alone. agent-start-pick.test.cjs (WebKit, en and zh) fails on the old code (Pick a model, no own models); agent-path-same, claude-default-off, agent-leave-magpie, claude-picker-fold, claude-direct, model-rate, unlisted-models, agent-connect, agent-field-names, pi-default-note, click-scroll, desktop-model-menu, model-pick, favorite-star, agent-disconnect, agent-layout, gui-ja, gui-de, import-row, agy-launch and subagent-effort pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 07:55:24 +08:00
  • 0b11514cf1 gui: many keys are added to a provider at once, and a key the gateway rests says why and until when on its row (361 on Discord: 密钥比较多的话,需要批量导入的话就不方便了) — a provider with several keys took them one at a time, each pasted into Add another key's field. Add another key now has Paste several, a box that takes any number of keys, one a line or separated by commas, semicolons or spaces (full-width ones too), quotes trimmed, repeats counted once, and says how many it holds; Add (or Cmd/Ctrl+Enter) posts keys/import, which adds the ones the provider hasn't got in order (the first becomes its key when it has none) and saves once, and the note says N keys added, M already there. Pasting several keys into the one key's field opens the box with them. Each key's row in the editor, when the gateway is passing it over (rate limited, out of credit, refused…), says Resting · 429 rate limited · back at 14:05, from the same rests the Routing page counts; rotation order and failover were there already (routing modes, rests). zh, ja, de strings. TestSplitKeys, TestAddKeys, TestKeysImportAndRest (no raw key in the reply) fail on the old code (don't build); key-import.test.cjs (WebKit, en and zh: the box, its count, the post, the note, a paste opening it, the rest line, no scroll on a click) fails 4 of 4 on the old assets. account-models, account-arrange, account-return and click-scroll pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestDevinSignedInOnlyInMagpie and TestClientGoneRecordedAsCanceled timed out once each under load and pass on their own). yetone 2026-10-05 07:54:05 +08:00
  • d696d8bc40 fix: 账号额度的两条读取路径共用同一份读数 (#836) FanbuzandClaude Opus 5.5 2026-10-05 07:48:23 +08:00
  • f5d777c58b fix(dsh): 保留家级模型选择并修正补丁配置继承 (#838) tsuixl 2026-10-05 07:48:17 +08:00
  • 066ecaae7d 修复 Windows MCP 连接拒绝分类并补充 CI 回归 (#805) tsuixl 2026-10-05 07:44:11 +08:00
  • 189a4b95ac 修正滚动测试的日期按钮定位与触底判断 (#807) tsuixl 2026-10-05 07:44:06 +08:00
  • 72c6b85b0d provider: Claude Code installed off magpie's PATH is found on Windows too, so its sign-in no longer says to install it (EZN7L2C3, #839) — claudeExecutable looked on PATH, then at ~/.local/bin/claude, /usr/local/bin/claude and /opt/homebrew/bin/claude; on Windows the installer's binary is ~/.local/bin/claude.exe, and a magpie started before Claude Code was installed hasn't its folder on PATH, so the Claude sign-in said "install Claude Code first" while the Agents page, which reads ~/.claude, listed it. proc.FindTool now finds a CLI as a terminal would: on PATH, in the folders users' tools go in (UserBinDirs: npm's, ~/.local/bin, bun's, volta's, pnpm's, …) as name.exe, name.cmd or name on Windows, then on the PATH the registry has now; the sign-in and the gateway's Claude runs both use it. TestClaudeFoundInLocalBin fails on the old code on Windows (built for windows/amd64 and run on the Windows 11 test box: claude ""), passes there and here; TestToolIn. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 07:42:57 +08:00
  • 372316260d provider: OpenRouter's decision models are listed with their window and image input, on the built-in OpenRouter too (ARNO on Discord: 手动添加的 systemone provider 填 openrouter,模型列表没有图像和上下文信息;默认的 openrouter provider 列表里又没有全部的 decision 模型) — three causes. A System One provider at OpenRouter whose list was fetched before v0.1.895 kept that list, without windows or input, since lists are fetched again only on Save or Refresh: FetchNew now fetches such a list again (decideListDue: on, at OpenRouter, missing or with no model's facts), once. One added with no list URL got typesafe/jev-router only, which is OpenRouter's chat router named like Jev: it now fetches OpenRouter's /models?output_modalities=decisions. And the built-in OpenRouter had no decision API at all: its preset (and a saved one, in Normalize as Zen's) gets Decide at https://openrouter.ai/api/v1, its decision list is fetched beside its chat list (kept at <id>.decisions, renamed with it), shown in its model list with context and image input (/api/providers deciders), offered to routing groups' classifier picker and asked at /systemone with the same key; Jev Router stays a chat model for agents (DecidesModel, app.js decidesModel). With the owner's real OpenRouter key in a sandbox HOME, FetchNew listed all 13 decision models with their facts (pplx-decider 262144 + images, solar-decide 524288, …) and the gateway's POST /v1/systemone with openrouter/inception/mercury-decide:free answered 200 from Inception. TestOpenRouterListsDecisionModels and TestOpenRouterDecisionListRefreshed fail on the old code ("OpenRouter has no decision API", "decision models: [typesafe/jev-router]"). system-one, gateway-systemone, gateway-decide-info, group-found-off, routing-reset-deadline pass on WebKit; group-from-model-add fails 2 the same on origin/main. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 07:24:08 +08:00
  • 60b301a9cd edit: a dotenv key set twice reads and writes its last line, as dotenv does (#832) Charan Rathore 2026-10-05 04:32:42 +05:30
  • 165fee0df5 agent: an agent's own provider named as one of magpie's isn't magpie's, in every agent that spells a model provider/model (the rest of #835) — OpenHanako's own deepseek/deepseek-v4-pro read as magpie's deepseek, and so did a model of any agent's own provider whose name magpie has a provider by: Pi's, Crush's, Hermes's, OpenCode's relay/glm-4.6 with magpie's relay had the row connected on the agent's own model, and Disconnect from magpie put that model back and left the row connected. An agent says how magpie's values are spelled in it (Spelled, replacing #835's Prefixed): magpie/<ref> for Antigravity CLI, Pi, OmO, Aside, Goose, Zed, VS Code, Crush, DeepSeek Harness, Command Code, fx, omp, Hermes, Mister Morph, Kimi Code, Empryo, MiniMax Code, Droid, Qoder, Qoder CN, Grok Build, AtomCode, Cline and OpenHanako, whose every Get spells magpie's so (a sandbox Set of magpie/relay/glm-4.6 read back as that in each); for OpenCode, MiMo Code and OpenChamber also a provider of the config's own that sends to magpie's gateway, as openCodeRef names a model there. A stopped WSL distro's agent keeps its live one's. Left as they are: Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor, Copilot, Devin (magpie's are bare refs there), Muse Code (a model with / is magpie's by design: Meta's have none), Alma (its own are providerId:model), Air (magpie's only). TestOwnProviderNamedAsMagpies (26 agents: own relay/glm-4.6 not connected, Connect, Disconnect puts it back and the row is off) fails on the old code in each; TestOpenCodeGatewayProviderIsMagpies. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 06:49:45 +08:00
  • b590edb5ef agent, gui: Claude Code taken off magpie by Default goes under Not set up and says Default (EZN7L2C3, #834 on v0.1.920) — picking Default and confirming Use default left the row up among the connected ones while it said Not connected, its model read Pick a model and its list had magpie's models alone. Default takes Claude Code's tiers and subagent model out with magpie's endpoint; Apply recorded only the field picked, so those read as changed outside magpie (replaced drift) and the drift kept the row up. Apply now records every field magpie set before that the change moves too. An agent not connected whose list has models of its own (Claude Code's, asked of Anthropic directly) now says what it is on, its Default or its own model, and lists everything as when connected: Default, its own models, magpie's. TestClaudeDefaultLeavesNoDrift (fails on the old code: drift replaced opus; a tier changed outside magpie is still said to be); claude-default-off.test.cjs (WebKit, en and zh: folded under Not set up, switch off, Default shown, Default current with the direct and via-magpie models listed, no scroll; fails on the old code: Pick a model / 选模型). agent-path-same, agent-leave-magpie, claude-picker-fold, claude-direct, agent-start-pick, model-rate, unlisted-models, agent-connect, agent-field-names, pi-default-note, click-scroll, desktop-model-menu, model-pick, favorite-star, agent-disconnect, agent-layout, gui-ja and gui-de pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 06:40:43 +08:00
  • 251ef21866 copilot: Auto falls back to gpt-4.1 first, the reply names the pick that answered, and the route says each pick's API and session token (infinitr0us, #256) — the route data from v0.1.921 showed /auto does answer a Student account: it picked gpt-5.6-luna, which Copilot refused "The requested model is not supported." magpie then went down /models in its order, but Copilot's list no longer flags any model as the chat default or fallback, nor bills any, so the order was the list's own: gpt-5.4-mini, gpt-6-luna, kimi-k3, mai-code-1.1-flash, gpt-5-mini all refused and the request failed with 400 before reaching gpt-4.1, last on the list and the one the plan is served; a second request reached it after claude-haiku-4.5. gpt-4.1 (Copilot's base model) now ranks right after a flagged fallback or default. X-Magpie-Model named mai-code-1.1-flash / claude-haiku-4.5, a refused pick: each new pick now updates it, so it ends on the one sent last. Each pick in tries[].auto now carries api (the path it went to) and session (whether Auto's Copilot-Session-Token went with it), shown on the Routing page's pick line (zh, ja, de strings), since why /auto's own pick is refused is still open: VS Code's /auto request matches magpie's. TestCopilotAutoFallsBackToBase (a Student list as the reporter's, /auto picking a refused model, only gpt-4.1 served) fails on the old code: eight refusals, X-Magpie-Model copilot/claude-haiku-4.5; routing-copilot-auto.test.cjs (WebKit, en and zh) asserts the API/session text. routing-wb-refused, routing-effort, routing-kind, routing-zcode-blocked pass on WebKit; go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 06:40:03 +08:00
  • 6fb05259d7 agent: OpenHanako's own provider named as one of magpie's isn't magpie's, so Disconnect from magpie takes it off and the row says Not connected (Hu9956, #835) — OpenHanako spells every model provider/id, its own providers' as magpie's (magpie/<ref>), and a value of its own DeepSeek, deepseek/deepseek-v4-pro, read as magpie's deepseek/deepseek-v4-pro because magpie has a provider of that name. So the row stayed 已接入 on it: Disconnect put back the model the agent had before (its own deepseek/deepseek-v4-pro), took magpie's provider out, and the row still read as connected, on and on. An agent can now say what each of magpie's values in it starts with (Prefixed, magpie/ for OpenHanako); a value without it is the agent's own, never magpie's. TestHanakoOwnProviderNamedAsMagpies (own relay/glm-4.6 with magpie's relay: not wired, Connect, Disconnect puts it back and the row is off) fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 06:35:59 +08:00
  • c65ddd988d opencode zen: big-pickle and Zen's other free models without -free in their id are asked as OpenCode asks, not only -free ones (361 on Discord: 能否修复opencode zen免费级无法使用的问题) — magpie already asked Zen's -free models as OpenCode does (streamed, tools named bash and read, a UA of opencode/1.18.34, an x-opencode-session of ses_ + 12 hex + 14 base62, the rules the reporter's picture lists), but OpenCodeFree knew a free model by its -free suffix alone, so big-pickle, free on Zen though its id doesn't say so, was relayed as the client sent it and Zen answered 403 "OpenCode's free tier can only be used from within OpenCode" (500 on Messages and Responses). A model is now free when its id ends in -free, when it is big-pickle or grok-code, or when models.dev's opencode prices it at nothing (input and output 0), so the gateway's reshaping (zenfree.go) and the Test button's probe take it too; a model models.dev prices is not touched. Through an in-process gateway under a sandbox HOME against the real opencode.ai/zen: zen/big-pickle answered 200 on Chat, Messages and Responses (streamed); on the old code 403 FreeTierError on Chat, 500 on the others. TestZenFreeZeroCostModels (big-pickle, a catalog zero-cost model, a priced one) fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn flaked once under load, passes 3/3 alone). yetone 2026-10-05 06:07:00 +08:00
  • aac5fa512b library: a skill copied into an agent where it can't be linked is copied again when the library's changes (#173) kevinandClaude Opus 5.5 2026-10-05 07:03:38 +09:00
  • 026158b0ad copilot: each Auto try in the route names the model Auto picked, where the pick came from and Copilot's refusal, and /auto's refused pick goes to the account's own model, not /models/session (infinitr0us, #256 again: on v0.1.916 a Student account's first copilot/auto requests each took two 400 "The requested model is not supported." tries before gpt-4.1 answered, and both refused tries were logged as model "auto", so neither the route nor X-Magpie-Model said whether /auto answered the account, what it picked, or whether magpie fell back to /models/session) — a try now carries auto: [{model, via, skipped, refused}], via being /auto, /models/session or fallback (the model the account may pick by hand), skipped why /auto's pick wasn't taken (its error, or the refused model it picked), refused Copilot's words; the Routing page names the try "GitHub Copilot (auto → gpt-5.3-codex)" and puts a line per pick under it (zh, ja, de strings), and the log says each pick not from /auto and each refusal. POST /auto is asked at Copilot Chat's tier, "balance", which its AutoV2Fetcher always sends. Once /auto has answered with a model the account was refused, the model it may pick by hand stands in, as Copilot Chat asks nothing else: /models/session names the same few models for every plan, which this account was refused (gpt-5.4-mini, gpt-5.3-codex). With the owner's real (Individual) Copilot account through an in-process gateway under a sandbox HOME: /auto picked gpt-6-luna at tier balance, 200, the try's auto [{gpt-6-luna /auto}]. TestCopilotAutoPicksInRoute (a fake Student plan whose /auto picks gpt-5.3-codex, refused) and routing-copilot-auto.test.cjs (WebKit, en and zh) fail on the old code; routing-wb-refused, routing-effort, routing-kind and routing-zcode-blocked pass on WebKit; go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 05:48:27 +08:00
  • da2a018d89 gui: an agent taken off magpie by a model of its own still shows that model on its row, and every agent's picker says via magpie the same way (EZN7L2C3, #834) yetone 2026-10-05 05:40:44 +08:00
  • c353f7bd3f gateway: a reply that is only a <tool_call> and DeepSeek's closing tags says nothing, and a <tool_call> wrapping DeepSeek's own invoke is the call (Dazzle-sys, #823 again: Trae CN's DeepSeek V4.1 Flash in Pi showed <tool_call> </|DSML|parameter> </|DSML|invoke> </ as its reply) — the reply (17 tokens out, the 04:23:54 Trae CN row in the request log) was the Hermes opener with no JSON in it, then DeepSeek's closes, cut short. A <tool_call> was read only for a JSON object, so the held text went to the agent as it was, and the model read it back. A <tool_call> whose content starts with a tag, or is nothing, now has its opener dropped and what follows read as it is: a DSML invoke in it is the call; held text that is tags and nothing else (a tag cut short at its end, </, too) is dropped, and the reply ends as it did (stop) when no call was in it. Text that only looks like a tag (x </tool_call> y) goes on whole. trae 0.1.13 does the same in the plugin. TestTextWrittenTagsOnly fails on the old code with the screenshot's text; go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 05:09:24 +08:00
  • 9e52a8d875 gui: a provider's models can be let out to their full height and folded back, as the Agents page's list is (Hu9956, #833: 模型选择区域可见空间太小,希望像 Agent 区域一样可以展开收起) — the editor's model chips were held in a box a few lines tall (min(132px, 28vh)) and scrolled within, so a relay with dozens of models showed a handful at a time. Under the box, when its chips don't fit, Expand the list lets them out to their full height (the editor's body scrolls instead) and Collapse the list holds them again; the choice is kept for the next editor opened, a pick doesn't fold it, a short list isn't offered it. The button goes down with what it opens (data-unrolls), so the click scrolls nothing; no border stripe. zh, ja, de strings. models-fold.test.cjs (WebKit, en and zh) fails on the old code (no button); provider-models-rest, models-free-only, editor-short-window, model-pick, provider-none-picked, provider-search, provider-draft-picks, unlisted-models, gui-ja, gui-de and click-scroll pass on WebKit (provider-levels-scroll fails the same on origin/main). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 05:05:16 +08:00
  • 8838e67732 gui tests: readable-focus passes on WebKit (#826 follow-up) — macOS WebKit has no computed userSelect (only webkitUserSelect) and doesn't Tab to buttons, so the body check read undefined and the Shift+Tab steps back to the first control never landed. The body check falls back to webkitUserSelect, and each keyboard step starts from a fresh page (a script's scroll back to the top is undone by the page keeping the reader's place). Still asserts: Tab's field stays in sight, a pointer click keeps scroll at 0, Enter and Space bring the focused field into view. Passes 4/4 on WebKit; mobile-web passes; click-scroll flakes 6/2 ↔ 8/0 the same on main. yetone 2026-10-05 04:41:14 +08:00
  • 6582aa75a5 gui: connection instructions and editor help are readable, model ids can be selected without picking their row, and keyboard focus comes into sight — the connection labels read at 3.66:1 in light mode and their help was fainter still; they, editor labels and help, settings descriptions and model descriptions use the existing fg-2 rather than changing the muted or faint palette. Gateway model descriptions, the ids in Names & levels and error or warning messages allow text selection, with a selection in a model row leaving it intact and an ordinary click still picking it. Enter and Space can focus another field while the click guard puts the page back, leaving that field out of sight; after the guard settles, a trusted keyboard action that moved focus to a different element reveals it only when needed, through scrollOnPurpose, with Tab and pointer scrolling kept as before. readable-focus tests the contrast in light and dark, mouse selection, ordinary model picks, Tab and Shift+Tab, Enter and Space, and pointer clicks staying put; its three cases fail on the old assets in Chromium and WebKit. click-scroll's date buttons are scoped to .rt-days .rt-day, retaining every scroll assertion. The new tests, click-scroll, settings-groups, gateway-model-info, phone-web and settings-shortcut pass in both engines; go test -tags nogui ./internal/gui, go vet -tags nogui ./..., go build -tags nogui, JavaScript syntax checks and git diff --check pass. (#826) XYenon 2026-10-05 04:35:28 +08:00
  • 4965117e78 gui: a provider's model says its reply limit in the Gateway's tooltip, the one agents are told (ARNO on Discord: some models' output tokens weren't in the tooltip, yet were in the config written for an agent) — the Gateway's model list took each provider model from /api/providers, whose models carried a context and no output, so its tooltip said Output only for routing groups, while agents were told the catalog's (the vendor's list's, else models.dev's, else the user's Max output, Command Code's within its 200000). Both now take provider.ReplyLimit, the one rule entryFor used; the Providers page's model JSON carries it as output and the tooltip says Output: up to N tokens. With it, trae 0.1.12 (magpie-community/plugins c172d93) no longer gives a made-up 32K for a model Trae names no max_tokens for, so models.dev's is told (DeepSeek V4.1 Flash 384K). WorkBuddy AI's glm-5.3-flash 32000 is WorkBuddy's own config's maxOutputTokens (asked with the owner's real workbuddy-ai account: glm-5.3-flash 32000, glm-5.3 48000, deepseek-v4.1-flash 128000), kept; Max output in the provider's editor sets another. TestProviderModelOutputSaid (the page's output equals Served()'s, models.dev's and the user's) fails on the old code; gateway-model-info.test.cjs asserts a model's Output line, failing on the old code; it and gateway-decide-info pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 04:33:33 +08:00
  • 2bfed7a66d edit: LF files stay LF through every editor, and CRLF files keep \r\n with no trailing break, in a multi-line TOML string, a YAML block scalar and after DelJSON (review of #829, #830, #831) — tests only. TestReviewLFUntouched and TestReviewCRLFEdges; the CRLF cases fail on the code before those PRs. yetoneandClaude Opus 5.5 2026-10-05 04:30:46 +08:00
  • 05295e5ab9 edit: keep a CRLF file's line endings when SetYAML, DelYAML and EditYAMLStrings rewrite it (#831) Charan Rathore 2026-10-05 02:00:23 +05:30
  • 6b0a44ea7d edit: keep a CRLF file's line endings when JSON members are added or replaced (#830) Charan Rathore 2026-10-05 01:59:55 +05:30
  • 0c38071c63 edit: keep a CRLF file's line endings when dotenv, TOML and top-level YAML lines are added or replaced (#829) Charan Rathore 2026-10-05 01:59:46 +05:30
  • 719a6820df gateway, copilot: Auto's pick is asked as Copilot Chat asks it, and a refused pick is made again on its own API (infinitr0us, #256) — on a Student plan copilot/auto's pick from POST /models/session (gpt-5.4-mini, gpt-5.3-codex) was refused 400 "The requested model is not supported.", and the retry with the next pick, gpt-4.1, went to the same /responses and got "model gpt-4.1 is not supported via Responses API." (1) Copilot Chat 0.69 (now in microsoft/vscode extensions/copilot, automodeService.ts / AutoV2Fetcher) no longer asks /models/session: it POSTs {capiBase}/auto with the prompt at X-GitHub-Api-Version 2026-08-01 and gets session_token, expires_at and selected_model with its supported_endpoints; /models/session answers a fixed, stale list (asked with the owner's account it still offers gpt-5.3-codex/gpt-5.4-mini while /auto picks gpt-6-luna). magpie now asks /auto first, with the last user message as the prompt, takes the pick's endpoints for its API, keeps the session at most an hour, and falls back to /models/session and then the hand-picked model as before. (2) After a refusal the retry with Auto's next pick breaks out of forward's same-API loop when that model isn't served on it, and the candidates' loop makes the request again (at most twice) on the new model's own API; a held refusal is passed on only when no retry is left. TestCopilotAutoRepickTakesItsAPI (gpt-5.3-codex refused on /responses, gpt-4.1 refused there and served on chat) fails on the old code with infinitr0us's exact error; TestCopilotAutoAsksAuto (version, prompt, token, /models/session not asked) fails with a 502. With the owner's real Copilot account in a sandbox gateway, copilot/auto on /v1/chat/completions came back 200 from gpt-6-luna, picked by /auto and sent on /responses. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 04:07:16 +08:00
  • 98b3ed5aad provider: MiniMax Code's international site is checked in daily too (ARNO on Discord: MiniMax Code 国际版能否也自动签到) — v0.1.910's check-in asked only agent.minimax.cn, for the plugin's minimax-code accounts, since the international site's wasn't known. It is the same: agent.minimax.io's page has the Daily check-in panel (signin.menu_label in its bundle), and its /minimax-cloud/api/v1/signin/status and /claim answer as the China site's do — {"error":"invalid signature"} unsigned, 401 signed with MiniMax Code's page secret and no sign-in, where a path that isn't there is a 404 page. The check-in now takes the accounts of both of the plugin's providers, minimax-code and minimax-code-global, each asked at its own site through the plugin's fetch, and keeps each apart in minimax-checkin.json (site|uid), its result shown on that site's card. TestMiniMaxGlobalCheckin (a global account claimed at its site, a China one with the same uid asked only at the China site, keys apart) fails on the old code; TestMiniMaxCheckin and TestMiniMaxClaimAlready pass. Not tried with a real international account (none here). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 04:03:15 +08:00
  • a84f1052e0 groups: several routing groups are removed at once, and the found ones removed are one folded line rather than listed (lc on Discord: 路由组可否关闭自动发现,并且可编辑批量移除,已经移除的不要显示,或者用移除组来替代,这样干净整洁,并且可以彻删) — groups could only be removed one at a time from each editor, and every found group removed stayed under the list as a chip of its own. Select, by New group, puts a box on each group's card: a click on a card picks it, the bar's box picks all or none, and Remove (a second click to confirm, Remove 2? Click again) posts groups/delete {ids}, which provider.DeleteGroups removes all or none: refused before any goes when one isn't there or a group left holds one as a member or classifier, and a group held only by another being removed goes after it. A found group removed stays removed (magpie doesn't make it again), now one line under the list, 3 found groups removed, whose app menu brings one back; with found groups off it isn't shown. magpie group rm takes several ids. Turning found groups off altogether was there already (Find groups on their own, v0.1.603). zh, ja, de strings. TestDeleteGroups, TestGroupsDeleteSeveral; group-bulk-remove.test.cjs (WebKit, en and zh: picking, the two clicks, the post, the folded line and its menu, no click moves the page), failing on the old code (the chips). group-found-off, group-arrange, group-fold, settings-groups and click-scroll pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 03:36:54 +08:00
  • bd917e7a9a site: the docs pages take the reader's language and remember the one picked, as the home page does (owner: 为啥不能自动识别用户语言以及自动记住用户上次的选择?) — / already sent a browser preferring Chinese, Japanese or German to /zh/, /ja/ or /de/ and kept the language picked in the menu (the lang cookie), but /docs/start and the other English docs pages were English for everyone and ignored the cookie. Now an English docs page (/docs/<page>, with or without .html) sends a browser whose language the docs are written in (zh, ja) to /docs/<lang>/<page>, query kept, with Vary: Accept-Language, Cookie; lang=en (picking English in the menu) keeps it English, German has no docs and stays English, a page not written in that language yet stays, and /docs/zh/… and /docs/ja/… are never moved. The test fails on the old worker. Under wrangler dev: zh-CN and lang=zh go to /docs/zh/start, intent, plugins; ja to /docs/ja/…; en and zh-CN with lang=en stay; /docs/zh/start stays for everyone. node --test worker.test.mjs passes. yetone 2026-10-05 03:33:03 +08:00
  • 878a8489f0 gateway: a plugin's model that writes its tool call into the text is answered as a built-in's is, proven (#823, Dazzle-sys: Trae CN's DeepSeek V4.1 Flash in a group ended the session in Pi) — TestPluginTextWrittenCall serves a plugin provider (trae-cn) whose Chat stream writes <tool_call>{"name":"bash",…}</|DSML|parameter></|DSML|invoke across two chunks, as the screenshot had it: a Chat client gets a tool_calls delta with the command intact and finish_reason tool_calls, an Anthropic Messages client a tool_use, neither any DSML. It fails on bbc89f9e^ (before v0.1.909's text-call reading) and passes now. The trae plugin reads these forms itself from 0.1.11. go vet and go test -tags nogui ./internal/gateway/ under a temp HOME pass. yetone 2026-10-05 03:25:31 +08:00
  • 7bfe3137bd docker: the image has bash and busybox, so a terminal in the container opens (スライム on Discord: 这2天的docker版更新后无法进入terminal模式,导致配置不了devin … exec: "/bin/bash": stat /bin/bash: no such file or directory) yetone 2026-10-05 03:23:18 +08:00
  • c377754c8f provider, gui: MiniMax Code's daily check-in (Hu9956, #811) — magpie claims each MiniMax Code (China) account's daily check-in credits once a Beijing day, as MiniMax Code's page does, the same way it does WorkBuddy's and Trae CN's. It asks GET agent.minimax.cn/minimax-cloud/api/v1/signin/status?timezone_id=Asia/Shanghai and, only while today's day is claimable (status 2), POST /claim with {}. Both go through the minimax-code plugin's fetch, which signs them in as the account. The page's x-timestamp and x-signature (md5 of ts + salt + body) go with them, though MiniMax doesn't check these now. Day status 3 (claimed) and claim_result 2 count as done; status 4 is not eligible; base_resp's code and message are the failure's reason, and an expired sign-in says sign in again. The streak is the week's day_no. Results are kept in minimax-checkin.json. The international site's check-in isn't known, so minimax-code-global accounts are left alone. The switch is in Settings › Usage › warm-up and check-in › MiniMax Code (minimaxCheckin, off by default) and on the usage card (Auto check-in, Check in now: POST /api/settings/minimax-checkin, /api/usage/minimax-checkin); the card row's vendor strings are now a table (CHECKINS). magpie checkin and the TUI also check it in. zh, ja and de strings. No real MiniMax account was at hand: TestMiniMaxCheckin and TestMiniMaxClaimAlready run against an httptest fake built from Hu9956's captured answers. The fake checks timezone_id, the signature, the GET without a body and {} on the claim. It covers claim, no second ask the same day, in already, disabled, a refusal with its reason, and expiry. They pass with -race. usage-checkin.test.cjs adds the MiniMax card (its own switch and press, Trae's untouched) and the Settings tab (WebKit, en and zh, 8/8). settings-sections, gui-ja, gui-de, click-scroll and usage-quota-head pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 03:01:35 +08:00
  • bbc89f9e2b gateway: a tool call a model wrote into its text is made the call it is, so the agent runs it and the session goes on (Dazzle-sys, #823: 报错导致会话直接中断,回复继续也是重复报错) — deep into a long session (~700k tokens in the screenshots) DeepSeek stopped calling tools and wrote them as text instead, Hermes' <tool_call>{"name":…,"arguments":…}</tool_call> or its own <|DSML|function_calls> blocks, sometimes with a raw newline in a command or stray DSML closing tags after it. pi got text, ran nothing and ended the turn; told 继续, the model copied its own text calls and it happened again. Now, when the request offered tools and the reply made no call itself, a reply whose text holds such blocks, each parseable and naming an offered tool, reaches the client as those tool calls (finish tool_calls / stop_reason tool_use), with the prose before them kept and the tags gone: on the Chat relay (textCallTidy, a line filter after the others, the marker held back across chunks) and on every translated path, streamed or not (textCallSee on the IR events). A block naming an unknown tool, one cut off, a reply with no tools offered or with a native call, and text that only looks like a tag stay as they were. With the owner's real WorkBuddy AI account in a sandbox on deepseek-v4.1-flash: native calls passed unchanged on Chat (relayed) and Messages (translated); asked to write <tool_call>{…bash…}</tool_call> as text, the client got a bash tool call {"command":"ls -la /tmp"} and finish tool_calls, twice. TestTextWrittenCallRelayed, TestTextWrittenCallWithJunkRelayed and TestTextWrittenDSMLCallTranslated (Anthropic, stream and not) fail on the old code; TestTextWrittenCallLeftAsText and TestTextWrittenCallBesideNative guard what is left alone. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 02:59:31 +08:00
  • 2a4042a94d perf: magpie opens and shows the Agents page in a fraction of the time it took (Junjie Zhou on Discord: 8 个 agent 30 个 provider … 每次我打开的时候都会很慢,要好几秒。setting 页面秒进后 我切换到 agent 就有问题) — at start, writing the agents' model lists (agent.SyncCatalog) built every provider's catalog thousands of times with nothing held, each build reading migrations.json, settings and groups again: 6000+ file reads and ~8.5s of CPU in the first 8s with the owner's 30-odd providers, all competing with the first /api/state and the Agents page. Now SyncCatalog, magpieModels and main's start-up moves run under provider.Hold, migrations, groups, settings and a provider's fetched models are held for a second like the rest, and filememo.Hold lets a GET /api/* not stat a file it confirmed unchanged within the last second (any magpie write, Changed() or a recent mtime still reads it again). A big ~/.codex/config.toml parsed in quadratic time (the TOML parser's Shape counts newlines from the start for every key): a 3 MB one took 5.4s, now 0.04s (tomlShaper). theInstalled reads through edit.Read's memo. Measured with a copy of the owner's magpie config and agent configs under a sandbox HOME, the real server in WebKit: CPU in the first 8s 8.59s → 0.39s, page up 475 → 75ms, Agents rows drawn 775 → 325ms after start; the agents' written model files are unchanged (pi byte for byte, opencode the same models). TestTOMLShaperMatchesParser, TestTOMLBigFileParsesInLinearTime (fails on the old code), TestHold (filememo), TestHoldReadsMigrationsOnce. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./... under a temp HOME pass. yetone 2026-10-05 02:59:08 +08:00
  • 399e5db63d gui, groups: a group's editor sets the context agents are told — its largest model's, its smallest model's, or one typed (Mikan on Discord: 路由组可以支持自定义上下文长短或者支持用户选择按照上下文长度最短的供应商还是上下文长度最長的供应商吗?) — a group told agents its largest member's window (#712), and another could only be set from the CLI. The group editor now has a Context row under Slow to start: Largest model's (as before), Smallest model's, or Custom with a box (200k, 1m, 128000), its hint naming the window agents will be told from the members' own, redrawn as members are added or taken off; a length that isn't one says so and isn't saved. Smallest is kept as smallest (Context -1, ContextSmallest), worked out as the members change, so the agent compacts before any member would turn a conversation away; a conversation too long for one member still goes on to one with room. magpie group set <id> context=smallest|largest|272k does the same. zh, ja, de strings. TestContextSetByUser (smallest, then smallest after a member leaves) fails on the old code; TestApplyGroupPairs covers context=. group-context.test.cjs (WebKit, en and zh): Largest by default with no box, Smallest saves -1 and reopens so, Custom starts at the smallest member's, a bad length shows its error, 300k saves 300000 and reopens, Largest saves 0. group-first-token and group-patterns get a taller window, the editor having grown under the fixed footer; they, group-arrange, fold, member-off, member-fast, rate-limited-sink, routing-compact, manual, levels, steady, time, unlisted-models and settings-groups pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 03:00:31 +08:00
  • 6159129f26 settings, library: the searcher picker says which providers it leaves out and why (#825), and Alma takes skills, in ~/.config/alma/skills (#824) yetone 2026-10-05 02:56:46 +08:00
  • e05e3886f9 gui: Cindy's row on the Agents page is laid out as the others (owner: Cindy 这个排版好奇怪啊,跟别的格格不入啊) — an app magpie is added to by a link of its own had no 「接入」 kind, so its row was drawn the old way: no line under the name, and its Add magpie button spanning both picker columns, wider than every other row's model picker and out of line with it. It is now kind "link": a line under the name says Not added · Cindy asks to add magpie when its link opens, or Added · magpie is a provider in Cindy (green dot), and its button stands where the others' model picker does, 196px and lined up with it, the switch's room kept beside it empty. zh, ja, de strings. import-row.test.cjs (Chromium and WebKit, en and zh, added or not): the line, the button lined up with Crush's picker at 960 and 700px, a click opens the link; it fails on the old code (no line). agent-layout, agent-start-pick, agent-disconnect, agy-launch, desktop-model-menu, gui-ja, gui-de and click-scroll pass on WebKit; go vet and go test -tags nogui ./internal/gui/ pass. yetone 2026-10-05 02:29:57 +08:00
  • 6f63333818 gateway: a reply says which provider and model answered it, in X-Magpie-Provider and X-Magpie-Model, and Settings › Models › Replies can have its model say magpie's provider/model id too (liuweifeng, #822) — a reply's model was only the vendor's own name (glm-5.3-flash), naming neither the provider nor the group's member, so pi, which counts usage by provider/responseModel, put every member's calls in one bucket. Every reply now carries X-Magpie-Provider (the provider id) and X-Magpie-Model (provider/model of the member that answered, after a failover the one that did), relayed or translated, streamed or not; the body is left as the vendor wrote it by default, since agents read it themselves (Claude Code its features, Codex its catalog). Name the member in replies (memberModel, off by default; zh, ja, de strings), or a request's X-Magpie-Response-Model: member, has the body's model say the member's id as well: Chat's model, Responses' response.model, Anthropic's message.model / model, Gemini's modelVersion, in each event of a stream as it goes and in a JSON body once whole (memberWriter, between the masking and the request log, which keeps the vendor's). Claude Code, Claude Desktop and Codex always get the vendor's name; X-Magpie-Response-Model: vendor asks for it too. The vendor's own name (dated versions included) stays in the usage ledger's Served. With the owner's real DeepSeek key in a sandbox, a group [a dead member, deepseek/deepseek-flash]: the headers said deepseek and deepseek/deepseek-flash on Chat, Messages and Responses, streamed and not; with member asked the body said deepseek/deepseek-flash in all six, with the setting on pi's token got it and Codex's token and a claude-cli User-Agent got deepseek-flash. TestReplyNamesMember (6 paths × streamed or not × default, on, asked, vendor asked, Codex, Claude Code, each after a failover; passes -race) fails on the old code, TestMemberLine; member-model-setting.test.cjs (WebKit, en and zh). settings-sections, settings-groups and searcher-pick pass on WebKit; redact-rule-row fails 2 the same on origin/main. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 02:23:41 +08:00
  • 558abd13ea site, omarchy: a reload shows the theme the page showed, not one magpie told before the desktop turned (owner: 在 Omarchy 下网页的确可以自动识别 Omarchy 主题切换事件了,但是一刷新又变回了默认的 Omarchy 主题) — with magpie not answering (here the VM had restarted and nothing served 127.0.0.1:3425), the page follows Omarchy only by light/dark: rose-pine set turned it to catppuccin-latte, but localStorage still held miasma, the theme magpie had last told, and a reload painted that. Now when the desktop turns to the other mode while magpie isn't answering, that stale theme is forgotten, so a reload paints what the page showed. Tried in the Omarchy VM in Chromium 152 on a copy of the owner's own profile (its loopback-network grant and storage), omarchy.js served from this change: magpie down, miasma → rose-pine turned the page to catppuccin-latte and a reload kept catppuccin-latte (it went back to miasma before); magpie up, rose-pine came through live and a reload kept rose-pine. yetone 2026-10-05 02:24:44 +08:00
  • b45b410b0c fix: discover Antigravity models across enabled accounts (#706) bocayouth 2026-10-05 02:16:28 +08:00
  • eb5edcedc7 gui: a failed check-in's reason wraps on its card rather than ending in … (#821, #808) — the Trae CN card's 签到失败,magpie 稍后重试 · <reason> was one line cut with an ellipsis, so the reason after · didn't show in the reporter's screenshot (only in the tooltip). A failed row now wraps: the reason flows onto the next lines and the Auto check-in / Check in now buttons go beside or under it. usage-quota-head.test.cjs asserts the reason isn't clipped (a long 9074 message), failing on the old CSS; it and usage-checkin.test.cjs pass on WebKit, en and zh; looked at in a screenshot. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./internal/gui/ under a temp HOME pass. yetone 2026-10-05 02:12:51 +08:00
  • 41ed1c95bc gui, provider: the request log scrolls sideways from a bar at the window's foot and a request's detail opens with its status, duration and a View routing link (mintonight, #799); a provider has a price rate its costs are counted at (ITea312, #819) — #799: the request table, wider than the window, could only be scrolled sideways from the scrollbar at its very end, below 40+ rows, so it looked like it had none; and the "status detail" the reply pointed to wasn't to be found in the row's detail. A bar (#ledHScroll) now sits at the window's foot while the table is wider than its box, scrolling with it both ways; a row's detail begins with Status (Succeeded for log rows), Duration and Routing: View routing, which opens the request's route. #819: costs were counted only at the official (list or maker) price, or a price set per model with magpie model price; a relay billing 0.8 of it had to have each model priced by hand. The provider editor (key and signed-in alike) has a Price rate field (empty for 1; 0–1000, three decimals), saved as priceRate; EffectivePrice multiplies the list/maker price by it, and a price set for a model stays as set. Usage caches key on the providers file, so the counts follow. zh, ja, de strings. ledger-hscroll.test.cjs (fails on the old code) and provider-price-rate.test.cjs (WebKit, en and zh); usage-ledger, usage-ledger-detail (updated for the new rows), usage-ledger-content, usage-ledger-chart, routing-failed-open, purpose-filter, provider-concurrency and provider-levels-save pass on WebKit. TestPriceRateScalesListPrice, TestPriceRateOK, TestPriceRateOf. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 02:03:07 +08:00
  • cd217c174b agent: Codex Desktop with WSL counts as connected when its gateway address is the one the user set for WSL, and magpie keeps that address (#816) — with Codex Desktop's "run in WSL" on, Codex runs inside WSL: the absolute Windows path magpie wrote for model_catalog_json didn't load there, and 127.0.0.1 is WSL's own loopback, not Windows'. After the user pointed openai_base_url and [model_providers.magpie] at the Windows host's address, magpie's check still said 未接入 (it asked for its own loopback URL), and a re-wire or sync would have put 127.0.0.1 back. On Windows magpie now writes model_catalog_json = "magpie-models.json", which Codex resolves against CODEX_HOME on either side (checked with Codex 0.160), and still reads the absolute path it wrote before as its own. A gateway address on a non-loopback host, on magpie's port path and with magpie's token, is taken as magpie's: Check passes, the agent is Routed, and setting a model or syncing keeps the address; a relay's address is not taken. TestCodexWSLAppAddressKept (fails on the old code with "no longer points at magpie's gateway") and TestCodexKeptGatewayOnlyMagpies. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 02:03:07 +08:00
  • c6875999b0 fix(agent): isolate Aside disconnect previews from the live daemon (#818) Junjie Zhou 2026-10-05 01:56:02 +08:00
  • 565cdf073a gui: recent calls show every kept call (#817) 2026-10-05 01:55:57 +08:00
  • 1a654afab2 library: a set of instructions added, or given text, while the one in use is empty is the one the agents read, and the page says which set they read (Fate on Discord: a shared set was made and Claude Code ticked, and ~/.claude/CLAUDE.md didn't change) — the agents switched on read only the set in use (the round button), and Fate's was the Default, which was empty, so nothing was written; ticking Claude Code said "it gets the shared instructions once there are some" while a set with text sat beside it. Now a set created, or a set given text, while the one in use is empty becomes the one in use (a set in use with text is left as it is). The Agents head says "They read {set}" (· Empty when it is), an open set not in use has a Switch the agents to this set button (it sends the text typed with it), an agent switched on while the set in use is empty and another has text says it reads the empty one and to switch, and a set added while the one in use is empty says the agents read it. zh/ja/de strings added. magpie still writes its own marked block into CLAUDE.md, keeping the user's text, and takes it out when the agent is switched off. TestInstructionSetTakesAnEmptyOnesPlace (sandbox HOME: CLAUDE.md gets the block after "# Mine", is "# Mine\n" again when off; a set in use with text is kept; emptied, the next set with text takes over) and library-instr-sets.test.cjs (WebKit, en and zh) fail on the old code; the library-*.test.cjs and gui-de pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 01:48:57 +08:00
  • c38728145b plugin: a slow reader pauses its stream instead of racing a watchdog (#812) Snowyy 2026-10-05 01:36:20 +08:00
  • eb0e5e1d00 feat: 在供应商账号行显示可用重置次数 (#813) Fanbuz 2026-10-05 01:31:25 +08:00
  • 38698270e9 fix: 在额度面板按账号显示 Codex credits 余额 (#815) Fanbuz 2026-10-05 01:31:17 +08:00
  • 3943cfa25b fix(gateway): a compaction that broke off keeps the conversation's stick (#814) TryWorld 2026-10-05 01:31:10 +08:00
  • 2f183c4cad agent: Cursor Private Inference's row picks which of magpie's models its own model picker lists, as Claude Desktop's does (mamba on Discord: 如果是以这种环境变量的方式接入的话,选不了模型在仪表盘) — its picker is the gateway's /v1/models as its key (magpie-cursor-local) is shown them, which already left out the models taken out for it (settings.HiddenModels), but its row had no way to take any out: no field of its picks among the catalog, so it had no model line or list. Agent.ListsModels marks an agent whose menu is that list; the row's line counts its models for it (agentModelCount takes the agent), and in the window and the tray panel the connected row has the Models button beside the launch square (MENU_FROM_LIST), which opens its model list to tick several at once; it says to quit and reopen it after a change. cursor-local-models.test.cjs (WebKit, en and zh, window and panel: the row's words, the button beside the launch square, a model taken out and put back posted, no scroll, no <select>) and TestCursorLocalModelLine fail on the old code; TestCursorLocalModels checks a model taken out isn't listed with its key and still is with another agent's. desktop-model-menu, cursor-local-launch and agy-launch pass on WebKit. Not tried with the real app (not installed here). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn, TestUserPath and TestClaudeSignedOut flaked in the full run, pass alone). yetone 2026-10-05 01:21:11 +08:00
  • 6ac01d2835 library: the skills picked can be put in a group of the user's own (#791, mintonight: 能不能在选择后自己创建分组呢) — with Select on (By source), the pick bar has Group…, which asks a name in the bar (Enter makes it, Escape goes back; a group there is is offered to add them to). The group is kept in library.json (skillGroups) and shown as a card of its own above the groups by source, open, its skills taken out of their sources' cards; a skill is in one group at most. The card has Rename (in place) and Ungroup, and the pick bar Ungroup for picked skills that are in one; grouping changes only how the page shows the skills, never what the agents get. A skill taken out of the library leaves its group, and an empty group goes. zh/ja/de strings added. TestSkillGroups and skill-groups.test.cjs (WebKit, en and zh: group, rename, ungroup; it fails on the old code, which has no Group…); pick-skills, skill-parts, group-skill-chips and the other library tests pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn, TestUserPath and TestClaudeSignedOut flaked under load and pass alone). yetone 2026-10-05 01:21:01 +08:00
  • d1c19131a6 provider: a decision model has its window and whether it takes images, and the Gateway list shows them with a tooltip saying what it is (ARNO on Discord: decision模型也是需要拉取正确的上下文长度以及是否支持视觉功能的,在网关的模型列表里也应该显示这些信息以及相关的tooltip) — a decision provider's list (OpenRouter's output_modalities=decisions, Vercel's) is now read for its context_length / context_window and its input modalities; a model the list says nothing of (TypeSafe's, OpenCode Zen's, Workers AI's and Bailian's presets) takes its vendor's documented values: Jev 32,000 and text, Clef and Clef Flash 65,536 and images, Bailian's decision-model-preview 65,536 and text. A gateway's Jev among its chat models has them too; its chat models are left as they were. The Gateway list's row of a decision model shows its context and image chips as other models' do, and its tooltip begins Decision model: routing groups ask it, agents never see it (zh, ja, de) in place of Reasoning levels: none known. /v1/models still leaves decision models out: agents can't use them. TestDecideModelsKnowWindowAndImages and gateway-decide-info.test.cjs (WebKit, en and zh) fail on the old code; gateway-model-info passes on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestClientGoneRecordedAsCanceled, TestProvidersAnswerWhileListsComeIn and TestClaudeSignedOut flaked under load, pass alone). yetone 2026-10-05 01:20:06 +08:00
  • 5daba301ca agent: WorkBuddy's magpie models pointed at another machine's magpie stay there through a sync (悠悠哥 on Discord: 这个问题workbuddy也会有) — as v0.1.891 did for ZCode: a sync rewrote every magpie entry in ~/.workbuddy/models.json to this machine's gateway and key, so models the user had moved to the magpie on a NAS went back to the local one. A sync now keeps the url and apiKey of a magpie entry on another machine (onAnotherMachine) for all of magpie's entries; one on this machine's loopback follows the gateway as before. TestWorkBuddyKeepsRemoteAddress fails on the old code (url http://127.0.0.1:3425/…, key magpie-workbuddy). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 01:04:07 +08:00
  • fe2603ff4f agent: Claude Code's model set back to its default puts back the endpoint and token the user had before magpie and leaves them (__jingling on X: 接入后跑 magpie claude model default,会把原来的 ANTHROPIC_BASE_URL 和 token 也删掉,之后再 default 也恢复不了,复现了两次) — the model field's default deleted every env key magpie writes, the user's own ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN among them, and forgot the stash that kept them from before magpie, so Disconnect after it had nothing to put back. It now takes magpie out as Disconnect does (its endpoint, token, tiers and window, the user's endpoint and token put back from the stash) and deletes only model; an endpoint the user set themselves, wired or not, stays, as the Agents page's default option (Claude Code · their host) says. magpie's env left at a gateway address since changed (its token) still goes. In a sandbox HOME with the release binary: settings.json with // mine, model opus, env ANTHROPIC_BASE_URL https://api.deepseek.com/anthropic and a token; magpie claude deepseek/deepseek-chat, then magpie claude model default: the comment, base URL and token back, model gone; magpie claude default after it leaves them. TestAgentModelDefaultKeepsTheEndpointBefore fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:56:43 +08:00
  • b7fef3877f agent: Cursor Private Inference's program in a .app is named as on a Mac on any system, so TestCursorLocal passes on Linux CI — the .app fallback (no Info.plist) took product.json's applicationName as Linux names it (cursor), while a .app is a Mac's bundle and its program is Cursor. The test failed on the ubuntu CI since v0.1.877 and passes now in a linux/arm64 container (it failed there on the old code). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:53:06 +08:00
  • 60b910b758 provider: the Agents page's data reads the settings and each provider's model list once per request (Junjie Zhou on Discord: the Agents page takes long to show) — a look at the agents asked settings.Load for every model of every agent (hundreds of reads of settings.json, about a fifth of /api/state's time in a profile) and catalog.Live for each model's APIs. The settings are now read through filememo (again only once the file changes) and held for the request like the catalog (heldSettings, used by VisibleTo, HiddenModels, ModelAPI, Labels), ListedAPIs holds each provider's live list, and settings.Save drops what is held. With a read-only copy of the owner's configs, a warm /api/state went from about 165 ms to about 100 ms. TestHoldReadsSettingsOnce. Check chain under a temp HOME passes. yetone 2026-10-05 00:51:57 +08:00
  • 63f83bf1e1 agent: a ZCode pointed at another machine's magpie in either of its files stays there in both (悠悠哥 on Discord: ZCode wired to the magpie on a NAS kept being switched back to the local one) — v0.1.812 kept a remote address per file only, but ZCode's own settings write provider_config.json alone, so a sync rewrote config.json to this machine's gateway and ZCode could take the provider back from it. A sync now reads magpie's provider in both files (zcodeKept): an address on another machine in either one is written to both, with its key; otherwise the gateway's. TestZCodeKeepsRemoteAddress edits each file alone to a NAS address and syncs; it fails on the old code (config http://127.0.0.1:3425, rules the NAS). Check chain under a temp HOME passes. yetone 2026-10-05 00:51:57 +08:00
  • 09a65410c3 i18n: German for the setting names #810 shows in an agent's opened row (standard, deep, visual, image), so gui-de's parity check passes again — gui-de.test.cjs and agent-field-names.test.cjs pass on WebKit yetone 2026-10-05 00:43:14 +08:00
  • 3f76105b33 gui: the Usage page's allowances head stays while the page loads again, and a failed check-in says why in its row (#809, #808, Hu9956: 用量界面红框这行会延迟几秒才会出现 — 点到其他界面比如Agent,再点回用量界面就能复现; TraeCN自动签到失效) — renderUsageLoading hid every .row-head on the Usage page, #quotaHead (Allowances, Trend, accounts masked, Used/Left) among them, while renderQuotas had just drawn it over the cards it heads; it came back only once /api/usage answered, seconds later, and a period with no calls hid it for good (renderUsage set every head to hidden=empty). Both loops now leave #quotaHead to renderQuotas. A failed WorkBuddy or Trae CN check-in kept its reason in the row's tooltip only, so the card read just 签到失败,magpie 稍后重试; the reason now follows it in the row (· code 9074: …). Trae CN's own fix is the plugin's: trae 0.1.9 (magpie-community/plugins 64c9e6c) sends the check-in as 0.1.6 did, which worked for the reporter before 0.1.7. usage-quota-head.test.cjs (WebKit, en and zh: the head stays visible through a slow reload and a period with no calls, a failed check-in shows its reason) fails on the old code; the usage-*.test.cjs and quota*.test.cjs pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:43:07 +08:00
  • d0fb1b6fee gui: name every setting in a connected agent's opened row (X: Aside's four roles and its picture model all read "default" under one logo) (#810) Junjie Zhou 2026-10-05 00:42:45 +08:00
  • 50686784bc appdir: reject tilde paths that readers do not expand (#803) Zhizhen He 2026-10-05 00:42:29 +08:00
  • 38cf469fb2 i18n: German for the strings main added after #770 (#806) tobitege 2026-10-04 18:42:22 +02:00
  • 9761248de3 agent: dsh's home patch layer, ~/.dsh/cordis.patch.yml, gets magpie's route and start model when it overrides the profiles' (#804, liuweifeng) — dsh applies $DSH_HOME/cordis.patch.yml over every profile's own, so a llm-pi-ai or agent-default-model entry there replaced what magpie wrote in profiles/*/cordis.patch.yml, and dsh ran the home layer's old snapshot while magpie read as connected. When the home layer has a llm-pi-ai entry, magpie's route is written in it beside the user's routes (a sync, a model picked, the 30 s round, and taken out on Disconnect); when it has an agent-default-model, the model and effort magpie set go there (the user's one stashed and put back when magpie's goes). A home layer without those entries is left as it is. Reading goes by the home layer too (the model and effort shown, Joined, the checks), and Check says when the home layer's llm-pi-ai lacks magpie's route. TestDshHomePatchLayer and TestDshHomePatchLayerUnwire fail on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn and TestUserPath flaked, pass alone). yetone 2026-10-05 00:39:40 +08:00
  • 3ffc99ef60 codex: a call id longer than 64 characters goes as one the backend takes on Codex's own ChatGPT sign-in too, and tool_search ids with it (#732, congee949) — #732 bounded them where magpie writes the request (codexBody: Chat and Anthropic clients on a Codex model, Codex App with spare accounts), but Codex on one ChatGPT account is relayed as it came (codexUpstream), so a conversation with a foreign provider's tool calls (two ids joined, 86 or 87 characters) still got 400 "input[7].call_id … maximum length 64" there: 30 in a week in the report, 29 of them thread_description on gpt-6-luna, on v0.1.869. The relay now gives every call_id over 64 characters as provider.BoundCallID has it (the sha256 of the trimmed id, so a call and its output, paired by the trimmed id, get the same one on every request), the rest of the request byte for byte; codexBody uses the same helper and covers tool_search_call / tool_search_output as well. TestCodexRelayBoundsLongCallIDs (single-account relay: function and tool_search ids bounded, paired and stable across requests, a 64-character id kept) fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:31:36 +08:00
  • 6a67774a99 fix(codex): bound foreign tool call IDs and preserve result pairing (#732) congee949 2026-10-05 00:31:19 +08:00
  • 987ce3d1b0 codex: a memory call on a model of Codex's own goes where Codex's turns go, rather than a 404 (#742, congee949) — Codex writes and consolidates its memories on models of its own by their bare names (memories.extract_model and consolidation_model, gpt-5.6-luna and gpt-5.6-terra by default) whatever it is set to, so with magpie as its provider every memory_consolidation call was turned away as "magpie knows no model" before it was routed (28 in a week in the report, from Codex on two other computers with their own gateway keys, where the stand-in read from this computer's ~/.codex/config.toml can't reach). A Codex memory call (memory_consolidation, memgen, memory) on a model magpie can't resolve now goes to the model the same Codex (the agent and the gateway key it came with) last had a turn of its own answered on here, else the last such turn in the ledger a week back (so after a restart too), and is routed and recorded as the memory call it is. Any other call on an unknown model, and a memory call from a Codex with no turn answered, is turned away as before. Base instructions are untouched. TestCodexMemoryCallsGoWhereItsTurnsGo (terra and luna after a turn, after a restart from the ledger, unknown turn and review still 404) fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:25:05 +08:00
  • f77ef6106e agent: Cursor Private Inference is connected by its row's switch, as other agents are, with no command to run (mamba on Discord: 这个单独搞个启动命令和别的供应商格格不入啊) — its Open configuration's base URL and key are kept in the state.vscdb regular Cursor shares, and are regular Cursor's own override settings too, so magpie still writes nothing of Cursor's. It sets CURSOR_LOCAL_AGENT_BASE_URL (<gateway>/v1) and CURSOR_LOCAL_AGENT_API_KEY (magpie-cursor-local), which only this build reads, for the user: launchctl setenv on the Mac (apps opened from the Dock or Finder from then on have them), HKCU\Environment plus a WM_SETTINGCHANGE on Windows, ~/.config/environment.d/magpie-cursor-local.conf (from the next login) and systemctl --user set-environment on Linux; switched off, it clears them. magpie notes it in cursor-local.env in its config folder, which the row reads as connected, and sets them again whenever it serves the gateway (launchd forgets them at a restart; the port may have changed). The row has the provider field (magpie) and the connect switch; connecting says to quit the app and open it again, and that a base URL in Open configuration still comes first. The launch command stays as the square beside it, for a start from a shell. TestCursorLocalConnects (connect sets them, a serve sets them again, disconnect clears them, off a serve sets nothing) fails on the old code; cursor-local-launch.test.cjs now checks the switch connects it with no command copied (WebKit, en and zh); agy-launch passes. Not tried with the real app (not installed here), and launchctl/the registry are not touched under tests. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:18:19 +08:00
  • 5f5f745fff usage: a Codex account in brief has its Auto-use switch beside its name, not only words (#801, ezdemo: 更新最新版后,似乎自动使用重置卡的开关的入口找不到了) — with several Codex accounts the one shown in full is the one last served, so the account whose week ran out, the one holding resets, is in brief, and in brief it only said "↺ 2 · Auto-use: off": the switch was a fold away, and nothing said so. Its brief row now reads "↺ 2 · Auto-use" (zh 自动用卡, ja 自動使用, de Automatisch) with the same small switch as the full card's (role=switch, aria-label Auto-use resets, posts settings/codex-auto-reset); the full card's row is unchanged. codex-auto-reset.test.cjs (WebKit, en and zh) turns it on from the brief row, sees it on in full, turns it off there and sees it off back in brief; it fails on the old code. Looked at in light (zh) and dark (en). go vet, builds and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-05 00:16:35 +08:00
  • 914abab3fc library: on this computer, skills whose names start alike are a part of their own wherever they sit, and a few of them among many are too (#791, mintonight: 没有看到自动分组 after v0.1.867) — the local group's parts were by folder first, so lark-* in ~/.agents/skills beside skills in ~/.claude/skills were only part of the ~/.agents/skills part, and a start shared by under a fifth of the skills (5 lark-* among 47) was dropped as one small part and the rest. The local group's parts now go by the start of the names first (a start three or more share, as before), and the rest by folder when they sit in more than one, else under Others; a repository's parts are as they were (its folders are its author's own grouping), less the under-a-fifth rule. skill-parts.test.cjs (WebKit, en and zh: lark / ~/.agents/skills / ~/.claude/skills, and lark 3 / Others 36) fails on the old code; pick-skills and list-sort pass. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestSavedButSignedOutClaudeServed flaked once, passes alone). yetone 2026-10-05 00:16:34 +08:00
  • 6892a28685 quota: each allowance says when it was read, a cached one keeps its own time, and magpie quota history tells the windows' readings over time (#802, margbug01) — a subscription's card had no time unless its reading had failed, and a Claude account's allowance, which is what Claude Code last told (kept until it answers again or runs /usage), was shown on every refresh as if just read and written into the history again at each one's time. A reading now carries ReadAt: the time it was made (readNow, for every subscription and account read), and a Claude account's the time Claude Code told it (claudeReadAt). The usage card says "Updated 40 minutes ago" from it, a reading standing in for a failed one still says "As of …" in amber, a failed one says neither. The history (#651) keeps a point at its ReadAt, so a reading shown again is no new point. magpie quota and magpie accounts add "read 40m ago" to a line read more than 2 minutes before, and --json and GET /v1/magpie/quotas carry readAt. magpie quota history [<provider|account>…] [--days N] [--json] tells each account's windows over time (UTC, kept 45 days, a point only where it changed, the runs of a window apart by their reset), the last eight a window in text with ↻ where it started again, every one with --json, as GET /v1/magpie/quotas/history answers. On the card, hovering a window's key under the curve lists its latest readings with their times; no control is added to the card (the curves are kept uncluttered). Strings in zh, ja, de. Request-log correlation between readings isn't attempted. TestClaudeKeptReadingKeepsItsTime (a kept Claude reading shown three times ten minutes apart is one point at its own time; fails on the old code), TestQuotaHistoryCmd, and quota-read-at.test.cjs (WebKit, en and zh; fails on the old code). quota history run against a copy of the owner's real quota-history.json lists their Claude, Codex, Command Code, Copilot, Cursor and Devin windows. quota-curve, quota-pools, quota-families, quota-credits, quota-count-wrap, claude-usage-asked, panel-usage and balance-* pass on WebKit. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn, TestUserPath, TestClaudeSignedOut and TestCursorSignInJoinsAWrappedLink failed under load and pass alone). yetone 2026-10-05 00:14:19 +08:00
  • 6dd0079b86 fix(routing): group Codex image title requests with their chats (#797) Zhu Wang 2026-10-05 00:14:23 +08:00
  • 687fb675a4 icons: From the website takes a new-api or one-api relay's own logo from /api/status, and one with none gets the provider's first letters on a tile (wiixdede on X: 从网站获取 favicon,new-api 中转站拿到的都是 newapi 默认图标,js 运行后才有网站独特的 favicon,多个供应商在首页选模型时不好分辨,或许可以改成首字或前两个字母) — such a panel's page names no icon (or its own /logo.png), its /favicon.ico is the panel's, the same on every relay, and its script sets the tab's icon from /api/status's logo. A site whose /api/status answers as a panel (success, data.system_name) now has that logo looked at first, then an icon its page was given by hand, never the panel's /favicon.ico or /logo.png; a panel with neither gets a tile with the provider's name's letters (FR for Foo Relay, Ak for akash, 中 for 中转站; the panel's name when the editor's is empty and it isn't New API or One API, else the domain's), its colour picked by the name. Other sites are looked at as before. Against real sites: one.ocoolai.com and api.xty.app gave their own logos (from /api/status), api.gpt.ge (logo "svg", junk) its page's own favicon.svg, api.deepseek.com its favicon.ico as before; the tiles drawn by WebKit read FR, 中, Ak. TestFavicon's panel cases fail on the old code (the panel's own icon was kept). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestProvidersAnswerWhileListsComeIn and TestUserPath flaked under load, pass alone). yetone 2026-10-05 00:13:51 +08:00
  • 531dc0aa33 claude: a Claude model runs to its own window in Claude Code, not 272K, and magpie model compact on|off is the Long conversations switch from the terminal (Max on Discord: a [1m] model's context stopped at 272K, magpie wrote CLAUDE_CODE_AUTO_COMPACT_WINDOW back when it was taken out, and there seemed to be no way to change it) — on magpie, Claude Code was told CLAUDE_CODE_AUTO_COMPACT_WINDOW=272000 whatever its model, so a [1m] Claude model compacted at 272K, though Anthropic runs it to 1M (the cap was meant for other vendors' long windows: Chen's DeepSeek turns of ~550K). Now a main model that is one of Anthropic's Claude models, from whichever provider, has the env left out (magpie's own value taken away), and Claude Code compacts at the model's own window; another vendor's model of a longer window keeps the 272K cap unless Settings → Long conversations is on Full window. A value the user writes there is still kept. The switch was only in the app's Settings; magpie model compact [on|off] (alias full-context) shows and sets it, and the Settings row's description says how Claude models are treated (en, zh, ja, de). TestClaudeCompactWindow (a Claude [1m] model gets no 272000, set and synced; another vendor's after it is capped again) and TestModelCompactCmd fail on the old code. The Long conversations row read right in WebKit, en and zh. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestClaudeFailureKeepsClaudeCodesStatus flaked once under load, passes alone). yetone 2026-10-05 00:09:41 +08:00
  • b93cc1623a fix: 显示 Codex OAuth 账号的 credits 余额 (#800) Fanbuz 2026-10-05 00:05:55 +08:00
  • e8eb8005f3 gui: one magpie at a time on the Mac, so one started at login twice (its own open at login and a Login Item the user added, or the Mac reopening it after a shutdown it wasn't quit for) ends instead of putting a second bird in the menu bar (Crispin on Discord) — Wails has no single instance on the Mac, and magpie's LaunchAgent runs the binary itself, past the Mac's one-copy-of-an-app, so both starts ran: the second found the gateway served and only watched it, with its own tray icon. A magpie now takes a flock in its config dir, keyed by the config dir and its resolved executable (a sandboxed HOME, and a copy elsewhere such as the owner's magpie-dev, each run on their own); a second one that finds it held ends: a start at login quietly, one for the window or the panel opens the .app, which has the running magpie show its window (the Dock's reopen; at most once in 10 s, so it can't go on), and a magpie:// link is opened, which the Mac hands to the running one. The system lets a flock go when its holder ends however it ends, so a shutdown leaves nothing held behind. Restart to update relaunches only once the old process has gone, so it is unaffected. TestOneMagpieAtATime (a second process holds the lock, this one is refused, the holder is killed, the lock is free) fails on the old code. Two GUI launches on the real Mac weren't tried, since a GUI magpie registers its magpie:// handler with the system. go vet, builds (darwin gui and nogui, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:43:31 +08:00
  • 05596ef4e2 davsync: scope provider and library credentials during partial sync (#744) TryWorld 2026-10-04 23:42:12 +08:00
  • 258eae592d agent: Cursor Private Inference, which magpie finds by its product.json and starts on magpie with a command its row copies, and whose /models gives each model's api_types and capabilities (#299, mamba on Discord) — the build (Cursor 3.23.x, the same app name, bundle id and ~/.cursor as Cursor) runs its agent locally and asks the endpoint in CURSOR_LOCAL_AGENT_BASE_URL / CURSOR_LOCAL_AGENT_API_KEY when its Open configuration has none; mamba confirmed it works with any account pointed at magpie. magpie writes nothing of Cursor's (its settings share Cursor's state.vscdb): the Agents page lists it when an app's product.json says "Cursor Private Inference" (/Applications, ~/Applications; %LOCALAPPDATA%\Programs on Windows; /opt and the like on Linux), and its row's one control, Copy launch command (复制启动命令), copies CURSOR_LOCAL_AGENT_BASE_URL=<gateway>/v1 CURSOR_LOCAL_AGENT_API_KEY=magpie-cursor-local '<app>' (PowerShell on Windows); in the tray panel the row copies it. Its notice says to quit it first (a second start hands over to the running one) and that a base URL in Open configuration comes first. /v1/models asked with its key gives each model api_types (the APIs its provider serves it on, all three for a group or a translated one; it asks Anthropic Messages only when no OpenAI one is listed) and capabilities (context_length, max_output_tokens, supports_vision); any other client's list is unchanged. usage.AgentOf matches a name before a UA prefix, so cursor-local isn't counted as Cursor. TestCursorLocal, TestCursorLocalModels and cursor-local-launch.test.cjs (WebKit, en and zh) fail on the old code; agy-launch and agent-* GUI tests pass on WebKit. Not tried with the real app (not installed here). go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:38:10 +08:00
  • 80441c2c29 gui: a provider's editor has a Max output beside its Context window, so a model whose reply limit magpie has wrong can be set right there (ARNO on Discord: 上下文长度有问题还可以手动覆盖,maxtoken错了如何解决呢) — the reply limits the user sets (ModelOutputs, "provider/model" or "provider/*") could only be set with magpie model output; the editor now shows them in a Max output box written as the Context window box is (32k for all its models, or gpt-6=128k, comma separated), and a Save sends them: the limits not in the box are dropped, a model the provider doesn't list is refused, and the catalog is touched so /v1/models, the agents' max tokens and the gateway's per-member clamp take the new limit. zh and ja strings added. TestModelOutputsSetFromTheEditor, TestProviderSaveOutputs and provider-max-output.test.cjs (WebKit, en and zh) fail on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass (TestClientGoneRecordedAsCanceled flaked once under load, passes alone). yetone 2026-10-04 23:37:06 +08:00
  • 3f5cd1f3cc tray: the Mac's menu bar icon can be Command-dragged again, so Hidden Bar and the like can move it (#792, BennettChina: after v0.1.865 a Command-click no longer opened the panel, but the icon still didn't move) — magpie's own monitor of mouse-downs on the icon (#629, which keeps it from flickering) took every left click on it and handed it to the action, so the button never saw a Command-held mouse-down, and that is what starts the system's drag. One with Command held is now left to the button. On this Mac (macOS 26.2) with a GUI build in a sandbox HOME: a synthetic Command-drag of its icon 60 px right did nothing on origin/main and swapped it with its neighbour with the change; the same drag moved a bare NSStatusItem, and one set up as Wails does (sendActionOn mouse-down, its local monitor) in both cases; a plain click still opened and closed the panel. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows), go test ./internal/gui/ and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:37:03 +08:00
  • 21702d01ff Add German translation; harden paths against unset env vars (#770) tobitege 2026-10-04 17:30:56 +02:00
  • 689b819294 budget: keep reservations in their original window (#796) Zhizhen He 2026-10-04 23:30:42 +08:00
  • c1f919ca09 fix(routing): simplify the request purpose filter (#795) Zhu Wang 2026-10-04 23:30:01 +08:00
  • 0e7a1f6b6a cli: magpie <agent> default takes magpie out and puts back what the agent had before, as the Agents page's Disconnect does (__jingling on X: magpie claude default took the model they had set away with magpie's) — the agent-wide default set its first field to the agent's own default, which for Claude Code is Claude Code as installed: settings.json's model was deleted with magpie's endpoint and tiers, so a user on opus before magpie was left on no model at all. On an agent magpie is wired into it now runs Disconnect (Unwire, then each field magpie set back to its default), which puts back the model, endpoint and token stashed when magpie was wired in; Codex goes back to its own model the same way. magpie <agent> <field> default is as it was, the field to the agent's own default. The README and usemagpie.ai said under 15 MB for the desktop app and 7 MB for the terminal build; v0.1.869's are 27–30 MB (CLI) and 31–35 MB (desktop on Linux and Windows), a 13–16 MB download on a Mac, and say so now (en, zh, ja). In a sandbox HOME: settings.json with // mine, model opus and theme dark, magpie claude deepseek/deepseek-chat, then magpie claude default: model opus back, the env cleared, the comment and theme kept (on origin/main: no model). TestAgentDefaultPutsBackTheModelBefore fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:25:00 +08:00
  • 0fd1c5c8f5 agent: an omp in WSL has its version asked in the distro, so its models offer max from 16.4.0 (whqtian on Discord: a WSL omp still had max made xhigh) — the omp there isn't the one on Windows' PATH, so its version wasn't known and was taken for an older omp's, whose models.yml refuses max. The distro's probe now asks the distro's own omp (not one on Windows' drives) its --version, with a 10 s timeout, and the WSL omp's entry is built for that version; one that says none is taken for an older omp as before. The version is kept with the distro's other probe results, and asked again when the distro is next started. TestWSLOmpVersionProbed; the probe script run under sh with a fake omp printed ver:omp omp/16.5.1. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:24:02 +08:00
  • 7909de22ac usage: magpie usage and the TUI's Usage page show the agents' own calls, read from their session files, beside the gateway's, and a Codex-based client's calls aren't counted twice (Kumo31 on Discord: Codex used directly, not through magpie, was on the window's Usage tab but not in magpie usage) — magpie usage and the TUI only ever summed the gateway's log (usage.Summarize); the calls the agents' session files record that the gateway never saw (Codex on the user's own ChatGPT sign-in, Claude Code, Claude Desktop…) were merged only into the ledger the window's Requests tab and the tray panel read (#239). usage.Direct sums those rows of the ledger (Source "log", this computer's, rejected ones left out) by agent, model, account and session, priced as the ledger prices them, and magpie usage prints them after the gateway's tables under "not through magpie · the agents' own requests, read from their session files" (a model whose provider the file doesn't tell reads "local session/<model>"); the TUI's Usage page shows the same block under the gateway's, each with its totals and agents' and models' tables. The two parts are separate, so nothing is counted in both; a period with only the agents' own calls shows them under "no calls through magpie". All of magpie usage's output now goes to the writer it is given. Checking it against the owner's real data showed the ledger counted a Codex-based client's calls twice: miyi-helper's requests through the gateway are logged under its own name while its Codex session file names Codex, and the gateway/session-file matcher keyed on the agent, so they never matched; the matcher now keys on the session, tokens and time alone (a session id names one conversation), which also corrects the Requests tab. With read-only copies of the owner's ~/.config/magpie and four days of ~/.codex/sessions in a sandbox HOME: magpie usage week printed 177 calls not through magpie, in 1.3M, out 52.4K, cache read 3.9M, gpt-6-astra 154 and gpt-6-sol 23 — the same rows, to the token, as usage.LedgerOf (what /api/usage/requests serves) gave for the period; before the matcher fix, today's 7 miyi-helper calls showed in both parts. TestDirectCountsOnlySessionFileCalls (the miyi-helper case included), TestUsageShowsCallsNotThroughMagpie and TestUsagePageShowsCallsNotThroughMagpie fail on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 23:03:12 +08:00
  • 2f5ff69d3d gui: the Gateway page's Connect speaks System One too, with a decision model (ARNO on Discord: gateway添加system one api 有想法吗) — magpie's gateway has served POST /v1/systemone, but Connect showed only OpenAI, Responses, Anthropic and Gemini, so nothing on the page said so or how to ask it. Connect has a System One tab: base …/v1, curl, Python (requests) and Node (fetch) snippets that POST …/v1/systemone with Authorization: Bearer, a state and a choice question, printing the answer's choice and confidence; the note says Clef also reads images ("images": [data URLs]). No SDK speaks it, so it has no Shell tab, and the base URL and key hints say where the request goes and how the key is sent instead of naming env variables. Its model is a decision model only (decidesModel: a decision-only provider's, or a Jev), and the other tabs no longer take one; a click on a decision model in the list switches Connect to System One, a click on any other model back to OpenAI, each tab keeping its own pick (magpie.decideModel). The head says five APIs; Connect's tab strips scroll in themselves on a narrow window, as the region strip does, rather than widening the card. zh and ja strings. gateway-systemone.test.cjs (WebKit, en and zh, light and dark) fails on the old code; gateway-connect-keys, -model-info, -fold, -older, -caller-keys, -key-limit and gui-ja pass on WebKit; Chromium doesn't launch in this sandbox. The snippet's request, sent to the gateway's handler, reached a Workers AI Jev and Clef in their own shapes, and with the owner's real TypeSafe key in a sandbox HOME, jev-latest answered 200 with choice billing, confidence 0.55. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass. yetone 2026-10-04 22:59:16 +08:00
  • 26706c3371 library: skills are picked to turn on or off together, and a part of a list (lark-*) has its own chips (#791, mintonight: 资源库中local中的技能,能不能支持多选分组,或者支持多选来开启或关闭 … lark-* 我希望把他们归到一起统一来管理) — the skills on this computer are one list with no heading when they're all from there, so #787's group chips never showed for them, and Feishu's lark-* skills were turned on or off one row at a time. A part of a big list (its skills' shared name start, or their folder) now has chips on its heading, as a repository's heading does: lit when an agent has them all, half lit when it has some, a click gives it every one or takes them all, All does it for every agent; a click doesn't fold the part. Select, beside Turn all on, puts a box on every skill's row and on every heading (ticked when all under it are picked, half with some), a row's click picks it instead of opening its SKILL.md, and a bar that stays in view under the list says how many are picked, has a box for every skill the filter shows ("All 4 that match"), the same chips for the picked ones, Clear and Done; the picks stay through a change and Done takes the boxes away. A pick doesn't scroll the page. zh and ja strings added. pick-skills.test.cjs (WebKit, en and zh): the lark part's Codex chip posts the four lark skills, rows and headings pick, the bar's chips post the picked ones, the filter's All picks what it shows, Done ends it; it fails on the old code. Looked at in light and dark. group-skill-chips, every-skill, library-all, library-items, library-toggle-status, library-row-open-scroll, own-skill, remove-all-skills, shared-skills, import-all-skills, library-own-folder and library-loading pass on WebKit; Chromium doesn't launch in this sandbox. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./internal/gui/ under a temp HOME pass. yetone 2026-10-04 22:51:27 +08:00
  • e8cd4bac8c fix: 透传 Claude 订阅审批上下文与服务端结果 (#794) AaronYiandyizhuolin 2026-10-04 07:51:45 -07:00
  • 7df9345903 routing: a group tells agents the longest reply a member of it gives, and each member is asked for no more than its own (ARNO on Discord: 发现group 模型的maxTokens是按照最小的来设定的,导致agent经常跑一半发生错误 "Response was truncated before completion.") yetone 2026-10-04 22:48:01 +08:00
  • 3cdb7fb3a5 gui: a Command-click on the Mac's menu bar icon is left to the system, which drags the icon with it (#792, BennettChina) — Hidden Bar's users move icons with Command-drag, and magpie's icon opened its panel instead. The tray's click handler now reads the held modifiers ([NSEvent modifierFlags]) and does nothing when Command is down; other systems are unchanged. go vet, builds (darwin with the GUI, GOOS=linux nogui, GOOS=windows) and go test -tags nogui ./internal/gui/ under a temp HOME pass; the drag itself wasn't exercised here (it would move icons in the owner's live menu bar). yetone 2026-10-04 22:45:25 +08:00
  • 28a830fc5c aside: magpie picks Aside's model, its thinking level, its four task models and its picture model (#789) Junjie Zhou 2026-10-04 22:45:16 +08:00