Skip to content

fix: stop Thinking chip from trapping answers in reasoning middleware - #1153

Open
Sdaswani wants to merge 2 commits into
thunderbird:mainfrom
Sdaswani:fix/thinking-middleware-content-trap
Open

fix: stop Thinking chip from trapping answers in reasoning middleware#1153
Sdaswani wants to merge 2 commits into
thunderbird:mainfrom
Sdaswani:fix/thinking-middleware-content-trap

Conversation

@Sdaswani

@Sdaswani Sdaswani commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Decouple the Thinking chip / model.startWithReasoning flag from extractReasoningMiddleware({ startWithReasoning }). The DB flag means "model can think"; the middleware option means "treat all content as reasoning until </think>".
  • Ollama thinking models emit a native reasoning field and plain answer content with no closing tag. Wiring the chip flag into the middleware classified the answer as reasoning forever, never emitted reasoning-end, and left the chat spinner stuck with the reply in the muted Thinking pane.
  • Show a Thinking label while streaming with no active tool (empty title + spinner looked hung).

Context

This bug already existed on main whenever startWithReasoning === 1. It became easy to hit after Ollama capability discovery auto-enables that flag for thinking models (see #1152). This PR is the standalone fix against main; #1152 also includes the same commit.

Impact on other models

This should not regress the common paths:

Path Effect
Shipped defaults / startWithReasoning === 0 Unchanged — middleware was already false
Native reasoning / reasoning_content (Ollama, etc.) Fixed — answer stays in content
Literal <think>...</think> tags in content Unchanged — tag extraction still runs with startWithReasoning: false
Thinking chip / reasoningEffort: 'none' when chip off Unchanged

Narrow edge case: a model that streams leading reasoning as plain content with no opening <think>, only a later </think>, previously relied on middleware startWithReasoning: true. Thunderbolt defaults do not ship that pattern; if a custom model depends on it, thinking extraction for that model could degrade.

Test plan

  • With a local Ollama qwen3:1.7b (or any thinking-capable) model, Thinking chip on: send hi — answer appears as normal message text and the spinner settles
  • Same model, Thinking chip off: still responds normally (no regression)
  • A non-thinking / default model still streams answers normally (no change)
  • Confirm streaming thinking-only turns show a Thinking status label next to the spinner
  • Models that emit literal <think>...</think> in content still extract reasoning correctly

- model.startWithReasoning means show/enable thinking; middleware
  startWithReasoning means treat content as reasoning until </think>
- Ollama thinking models emit a native reasoning field and plain answer
  content with no closing tag, so wiring the chip flag through left the
  spinner stuck with the reply in the muted Thinking pane
- show a Thinking label while streaming with no active tool

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Preview environment deployed 🚀

Service URL
Marketing / blog / docs https://thunderbolt-pr-1153.preview.thunderbolt.io
App https://app-pr-1153.preview.thunderbolt.io
API https://api-pr-1153.preview.thunderbolt.io
Keycloak https://auth-pr-1153.preview.thunderbolt.io
PowerSync https://powersync-pr-1153.preview.thunderbolt.io

Stack: preview-pr-1153 · Commit: 2de327307fe0270d1f51265ee0f5dd4de443b48f

Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — demo@thunderbolt.io / demo by default.

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