Skip to content

feat(acp): support selecting thinking effort levels - #1992

Merged
RealKai42 merged 2 commits into
mainfrom
feat/acp-thinking-effort-levels
Jul 21, 2026
Merged

feat(acp): support selecting thinking effort levels#1992
RealKai42 merged 2 commits into
mainfrom
feat/acp-thinking-effort-levels

Conversation

@RealKai42

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below (user feedback).

Problem

Users reported that ACP clients (e.g. Zed) cannot select a thinking effort level — the thinking config option was a binary off / on toggle, and on was silently mapped to the model's default effort. The engine (resolveThinkingEffort) and the SDK (Session.setThinking(effort)) already fully support support_efforts granularity; the adapter deliberately collapsed it to a boolean, so levels like low / medium / high were unreachable over ACP even though the protocol's thought_level select carries arbitrary rows.

What changed

Scoped to packages/acp-adapter (engine / SDK / protocol untouched):

  • Advertise levels: the thinking config option now emits off plus one row per declared support_efforts level of the current model. Boolean models (no support_efforts) keep the legacy off / on rows; always_thinking models drop the off row. The model catalog helper now exposes supportEfforts alongside defaultThinkingEffort.
  • Accept levels: session/set_config_option({configId: 'thinking', value}) takes off, the legacy on (alias for the model default effort, kept for compatibility), or a declared level; unknown levels are rejected with invalid_params before any SDK call.
  • Truthful snapshots: the adapter tracks the thinking state as an effort string and reconciles it with the engine-normalized value read back from Session.getStatus() after model/thinking changes, so engine-side clamping (e.g. always_thinking rejecting off, or a level the newly selected model does not declare) is what the next snapshot renders.

This fits Kimi Code because the adapter stays a thin projection over the engine's single source of truth (support_efforts / default_effort / resolveThinkingEffort) — no parallel effort logic is introduced.

Verification: 324 unit tests green (new cases for per-level rows, default-effort mapping, invalid-level rejection, status reconciliation); typecheck clean; plus a real-process smoke test driving kimi acp over stdio with a real ACP client through initialize → session/new → level selection → invalid-level rejection → model switching (16/16 assertions passed).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

The ACP thinking config option was a binary on/off toggle mapped to the
model's default effort, so ACP clients (e.g. Zed) could not pick a
concrete level even though the engine and the SDK fully support
support_efforts granularity.

- Advertise one select row per declared effort level (off + levels);
  boolean models keep the legacy off/on rows, always-thinking models
  drop the off row.
- Track the session thinking state as an effort string and reconcile it
  with the engine-normalized value read back from session status after
  model/thinking changes.
- Validate incoming levels against the current model's catalog and
  reject unknown ones with invalid_params before any SDK call; keep the
  legacy 'on' value as an alias for the model default effort.
@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 344f296

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@344f296
npx https://pkg.pr.new/@moonshot-ai/kimi-code@344f296

commit: 344f296

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 77c13d990e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +132 to +137
const currentValue =
!alwaysThinking && currentEffort === 'off'
? 'off'
: efforts.includes(currentEffort)
? currentEffort
: defaultEffort;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep thinking currentValue within advertised options

When a model declares default_effort that is not present in support_efforts (the schema allows this, and agent-core's defaultThinkingEffortFor falls back to a declared effort), this fallback makes the ACP select's currentValue become that invalid default even though options only contains off plus supportEfforts. In that configuration, a fresh snapshot with current effort on/unknown can render a value the client cannot select; validate defaultEffort against efforts and fall back to the middle declared effort instead.

Useful? React with 👍 / 👎.

@RealKai42
RealKai42 merged commit a8f1ca3 into main Jul 21, 2026
14 checks passed
@RealKai42
RealKai42 deleted the feat/acp-thinking-effort-levels branch July 21, 2026 05:48
@github-actions github-actions Bot mentioned this pull request Jul 21, 2026
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