Skip to content

feat(kimi): add Kimi Code CLI provider via ACP#4105

Open
ccdwyer wants to merge 2 commits into
pingdotgg:mainfrom
ccdwyer:feat/kimi-provider
Open

feat(kimi): add Kimi Code CLI provider via ACP#4105
ccdwyer wants to merge 2 commits into
pingdotgg:mainfrom
ccdwyer:feat/kimi-provider

Conversation

@ccdwyer

@ccdwyer ccdwyer commented Jul 17, 2026

Copy link
Copy Markdown

What Changed

Adds Kimi (Moonshot AI's Kimi Code CLI, default model kimi-k3) as a first-party CLI provider, following the same shape as the Grok provider (#2809) in its current in-tree form:

  • Server: KimiAcpSupport spawns kimi acp (standard ACP over stdio, auth method login, KIMI_API_KEY passthrough); KimiDriver + KimiAdapter (sessions, turns, permissions, prompt/cancel settlement), KimiProvider (health via kimi --version + ACP model discovery with kimi-k3 fallback), and headless KimiTextGeneration for commit/PR/branch/title helpers.
  • Contracts: KimiSettings (+patch, providers.kimi), driver kind kimi, default model kimi-k3, slug aliases (k3, k2-thinking), display name.
  • Web: model picker + provider settings entries with an "Early Access" badge and a Kimi icon.
  • Tests: mirrored Grok's suites (adapter, provider, ACP support, text generation, gated live-CLI probe); the shared ACP mock agent gains an additive T3_ACP_MODEL_SET=kimi switch, defaulting to the existing Grok behavior byte-for-byte.

Deliberate deltas from the Grok pattern, because Kimi speaks standard ACP (built on the official ACP SDK):

  • No requiresNewThreadForModelChangesession/set_model works mid-session, covered by an adapter test asserting the RPC round-trip against the mock's request log.
  • No xAI-extension analog — no ask_user_question handler, prompt-completion fallback, or stop-reason patching; respondToUserInput is an explicit always-failing stub since no user-input request can ever be pending.

Why

Kimi K3 launched July 17 and the Kimi Code CLI ships native ACP support (kimi acp, the same integration surface Zed and JetBrains use), so it slots cleanly into the existing ACP provider infrastructure — same integration story as Grok, minus the vendor-extension workarounds. This gives Kimi subscribers first-party access from T3 Code.

UI Changes

Adds "Kimi" (with Early Access badge) to the provider picker sidebar and the provider settings list, mirroring Grok's presentation. No changes to existing UI.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Validation

  • Typecheck clean across contracts, shared, server, web; lint clean on touched files.
  • 126 targeted tests green, including the full Grok adapter/provider/support/text-generation suites re-run as regression.
  • Live kimi CLI probe test is gated behind T3_KIMI_ACP_PROBE=1 (same pattern as Grok's).

https://claude.ai/code/session_01PBVLpXchsU1WrZ1g5ndib6


Note

Medium Risk
Large new provider surface (child processes, turn/cancel settlement, auth discovery); Kimi defaults to enabled so hosts without the CLI may see probe errors until disabled or installed.

Overview
Adds Kimi as a first-party CLI provider (kimi acp), wired like other ACP-based drivers but without Grok-style vendor extensions.

Server: New KimiDriver, KimiAdapter, KimiProvider, KimiAcpSupport, and KimiTextGeneration — sessions/turns/permissions over ACP, health via kimi --version plus ACP model discovery (signed-out vs incompatible CLI), in-session session/set_model, and headless git helper prompts. The shared acp-mock-agent gains optional T3_ACP_MODEL_SET=kimi (default Grok unchanged).

Contracts & web: KimiSettings / providers.kimi, default model kimi-k3, Kimi in built-in drivers, text-generation routing, picker/settings (Early Access + icon).

Tests: Large adapter/provider/support/text-generation suites; registry tests include Kimi.

Reviewed by Cursor Bugbot for commit 5b199b3. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add Kimi Code CLI provider via ACP protocol

  • Adds a full Kimi provider integration backed by the ACP protocol, including driver registration, adapter, provider status checks, and text generation (commit messages, PR content, branch names, thread titles).
  • Introduces KimiAcpSupport for CLI path resolution (with Windows fallback to ~/.kimi-code/bin/kimi.exe), ACP runtime construction, and model selection.
  • Adds KimiProvider with health check logic that probes kimi --version and ACP model discovery, distinguishing signed-out, no-model-option, and available-models states.
  • Registers Kimi in the built-in driver list, settings schema, provider picker (with a 'new' badge), and settings UI with icon and 'Early Access' badge.
  • Adds kimi-k3 as the default model with no slug aliasing in the contracts layer.

Macroscope summarized 5b199b3.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5b35a17b-97f0-42cf-b380-95eb38900026

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jul 17, 2026
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from daa8df1 to 7e08be0 Compare July 17, 2026 21:06
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
@macroscopeapp

macroscopeapp Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces a substantial new provider integration (Kimi Code CLI) with ~4200 lines of new code across driver, adapter, text generation, and UI components. New features of this scope warrant human review. Additionally, two unresolved review comments identify potential bugs: a race condition in stopAll and unreachable signed-out error handling.

You can customize Macroscope's approvability policy. Learn more.

@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from 7e08be0 to bed537d Compare July 17, 2026 21:18
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from bed537d to 36244e5 Compare July 17, 2026 21:34
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from 36244e5 to 0e1f4d2 Compare July 17, 2026 21:50
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts Outdated
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
Comment thread apps/server/src/provider/Layers/KimiProvider.ts
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from 0e1f4d2 to ef6fc89 Compare July 17, 2026 22:05
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts Outdated
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from ef6fc89 to 21e95ae Compare July 17, 2026 22:35
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts Outdated
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from 21e95ae to 8156816 Compare July 17, 2026 23:20
Comment thread apps/server/src/provider/Layers/KimiAdapter.ts
Add Kimi (MoonshotAI Kimi Code CLI, default model kimi-k3) as a
first-party CLI provider, mirroring the in-tree Grok ACP provider:
KimiAcpSupport spawns `kimi acp` (standard ACP over stdio, auth method
"login"), with KimiDriver, KimiAdapter, KimiProvider snapshot/status
(`kimi --version`), headless KimiTextGeneration, contracts settings and
model registration, and web picker/settings UI with an Early Access
badge.

Unlike Grok, Kimi speaks standard ACP: no requiresNewThreadForModelChange
flag (session/set_model works mid-session, covered by an adapter test
asserting the RPC round-trip) and no xAI extension analog — the
ask_user_question handler, prompt-completion fallback, and stop-reason
patching are omitted, and respondToUserInput is an explicit
always-failing stub. The ACP mock agent gains a T3_ACP_MODEL_SET switch
to serve the Kimi model list additively.

Reviewed by a kimi-k3 + grok-4.5 + gpt-5.6-sol panel; both applied
follow-ups (dead user-input plumbing removal, mid-session set_model
test) came from panel findings.

Claude-Session: https://claude.ai/code/session_01PBVLpXchsU1WrZ1g5ndib6
@ccdwyer
ccdwyer force-pushed the feat/kimi-provider branch from 8156816 to eb978de Compare July 17, 2026 23:28
Ports three robustness gaps from the competing Kimi PR (pingdotgg#4098) into this
provider, adapted to the Grok-mirroring architecture:

1. resolveKimiBinaryPath — when `kimi` is not on PATH (the Windows installer
   does not add it), fall back to ~/.kimi-code/bin/kimi[.exe] before giving up,
   so a Windows user with no explicit binaryPath no longer gets a spurious
   "not installed". An explicit binaryPath stays authoritative. Requires
   FileSystem/Path, provided at every call site (KimiAdapter, KimiDriver,
   KimiTextGeneration, provider status probe).
2. Version-probe timeout 4s -> 15s — Kimi is a large single binary; cold starts
   on Windows can far exceed the warm-path latency and were failing the probe.
3. Signed-out UX — classifyKimiSessionModels distinguishes an EMPTY ACP model
   list (signed out -> "run `kimi login`", auth unauthenticated) from a MISSING
   model option (incompatible CLI), instead of silently falling back to a
   built-in model that fails on first use.

Reviewed by grok-4.5, kimi-k3, and gpt-5.6-sol against the three changes.

Claude-Session: https://claude.ai/code/session_01QGeRY5z128NxiM6Buz7ZQV

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5b199b3. Configure here.

auth: { status: "unauthenticated" },
message: KIMI_SIGNED_OUT_MESSAGE,
},
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signed-out path likely unreachable

Medium Severity

The new signed-out health path only runs after ACP startup succeeds with an empty model list, but this PR’s own probe notes that missing credentials fail at authenticate. Those users hit the generic ACP startup failure with auth: unknown instead of unauthenticated and the kimi login guidance.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5b199b3. Configure here.

});

const stopAll: KimiAdapterShape["stopAll"] = () =>
Effect.forEach(Array.from(sessions.values()), stopSessionInternal, { discard: true });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High Layers/KimiAdapter.ts:1386

stopAll iterates sessions.values() directly instead of acquiring each thread's lock, so a startSession that is mid-flight (between removing the old session and inserting the new ctx) is invisible to stopAll. stopAll reports success, then startSession finishes and leaves a live Kimi process that is never stopped. Consider routing each stop in stopAll through withThreadLock, or coordinating with in-progress starts.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/KimiAdapter.ts around line 1386:

`stopAll` iterates `sessions.values()` directly instead of acquiring each thread's lock, so a `startSession` that is mid-flight (between removing the old session and inserting the new `ctx`) is invisible to `stopAll`. `stopAll` reports success, then `startSession` finishes and leaves a live Kimi process that is never stopped. Consider routing each stop in `stopAll` through `withThreadLock`, or coordinating with in-progress starts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant