Skip to content

Add TEI rerank provider - #4469

Open
joicemjoseph wants to merge 18 commits into
maximhq:devfrom
joicemjoseph:feature/tei-rerank-provider
Open

Add TEI rerank provider#4469
joicemjoseph wants to merge 18 commits into
maximhq:devfrom
joicemjoseph:feature/tei-rerank-provider

Conversation

@joicemjoseph

Copy link
Copy Markdown

Summary

  • add a native Hugging Face TEI provider for rerank requests
  • send TEI-native /rerank payloads with query and texts instead of OpenAI/vLLM/Cohere-shaped bodies
  • register TEI in provider schemas and UI config as a keyless rerank-capable provider

Tests

  • go test ./providers/tei
  • go test ./... -run '^$'\n- git diff --check\n\nNote: full go test ./... in this clone has unrelated existing failures in MCP stdio fixture tests and a Bedrock rerank assertion.

@CLAassistant

CLAassistant commented Jun 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 98734ea3-2663-470b-ac3f-51bb485dc9bf

📥 Commits

Reviewing files that changed from the base of the PR and between 822b1c4 and 928325c.

📒 Files selected for processing (3)
  • core/bifrost.go
  • core/schemas/bifrost.go
  • core/utils.go
✅ Files skipped from review due to trivial changes (1)
  • core/utils.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/bifrost.go
  • core/schemas/bifrost.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added Hugging Face Text Embeddings Inference (TEI) as a selectable provider across config, standard/provider lists, and UI (icon/label).
    • Enabled TEI embedding and rerank, including /rerank support, configurable request payload building, and optional extra-parameter passthrough.
  • Bug Fixes
    • Allowed TEI API keys to be empty when the provider supports it.
  • Tests
    • Added TEI test coverage for request/response conversions, upstream HTTP behavior, allowed-request gating, path overrides, and raw payload options.

Walkthrough

Adds TEI as a new Bifrost provider with rerank and embedding support, plus backend wiring, config/schema updates, tests, and UI registration.

Changes

TEI Provider Integration

Layer / File(s) Summary
TEI provider schema and config registration
core/schemas/bifrost.go, core/utils.go, transports/config.schema.json
Registers TEI as a provider, adds it to provider lists, allows empty TEI keys, and extends config schema support for TEI provider entries and base provider type values.
TEI rerank models and conversion helpers
core/providers/tei/models.go, core/providers/tei/utils.go
Defines TEI rerank wire models, converts Bifrost rerank requests to TEI format, converts TEI ranks back to Bifrost responses with validation and sorting, and wraps provider errors with request and response bodies.
TEIProvider implementation and request handling
core/providers/tei/tei.go, core/bifrost.go
Implements TEI HTTP client setup, rerank execution, embedding delegation, request URL resolution, rerank body building, TEI error parsing, unsupported-operation stubs, and provider factory wiring.
TEI utility and provider tests
core/providers/tei/utils_test.go
Covers request/response conversion, rerank and embedding HTTP behavior, request URL overrides, and allowed-request gating.
UI provider registration
ui/lib/types/config.ts, ui/lib/constants/logs.ts, ui/lib/constants/config.ts, ui/lib/constants/icons.tsx, ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
Adds TEI to UI provider types, labels, icons, supported requests, allowed-request endpoints, and request selection options.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Bifrost
  participant TEIProvider
  participant TEI

  Client->>Bifrost: select base provider "tei"
  Bifrost->>TEIProvider: createBaseProvider(config)
  Client->>TEIProvider: Rerank request
  TEIProvider->>TEI: POST /rerank
  TEI-->>TEIProvider: rerank results
  TEIProvider-->>Client: Bifrost rerank response
Loading

Possibly related PRs

  • maximhq/bifrost#4425: The embedding path here uses the shared OpenAI-compatible embedding handler, matching the provider auth/header changes in that PR.
  • maximhq/bifrost#4601: Extends the same provider-construction path with a new base-provider branch and matching wiring.

Suggested reviewers: akshaydeo, danpiths, roroghost17

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning It has Summary and Tests, but omits most required template sections like Changes, Type, Affected areas, breaking changes, issues, security, and checklist. Add the missing template sections and briefly fill in type of change, affected areas, testing steps, breaking changes, related issues, security notes, and checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a TEI rerank provider.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 2

🤖 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/providers/tei/rerank.go`:
- Around line 26-31: In the rerank parameters conversion logic where
bifrostReq.Params is processed, the code currently only forwards ExtraParams and
ReturnDocuments to teiReq but silently ignores TopN, MaxTokensPerDoc, and
Priority from schemas.RerankParameters. Add assignments to also forward these
missing parameters (TopN, MaxTokensPerDoc, and Priority) from bifrostReq.Params
to the corresponding fields in teiReq within the same conditional block,
ensuring all rerank parameters are properly transferred to the TEI request.

In `@transports/config.schema.json`:
- Around line 352-354: The tei provider configuration is using the generic
`#/`$defs/provider schema which requires a keys field with minItems: 1, but TEI
should support keyless configuration. Create a TEI-specific provider schema
definition in the $defs section that removes or relaxes the keys requirement,
then update the tei provider reference to point to this new TEI-specific schema
instead of the generic `#/`$defs/provider reference.
🪄 Autofix (Beta)

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: 060956f7-2517-43c7-8a2b-8d0787eff066

📥 Commits

Reviewing files that changed from the base of the PR and between fa9d8f0 and 7c9bd63.

📒 Files selected for processing (16)
  • core/bifrost.go
  • core/providers/tei/cachedcontents.go
  • core/providers/tei/containers.go
  • core/providers/tei/models.go
  • core/providers/tei/rerank.go
  • core/providers/tei/rerank_test.go
  • core/providers/tei/tei.go
  • core/providers/tei/unsupported.go
  • core/schemas/bifrost.go
  • core/utils.go
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
  • ui/lib/constants/config.ts
  • ui/lib/constants/icons.tsx
  • ui/lib/constants/logs.ts
  • ui/lib/types/config.ts

Comment thread core/providers/tei/rerank.go
Comment thread transports/config.schema.json
@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge; the new TEI provider correctly converts Bifrost rerank requests to TEI format on both the normal and large-payload code paths, handles keyless auth, and honors path overrides.

All issues raised in prior review threads have been resolved in the current revision: first-class rerank parameters are forwarded in ToTEIRerankRequest, buildRequestURL delegates to GetRequestPath for custom path overrides, the large-payload branch explicitly calls ToTEIRerankRequest instead of streaming the raw Bifrost body, and provider_with_tei_config drops the required keys constraint. The only remaining gap is that ProviderResponseHeaders is not populated on the Rerank success path, which is a minor omission relative to the rest of the codebase.

core/providers/tei/tei.go — the Rerank success path does not extract and store provider response headers, unlike every other provider that owns its HTTP call.

Important Files Changed

Filename Overview
core/providers/tei/tei.go New TEI provider with Rerank and Embedding operations; correctly handles path overrides, large-payload mode conversion, fasthttp acquire/release pattern, and keyless auth. Missing ProviderResponseHeaders in the Rerank success response.
core/providers/tei/utils.go ToTEIRerankRequest and ToBifrostRerankResponse converters are pure, handle nil, duplicate-index, out-of-range, sorting, and topN truncation correctly.
core/providers/tei/utils_test.go Covers converter functions, HTTP round-trips (including large-payload drain and path overrides), and disabled-operation guard; correctly avoids require.* inside handler goroutines.
core/providers/tei/models.go Clean model definitions; ExtraParams uses json:"-" and GetExtraParams() pattern to support passthrough merging.
transports/config.schema.json Adds provider_with_tei_config without a required keys field, making keyless TEI deployments schema-valid; TEI added to the provider enum.
core/schemas/bifrost.go TEI added to ModelProvider constants, SupportedBaseProviders, and StandardProviders consistently.
core/utils.go TEI added to CanProviderKeyValueBeEmpty, consistent with other keyless providers (VLLM, Ollama, SGL).
ui/lib/types/config.ts tei added to BaseProvider union type, consistent with Go SupportedBaseProviders.
ui/app/workspace/providers/fragments/allowedRequestsFields.tsx TEI rerank/embedding path placeholders added; rerank added to the global RequestTypes list.
ui/lib/constants/config.ts TEI model placeholder, isKeyRequiredByProvider: false, and PROVIDER_SUPPORTED_REQUESTS entry added correctly.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant Bifrost
    participant TEIProvider
    participant TEI as TEI Server

    Client->>Bifrost: POST /rerank (BifrostRerankRequest)
    Bifrost->>TEIProvider: Rerank(ctx, key, request)
    
    alt normal payload
        TEIProvider->>TEIProvider: CheckContextAndGetRequestBody → ToTEIRerankRequest
        Note over TEIProvider: {query, texts, top_n, return_text}
    else large payload mode
        TEIProvider->>TEIProvider: ToTEIRerankRequest(request struct)
        Note over TEIProvider: converts from parsed struct, not raw reader
    end

    TEIProvider->>TEI: "POST /rerank {query, texts}"
    TEI-->>TEIProvider: "[{index, score, text?}]"
    
    TEIProvider->>TEIProvider: ToBifrostRerankResponse (sort by score, apply topN)
    
    alt large payload
        TEIProvider->>TEIProvider: DrainLargePayloadRemainder
    end

    TEIProvider-->>Bifrost: BifrostRerankResponse
    Bifrost-->>Client: response
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant Bifrost
    participant TEIProvider
    participant TEI as TEI Server

    Client->>Bifrost: POST /rerank (BifrostRerankRequest)
    Bifrost->>TEIProvider: Rerank(ctx, key, request)
    
    alt normal payload
        TEIProvider->>TEIProvider: CheckContextAndGetRequestBody → ToTEIRerankRequest
        Note over TEIProvider: {query, texts, top_n, return_text}
    else large payload mode
        TEIProvider->>TEIProvider: ToTEIRerankRequest(request struct)
        Note over TEIProvider: converts from parsed struct, not raw reader
    end

    TEIProvider->>TEI: "POST /rerank {query, texts}"
    TEI-->>TEIProvider: "[{index, score, text?}]"
    
    TEIProvider->>TEIProvider: ToBifrostRerankResponse (sort by score, apply topN)
    
    alt large payload
        TEIProvider->>TEIProvider: DrainLargePayloadRemainder
    end

    TEIProvider-->>Bifrost: BifrostRerankResponse
    Bifrost-->>Client: response
Loading

Reviews (12): Last reviewed commit: "Merge branch 'dev' into feature/tei-rera..." | Re-trigger Greptile

Comment thread core/providers/tei/rerank.go
Comment thread core/providers/tei/tei.go Outdated
Comment thread core/providers/tei/tei.go Outdated
Comment thread transports/config.schema.json
@rlex

rlex commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Since TEI can do both embed and rerank it will be nice to see embedding too

@joicemjoseph
joicemjoseph force-pushed the feature/tei-rerank-provider branch from 7c9bd63 to e55dd92 Compare June 17, 2026 03:18

@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/providers/tei/tei.go`:
- Around line 86-88: The conditional logic in the block with
ApplyLargePayloadRequestBodyWithModelNormalization is causing the TEI converter
output to be bypassed in large-payload mode. Remove the conditional check and
call req.SetBody(jsonData) unconditionally to ensure the properly converted TEI
payload with the correct texts field structure is always set on the request,
regardless of whether large-payload mode is enabled.
🪄 Autofix (Beta)

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: 6a4abf2b-2340-4479-a9f5-91f4b596f03b

📥 Commits

Reviewing files that changed from the base of the PR and between 7c9bd63 and e55dd92.

📒 Files selected for processing (16)
  • core/bifrost.go
  • core/providers/tei/cachedcontents.go
  • core/providers/tei/containers.go
  • core/providers/tei/models.go
  • core/providers/tei/rerank.go
  • core/providers/tei/rerank_test.go
  • core/providers/tei/tei.go
  • core/providers/tei/unsupported.go
  • core/schemas/bifrost.go
  • core/utils.go
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
  • ui/lib/constants/config.ts
  • ui/lib/constants/icons.tsx
  • ui/lib/constants/logs.ts
  • ui/lib/types/config.ts
🚧 Files skipped from review as they are similar to previous changes (13)
  • core/providers/tei/models.go
  • ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
  • ui/lib/types/config.ts
  • core/bifrost.go
  • ui/lib/constants/config.ts
  • ui/lib/constants/logs.ts
  • transports/config.schema.json
  • ui/lib/constants/icons.tsx
  • core/providers/tei/rerank.go
  • core/providers/tei/containers.go
  • core/providers/tei/rerank_test.go
  • core/providers/tei/cachedcontents.go
  • core/providers/tei/unsupported.go

Comment thread core/providers/tei/tei.go Outdated
Comment thread core/providers/tei/rerank_test.go Outdated
@joicemjoseph
joicemjoseph force-pushed the feature/tei-rerank-provider branch 2 times, most recently from e55dd92 to be87572 Compare June 17, 2026 05:18
@joicemjoseph

Copy link
Copy Markdown
Author

Since TEI can do both embed and rerank it will be nice to see embedding too

Thank you for the review. as per your suggestion, i have both embed along with rerank.

@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

🧹 Nitpick comments (1)
core/providers/tei/rerank_test.go (1)

177-215: ⚡ Quick win

Add a negative embedding test for disabled operation config.

Please add one case where TEI embedding is disabled via provider config and assert the call returns an unsupported/blocked error. This will lock in the operation-gating contract and prevent regressions.

As per coding guidelines: "Apply standard Go review practices: ... deterministic tests, and table-driven coverage for behavior changes."

🤖 Prompt for 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.

In `@core/providers/tei/rerank_test.go` around lines 177 - 215, The
TestTEIProviderEmbedding function only covers the happy path for embedding. Add
a negative test case where the provider configuration disables the embedding
operation, then call provider.Embedding and assert that it returns an
appropriate unsupported or blocked error. This can be implemented by adding a
second test case with modified schemas.ProviderConfig that disables the
embedding operation, or by refactoring into a table-driven test structure to
cover both the enabled and disabled scenarios with NewTEIProvider and the
provider.Embedding method call.

Source: Coding guidelines

🤖 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/providers/tei/embedding.go`:
- Around line 10-23: The Embedding method in the TEIProvider type currently
dispatches directly to openai.HandleOpenAIEmbeddingRequest without first
validating that embedding operations are allowed in the provider configuration.
Add a check using providerUtils.CheckOperationAllowed before the existing
openai.HandleOpenAIEmbeddingRequest call to enforce the AllowedRequests
configuration, following the same pattern used in the OpenAI provider
implementation. This ensures that embedding requests are gated by the provider's
configured operation permissions before being processed.

---

Nitpick comments:
In `@core/providers/tei/rerank_test.go`:
- Around line 177-215: The TestTEIProviderEmbedding function only covers the
happy path for embedding. Add a negative test case where the provider
configuration disables the embedding operation, then call provider.Embedding and
assert that it returns an appropriate unsupported or blocked error. This can be
implemented by adding a second test case with modified schemas.ProviderConfig
that disables the embedding operation, or by refactoring into a table-driven
test structure to cover both the enabled and disabled scenarios with
NewTEIProvider and the provider.Embedding method call.
🪄 Autofix (Beta)

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: 75870620-c3da-4829-aab0-779a45a6b21d

