Repository navigation
fix: merge chat and completion provider routing instead of replacing it - #605
Closed
LukasParke wants to merge 3 commits into
Closed
LukasParke wants to merge 3 commits into
LukasParke wants to merge 3 commits into
Conversation
A runtime providerOptions.openrouter.provider object replaced the configured provider routing wholesale. Chat and completion now shallow merge it like the image model (#551), through a shared mergeProviderRouting helper that the image model also uses. Fixes #587 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lict with #603 The image model already shallow merges provider routing (#551); moving it onto mergeProviderRouting was a pure refactor, and its new import landed on the same line as #603's user-agent import. Keep image/index.ts as on main so the two PRs merge in either order. No behaviour change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
LukasParke
added a commit
that referenced
this pull request
Oct 23, 2026
Behaviour is unchanged; only where the stripping happens moves, so this PR merges cleanly with #605 and #608 in either order: - chat: drop reasoningReplay where openrouterOptions is read, leaving the cacheControl destructure as on main (#605 extends that destructure). - completion: drop it from the assembled args in a separate statement, leaving the openrouterOptions line as on main (#605 rewrites it). - convert: put a blank line between the candidate selection and the replay filter so the hunk does not touch the findFirstReasoningDetails call (#608 renames it). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
5 tasks done
Contributor
Author
LukasParke
added a commit
that referenced
this pull request
Nov 10, 2026
Behaviour is unchanged; only where the stripping happens moves, so this PR merges cleanly with #605 and #608 in either order: - chat: drop reasoningReplay where openrouterOptions is read, leaving the cacheControl destructure as on main (#605 extends that destructure). - completion: drop it from the assembled args in a separate statement, leaving the openrouterOptions line as on main (#605 rewrites it). - convert: put a blank line between the candidate selection and the replay filter so the hunk does not touch the findFirstReasoningDetails call (#608 renames it). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #587
Bug. In the chat model,
providerOptions.openrouter.providerreplaced the configured provider routing instead of merging into it.doGenerate/doStreambuilt the body as{ ...this.getArgs(options), ...restOpenrouterOptions }. HeregetArgs()setsprovider: this.settings.provider(and then spreads bothextraBodys), so a runtimeproviderobject overrode all of it. The completion model had the same pattern forextraBody.provider. Completion has no typedprovidersetting.Repro.
Fix. Same semantics as the image model (#551): a shallow merge with precedence
settings.provider<config.extraBody.provider<settings.extraBody.provider<providerOptions.openrouter.provider. Non-object values (null, arrays, primitives) are ignored.src/utils/merge-provider-routing.ts(mergeProviderRouting). The image model keeps its own inline merge (same semantics), see Merge coordination below.doGenerateanddoStream.doGenerateanddoStream, using the twoextraBodysources plus runtime.Behavior change (noted in the changeset): a runtime
providerobject no longer drops configured keys it doesn't set. To override a key, set it explicitly in the runtime object.Not changed. Embedding, reranking and evaluation spread
providerOptions.openrouterdifferently, and the issue doesn't cover them. I left them alone to keep this PR scoped. I can follow up if we want the same semantics there.Tests.
src/chat/index.test.ts: the issue's example indoGenerateanddoStream, full precedence across all four sources, and anullruntime provider being ignored.src/completion/index.test.ts: provider and modelextraBodymerged with runtime, indoGenerateanddoStream.src/utils/merge-provider-routing.test.ts: unit tests for the helper.e2e/issues/issue-587-provider-routing-merge.test.ts: issue regression test (pnpm test:issues, mocked fetch). It runs the issue's example throughgenerateText.I checked that the 6 new chat/completion tests and the issue test fail on
origin/mainand pass with this fix.Checklist
pnpm stylecheckandpnpm typecheckpnpm testand all tests passChangeset
pnpm changesetto create a changeset fileMerge coordination
Merges cleanly with #603 and #597 in either order, so no hand resolution is needed. The image model is no longer refactored onto
mergeProviderRouting. Its new import landed on the same line as #603's user-agent import, and the refactor didn't change behaviour, sosrc/image/index.tsstays as on main. I checked this with local integration merges of #590–#609 in both orders.🤖 Generated with Claude Code