Skip to content

fix(core): accept interleaved Copilot reasoning_opaque values - #54207

Merged
rekram1-node merged 1 commit into
devfrom
copilot-opaque-dev
Oct 9, 2026
Merged

rekram1-node merged 1 commit into
devfrom
copilot-opaque-dev

Conversation

@rekram1-node

Copy link
Copy Markdown
Collaborator

Closes #51466

Port of #54201 (merged on v2).

Claude models with thinking enabled (e.g. Opus 5.5) on Copilot's /chat/completions emit a new reasoning_opaque before each tool call, so one response can carry several. The stream parser threw Multiple reasoning_opaque values received in a single response on the second one, aborting any multi-tool-call turn. Claude lands on this route when the Copilot /models request fails and the static catalogue is used.

Changes:

  • Stream parser keeps the latest reasoning_opaque instead of throwing. Each reasoning segment's reasoning-end and its tool call carry the value that arrived with them; finish metadata carries the latest.
  • Message conversion replays the latest reasoning_opaque with the concatenated reasoning text. Previously it paired the first opaque with only the last reasoning part's text.

This matches the Copilot VS Code client, which accumulates thinking text across deltas, overwrites the id with each new opaque, and replays the final pair.

Verification:

  • New stream and replay tests fail without the fix; bun test test/github-copilot/ and bun typecheck in packages/core pass.
  • Live multi-step agent loops on Copilot /chat/completions (Sonnet 5, Sonnet 5.5, Haiku 5.5; effort high/max) through the patched parser and replay: ~75 steps, no errors, all replayed opaques accepted. Those models only emitted one thinking segment per response, and Opus 5.5 was unavailable on the test account, so the interleaved case itself is covered by fixtures rather than live traffic.

Also covers the joined-reasoning-text replay that #53191 leaves out.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking problems found. On the base branch, the new interleaved-opaque stream fixture reproduces the Multiple reasoning_opaque values received in a single response error from #51466, and the replay test fails because base pairs the first opaque value with only the last reasoning text. With this PR both pass, along with the rest of test/github-copilot/ (37/37) and typecheck in packages/core. Each reasoning segment's reasoning-end and its tool call keep the opaque value that came with them, and the replayed text and opaque value stay scoped to one assistant message. Not checked against live Opus 5.5 traffic.

Public API unchanged: this only changes the internal Copilot chat stream parser and message conversion.

@rekram1-node
rekram1-node merged commit b2a3926 into dev Oct 9, 2026
10 checks passed
@rekram1-node
rekram1-node deleted the copilot-opaque-dev branch October 9, 2026 22:03
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.

multiple reasoning_opaque values received in a single response. Only one thinking part per response is suported

1 participant