studio/chat: force reasoningEnabled=true on local reasoning-effort models

Followup to PR 5402 / 5412. The model-status refresh path in
use-chat-model-runtime carried reasoningEnabled forward verbatim for
every reasoning-capable model. That left one observable edge case:

  1. user picks an external model that supports Off (gpt-5.x, Claude
     4.x), clicks Off — store sets reasoningEnabled=false
  2. user switches back to a local reasoning-effort model
     (gpt-oss / Harmony-style) which does NOT support Off
  3. composer's effectiveReasoningEnabled override paints the UI as
     'Think: <level>' (on)
  4. chat-adapter sees reasoningEnabled=false on the local branch
     and sends '{}', so the backend's _request_reasoning_kwargs
     returns None and the Harmony template falls back to its own
     default effort instead of the displayed level

Mirror the composer's override in the store on load: for local
reasoning-effort models (where supportsReasoningOff is false), force
reasoningEnabled=true so the store and the UI agree on every send.
Other reasoning styles still inherit prior state — only the
reasoning-effort family changes.
This commit is contained in:
Roland Tannous 2026-05-14 11:18:44 +04:00
commit 4c612127e0

View file

@ -297,10 +297,20 @@ export function useChatModelRuntime() {
reasoningEffort: clampedReasoningEffort,
supportsPreserveThinking,
supportsTools,
// Reset per-turn reasoning flag so models that do not support
// reasoning do not inherit a stale off state from a prior model.
// Reset per-turn reasoning flag so:
// 1. models that do not support reasoning do not inherit a stale
// off state from a prior model, and
// 2. local reasoning-effort models (where the composer hides
// the Off option via supportsReasoningOff=false) cannot end
// up with reasoningEnabled=false carried over from an
// external model where Off was selected — the composer would
// keep showing "Think: <level>" via effectiveReasoningEnabled,
// but the chat-adapter would omit the kwarg and the Harmony
// template would fall back to its own default effort.
reasoningEnabled: supportsReasoning
? useChatRuntimeStore.getState().reasoningEnabled
? reasoningStyle === "reasoning_effort"
? true
: useChatRuntimeStore.getState().reasoningEnabled
: true,
ggufContextLength: currentGgufContextLength,
ggufMaxContextLength,