fix(usage): zai/kimi probes against the REAL API shape (live-captured) - #2540
Merged
Merged
Conversation
The earlier probe structs were transcribed from sub2api and matched
NOTHING in the real payloads: zai parsed limit_used/limit_total (fields
that do not exist -> 200 OK with zero windows -> panel rendered an
empty/wrong entry), kimi parsed limits[].detail as a flat string while
the real API returns a nested object (unmarshal ERROR for every
coding-plan user).
Ground truth captured live against the user's own key (2026-09-18):
zai /api/monitor/usage/quota/limit:
{code, msg, data:{limits:[{type:TIME_LIMIT|TOKENS_LIMIT, unit,
number, percentage(0-100), nextResetTime(ms-epoch), currentValue,
remaining...}]}} -> windows: 5h (TIME_LIMIT unit=5 number=1) and
weekly (TOKENS_LIMIT), percent straight from percentage.
kimi /coding/v1/usages:
{usage:{limit,used,remaining,resetTime(str)}, limits:[{window,
detail:{...object...}}], usages:{limit_5h:{used_ratio(0-1),
reset_time}, limit_7d:{...}}} -> windows: 5h/7d from usages.*.
used_ratio*100 (cleanest source), limits[] fallback derives from
decimal strings.
Verified end-to-end with the live key (cmd/usageprobe-e2e throwaway,
not committed): zai 5h=5.0% weekly=86.0% with resets matching the raw
response; kimi 5h=0.5% 7d=6.7% ditto; moonshot/openrouter unchanged
and still OK.
Also: View() render meter (>100ms logs 'slow view render'), the
symmetric blind spot of #2538's handler meter - during the startup
freeze reproduction the event loop stalled 10s with only 291ms
attributable to handlers; a 1862-message View bench now pins full
render at ~0ms, and the meter stays for the next reproduction.
All usage tests re-pinned to the captured real bodies.
Co-Authored-By: ggcode <noreply@ggcode.dev>
Review follow-up: transcribed sub2api's actual parsers (cn_provider_quota_service.go, cc-switch-aligned) instead of eyeballing the captured JSON. zai - parseZhipuTokenTiers rules: - Only TOKENS_LIMIT entries compete for 5h/weekly; TIME_LIMIT (tool/ search meter) is skipped - it was previously mislabeled '5h'. - Explicit unit wins: 3=5h, 6=weekly. The live capture's TOKENS_LIMIT (unit=3) is the 5h window - reset-order labeling flips them near a period boundary. - CREDIT_LIMIT shows only when no TOKENS_LIMIT exists; entries without nextResetTime claim 5h first, rest fill slots by ascending reset. - Live-key verification: single TOKENS_LIMIT(unit=3) entry now renders 5h=1% after the 21:38 window reset (was 86% before it). kimi - parseKimiUsageTiers rules: limits[0].detail is the 5h window, top-level usage is weekly; utilization = (limit-remaining)/limit*100 on the decimal strings (integer-exact, matches cc-switch), replacing the usages.*.used_ratio float path. minimax - parseMiniMaxUsageTiers fields (the previous struct used invented field names that matched nothing): select model_name== 'general' (not index 0; video entries are different meters), current_interval_remaining_percent + end_time (5h), and weekly ONLY when current_weekly_status==1 via current_weekly_remaining_percent + weekly_end_time. Tests re-pinned to the real shapes; live-key e2e re-verified zai + moonshot + openrouter (kimi key returned 401 during the second run - path/shape were verified during the earlier 200 response). Co-Authored-By: ggcode <noreply@ggcode.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
用户报告
zhipu coding plan 与 kimi 的 usage 显示不正确(#2537 只修了路径归一化——shape 仍是错的)。
根因(用户 key 实抓响应体,非猜测)
data.limits[].{type,percentage,nextResetTime}→ 200 但零窗口=面板空数据limits[].detail当 string,真实是嵌套 object(limit/used/remaining 均为十进制字符串)→ 每个 coding 用户 unmarshal 报错修复
usages.{limit_5h,limit_7d}.used_ratio(0-1)×100,limits[] 兜底端到端验证(真实 key,临时探针程序未入库)
单测全部改为实抓 body 的 mock。
附带:View() 渲染 >100ms 仪表(#2538 handler 仪表的对称盲区;1862 消息全量渲染基准实测 ~0ms 已钉死)。
Co-Authored-By: ggcode noreply@ggcode.dev