yetone
d924802de5
usage: a streamed reply's time to its first token is kept, and its first text's (#196: usage 记录首字延迟(TTFT),用于计算模型的真实生成速度) — usage.jsonl had only a call's whole ms and its out tokens, so how fast a model writes couldn't be told from how long it waited or thought. The reply is now read as it goes to the agent, in the agent's protocol whatever the vendor spoke (Anthropic content_block_delta text/thinking/input_json and a tool_use's start, Chat content/reasoning_content/reasoning/tool_calls, Responses output_text/reasoning/function_call_arguments deltas and a function call's start, Gemini parts), and each record gets ttft_ms to the first content and first_text_ms to the first text, counted from the request as ms is, so ms − ttft_ms is the writing time; a reply that isn't streamed gets neither, and omitempty leaves old records as they were. Only the stream's events up to its first text are read (a JSON reply, or past 8 MB, not at all). Each try in the routing trace keeps its own from when it was sent, so a group that fails over shows which member was slow, and the route, the request log and the Codex backend's relay keep them too. Shown on the Routing page (TTFT in the list, first token / first text / tok/s in a try's story), in the Gateway's request log, and on the Usage page and in magpie usage per model as the mean TTFT and tok/s = out ÷ (ms − ttft) over the answered streamed calls. Tested with fake vendors streaming a gap apart for Anthropic, Chat and Responses, as they came and translated (Chat from Anthropic, Responses from Chat), the ChatGPT backend without a Content-Type, a whole reply, a group whose first member fails (its try untimed, the second's timed from its own start, the request's including the failed try), each protocol's events and split writes, and the summary's sums; the GUI's browser tests pass
2026-09-29 16:40:03 +08:00
..
usage: a streamed reply's time to its first token is kept, and its first text's (#196: usage 记录首字延迟(TTFT),用于计算模型的真实生成速度) — usage.jsonl had only a call's whole ms and its out tokens, so how fast a model writes couldn't be told from how long it waited or thought. The reply is now read as it goes to the agent, in the agent's protocol whatever the vendor spoke (Anthropic content_block_delta text/thinking/input_json and a tool_use's start, Chat content/reasoning_content/reasoning/tool_calls, Responses output_text/reasoning/function_call_arguments deltas and a function call's start, Gemini parts), and each record gets ttft_ms to the first content and first_text_ms to the first text, counted from the request as ms is, so ms − ttft_ms is the writing time; a reply that isn't streamed gets neither, and omitempty leaves old records as they were. Only the stream's events up to its first text are read (a JSON reply, or past 8 MB, not at all). Each try in the routing trace keeps its own from when it was sent, so a group that fails over shows which member was slow, and the route, the request log and the Codex backend's relay keep them too. Shown on the Routing page (TTFT in the list, first token / first text / tok/s in a try's story), in the Gateway's request log, and on the Usage page and in magpie usage per model as the mean TTFT and tok/s = out ÷ (ms − ttft) over the answered streamed calls. Tested with fake vendors streaming a gap apart for Anthropic, Chat and Responses, as they came and translated (Chat from Anthropic, Responses from Chat), the ChatGPT backend without a Content-Type, a whole reply, a group whose first member fails (its try untimed, the second's timed from its own start, the request's including the failed try), each protocol's events and split writes, and the summary's sums; the GUI's browser tests pass
2026-09-29 16:40:03 +08:00
2026-09-29 16:29:33 +08:00
tray: clicked, the bird flaps as the header logo does on hover (一定要用应用里的那个 Magpie icon 被 hover 的动画效果) — the frames were a bend of the outline of my own; now build/icon/gen.go draws app.css's .logo.wag itself: the bird cut into body, tail and wing by index.html's clip paths, each turned about the same origin through the same keyframes, cubic-bezier(.3, 0, .3, 1) between each two, the whole bobbing about its feet, over the same .9s — 29 frames played 30ms apart. Checked against Chrome's own rendering of the logo paused at the same 29 moments: at most 0.7% of pixels differ, all of them at anti-aliased edges
2026-09-28 18:43:55 +08:00
redact: a gateway's key in "key": "oc_sk_…" is masked, and Settings → Privacy takes the user's own masking rules (#195) — an OpenCode Go key in providers.json went to the vendor as it was: the API key rules wanted sk- with a hyphen, and a field called key alone was none of the secret field's names. Now a key of a gateway or relay, two to four letters and _sk_ (oc_sk_, or_sk_) with digits in it, is an API_KEY wherever it is, and a field named key and nothing more (not sort_key, monkey or obj.key) is a SECRET when its value is 16 or more letters and digits both, so a map's "key": "value" and key = "someIdentifier" are left alone; \"key\": \"…\" in JSON inside a string is found too. The secret field's names and its markers come from one list, so they can't drift apart, and of two rules finding the same value the first keeps it, so its placeholder no longer changes between an API_KEY and a SECRET from one request to the next. Masking rules, next to 脱敏词: a name for the placeholders (upper case letters, digits and _, 24 at most) and a prefix (then 8 or more key characters) or an RE2 regular expression, group 1 the value if it has one, masked with the secrets while 脱敏密钥 is on and put back as the others are, the user's name winning where one of magpie's finds the same value. They are set on their own: a pattern that doesn't compile, matches nothing at all, or is too long (300), a prefix under 3 or over 64, both at once, or more than 32 rules, is refused with the reason under the add row and what was typed kept. Tested: every row of the issue's table and the false positives, the rules' tidying, errors, stable placeholders, restore, overlaps, and kinds with digits in a stream; the settings file and the gateway's count_tokens with a rule; the page in a stub magpie web (add, a bad regex, remove, zh dark)
2026-09-29 15:26:01 +08:00
2026-09-29 10:15:13 +08:00
2026-09-27 03:44:55 +08:00
2026-09-28 18:56:50 +08:00
2026-09-28 01:12:46 +08:00
2026-09-28 14:54:04 +08:00
2026-09-28 14:54:04 +08:00
2026-09-24 12:17:45 +08:00
2026-09-24 12:17:45 +08:00
2026-09-29 11:59:57 +08:00
2026-09-28 18:56:50 +08:00
2026-09-28 18:56:50 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
2026-09-28 17:51:03 +08:00
2026-09-28 18:56:50 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
2026-09-26 14:22:47 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
2026-09-25 02:19:32 +08:00
2026-09-25 02:19:32 +08:00
2026-09-26 14:14:26 +08:00
routing: a group's member may be a model at an effort of its own, provider/model:low (#189, @luw2007: model + effort 才是完整的组合项) — a member was only a model, reasoning as the agent asked or as the group's classifier picked, so "the same model, cheap and quick" and "the same model, thinking hard" could not both be in a group, nor could a rule send to one of them. A member now may carry an effort (none … max): a request routed to it is asked for that much reasoning whatever the agent asked or effort=auto picked, at the level the model has nearest, while the vendor is asked for the model's own id. The same model at two efforts is two members that rules (use=m:high), stickiness and the trace tell apart; an id whose own last part is a colon (a :free, :7b, :0) stays the model's. The group's reasoning levels are those of its members that follow the agent, and the editor has a reasoning button on each member. Tested with a fake provider through a sandbox magpie: the upstream bodies carry the fixed effort in Chat, Responses and Anthropic shapes, and the routing view shows m1:low / m1:high as two seats, light and dark
2026-09-29 13:45:29 +08:00
2026-09-26 01:03:33 +08:00
2026-09-24 01:09:59 +08:00
2026-09-26 14:30:16 +08:00
2026-09-24 17:13:03 +08:00
2026-09-24 17:13:03 +08:00
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
2026-09-29 01:01:25 +08:00
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
2026-09-28 19:51:46 +08:00
2026-09-29 10:17:30 +08:00
providers: StepFun and StepFun (China) show the Step Plan's 5-hour, weekly and credit windows on the Usage page (StepFun 国外版跟国内版这两个provider都应该支持显示额度) — the platform tells them only to a sign-in on platform.stepfun.ai or .com, never to a key ("api key not permitted for this method"), and its session cookie is HttpOnly with no way back to an app, so the user signs in in their own browser and brings the session over: the provider's editor has a bookmarklet that, on the signed-in platform page, asks the platform to renew the session as the page does and copies it, and a box to paste it into (the Oasis-Token cookie from developer tools is taken too). magpie keeps it in stepfun-auth.json (0600), one per site, renews it before it runs out and once more when it is refused, and asks QueryStepPlanRateLimit and GetStepPlanStatus for a card with the plan, its windows and when it ends; an anonymous session, another site's, or one renewed as someone else (past the refresh token's 30 days) is not kept or shown. Tested with a fake StepFun platform (renewal, early expiry, another account, pastes of each kind), the bookmarklet run against a stubbed page, and the field in a sandbox magpie web (signed out, a bad paste, signed in, sign out); not with a real StepFun sign-in
2026-09-29 16:04:47 +08:00
windows: the desktop app no longer opens a console window for every command it runs (#54) — it is linked as a GUI program and has no console, so each console CLI it started (devin auth status and models list, devin acp for every Devin turn, claude, codex, cursor-agent and grok probes and runs, grok login) was given a new console by Windows, and a Windows Terminal window with it, some every few seconds while the app sat idle. Every command magpie runs is now made through internal/proc, which starts it with CREATE_NO_WINDOW when magpie has no console of its own: the child gets a console without a window, and its output, which magpie always pipes back, arrives as before. A magpie run in a terminal (magpie serve, the TUI, the desktop app started from one with a command) has one, and its children share it as they did, so Ctrl+C there still reaches them. The relaunch after an update keeps its DETACHED_PROCESS, added to rather than replacing the flags it was made with, and a test fails on any command made with os/exec directly, so a new one can't bring the windows back
2026-09-25 14:04:44 +08:00
2026-09-24 12:17:45 +08:00
2026-09-24 12:17:45 +08:00
sessions: OpenCode's and Pi's sessions are listed too (貌似没有opencode和pi的session,能支持一下么) — Usage → Sessions, magpie sessions and the TUI read OpenCode's opencode.db (or $OPENCODE_DB) read-only, or its older storage/ JSON files when there is no database, under $XDG_DATA_HOME/opencode or ~/.local/share/opencode, a subagent's session counted under the one that started it; and Pi's JSONL sessions under $PI_CODING_AGENT_DIR or ~/.pi/agent, plus $PI_CODING_AGENT_SESSION_DIR or settings.json's sessionDir, a forked session not counting again what it copied from its parent. Each gets its title, folder, times, tokens per model with cache reads and writes, cost, and a resume command (opencode --session <id>, pi --session <id>); the folders note names only the agents that are there
2026-09-28 18:45:07 +08:00
2026-09-26 14:30:16 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
web: magpie web serves the app's window to a browser, with the gateway beside it — for a computer that can't show the app: no desktop, WSL, a server over SSH, or the CLI-only build, which now carries the page too (what of the app needs Wails is left out of nogui builds). Every request needs this run's key, which the printed link carries and trades for a cookie other sites' pages can't send with a POST; --lan serves it on the network too, with a warning, --addr elsewhere, --no-open leaves the browser shut. In the browser the page opens links and sign-ins itself, names a folder instead of opening it, and leaves out the tray, the Dock and open at login. Tested from a nogui build in a sandbox: no key, a wrong key and a cookieless POST are refused; with the link Agents, Providers and Settings load and a setting saves. Issue #102
2026-09-27 16:21:26 +08:00
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
2026-09-29 02:22:35 +08:00
2026-09-24 01:09:59 +08:00
2026-09-28 09:27:49 +08:00
2026-09-28 16:15:40 +08:00
2026-09-28 09:27:49 +08:00
2026-09-26 21:00:33 +08:00
2026-09-27 19:39:45 +08:00
usage: a Codex account's rate-limit resets are on its card, so they don't go unused (可能把 resets card 在里边反应出来么?免得我们忘了用) — wham/usage's rate_limit_reset_credits count, and from /wham/rate-limit-reset-credits when the first of those left runs out, show as "↺ 2 resets · until Sat 22:30" under a hairline on the tray's Usage card, under the account's windows in the window's Usage view, and in magpie quota / accounts and the TUI (nothing when there are none, no date when none expire); "Use one…" asks first — which account, that its windows start again at once, that it can't be undone, and that there is nothing to start again when no window has been used — then spends one with a fresh redeem_request_id on that account (POST /api/usage/codex-reset, or magpie quota reset [<account>] [--yes]), says what came of it in words and reads the usage again; the account signed in now is found from Codex's own auth.json, not only the list magpie keeps. panel: a section's account count is a quiet rounded pill by its name, not a bare 2 at the far end (那个 2 是没有仔细打磨), the "N accounts" kept as its tooltip
2026-09-28 18:01:48 +08:00
2026-09-27 17:26:32 +08:00
library: a project's agents can have some of the library's skills as the project's own — under Skills, In projects takes a folder (the system's picker in the app, a typed path anywhere) and each of its skills gets agents' chips; magpie links the skill into <project>/.claude/skills for Claude Code and <project>/.agents/skills for Codex, Gemini CLI, OpenCode, Pi, Cursor and Copilot (the agents documented to read it; MiMo Code, Crush, ZCode, DeepSeek Harness and oh-my-pi aren't, so they're left out), or copies it when the project asks for copies, a copy made again whenever the library's skill changes (updates included). What it places is listed between magpie's marks in the project's .gitignore, made if there was none; taking a skill or the project away removes only what magpie placed, its lines and the folders it made once empty, and a folder of the same name that isn't magpie's is left as it is and said so. The home folder, or one whose project skills folder is an agent's own, can't be added
2026-09-28 13:34:17 +08:00