📥 Commits

Reviewing files that changed from the base of the PR and between e55dd92 and be87572.

📒 Files selected for processing (17)
  • core/bifrost.go
  • core/providers/tei/cachedcontents.go
  • core/providers/tei/containers.go
  • core/providers/tei/embedding.go
  • core/providers/tei/models.go
  • core/providers/tei/rerank.go
  • core/providers/tei/rerank_test.go
  • core/providers/tei/tei.go
  • core/providers/tei/unsupported.go
  • core/schemas/bifrost.go
  • core/utils.go
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
  • ui/lib/constants/config.ts
  • ui/lib/constants/icons.tsx
  • ui/lib/constants/logs.ts
  • ui/lib/types/config.ts
💤 Files with no reviewable changes (6)
  • ui/app/workspace/providers/fragments/allowedRequestsFields.tsx
  • ui/lib/types/config.ts
  • ui/lib/constants/icons.tsx
  • ui/lib/constants/config.ts
  • transports/config.schema.json
  • ui/lib/constants/logs.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • core/utils.go
  • core/bifrost.go
  • core/providers/tei/cachedcontents.go
  • core/providers/tei/models.go
  • core/providers/tei/rerank.go
  • core/providers/tei/containers.go
  • core/schemas/bifrost.go
  • core/providers/tei/tei.go

Comment thread core/providers/tei/embedding.go Outdated
Comment thread core/providers/tei/embedding.go Outdated
@akshaydeo
akshaydeo force-pushed the dev branch 3 times, most recently from fa15f50 to ca190fc Compare June 21, 2026 11:44
@joicemjoseph
joicemjoseph force-pushed the feature/tei-rerank-provider branch from bad0e63 to f9631c4 Compare June 24, 2026 17:29
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 24, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 29, 2026
@akshaydeo
akshaydeo dismissed coderabbitai[bot]’s stale review June 30, 2026 03:04

The merge-base changed after approval.

@akshaydeo
akshaydeo requested a review from a team as a code owner June 30, 2026 03:04
@joicemjoseph
joicemjoseph force-pushed the feature/tei-rerank-provider branch from fc53dd0 to 41a3ce4 Compare July 2, 2026 07:29
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Want your agent to iterate on Greptile's feedback? Try greploops.

akshaydeo and others added 10 commits July 6, 2026 15:44
## Summary

Bumps several indirect Go dependencies to their latest patch/minor versions across the `framework`, `tests/cmd/seed`, `tests/cmd/e2eseed`, and `tests/cmd/seedvks` modules.

## Changes

- `github.com/ClickHouse/ch-go` upgraded from `v0.61.5` → `v0.65.0`
- `github.com/hashicorp/go-version` upgraded from `v1.6.0` → `v1.7.0`
- `github.com/pierrec/lz4/v4` upgraded from `v4.1.21` → `v4.1.22`
- `github.com/maximhq/bifrost/core` upgraded from `v1.6.2` → `v1.6.3` (in `e2eseed`, `seed`, and `seedvks`)
- `go.sum` files updated with additional transitive dependency checksums introduced by the `ch-go` upgrade (e.g., `go-faster/city`, `go-faster/errors`, `segmentio/asm`, `shopspring/decimal`, `paulmach/orb`, and various `golang.org/x/*` historical entries)

## Type of change

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

## Affected areas

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

## How to test

```sh
go version
go test ./...
```

## Screenshots/Recordings

N/A

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

N/A

## Security considerations

No security implications. All changes are indirect dependency version bumps with no API surface changes.

## 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
## Summary

Adds the `v2.0.0` branch as a trigger for the release pipeline so that releases can be cut directly from that branch in addition to `main`.

## Changes

- Added `v2.0.0` to the list of branches that trigger the release pipeline on push, enabling the pipeline to run when changes are pushed to the `v2.0.0` branch.

## Type of change

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

## Affected areas

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

## How to test

Push a commit to the `v2.0.0` branch and verify the release pipeline is triggered automatically.

## Screenshots/Recordings

N/A

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

N/A

## Security considerations

No security implications. This only affects which branches trigger the CI release pipeline.

## 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
## Summary

Bumps several indirect Go dependencies to their latest patch/minor versions across all modules in the repository.

## Changes

- `github.com/andybalholm/brotli`: `v1.2.1` → `v1.2.2`
- `github.com/ClickHouse/ch-go`: `v0.61.5` → `v0.65.0`
- `github.com/ClickHouse/clickhouse-go/v2`: `v2.30.0` → `v2.32.0`
- `github.com/hashicorp/go-version`: `v1.6.0` / `v1.7.0` → `v1.8.0`
- `github.com/pierrec/lz4/v4`: `v4.1.21` → `v4.1.22`
- `github.com/tidwall/pretty`: `v1.2.0` → `v1.2.1`
- `github.com/onsi/gomega` (transports only): `v1.35.1` → `v1.38.2`

## Type of change

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

## Affected areas

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

## How to test

```sh
go test ./...
```

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

No security implications. These are routine dependency version bumps with no API surface changes.

## 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
… guardrails (maximhq#4169)

## Summary

This PR introduces reversible redaction support across the Bifrost stack, allowing enterprise guardrails plugins to redact PII from log content while preserving an encrypted reversible mapping that authorized users can later reveal inline in the log detail view.

## Changes

- Added `RedactionPayload` schema type and associated context helpers (`RedactionPayloadFromContext`, `SetRedactionPayloadOnContext`, `ApplyLiteralReplacements`) to carry request-scoped redaction data from guardrails to log sinks
- Added `BifrostContextKeyRedactionData` context key for guardrails plugins to attach redaction payloads (marked DO NOT SET MANUALLY)
- Added `RedactionData` (transient), `RedactionMapping` (persisted), and `HasReversibleRedaction` (virtual) fields to the `Log` table struct
- Added `migrationAddRedactionMappingColumn` to persist the reversible mapping alongside the log row so it shares the row's lifecycle
- Updated `FindByID` to use `ScopedDB` so point lookups honor caller-supplied query scope (e.g. Enterprise DAC), preventing out-of-scope ID access
- Added `attachLogRedactionData` in the logging plugin to copy guardrail redaction payloads into log entries before async writes, gated on content logging being enabled
- Exposed `HasReversibleRedaction` on log detail and list endpoints so the UI knows when a reveal toggle is applicable
- Added a `Reveal` RBAC operation and `canReveal` prop threading through `LogDetailSheet` → `LogDetailView`
- Added a "Show original values" toggle in the log detail header that calls a new `POST /logs/:id/reveal` endpoint and applies the returned mapping inline to all message text, reasoning, and refusal fields without mutating stored data
- Added `useRevealLogRedactionMappingMutation` RTK Query mutation and `LogRedactionRevealResponse` type
- Literal replacement applies longest-match-first ordering to avoid partial substitution of overlapping tokens

## Type of change

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

## Affected areas

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

## How to test

```sh
# Core/Transports
go test ./core/schemas/... ./framework/logstore/... ./plugins/logging/...

# UI
cd ui
pnpm i
pnpm build
```

To validate end-to-end:
1. Configure an enterprise guardrails plugin that sets `BifrostContextKeyRedactionData` with a `RedactionPayload` containing `ReversibleMappings`
2. Send a request containing PII through Bifrost
3. Open the log detail view — the "Show original values" toggle should appear only for users with the `Reveal` RBAC permission on `Logs`
4. Toggle reveal — placeholders like `[EMAIL-1]` should be replaced inline with their original values
5. Navigate to a different log — the toggle resets and the mapping is cleared from state

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

- The `RedactionMapping` column stores the reversible mapping encrypted when an encryption key is configured; the mapping is deleted when the log row is deleted, preventing orphaned sensitive data
- The reveal endpoint is gated behind a new `Reveal` RBAC operation so only authorized users can recover original PII values
- `BifrostContextKeyRedactionData` is explicitly marked DO NOT SET MANUALLY to prevent plugins from injecting arbitrary mappings
- `attachLogRedactionData` is a no-op when content logging is disabled, preventing sensitive payloads from leaking through the async write path
- `FindByID` now enforces query scope, closing a gap where a scoped caller could retrieve out-of-scope log rows by ID

## Checklist

- [x] I added/updated tests where appropriate
- [x] I verified builds succeed (Go and UI)
…4417)

## Summary

Adds trace-level redaction of span content attributes before traces are exported to observability plugins. Connectors can register raw-to-placeholder replacement maps on a trace; when the trace completes, all content-bearing span attributes (messages, prompts, tool arguments, etc.) are rewritten in-place before any plugin receives the trace. The replacement map is stored in an unexported field so it is never serialized or leaked to connectors.

## Changes

- Added `IsContentAttribute(key string) bool` to classify which span attribute keys may carry user or model content (messages, prompts, embeddings, tool arguments, reasoning text, etc.).
- Added `RedactAttributeValue(value any, replacements map[string]string) any` to apply literal replacements across `string`, `[]string`, and `[]any` attribute shapes.
- Added `redactionReplacements` as an unexported field on `Trace` so the map is never JSON-serialized and cannot be observed by connectors.
- Added `Trace.SetRedactionReplacements` to store a defensive copy of the replacement map, stripping empty keys.
- Added `Trace.ApplyRedactionReplacements` to walk every span, redact content attributes, and clear the map atomically.
- Added `Trace.Reset` cleanup to ensure pooled traces cannot carry redaction data across requests.
- Added `redactSpanAttributes` as a package-private helper that locks a single span and rewrites its content attributes.
- Added `SetTraceRedactionReplacements` to the `Tracer` interface and its `NoOpTracer` implementation.
- Wired `ApplyRedactionReplacements` into `Tracer.CompleteAndFlushTrace` so redaction runs before any observability plugin `Inject` call.
- Added `Tracer.SetTraceRedactionReplacements` in the framework tracing layer to look up the live trace and delegate to `Trace.SetRedactionReplacements`.

## Type of change

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

## Affected areas

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

## How to test

```sh
go test ./core/schemas/... ./framework/tracing/...
```

Key scenarios covered by new tests:

- `TestIsContentAttribute` — verifies the content attribute classifier includes message, prompt, embedding, and tool fields while excluding metadata fields like model name and session ID.
- `TestTraceApplyRedactionReplacementsRedactsContentAttributes` — verifies replacements are applied to all spans and that non-content attributes are left untouched.
- `TestTraceRedactionReplacementsDoNotSerialize` — verifies the replacement map never appears in JSON output.
- `TestTraceResetClearsRedactionReplacements` — verifies pooled traces cannot retain replacement data.
- `TestTracer_CompleteAndFlushTraceRedactsContentBeforeInject` — end-to-end: replacements set before span population are applied before the observability plugin receives the trace.
- `TestTracer_SetTraceRedactionReplacementsSurvivesLaterObservabilityPlugins` — replacements set before plugin registration still take effect at flush time.

## Breaking changes

- [x] Yes
- [ ] No

The `Tracer` interface gains a new method `SetTraceRedactionReplacements`. Any external implementation of `Tracer` must add this method. The `NoOpTracer` implementation is provided as a reference no-op.

## Security considerations

