Skip to content

fix: base provider resolution - #5897

Merged
akshaydeo merged 1 commit into
devfrom
08-06-fix_base_provider_resolution
Aug 6, 2026
Merged

fix: base provider resolution#5897
akshaydeo merged 1 commit into
devfrom
08-06-fix_base_provider_resolution

Conversation

@TejasGhatte

@TejasGhatte TejasGhatte commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

OpenAI models served through a custom provider (e.g. an openai-based custom provider with its own key like "my-openai") were silently losing the reasoning item ID when converting to Anthropic thinking blocks. Because ShouldEmbedReasoningItemID matched against the raw provider key, custom providers never matched the OpenAI case and fell through to the default false arm — causing a mismatch OpenAI rejects with "Encrypted content item_id did not match the target item id.".

Changes

  • Added BifrostContextKeyBaseProviderType context key, set during requestWorker to record the built-in provider backing each attempt. Custom providers surface their own key everywhere a ModelProvider is reported, so this gives downstream converters a way to resolve back to the underlying provider type.
  • Added ResolveBaseProvider(ctx, provider) helper in schemas/account.go that reads BifrostContextKeyBaseProviderType from the context and falls back to the raw provider key when the context carries none (direct converter calls, tests).
  • Updated ShouldEmbedReasoningItemID to accept a *BifrostContext and resolve through ResolveBaseProvider before switching on provider family. A custom provider wrapping OpenAI now qualifies unconditionally, matching native OpenAI behaviour — deployment-style model names used on OpenAI-compatible endpoints would never match an OpenAI-family model name check anyway.
  • Propagated the new ctx parameter through all call sites of ShouldEmbedReasoningItemID and convertBifrostReasoningToAnthropicThinking.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

go test ./core/providers/anthropic/... ./core/providers/utils/... ./core/schemas/...

The new test "openai-based custom provider embeds the id" in reasoningstream_test.go directly covers the fixed path: it sets BifrostContextKeyBaseProviderType to schemas.OpenAI on the context while passing a custom provider key, and asserts the reasoning item ID is correctly embedded in the signature.

TestShouldEmbedReasoningItemID_NilContext pins the nil-context fallback to ensure converters called outside a request context neither panic nor regress.

Breaking changes

  • Yes
  • No

Related issues

Security considerations

None. The change only affects how a reasoning item ID is embedded into an opaque signature field passed between Anthropic-compatible clients and OpenAI backends. No auth, secrets, or PII are involved.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved reasoning item ID handling for custom providers backed by OpenAI.
    • Preserved provider- and model-specific reasoning behavior for Azure, Bedrock Mantle, and Vertex.
    • Ensured reasoning conversions correctly identify the underlying provider across request flows.
  • Tests

    • Expanded coverage for custom providers, provider resolution, and missing-context scenarios.

Walkthrough

The request path records each attempt’s base provider in BifrostContext. Reasoning ID eligibility resolves this provider before applying model checks. Anthropic reasoning conversion passes the context and adds coverage for custom providers backed by OpenAI.

Changes

Reasoning ID context flow

Layer / File(s) Summary
Base provider resolution and propagation
core/schemas/bifrost.go, core/schemas/account.go, core/bifrost.go
Adds a context key and resolver for base providers. Each provider attempt stores its resolved base provider in the request context.
Context-aware reasoning ID eligibility
core/providers/utils/utils.go, core/providers/utils/reasoningid_test.go
ShouldEmbedReasoningItemID resolves the base provider before applying provider and model rules. Tests cover custom providers and nil contexts.
Anthropic reasoning conversion integration
core/providers/anthropic/responses.go, core/providers/anthropic/reasoningstream_test.go, core/providers/anthropic/reasoningid_test.go
Anthropic conversion passes BifrostContext to reasoning ID checks. Tests cover existing calls and custom providers backed by OpenAI.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • maximhq/bifrost#5192: Modifies Anthropic reasoning conversion and reasoning ID embedding for OpenAI and custom providers.
  • maximhq/bifrost#5277: Updates Anthropic reasoning conversion and OpenAI reasoning details handling.
  • maximhq/bifrost#5286: Updates Anthropic reasoning conversion and streaming block handling.

Suggested reviewers: akshaydeo, sammaji, pratham-mishra04

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR fixes reasoning item ID handling, but issue #123 requires File API support for uploads and the POST /v1/files endpoint. Implement the File API requirements from issue #123 or link the PR to the issue that covers base provider resolution.
Out of Scope Changes check ⚠️ Warning The changes address Anthropic reasoning item IDs and custom provider resolution, which are unrelated to the linked File API objective in issue #123. Limit this PR to issue #123 requirements or update the linked issue to reflect the reasoning item ID fix.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 91.67% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The description explains the bug, implementation, affected areas, testing, breaking changes, security impact, and checklist status.
Title check ✅ Passed The title clearly identifies the main fix: resolving the base provider for custom providers.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 08-06-fix_base_provider_resolution

Comment @coderabbitai help to get the list of available commands.

