Skip to content

refactor!: overhaul thinking config and effort resolution#1132

Open
liruifengv wants to merge 15 commits into
mainfrom
support-effort
Open

refactor!: overhaul thinking config and effort resolution#1132
liruifengv wants to merge 15 commits into
mainfrom
support-effort

Conversation

@liruifengv

Copy link
Copy Markdown
Collaborator

Related Issue

No issue — this implements the internal design at plan/thinking-model-overhaul.md.

Problem

The thinking on/off toggle and effort level were scattered across config, agent-core, SDK, TUI, and providers, accumulating redundancy:

  • default_thinking (boolean), thinking.mode (auto/on/off, where auto and on were equivalent), and thinking.effort overlapped semantically.
  • The static ThinkingEffort enum ('off' | 'low' | 'medium' | 'high' | 'xhigh' | 'max') hardcoded levels that should come from each model's support_efforts, forcing provider-specific mappings like xhigh → high for Kimi.
  • 'on' leaked across TUI → SDK → agent-core as a ghost level that was never in the enum.
  • always_thinking was clamped in three separate places (UI, getter, ACP adapter).
  • The TUI stored one state in two fields (thinking: boolean + thinkingLevel?: string) with five duplicate fallbacks.

What changed

  • Config converged to [thinking] { enabled, effort }. default_thinking and thinking.mode are removed. enabled = false means off; otherwise effort (or the model default) is used.
  • ThinkingEffort is now an open string ('off' | 'on' | (string & {})). Effort levels come from each model's declared support_efforts; providers normalize any undeclared level to "no effort" instead of rejecting it. The kimiEffort / wireEffortToThinkingEffort mappings are gone.
  • Single source of truth for defaults and clamping. resolveThinkingEffort / defaultThinkingEffortFor derive the default from the model (default_effort → middle of support_efforts'on'). The always_thinking clamp lives in one place and now honors an explicitly configured effort instead of discarding it.
  • TUI keeps one thinkingEffort field instead of the boolean + level pair. 'on' is normalized to the model default at the UI boundary so it never leaks past the picker.
  • Naming is unified to thinkingEffort / resolveThinkingEffort / defaultThinkingEffortFor across the codebase.

This is a breaking change: existing default_thinking and thinking.mode are no longer read, and are stripped on the next config write. Docs include a "Deprecated fields" section with the migration path and the version the new fields were added in.

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.

- kimi provider: emit thinking.effort in the new wire format; keep reasoning_effort mirrored during the transition
- model catalog: thread support_efforts / default_effort from oauth through to /models
- config schema: add supportEfforts / defaultEffort on model aliases
- TUI: multi-segment thinking control in /model, new /effort command, footer effort display
- switch status uses displayName and distinguishes model vs effort-only changes
- thinking-effort-switching.md: implemented multi-level effort switching
- thinking-model-overhaul.md: follow-up refactor plan for the thinking state model
Replace default_thinking and thinking.mode with a single [thinking] enabled/effort table. ThinkingEffort is now an open string ('off' | 'on' | model-declared effort); effort levels come from each model's support_efforts instead of a fixed enum.

Centralize default and always_thinking clamp logic in resolveThinkingEffort/defaultThinkingEffortFor, and honor an explicitly configured effort when an always_thinking model is forced back on.

TUI keeps a single thinkingEffort field instead of the boolean + level pair; 'on' is normalized to the model default at the UI boundary.

BREAKING CHANGE: default_thinking and thinking.mode are removed from config; migrate to [thinking] enabled/effort.
@changeset-bot

changeset-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bcea992

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

This PR includes changesets to release 3 packages
Name Type
@moonshot-ai/kimi-code Major
@moonshot-ai/kimi-code-sdk Major
@moonshot-ai/acp-adapter Patch

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 Jun 26, 2026

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

commit: bcea992

@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: 04f3a6a3a2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agent-core/src/agent/config/thinking.ts
Comment thread packages/acp-adapter/src/server.ts Outdated
Comment thread packages/protocol/src/modelCatalog.ts
Rename comments, error messages, parameter names, the SetThinkingPayload wire field (level -> effort), and TUI local variables so the thinking effort naming is consistent throughout. No behavior change.
…fort

Rename liveLevel/prevLevel/levelChanged/commitLevel/effectiveLevel to liveEffort/prevEffort/effortChanged/commitEffort/effectiveEffort in the TUI model picker and config commands.
…tests

Rename levelLabel -> effortLabel, EffortSelectorOptions.levels -> efforts, and 'effort level(s)' / 'default level' / 'requested level' wording in comments, error messages, slash-command description, and test titles to effort. Also restore the withThinking(effort) parameter rename in the Kimi provider that was accidentally reverted.
- OpenAI thinkingEffortToReasoningEffort and Anthropic clampEffort now normalize 'on' / unrecognized efforts instead of throwing, so boolean non-Kimi models no longer crash on session start.

- ACP resolveCurrentThinkingEnabled treats a non-empty thinking.effort as enabled, matching agent-core's resolveThinkingEffort.

- REST promptThinkingSchema accepts any non-empty effort string so model-declared efforts are not rejected at the API boundary.
…_effort

The kimi provider now sends reasoning_effort only when the model declares support_efforts; boolean models (no support_efforts) send only thinking.type. Update the kimi e2e tests to drop the stale reasoning_effort expectation for the boolean test model.
Add effort = "high" to the documented [thinking] table in the config parse test and assert config.thinking.effort is resolved, so the new [thinking] effort field has direct parse coverage.
Capture the explore agent's test coverage review for the thinking overhaul PR, including P1/P2 gaps and the two open design questions, for follow-up test additions.
The /models endpoint now returns effort levels under a nested think_efforts object ({ support, valid_efforts, default_effort }). Parse it preferentially in both managed-kimi-code and open-platform model parsing, falling back to the legacy flat support_efforts / default_effort fields for older servers.
Drop the legacy flat support_efforts / default_effort fallback. The think_efforts object is now the single source, and its support flag gates the whole object — when support is not true, valid_efforts and default_effort are ignored entirely.
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