Skip to content

fix(web): submit thinking level verbatim and drop the hardcoded default - #1673

Merged
wbxl2000 merged 3 commits into
mainfrom
fix/web-thinking-level-verbatim
Jul 14, 2026
Merged

fix(web): submit thinking level verbatim and drop the hardcoded default#1673
wbxl2000 merged 3 commits into
mainfrom
fix/web-thinking-level-verbatim

Conversation

@wbxl2000

Copy link
Copy Markdown
Collaborator

Related Issue

None — the problem is explained below.

Problem

kimi-web silently rewrote the user's thinking level before it reached the backend, diverging from the CLI (TUI):

  • Every prompt path (prompt submit, steer, skill activation, BTW side chat) coerced the stored level onto the target model's declared support_efforts — e.g. a carried-over max was downgraded to the model's default high, so what ran did not match what the user picked.
  • With nothing persisted, the web defaulted to a hardcoded high, a frontend invention with no CLI counterpart. The CLI sends no thinking override when [thinking] is unset and lets the daemon resolve the config/model default.
  • Switching models carried the old level over (coerced), while the TUI model picker pre-selects the target model's own default level.

What changed

  • All prompt paths now submit rawState.thinking verbatim; the coercion helpers (coerceThinkingForModel, coercePromptThinking) are removed.
  • rawState.thinking is ThinkingLevel | undefined. An absent/invalid stored value means "no preference": prompts omit the thinking field and the daemon resolves the default (the kap-server prompt route already treats thinking as optional). Only concrete levels are persisted to localStorage.
  • thinkingLevelForModelSwitch now mirrors the TUI picker: switching onto a different model pre-selects that model's default level; re-selecting the current model keeps the level untouched.
  • Composer, mobile settings sheet, and /status display the effective level via a new effectiveThinkingLevel helper (stored value, else the model default), and /thinking cycles from it.
  • Tests that locked in the old coercion were replaced with verbatim/undefined-semantics cases. Includes a patch changeset for @moonshot-ai/kimi-code (web is bundled into the CLI artifact).

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 (behavior fix only; no documented behavior changes).

@changeset-bot

changeset-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 94dd9bf

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 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 Jul 14, 2026

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

commit: 9dec241

@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: 7fad48053b

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

model: ModelThinkingInfo | undefined,
level: ThinkingLevel | undefined,
): ThinkingLevel {
return level ?? defaultThinkingLevelFor(model);

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 Use daemon-resolved thinking for unset preference

When level is undefined, this assumes the daemon will use the model default, but the daemon resolver honors [thinking] config first (packages/agent-core-v2/src/app/model/thinking.ts:79-93), so enabled=false or a configured effort can override the model default. In a fresh web client with no persisted thinking, prompts now omit thinking, meaning Composer/mobile /status can display and /thinking can cycle from a level that is not what will actually run; please use the daemon-resolved status/config value for the unset case instead of deriving it solely from the model.

Useful? React with 👍 / 👎.

if (nextThinking !== prevThinking) {
rawState.thinking = prevThinking;
saveThinkingToStorage(prevThinking);
applyThinkingLevel(prevThinking);

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 Clear persisted thinking when rolling back to unset

When a model switch fails after prevThinking was unset, this rollback calls applyThinkingLevel(undefined), but applyThinkingLevel only writes localStorage for concrete levels; the target model default saved by the optimistic call remains in storage. Reproduces by switching models from a fresh/no-preference state while the profile POST fails: the UI rolls back for this session, but after reload prompts send the stale explicit effort instead of omitting thinking.

Useful? React with 👍 / 👎.

@wbxl2000
wbxl2000 force-pushed the fix/web-thinking-level-verbatim branch from 7fad480 to 8fe65ef Compare July 14, 2026 06:24
@wbxl2000
wbxl2000 changed the base branch from main to fix/v2-model-catalog-efforts July 14, 2026 06:24
wbxl2000 added 3 commits July 14, 2026 15:00
Align kimi-web's thinking-level handling with the TUI:

- Submit the stored level as-is on every prompt path (prompt, steer,
  skill activation, BTW side chat) instead of coercing it onto the
  target model's declared efforts.
- No stored preference (undefined) instead of a hardcoded 'high'
  default: prompts omit the thinking override and the daemon resolves
  the config/model default, same as an unset [thinking] in the TUI.
- Model switcher pre-selects the target model's own default level when
  switching models; re-selecting the current model keeps the level.
- Display the effective level (stored value, else the model default)
  in the composer, mobile sheet, and /status panel.
The stub daemon (dev/stub-daemon.mjs) no longer exists, so the
dev:stub npm script and its docs references were dead weight.
…ally

- With no stored preference, loadModels() pins the active model's
  catalog default_effort as a concrete in-memory value, so what the
  UI shows, what prompts submit, and what the session runs always
  agree. localStorage stays reserved for levels the user picked.
- setThinking and model switches now also write the daemon-wide
  [thinking] config (same mapping as the TUI's thinkingEffortToConfig),
  so sessions created by other clients inherit the pick.
@wbxl2000
wbxl2000 force-pushed the fix/web-thinking-level-verbatim branch from 94dd9bf to 9dec241 Compare July 14, 2026 07:01
@wbxl2000
wbxl2000 changed the base branch from fix/v2-model-catalog-efforts to main July 14, 2026 07:01
@wbxl2000

Copy link
Copy Markdown
Collaborator Author

@codex

@wbxl2000
wbxl2000 merged commit 0f64b4d into main Jul 14, 2026
13 checks passed
@wbxl2000
wbxl2000 deleted the fix/web-thinking-level-verbatim branch July 14, 2026 07:04

@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: 9dec241470

ℹ️ 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 on lines +188 to +190
if (rawState.thinking === undefined) {
const active = modelById(currentModelId());
if (active !== undefined) rawState.thinking = defaultThinkingLevelFor(active);

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 Defer default pin until the active session is known

When there is no stored thinking preference, this pins rawState.thinking during loadModels(), but the first-load flow calls modelProvider.loadModels() before sessions are loaded and before a deep-linked or auto-selected session is chosen. In that path currentModelId() only sees the global default model, so opening an existing session whose model differs from the default can store e.g. off and later submitPrompt sends that explicit value instead of letting the daemon resolve the session/model default.

Useful? React with 👍 / 👎.

@github-actions github-actions Bot mentioned this pull request Jul 14, 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