@TejasGhatte
TejasGhatte marked this pull request as ready for review August 6, 2026 10:59

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@core/bifrost.go`:
- Around line 6508-6509: Move the base provider assignment from shared
BifrostContext state into attempt-scoped response metadata, alongside the
existing RoutingInfo snapshot, and have chunk conversion—including
ShouldEmbedReasoningItemID—read that snapshot rather than the mutable context
key. Add a streaming fallback test using different base providers to verify
earlier chunks retain their original provider metadata.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fdfe22cc-18a8-4015-ae5d-8c3ac2734843

📥 Commits

Reviewing files that changed from the base of the PR and between 041817a and b4f15b2.

📒 Files selected for processing (8)
  • core/bifrost.go
  • core/providers/anthropic/reasoningid_test.go
  • core/providers/anthropic/reasoningstream_test.go
  • core/providers/anthropic/responses.go
  • core/providers/utils/reasoningid_test.go
  • core/providers/utils/utils.go
  • core/schemas/account.go
  • core/schemas/bifrost.go

Comment thread core/bifrost.go

akshaydeo commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Aug 6, 3:57 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 6, 3:58 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit 4a51039 into dev Aug 6, 2026
14 of 15 checks passed
@akshaydeo
akshaydeo deleted the 08-06-fix_base_provider_resolution branch August 6, 2026 15:58
akshaydeo pushed a commit that referenced this pull request Aug 7, 2026
## Summary

OpenAI models served through a custom provider (e.g. an `openai`-based custom provider with its own key like `"my-openai"`) were silently losing the reasoning item ID when converting to Anthropic thinking blocks. Because `ShouldEmbedReasoningItemID` matched against the raw provider key, custom providers never matched the `OpenAI` case and fell through to the default `false` arm — causing a mismatch OpenAI rejects with `"Encrypted content item_id did not match the target item id."`.

## Changes

- Added `BifrostContextKeyBaseProviderType` context key, set during `requestWorker` to record the built-in provider backing each attempt. Custom providers surface their own key everywhere a `ModelProvider` is reported, so this gives downstream converters a way to resolve back to the underlying provider type.
- Added `ResolveBaseProvider(ctx, provider)` helper in `schemas/account.go` that reads `BifrostContextKeyBaseProviderType` from the context and falls back to the raw provider key when the context carries none (direct converter calls, tests).
- Updated `ShouldEmbedReasoningItemID` to accept a `*BifrostContext` and resolve through `ResolveBaseProvider` before switching on provider family. A custom provider wrapping OpenAI now qualifies unconditionally, matching native OpenAI behaviour — deployment-style model names used on OpenAI-compatible endpoints would never match an OpenAI-family model name check anyway.
- Propagated the new `ctx` parameter through all call sites of `ShouldEmbedReasoningItemID` and `convertBifrostReasoningToAnthropicThinking`.

## Type of change

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/providers/anthropic/... ./core/providers/utils/... ./core/schemas/...
```

The new test `"openai-based custom provider embeds the id"` in `reasoningstream_test.go` directly covers the fixed path: it sets `BifrostContextKeyBaseProviderType` to `schemas.OpenAI` on the context while passing a custom provider key, and asserts the reasoning item ID is correctly embedded in the signature.

`TestShouldEmbedReasoningItemID_NilContext` pins the nil-context fallback to ensure converters called outside a request context neither panic nor regress.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

None. The change only affects how a reasoning item ID is embedded into an opaque signature field passed between Anthropic-compatible clients and OpenAI backends. No auth, secrets, or PII are involved.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request Aug 7, 2026
18 tasks
atharvamhaske pushed a commit to atharvamhaske/bifrost that referenced this pull request Aug 13, 2026
## Summary

OpenAI models served through a custom provider (e.g. an `openai`-based custom provider with its own key like `"my-openai"`) were silently losing the reasoning item ID when converting to Anthropic thinking blocks. Because `ShouldEmbedReasoningItemID` matched against the raw provider key, custom providers never matched the `OpenAI` case and fell through to the default `false` arm — causing a mismatch OpenAI rejects with `"Encrypted content item_id did not match the target item id."`.

## Changes

- Added `BifrostContextKeyBaseProviderType` context key, set during `requestWorker` to record the built-in provider backing each attempt. Custom providers surface their own key everywhere a `ModelProvider` is reported, so this gives downstream converters a way to resolve back to the underlying provider type.
- Added `ResolveBaseProvider(ctx, provider)` helper in `schemas/account.go` that reads `BifrostContextKeyBaseProviderType` from the context and falls back to the raw provider key when the context carries none (direct converter calls, tests).
- Updated `ShouldEmbedReasoningItemID` to accept a `*BifrostContext` and resolve through `ResolveBaseProvider` before switching on provider family. A custom provider wrapping OpenAI now qualifies unconditionally, matching native OpenAI behaviour — deployment-style model names used on OpenAI-compatible endpoints would never match an OpenAI-family model name check anyway.
- Propagated the new `ctx` parameter through all call sites of `ShouldEmbedReasoningItemID` and `convertBifrostReasoningToAnthropicThinking`.

## Type of change

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/providers/anthropic/... ./core/providers/utils/... ./core/schemas/...
```

The new test `"openai-based custom provider embeds the id"` in `reasoningstream_test.go` directly covers the fixed path: it sets `BifrostContextKeyBaseProviderType` to `schemas.OpenAI` on the context while passing a custom provider key, and asserts the reasoning item ID is correctly embedded in the signature.

`TestShouldEmbedReasoningItemID_NilContext` pins the nil-context fallback to ensure converters called outside a request context neither panic nor regress.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

None. The change only affects how a reasoning item ID is embedded into an opaque signature field passed between Anthropic-compatible clients and OpenAI backends. No auth, secrets, or PII are involved.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
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.

3 participants