fix(runtime,web): route inline think tags into reasoning lane #109

Merged
salmaelsoly merged 2 commits from integration_hide_inline_think_tags into integration 2026-06-11 12:53:21 +00:00
Member

Summary

Models that inline their reasoning as literal <think>...</think> tags in the assistant content were having those tags rendered as plain text in the chat. This change routes that content into the existing reasoning lane so it appears in the collapsible ThinkingPane, both live during streaming and after reload.

Closes #104

Changes

  • New think_tags module in hero_shrimp_runtime: incremental ThinkTagFilter for streaming (handles markers split across SSE chunks, held-back partial markers, unclosed trailing <think>) and split_think_tags for whole responses; 13 unit tests
  • Streaming path in llm/completion/mod.rs routes every content delta through the filter, emitting llm:delta with kind: "content" or kind: "reasoning"; non-streaming OpenAI-compatible path splits content and pushes extracted segments as ReasoningBlock entries; Anthropic branch and trajectory export untouched
  • Web UI fallback in store.ts (extractThinkBlocks applied in stream flush, turn:end, and history load) so messages already persisted with raw tags render clean
  • ChatThread.tsx: settled assistant messages with reasoning render a collapsed ThinkingPane
  • Regenerated embedded Vite bundle

Test Results

  • cargo test --workspace: 2740 passed, 0 failed, 18 ignored
  • cargo clippy --workspace -- -D warnings: clean
## Summary Models that inline their reasoning as literal `<think>...</think>` tags in the assistant content were having those tags rendered as plain text in the chat. This change routes that content into the existing reasoning lane so it appears in the collapsible ThinkingPane, both live during streaming and after reload. ## Related Issue Closes https://forge.ourworld.tf/lhumina_code/hero_shrimp/issues/104 ## Changes - New `think_tags` module in `hero_shrimp_runtime`: incremental `ThinkTagFilter` for streaming (handles markers split across SSE chunks, held-back partial markers, unclosed trailing `<think>`) and `split_think_tags` for whole responses; 13 unit tests - Streaming path in `llm/completion/mod.rs` routes every content delta through the filter, emitting `llm:delta` with `kind: "content"` or `kind: "reasoning"`; non-streaming OpenAI-compatible path splits content and pushes extracted segments as `ReasoningBlock` entries; Anthropic branch and trajectory export untouched - Web UI fallback in `store.ts` (`extractThinkBlocks` applied in stream flush, `turn:end`, and history load) so messages already persisted with raw tags render clean - `ChatThread.tsx`: settled assistant messages with reasoning render a collapsed ThinkingPane - Regenerated embedded Vite bundle ## Test Results - cargo test --workspace: 2740 passed, 0 failed, 18 ignored - cargo clippy --workspace -- -D warnings: clean
fix(runtime,web): route inline think tags into reasoning lane
Some checks failed
Verify / verify (push) Failing after 18s
Verify / verify (pull_request) Failing after 30s
e467e6d3c8
#104
style: cargo fmt
All checks were successful
Verify / verify (push) Successful in 11m43s
Verify / verify (pull_request) Successful in 34m2s
4eba87403e
salmaelsoly merged commit 06242d266d into integration 2026-06-11 12:53:21 +00:00
salmaelsoly deleted branch integration_hide_inline_think_tags 2026-06-11 12:53:34 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_shrimp!109
No description provided.