Skip to content

feat(auth): native kimi-oauth provider (Kimi Code membership device flow) + K3 notional pricing - #1392

Merged
ang-fleet-lander[bot] merged 5 commits into
mainfrom
daedalus/t_7a3e9527-kimi-oauth
Sep 28, 2026
Merged

ang-fleet-lander[bot] merged 5 commits into
mainfrom
daedalus/t_7a3e9527-kimi-oauth

Conversation

@ang-fleet-workers

@ang-fleet-workers ang-fleet-workers Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Native kimi-oauth provider: Kimi Code membership (K3) via RFC 8628 device flow. No CLIProxyAPI hop. Card t_7a3e9527.

What

  • hermes_cli/auth.py: kimi-oauth registry entry (auth_type=oauth_kimi). Device-flow login against auth.kimi.com handles authorization_pending/slow_down(+5 s)/access_denied/expired_token. refresh_kimi_oauth_state() runs read -> POST -> write-back under _provider_state_transaction (rotating refresh token, written back to the source store, 0600 atomic, never flips active_provider). A terminal refusal quarantines the state. There is a per-request token provider and status/runtime resolvers. The device id is persisted per login, and the five X-Msh-* identity headers go on every auth and inference call.

  • agent/anthropic_adapter.py: single choke point in build_anthropic_client. A kimi-oauth JWT (by client_id claim) on api.kimi.com/coding is swapped for the per-request bearer hook, so every rebuild path (init, /model, fallback, rotation, aux) survives the 900 s access token. sk-kimi- keys keep the static path.

  • agent/credential_pool.py: seeds a single oauth entry from providers.kimi-oauth on every load, so a rotation by the keeper or another process is adopted and does not add a second entry (credential pool: adopt the rotated token when the agent's stale key matches no entry (xai-oauth fallback 2026-09-19) #730 class). Refresh delegates to the store authority.

  • Runtime resolution (anthropic_messages), hermes auth add kimi-oauth, hermes model flow, provider profile/overlay/aliases, persistence + removal steps.

  • agent/usage_pricing.py: Kimi ids (kimi-*, k3, k3-*) are added to the existing shared _infer_vendor_from_model() (-> moonshotai). This is the ONE model->vendor map, and the multi-vendor cpa proxy lane (card t_d59c7936) dispatches through it too. kimi-oauth (plus kimi-code rows recorded before the rename) routes to the notional OpenRouter moonshotai/kimi-k3 snapshot ($3/$15/$0.30 per M, status estimated) only when the SERVED model's vendor is moonshotai. kimi-for-coding* stays unpriced rather than borrowing K3 rates.

  • agent/model_metadata.py: k3-256k = 262,144 (from /coding/v1/models). k3 was already 1,048,576.

  • 402 We're unable to verify your membership benefits classifies as billing, non-retryable, fallback. This is existing behavior; a test now pins it.

  • hermes_cli/provider_catalog.py: oauth_kimi added to _ACCOUNTS_AUTH_TYPES, so the provider appears on the desktop Accounts tab (catalog-derived card, flow: external, hermes auth add kimi-oauth). The desktop parity contract test_every_hermes_model_provider_is_configurable_in_desktop failed on the first push without this change.

Prior art

Upstream NousResearch#71039 (webtecnica; twin NousResearch#71038, issue NousResearch#70928) was closed 2026-07-30 as not_planned under the in-tree-provider policy. Its diff adds only a plugins/model-providers/kimi-oauth ProviderProfile (auth_type=oauth_external, base api.kimi.com/coding/v1, alias kimi). It is meant to consume the official kimi CLI's ~/.kimi-code/credentials/kimi-code.json, but the diff carries no reader for that file, no refresh, no X-Msh-* headers and no credential-pool wiring; its web_server.py hunk is unrelated isolated-profile code. What this PR does differently:

  • It owns the device login, so there is no dependency on the kimi CLI's token file.
  • It uses the Anthropic Messages surface at /coding.
  • It refreshes rotating tokens with store-authority adoption.
  • It sends the identity headers.
  • It does NOT take the kimi alias, which stays on kimi-coding.

Verified

  • tests/hermes_cli/test_auth_kimi_oauth_provider.py: 19 passed; test_provider_parity.py + test_web_oauth_dispatch.py pass with it (38 total). RED-proof: reverting each of credential_pool / anthropic_adapter / usage_pricing / model_metadata to fork/main fails 2/2/4/1 tests.
  • Neighbor suites (minimax, xai-oauth, auth_commands, runtime resolution, provider groups, plugin discovery, anthropic adapter, credential pool, model metadata, usage pricing, error classifier): 1088 passed, 1 failed. The failure (test_try_gh_cli_token_uses_homebrew_path_when_not_on_path) also fails on clean fork/main, so it is not from this change.
  • Live, sandbox home, worktree code:
    • The device-authorization leg returns all 6 fields (verification_uri_complete = https://www.kimi.com/code/authorize_device, expires_in 1800, interval 5), and the first poll answers authorization_pending.
    • With the proxy's current access token and a dummy refresh token (so nothing rotates): registry -> runtime (anthropic_messages, api.kimi.com/coding) -> client (bearer hook, X-Msh-Device-Id matches) -> live k3 completion KIMI-OAUTH-OK, usage 97/53, cost estimated $0.001086.

Not yet done (needs Ace)

The real device login on the Studio and the forced-expiry proof on the live store come after deploy. Alias k3 -> kimi-oauth/k3 (cpa/kimi-k3 stays as the fallback lane) is deferred until the native lane is proven. Keeper + lint are in ANG-Ventures/hermes-home (companion PR).


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@ang-fleet-lander

Copy link
Copy Markdown

🤖 merged-by: apollo · lane: kanban-merge-pass · gate: ADVISORY (FleetReview not green for 69da029): fleetreview-advisory-20260927-standing.md · why: t_7a3e9527: Native kimi-oauth provider (Kimi Code membership device flow) + keeper + parity ; Argus off card review (Ace 13:08), CI green

@ang-fleet-lander
ang-fleet-lander Bot added this pull request to the merge queue Sep 28, 2026
Merged via the queue into main with commit f65cbd8 Sep 28, 2026
56 checks passed
@ang-fleet-lander
ang-fleet-lander Bot deleted the daedalus/t_7a3e9527-kimi-oauth branch September 28, 2026 04:03
@ang-fleet-ci-actuators ang-fleet-ci-actuators Bot added the fleetreview:post-merge Ask FleetReview to review this MERGED pull (merge commit vs first parent) label Sep 28, 2026
@ang-prism

ang-prism Bot commented Sep 28, 2026

Copy link
Copy Markdown

FleetReview

Review: post-merge · head f65cbd81a56d · duration 10m 30s
Profile: heavy (merit: lines 1094>=800) · policy: changed-lines>400
Roster: B-assert-ctx → gpt-6-sol (openai), B-state → gpt-6-sol (openai), C-assert-xhigh → gpt-6-sol (openai), F → gpt-6-sol (openai), G → gpt-6-sol (openai), L6 → gpt-6-sol (openai)

PARTIAL — ensemble escalated: family floor: too few distinct model families completed

This review did not reach a trusted verdict, so it is not a gate pass and the findings below may be incomplete. They are posted so they can be read rather than lost in a terminal record.

Post-merge review (fleetreview:post-merge override): this reviewed the merge commit against its first parent — the bytes that already shipped. It is not a pre-merge gate pass.

Reviewed with 1 of 3 model families — anthropic, xai unavailable.

profile: heavy (rule: lines 1094>=800) · round 0 · members: C-assert-xhigh, B-assert-ctx, B-state, L6, F, G · families: openai

Confidence: 1/5

Findings

  • P1 hermes_cli/auth_commands.py:530 — Token Rotation · agreed: B-assert-ctx,C-assert-xhigh,F (openai)
  • P2 hermes_cli/auth.py:9343 — Polling timeout · agreed: B-assert-ctx,L6 (openai)
  • P1 plugins/model-providers/kimi-coding/__init__.py:146 — Route Kimi OAuth through the auxiliary client resolver · agreed: B-assert-ctx,F (openai)
  • P2 tests/hermes_cli/test_auth_kimi_oauth_provider.py:179 — Untested store reload · agreed: B-assert-ctx,L6 (openai)
  • P1 hermes_cli/auth.py:9479 — Lost refresh token · agreed: B-state,F,G (openai)
  • P1 agent/anthropic_adapter.py:720 — Do not replace an arbitrary Kimi JWT with the stored account's token · agreed: L6,C-assert-xhigh,F,G (openai)
  • P1 agent/credential_sources.py:191 — Removing profile Kimi OAuth credentials leaves the global fallback usable · agreed: C-assert-xhigh,G (openai)
  • P1 agent/credential_pool.py:3465 — Quarantined Kimi credentials remain usable from the pool · agreed: C-assert-xhigh,F,G (openai)
  • P1 agent/credential_sources.py:443 — Removing Kimi OAuth in a profile can reactivate the global credential · agreed: C-assert-xhigh,F (openai)
  • P1 hermes_cli/auth.py:9416 — Unsuppress the OAuth pool source on device-flow re-login · agreed: F (openai)
  • P1 hermes_cli/runtime_provider.py:2246 — Honor profile credential removal before using global Kimi tokens · agreed: G (openai)
  • P1 hermes_cli/auth.py:429 — Kimi OAuth is unreachable by auxiliary-client routing · agreed: G (openai)

FleetReview provenance · models: B=gpt-6-sol, C=claude-code-opus-5-5, D=grok-4.6, F=gpt-6-sol · cost: $21.49 · duration: 10m 28s · rounds: 2 · files examined: 16

@ang-prism

ang-prism Bot commented Sep 28, 2026

Copy link
Copy Markdown

FleetReview

FleetReview's daily member-call budget is spent (60/600 for 2026-09-28 UTC); review skipped.


FleetReview · reviewKind: skipped-budget

Kyzcreig pushed a commit that referenced this pull request Sep 28, 2026
…ai row (t_a0cdc01a) (#1405)

The vendor fallback in _lookup_official_docs_pricing retried under
provider=moonshotai with the raw model id, so Kimi Code membership ids
(k3, k3-256k) served through the cpa proxy lane priced as unknown.
Normalize them to kimi-k3 on that hop, as the notional kimi lanes do.

Test is a relation (lane entry == moonshotai/kimi-k3 row), not a URL
snapshot: #1401's source_url assertion went red in the queue once #1392
routed kimi-code through moonshotai. Supersedes #1401.
Verified: tests/agent/test_usage_pricing.py + test_auth_kimi_oauth_provider.py
151 passed; cpa-k3/cpa-k3-256k cases fail with the source change reverted.

Co-authored-by: ang-fleet-workers[bot] <333956806+ang-fleet-workers[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fleetreview:post-merge Ask FleetReview to review this MERGED pull (merge commit vs first parent)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants