Skip to content

fix(usage): zai/kimi probes against the REAL API shape (live-captured) - #2540

Merged
topcheer merged 2 commits into
mainfrom
fix/usage-probe-real-shapes
Sep 18, 2026
Merged

topcheer merged 2 commits into
mainfrom
fix/usage-probe-real-shapes

Conversation

@topcheer

Copy link
Copy Markdown
Owner

用户报告

zhipu coding plan 与 kimi 的 usage 显示不正确(#2537 只修了路径归一化——shape 仍是错的)。

根因(用户 key 实抓响应体,非猜测)

  • zai:旧 struct 抄自 sub2api(limit_used/limit_total),真实 API 是 data.limits[].{type,percentage,nextResetTime} → 200 但零窗口=面板空数据
  • kimi:旧 struct 把 limits[].detail 当 string,真实是嵌套 object(limit/used/remaining 均为十进制字符串)→ 每个 coding 用户 unmarshal 报错

修复

  • ZaiProbe:TIME_LIMIT(unit5×1)→"5h"、TOKENS_LIMIT→"weekly",percentage(0-100)+nextResetTime(ms) 直取
  • KimiProbe:优先 usages.{limit_5h,limit_7d}.used_ratio(0-1)×100,limits[] 兜底

端到端验证(真实 key,临时探针程序未入库)

zai  5h=5.0% (reset 09-19 23:27)  weekly=86.0% (reset 09-18 21:38)
kimi 5h=0.5% (reset 09-18 13:53)  7d=6.7%    (reset 09-22 12:53)
moonshot/openrouter 回归不变 OK

单测全部改为实抓 body 的 mock。

附带:View() 渲染 >100ms 仪表(#2538 handler 仪表的对称盲区;1862 消息全量渲染基准实测 ~0ms 已钉死)。

Co-Authored-By: ggcode noreply@ggcode.dev

Junjun Zhang and others added 2 commits September 18, 2026 21:29
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>
@topcheer
topcheer merged commit a169cce into main Sep 18, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant