Skip to content

feat: add disable_content_logging option to OTel profiles to drop message/tool content from exported spans - #4064

Merged
akshaydeo merged 1 commit into
devfrom
06-05-feat_disable_content_logging_on_otel
Jun 5, 2026
Merged

feat: add disable_content_logging option to OTel profiles to drop message/tool content from exported spans#4064
akshaydeo merged 1 commit into
devfrom
06-05-feat_disable_content_logging_on_otel

Conversation

@BearTS

@BearTS BearTS commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a disable_content_logging option to OTEL profiles that allows operators to strip message content from exported spans before they reach the collector. When enabled, only metadata (model, token counts, latency, etc.) is exported — input/output messages, tool definitions, tool call arguments, and tool call results are dropped from span attributes and events.

Changes

  • Added DisableContentLogging bool field to the Profile and otelTarget structs, and included it in profileForStorage serialization/deserialization so the setting persists correctly.
  • Propagated disableContentLogging through convertTraceToResourceSpanconvertSpanToOTELSpanconvertAttributesToKeyValues and convertSpanEvents, so filtering applies to both span attributes and span event attributes.
  • Introduced isContentAttribute(key string) bool to centralize the list of attribute keys that carry message/tool content (AttrInputMessages, AttrOutputMessages, AttrInputText, AttrInputSpeech, AttrTools, AttrRespTools, AttrToolName, AttrToolCallID, AttrToolCallArguments, AttrToolCallResult, AttrToolType, AttrToolChoiceType, AttrToolChoiceName, AttrRespToolChoiceType, AttrRespToolChoiceName).
  • Added a Disable Content Logging toggle to the OTEL profile form in the UI, wired to the disable_content_logging field with appropriate label and description text.
  • Extended the Zod schema (otelConfigSchema) and the StoredOtelProfile TypeScript interface to include disable_content_logging.

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

# Core/Transports
go test ./plugins/otel/...

# UI
cd ui
pnpm i
pnpm build
  1. Configure an OTEL profile in the UI and enable Disable Content Logging.
  2. Send a request through Bifrost that produces a trace with input/output messages and tool calls.
  3. Inspect the spans received by the OTEL collector and confirm that attributes such as gen_ai.prompt, gen_ai.completion, tool definitions, and tool call arguments/results are absent, while model, token count, and latency attributes are still present.
  4. Disable the toggle and repeat — confirm content attributes reappear in the exported spans.

New config field:

Field Type Default Description
disable_content_logging bool false When true, drops message content and tool data from exported OTEL spans.

Screenshots/Recordings

A new toggle appears in the OTEL profile configuration section beneath the existing request headers field, labeled Disable Content Logging with a description explaining what is suppressed.

Breaking changes

  • No

Related issues

Security considerations

This feature directly addresses PII and data-sensitivity concerns. Operators handling regulated data or operating under strict data-minimization requirements can enable disable_content_logging to ensure that raw prompt/completion content and tool payloads are never forwarded to the OTEL collector, reducing the risk of sensitive data exposure in observability pipelines.

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 by CodeRabbit

  • New Features
    • Added a per-profile "Disable Content Logging" toggle for OTEL. When enabled, exported traces omit message content (inputs/outputs, embeddings, tool and tool-call details) while retaining metadata (model, tokens, latency). The option appears in the UI and is persisted per profile (defaults to off).
  • Chores
    • Configuration schemas and Helm values updated to expose and document the new per-profile setting.

@coderabbitai

coderabbitai Bot commented Jun 4, 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: ASSERTIVE

Plan: Pro

Run ID: fc734ca5-089f-4297-aa2c-9299249e0ffd

📥 Commits

Reviewing files that changed from the base of the PR and between e7be55c and 8da7bd1.

📒 Files selected for processing (7)
  • helm-charts/bifrost/values.schema.json
  • helm-charts/bifrost/values.yaml
  • plugins/otel/converter.go
  • plugins/otel/main.go
  • transports/config.schema.json
  • ui/app/workspace/observability/fragments/otelFormFragment.tsx
  • ui/lib/types/schemas.ts

📝 Walkthrough

Walkthrough

Adds a per-profile disable_content_logging flag to OTEL profiles. Backend persists and wires the flag into runtime targets and span conversion to skip content-bearing attributes/events when enabled. Frontend schema and form expose a per-profile toggle; deployment and transport schemas updated.

Changes

OTEL Content Logging Control

Layer / File(s) Summary
Backend profile model and target configuration
plugins/otel/main.go
Profile gains DisableContentLogging; profileForStorage persists it; MarshalForStorage maps it; otelTarget stores it; buildTarget initializes it from the profile.
Backend span attribute and event filtering
plugins/otel/converter.go
Adds isContentAttribute; convertAttributesToKeyValues and convertSpanEvents accept disableContentLogging and skip content-bearing keys when the flag is true.
Backend trace conversion and Inject wiring
plugins/otel/converter.go, plugins/otel/main.go
convertTraceToResourceSpan and convertSpanToOTELSpan accept/forward the flag; Inject passes per-target disableContentLogging into trace conversion.
Frontend schema validation
ui/lib/types/schemas.ts
otelConfigSchema adds disable_content_logging: z.boolean().default(false).
Frontend form and UI
ui/app/workspace/observability/fragments/otelFormFragment.tsx
Profile shape, emptyProfile(), and toProfileForm() include disable_content_logging; new FormField renders a "Disable Content Logging" Switch, disabled when hasOtelAccess is false.
Deployment and transport schemas
helm-charts/bifrost/values.schema.json, helm-charts/bifrost/values.yaml, transports/config.schema.json
Helm values/schema and transport config schema include disable_content_logging (default false) and documentation describing that enabling it drops message content from exported OTEL spans while retaining metadata.

Sequence Diagram(s)

sequenceDiagram
  participant UI
  participant Inject
  participant convertTraceToResourceSpan
  participant convertSpanToOTELSpan
  participant convertAttributesToKeyValues
  participant convertSpanEvents

  UI->>Inject: configure profile (disable_content_logging)
  Inject->>convertTraceToResourceSpan: pass disableContentLogging
  convertTraceToResourceSpan->>convertSpanToOTELSpan: pass disableContentLogging
  convertSpanToOTELSpan->>convertAttributesToKeyValues: convert attributes (with flag)
  convertSpanToOTELSpan->>convertSpanEvents: convert events (with flag)
  convertSpanEvents->>convertAttributesToKeyValues: convert event attributes (with flag)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • maximhq/bifrost#3894: Modifies the same trace→OTEL span conversion functions (convertTraceToResourceSpan/convertSpanToOTELSpan).
  • maximhq/bifrost#3732: Also updates OTEL span conversion logic and root-span attributes in plugins/otel/converter.go.

Suggested reviewers

  • roroghost17
  • danpiths

Poem

🐰 I hop through spans at break of dawn,

I tuck away inputs, outputs withdrawn,
A switch flips quiet, traces keep their face,
Metadata dances, content leaves no trace,
I nibble logs with a gentle grace.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature: adding a disable_content_logging option to OTel profiles to filter message/tool content from exported spans.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all required sections including summary, changes, type of change, affected areas, testing instructions, screenshots, and security considerations.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 06-05-feat_disable_content_logging_on_otel

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"


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

BearTS commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@BearTS BearTS changed the title feat: disable content logging on otel feat: add disable_content_logging option to OTel profiles to drop message/tool content from exported spans Jun 4, 2026
@BearTS
BearTS marked this pull request as ready for review June 4, 2026 19:09
@greptile-apps

greptile-apps Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

Safe to merge after fixing the incomplete content filter — the infrastructure is correct but three attribute keys carrying real user content slip through when the flag is enabled.

The isContentAttribute allowlist omits AttrPrompt, AttrInstructions, and AttrRespReasoningText, all of which are populated by llmspan.go with verbatim user/system content. An operator enabling disable_content_logging to satisfy a data-minimization or PII requirement would still have that content exported for transcription, Responses API, and reasoning requests, silently defeating the feature's stated guarantee.

plugins/otel/converter.go — the isContentAttribute switch is the only place that needs updating.

Important Files Changed

Filename Overview
plugins/otel/converter.go Adds disableContentLogging parameter through the converter chain; isContentAttribute is missing AttrPrompt, AttrInstructions, and AttrRespReasoningText, causing content to leak for transcription and Responses API spans even when the flag is enabled.
plugins/otel/main.go Adds DisableContentLogging field to Profile and otelTarget, wires it through buildTarget and Inject, and round-trips it through profileForStorage serialization — all correct.
transports/config.schema.json Adds disable_content_logging boolean field to the OTEL profile schema definition; matches the Go struct and Helm schema.
helm-charts/bifrost/values.schema.json Adds disable_content_logging to both the per-profile and the deprecated top-level OTEL schema objects with correct descriptions and defaults.
helm-charts/bifrost/values.yaml Adds disable_content_logging: false to the default profile example; no issues.
ui/app/workspace/observability/fragments/otelFormFragment.tsx Adds disable_content_logging to StoredOtelProfile, emptyProfile, toProfileForm, and renders a Switch toggle with a data-testid; correctly wired and gated behind hasOtelAccess.
ui/lib/types/schemas.ts Adds disable_content_logging boolean with default(false) to otelConfigSchema; consistent with the form fragment and backend.

Reviews (4): Last reviewed commit: "feat: disable content logging on otel" | Re-trigger Greptile

Comment thread plugins/otel/converter.go

@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 `@ui/app/workspace/observability/fragments/otelFormFragment.tsx`:
- Around line 444-461: The Switch in the FormField for name
`${base}.disable_content_logging` is missing a data-testid used by E2E tests;
add a stable data-testid prop to the Switch (e.g.,
data-testid="disable-content-logging-toggle" or similar) while leaving its
checked, onCheckedChange, and disabled props intact so tests can reliably select
this interactive element in otelFormFragment.tsx.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: aac7d06e-ab78-4378-b8ff-6318f66e87cb

📥 Commits

Reviewing files that changed from the base of the PR and between d754185 and 0072029.

📒 Files selected for processing (4)
  • plugins/otel/converter.go
  • plugins/otel/main.go
  • ui/app/workspace/observability/fragments/otelFormFragment.tsx
  • ui/lib/types/schemas.ts

@BearTS
BearTS force-pushed the 06-05-feat_disable_content_logging_on_otel branch from 0072029 to c74c501 Compare June 5, 2026 06:02

@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

♻️ Duplicate comments (1)
ui/app/workspace/observability/fragments/otelFormFragment.tsx (1)

457-457: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a unique data-testid per OTEL profile toggle.

data-testid="disable-content-logging-toggle" is duplicated across profiles, which makes E2E selectors ambiguous when multiple profiles are present.

Suggested fix
- <Switch checked={field.value} onCheckedChange={field.onChange} disabled={!hasOtelAccess} data-testid="disable-content-logging-toggle" />
+ <Switch
+   checked={field.value}
+   onCheckedChange={field.onChange}
+   disabled={!hasOtelAccess}
+   data-testid={`otel-profile-${index}-content-logging-toggle`}
+ />

As per coding guidelines: "Always use stable, unique keys in lists" and "E2E tests must use data-testid attributes for element selection."

🤖 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 `@ui/app/workspace/observability/fragments/otelFormFragment.tsx` at line 457,
The Switch's data-testid ("disable-content-logging-toggle") is duplicated across
OTEL profiles; update the Switch in otelFormFragment (the element with
checked={field.value} onCheckedChange={field.onChange}
disabled={!hasOtelAccess}) to emit a stable unique test id per profile—e.g.,
append the profile identifier or form field name/index (use profile.id,
profile.name, or field.name/index) so the attribute becomes something like
"disable-content-logging-toggle-{profileId}" to ensure uniqueness for E2E
selectors.
🤖 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 `@plugins/otel/converter.go`:
- Line 250: The code currently drops schemas.AttrToolCallID when content logging
is disabled; change the filtering in the attribute-building logic in
plugins/otel/converter.go (the block that builds the attributes list including
schemas.AttrToolName and schemas.AttrToolCallID) so that you only remove
content-bearing fields (tool definitions, arguments, results, and any
payload-specific attrs) and always retain schemas.AttrToolCallID (and other
correlation metadata like schemas.AttrToolName) so tool call IDs remain
available for correlation even when content logging is off.
- Around line 241-258: Add a small table-driven unit test for isContentAttribute
that enumerates each relevant schemas.Attr* key (both those currently expected
to return true and a few representative keys expected to return false) and
asserts the boolean result matches the contract; name the test to indicate it
protects the OTEL content-filtering privacy boundary, use a loop over test cases
with t.Run to isolate failures, and fail explicitly when the returned value
differs from the expected value so future additions to schemas.Attr* will be
caught.

---

Duplicate comments:
In `@ui/app/workspace/observability/fragments/otelFormFragment.tsx`:
- Line 457: The Switch's data-testid ("disable-content-logging-toggle") is
duplicated across OTEL profiles; update the Switch in otelFormFragment (the
element with checked={field.value} onCheckedChange={field.onChange}
disabled={!hasOtelAccess}) to emit a stable unique test id per profile—e.g.,
append the profile identifier or form field name/index (use profile.id,
profile.name, or field.name/index) so the attribute becomes something like
"disable-content-logging-toggle-{profileId}" to ensure uniqueness for E2E
selectors.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 31935830-59c3-45bc-9444-b5a5e11b0264

📥 Commits

Reviewing files that changed from the base of the PR and between 0072029 and c74c501.

📒 Files selected for processing (4)
  • plugins/otel/converter.go
  • plugins/otel/main.go
  • ui/app/workspace/observability/fragments/otelFormFragment.tsx
  • ui/lib/types/schemas.ts

Comment thread plugins/otel/converter.go
Comment thread plugins/otel/converter.go
@BearTS
BearTS force-pushed the 06-05-feat_disable_content_logging_on_otel branch from c74c501 to 815992c Compare June 5, 2026 06:15
@BearTS
BearTS requested a review from a team as a code owner June 5, 2026 06:16
@BearTS
BearTS force-pushed the 06-05-feat_disable_content_logging_on_otel branch from 815992c to e7be55c Compare June 5, 2026 06:16

@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 `@helm-charts/bifrost/values.schema.json`:
- Around line 3453-3457: The new boolean property disable_content_logging was
added to otelProfileConfig but the outer compatibility wrapper
otelProfilesConfig still disallows that deprecated top-level key
(additionalProperties: false), causing validation failures during migration;
update otelProfilesConfig to accept the same deprecated disable_content_logging
key for compatibility—either add disable_content_logging to otelProfilesConfig's
allowed properties (mirroring otelProfileConfig) or relax the wrapper validation
to map/forward that deprecated top-level key into the profile entries so merged
values validate correctly.

In `@ui/app/workspace/observability/fragments/otelFormFragment.tsx`:
- Around line 444-461: The data-testid "disable-content-logging-toggle" is
static but this FormField is rendered per profile; update the test id to be
profile-unique (consistent with nearby toggles) by including the profile index
or profile identifier when rendering the Switch for the field named
`${base}.disable_content_logging` inside the FormField/Render block; ensure you
reuse the same naming pattern used elsewhere (e.g., append `-${profileIndex}` or
`${profileIndex}-...`) so the Switch's data-testid becomes unique per profile
while keeping the original base string for E2E tests.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 2cc70d56-3758-44ca-b160-d5f52f3a4760

📥 Commits

Reviewing files that changed from the base of the PR and between c74c501 and e7be55c.

📒 Files selected for processing (7)
  • helm-charts/bifrost/values.schema.json
  • helm-charts/bifrost/values.yaml
  • plugins/otel/converter.go
  • plugins/otel/main.go
  • transports/config.schema.json
  • ui/app/workspace/observability/fragments/otelFormFragment.tsx
  • ui/lib/types/schemas.ts

Comment thread helm-charts/bifrost/values.schema.json
Comment thread ui/app/workspace/observability/fragments/otelFormFragment.tsx
@BearTS
BearTS force-pushed the 06-05-feat_disable_content_logging_on_otel branch from e7be55c to 8da7bd1 Compare June 5, 2026 06:34

akshaydeo commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Jun 5, 7:44 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 5, 7:45 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit f8a1972 into dev Jun 5, 2026
16 checks passed
@akshaydeo
akshaydeo deleted the 06-05-feat_disable_content_logging_on_otel branch June 5, 2026 07:45
@akshaydeo akshaydeo mentioned this pull request Jun 7, 2026
akshaydeo pushed a commit that referenced this pull request Jun 7, 2026
…essage/tool content from exported spans (#4064)

## Summary

Adds a `disable_content_logging` option to OTEL profiles that allows operators to strip message content from exported spans before they reach the collector. When enabled, only metadata (model, token counts, latency, etc.) is exported — input/output messages, tool definitions, tool call arguments, and tool call results are dropped from span attributes and events.

## Changes

- Added `DisableContentLogging bool` field to the `Profile` and `otelTarget` structs, and included it in `profileForStorage` serialization/deserialization so the setting persists correctly.
- Propagated `disableContentLogging` through `convertTraceToResourceSpan` → `convertSpanToOTELSpan` → `convertAttributesToKeyValues` and `convertSpanEvents`, so filtering applies to both span attributes and span event attributes.
- Introduced `isContentAttribute(key string) bool` to centralize the list of attribute keys that carry message/tool content (`AttrInputMessages`, `AttrOutputMessages`, `AttrInputText`, `AttrInputSpeech`, `AttrTools`, `AttrRespTools`, `AttrToolName`, `AttrToolCallID`, `AttrToolCallArguments`, `AttrToolCallResult`, `AttrToolType`, `AttrToolChoiceType`, `AttrToolChoiceName`, `AttrRespToolChoiceType`, `AttrRespToolChoiceName`).
- Added a **Disable Content Logging** toggle to the OTEL profile form in the UI, wired to the `disable_content_logging` field with appropriate label and description text.
- Extended the Zod schema (`otelConfigSchema`) and the `StoredOtelProfile` TypeScript interface to include `disable_content_logging`.

## Type of change

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

## Affected areas

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

## How to test

```sh
# Core/Transports
go test ./plugins/otel/...

# UI
cd ui
pnpm i
pnpm build
```

1. Configure an OTEL profile in the UI and enable **Disable Content Logging**.
2. Send a request through Bifrost that produces a trace with input/output messages and tool calls.
3. Inspect the spans received by the OTEL collector and confirm that attributes such as `gen_ai.prompt`, `gen_ai.completion`, tool definitions, and tool call arguments/results are absent, while model, token count, and latency attributes are still present.
4. Disable the toggle and repeat — confirm content attributes reappear in the exported spans.

**New config field:**

| Field | Type | Default | Description |
|---|---|---|---|
| `disable_content_logging` | `bool` | `false` | When `true`, drops message content and tool data from exported OTEL spans. |

## Screenshots/Recordings

A new toggle appears in the OTEL profile configuration section beneath the existing request headers field, labeled **Disable Content Logging** with a description explaining what is suppressed.

## Breaking changes

- [x] No

## Related issues

## Security considerations

This feature directly addresses PII and data-sensitivity concerns. Operators handling regulated data or operating under strict data-minimization requirements can enable `disable_content_logging` to ensure that raw prompt/completion content and tool payloads are never forwarded to the OTEL collector, reducing the risk of sensitive data exposure in observability pipelines.

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

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added a per-profile "Disable Content Logging" toggle for OTEL. When enabled, exported traces omit message content (inputs/outputs, embeddings, tool and tool-call details) while retaining metadata (model, tokens, latency). The option appears in the UI and is persisted per profile (defaults to off).
* **Chores**
  * Configuration schemas and Helm values updated to expose and document the new per-profile setting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
akshaydeo added a commit that referenced this pull request Jun 7, 2026
## ✨ Features

- **OpenAI Compaction** — Added OpenAI conversation compaction support
across core, framework, logging, and the API surface (#4053)
- **Multi-Customer & Org Hierarchy** — Logs and usage tracking now
support multiple customers, teams, and business units, including
business unit CRUD, team assignment, and governance endpoints in the
OpenAPI spec (#4066, #4041, #4082)
- **Provider-Level Governance** — Budgets & limits are now scope-aware
and can be applied at the virtual-key top level and per provider, wired
from the model configs table, with UI filters for scope and providers
(#3938, #3937, #3939, #3981, #3962)
- **Customer Budgets** — Customers support multiple budgets and
`calendar_aligned` budget windows (#3998, #3997)
- **Virtual Key Attribution & Controls** — Added a `created_by` user
attribution column and a `blacklisted_models` column for virtual key
provider configs (#3672, #3653)
- **Request Header Capture** — OTel and Maxim observability plugins
capture `request_headers` by pattern, with wildcard support (e.g.
`x-custom-*`); logging gained the same wildcard header capture (#4012,
#3958)
- **OTel Content Controls & Collectors** — New `disable_content_logging`
option drops message/tool content from exported spans, plus support for
multiple OTel collectors (#4064, #3894)
- **xAI x_search** — Added xAI `x_search` tool support (#3976)
- **URL Validation** — Added fetch URL validation with private-network
configuration and link-local blocking (#3947, #3991)
- **File Scheme Pricing URLs** — Pricing source URLs now accept the
`file://` scheme for air-gapped and self-hosted deployments (#4045)
- **Paginated Virtual Keys** — Virtual key fetching is paginated to
handle deployments with very large numbers of keys (#3957)
- **Client IP Resolution** — Resolve client IP from
`X-Forwarded-For`/`X-Real-IP` headers
- **SCIM Provisioning** — Added `attributeType`/`attributeValue` SCIM
provisioning fields
- **Helm/Config Schema** — Added `roles` RBAC governance config and
`per_user_oauth` MCP auth to the Helm chart and config schema (#4004,
#4009)
- **Log Navigation UI** — Added a "View logs" menu item to customer,
team, and virtual key tables, clickable links in log detail views, a
customer detail sheet, and a reusable `BudgetDisplay` component (#4073,
#4054, #4026, #4055)
- **Faster First Paint** — Added an inline loading shell to `#root`
before React mounts (#4063)
- **Materialized View Alias** — Added an `alias` column to the
materialized view with filter support (#4078)

## 🐞 Fixed

- **Fetch URL IP Checks** — Hardened fetch URL IP checks against SSRF
(#4092)
- **Mantle Model Matching** — Broadened Mantle model matching to all
`gpt` variants (#4091)
- **Empty Thinking Blocks** — Strip thinking blocks when the signature
is empty (#4079)
- **OpenAI Stream Usage** — Removed usage from the `responses.created`
event in the OpenAI stream (#4080)
- **Prompt Cache Key** — Set the prompt cache key from the Anthropic
integration (#4086)
- **Upstream Failure Status** — Map upstream connection failures to 502
instead of 400 (#3929) (thanks
[@chris-colinsky](https://github.com/chris-colinsky)!)
- **Gemini Schema Constraints** — Accept numeric schema integer
constraints for Gemini (#3994) (thanks
[@yanhao98](https://github.com/yanhao98)!)
- **Files Provider Param** — Accept the `?provider=` query param on `GET
/v1/files` (#3971) (thanks [@alexef](https://github.com/alexef)!)
- **Optional Batch Model** — Made the `model` field optional on `POST
/v1/batches` (#3973) (thanks [@alexef](https://github.com/alexef)!)
- **Helm Azure Config** — Added missing `azure_key_config` fields to the
Helm schema (#3996) (thanks
[@axelray-dev](https://github.com/axelray-dev)!)
- **Text Completion Chunk Model** — Added the missing `Model` field to
`TextCompletionChunkResponse` (#3970) (thanks
[@kuishou68](https://github.com/kuishou68)!)
- **MCP Inline stdio Env** — MCP stdio server configs accept inline
environment variable assignments (#3861) (thanks
[@Shushmitaaaa](https://github.com/Shushmitaaaa)!)
- **Orphaned Tool Results** — Orphaned tool results in the OpenAI to
Anthropic conversion flow are no longer rejected by the Anthropic API
(#3919)
- **Node Usage Reconciliation** — Added a monotonic `inc_number` log
cursor so node usage reconciliation does not skip late async log writes
(#3664)
- **Bedrock Output Assessments** — Corrected the type of
`outputAssessments` in Bedrock responses (#4028)
- **Model Pool Pricing Reloads** — Preserve non-pricing model pool
entries across pricing reloads (#3999)
- **Ghost Node Reconciliation** — Replicate the VK hierarchy flow for
ghost node reconciliation (#4088)
- **VK Double Usage Counting** — Fixed double usage counting when
creating a virtual key (#4070)
- **Model Config Lifecycle** — Cascade deletes for model configs and
removal of stale in-memory model configs (#4051, #4043)
- **FTS Index Cap** — Reduced the FTS index `left()` cap from 800k to
250k chars to stay within the tsvector limit (#4057)
- **Sync Worker Drift** — Reduced the sync worker ticker period to 5m to
prevent threshold drift (#4023)
- **Passthrough** — Fixed passthrough budgets, gated passthrough models
per VK, model extraction for Azure passthrough, and restricted
fallbacks/provider selection to the VK boundary (#3941, #3988, #3983,
#3924)
- **Provider Response Headers** — Strip provider response headers and
add a content-type filter (#3955, #4024)
- **Stream Handling** — Drain non-SSE stream readers and retry stale
connections (#3956, #3967)
- **Azure Claude** — Strip Azure diagnostic property for Claude models
(#3925)
- **Compat max_tokens** — Preserve chat `max_tokens` during param
filtering (#3992)
- **Raw Request Flag** — Removed the raw request flag from providers
that don't support it (#4058)
- **UI Fixes** — Standardized page container layout, virtual key model
configs UI, and dashboard chart tooltips (#4046, #4052, #4044)

## 🔧 Maintenance

- **Dependency Upgrades** — Bumped transitive `golang.org/x`
dependencies (crypto, net, sys, text) for Docker Scout CVE remediation
and `recharts` to 3.8.1; cascaded version bumps across all modules
(#3900, #4003)
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.

2 participants