Skip to content

session: auto-title saved as raw <think> tag with reasoning small models via ollama (openai-compatible) #53493

Closed

Description

@rgwood-github2018dec31

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

  1. ~/.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" } }
        }
      }
    }
  2. Ollama running locally with lfm2.5:latest (LiquidAI LFM2.5, thinking-capable).
  3. 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 textDelta events only, then cleaned with
    text.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 resolves small_model from config (confirmed in provider.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 in agent.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

  1. changed the title [-]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)[/+] on Oct 6, 2026
  2. github-actions commented on Oct 6, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • The Bug Report template requires a Description field, but this issue uses Summary and does not include that required field. Please use one of the provided issue templates and ensure its Description field contains this report's content.

    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:

    If you believe this was flagged incorrectly, please let a maintainer know.

  3. rgwood-github2018dec31 commented on Oct 6, 2026

    @rgwood-github2018dec31
    Author

    Looks like a dupe. I did ask the LLM to look for dupes but it missed the above. Thanks for the great software!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs:complianceThis means the issue will auto-close after 2 hours.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions