Fork of DimQ1/kimi-copilot-provider adding Kimi K3 support, Moonshot API endpoints, usage/cost tracking, and balance display.
VS Code extension that registers Kimi K2, K2.7, and K3 models as a custom language model provider for GitHub Copilot Chat. Proxies chat requests to the Moonshot API via SSE streaming with real-time cost and cache hit tracking.
| Picker ID | Context | Notes | Input (miss / hit) / Output |
|---|---|---|---|
kimi-k2.7-code |
256K / 32K | Coding model, thinking always on | $0.95 / $0.19 / $4.00 per 1M |
kimi-k2.7-code-highspeed |
256K / 32K | ~180 T/s output variant | $1.90 / $0.38 / $8.00 per 1M |
kimi-k2.6 |
256K / 32K | Multimodal + thinking | $0.95 / $0.16 / $4.00 per 1M |
kimi-k2.5 |
256K / 32K | Multimodal + thinking | $0.60 / $0.10 / $3.00 per 1M |
kimi-k3 |
1M / 32K | Frontier MoE, always-on reasoning, multimodal — may need separate K3 API key | $3.00 / $0.30 / $15.00 per 1M |
Official pricing, verified 2026-07-24: K3 · K2.7 Code · K2.6 · K2.5. "Hit" = cache-hit input rate, "miss" = cache-miss input rate.
The extension implements the vscode.lm.LanguageModelChatProvider API (VS Code 1.93+) and forwards chat requests to the Moonshot API:
POST https://api.moonshot.ai/v1/chat/completions
- All models share the same endpoint; no manual endpoint switching needed
- Streaming uses
stream_options: {include_usage: true}to capture token usage from every response - After each call the extension fetches
GET /v1/users/me/balanceand shows it in the status bar
npm install
npm run compile
# or press F5 to launch the Extension Development HostCtrl+Shift+P → Extensions: Install from VSIX... → kimi3-copilot-provider-*.vsix
Ctrl+Shift+P → Kimi3 Copilot: Set API Key
For Kimi K3, get a key from platform.kimi.ai/console/api-keys. If your account doesn't have K3 access yet, set a separate K3 key:
Ctrl+Shift+P → Kimi3 Copilot: Set K3 API Key
When a K3 key is set it takes priority for K3 requests and falls back to the main key when absent.
- Open Chat in VS Code
- Click the model picker → Manage Models
- Find Kimi3 Copilot Provider → ✅ check the desired model
| Setting | Default | Description |
|---|---|---|
kimi3Copilot.model |
kimi-k2.7-code |
Default model used in chat |
kimi3Copilot.endpoint |
https://api.moonshot.ai/v1/chat/completions |
Chat completions endpoint |
kimi3Copilot.k3Endpoint |
(empty) | Override endpoint for K3 only; leave empty to use main endpoint |
kimi3Copilot.baseUrl |
https://api.moonshot.ai |
Base URL (used for balance fetch) |
kimi3Copilot.temperature |
1.0 |
Sampling temperature (model-dependent; fixed at 1.0 for K2.7/K3) |
kimi3Copilot.maxTokens |
0 |
Max completion tokens (0 = model default) |
kimi3Copilot.topP |
0.95 |
Top-p sampling (fixed at 0.95 for K2.7/K3) |
kimi3Copilot.systemPrompt |
(see config.ts) |
System prompt prepended to every request |
kimi3Copilot.timeout |
60000 |
Request timeout in ms |
kimi3Copilot.enableStreaming |
true |
Enable SSE streaming |
kimi3Copilot.maxRetries |
5 |
Max retry attempts for failed requests (network errors, HTTP 429/5xx) |
kimi3Copilot.retryBaseDelayMs |
2000 |
Base delay between retries in ms (backoff grows exponentially from it) |
kimi3Copilot.retryMaxDelayMs |
60000 |
Upper bound for the retry delay in ms |
kimi3Copilot.modelConfigs |
{} |
Per-model JSON overrides (temperature, topP, maxOutputTokens, systemPrompt, toolCalling, etc.) |
kimi3Copilot.modelIdOverrides |
{} |
Remap picker model IDs to custom API model IDs |
kimi3Copilot.warnOnContextFill |
true |
Warn when the conversation fills much of the context window |
kimi3Copilot.contextWarnThreshold |
0.8 |
Context-fill fraction (0–1) that triggers a fill warning |
kimi3Copilot.contextErrorThreshold |
0.95 |
Context-fill fraction (0–1) at which requests are refused to prevent API errors |
kimi3Copilot.warnOnCacheMiss |
true |
Warn when the prefix-cache miss rate is high |
kimi3Copilot.cacheMissWarnThreshold |
0.8 |
Cache-miss fraction (0–1) that triggers a warning |
Six behaviours mirror the official MoonshotAI/kimi-code agent's request layer:
- Prompt-cache session affinity — every chat turn sends a stable
prompt_cache_key: a seed persisted across VS Code restarts (so a returning session can hit a still-warm server cache) plus a hash of the first user message, which keeps different conversations on separate cache entries. This is what actually improves the cache-hit rate shown in the usage stats. - Deterministic tool ordering — tool definitions are serialized sorted by name. Copilot may hand tools in varying order between turns; an unstable order breaks the prefix cache for everything downstream of the tool block.
- Completion-budget clamp —
max_completion_tokensis folded against the remaining context window each turn, so a nearly-full conversation no longer triggers a400 max_tokens too largerejection. x-trace-idcapture — Kimi's trace id is read from each response and included in the completion log and error messages for support.- Typed error classification — API errors are classified once into a typed kind (
context_overflow,auth,rate_limit,server, …) insrc/errors.ts, so auto-compact triggers only on a genuine context overflow. - Streaming timing stats — streaming turns log time-to-first-token and output throughput (e.g.
← completed in 2200ms, ttft 200ms, 20 tok/s). - Context fill counts output too — the pre-send guard's floor is
prompt_tokens + completion_tokens, so the previous reply's tokens count toward the next turn's context estimate.
Kimi's context caching is automatic: it reuses the request's stable leading prefix, and any change invalidates that point and everything after it. The extension therefore keeps the prefix stable by construction:
- System prompt first — the volatile bits (date at day precision, workspace folders) go at its end.
- Tool definitions — sorted by name (see above), and
tool_choice/sampling/thinking params are fixed per model so they never churn between turns. - Conversation history, then the new user message last.
Two ground rules to know: a request is only cached when its prompt exceeds 256 tokens (tiny requests never warm the cache), and keeping tool definitions / system content byte-stable across turns is what drives the hit rate — which is why the usage stats' cache-hit rate exists as a feedback signal.
Two optional, non-blocking warnings help you avoid degraded output and wasted spend. Each fires at most once per threshold-bucket per session (no notification spam) and is written to the Kimi3 Copilot output channel.
Models degrade in very long contexts (lost-in-the-middle, higher latency/cost) well before the hard token limit. Kimi does not publish an official degradation point, so the extension warns at a configurable 80% fill by default, computed from the actual usage.prompt_tokens returned by each response against the model's advertised input budget.
How context is managed: GitHub Copilot Chat (not the Kimi API) trims conversation history to fit the
maxInputTokensthis provider reports — there is no server-side context compression for BYOK providers. The warning tells you before quality drops, so you can start a fresh chat. When a warning appears you'll see something like:
Kimi: Context is 82% full for kimi-k3 (858,993 / 1,048,576 tokens). Models degrade in long contexts — consider starting a fresh chat.
Tune or disable via kimi3Copilot.contextWarnThreshold / kimi3Copilot.warnOnContextFill.
Before any request is sent, the extension estimates the full token size of the outgoing request (messages, tool calls, and tool results, using the CJK-aware heuristic) and compares it against the model's input budget. The estimate is anchored to actual usage: the API-reported prompt_tokens from the previous conversation turn serves as a hard floor (context only grows within a session), so the guard tracks real consumption rather than the deliberately-conservative heuristic alone. A fresh chat resets the floor automatically.
-
~80% (warning threshold) — logged to the Kimi3 Copilot output channel (
Context estimate: ~x / y tokens (z% — status), actual floor n). -
95% (error threshold) — the request is refused with a clear error instead of failing at the API:
Kimi context critical: ~990,000 / 1,048,576 tokens (94%). The context is almost full. Consider starting a new chat session or running "/compact" soon. -
100%+ (exceeded) — refused with guidance to start a new chat, run
/compact, or remove files from the context.
The estimate is diagnostics-only (output channel) — the live context display is Copilot Chat's native gauge below the chat input (see Session Info below), which is fed actual prompt_tokens and is therefore exact. The error threshold is tunable via kimi3Copilot.contextErrorThreshold; the warn threshold via kimi3Copilot.contextWarnThreshold. Test Connection is exempt from the guard.
Kimi's prefix cache makes repeated system/tool context cheap (for K3, cached input is $0.30/1M vs $3.00/1M uncached). If the conversation prefix keeps changing — e.g. tools being added/removed, or earlier messages edited — the cache can't help and you pay full price. The extension warns when the daily cache-miss rate exceeds 80% (after a 10K-token warm-up so cold starts don't trigger it).
Kimi: Cache miss rate is 95% — most prompt tokens are being re-processed at full cost. Keep the conversation prefix stable to reuse Kimi's prefix cache.
Tune or disable via kimi3Copilot.cacheMissWarnThreshold / kimi3Copilot.warnOnCacheMiss.
VS Code 1.109+ shows a context window usage indicator in the chat input (click it, or run Show Context Window Usage, for the Session Info popover). Kimi models fully integrate with it:
| What | Status |
|---|---|
Total window (denominator, e.g. … / 1M tokens) |
✅ Works — read from each model's maxInputTokens + maxOutputTokens |
| Context Size picker (model-picker dropdown) | ✅ Works — pick a smaller tier (e.g. K3: 1M → 256K); the gauge, Copilot's history trimming, and this extension's fill warning all honor it |
| Used tokens (numerator + breakdown) | ✅ Works — the extension emits a usage data part after each real conversation turn, matching the mechanism used by the DeepSeek V4 provider |
The Context Size picker defaults to the full window, so nothing changes unless you opt into a smaller budget. Picking a smaller tier makes Copilot trim history earlier, rescales the Session Info gauge, and makes the context-fill warning measure against that budget.
After every API call the status bar shows your live account balance (fetched from GET /v1/users/me/balance):
K₃ $49.58
Context-window usage is shown only in Copilot Chat's native gauge (below the chat input), which uses actual API-reported token counts — the status bar no longer duplicates it with a less accurate estimate.
The status bar has two display modes:
| Display | Meaning |
|---|---|
K₃ $49.58 |
Live balance — fetched from GET /v1/users/me/balance after the last request. |
K₃ ~$0.0123 |
Estimated cost (note the ~) — today's accumulated cost, computed locally from the per-model pricing table. Shown when the balance fetch hasn't succeeded yet. |
The display falls back to the estimate whenever the balance endpoint returns no value — for example:
- the balance request failed (network error, non-2xx status, expired/invalid key),
- no successful balance fetch has happened since startup (the balance is only fetched after a chat request, not on activation),
- the response body didn't contain
data.available_balance.
When this happens a warning is written to the Kimi3 Copilot output channel (Balance fetch failed (HTTP …) — status bar will show estimated cost instead). Check that channel if the status bar shows ~ unexpectedly. The balance is fetched with the same effective key as the request (K3 key for K3 models, main key otherwise), so a K3-only key setup still reports balance.
Hover for a tooltip with today's aggregated stats:
| Metric | Source |
|---|---|
| Balance | Real-time API call |
| Requests | Counted per response |
| Input / Output tokens | From usage.prompt_tokens / usage.completion_tokens |
| Cached tokens | From usage.cached_tokens (cache hit → e.g. $0.30/1M vs $3.00/1M miss for K3; see the pricing table above) |
| Cache hit rate | cached_tokens / prompt_tokens × 100% |
| Estimated cost | Per-model pricing table, cached vs uncached input |
Stats reset at midnight and persist across VS Code restarts via workspaceState.
| Command | Description |
|---|---|
| Kimi3 Copilot: Set API Key | Store main API key in SecretStorage |
| Kimi3 Copilot: Set K3 API Key | Store separate K3 API key (optional) |
| Kimi3 Copilot: Select Default Model | Pick the default model |
| Kimi3 Copilot: Edit Model Configuration | Per-model JSON overrides |
| Kimi3 Copilot: Test Connection | Verify endpoint + key with a live request; shows model, endpoint, and key source |
| Kimi3 Copilot: Show Usage Stats | Open today's usage report as a Markdown document |
| Kimi3 Copilot: Reset Usage Stats | Reset today's counters |
| Kimi3 Copilot: Open Settings | Open kimi3Copilot settings |
src/
├── config.ts # ConfigurationManager: settings, SecretStorage keys (main + K3)
├── context-tracker.ts # SessionContextTracker: pre-send context estimate + overflow guard
├── errors.ts # Pure API-error classification (typed context-overflow / auth / rate-limit)
├── extension.ts # activate(): provider, usage tracker, command registration
├── models.ts # Model registry with per-model capabilities and defaults
├── provider.ts # KimiChatProvider: request building, retry, usage capture, balance fetch
├── requestKind.ts # Request classifier (skips aux requests for native gauge reporting)
├── retry.ts # Pure retry/backoff helpers (jitter + deadline budget)
├── thinking.ts # LanguageModelThinkingPart shim (reflection + text fallback)
├── tokenize.ts # Pure token estimator + cache-key / completion-budget / stream-timing helpers
├── types.ts # Shared API types (KimiRequest, KimiMessage, KimiUsage, …)
├── usage.ts # UsageTracker: cost calculation, status bar, daily aggregation
├── usageMath.ts # Pure pricing/cost/format math
├── warnings.ts # Pure context-fill + cache-miss threshold logic
└── test/ # Unit tests
Provider implements the 3 mandatory methods of LanguageModelChatProvider:
provideLanguageModelChatInformation— returns model metadataprovideLanguageModelChatResponse— streams response viaProgress<LanguageModelResponsePart>provideTokenCount— estimates token count
For all thinking-capable models (K2.7-code, K2.6, K2.5, K3), the model's chain-of-thought (reasoning_content) streams inline before the final answer in Copilot Chat. This is always enabled — no configuration needed.
K3 note: When switching to K3 mid-session, the extension shows a warning that quality may be unstable without full thinking history. Starting a fresh chat is recommended.
| Feature | Behaviour |
|---|---|
K2.7 thinking |
Always {type: "enabled", keep: "all"} — cannot be disabled |
K2.6 thinking |
{type: "enabled"} by default; can be disabled |
| K3 reasoning | reasoning_effort: "max" (replaces thinking) |
reasoning_content |
Streamed inline before the final answer for all thinking models |
temperature / top_p |
Fixed by API for all K2.x/K3 models; not sent explicitly |
presence_penalty / frequency_penalty |
Fixed at 0 for K2.x/K3; not sent explicitly |
max_completion_tokens |
Used (not deprecated max_tokens); clamped to the remaining context window each turn |
stream_options |
{include_usage: true} always set when streaming |
prompt_cache_key |
Stable key sent on every chat turn for cache affinity; the seed persists across VS Code restarts |
tool_choice |
auto/none/required or {type:"function",function:{name:"…"}} — required is K3-only |
K3 uses a dedicated default system prompt designed to channel its architectural reasoning productively. It requires K3 to explain its reasoning before making structural changes, present trade-offs, and surface unexpected issues. Override via kimi3Copilot.systemPrompt or per-model kimi3Copilot.modelConfigs.
| Task | Command |
|---|---|
| Compile (once) | npm run compile or .\scripts\release.ps1 compile |
| Compile (watch) | npm run watch |
| Launch extension | F5 (Extension Development Host) |
| Verify (compile + unit tests + lint) | .\scripts\release.ps1 verify |
| Package .vsix | .\scripts\release.ps1 package (auto-versioned filename) |
| Full release (verify + package) | .\scripts\release.ps1 release |
| Run unit tests | npm run test:unit |
| Run extension-host tests | npm test (downloads VS Code — heavy) |
| Lint | npm run lint |
| Format | npm run format |
- VS Code 1.93.0 or higher
- Node.js 18+
- Active Moonshot API key from platform.kimi.ai/console/api-keys
- Moonshot API Overview
- Chat Completions API
- K3 Pricing
- K3 Tool Calling Best Practices
- Model Parameter Reference
- Check Balance API
- Kimi K2.7 Code Quickstart
- VS Code Language Model Chat Provider
MIT