Repository navigation
Description
Summary
Session auto-titling stores the literal opening think tag (<think>) as the session title whenever the configured small_model streams reasoning into the text channel (ollama @ai-sdk/openai-compatible + a thinking-capable small model). Every new session gets titled <think> — 19 consecutive sessions observed across 2.0.20 and 2.0.24, zero exceptions.
Environment
- opencode version: 2.0.24 (first observed on 2.0.20; v1.18.30 titled the same setup correctly)
- OS: Darwin 27.0.0 arm64 (macOS)
- Terminal: iTerm.app (TERM=xterm-256color, COLORTERM=truecolor)
- Shell: /bin/zsh
- Install/channel: latest, Homebrew tap
anomalyco/tap/opencode-v2 - Active plugins: none configured
Reproduction
~/.config/opencode/opencode.json:{ "model": "openrouter/z-ai/glm-5.3-flash", "small_model": "ollama/lfm2.5:latest", "provider": { "ollama": { "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "http://localhost:11434/v1" }, "models": { "lfm2.5:latest": { "name": "LFM2.5 8B MoE" } } } } }- Ollama running locally with
lfm2.5:latest(LiquidAI LFM2.5, thinking-capable). - Start any session and send a first message.
Expected Behavior
The session title is a short summary of the first user message (per the built-in title agent prompt).
Actual Behavior
The session title is the 7-character string <think> — the opening tag of the model's reasoning block. 100% of new sessions affected (19/19 observed over Oct 3–6).
Root cause (from packages/opencode/src/session/prompt.ts, SessionPrompt.ensureTitle):
- The title text is assembled from
textDeltaevents only, then cleaned withtext.replace(/<think>[\s\S]*?<\/think>\s*/g, "") .split("\n").map(trim).find(line => line.length > 0)
- Through the ollama OpenAI-compatible endpoint, LFM2.5 emits its reasoning inline in
content, beginning with<think>. In the opencode flow the closing</think>never lands in the text-delta stream, so the closed-pair regex can't strip anything and the first non-empty line — the dangling<think>— becomes the title. provider.getSmallModel()correctly resolvessmall_modelfrom config (confirmed inprovider.ts), so the right model is called; only the parsing leaks the tag.
Notes:
- v1.18.30 produced clean titles with the identical model/config, so this is a v2 title-pipeline regression.
- Verified fix on the user side: override the built-in title agent's model in config —
"agent": { "title": { "model": "ollama/granite4.1:3b" } }(a non-thinking small model) — which yields clean titles. The built-in agent merge inagent.ts(if (value.model) item.model = Provider.parseModel(value.model)) honors this.
Additional Context
Same parser family but distinct manifestation from #42287 (reasoning-only output -> empty title, silently unset) and #51997 (commentary phases leak): here the closed-pair strip fails entirely because the closing tag never reaches the text-delta stream, so a dangling opener is stored as the title.
Possible fixes: strip a dangling opening <think> when no closing tag is present (e.g. treat text after an unclosed tag opener as the payload, or also accept split("</think>").pop()); or filter reasoning deltas out of the text stream before assembly; or validate the cleaned title against tag-like content and fall back to a truncation of the first user message.
Happy to provide the affected session records or a trace if useful.
Activity
[-]session: auto-title saved as raw ڴ tag with reasoning small models via ollama (openai-compatible)[/-][+]session: auto-title saved as raw <think> tag with reasoning small models via ollama (openai-compatible)[/+]github-actions commentedon Oct 6, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
Please edit this issue to address the above within 72 hours, or it will be automatically closed.
This issue might be a duplicate of an existing issue. Please check:
<think>block) #42287: Both report reasoning-model<think>output affecting automatic session titles; Session title silently empty when the title model is a reasoning model (returns only a<think>block) #42287 leaves the title empty, while this issue saves the raw opening tag.If you believe this was flagged incorrectly, please let a maintainer know.
rgwood-github2018dec31 commentedon Oct 6, 2026
Looks like a dupe. I did ask the LLM to look for dupes but it missed the above. Thanks for the great software!