bug: Shift+Tab thinking cycle is a no-op when model has no reasoning support #206

Open
opened 2026-03-19 02:10:42 +00:00 by jason.woltje · 0 comments
Owner

Summary

Pressing Shift+Tab to cycle thinking levels appears to do nothing when the active gateway session uses a model with reasoning: false. The cycle is mathematically a no-op.

Root Cause

In packages/cli/src/tui/app.tsx (Shift+Tab useInput handler):

const levels = socket.availableThinkingLevels;   // ["off"] — single element
const currentIdx = levels.indexOf(socket.thinkingLevel);  // 0
const nextIdx = (currentIdx + 1) % levels.length;          // (0+1) % 1 = 0  <- always 0
const next = levels[nextIdx];                               // "off"
socket.setThinkingLevel(next);                              // sends "off" again

When availableThinkingLevels is ["off"] (single element), modulo wraps back to index 0 on every keypress. The handler emits set:thinking { level: "off" } on every Shift+Tab. The gateway accepts it, changes nothing, and echoes back the same state. Infinite no-op.

Steps to Reproduce

  1. Start the CLI TUI against a gateway session using any non-reasoning model (Ollama, custom provider without reasoning: true)
  2. Press Shift+Tab repeatedly
  3. Thinking level stays at "off", no feedback given

Expected Behaviour

Guard against single-element arrays: if availableThinkingLevels contains only "off", display a status message that thinking is unsupported for the current model rather than silently cycling.

Affected File

  • packages/cli/src/tui/app.tsx — Shift+Tab useInput handler
## Summary Pressing Shift+Tab to cycle thinking levels appears to do nothing when the active gateway session uses a model with `reasoning: false`. The cycle is mathematically a no-op. ## Root Cause In `packages/cli/src/tui/app.tsx` (Shift+Tab `useInput` handler): ```ts const levels = socket.availableThinkingLevels; // ["off"] — single element const currentIdx = levels.indexOf(socket.thinkingLevel); // 0 const nextIdx = (currentIdx + 1) % levels.length; // (0+1) % 1 = 0 <- always 0 const next = levels[nextIdx]; // "off" socket.setThinkingLevel(next); // sends "off" again ``` When `availableThinkingLevels` is `["off"]` (single element), modulo wraps back to index 0 on every keypress. The handler emits `set:thinking { level: "off" }` on every Shift+Tab. The gateway accepts it, changes nothing, and echoes back the same state. Infinite no-op. ## Steps to Reproduce 1. Start the CLI TUI against a gateway session using any non-reasoning model (Ollama, custom provider without `reasoning: true`) 2. Press Shift+Tab repeatedly 3. Thinking level stays at "off", no feedback given ## Expected Behaviour Guard against single-element arrays: if `availableThinkingLevels` contains only `"off"`, display a status message that thinking is unsupported for the current model rather than silently cycling. ## Affected File - `packages/cli/src/tui/app.tsx` — Shift+Tab `useInput` handler
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#206