Skip to content

Port upstream 0.60.5: Kimi accepts monthly-only and partial ratio-pool Code API responses (stacked on #697) - #730

Draft
Finesssee wants to merge 2 commits into
port/micro-0.69.0-kimi-blocking-monthlyfrom
port/micro-0.60.5-kimi-monthly-only-pool
Draft

Finesssee wants to merge 2 commits into
port/micro-0.69.0-kimi-blocking-monthlyfrom
port/micro-0.60.5-kimi-monthly-only-pool

Conversation

@Finesssee

@Finesssee Finesssee commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The Kimi Code API (/coding/v1/usages) can report quota as ratio pools (usages.limit_5h, limit_7d, limit_month_total) and may leave some of them out. Before this change, a response without a usable limit_5h pool failed with "unusable session quota pool", so a monthly-only account showed an error, and a ratio-pool response put the 5-hour pool under the "Weekly" label and the 7-day pool under "Rate Limit". This PR follows upstream 0.60.5 (PR steipete#3697, fixing steipete#3694), which v0.70.0 still uses.

  • Lane order matches the legacy counters and the web path.
    • Weekly (primary) is the limit_7d pool, else the legacy usage counters.
    • Rate Limit (secondary) is the limit_5h pool, else the first legacy limits entry.
    • The 0.63.0 zero-placeholder reconciliation still applies to each lane.
  • Total usage comes straight from the Code API. The limit_month_total pool becomes the kimi-monthly "Total usage" lane with no browser sign-in. Web enrichment only fills that lane when the API did not report a usable one.
  • Missing lanes are not invented.
    • A missing weekly quota shows as an informational "No weekly quota reported" row, not a 0% bar.
    • An invalid ratio (negative, non-numeric or null) cannot hide usable legacy counters.
    • A response with no usable window fails with "No supported quota windows in Code usage response", so Auto mode moves on to the Kimi Code CLI credential and then the web source.
  • Automatic metric. For an account that reports only the monthly pool, Automatic reads Total usage instead of stopping at the informational weekly row. So do the Session and Weekly preferences, which fall through to Automatic. The tray icon and float bar then show that pool.
  • With Port upstream 0.69.0: mark Kimi windows blocked by an exhausted monthly limit (stacked on #691) #697, an exhausted monthly pool from the Code API blocks the Weekly and Rate Limit rows until the pool resets.

Upstream reference

Ported / Deferred

  • Ported, Kimi provider (rust/src/providers/kimi/):
    • code_api::snapshot_from_code_api_response builds each lane from its pool or falls back to that lane's legacy counters, and puts the monthly pool in the kimi-monthly extra lane. It returns upstream's error when no window is usable.
    • apply_subscription_windows keeps an API monthly pool and only fills a missing one.
    • is_equivalent_to_weekly_window treats a missing weekly as never equivalent, so the "Code 7-day" row is not hidden by a weekly placeholder.
    • KimiProvider::automatic_metric_missing_core_is_terminal returns false. The trait doc in core/provider.rs names this case.
  • Ported, tests:
    • Every upstream v0.70.0 KimiRatioPoolTests case is in ratio_pool.rs, in upstream lane order. The 0.60.5 web-enrichment test (status 200 and 503) runs at the enrichment seam: fetch_via_code_api applies web stats only when the call succeeds.
    • Extra cases: weekly-only, count rate limit plus monthly-only, and web enrichment filling a missing or invalid API monthly pool.
    • The code_api.rs tests now expect upstream lane order.
    • monthly_blocking_tests.rs checks that an exhausted Code API monthly pool blocks both Code windows, and that a monthly-only response has nothing to block.
    • usage_metric.rs checks that a monthly-only Kimi snapshot resolves Automatic, Session and Weekly to Total usage.
  • Docs: a "Kimi Code quotas" section in docs/PROVIDERS.md, and a CHANGELOG entry.
  • Deviations from upstream:
    • Upstream represents a missing weekly as nil. UsageSnapshot.primary is not optional here, so a missing weekly is an informational placeholder, the same shape as the existing "No active 5h session" row.
    • Count descriptions still read "N/M credits" where upstream says "N/M requests" or "Rate: N/M per 5 hours". The login label still falls back to "Code API" or "Kimi Code CLI" where upstream returns nil. Both behaviors were already there before this PR.
    • When a legacy rate limit has no window, its window minutes stay unknown. Upstream assumes 300 minutes. A zero limit_5h placeholder is therefore not replaced by those counters. This behavior was already there before this PR.
    • Upstream's Kimi menu-bar resolver shows nothing for a monthly-only account until the pool is exhausted. Here, Automatic already picks across all Kimi lanes, including Total usage, so a monthly-only account shows its monthly percentage. When the pool is exhausted, both show 100%.
  • Not changed (known gaps, not Kimi-specific):
    • The Settings > Providers sidebar and the tray provider grid read the primary lane, so for a monthly-only account they show the weekly placeholder's value (0% used, 100% left) rather than Total usage. The shared helpers (selectSingleMetricUsageWindow and ProviderGrid's gridPercent) do this for every provider with an informational primary.
    • The Settings Usage section uses the generic Session and Weekly labels for Kimi. This is the same at the base.
  • File size: rust/src/core/provider.rs was already 1508 lines at the base and grows by 1 doc-comment line. Every other changed source file is under 1000 lines.

Validation

Run on bfb026a3. 7b6e2688 only adds the docs and the CHANGELOG line.

Check Result
cargo +1.98.0 fmt --all --check pass (also at 7b6e2688)
cargo +1.98.0 clippy --workspace --all-targets -- -D warnings pass (also at 7b6e2688)
cargo +1.98.0 test -p codexbar providers::kimi 101 passed, 0 failed
cargo +1.98.0 test -p codexbar-desktop-tauri usage_metric 19 passed, 0 failed
cargo +1.98.0 test -p codexbar 2273 passed, 0 failed, 1 ignored
cargo +1.98.0 test -p codexbar-desktop-tauri 482 passed, 1 failed: bootstrap_payload_exposes_every_provider_variant, see note below
Frontend (pnpm check-locale, lint, test, build) not run: no frontend, locale or bridge file changed

The desktop failure is environment-dependent: the test reads the host's settings. It is the known #684 failure, fixed by #711, and fails the same way at the base.

Affected areas

  • Kimi provider (Code API parsing, web enrichment, Automatic metric)
  • Tray panel card (Kimi rows)
  • Tray icon and float bar metric for monthly-only Kimi accounts
  • CLI output order for Kimi Code API responses (it now matches the web path)
  • Documentation and CHANGELOG

UI proof

PASS on 7b6e2688: #730 (comment) (browser-use over WebView2 CDP, per the maintainer).

This PR stays a draft because it is stacked on #697.

Upstream 0.60.5 steipete#3694: accept Code API responses that report any supported window. Weekly is the primary lane and the 5-hour rate limit the secondary, matching the web path; an absent weekly quota stays an informational placeholder; the monthly pool is the Total usage lane and web enrichment only fills in a missing one. A response without any supported window is a parse error. A monthly-only snapshot drives Automatic metric selection.
@coderabbitai

coderabbitai Bot commented Oct 1, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Finesssee

Copy link
Copy Markdown
Collaborator Author

UI proof (browser-use)

Result: PASS on build 7b6e268815edcf165476d8b17cd8acb83b7f02df, the current PR head "Document Kimi Code quota lanes". Six Kimi Code API response bodies went through the app's real Code API parsing.

  • A monthly-only account now shows an informational Weekly row and its Total usage pool, and the float bar follows that pool.
  • Ratio pools land in upstream lane order.
  • An exhausted monthly pool blocks both Code rows.
  • A body with no usable window is an error, never a 0% window.

At the maintainer's direction, this proof drove the app's WebView2 over CDP with the browser-use CLI instead of CUA. It used no keyboard, mouse or focus. The proof windows stayed on the second display, and the kit settings turned the global shortcut off.

Setup

  • Build: pnpm install --frozen-lockfile, then pnpm run tauri:build:debug at 7b6e2688 in the lane-A worktree. The exe was copied to the proof kit, and bin\BUILD_COMMIT records the commit.
  • Proof-only patch: never committed, restored right after the build, and kept as proof-only.diff in the kit.
    • A workspace Cargo.toml [patch.crates-io] dirs shim for an isolated home, plus the resulting Cargo.lock change.
    • A CODEXBAR_PROOF_KIMI_CODE_FIXTURE hook inside fetch_via_code_api in providers/kimi/code_api.rs. It replaces only the HTTP send: the fixture body is deserialized into the real KimiCodeApiUsageResponse, and the rest of fetch_via_code_api runs unchanged (snapshot_from_code_api_response, the login label, subscription windows and the Port upstream 0.69.0: mark Kimi windows blocked by an exhausted monthly limit (stacked on #691) #697 monthly block). The endpoint is still built from the region and is https-only, so TLS and URL validation are unchanged.
    • The hook logs one line per call with the endpoint, whether the key equals the synthetic one, and the login label. It never logs the key. All 11 calls logged endpoint=https://api.kimi.com/coding/v1/usages synthetic_key=true login=Code API.
  • Data:
    • USERPROFILE, HOME, APPDATA, LOCALAPPDATA, TEMP and the provider homes are isolated under the kit. KIMI_CODE_HOME is an empty kit folder, so there is no Kimi CLI credential.
    • Only Kimi is enabled. The Kimi cookie source is off, so there is no browser import and no web enrichment. The theme is auto, the float bar is on, and Kimi's metric is Automatic.
    • The kit's api_keys.json holds a synthetic Kimi Code API key (proof-fixture-key), as if it had been typed in Settings.
    • The first launch passed the key only as KIMI_CODE_API_KEY. The shell then gave Kimi SourceMode::Cli, which fails with "Source mode 'Cli' not supported for this provider", so the kit stores the key instead. That mapping is already on main; see the not-blocking notes below.
  • Fixtures (resets are relative to each launch):
    • monthly-only: {"usages":{"limit_month_total":{"used_ratio":1.05}}}, the exact body from upstream's "monthly only response does not invent code windows" test.
    • monthly-42: only limit_month_total at 0.42, resetting in 20 days.
    • missing-weekly: the body from upstream's "reported ratio pools retain missing weekly quota and monthly identity" test. It has a 300-minute legacy limits[0] at 25/100, a limit_5h of 0, a limit_month_total of 0.0056 and a limit_month_code of 0, with no usage and no limit_7d.
    • lanes: limit_7d at 0.125 and limit_5h at 0.625, from upstream's "ratio weekly and session retain established lane ordering" test.
    • exhausted: limit_5h 0, limit_7d 0 and limit_month_total 1.0, the shape used by exhausted_code_api_monthly_pool_blocks_code_windows.
    • empty: {"usages":{"limit_5h":{}}}, the third case of upstream's "unrecognized or empty quotas do not succeed as unused" test.
  • Commands:
    • bash launch.sh trayPanel|settings:providers <fixture> ran 9 times: six tray runs and three Settings runs, one launch each. It exports WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9351 ....
    • Each run was driven with BU_CDP_URL=http://127.0.0.1:9351 BU_NAME=lane-a-730 BH_TAB_MARKER=0 browser-use.
    • Before each attach, curl /json/version showed Edg/154 WebView2, and the port 9351 listener's parent was this kit's exe, the only CodexBar process running.

Results

# Assertion Result
A0 No real email or account from the host is visible. DOM scans before every screenshot (tray overview, Kimi card, float bar and Settings) in all nine runs found no @ addresses, no host user name and no account-email node. The bridge snapshot has no account email. PASS
A1 Dark under theme auto in every run: matchMedia('(prefers-color-scheme: dark)') is true, data-theme=dark, and the body is rgb(28, 28, 30) with text rgb(245, 245, 247). The float bar window also reports prefers-color-scheme: dark. PASS
A2 monthly-only: the state is ready and the plan label is "Code API". The Kimi card shows Weekly "No weekly quota reported", with no bar and no 0%, then Total usage "100% used" and "Exhausted", with no reset because the body has none. In the bridge, the primary is informational and the extra lane kimi-monthly "Total usage" is 100% over 43200 minutes. Automatic selectedMetric is that lane, and the float bar pill reads 100% in the critical tone. PASS
A3 monthly-42: Weekly is informational. Total usage reads "42% used" and "Resets in 19d 23h". Automatic picks the monthly pool at 42%, and the float bar reads 42%. PASS
A4 missing-weekly: Weekly is informational. Rate Limit reads "0% used" and "Resets in 2h 59m": it is the limit_5h pool over 300 minutes. The zero pool stays, as in the ported upstream test, because a zero placeholder is reconciled with legacy counts only when no monthly pool is reported. Total usage reads "1% used" (0.56%) and "Resets in 15d 23h". limit_month_code adds no row. Automatic picks Total usage, and the float bar reads 1%. PASS
A5 lanes, in upstream lane order: Weekly "13% used" is the limit_7d pool (10080 minutes, "Resets in 3d 23h"), and Rate Limit "63% used" is the limit_5h pool (300 minutes). There is no Total usage row. Automatic picks the higher lane (62.5%), and the float bar reads 63%. PASS
A6 exhausted, with #697: Weekly and Rate Limit read "Blocked by monthly limit" with no bar, percentage or reset. Total usage reads "100% used", "Resets in 29d 23h" and "Exhausted". In the bridge, both Code windows carry monthlyLimitBlock.resetsAt equal to the pool's reset. The float bar reads 100%. PASS
A7 empty: no Code window is produced. The provider is in a problem state (errorState unknown) with no rows and no 0% bar, and the float bar reads "Usage unavailable". PASS
A8 Settings > Providers > Kimi > Usage. monthly-only shows "Session" with "No weekly quota reported" and no track, then "Total usage" with "Exhausted". lanes shows 13% and 63%. exhausted shows two "Blocked by monthly limit" rows, then Total usage with "Exhausted" and "Resets in 29d 23h". PASS
— Tray icon pixels. Not covered (native, browser-use per maintainer). The icon uses selected_usage_icon_windows, which starts from the same selected_usage_window as the selectedMetric asserted above. See kimi_monthly_only_snapshot_selects_the_total_usage_lane in usage_metric.rs, and exhausted_code_api_monthly_pool_blocks_code_windows and monthly_only_code_api_response_has_no_code_window_to_block in providers/kimi/monthly_blocking_tests.rs.

Validation

Run in the lane-A worktree on Rust 1.98.0. 7b6e2688 only adds docs, the CHANGELOG line and one doc comment on top of bfb026a3.

Command Result
cargo +1.98.0 fmt --all --check pass at 7b6e2688
cargo +1.98.0 clippy --workspace --all-targets -- -D warnings pass at 7b6e2688
cargo +1.98.0 test -p codexbar providers::kimi 101 passed, 0 failed
cargo +1.98.0 test -p codexbar-desktop-tauri usage_metric 19 passed, 0 failed
cargo +1.98.0 test -p codexbar 2273 passed, 0 failed, 1 ignored
cargo +1.98.0 test -p codexbar-desktop-tauri 482 passed, 1 failed: bootstrap_payload_exposes_every_provider_variant. This is the non-hermetic #684 test, which #711 fixes. It fails the same way at the base.
pnpm install --frozen-lockfile, then pnpm run tauri:build:debug pass (the proof build, which runs tsc --noEmit and vite build)

Screenshots

All paths are under C:\Users\FSOS\AppData\Local\Win-CodexBar\port-audit\proof\730\shots-bu\.

  • 01-<fixture>-tray-overview.png, 02-<fixture>-tray-kimi.png and 03-<fixture>-floatbar.png for each of the six fixtures.
  • 04-monthly-only-settings-kimi.png, 04-lanes-settings-kimi.png and 04-exhausted-settings-kimi.png.

The raw browser-use output is in bu-<fixture>-tray.json and bu-<fixture>-settings.json in the kit.

Not blocking (found on main, not caused by this PR)

  • The Settings sidebar and the provider grid read the primary lane. For monthly-only and exhausted, the Kimi sidebar row shows "0%" while Total usage is exhausted. The PR description lists this as a known gap: selectSingleMetricUsageWindow and ProviderGrid's gridPercent read the primary for every provider.
  • The Settings Usage labels are generic. The primary window is always "Session" and the secondary "Weekly". So in lanes, the 7-day pool reads "Session 13%" and the 5-hour pool reads "Weekly 63%". UsageSection ignores primaryLabel for every provider, as noted in the Port upstream 0.70.0: offer Mistral Monthly Plan metric #717 proof.
  • An environment-only Kimi key with the cookie source off maps to Cli. build_fetch_context in commands/providers.rs counts only a stored key for has_kimi_code_api_key. So KIMI_CODE_API_KEY alone, with the cookie source Off, fails with "Source mode 'Cli' not supported for this provider". Upstream's KimiAPIFetchStrategy.isAvailable accepts the environment key.
  • Auto mode reports the web fallback's error.
    • In empty, the card reads "Kimi cookie source is Off; provide a manual cookie header or enable browser import."
    • In upstream v0.70.0, the CLI and web strategies are unavailable in this setup, so the pipeline would end on the Code API decoding error.
    • Here, fetch_cli_then_web always calls the web source, and that error wins.
    • Both are problem states with no 0% window.

This PR stays a draft because it is stacked on #697.

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