63b131c1d7
tray: a reset next week shows its date, and the panel keeps one height across its tabs (#181: 重置次数那个地方现在是固定显示周一,但实际不是本周一; #124: 从方案切换到用量,一下子面板就变大了) — a reset time or reset credit's expiry within 7 days showed a bare weekday, so on a Tuesday next Monday read as this week's; now a weekday is shown only for later this week (Monday to Sunday), else the date (10月5日 12:21). The tray panel was as tall as the tab showing; it is now as tall as its tallest tab (capped as before), so switching tabs doesn't resize it, and a short tab leaves room. Checked with Playwright in Chromium and WebKit with the clock on Tuesday 09-29: 10月5日 12:21前有效, and one height on every tab with one account and with five
yetone2026-09-29 11:04:46 +08:00
6e7546337b
grok: Grok Build is found on Windows where its installer puts it (#180: the Grok Build installer finished, but magpie can't find it) — magpie looked for ~/.grok/bin/grok, without .exe, and then only at the first grok on PATH, which on Windows may be another (an npm grok.cmd). Now it looks at GROK_BIN_DIR, the grok home's bin and ~/.grok/bin (grok.exe on Windows), then every folder on PATH and on the registry's PATH, which has what was installed since magpie started, taking a grok there only under a .grok folder; the install-first error gives the PowerShell command on Windows. Tested the order and names of the places looked at, and which grok is taken, in a fake home
yetone2026-09-29 11:04:46 +08:00
57bcccc980
gateway: Claude Code's own headers reach a key+URL Anthropic provider (#179: 403 packy: This API endpoint is only accessible via the official Claude CLI) — magpie sent Claude Code's request on with only anthropic-version and anthropic-beta and its own User-Agent, so a relay that serves only Claude Code, telling it by claude-cli/ and x-app, refused it. Now a request from Claude Code to a provider without an account goes on with its User-Agent, x-app, anthropic-*, X-Stainless-* and x-claude-code-* headers and ?beta=true as it sent them; its key to magpie never does, the provider's own is set. Tested against a fake upstream: the headers and query arrive, the provider's key and not magpie's, another agent still goes as magpie
yetone2026-09-29 11:04:45 +08:00
207042dd78
claude: the signed-in account is one account, and one out of quota hands over to the next (#177) — the account Claude Code is signed in to was named one way as a provider and another as a saved login, so it was served twice and its limits weren't found under its name; and claude auth status was asked with magpie's own ANTHROPIC_BASE_URL/token in the environment, telling of those rather than the sign-in. Now both go by ~/.claude.json's email (with the org), the CLI's email when that has none, and the status is asked without magpie's wiring. A turn the CLI ends with an error result (out of quota, rate limited) ends the reply there instead of waiting on, and a non-streamed one answers 429 for quota words, so another account takes over as in a stream. Tested: the account named as its login, the quota result ending the reply, another account taking over
yetone2026-09-29 10:50:39 +08:00
69a14800d9
warmup: a window that hasn't started is started, and started again after a try that didn't take (#178) — the warm-up only acted on a window with a reset time, so a Codex or Claude account whose 5-hour window had never started (no reset time, nothing used) was never warmed. Now a window the usage reads as not started, or one the agent's windows should have but the reading lacks, is due at once when idle; a try that leaves it unstarted is tried again after 15 minutes, doubling to 4 hours; reading the usage and seeing a window not started kicks the warm-up rather than waiting its 10-minute round, and a warm-up forgets the cached usage so the new window shows. Tested with the repro of the issue, the backoff, and the kick
yetone2026-09-29 10:50:39 +08:00
7047716de6
gemini: a Gemini CLI account lists the models Gemini CLI 0.61 offers it, Gemini 3.8 Flash among them (蒙面人 on Discord: 请问,这个不显示 Gemini 3.8 吗??) — magpie's list was Gemini CLI's of some versions ago, and the models it fetched were the account's quota buckets, which name models by Code Assist's ids (gemini-3-flash) and never 3.8 Flash. Now, as the CLI does, magpie asks Code Assist which experiments the account is in (listExperiments, at most hourly) and offers what the CLI's /model would: 3.1 Pro Preview or 3 Pro Preview, 3 Flash Preview (previews only with quota for one), 3.8 Flash where Google has rolled it out and 3.5 Flash where not, 3.5 or 3.1 Flash Lite likewise, 2.5 Pro and 2.5 Flash Lite; a request goes out under the id the CLI sends (3.5 Flash as gemini-3-flash, or as gemini-3.8-flash once rolled out), and quota buckets are shown under the models listed. The list magpie falls back on has 3.8 Flash, 3.5 Flash and 3.5 Flash Lite, and no longer the retired 3.1 Flash Lite Preview; magpie says it is Gemini CLI 0.61.0. Tested against a fake Code Assist with the experiments off, rolled out, and without Pro or preview access
yetone2026-09-29 10:43:23 +08:00
2715696138
workbuddy: WorkBuddy AI chats carry the rest of the headers its own client sends (lightyear, Jerry lee on Discord: deepseek flash 提示 API error:400 workbuddy AI : illegal API invocation from an unapproved channel) — on the international build deepseek-v4.1-flash was refused as "from an unapproved channel" while GPT and Claude answered. WorkBuddy AI's desktop app lists what its /v2/chat/completions gateway needs ("x-requested-with 是网关的准入约定"), and its CLI sends the same on every chat: X-Requested-With: XMLHttpRequest, X-Agent-Intent: craft, X-Agent-Type: main, X-IDE-Name and X-IDE-Version, and conversation, message and request ids; magpie sent none of them. WorkBuddy AI chats now carry them; the China build, which serves that model already, is left as it was. Tested against a fake gateway that the headers and ids go out; not yet checked against WorkBuddy AI itself
yetone2026-09-29 10:43:22 +08:00
c286c218e3
routing: a group's intent classifier can be a routing group, failing over as any request to it does (lantern2077 on Discord: 意图分类模型能否也选择路由组?现在只能选择单个模型,缺乏回退保障) — the classifier was one model, and when it was down no intent matched. It can now be group/<id>, asked through magpie as before, so its first model failing the next is asked. A group can't be its own classifier, one that classifies for another can't be removed until that one chooses another, a rename carries over, and a classifier's own call asks no classifier in turn, so two groups classifying with each other don't loop. The GUI and TUI pickers list the other groups. Tested: the classifier group's first model 500s and the next answers and the rule matches; two groups set to classify with each other finish at once; checked in a sandbox magpie web that the picker lists Cls and not the group being edited, and via the CLI that self-classifying and removing a classifier group are refused
yetone2026-09-29 10:25:41 +08:00
1963f7f262
providers: a provider's editor lists its image models under its models (Raven on Discord: 同样的 baseurl 和 key,识别不出来里面的 image 生图模型,cc 那边可以) — an image model isn't one an agent chats with, so it was never among a provider's Models chips, and nothing in the editor said magpie had seen gpt-image-1 in the vendor's list. Under Models an Image models row now lists them, as chips that can't be picked, saying the one that draws is chosen in Settings → Images. Tested with a fake vendor listing gpt-5.5, gpt-image-1 and flux-1-schnell; checked in a sandbox magpie web that the editor shows gpt-5.5 under Models and the other two under Image models
yetone2026-09-29 10:17:30 +08:00
40fc5a8d87
panel: the tray panel stops at 560 points tall, not 720, and the rest scrolls in it (#124: 托盘图标这里 体验优化~用量这里 一下子弹出来多大一个框) — with several subscription accounts the Usage tab grew the panel to 720 points, most of a 1080p screen, dropping down from the tray as a big box; the panel now stops at 560 and the accounts scroll under the tabs, the footer staying put, as they already did past 720
yetone2026-09-29 10:15:13 +08:00
034da2b693
providers: one that only draws images says how many image models it has, not "no models exposed" (#124: 供应商里面img模型读不出来,只有在设置里面可以看到) — an image model isn't one an agent picks, so a provider whose list had only image models read "no models exposed" under Providers although Settings → Image generation drew with them. Its row now reads 2 image models. Checked in a sandbox magpie web with a custom provider whose /v1/models lists gpt-image-1 and flux-1-schnell
yetone2026-09-29 10:04:30 +08:00
93d74d2b81
workbuddy: requests are streamed to it, Test's too (#124: 测试 400 · Non-stream chat request is currently not supported, 对话正常的) — WorkBuddy refuses any request that doesn't stream, so its Test, a small non-streaming request, failed with 400 while agents, which stream, answered. A WorkBuddy account is now a backend that only streams: Test sends it stream:true, and the gateway streams it a client's non-streaming request and gives the client one answer, as it does Codex's and Google's. Tested: Test's request to such a backend streams on each endpoint, and a non-streaming chat request through the gateway to a fake upstream that refuses one comes back as one chat.completion
yetone2026-09-29 10:01:21 +08:00
67480a037b
accounts: WorkBuddy's daily check-in (签到) done for each WorkBuddy (China) account, when Settings says to (zhanglolo on Discord: 能不能加个 WorkBuddy 自动签到) — while WorkBuddy's check-in event runs, an account is given credits a day for pressing 签到 in the app. Settings has Check in to WorkBuddy daily (off by default, shown while a WorkBuddy China account is signed in): the gateway asks the event's status for each account and claims when it runs and today's isn't in, once a Beijing day; an answer holds for the day (claimed, already in, not eligible, the event over), no answer is tried again after 30 minutes. What came of it is kept by site and account id in workbuddy-checkin.json and shown under the setting. magpie accounts checkin [--json] does it now. WorkBuddy AI (international) has no event and is left alone. Tested with a fake WorkBuddy API; checked the row in a sandbox magpie web
yetone2026-09-29 09:56:46 +08:00
ea20c2db59
providers: Xiaomi MiMo is a preset, its Token Plan in China, Singapore or Europe or pay as you go (#174 供应商没有小米Mimo的) — MiMo could only be added as a custom provider with its base URL typed in. Now Xiaomi MiMo is under Vendors: a Token Plan's tp- key goes to its region's host (token-plan-cn / -sgp / -ams.xiaomimimo.com), pay as you go to api.xiaomimimo.com, each with chat completions and Responses at /v1 and Anthropic messages at /anthropic, as MiMo's Token Plan page gives them; its models from models.dev's xiaomi-token-plan-cn and xiaomi until Refresh asks MiMo. Checked in a sandbox HOME: the preset added on the Singapore plan lists 9 models, and Test reached all three endpoints of each host, answering 401 Invalid API Key to a made-up key (a wrong path is 404)
yetone2026-09-29 09:46:22 +08:00
35ced89666
provider: a vendor's refusal is shown in its own words, not a bare 400 Bad Request (Mrhe525 on #124: WorkBuddy 和 WorkBuddy AI 测试都 400 错误,积分都是有的) — an error body was read only for an OpenAI/Anthropic-style error or message, or shown as it was when under 200 bytes; Tencent's {code, msg} (WorkBuddy's endpoints) and any longer body were dropped, so the provider editor's Test and the error an agent got said only "400 Bad Request", nothing of why. msg is now read too, and a body in no known shape is shown collapsed to one line and cut at 300 characters; an HTML page still says nothing. Tested: {code, msg}, a long JSON body, an HTML page and an empty body
yetone2026-09-29 09:38:33 +08:00
860292fcc0
routing: a row answering another request says so, not "answering…" under this one's header (yonghe on Discord: 这个调用已经失败/结束,这里还是显示回答中) — the stage shows the rows of every request an agent has in flight, so when Claude Code's Sonnet side request failed while its Opus answer went on, the Opus row stood under the Sonnet route's header saying 回答中, as if that failed request were still answering. A row whose try belongs to a request other than the one the header and log tell of now says "answering another request…" (在回答另一个请求…); with several agents on the stage the wire's colour already tells whose it is. Checked in a sandbox magpie web with a slow and a fast model on one fake upstream: while the slow one streamed and the fast one had answered, the slow row read answering another request… under the fast one's header
yetone2026-09-29 09:27:52 +08:00
a46a6bb2ec
providers: a custom provider named in Chinese is added under its site's name, and a second one beside it (mamba on Discord: 供应商里面自己添加第三方URL只能加一个吗,第二个会提示id重复) — a provider's id is its name slugged to Latin letters and digits, so a name such as 中转站 slugged to nothing and Add was refused ("provider id must be lowercase letters, digits and dashes, not \"\""). Now such a name takes its id from the host of its URL, api. and www. and the .com left off (api.relay-one.com is relay-one), and one on an IP address or localhost-like address is custom; a taken id moves on to relay-one-2 as before, and a second 中转站 is named 中转站 2. Tested: two 中转站 on one host, one on a host with a port, one on 127.0.0.1 and one on [::1] each added under its own id; checked in a sandbox magpie web that 中转站 is added beside another custom provider
yetone2026-09-29 09:17:47 +08:00
3c043f7b2b
settings: About's Community row links the GitHub repo beside Discord (#124: 这里能不能再加上tg群或者github的仓库链接,dis根本没啥人用感觉) — a GitHub button, next to Join Discord, opens github.com/yetone/magpie, where issues are filed and the code is; the row now says questions, ideas and feedback go on Discord or GitHub. There is no Telegram group, so none is linked. Checked in a sandbox magpie web, light and dark, and hovered
yetone2026-09-29 08:36:10 +08:00
ff4f730d0e
gateway: keep one Chat choice when translating, including relay indexes (#168)
Charan Rathore2026-09-29 02:09:52 +05:30
0b31315a47
gateway: 400 when a required tool choice leaves nothing callable (#169)
Charan Rathore2026-09-29 02:09:49 +05:30
42a13798bc
gateway: keep Gemini affinity when the first turn omits role (#171)
Charan Rathore2026-09-29 01:44:50 +05:30
504b470f12
gateway: images a tool returned reach a Chat model after the tool messages (charan-rathore in #167: Claude Code's tool_result images were dropped on the way to Chat Completions)
yetone2026-09-29 03:43:56 +08:00
bdf3d11f50
gateway: hash Gemini contents for the session-affinity fallback ID (#165)
Charan Rathore2026-09-29 01:10:00 +05:30
3b6ea8b589
gateway: clear 400 for Responses images named by file_id on translated routes (#166)
Charan Rathore2026-09-29 01:08:54 +05:30
995edc135d
gateway: honor allowed-tool subsets from Gemini ANY and Responses allowed_tools (#164)
Charan Rathore2026-09-29 01:08:21 +05:30
e330cb815d
workbuddy: a model the plan serves free says so (这个应该是Workbuddy国际版免费的模型,要不要在模型名字后面加上一个免费标记?) — WorkBuddy's product config gives each model the credits a request costs, as its own picker shows them: WorkBuddy AI's deepseek-v4.1-flash is "x0.00", its -sg twin "x0.03", GPT-5.5 "x1.00". A model at x0.00 (or 0) is now Free in the catalog, and carries it to the provider editor's model chips and every agent's model picker, where it has a green 免费/free badge after its name ("free: it doesn't use the plan's credits" on hover); a rate that can't be read is not free. Both WorkBuddy sites, as they share the config. A list fetched before this has no rates: Refresh in the editor asks again. Checked: the credits parse (x0.00, 0 free; x0.03, x1.00, none not), and the badge on a chip and in the picker in the sandbox, dark
yetone2026-09-29 03:02:32 +08:00
b2744c417e
gateway: the package's tests no longer write routes to disk behind their backs (修一下CI里routing目录没清理的测试失败) — a done route was saved by a goroutine of its own, which could still be writing $XDG_CONFIG_HOME/magpie/routing when the test that made it had ended, so TempDir's cleanup failed with 'unlinkat …/magpie/routing: directory not empty' (TestCodexOwnModelRefusalPassesThrough, TestFallbackWhenOutOfQuota/overloaded, TestCodexOwnModelTraced on macOS CI). Saving done routes is now behind keepRoutes, on in magpie and off in the gateway's TestMain; the history's own tests call saveRoute themselves. Ran the gateway tests four times and the whole suite
yetone2026-09-29 02:56:17 +08:00
efed707066
providers: a provider can be switched off, kept with its keys but out of every agent's list (希望服务商可以有一个开关按钮,关闭后不再写入模型) — a provider whose quota ran out could only be removed, losing its key and settings, or left in, its models still written into the agents and requests still sent to it. Now each provider (a signed-in account too) has a switch on its row in Providers and in its editor's header; off, the row is dimmed and says Switched off (已关闭), its models leave the catalog, so the model lists magpie writes into agents' files are rewritten without them as after any provider edit, and it is left out of routing groups, fallbacks, the Automatic image, vision and search picks, the routing pools and balance and usage polling. A request naming one of its models is answered 404 saying the provider is switched off in Magpie, not that the model is unknown. Switched on, all of it comes back. Saving the provider from its editor keeps it off; magpie provider off|on <id> and the TUI's o do the same. Tested: an off provider's models are not in the catalog or served, a group with it routes to the member left, a fallback to it is not tried, a request for it is refused as switched off, and turned on it is listed and answers again; an account's off is kept. Checked the Providers page in a sandbox HOME in light and dark: switching a row off and on, the editor's switch and its note
yetone2026-09-29 02:49:01 +08:00
cdbd2250f6
providers: AIHubMix's GPT Image 2 and 2.5 can be picked to draw (我记得AI Hub Mix是有GPT Image 2以及GPT Image 2.5模型的,为什么选不到呢?) — AIHubMix's /v1/models, asked with a key, lists only its Gemini image models, though the same key draws with gpt-image-1/2/2.5 and the rest; its public catalog (aihubmix.com/api/v1/models) lists them all. Now when an AIHubMix provider's list is fetched, the image models of that catalog join it as drawing (Settings → Images, never offered to agents to chat with); Ideogram's V_2, DESCRIBE and UPSCALE are left out. Checked in a sandbox HOME against the real AIHubMix: after a refresh the picker has aihubmix/gpt-image-2, gpt-image-2.5-flare and 2.5-sunburst among 46 of its image models, and gpt-image-2 and gpt-image-2.5-flare each drew a 1024² PNG through the gateway
yetone2026-09-29 02:37:55 +08:00
ad9536af70
gateway: an empty reasoning_content is left out of a relayed Chat stream, so Qoder reads a WorkBuddy reply as one message, not a word to a line (lml on Discord: 在Qoder CN里面使用Workbuddy里面的模型的话,它这个输出不对) — WorkBuddy's endpoint (copilot.tencent.com/v2) goes on sending "reasoning_content": "" in every delta once the model has done thinking. Its own CLI ignores an empty one after the thinking is over (codebuddy.js: !(this.thinkingBlockCompleted&&""===ec.reasoning_content)), and Cline copes, but Qoder CN 1.1.64 takes each for the thinking starting again and each piece of text after it for a new message, so "hi" was answered one word to a line. A Chat stream magpie relays as it is now has an empty reasoning_content taken out of each delta; it says nothing, and any other line goes on byte for byte, split reads put back into whole lines first. Tested with a scripted Chat upstream streaming WorkBuddy's shape: the agent gets the thinking, the text, finish_reason and usage, and no empty reasoning_content (the test fails without the change); lines split every 7 bytes come out whole
yetone2026-09-29 02:31:16 +08:00
04f82010a4
gui: the image model pickers keep routing groups in one group, as an agent's picker does (重大bug,这里为什么都是重复的icon?) — Settings → Images put each routing group in a group named after itself, so the picker's rail had a button for every one of them, each with its first member's icon: with 31 groups, rows of the same OpenRouter, AIHubMix, Claude Code, Codex and Copilot icons. A model without a provider of its own (a routing group) is now under Routing groups, one rail button with the fan, then one per provider. Automatic and Off, the picker's own choices, stay above the routing groups, which every model picker puts first. Checked with the live Settings' 31 groups and their providers: the rail is All, Favorites, Routing groups, OpenRouter, DeepSeek, 鱼鱼连线, AiHubMix, Claude Code, Codex, Copilot… once each, in light and dark
yetone2026-09-29 02:34:01 +08:00
d730192cc0
gui: the header's view switch is small again, and in dark mode a faint track with a lighter thumb (深色模式下,这一坨像膏药一样…以前我记得是挺精致的) — dc3f691 made its tabs 30px with 13.5px text, not asked for by anyone but by a loop tick that had just enlarged the profile chips after a Discord request; they are 24px and 12.5px again, as they were. In dark mode its track was --pill (#2d2d33), a solid slab lighter than the window, and the thumb on the view shown --card (#232327), darker than the track, so the switch read as a grey plaster with a dent in it. It now has tokens of its own: light as before (pill track, white thumb with its shadow); dark a track of white at 4.5% and a thumb of white at 10% with a hairline top highlight. Checked in the window in light and dark
yetone2026-09-29 02:29:47 +08:00
4cc32dbcb0
routing: every request's route is kept on disk, for a day long gone to be looked at and replayed, with retention (历史中的路由记录是不是都应该保存下来,方便用户去回放?…这种历史记录会特别大,应该有自动的retention) — the trace holds only the last 60 routes, and only since the gateway started. Now each route, once done, is appended to ~/.config/magpie/routing/YYYY-MM-DD.jsonl; a day that is over is gzipped, days older than 30 are dropped, then the oldest until all of it fits 200 MB (today is never dropped), checked at most hourly. Route ids start at the time the gateway started, so they don't repeat across runs. /api/gateway/history?day= gives the days kept with their counts and a day's routes (its latest 2000). The Requests list has a chip per day (实时, 今天 3, 昨天, …): a day's requests can be picked, looked at, replayed all, or replayed from one on (从这里重放), with the real-time clock as before. Checked in a sandbox HOME against real DeepSeek: three requests written to the day's file, the gateway restarted, the list showed 今天 3 with them, 从这里重放 played them at 02:19:46 · 第 1/3, stop and 实时 came back to live
yetone2026-09-29 02:22:35 +08:00
3a18ec8efc
images: every provider's image models and the Codex subscription's GPT Image 2 / 2.5 can draw (为什么生图模型只有这几个?只有OpenRouter这个provider才提供…CodeX Subscription里面也有GPT Image 2和GPT Image 2.5) — Settings → Images → Image generation listed only OpenRouter's, for two reasons: a vendor's model list was cut to the models agents chat with before it was kept, so a relay's gpt-image, flux or Gemini image models were gone by the time the picker looked; and a subscription was never asked. Now the list is kept whole, image models marked as drawing and still never offered to agents to chat with, and the picker has them per provider; a Codex (ChatGPT) account draws with GPT Image 2 and 2.5 on chatgpt.com's own images API (signed as Codex, generations and edits, an edit as JSON with each image a data URL, since the backend turns multipart away), and Automatic prefers it, as a plan's images come with it. AIHubMix answers a Gemini image model's chat with the image in multi_mod_content's inline_data, which is now read. Checked in a sandbox HOME against the real vendors: the picker lists OpenRouter's, AIHubMix's and Codex's, Automatic is GPT Image 2.5 · Codex; codex/gpt-image-2 drew a 1254² PNG and edited it (night-blue background), aihubmix/gemini-2.5-flash-image drew a PNG. The backend takes any model name, so whether 2.5 draws differently from 2 can't be told from outside
yetone2026-09-29 02:20:18 +08:00
beedc17b2a
providers: the model filter is a search, and says why an image model isn't there (这个搜索框是不是有问题?没列出来的搜不到) — typing in a provider's model filter left every picked model shown whether or not it matched, so filtering AIHubMix for "image" showed fourteen picked chat models and looked like a search that doesn't work. Now what the filter doesn't match is left out, picked or not (models added by hand too); Select all still picks only those it shows. The list is of models agents chat with — image, embedding and speech models are left out of it when it is fetched — so a filter that matches nothing says so and where an image model is set: Settings → Images. Checked on the page with 30 models, 6 picked: "image" shows the hint alone, "glm" the two glm models, an empty filter all 30
yetone2026-09-29 02:03:54 +08:00
3ee4ebbf62
images: agents can generate and edit images with a model set in Magpie (让Magpie支持配置图像识别模型以及生图模型, part 2) — the gateway answers /v1/images/generations and /v1/images/edits for any model that draws: an images-API model (gpt-image-1, dall-e, imagen, a relay's) is sent the vendor's own images request (an edit as multipart, image[] per reference); a chat model that answers with images (OpenRouter's Nano Banana and GPT-5 Image, gpt-5-image) is asked with modalities ["image","text"], the size given as an aspect ratio, once per image asked for; Gemini's own image models over generateContent. Either way the answer is the images API's (b64_json with its mime_type, the model's text, usage), recorded in usage like any request. The model is Settings → Images → Image generation: Automatic (a model that draws among the providers set up, from the catalog's image-output models), Off, or any model; a request that names none is drawn by it, and with it Off is refused saying where to set one. Subscriptions draw nothing yet. magpie mcp image is a stdio MCP server with one tool, generate_image (prompt, size, n, path, reference_images): it asks the agent for its roots, saves each image in the project (assets/ by default, a name from the prompt, never over a file, the extension of what came back — a JPEG asked for as hero.png is hero.jpg), and says where; reference images are read from the project and sent as an edit. Its requests carry the agent's own name (claude-code/… magpie-image/1) so usage says which agent drew. Library → MCP servers → Discover has it as Magpie Image, opt-in: no agent is given it until picked, since every image costs what the model charges. Checked in a sandbox HOME against real vendors: OpenRouter's gemini-3.1-flash-lite-image drew a 3:2 magpie over MCP as Claude Code and edited it from the saved file as Codex (usage: claude, codex), AIHubMix's gpt-image-1 answered /v1/images/generations with a 1024² PNG; the Settings row and picker in light and dark, the Library card and its opt-in sheet
yetone2026-09-29 01:52:50 +08:00
5910bdada5
docs: Get started says agents, not coding agents (把文案里的Coding agents统一改成agents) — magpie chooses the model for any agent, not only coding ones; the English lede said "each of your coding agents" and the Chinese one "编程 Agent"; both now just agents, as the home page already does
yetone2026-09-29 01:45:47 +08:00
92aef441d4
providers: 添加供应商 scrolls down to the sheet on the first click, and the sheet unrolls with the view going down along with it (第一次点击添加供应商…并不会自动向下滚动,第二次才会;滚动跟展开都没有丝滑的动画) — the view's guard against scrolls nobody asked for (backToReader) put back the smooth scrollIntoView the button started, as it never said scrollOnPurpose; it only got through when something else happened to have. Now the button says so, and the sheet opens from nothing to its height on the rows' spring (ROW_OPEN), its head and tiles easing down into place, while the view's scrollTop is set frame by frame from the sheet's height: from when the sheet reaches the view's foot to when it is whole, into room the sheet has made, so it neither jumps nor stops short, until the sheet's top is 12px under the view's — scrollTop set directly, which WebKit animates where a smooth scrollIntoView may not. Scrolling meanwhile hands the view back to the reader. 关闭 rolls it up the other way before it is hidden. Reduced motion jumps there as before. Checked in a sandbox HOME with six providers in headless Chrome: on the first click scrollTop went 0 → 301 over ~550 ms along with the height (0 → 868), no jump; closed and reopened the same; reduced motion lands at 301 with no animation
yetone2026-09-29 01:38:38 +08:00
7353323382
routing: Jev is told what each level is for (我用 jev 作为意图判断模型的时候「写个纸牌游戏」为啥会被识别为简单任务) — intents that are levels (简单任务 / 复杂任务) went to Jev as bare names, and a short message left it torn: 写个纸牌游戏 came out 复杂任务 at 0.62 with no turn before, too unsure to hold, and 简单任务 at 0.57 after a 简单任务 turn, so the turn before's level stood. Now the call that asks once per set of intents whether they are levels also asks, per level, how much work a request at it is (a score over four tiers: little, some, much, the most work — a new program, app or game), and each tier goes to the level rated nearest it; the level question then gives each its place (lowest, highest, level k of n) and its tiers, and says to judge the work asked for, not how short the message is. Still one extra call per set of intents, cached. Checked against Jev itself: 简单任务 0.03, 复杂任务 2.32; 写个纸牌游戏 复杂任务 at 1.0, and 0.99 after a 简单任务 turn; 修个错别字 and 解释一下这个函数 简单任务 at 1.0, 继续 at 0.94. Unrated levels keep bare names as before
yetone2026-09-29 01:36:32 +08:00
f39f25032c
routing: a replay — the requests the gateway keeps, one or all of them, played again as they happened, from its own trace: each at its time and each try as long as it took, a wait over 1.8 s cut short; the stage as it was then, every agent, account, its use and rest, what it answered, the captions and the story of each request. Over the stage a clock tells the real time it is replaying, running fast (and saying so) through what was cut; under it which requests are in flight then — which of how many, the agent, the model, who answered, when it was sent — and a track with a mark for each request, played along and clicked to go to. It plays at 1×, 2×, 4× or 8× and stops back where it was begun
yetone2026-09-29 01:31:21 +08:00
a8db8872b4
accounts: switch and forget take an account's email alone, and refresh says which one it leaves to the agent (vincentzhang on Discord: magpie accounts switch codex rc826353@gmail.com → no saved codex account) — a ChatGPT seat in a workspace is listed as "email · Team" so it reads apart from a personal plan of the same email, and switch/forget matched only that whole name, so the email the usage line itself asks for (switch <agent> <email>) was refused. Now the name as listed, or the email alone when only one of the agent's accounts has it; an email two accounts share is refused naming both, and an unknown one lists the agent's accounts. refresh renews the saved accounts an agent isn't signed in to, the one it is being renewed by the agent itself; that one is now named ("· codex a@b.com · Team signed in now · codex renews it itself") instead of missing from the count. Checked with a sandbox HOME: a Team seat switched to by email, an email with Team and Business seats refused naming both, an unknown email listing the accounts, and refresh naming the signed-in account
yetone2026-09-29 01:30:02 +08:00
d00d9ffe6f
gateway: a model that can't see images is given what a model that can says of them (让Magpie支持配置图像识别模型) — until now an image sent to a model the catalog knows takes text only was turned away in the latest turn and left out of older turns and tool results, so an agent on DeepSeek, GLM or any text-only model couldn't be shown a screenshot at all. Now each image in such a request is described once by the vision model and the description goes in its place, in every protocol (Chat, Responses, Anthropic, Gemini), current turn, older turns and tool results alike: "[Image, as <model> describes it for this model, which can't see images:] … [End of the image's description]". The describer is asked through the gateway itself (User-Agent magpie-vision/1, recorded as agent magpie), with a system prompt to transcribe text, code, errors and UI state exactly and not to answer or guess; images are described four at a time, and a description is kept (256, by model+image) since an agent sends a conversation's images again every turn, a failure not kept. An image of the latest turn that can't be described is a 502 saying why; one in an older turn is left out as before. Settings → Images → Image recognition picks the model: Automatic (a small model that sees — a Claude account's, a Codex account's, the cheapest of an API key's, another account's), Off (images turned away as before), or any model or group that sees; an id that doesn't resolve is refused. In a routing group the description is made only when a text-only member is actually tried, so a rule that routes images to a member that sees costs nothing; a member whose image can't be described is skipped for the next, the last one answers 502. The describer's own request is never described again, so a Vision set to a text-only model is turned away, not looped. Checked in a sandbox HOME against a local vendor: an image sent over Chat and over Anthropic to a text-only model reached it as the description, the describer was asked once per image, and the Settings row and its picker in light and dark.
yetone2026-09-29 01:20:21 +08:00
4150dfc079
provider: Volcengine Ark (火山方舟) is a preset, its Coding Plan, Agent Plan and pay-as-you-go (tcdw: 提供一个选项能够取消自动给 LLM 提供商地址补全 /v1/ 的默认行为) — volcengine, a first-party vendor with a Plan picker: Coding Plan (default) at https://ark.cn-beijing.volces.com/api/coding/v3 for chat completions and Responses and /api/coding for messages (套餐概览 docs/82379/1925114, 快速开始 1928261; its Codex page 2556056 sets wire_api "responses"); Agent Plan, which tcdw is on, at /api/plan/v3 (chat completions and Responses, its Hermes Agent page 2373743) and /api/plan (其他工具 2373746, Claude Code 2373740), with a key of its own; pay-as-you-go at /api/v3 (兼容 OpenAI SDK 1330626, 创建 Response 1569618), which both plans' pages warn bills apart from the plan — no Anthropic endpoint is documented for it. Its models (ark-code-latest, whichever the console picked, then doubao-seed-evolving, doubao-seed-2.1-pro/-lite, doubao-seed-2.0-mini, minimax-m3, glm-5.3, glm-5.3-flash, deepseek-v4.1-flash, deepseek-v4-flash, deepseek-v4-pro, kimi-k2.7-code, kimi-k2.8-preview, kimi-k3, lowercase as the quick-start page gives them) are shown until a list is fetched; no models.dev catalog is tied to it, as its volcengine one has pay-as-you-go's dated ids and volcengine-coding-plan misses the Agent Plan's. Key from ark.volcengine.com/region:cn-beijing/apikey. Their versioned paths go out as written (previous commit). Icon is lobehub's volcengine-color, as the others are; the import page offers its three plans
yetone2026-09-29 01:17:57 +08:00
111f5ba8ef
provider: a base URL with a version in its path is used as written, never given a /v1 (tcdw: 提供一个选项能够取消自动给 LLM 提供商地址补全 /v1/ 的默认行为) — a custom provider at Volcengine Ark's Agent Plan, https://ark.cn-beijing.volces.com/api/plan/v3 (its 其他工具 page, docs/82379/2373746), was asked for its list at …/v3/models and then …/v3/v1/models, and only the last failure was shown, so the error named a URL the user never gave. Ark answers both 401 without a valid key (checked unauthenticated: auth comes before routing), so which path it serves can't be told from outside; and had …/v3/v1/models answered, fixV1 would have rewritten the chat base to …/v3/v1 for good. Now an OpenAI-style base with a version segment anywhere in its path (v1, v3, v4, v1beta: Ark's /api/plan/v3 and /api/coding/v3, Zhipu's /api/paas/v4, Gemini's /v1beta/openai) is asked only at base/models and fixV1 leaves it alone; a bare host or an unversioned path (a relay's …/api) is still looked around for the /v1 it may lack, and an Anthropic base still has its /v1/models. A failed list names every URL asked with its status and the vendor's own message ("401 Unauthorized (The API key doesn't exist.)") and says the model ids can be typed in by hand or a models URL given — both already work, the base stays as typed; magpie provider add now prints it instead of saying nothing. No "don't touch my URL" toggle: a versioned URL is never touched, and an unversioned one is only fixed when its /v1 alone answered, when requests at the base as written would miss too. Tested against an httptest server shaped like Ark (/api/plan/v3/chat/completions served, /models 404, a lenient /v3/v1/models) in a sandbox HOME: before, …/v3/v1/models: 404 and, lenient, chat moved to …/v3/v1; after, only …/api/plan/v3/models is asked and the base is kept
yetone2026-09-29 01:17:48 +08:00
2d7a46e4de
routing: a rule's intent is typed in its pill, and a group's logos are whole (这里的输入框跟它外面围起来的这个框,感觉好奇怪,好丑。另外下面的Provider的logo也被裁剪了) — the editor's boxed input (its border, radius and focus ring) outranked the pill's own, so the intent field was a box inside the pill; it is bare now and the pill shows the focus. The send-to pill clipped its children, the overlapping logo discs and their rings with them; the stack is not clipped
yetone2026-09-29 01:15:56 +08:00
e08627be61
library: an agent's icon beside a skill or server an agent has of its own shows once again (这里的图标怎么变成这样了?) — since ef247c1 an agent's icon is made once, with a grey copy for a chip whose agent hasn't the item, and copied from there; the copy was hidden only inside a chip (.lib-ag), so in the rows of what the agents have of their own (Agent 中已有) each icon showed its colour and grey pictures squeezed side by side. The grey copy is hidden wherever the icon goes, and shown only in a chip that's off, as before. Checked in a sandbox magpie's Skills tab
yetone2026-09-29 01:10:12 +08:00
41ff300d9a
panel: the Agents list shows it is loading (Agent列表加载出来之前没有加载动画呀) — its skeleton was there but unseen: the light panel's pills are white on white cards, and the skeletons shimmered in those same colours; they have a grey of their own there now (--skel, --skel-hi). The rows take the panel's shape too, the name at the left and what is set as words at the right with its bars, not the window's two setting columns, and the panel is fitted to them as they are drawn
yetone2026-09-29 01:06:32 +08:00
5b43bdd61c
library: RTK's version is kept up to date from magpie, and what it saved is drawn day by day (这里要能够管理RTK的版本,比如给它升级,以及能够看到RTK省token的趋势) — the RTK card shows its latest release beside the installed one (read from where github.com/rtk-ai/rtk/releases/latest redirects, as RTK's install.sh does, the API as fallback; kept six hours) and, when newer, an Upgrade button that brings it up the way it was installed: brew upgrade rtk for Homebrew's (in a Cellar; Homebrew updated first), winget upgrade on Windows, cargo install --git again for cargo's, and RTK's own script again, into the same folder (RTK_INSTALL_DIR), for one it put elsewhere; when Homebrew's formula is still behind the release, that is said. Also magpie library rtk upgrade. Under the totals, a chart of what RTK saved each day (week by week past 92 days) over 30 days, 90 days or all it has recorded: each bar the commands' whole output, the part saved above what still went to the model, the range's own total beside it — from rtk gain --daily --format json (RTK 0.28 on), which carries the summary too. Tested with a fake Homebrew rtk behind its release and a fake script install, and against the real rtk 0.28.2 and its history in a sandbox magpie (GitHub says 0.50.0); the upgrade itself not run on this machine
yetone2026-09-29 01:01:23 +08:00
fb1575730e
gateway: Claude Desktop offers its thinking-effort picker for magpie's models that take reasoning levels (ARNO: 接入claude desktop后无法设置思考强度,不确定是哪里的问题) — in a gateway's mode Desktop reads no effort from /v1/models (IIt keeps id, display_name, description, supports_1m, anthropic_family_tier), and its model catalog must be Anthropic's signed file, so a model's levels come only from tIt in index.chunk-D3OyLXgG.js: let t=IC(e),n=HFt[t]??(UFt.test(t)?VFt:void 0). HFt is its own table (claude-sonnet-4-6, claude-sonnet-5, claude-opus-4-6/4-7/4-8, claude-opus-5), UFt /^(?:claude-)?(?:fable|mythos)(?:-|$)/ with VFt low…max, and IC the lowercased id with a "<label>.anthropic." prefix and a date taken off (qS). magpie's ids (provider/model, anthropic/magpie-<n>) were neither, so no model had the picker, not even a real Claude one. A model with reasoning levels is now listed as mythos-magpie-<n> (UFt matches; no haiku/sonnet/opus in it, so Desktop's small_fast pick is unchanged), or, for a real Claude model, as magpie-<n>.anthropic.<claude model> (IC reads it as that model, so HFt gives its own levels). One without levels is listed as before. aliased serves all three forms, with or without [1m]. Checked against Desktop's bundled Claude Code 2.1.280 in a sandbox HOME, pointed at a local logger: mythos-magpie-<n> goes out exactly as anthropic/magpie-<n> did (thinking adaptive, output_config.effort as picked, 32000 tokens); magpie-<n>.anthropic.claude-opus-4-8 goes out exactly as x/claude-opus-4-8 did, known as Opus 4.8 (no unrecognized_model warning, 64000 tokens). The effort then reaches the model fitted to its levels: Anthropic passthrough now fits output_config.effort as Chat's reasoning_effort and Responses' reasoning.effort already were (bodyEffort/withBodyEffort), so Desktop's max goes to a low/high model as high. VFt always thinks: Desktop offers no "off" for a non-Claude model with levels. A session saved on an old id must be moved once to the new entry in the picker; magpie still serves the old id.
yetone2026-09-29 00:52:40 +08:00
7a1a2b1e63
gateway: a new Claude Desktop session's title goes to the model the session starts on, not Claude's own (ARNO: claude desktop在会话第一次我发消息的时候就先生成标题了,导致还是走了claude自己的模型请求,然后等自定义的模型运行过之后才会正常转发给当前正在用的模型) — Desktop titles a session's first message before sending it: one tool-less request (max_tokens 200, "You write short session titles…", no session id) on its small_fast pick, the first listed id with haiku/sonnet/opus in it (_$n/v$n in index.chunk-D3OyLXgG.js). desktopTurn sent it to the model of the latest turn, but before any turn at all there is none, so it went as asked, to a Claude model the user never picked. It now goes to desktopDefault: the model the agent is set to stand in (StandIn("claude-desktop", …), none today), else the first model shown to Desktop, which is what a new Desktop session starts on (resolveDefaultSessionModel takes the first unrestricted /v1/models row). A title doesn't pick a model; a turn on a real Claude model magpie serves is kept as it was. The title can't be tied to its own session: the request carries no session or conversation id, and rejecting small_fast to make Desktop retry on the session model (Tcr) fails outright when the two are the same model.
yetone2026-09-29 00:45:17 +08:00
356549710b
subscription: Antigravity accounts can be imported from a JSON file (莫: https://github.com/jlcodes99/vscode-antigravity-cockpit 这个开源的里面有 你可以看看) — beside Add account (and as "Import instead…" on the risk note) the Antigravity card takes files or pasted text exported by Antigravity Cockpit (a JSON array of {email, refresh_token}, or refresh tokens one a line), Antigravity Manager (the same array, {accounts:[…]}, or an account file with token{refresh_token, email, project_id}) and CLIProxyAPI (an antigravity auth file, type/email/refresh_token/project_id; another type's is refused). All three sign in with the Antigravity app's own OAuth client, as magpie does, so their refresh tokens are good here. Each account is checked as signing in does: the token refreshed at Google, the email read from userinfo (the file's if that's refused), the project and plan from loadCodeAssist, then kept in logins.json like a signed-in account. A token magpie already has is not sent again (exists); a known email with a new token replaces the old (updated); duplicates in the file, entries with no token and tokens Google refuses are reported per account, Google's bare "Bad Request" explained. POST /api/signin/import; tokens are never logged, shown or returned, and the paste box is masked. Tested against an httptest token/userinfo/Code Assist server in a sandbox HOME
yetone2026-09-29 00:50:10 +08:00
05094bed3d
workbuddy: two models of the same name are told apart (为啥会有两个 Deepseek-V4.1-Flash) — WorkBuddy AI's config gives deepseek-v4.1-flash (x0.00 credits) and deepseek-v4.1-flash-sg (Singapore, x0.03) both the name Deepseek-V4.1-Flash, and both are in its CLI agent's picker; a later model of a name already taken is now named for what its id adds to the first's, "Deepseek-V4.1-Flash (SG)", or else for its id. Both builds' lists go through it.
yetone2026-09-29 00:49:07 +08:00
42aae751f5
agent: Pi's MCP servers go where pi-mcp-adapter reads them now (xiaozhu1337 on #58: pi-mcp-adapter no longer reads …\.pi\agent\mcp.json) — pi-mcp-adapter 3 (3.0.0 2026-09-26, 3.1.0 now) reads <agent dir>/mcp-adapter.json, same format, after ~/.config/mcp/mcp.json and ~/.agents/mcp.json (.mcp.json and .pi/mcp-adapter.json per project), and no longer <agent dir>/mcp.json; at every session start it warns while that file has any server, settings, imports or claudePlugins, whether or not mcp-adapter.json is there too (config.ts getLegacyMcpMigrationNotices, index.ts session_start). magpie only looked for the adapter in <agent dir>/npm/node_modules, so one Pi installed the older way (npm -g: %APPDATA%\npm\node_modules and the like, which Pi 0.87's package manager still resolves), from git, or from a folder counted as none and mcp.json kept being written; and with mcp-adapter.json already there (the adapter's own setup writes it) mcp.json's servers were left behind. Now which extension Pi has comes from settings.json's packages (a pin like npm:pi-mcp-adapter@2.9.1 counts) and the folders Pi installs them in: adapter 3, or listed with no version found, or mcp-adapter.json there → mcp-adapter.json; mcp.json is renamed to it when there is none, else each server and setting it lacks is merged in (backed up first), one the two have differently left in mcp.json for the user, and mcp.json removed once empty. pi-mcp-extension 1.5 reads only ~/.pi/agent/mcp.json (its home's, not PI_CODING_AGENT_DIR's; transport field, zod schema): with it alone that file, with both each file gets the servers (user fields in each entry kept) and mcp.json isn't moved — the adapter's warning can't be avoided then. Adapter before 3 → mcp.json; nothing found → mcp.json if there, else mcp-adapter.json. Servers in either file are found for bringing into the library. Tested in sandbox homes, and against the real 3.1.0 loader: the reporter's shape (adapter under npm's global folder, mcp.json from magpie, mcp-adapter.json from setup) warned before, and after one magpie write it gives no notice and loads all three servers
yetone2026-09-29 00:42:53 +08:00
e13677fd3a
sessions: OpenCode v2's sessions are read (Kumo31: opencode v2的session改写到新表里了) — OpenCode 2 (v2.0.x, checked against v2.0.18's source) keeps sessions in the same opencode.db but in tables of its own (packages/core/src/session/sql.ts): session_v2 (the session row as before — directory, parent_id, a title that may now be null, time_created/updated, model {id, providerID, variant}, session totals) and session_message (id, session_id, type, seq, time_created/updated, data), not "sessionmessage". A message's kind is its type column (user, assistant, synthetic, system, compaction, idle, …); a user message's data is its prompt {text, files, …} with no part rows; an assistant's has model {id, providerID, variant}, content (text/reasoning/tool), cost, tokens {input, output, reasoning, cache {read, write}} and time {created, completed} (packages/schema/src/session-message.ts, token-usage.ts), counted as before: input without the cache, output without the reasoning (core/src/session/usage.ts). A compaction carries its own tokens, counted on its model, else the one last replied with. On first start OpenCode 2 copies every old session over (core/src/database/v1-migration.bun.ts), leaving session/message/part unwritten and recording kv migration.v1-v2 {"phase":"completed"}; so with session_v2 present only it is read once that is recorded (or no old table is left, as for the pre-split v2 databases it renamed in place), and while the copy is under way an old session not yet in session_v2 is read from the old tables — never both, so nothing counts twice and a session deleted in v2 doesn't come back. Resume stays opencode --session <ses…> (cli/src/commands/commands.ts). Tested with a v2 fixture made in the test from SQL beside stale old tables; the old-table and JSON-file tests still pass.
yetone2026-09-29 00:37:27 +08:00
a47e70fb63
usage: Command Code shows its 5-hour and weekly windows, its balance beside them (Command Code为什么没有用量只有余额???) — a quota with a balance was taken for a balance alone: the Usage page showed only the figure, the panel put it among Balances, and the used/left toggle didn't count it, so Command Code's credits hid the windows read with them. A balance is the whole quota now only when there are no windows; with windows, the meters come first and the balance is a row under them (the panel: in the account's note and title)
yetone2026-09-29 00:35:15 +08:00
44fd12dfe8
subscription: WorkBuddy AI, the international build, is its own subscription (Workbuddy国际版的Subscription是否也要支持呀?… 你应该新加一个Subscription Provider叫做Workbuddy国际版) — workbuddy-ai, "WorkBuddy 国际版 (WorkBuddy AI)" under 订阅. From WorkBuddy AI.app 5.6.2's product config: the same API as the Chinese build at its own endpoint, https://www.workbuddy.ai (isOversea, externalDomain www.codebuddy.ai / www.workbuddy.ai), signed in with platform=workbuddy-ai; its own account is read, never changed, from workbuddy-desktop-ai.info beside workbuddy-desktop.info in CodeBuddyExtension's auth folder, others kept in logins.json apart from the Chinese build's. Its models are its own (the Fast/Balanced/Primary/Deep tiers, GPT-5.5/5.4/5.3-Codex, Gemini 3.1 Pro/3.5 Flash, GLM-5.3/5.2, Hy3, Kimi-K3/K2.6, MiniMax-M3) until /v3/config is read; credits from the same resource summary. workbuddy.go is now parametrised by a wbSite (CN, AI); token cache keyed by site and uid. Checked live: auth/state at www.workbuddy.ai answers and magpie opens https://www.workbuddy.ai/login?platform=workbuddy-ai (200); chat and usage not tried against a real international account.
yetone2026-09-29 00:31:45 +08:00
841855ca5a
provider: Huawei Cloud's MaaS Token Plan is a preset (Lemon: 能否支持华为 codearts 订阅啊) — huaweicloud, Huawei Cloud MaaS: the Token Plan (personal accounts, 西南-贵阳一 only) is spent only at its own endpoints, https://api.modelarts-maas.com/plan/v2 for chat completions (its OpenClaw, Cherry Studio and CodeArts pages, tokenplan-maas-0004/0009/0014) and /plan/anthropic for messages (its Claude Code page, tokenplan-maas-0003); pay-as-you-go MaaS is the other Plan, /openai/v1 (qs-maas-0001, OpenCode page maas-modelarts-0909) and /anthropic (model-call-060). No Responses on either. Its models (glm-5.3, glm-5.1, kimi-k2.6, deepseek-v4.1-flash, deepseek-v4-flash, lowercase as its OpenClaw page has them) are given until a list is fetched; the key is a MaaS API key from console.huaweicloud.com/modelarts/?#/model-studio/authmanage; no usage API is documented (quota is shown in the console's 订阅管理), so none is read. CodeArts (码道) itself isn't a provider: it has no official API, its private endpoints are reverse-engineered, and its own doc has it reach the Token Plan through these same endpoints. Icon is lobehub's huaweicloud-color, as the others are.
yetone2026-09-29 00:20:52 +08:00
b0c42d738e
subscription: a Command Code plan's 5-hour and weekly windows show on the Usage page and the panel (ARNO: command code plan的五小时额度,周额度等订阅信息没有显示到用量面板里) — the plan's card was read right (billing/credits as command-code 1.66's /usage reads it: credits.{planId, monthlyCredits, purchasedCredits, freeCredits}, windowLimits.{limited, fiveHour, weekly}.{used, cap, resetAt in ms} beside it) but also carried the dollars left as its Balance, and a card's Balance is shown in place of its windows everywhere (the panel, the Usage page, the TUI): the windows were read and never drawn. The dollars are now a Credits window, used of the CLI's own pool (the plan's month — Go $10, Pro $30 or $80 for pro-v1, Provider $15, GOAT $70, Teams Pro $40, Max $150, Ultra $300 — or what is left of it if more, plus bought and free credits), "$spent / $pool"; only a reply with no windows and no known plan is a Balance still. A plan's key on the keyed commandcode preset gets the same windows as a plan card (api.commandcode.ai is a plan quota source; a pay-as-you-go key has none and no card), and its balance card is the dollars left alone rather than "5h 42% · week 18% · $12.30" squeezed into one amount. billing/credits carries no planId (4b21f62 found it so on a live account), so the pool's month is the plan billing/subscriptions names; an account with no plan and no windows shows what it bought as its Balance
yetone2026-09-29 00:20:20 +08:00
8a30a938d6
provider: Antigravity's usage shows only the models enabled again (antigravity 为什么又显示了没有启用的模型的用量?) — since #150 (2baad53) magpie offers a family of Antigravity's levels as one model (gemini-3.8-flash), but its quota still names each level's id (gemini-3.8-flash-high), so none of the windows matched what's enabled and chosenWindows, finding none, kept all 27. A window's id is now taken to the model magpie offers for it (AntigravityBase) before it's matched; on this machine, with Gemini 3.8 Flash enabled, 3 of 27 are kept: its high, low and medium
yetone2026-09-29 00:21:18 +08:00
4b21f62e89
commandcode: a plan's usage says its plan (为什么Command Code Plan没有用量?) — billing/credits has no planId, so the plan (and the account's badge) came up empty; it's read from billing/subscriptions: planId, currentPeriodEnd as when it ends, cancelAtPeriodEnd as whether it renews, and an account with none is "No plan" (无订阅). The plan is said even when billing/credits fails — Command Code answers it 503, "Couldn't verify your credit balance just now", at times — and an account with a balance but no 5-hour or weekly window shows the balance instead of 暂无用量数据. Checked against a live GOAT account: GOAT, $70.00, both windows
yetone2026-09-29 00:19:00 +08:00
8060650048
agent: Pi starts on the model magpie picks, and asks a Messages-only provider's models on Messages (#160 Aimer779; Cleary on Discord)
yetone2026-09-29 00:02:01 +08:00
82e778e629
gateway: prompt_cache_test keeps its tests — ac2340d wrote TestAnthropicPromptCache over the file, dropping TestCodexThreadOnChatUpstreamCaches, TestPromptCacheKeyRefused and TestChatUsageCache; they're back, the new test after them
yetone2026-09-29 00:08:17 +08:00
ac2340d580
gateway: a request translated for Claude is cached (Passluo: 用户直接用 magpie 把 claude api 接入到 codex,这样没有申明缓存,用户没有写缓存) — Anthropic caches a prompt only up to a block marked cache_control, and a request from Codex (Responses) or a Chat client, rebuilt as Messages, had none, so every turn paid the whole conversation again. buildAnthropic now marks the system prompt (as a text block; the last tool when there's none) and the conversation's last block that can be (never thinking), so the next turn, which only adds to it, reads it from the cache; two marks, within Anthropic's four with the one Claude's sign-in adds. Anthropic's cache_read tokens already come back as Codex's cached_tokens
yetone2026-09-29 00:05:27 +08:00
17a3e0b4ea
gateway: Claude Desktop's titles go to the model its session is on (ARNO: 给claude desktop配置了自定义模型后偶尔还是会请求到claude自己的模型)
yetone2026-09-28 23:58:50 +08:00
2476cd5c1a
gateway: a Codex conversation moved to another Grok account or vendor goes on (waroy: Could not decrypt the provided encrypted_content … 中途换 routing)
yetone2026-09-28 23:54:03 +08:00
e927f027f3
sessions: Grok Build's and WorkBuddy's sessions are counted too (Aimer779: 用量→会话 增加 Grok Build 和 WorkBuddy 的本地会话统计)
yetone2026-09-28 23:24:47 +08:00
fa3ea3149a
subscription: Command Code Plan, signed in from magpie (Yetone 老师,CommandCode 也是有登录订阅额度的,并不是类似中转的那种哇 — @RookieRicardoR) — a Command Code plan (Pro, GOAT, Max, Ultra) is now a subscription under 订阅, not only the keyed relay preset: Add signs in with the CLI's own browser sign-in (commandcode.ai/studio/auth/cli posting the new key to a callback on 127.0.0.1, answered as the CLI does, 303 to its complete page; wrong state 403, access_denied fails), whoami names the account and billing/credits its plan; the CLI's own account is read from ~/.commandcode/auth.json, never changed, others kept in logins.json with switch/on/forget like ZCode's. Its models are served from the Provider API (/provider/v1 Chat and Responses, /provider Messages) with the plan's key, billed against the plan's credits; usage shows the 5-hour and weekly windows with their resets and the credits left. Its id is commandcode-plan, since commandcode is the keyed preset's
yetone2026-09-28 23:24:19 +08:00
9c44e5b8c0
gateway: Codex on a Chat Completions relay keeps its prompt cache, and is told what it read (Codex 通过 magpie 走 OpenAI 兼容中转站,缓存好像没生效、token 用量很高) — Codex's prompt_cache_key (its thread's id) was dropped when its Responses request was made a Chat Completions one, so OpenAI and the relays that route a conversation by it to where its prompt is cached sent each turn somewhere cold; it now goes along to Chat and Responses upstreams alike, and a vendor that turns the unknown field away (400/422 naming it: Gemini's Unknown name, Mistral's extra_forbidden, Groq's unsupported) is asked again without it and not sent it again; so is one whose 400/422 doesn't name it, remembered only once the request works without it, and a 400 for something else still gets the key next time. What was read from the cache reached Codex, magpie's usage and affinity only as OpenAI's prompt_tokens_details.cached_tokens; DeepSeek's prompt_cache_hit_tokens, Moonshot's cached_tokens, OpenRouter's cache_write_tokens and a Claude relay's cache_read/cache_creation_input_tokens (its prompt_tokens taken as the whole prompt when it is at least those, as Anthropic counts otherwise) are read too — before, a DeepSeek-style relay's hits showed as cached_tokens 0 and affinity saw no cache worth staying for. The converted request was already prefix-stable turn to turn (instructions first, tools in Codex's order and schemas as sent, sorted keys, no ids or times added); tested with two Codex turns against a fake Chat upstream: every message of the first sent again byte for byte, tools the same, the key on both, 2048 cached tokens back to Codex
yetone2026-09-28 23:02:22 +08:00
4eba5c37a8
sessions: ZCode, DeepSeek Harness, Cline and Qoder's sessions are listed too (lml: 希望会话里也能看到 ZCode、Qoder CN、Cline、DeepSeek Harness 的) — ZCode's are OpenCode's tables in ~/.zcode/cli/db/db.sqlite, read as OpenCode's database is (opened read-only), its tokens the AI SDK's (input less the cache, output as it is), its model modelId, a title_source of default no title, a prompt typed a real_user's; dsh's are ~/.dsh/sessions ($DSH_HOME), a folder a session, the latest format's session[.vN].jsonl[.zstd] read whole, zstd frames and all, a subagent's (parentSession) in its parent's, a fork's seeded events (seedLength, or up to an inherited session/end-seed) counted where they were first written; Cline's are ~/.cline/data/sessions ($CLINE_SESSION_DATA_DIR, $CLINE_DATA_DIR, $CLINE_DIR), <id>.messages.json with its manifest <id>.json for the cwd, the prompt and the title, a subagent's other messages file beside it, a fork's messages before its forkedAt not counted, cline --id <id> to pick it up; Qoder's and Qoder CN's are Claude Code's lines in ~/.qoder/projects and ~/.qoder-cn/projects ($QODER_CONFIG_DIR, $QODERCN_CONFIG_DIR), qodercli --resume / qoderclicn --resume. Each folder is watched when it's there (Dirs). Tests keep HOME in their sandbox now. Tested with made-up fixtures for each (a ZCode database made in the test, dsh plain and zstd, forks of both formats, a Cline fork and subagent, both Qoder builds), and read-only against copies of this machine's ZCode database and dsh sessions: 2 and 13 sessions, their token totals the same as a separate tally of the raw rows
yetone2026-09-28 22:44:39 +08:00
839c762098
app: Magpie is in the Start menu on Windows (#158: Windows 便携版首次运行后,无法在开始菜单 / 系统搜索中找到 Magpie — @Aimer779) — the Windows build is one portable exe with no installer, so nothing put it anywhere Windows search looks. Each start of the desktop app (not the CLI, TUI or serve) now makes sure %APPDATA%\Microsoft\Windows\Start Menu\Programs\Magpie.lnk (the Programs known folder) opens the exe it runs as, symlinks resolved, in its folder, with its icon and "Magpie" as its description; one that already does is left be, one for where the exe was before it was moved is pointed here again. It is the shell's own link, made through WScript.Shell with go-ole (already in the build through Wails, now a direct require), in the background beside the magpie:// registration, and a failure is only logged. An update replaces the exe in place, so the shortcut stays good; a magpie left running from magpie.exe.old(-N) (or .new) points it at magpie.exe, never at what was moved aside. HKCU App Paths\magpie.exe is set to the exe (and its folder) so Win+R magpie opens it too. No uninstall entry, nothing copied. MAGPIE_NO_SHORTCUT=1 skips it (tests, sandboxes); other systems do nothing. Tested with the Windows test built here and run on Windows 11: a shortcut made, left as it was on a second start, pointed at the moved exe. Run on Windows 11 as the desktop app: the shortcut made with the exe's folder and icon, pointed anew after the exe moved, left as it was on a start with nothing changed; App Paths set
yetone2026-09-28 22:42:00 +08:00
63f9fa7465
agent: Claude Desktop runs on magpie in its third-party mode (#156: Claude Desktop 不会解锁 Claude Code 面板 — CC Switch 可以,咱这个支持吗?) — signed in with a Free account, Desktop's Code tab is only "Get Claude Code"; in its 3p deployment mode it needs no Anthropic sign-in and Code and Cowork run on the gateway. A Claude Desktop agent whose provider field switches it: on writes deploymentMode "3p" into Claude/ and Claude-3p/claude_desktop_config.json, a magpie profile in Claude-3p/configLibrary/<id>.json (inferenceProvider gateway, inferenceGatewayBaseUrl the gateway's address, inferenceGatewayApiKey magpie-claude-desktop, inferenceGatewayAuthScheme bearer; disableDeploymentModeChooser and coworkEgressAllowedHosts ["*"] only where unset) and its entry in _meta.json, applied — the keys and files CC Switch writes (claude_desktop_config.rs). No inferenceModels: Desktop lists /v1/models, which the gateway already gives it by ids it keeps. Off puts each deploymentMode back as it was (gone where there was none), the profile applied before applied again, magpie's profile and entry removed, and files and folders magpie made gone if nothing else went in; other keys and profiles are never touched. Folders as CC Switch finds them: ~/Library/Application Support, %LOCALAPPDATA% (a Claude… folder there if not Claude itself), $XDG_CONFIG_HOME. Desktop reads them at start-up, which the picker and notice say. The Library keeps giving Desktop's MCP servers to %APPDATA%'s file on Windows, listed once. Tested in a sandbox home: fresh, with the user's settings and 3p profiles (off restores every byte), on twice, on → off → on, drift, odd files refused, each system's folders; and against Claude Desktop 2.9939.2 on Windows 11 (winget): on, it started in 3P mode (provider gateway, apiHost the gateway) with the Code tab and no sign-in, and asked the gateway's /v1/models; off, it went back to claude.ai
yetone2026-09-28 22:28:01 +08:00
376a02bb80
library: tests keep Windows' LOCALAPPDATA out of the sandbox — Crush's crush.json is %LOCALAPPDATA%\crush's on Windows, and the sandbox left LOCALAPPDATA as it was, so TestTargets looked for Crush in the real one and found it missing (crush not a target), on main as with #157. Now it is blanked with APPDATA, and Crush is found in the sandbox's ~/.config/crush. Run on Windows 11 in a scratch profile
yetone2026-09-28 22:16:33 +08:00
2ff1842257
library: Crush on Windows gets the library's instructions in ~/.config/crush, where it reads CRUSH.md (#157)
kevinandClaude Opus 5.52026-09-28 23:16:26 +09:00
bb7ce5ec31
provider: an account signed in from magpie is listed even when the agent's own sign-in of it can't be read (tinysnake: workbuddy 登录以后,对应的 provider 并未出现) — once WorkBuddy's own account had been seen, logins.json remembered it as WorkBuddy's own (no secrets). With WorkBuddy then signed out, or its tokens kept encrypted ({"$wbEncrypted":…}), that entry is hidden, and signing the same account in from magpie was taken for a duplicate of it and dropped (addSideLogin): the sign-in said done, the toast showed, and no WorkBuddy provider appeared. addSideLogin is now told who the agent is signed in to right now; only when that is the same account is the new sign-in a duplicate, otherwise the remembered entry takes the new sign-in, and sideLogins doesn't add the own account twice once it's back. Copilot, Grok, ZCode and Gemini had the same flaw through the same code and are fixed with it. The window no longer says "added" when a finished sign-in isn't in the Providers list: it says so as an error. Tested with a fake WorkBuddy sign-in server in a sandbox HOME (own account remembered, then signed out or encrypted, then signed in from magpie: listed and signing with the new token; WorkBuddy readable again: still one account); not tested against the real WorkBuddy, and whether the reporter's WorkBuddy was signed out or encrypted isn't known
yetone2026-09-28 21:37:16 +08:00
46454d9801
gateway: a 429 that is a per-minute rate limit rests a minute, not a quarter of an hour (found reviewing #153) — usedUpWords took "Rate limit exceeded" and "Rate limit reached … tokens per min" for a used-up plan, and as magpie words an upstream error ("rate_limit_error" its type) exceeded.*limit matched every such 429 whatever the vendor said, so a provider rate-limited for a minute sat out 15 as out of quota (an OpenRouter free model's free-models-per-min, OpenAI's TPM, Anthropic's per-minute limit). Now a 429 in rate words (rate limit, too many requests, per second/minute, RPM/TPM) is a rate limit unless it also says the plan's allowance is used (quota, usage limit, per day/week/month, daily…), and a 429 saying that is out of quota, as a day's free requests are. Tested: those bodies as vendors and magpie word them, and a group through the gateway whose first member answers OpenRouter's free-models-per-min — it rests rate for 1m where main rested quota for 15m
yetone2026-09-28 21:37:46 +08:00
2de043dabf
provider: Cursor stays listed when cursor-agent can't say who is signed in (cataglyphis: 供应商选型中间歇无法显示 cursor,导致路由里不能正常路由到 cursor 的模型) — who Cursor's account is comes from cursor-agent about --format json, asked again behind the served answer every minute, and any about that failed, ran past its 10s (it asks Cursor's servers), or printed something besides its JSON was taken for nobody signed in: Cursor dropped out of the Providers page and of routing (All() lists the accounts for both), and that was kept on disk, until an ask a minute or more on came back. Now an ask that couldn't tell leaves what was served, on disk too, and is asked again in a minute (cliIdentity's ask returns an error for that); Cursor is taken as signed out only when about says so in its JSON or cursor-agent keeps no token. About's JSON after a line of its own (an update notice) is read too. Devin's ask is as before. Tested with fake cursor-agent scripts in a temp HOME (signed in, update notice, says nobody, fails, no JSON, fails with the token gone) and the cache through a failed ask and a sure sign-out; not tested against a real cursor-agent, and what made reporter's about fail isn't known
yetone2026-09-28 21:02:20 +08:00
e665d70b56
gateway: an Antigravity account Google wants verified says so, and rests (marsxxl: Antigravity 返回「Verify your account to continue」403) — Cloud Code Assist refuses such an account with a 403 whose details say VALIDATION_REQUIRED, a validation_url in their metadata (as pi-ai's google-validation reads it); magpie passed on only the message, and every reconnect went back to the account Google had stopped. Now provider.Verification knows the refusal (the reason, or its words) and APIError adds what to do: open the link, when it's https, in a browser signed in to that account, or else the Antigravity app (or Gemini CLI), then try again. The account rests half an hour as failVerify ("needs verification", 账号需验证) — the last one left too, which rested never — and for a minute the agent's retries get the same error from magpie without asking Google. The Routing page shows the rest with a Verify link and "It's verified — try it again", which lifts it (POST /api/gateway/unrest, Server.Unrest); an answer lifts it as before. Tested with fake upstreams in a sandbox HOME: with a link and without, held retries not sent on, a group falling back past it; the exact body marsxxl got isn't known
yetone2026-09-28 20:50:54 +08:00
b22815be9c
tui: the Sessions page lists the sessions (Kumo31: tui sessions里能看到统计信息,但没有列出具体session) — it opens on the sessions active in the range, the latest first, under the model and folder picked, as the app and magpie sessions list them: when, agent, folder, tokens, cost and title, as many as fit around the one picked with how many more above and below. ↑↓ pick one and enter resumes it in this terminal (its resume command, shown under the list, through sh or PowerShell; back on the page when the agent quits), or says its folder is gone rather than a shell's exit status; s (or tab) goes to the stats — totals, chart, top models and folders — and back
yetone2026-09-28 20:40:44 +08:00
ef247c1889
library: a long skill list is drawn near the view first and then filled in while the page is idle (requestIdleCallback, or 20 rows every 24ms in WebKit), every row kept once drawn so a scroll neither builds nor removes rows (a scroll that outruns the filling finishes it at once), each row is contained as a skipped one was and shows its buttons without the fade while its list scrolls (in WebKit each fade under a passing pointer was a long frame), and a chip's grey icon is made once rather than filtered on every paint (a drawing with its colours greyed by grayscale's own sum, a picture greyed pixel by pixel, one in the text's colour through a relative colour) with its cut-out ring an outline instead of a spread shadow, so scrolling 300 skills in WebKit has a median of 0–8 long frames where main had 11–37 and 8767eb6 94–152
yetone2026-09-28 20:27:31 +08:00
372eb2cc07
library: the Skills tab draws only the rows near the view — each group's list is a window with room kept above and below, rows held to fixed heights so what's kept is exactly what's missing, a few more a frame as a scroll nears the end of what's drawn and those far behind taken away, no content-visibility flips on every scroll — a single big group (215 on this computer) no longer skips folding, a group of more than eight splits into parts by the folder its skills sit in (the path inside a GitHub repository, the folder a local one was linked from) or else by a start of their names three or more share, each part folding on its own and remembered, and the filter redraws only the rows, 120ms after the last key
yetone2026-09-28 17:08:44 +08:00
e91aaab33c
library: the MCP page no longer spells out an agent's own servers (ARNO: 这些文字可能更应该出现在代码注释里,而不是ui上) — the line naming Codex's node_repl, a server Codex adds itself each time it starts and magpie leaves alone, told the user nothing they could act on; those servers stay unlisted, and why is now a comment in the code
yetone2026-09-28 20:25:02 +08:00
761156a816
agent: Pi asks a Responses-native model on Responses (Leo: 同协议优先) — every magpie model in Pi's models.json went out as openai-completions, so a ChatGPT sign-in's models, a Responses-only provider's, and GPT on OpenAI's API or Copilot's were asked on Chat and translated to Responses by the gateway. Now each such model carries "api": "openai-responses" (Pi takes a model's own api over its provider's, and posts it to baseUrl/responses), so the gateway relays what Pi sent as it is: reasoning effort and summary, its encrypted reasoning, images, tools, prompt_cache_key; a ChatGPT sign-in's still made into Codex CLI's request. Which API is a model's is provider.Native — what the provider serves it on itself, Responses first for an OpenAI model where the gateway already put it first (ResponsesFirst, moved from the gateway). Chat providers, groups, Cursor/Devin/Kiro/Claude Code sign-ins and Anthropic-API models stay on openai-completions: Pi's anthropic-messages picks thinking by the Claude ids it knows and asks a newer Claude for a thinking budget it refuses, which magpie's translation doesn't. Tested with Pi 0.73.1 and @earendil-works/pi-coding-agent 0.87.1 against a sandbox gateway and a fake Responses upstream: /v1/responses relayed with effort high, xhigh, none (thinking off); a Chat model still on /v1/chat/completions
yetone2026-09-28 20:17:48 +08:00
97e55faca9
gui: the chart label comment sits over the rule it explains — #149 moved the last label's rule to every chart and left its comment above .sess-list
yetone2026-09-28 20:10:06 +08:00
2baad5366c
provider: Antigravity's models at several levels are one model with those levels (#150: 统一 Antigravity 模型变体与客户端推理档位的映射) — Antigravity lists gemini-3.7-flash-low, -medium and -high as three models, "Gemini 3.7 Flash (Low)" …, so a client picked a level twice: once in the model, once as its reasoning effort, with no telling which won. Now ids that are one id with an effort word after it (-low, -medium, -high, -extra-low, -minimal, -xhigh) are one model, gemini-3.7-flash "Gemini 3.7 Flash", declaring only the levels there are (low,medium,high; Gemini 3.1 Pro low,high), so Codex, Pi and the rest get reasoning levels for it. The level a variant is at is what Antigravity's name says where each name says a different one (gemini-3.5-flash-extra-low is "(Low)", gemini-3.5-flash-low "(Medium)"), else its id's word; a model only named like another (gemini-3-flash-agent, "Gemini 3.5 Flash (High)"; gemini-pro-agent) or with no sibling (gpt-oss-120b-medium) stays as listed. A request asks for the variant the effort picks, an effort it lacks at the nearest level (xhigh is high; medium on low/high is high); with none asked, the id without a level if Antigravity has one, else high — what Gemini 3 does unasked — else the highest. A variant's request carries no thinkingLevel, so the id and the level can't disagree. An old variant id still works: as named with no effort, and moved to the effort asked for. Saved picks and agents set to a variant (antigravity/gemini-3.7-flash-high) are moved to the family, at that level where the agent's own is unset, as Cursor's are. For Gemini 3 models without variants, medium now goes as medium to Flash (which takes minimal/low/medium/high) and still as high to Pro (low/high). Tested against the list an account's fetchAvailableModels gave (sandbox cache)
yetone2026-09-28 20:09:01 +08:00
fb4b6c76cd
library: a skill whose folder is gone can be removed (#151) — its folder was moved aside with the backups on removal, and with no folder the move failed (rename …: The system cannot find the file specified), so a skill marked as no longer in the library stayed listed for good. Now only its entry is taken out when its folder isn't there
yetone2026-09-28 20:01:48 +08:00
e9b3c8f2ca
provider: Cursor's per-effort picks become the model with efforts (Leo: Cursor 旧模型清单没有迁移) — a Cursor model list picked before each family was one model still named grok-4.7-low … -xhigh and the -fast ones, so /v1/models and the model lists written for agents (Pi's models.json) kept those ids with no reasoning, and Pi never sent reasoning_effort. Now each saved pick that is one of Cursor's ids at an effort is the family magpie offers for it (grok-4.7, grok-4.7-fast), in the order picked, once; ids of a family of one stay. An agent set to such an id (magpie/cursor/grok-4.7-low) is moved at start-up to the family, spelled its way, and to the effort the id was at when its own is unset and it has that one; a model the picker doesn't offer is left. A request naming one of Cursor's own ids with a reasoning_effort goes at that effort where Cursor has the id (grok-4.7-low at high is grok-4.7-high), else as named; and Chat Completions' service_tier: priority asks for the fast id as Responses' does. Tested with sandbox HOME/cache: legacy picks → grok-4.7|low,medium,xhigh, grok-4.7-fast; a sandbox Pi moved to curs/grok-4.7 at low
yetone2026-09-28 19:55:03 +08:00
24695c19ba
library: the MCP page's note on an agent's own servers says what they are (ARNO: mcp服务器页面好像有些多余的内容被显示到ui上了) — "Codex 每次启动都会自己加上这些…: node_repl" read as if it pointed at servers listed above it, which it doesn't; it now says node_repl is Codex's own MCP server, one it adds itself each time it starts, and that magpie leaves it as it is
yetone2026-09-28 19:59:07 +08:00
ee8f9eca24
provider: Jev's endpoint can be given in the editor (ARNO: ui中没有地方给我填写自定义的端点) — v0.1.294 took Cloudflare's documented address, …/accounts/<id>/ai/run, but a Jev preset's editor only showed its endpoint, and a save rebuilt the provider from the preset, so there was nowhere to paste it. A Jev provider (TypeSafe, Vercel, Cloudflare) now has a "Jev endpoint" field, the preset's address to start with, kept on save and shown again when it's opened; a preset with no decision API is given none. Tested in a sandbox web UI (WebKit): Cloudflare Jev added with an /accounts/<id>/ai/run endpoint, saved as given, reopened with it and saved again unchanged
yetone2026-09-28 19:51:46 +08:00
0de3094d67
agent: WorkBuddy takes magpie's models (能否作为Agent的支持WorkBuddy) — a WorkBuddy agent whose provider field puts every magpie model into WorkBuddy's picker: entries in ~/.workbuddy/models.json ($WORKBUDDY_CONFIG_DIR), the custom-model list WorkBuddy reads and watches (no restart), as OpenAI chat-completions models at the gateway's /v1/chat/completions under magpie-workbuddy, with each model's context, output, images and reasoning levels (reasoning.supportedEfforts, canDisableThinking where it can think off). WorkBuddy's own entries (its local models) and the CLI's {models, availableModels} form are kept; a magpie model turned off in WorkBuddy stays off; off takes only magpie's out. Its requests say CLI/<ver> WorkBuddy/<ver>, so they're known by the key. Tested with WorkBuddy 5.5.6's own CLI against a sandbox gateway: deepseek/deepseek-v4-pro answered, reasoning_effort sent, usage under WorkBuddy
yetone2026-09-28 19:24:39 +08:00
3ad65b03ed
gateway: Linux builds again — syscall has no SO_REUSEPORT on linux (only darwin), so e0c6892's dev handover broke every Linux release from v0.1.291 on (listen_reuseport.go: undefined: syscall.SO_REUSEPORT); it's taken from golang.org/x/sys/unix, which has it on both
yetone2026-09-28 19:18:01 +08:00
571766e6ff
provider: Jev on Vercel is asked at its TypeSafe API, and on Workers AI at the account the endpoint names (ARNO: Vercel Jev 的默认端点为什么不是 https://ai-gateway.vercel.sh/typesafe;Cloudflare 官方写的是 …/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run,当前默认端点好像没起作用) — Vercel's preset now points at https://ai-gateway.vercel.sh/typesafe, its documented TypeSafe-compatible API: System One's own request and answer at /v1/systemone with typesafe-ai/jev, the key checked by /v1/models; …/typesafe/v1, …/v1/systemone and the bare host are taken for it, and a saved /v4/ai base keeps the AI SDK evaluation-model protocol it used (ViaVercelEval). Workers AI takes the address Cloudflare's docs give — an endpoint with /accounts/<id> in it, /ai/run after it or not, is asked there as it is and its key checked by that account's /ai/models/search, since a token made for Workers AI alone may not list /accounts; a placeholder ($CLOUDFLARE_ACCOUNT_ID) is looked up as before, and a token /accounts refuses is told to put its account ID in the endpoint
yetone2026-09-28 19:14:08 +08:00
aed12ac60f
codex: the ChatGPT account's own models Codex lists follow the user's picks too (在magpie里把ChatGPT提供商只勾选GPT-6-Sol,codex里还是显示所有模型 — @vemsux) — signed into ChatGPT with magpie as the base URL, Codex asked the backend for its model list and magpie passed every model the account can reach straight through, so picking among them on the codex provider only ever narrowed magpie's own added models, never ChatGPT's. Now the gateway keeps that /models answer to the slugs the user kept (provider.CodexNativePicked, from the codex provider's picks); untouched picks leave the list whole, as before. The dedup that skips a ChatGPT account's models in CodexListed is unchanged — the backend still lists them, now only the kept ones
yetone2026-09-28 19:06:32 +08:00
c8d7a995d1
rtk: Codex isn't given an rtk older than 0.50 (LeeHom: rtk's installer didn't add its hook to Codex) — rtk has a hook for Codex (rtk hook codex in hooks.json) from 0.50.0 on; an older rtk init -g --codex only puts @RTK.md in AGENTS.md, which rewrites no command, so switching Codex on ran it and then said the hook wasn't there. With an rtk before 0.50 the Library shows Codex with "Update RTK" (需更新 RTK), its switch off, the tooltip and magpie library rtk saying to update it (brew upgrade rtk, or its installer again) first
yetone2026-09-28 19:02:20 +08:00
e0c6892f56
dev: a Go change hands the backend over instead of cutting the agents off (为什么老是会reconnecting) — make dev killed the backend, and the dev gateway with it, on every Go save, so Cindy's Pi on :3426 lost its stream and reconnected; now the new backend listens beside the old one (SO_REUSEPORT, dev only), and once it does the old one is sent USR2, stops taking requests, finishes those in flight — a stream as long as it takes — and exits. A backend that builds but never comes up leaves the old one serving. Tested in a sandbox: a 12s stream through the gateway ran to [DONE] across a handover, new requests went to the new backend, and the old one exited when the stream ended
yetone2026-09-28 18:56:17 +08:00
9eccb96a51
provider: ZCode's and WorkBuddy's models take the reasoning levels their apps offer them (当然要做) — ZCode's from its modelRules' reasoningLevel (disabled is none; enabled, GLM-5-Turbo's one level, is high): GLM-5.3 low/high/max, GLM-5.2 none/high/max; WorkBuddy's from its config's reasoning.supportedEfforts, with none only where its CLI offers thinking off (deepseek-v4-pro): hy3 low/high, glm-5.2 high/xhigh, kimi-k3-1 low/high/xhigh, and a model it gives no levels still takes any. The written-in lists carry them too. gateway: Z.ai's GLM-5.2 and GLM-5.3 are asked their effort in output_config.effort beside thinking on, as ZCode asks them, built or passed through and fitted to their levels — a budget alone left them at their default: tested live, budget_tokens 4096 thought 4.8k–7.6k chars, output_config low 0.9k
yetone2026-09-28 18:56:00 +08:00
35f43e6665
gateway: Claude Desktop keeps every magpie model (#148) — its gateway check drops any id naming another vendor's model (deepseek, kimi, gpt, codex, glm, qwen… anywhere in it, anthropic/ in front or not), so anthropic/deepseek/deepseek-flash was turned away and, asked without the magpie-claude-desktop key, /v1/models gave it bare ids it kept none of ("returned 0 usable models { rawCount: 13 }"). A model whose id doesn't already read as Claude's is listed to it as anthropic/magpie-<number>, a hash of its magpie id that magpie serves again (/v1/messages, count_tokens, /v1/models/{id}, with [1m] too), its name as display_name and its magpie id as description; Desktop is known by its Electron User-Agent (… Claude/<ver> Chrome/…) as well as by the key. Checked with Desktop's own checks cut out of its app.asar against a sandbox gateway: 4 of 4 kept, was 0
yetone2026-09-28 18:49:05 +08:00
29c27c65f2
routing: an account out of quota rests until it says it's back, not an hour at a time (关于路由组优先级高的模型异常的展示文案 #147) — ChatGPT's usage-limit refusal reaches the failover put in words, its resets_at only as the Retry-After magpie made of it, and a Retry-After is trusted for an hour at most, so a Plus account out until 21:34 read "59 分钟后恢复" and was tried, refused and benched again each hour; the reset now goes on beside the error for the rest to take as the vendor's own, the window it filled renews next, a bare Retry-After alone keeps the hour, a rate limit and a failure keep their short rests, and a Codex reset spent in magpie brings the account back at once. The Routing page says when as well as how long: "quota used up · back at 10:29 PM · in 3 h 41 min" (额度用尽 · 22:29 恢复 · 还有 3 小时 41 分钟)
yetone2026-09-28 18:48:56 +08:00