The replacement map is stored in an unexported struct field (`redactionReplacements`) and is explicitly cleared after `ApplyRedactionReplacements` runs and during `Reset`. This prevents PII or secret values used as redaction keys from being serialized into trace payloads, retained across pooled trace reuse, or observed by observability plugin authors inspecting the exported `Trace` struct.

## Checklist

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

Adds documentation for Bifrost-managed guardrail redaction, two new PII guardrail providers (Microsoft Presidio and Azure AI Language PII), and a `POST /api/logs/{id}/reveal` endpoint for revealing reversible redaction mappings from Bifrost logs.

## Changes

- Added a new `Guardrail Redaction` reference page (`enterprise/guardrails/redaction.mdx`) covering the three redaction modes (`runtime`, `logs_only`, `runtime_reversible`), redaction strategies (`replace`, `mask`, `hash`), the reveal permission model, and connector export behavior.
- Added integration pages for Microsoft Presidio (`integrations/guardrails/presidio.mdx`) and Azure AI Language PII (`integrations/guardrails/azure-language-pii.mdx`), including configuration fields, authentication modes, and all four config formats (Web UI, API, config.json, Helm).
- Extended the Regex and Secrets Detection provider docs and config examples to include per-pattern `action`, `redaction_strategy`, `redaction_mode`, and `entity_type` fields.
- Updated the guardrails overview to list Presidio and Azure AI Language PII in the provider capability matrix, added a warning against combining provider-managed transformation with Bifrost-managed redaction on the same phase, and added a Redaction section summarizing the three modes.
- Updated the nav (`docs.json`) to add a `Providers` sub-group under Guardrails and surface the new Redaction, Presidio, and Azure AI Language PII pages.
- Added `POST /api/logs/{id}/reveal` to the OpenAPI spec (YAML and compiled JSON), gated by `Logs:Reveal`, returning a `LogRevealResponse` with a placeholder-to-original-value mapping. Added `has_reversible_redaction` to `LogEntry`.
- Added `Logs:Reveal` and `MCPToolGroups`/`MCPLogs` to the RBAC resource table.
- Added guardrail redaction notes to the Datadog connector, OTel, default observability, and log-exports pages explaining that exported content receives redacted or placeholderized values and that reveal mappings are not forwarded to connectors.

## Type of change

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

## Affected areas

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

## How to test

Review the rendered docs to confirm:

- The Guardrail Redaction page renders the mode matrix table and the redaction mode selector screenshot correctly.
- The Presidio and Azure AI Language PII pages appear under the Guardrails > Providers nav group.
- The `POST /api/logs/{id}/reveal` endpoint appears in the API reference with correct request/response schemas and a `403` for missing `Logs:Reveal` permission.
- The Regex and Secrets Detection config examples include `action`, `redaction_strategy`, and `redaction_mode` fields.
- Cross-links between the redaction page and provider pages resolve without 404s.

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

- The `POST /api/logs/{id}/reveal` endpoint returns original sensitive values and is gated by the `Logs:Reveal` RBAC permission. The response is marked `Cache-Control: no-store`.
- Reveal mappings are stored only in Bifrost logs and are never forwarded to trace-export connectors, object storage payloads, or external observability destinations.
- When an encryption key is configured, the reveal mapping is encrypted before storage.
- If `disable_content_logging` is enabled, no reveal data is persisted.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
@akshaydeo
akshaydeo dismissed coderabbitai[bot]’s stale review July 14, 2026 08:11

The merge-base changed after approval.

@akshaydeo
akshaydeo force-pushed the dev branch 3 times, most recently from 44564de to 493bff0 Compare July 18, 2026 01:10
@akshaydeo

Copy link
Copy Markdown
Contributor

Hi @joicemjoseph — thanks for the contribution! This PR is currently blocked because our CLA bot shows the Contributor License Agreement as not yet signed. Could you sign it here so we can move this forward: https://cla-assistant.io/maximhq/bifrost?pullRequest=4469

Let us know if you run into any issues signing.

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.

6 participants