Kimi Provider
Running Omniscio's sessions on Moonshot's Kimi instead of Claude. A Kimi session looks and behaves like a Claude one — same sidebar, same streaming, same approval flow — because the same underlying CLI does the talking; only the model and the upstream endpoint differ. Covers enabling it, choosing models, and what it costs.
What it is
Omniscio supports spawning Claude-Code-style sessions backed by Moonshot's Kimi Anthropic-compatible API as an additional provider, alongside claude (the default), codex, gemini, antigravity, deepseek, glm, minimax, cursor, hermes, pi, opencode, and openclaw.
Where to find it
Settings → Accounts, and only after Show alternative AI providers has been switched on there — the whole Kimi section is hidden until it is. A Kimi session then appears in the sidebar like any other, marked with the Kimi icon in its header.
How it behaves
What the user sees
A Kimi session looks identical in the sidebar and main pane to a Claude session — same status dots, same streaming bubbles, same Ctrl+Enter to send, same Plan / Auto-Accept / Bypass Permissions modes, same tool-call approval UI. The provider is invisible in normal chat. The only user-visible difference is the Kimi icon (a non-Claude provider mark, no text label) in the session header.
Tool-call behavior is identical to Claude because the same claude CLI binary is doing the talking — only the model and the upstream endpoint differ. There is no yolo / auto-approve mode like Gemini or Anti-Gravity; the standard Claude approval flow applies.
How to enable
Master toggle required first. Kimi is an alternative provider — by default Omniscio ships as a Claude-only product, and the entire Kimi setup section below is hidden in Settings → Accounts. Flip Settings → Accounts → Show alternative AI providers to ON and the Kimi panel appears alongside Gemini, Codex, Anti-Gravity, and DeepSeek. With the master off, the per-project "Default provider" radio collapses to a single Claude row and the session header's provider switcher (ChangeProviderButton) hides Kimi — Kimi effectively does not exist in the UI even if every gate below is configured. Your saved API key and "Allow Kimi sessions" toggle are preserved across master-toggle flips.
You need two of these in place (note: no binary check — same claude binary as Claude). The opt-in toggle leads and gates the key field — the API key input appears only once Kimi is turned on, so a key can't be entered into a disabled provider (when off, a hint keeps the kimi-api-key Settings-search anchor landable and a saved key is preserved):
- Settings → Account → Allow Kimi sessions in any project — opt-in toggle, off by default; same security stance as the Codex/Gemini spawn guards. Turning it on reveals the key field below.
- Settings → Account → Kimi → API key — paste a Kimi API key from
platform.moonshot.ai(encrypted at rest via ElectronsafeStorage).
A key is one way to pay, not the only one. Who pays for a Kimi session, and which company serves it, is Kimi's supply list in Settings → Accounts → Who pays & who serves. It holds your own Kimi key and Omniscio credits (signed-in, drawn from your prepaid balance) — so with no key saved, a Kimi session can still run on credits — and it can hold a DeepInfra row for Kimi K2.7 Code. A session connects through the first row that can serve. See model-vendors.md.
Once both are green, you can launch a Kimi session in three ways:
- Per-launch override — on a fresh (zero-message) session, the ChangeProviderButton in the new session's main panel (the launch-config pickers on a fresh session) lets you pick a one-off provider before sending the first message. Non-ready providers appear
aria-disabledwith an "Add key…" / "Enable in Settings…" suffix and deep-link to the right Settings panel. - Per-project default — Edit Project dialog (three-dot menu → Edit) has a "Default provider" section listing every enabled provider. Pick Kimi and the project's sidebar "+ New Session" button spawns Kimi automatically.
- Programmatically — anything that creates a session with
provider: 'kimi'(recipes, agent-driven sessions, the CLI control HTTP API). Same readiness gates apply on the backend.
Choosing the model
A fresh Kimi session lets you pick the model in the launch-config pickers (next to the provider chooser). The list is registry-driven (MODELS_BY_PROVIDER.kimi in provider-models.ts) and offers two models: Kimi K3 (kimi-k3, the default — Moonshot's flagship 1M-context model for coding + knowledge work, live-verified 2026-07-20 to complete a real Claude Code turn) and Kimi K2.7 Code (kimi-k2.7-code — the proven 256K agentic coding model, kept as a selectable fallback). Either may be gated to higher account tiers, so a key without access surfaces a clear "model not supported". ⚠️ moonshot-v1-* was removed from the picker (2026-06-27): it passes a minimal model-acceptance check, but Moonshot rejects a full Claude Code session (which carries tool definitions) with a 400 "tokenization failed" error — so every real turn on it failed, making it a useless option. A session or project still defaulted to moonshot-v1-128k is now refused before the (paid) spawn with a clear "no longer available — pick another" message, instead of failing every turn. The earlier kimi-k2-0711-preview ("Kimi K2") was discontinued by Moonshot 2026-05-25 and removed the same way. The pick is staged locally and applied when you send your first message. Use default spawns kimi-k3 rather than omitting the model flag — Kimi requires a real Moonshot id (the shared claude binary's built-in default is a Claude id that Moonshot 404s as "model not found"), so the registry pins one via getProviderDefaultModel. Kimi has no separate "reasoning effort" knob. The model list is Moonshot's own — a Kimi session never inherits your Claude default model (those are Claude ids its endpoint would reject). See start-a-new-session.md.
Per-project default
Each project remembers a default provider in the projectDefaultProviders setting (a Record<projectId, ProviderId>). Empty by default — every project falls back to Claude. Change it from the project's three-dot menu → Edit → Default provider radios; the change persists immediately.
When you set a project's default to Kimi but Kimi isn't ready (toggle off or key missing), an amber "!" badge appears on that project's sidebar row. Hover the badge for a tooltip explaining the gap; click it to deep-link straight to the right Settings panel. The badge re-checks on every render, so fixing the gap clears it without a refresh. Claude defaults never show the badge — Claude is always considered ready.
Error states and fixes
Two gap codes — fewer than Gemini/Codex because there is no separate binary to check:
| Gap | What it means | Click-to-fix lands you at… |
|---|---|---|
toggle-off |
"Allow Kimi sessions" is OFF in Settings | Settings → Account → Allow Kimi sessions toggle |
key-missing |
No row of Kimi's supply list can serve (no Kimi key, and no other row ready) | Settings → Account → Kimi API key field, or Who pays & who serves |
Retired / unavailable model (added 2026-06-15). If a session's selected model is no longer accepted by Moonshot — either Omniscio has removed it from the picker (e.g. the discontinued kimi-k2-0711-preview) or the vendor killed a still-listed id server-side — Omniscio surfaces a clear "this Kimi model is no longer available — open the model picker and choose another" and parks the session as needs_you / recovery_failed, instead of silently retrying the rejected request into the generic placeholder-stuck give-up loop (which never names the real model problem). Two guards back this: a pre-spawn refusal (the model isn't in the current picker list) and a placeholder-stuck config-error guard (an anthropic-compat session that produced no output and hit the rejected-request signature). See provider-spawn-model-availability-contract.md.
The real reason, not a blanket "model unavailable." When Moonshot rejects a request mid-session for a reason other than the model — the account is out of balance, the conversation outgrew the context window, the key became invalid, or you're rate-limited — Omniscio reads Moonshot's actual error (carried on the zero-output synthetic placeholder, the same spot the Consumer-Terms gate reads) and shows the specific cause + fix (recharge / start fresh or pick a larger-context model / check the key in Settings / wait a moment) instead of the generic "model no longer available — choose another," which is now reserved for a genuinely unknown/retired model. Message-only — the session still parks as needs_you / recovery_failed. See provider-spawn-model-availability-contract.md vendor-error-is-classified-and-named.
Out-of-balance is also caught at turn-end (2026-07-04). The reason-specific surfacing above reads Moonshot's error off the zero-output synthetic placeholder. But if a Kimi turn streams some output and THEN Moonshot rejects it for non-payment (Request rejected (429) — [1113][Insufficient balance … Please recharge.]), that arrives on the turn buffer, not a placeholder — and previously fell through to the generic "this turn ended without a response." A dedicated turn-end gate now catches it there too and surfaces the same terminal "your Kimi account is out of balance — recharge, then send your message again" error (routed to a red error status). See vendor-model-config-400-surfacing-contract.md (its insufficient-balance sibling gate). That stop is the last resort: when Kimi's supply list has another row that can serve, running out of credit moves the session to that row and resends your message instead (see model-vendors.md).
Cost tracking
Spend hits the standard api_cost_log table because the claude CLI emits per-turn cost events in its stream-json output and process-manager.ts already plumbs those into trackApiCostRaw(). The source field on the cost row carries the provider ID (kimi), so the Settings → Usage dashboard breaks down Kimi spend separately from Claude/Codex/Gemini.
Cost is re-priced, not taken verbatim. The claude binary has no Moonshot price table, so its total_cost_usd bills Kimi models at Claude rates. Kimi is therefore costReporting: 'estimated', and Omniscio recomputes each turn from the token counts × Kimi's real rate (MODEL_PRICING) via applyAnthropicCompatReprice — the path shared by all four anthropic-compat vendors (DeepSeek/Kimi/GLM/MiniMax) — and, via the same repriceAnthropicCompatTurnCost, the human's one-shot aside side-questions too, which fork against the same Moonshot endpoint and so carry the identical Claude-rate mis-price. See central-ai-spend-contract.md anthropic-compat-cost-is-repriced.
Prompt-cache reads bill at the real cache-hit rate. The legacy kimi-k2.7-code reads from cache at Moonshot's published $0.19/M — a cacheRead override on its MODEL_PRICING row, not the flat 0.1×-input default. The flagship kimi-k3 needs no override: its real cache-hit rate ($0.30/M) already IS 0.1× of its $3/M input, so the default prices it correctly.
Telemetry: every successful Kimi spawn fires the spawn_non_claude_session feature event, recording { provider: 'kimi' } only — no session ID, project ID, or prompt content.
For agents
How it works under the hood
Spawn-env redirect, no alternate manager. Moonshot publishes an Anthropic-compatible API for Kimi — same request/response shape as Anthropic's Messages API, just at a different base URL. So Omniscio reuses the existing claude CLI binary (the same one Claude sessions use) and redirects every HTTP call at spawn time by setting two environment variables on the child process:
ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic— sends every HTTP request to Moonshot's compat endpoint instead ofapi.anthropic.com.ANTHROPIC_AUTH_TOKEN=<your Kimi API key>— supersedes the Claude OAuth/API-key for this child only.
The child process never knows it isn't talking to Anthropic. Streaming, tool calls, --resume for multi-turn, --output-format stream-json parsing all "just work" because they're handled by the standard claude binary against an upstream that speaks the same protocol.
No alternate session manager exists for Kimi — session-handlers.ts gates readiness, fires the spawn_non_claude_session feature event, then falls through to the same createSessionWithPrompt() path Claude sessions use. The provider: 'kimi' value is stored on the session row in the database; process-manager.ts reads that column and injects the right spawn-env on every CLI invocation (initial spawn, resume, aside-runner).
Compared to:
- DeepSeek — same shape (Anthropic-compat, no binary, spawn-env redirect). The only differences are the vendor base URL and the credential field. The Phase 2 code path branches
effectiveProvider === 'deepseek' || effectiveProvider === 'kimi'and treats them identically downstream. - Codex / Anti-Gravity — separate CLI binaries with their own protocols; need dedicated
*-session-manager.tsfiles. Kimi does not. - Gemini — a long-lived
gemini --acpACP child per session (its own JSON-RPC protocol). Kimi keeps the long-livedclaudechild process; resume viaclaude --resume <uuid>. - OpenClaw — remote WebSocket gateway. Kimi is plain HTTP to a vendor-hosted compat endpoint.
Files
- src/main/services/provider-setup/provider-readiness.ts — single source of truth for the 2-gate readiness check (used by ChangeProviderButton, Edit Project radios, project-row cue, spawn guard)
- src/main/process/process-manager.ts — injects
ANTHROPIC_BASE_URL+ANTHROPIC_AUTH_TOKENper session row'sprovidercolumn - src/main/ipc/session-handlers.ts — DeepSeek/Kimi spawn branch that gates readiness, fires the analytics event, and falls through to the claude path
- src/shared/types.ts —
ProviderIdunion,kimiApiKey,allowKimiSessionSpawnsetting fields - src/renderer/src/features/settings/sections/accounts/AccountSettings.tsx — Kimi section under "Show alternative AI providers"
Related
- deepseek-provider.md — same shape (Anthropic-compat, no binary, spawn-env redirect), different vendor + key
- model-vendors.md — who pays for a Kimi session and which company serves it (the supply list)
- gemini-provider.md — alt-CLI provider with per-turn spawn model
- codex-provider.md — alt-CLI provider with long-lived JSON-RPC child
- ai-providers.md — landing page for the full provider matrix
Last verified 2026-10-06