Skip to content

feat: force adaptive thinking via KIMI_MODEL_ADAPTIVE_THINKING#232

Open
RealKai42 wants to merge 2 commits into
mainfrom
feat/adaptive-thinking-env
Open

feat: force adaptive thinking via KIMI_MODEL_ADAPTIVE_THINKING#232
RealKai42 wants to merge 2 commits into
mainfrom
feat/adaptive-thinking-env

Conversation

@RealKai42
Copy link
Copy Markdown
Collaborator

Summary

Adds a way to explicitly force adaptive thinking (thinking: { type: 'adaptive' }) on Anthropic-compatible endpoints, overriding the model-name version inference.

Today the adaptive-vs-budget decision in kosong's AnthropicChatProvider.withThinking() is gated solely by supportsAdaptiveThinking(model), which parses the model name (FAMILY_VERSION_RE, requires Claude ≥ 4.6). Custom-named staff endpoints (e.g. coding-model-okapi-0527-vibe) fail that regex and always fall back to budget-based thinking — even when the backing model supports adaptive. There was no way to opt in.

This adds two aligned knobs:

  • Env var: KIMI_MODEL_ADAPTIVE_THINKING=true (part of the KIMI_MODEL_* channel)
  • Config field: adaptive_thinking on a [models.<alias>] entry (works for hand-written config.toml aliases too)

Both flow down to a new adaptiveThinking?: boolean option on the kosong provider. withThinking() now resolves the decision once as _adaptiveThinking ?? supportsAdaptiveThinking(model) and threads it through clampEffort / supportsEffortParam, so forcing adaptive also unlocks the max effort level. Unset = current behavior (infer from name).

Layers touched

  • packages/kosong/src/providers/anthropic.ts — new option + resolved-once adaptive decision
  • packages/agent-core/src/config/schema.tsadaptiveThinking on ModelAliasSchema
  • packages/agent-core/src/config/env-model.ts — parse KIMI_MODEL_ADAPTIVE_THINKING (generic parseBooleanVar, fail-fast)
  • packages/agent-core/src/session/provider-manager.ts — thread alias field into the anthropic provider config
  • Docs (en/zh env-vars.md + config-files.md) + changeset

Risk

Forcing adaptive on an endpoint whose backing model does not support it makes the API reject the request. The docs call this out; leave it unset unless you know the backing model supports adaptive thinking.

Test Plan

TDD throughout (failing test first, then implementation):

  • kosong: adaptiveThinking=true forces adaptive on an unversioned model name; max not clamped; no-flag stays budget-based (regression guard); explicit false forces budget on a 4.6 name
  • agent-core: KIMI_MODEL_ADAPTIVE_THINKING maps onto the alias (true/false/omitted) and rejects invalid input; alias adaptiveThinking forwarded to the anthropic provider config and omitted when unset
  • Full suite: 5023 passed, 0 failed
  • Lint: 0 errors
  • Typecheck: all packages + CLI pass

Add the KIMI_MODEL_ADAPTIVE_THINKING env var and a matching
adaptive_thinking model-alias field that force adaptive thinking
(thinking: { type: 'adaptive' }) on or off, overriding the Anthropic
model-name version inference.

This lets custom-named staff endpoints that back an adaptive-capable
model opt in even when the model name does not encode a parseable Claude
version (which would otherwise fall back to budget-based thinking).

The kosong AnthropicChatProvider resolves the adaptive decision once in
withThinking() as `_adaptiveThinking ?? supportsAdaptiveThinking(model)`
and threads it through clampEffort/supportsEffortParam so forced adaptive
also unlocks the max effort level.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 29, 2026

🦋 Changeset detected

Latest commit: 983399c

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

This PR includes changesets to release 4 packages
Name Type
@moonshot-ai/agent-core Minor
@moonshot-ai/kimi-code Minor
@moonshot-ai/kosong Minor
@moonshot-ai/migration-legacy 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
Copy link
Copy Markdown

pkg-pr-new Bot commented May 29, 2026

pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@983399c
npx https://pkg.pr.new/@moonshot-ai/kimi-code@983399c

commit: 983399c

@RealKai42
Copy link
Copy Markdown
Collaborator Author

@codex

Copy link
Copy Markdown

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

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: 298c22518a

ℹ️ 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".

// Explicitly declare adaptive-thinking support, overriding the kosong
// model-name version inference. Needed for custom-named Anthropic endpoints
// whose model name does not encode a parseable Claude version.
adaptiveThinking: z.boolean().optional(),
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 Make adaptive_thinking advertise thinking support

For the documented custom-named Anthropic case, setting only adaptive_thinking = true leaves capabilities empty. The TUI model picker uses ModelAlias.capabilities directly (apps/kimi-code/src/tui/components/dialogs/model-selector.ts:71-75) and treats aliases without thinking as unsupported, so switching to such an alias forces thinking=false before the request ever reaches the provider; the runtime capability resolver also still relies on declared/detected capabilities (packages/agent-core/src/session/provider-manager.ts:200-205). Please have the new flag imply the thinking capability, or require capabilities = ["thinking"] alongside it in the config docs, so the advertised one-field opt-in actually enables thinking for custom model names.

Useful? React with 👍 / 👎.

}

const effectiveEffort = clampEffort(effort, this._model);
const effectiveEffort = clampEffort(effort, this._model, adaptive);
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 Preserve xhigh when adaptive is forced

When adaptiveThinking=true is used for the documented custom-named endpoint case, xhigh still goes through clampEffort with the opaque model name and is downgraded to high because isOpus47(model) cannot recognize the backing model. That makes KIMI_MODEL_ADAPTIVE_THINKING=true fail to fully override name-based inference for custom Claude Opus 4.7/4.8 endpoints that support xhigh, even though max is preserved; the override needs a way to keep xhigh for known-capable custom endpoints or document that it cannot.

Useful? React with 👍 / 👎.

A model alias that sets adaptive_thinking=true (or env
KIMI_MODEL_ADAPTIVE_THINKING=true) without listing a thinking
capability previously resolved to thinking=false for custom-named
endpoints not in the capability catalog. The model picker then
classified the alias as "thinking unsupported" and forced thinking
off (persisting default_thinking=false).

Treat a forced adaptive flag as advertising the thinking capability
in resolveModelCapabilities, so the config.toml one-field opt-in
agrees with the KIMI_MODEL_* env path (which already defaults
capabilities to include thinking).
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