Files
magpie group set <id> levels=low,medium,high,xhigh, levels= clears; TUI l; GUI group editor's Levels: its models' shared / named) is offered instead in /v1/models, Codex's catalog, Pi and the rest; only levels magpie knows are taken, stored lowest first; a group in a group that names its own offers them for its models; unset is as before. A member without the level asked is sent its nearest, as it already was. The GUI's group save also keeps a family set from the CLI. TestGroupLevelsOverride, TestGroupLevelsReachAgents, TestGroupLevelsNamed (passthrough and translated: medium→high, xhigh→max on the low/high/max member, as asked on the one with all), TestGroupSetLevels and routing-levels.test.cjs (Chromium, WebKit, en/zh) fail without the change. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass (TestUserPath, a known flake under load, passes alone); click-scroll, old-webkit, routing-effort(-row), routing-levels, settings-groups GUI tests pass.
zcode: a seat on a team's GLM Coding Plan (团队套餐) is signed in, routed and metered as ZCode does it, on BigModel (智谱) as well as Z.ai, and a Zhipu key on a team plan shows its 5-hour and weekly windows and resets (#236 EZN7L2C3: a BigModel team GLM Coding Plan, the sign-in refused it and the usage was never read) — magpie's ZCode sign-in only went to Z.ai and only looked for the account's own coding-plan key, so a member of a team's plan, whose seat lives in a team project, was refused, and a key on a team plan read nothing from /api/monitor/usage/quota/limit. Read from ZCode.app 3.14.3 (host/index.js and config/provider/zcode-builtin.json): the team rules account:{zai|bigmodel}-team-coding-plan use the individual plans' base URLs with no extra inference headers; getCustomerInfo lists the projects, projectType "2" being a team's (isBigModelTeamCodingPlanProject); fetchTeamCodingPlanEntitlement asks /api/biz/team/subscribe/product/querySubscribeDetail (EFFECTIVE + memberGrantStatus VALID usable, UNASSIGNED no seat, EXPIRED run out); ensureBigModelTeamPlanProjectApiKeyWithStatus / copyBigModelTeamPlanProjectApiKeySecret find or create "zcode-team-api-key" (keyType 2) in the team project and copy its secret; createBigModelBizHeaders sends the access token bare in Authorization with bigmodel-organization / bigmodel-project; resolveAccountTeamPlanRuntimeApiKey takes the stored oauth:{family}:access_token (skipping BigModel's when it equals zcodejwttoken); buildQuotaLimitUrl adds type=2 and createBigModelUsageHeaders sends the key with the org/project headers; ZCode keeps the chosen team in ~/.zcode/v2/setting.json providerFamilyConnectionSelections (legacy modelProviderFamilySelectedKeys "team-plan:builtin:…", migrateLegacyAccountConnectionSettings); pollPendingOAuth/startOAuthWithPolling init with {provider:"zai"|"bigmodel"}, BigModel's redirect param being
redirect, its token the poll's bigmodel.access_token. Now: the sign-in first asks where the account is — Z.ai or BigModel (智谱) (POST /api/signin takes a site, StartSignInAt, "zcode:bigmodel" too) — and on its site tries the account's own plan, then a team project with a usable seat (a new zcode_team.go: zcodeTeamSignIn keeps the team key, org, project and the biz token, the plan named by its product, "GLM Coding Team" otherwise), then the Start Plan; a team seat not yet granted or a team plan expired is refused saying so ("…has no seat on it yet — ask the team's admin…"), and an account with none of them names both plans and the site's subscribe page. ZCode's own team login is read from its credentials and setting.json (zcodeOwnTeam), its key minted lazily and kept (zcodeTeamKeyOf, retried after a minute, "sign in to ZCode again" when refused). Team requests go to the family's Anthropic base signed with the team key, no ZCode headers, never the Start Plan. Team usage asks bigmodel.cn (or api.z.ai) /api/monitor/usage/quota/limit?type=2 with the key and Authorization, Bigmodel-Organization, Bigmodel-Project, Set-Language, Accept-Language: CREDIT_LIMIT windows, unit 3 "5 hours" and unit 6 weekly, "current / total" when there is no remaining; /api/biz/customer-package-reset/list?targetType=TEAM gives the resets, fiveHourResets and weekResets counted where available is true, the soonest expireTime as until; the plan's end from querySubscribeDetail, Renew off. ResetCredits gains byWindow/fiveHour/weekly and Words(), "2 five-hour resets · 1 weekly reset" in the CLI, TUI and GUI (en and zh), with no "Use a reset" button for them since they are spent on the vendor's page. The Zhipu GLM key provider (planquota.go) falls back to the team query when the personal one fails or has no windows, adding the team headers when a ZCode team login holds that key. Personal accounts, Coding Plan and Start Plan, are routed, signed and metered as before. Tested with a new internal/provider/zcode_team_test.go against a fake bigmodel.cn/Z.ai in a sandbox HOME, no real tokens: a BigModel team sign-in through StartSignIn("zcode:bigmodel") is added (redirect param, plan "GLM Coding Team Pro", key made with keyType 2, org/project kept), its requests at the BigModel base signed with the team key and no ZCode headers, usage 5 hours 42% "420 / 1000" with a 5h span and weekly 10%, the quota headers sent, resets 2 five-hour and 1 weekly until 2026-10-05, plan until 2026-12-31; an unassigned seat is refused with no key made; ZCode's own team login from credentials + setting.json is found and metered while an individual plan stays as it was; the key provider's team fallback. TestPlanQuotas gains the type=2 case; the zcode Start Plan and account tests pass. A new internal/gui/tests/zcode-site.test.cjs, Chromium and WebKit, en and zh: starting ZCode's sign-in asks the site and posts nothing, BigModel posts {agent:"zcode",site:"bigmodel"} and keeps it, and the by-window resets read in both languages; signin-callback, click-scroll and login-import pass. go vet ./internal/..., go build -tags nogui (and GOOS=linux, GOOS=windows) and go test -tags nogui ./... pass (TestUserPath timed out under load and passes alone). Not tried against a real account: BigModel's OAuth sign-in and poll shape, the Set-Language values, customer-package-reset's field formats, querySubscribeDetail on Z.ai, type=2 for a pasted key with no org/project, and the time formats are from ZCode's code, not seen on the wire; not tried in the real Wails window.
routing: a group can name the reasoning levels agents are offered, so one member with few doesn't take the rest from the others (#295) — a group offered only the levels every member has, so deepseek-flash (low/high/max) beside models with medium and xhigh left the group without them. Group.Levels (CLI
magpie group set <id> levels=low,medium,high,xhigh, levels= clears; TUI l; GUI group editor's Levels: its models' shared / named) is offered instead in /v1/models, Codex's catalog, Pi and the rest; only levels magpie knows are taken, stored lowest first; a group in a group that names its own offers them for its models; unset is as before. A member without the level asked is sent its nearest, as it already was. The GUI's group save also keeps a family set from the CLI. TestGroupLevelsOverride, TestGroupLevelsReachAgents, TestGroupLevelsNamed (passthrough and translated: medium→high, xhigh→max on the low/high/max member, as asked on the one with all), TestGroupSetLevels and routing-levels.test.cjs (Chromium, WebKit, en/zh) fail without the change. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass (TestUserPath, a known flake under load, passes alone); click-scroll, old-webkit, routing-effort(-row), routing-levels, settings-groups GUI tests pass.
routing: a group can name the reasoning levels agents are offered, so one member with few doesn't take the rest from the others (#295) — a group offered only the levels every member has, so deepseek-flash (low/high/max) beside models with medium and xhigh left the group without them. Group.Levels (CLI
magpie group set <id> levels=low,medium,high,xhigh, levels= clears; TUI l; GUI group editor's Levels: its models' shared / named) is offered instead in /v1/models, Codex's catalog, Pi and the rest; only levels magpie knows are taken, stored lowest first; a group in a group that names its own offers them for its models; unset is as before. A member without the level asked is sent its nearest, as it already was. The GUI's group save also keeps a family set from the CLI. TestGroupLevelsOverride, TestGroupLevelsReachAgents, TestGroupLevelsNamed (passthrough and translated: medium→high, xhigh→max on the low/high/max member, as asked on the one with all), TestGroupSetLevels and routing-levels.test.cjs (Chromium, WebKit, en/zh) fail without the change. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass (TestUserPath, a known flake under load, passes alone); click-scroll, old-webkit, routing-effort(-row), routing-levels, settings-groups GUI tests pass.
routing: a group can name the reasoning levels agents are offered, so one member with few doesn't take the rest from the others (#295) — a group offered only the levels every member has, so deepseek-flash (low/high/max) beside models with medium and xhigh left the group without them. Group.Levels (CLI
magpie group set <id> levels=low,medium,high,xhigh, levels= clears; TUI l; GUI group editor's Levels: its models' shared / named) is offered instead in /v1/models, Codex's catalog, Pi and the rest; only levels magpie knows are taken, stored lowest first; a group in a group that names its own offers them for its models; unset is as before. A member without the level asked is sent its nearest, as it already was. The GUI's group save also keeps a family set from the CLI. TestGroupLevelsOverride, TestGroupLevelsReachAgents, TestGroupLevelsNamed (passthrough and translated: medium→high, xhigh→max on the low/high/max member, as asked on the one with all), TestGroupSetLevels and routing-levels.test.cjs (Chromium, WebKit, en/zh) fail without the change. go vet, go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui ./... pass (TestUserPath, a known flake under load, passes alone); click-scroll, old-webkit, routing-effort(-row), routing-levels, settings-groups GUI tests pass.
usage: costs show in RMB at a live rate, when Settings picks it (#212 L1cardo: 添加费用用人名币结算的选项,最好是能根据实时汇率来计算) — the Usage page, the tray panel, the TUI and the CLI all price a call in USD, magpie's list prices being dollars; Settings now has a Currency row (after Usage shows) offering $ USD, kept by default, and ¥ CNY, which converts every one of those at display time only — usage.Totals.Cost and the JSONL records it comes from stay in USD always, and a vendor's own balance (already in its own currency, a relay's ¥) is never touched.