Skip to content

session: synthesize reasoning-start when stream omits it#25185

Closed
jackmazac wants to merge 1 commit intoanomalyco:devfrom
jackmazac:pr/upstream-2-reasoning-stream
Closed

session: synthesize reasoning-start when stream omits it#25185
jackmazac wants to merge 1 commit intoanomalyco:devfrom
jackmazac:pr/upstream-2-reasoning-stream

Conversation

@jackmazac
Copy link
Copy Markdown

Summary

Some model streams send reasoning updates without ever sending a matching “reasoning started” marker first. Downstream code then sees deltas or ends for an id it never opened, which can break ordering or UI assumptions. This adds a small stream normalizer so every reasoning id gets an explicit start before any delta or end.

Problem (plain language)

Think of reasoning like a paragraph: you expect “paragraph begins,” then sentences, then “paragraph ends.” If the provider skips the “begins” line and only sends middle sentences, anything that tracks open blocks by id gets confused. Users may see glitches or missing reasoning; worse, the stack may mishandle chunks.

Technical breakdown

  1. The AI SDK exposes a wrapStream hook on language-model middleware.
  2. Some providers emit reasoning-delta / reasoning-end for an id before a reasoning-start with that id.
  3. We already normalize prompts in transformParams; this change normalizes the stream so each id is self-consistent.

Solution

  • In packages/opencode/src/session/llm.ts, extend the existing stream middleware with wrapStream.
  • Track ids that have received reasoning-start.
  • On reasoning-delta or reasoning-end without a prior start for that id, enqueue a synthetic reasoning-start first, then the original chunk.

Files

  • packages/opencode/src/session/llm.ts

How to test

From packages/opencode:

bun typecheck

Merge order

This PR does not depend on PR: session stripReasoning / compaction. It can land before or after that change. If both merge, behavior stacks: compaction strips reasoning from history, while this hook fixes live stream ordering for reasoning chunks.

wrapStream middleware enqueues reasoning-start before delta/end
when the provider skipped the opening chunk for that id.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

Hey! Your PR title session: synthesize reasoning-start when stream omits it doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label May 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

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

@jackmazac
Copy link
Copy Markdown
Author

Closing to reopen with a linked issue and the repo PR template per CONTRIBUTING.

@jackmazac jackmazac closed this May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs:compliance This means the issue will auto-close after 2 hours. needs:title

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant