test fixes - #3761
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR updates test expectations and infrastructure across multiple provider implementations. Migration test generation now populates v1.5.4 schema columns with conditional guards, and snapshot validation excludes intentionally dropped columns. Provider tests are refactored to align with updated tool parameter serialization, stop-reason mappings, and role attribution in Gemini, Anthropic, and Bedrock providers. Two production changes update Bedrock tool-use detection logic and Azure endpoint redaction handling. ChangesProvider Test Updates and Migration Infrastructure
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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" Warning Review ran into problems🔥 ProblemsStopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a Comment |
|
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. |
Confidence Score: 5/5This PR is safe to merge; all behavioural changes are backed by matching test updates and the underlying logic is consistent with the existing data-model conventions. Every fix is localised and well-understood: the Azure endpoint panic fix is guarded correctly, the Bedrock hasToolUse rewrite is consistent with how server-managed tool types are distinguished in the rest of the file, the Gemini passthrough and role corrections are tested end-to-end, and the migration script additions follow the established pattern for log-store tables. No unguarded code paths or data-model mismatches were found. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "test fixes" | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
core/providers/gemini/gemini_test.go (1)
735-739: ⚡ Quick winAssert that empty
itemsstays an object, not just a present key.
assert.Contains(..., "items")still passes for"items": nullor any other non-object value. These regressions would slip through even though the edge case here is specifically preserving an empty schema object. Decodeitemsasmap[string]interface{}and assert it is empty.Also applies to: 2609-2612
🤖 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/gemini/gemini_test.go` around lines 735 - 739, The test currently only asserts the "items" key exists (using assert.Contains) which allows non-object values like null; update the assertion to decode dataProp["items"] into a map[string]interface{} (using a type assertion or json decoding) and assert that the resulting map is non-nil and has length 0 to guarantee it's an empty object; apply the same change to the other occurrences mentioned (the similar assertions around lines 2609-2612) and keep references to parseToolParams, getSchemaProperty, and the local variable dataProp to locate the checks.
🤖 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/gemini/gemini_test.go`:
- Around line 435-445: The tests currently lose property ordering because
parseToolParams marshals then unmarshals into map[string]interface{}, which
discards key order; change parseToolParams (and the PropertyOrdering tests) to
preserve ordering by returning the marshaled JSON bytes (or
json.RawMessage/string) from json.Marshal(fd.ParametersJSONSchema) instead of
unmarshalling to a map, and update the assertions to compare the marshaled bytes
(or normalized compact string) against the expected ordered JSON so the tests
verify exact key order; references: function parseToolParams and the
PropertyOrdering test blocks that currently call it.
---
Nitpick comments:
In `@core/providers/gemini/gemini_test.go`:
- Around line 735-739: The test currently only asserts the "items" key exists
(using assert.Contains) which allows non-object values like null; update the
assertion to decode dataProp["items"] into a map[string]interface{} (using a
type assertion or json decoding) and assert that the resulting map is non-nil
and has length 0 to guarantee it's an empty object; apply the same change to the
other occurrences mentioned (the similar assertions around lines 2609-2612) and
keep references to parseToolParams, getSchemaProperty, and the local variable
dataProp to locate the checks.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9b0c2dcf-8e4d-42f9-8b86-6560a01b3b5b
📒 Files selected for processing (8)
.github/workflows/scripts/run-migration-tests.shcore/providers/anthropic/compaction_test.gocore/providers/anthropic/utils_test.gocore/providers/bedrock/responses.gocore/providers/gemini/gemini_test.gocore/providers/gemini/uniontype_test.goframework/configstore/clientconfig.goplugins/jsonparser/plugin_test.go
03e8779 to
519e4f7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
core/providers/gemini/gemini_test.go (1)
435-445:⚠️ Potential issue | 🟠 Major | ⚡ Quick winProperty-ordering tests currently can’t verify ordering.
parseToolParamsconverts schema intomap[string]interface{}, which drops key order before the ordering tests run. The assertions at Line 1015 and Line 1063 only prove presence, not order preservation.Proposed minimal fix
-func parseToolParams(t *testing.T, fd *gemini.FunctionDeclaration) map[string]interface{} { +func parseToolParamsRaw(t *testing.T, fd *gemini.FunctionDeclaration) []byte { t.Helper() require.NotNil(t, fd.ParametersJSONSchema, "ParametersJSONSchema must be set") raw, err := json.Marshal(fd.ParametersJSONSchema) require.NoError(t, err) - var m map[string]interface{} - require.NoError(t, json.Unmarshal(raw, &m)) - return m + return raw +} + +func parseToolParams(t *testing.T, fd *gemini.FunctionDeclaration) map[string]interface{} { + t.Helper() + raw := parseToolParamsRaw(t, fd) + var m map[string]interface{} + require.NoError(t, json.Unmarshal(raw, &m)) + return m }-params := parseToolParams(t, fd) -props, ok := params["properties"].(map[string]interface{}) -require.True(t, ok, "parameters must have properties") -assert.Len(t, props, 3) -assert.Contains(t, props, "chain_of_thought") -assert.Contains(t, props, "answer") -assert.Contains(t, props, "citations") +raw := string(parseToolParamsRaw(t, fd)) +idxChain := strings.Index(raw, `"chain_of_thought"`) +idxAnswer := strings.Index(raw, `"answer"`) +idxCitations := strings.Index(raw, `"citations"`) +require.NotEqual(t, -1, idxChain) +require.NotEqual(t, -1, idxAnswer) +require.NotEqual(t, -1, idxCitations) +assert.True(t, idxChain < idxAnswer && idxAnswer < idxCitations, "property order must be preserved")Also applies to: 1015-1021, 1063-1075
🤖 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/gemini/gemini_test.go` around lines 435 - 445, The tests lose property ordering because parseToolParams currently returns a map (map[string]interface{}) which drops key order; change parseToolParams (and its callers) to return an ordered representation (e.g., []string of property names in the schema) by marshaling fd.ParametersJSONSchema and using json.NewDecoder to stream/iterate tokens and collect object keys in their original order (specifically iterate into the top-level "properties" object and append each property key to a slice). Update tests that assert ordering to consume the new ordered slice instead of a map.
🤖 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/bedrock/responses.go`:
- Around line 2595-2597: The tool-use detection currently only sets hasToolUse
when msg.Type equals schemas.ResponsesMessageTypeFunctionCall; update the check
in the loop over bifrostResp.Output to also consider
schemas.ResponsesMessageTypeWebSearchCall and
schemas.ResponsesMessageTypeCodeInterpreterCall (e.g., treat any of those three
types as tool use), so hasToolUse is true for any of those message types and the
stop reason will be correctly set to "tool_use". Ensure you change the
conditional that references ResponsesMessageTypeFunctionCall to check for all
three constants (or use a small switch/lookup) where hasToolUse is assigned.
---
Duplicate comments:
In `@core/providers/gemini/gemini_test.go`:
- Around line 435-445: The tests lose property ordering because parseToolParams
currently returns a map (map[string]interface{}) which drops key order; change
parseToolParams (and its callers) to return an ordered representation (e.g.,
[]string of property names in the schema) by marshaling fd.ParametersJSONSchema
and using json.NewDecoder to stream/iterate tokens and collect object keys in
their original order (specifically iterate into the top-level "properties"
object and append each property key to a slice). Update tests that assert
ordering to consume the new ordered slice instead of a map.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fe348e7e-6405-45db-ace1-79d015046933
📒 Files selected for processing (12)
.github/workflows/scripts/run-migration-tests.shcore/internal/llmtests/provider_feature_support_test.gocore/providers/anthropic/compaction_test.gocore/providers/anthropic/requestbuilder_test.gocore/providers/anthropic/types.gocore/providers/anthropic/utils.gocore/providers/anthropic/utils_test.gocore/providers/bedrock/responses.gocore/providers/gemini/gemini_test.gocore/providers/gemini/uniontype_test.goframework/configstore/clientconfig.goplugins/jsonparser/plugin_test.go
✅ Files skipped from review due to trivial changes (1)
- core/providers/anthropic/compaction_test.go
Merge activity
|
## Summary This PR delivers a collection of fixes and improvements across the Gemini provider, Anthropic provider, Bedrock Responses API, Azure config redaction, and migration test infrastructure for v1.5.4. ## Changes - **Gemini – tool schema passthrough via `ParametersJSONSchema`**: Tool parameter schemas are now forwarded to Gemini using the `parametersJsonSchema` wire key instead of the structured `parameters` field. This removes the previous schema-transformation layer (union-type expansion, `anyOf` rewriting, sibling-field stripping, `nullable` injection) and passes the raw JSON Schema through unchanged. As a result, array-typed unions, sibling fields alongside `anyOf`, and `description` fields are all preserved. The `propertyOrdering` field is no longer emitted separately; property order is maintained by the underlying `OrderedMap` serialization. - **Gemini – tool response role corrected to `"user"`**: Function/tool response content blocks were being emitted with role `"model"`; they are now correctly emitted with role `"user"` across both the Chat and Responses API paths. - **Gemini – structured output + tools conflict**: When both tools and a JSON response format are present for Gemini 2.5, `responseJsonSchema` is now also dropped (previously only `responseMimeType` was dropped). - **Anthropic – stop reason normalization**: `end_turn` → `stop`, `tool_use` → `tool_calls`, `max_tokens` → `length` to align with the normalized Bifrost stop-reason vocabulary. Tests updated accordingly. - **Anthropic – computer-use tool version mapping**: `text_editor_20250124`/`str_replace_editor` is now upgraded to `text_editor_20250728`/`str_replace_based_edit_tool` for `claude-sonnet-4-5` models. Test names and expectations updated to reflect the corrected behavior. - **Bedrock – Responses API `hasToolUse` detection**: Replaced the content-block scan (which checked for unmatched `toolUse` blocks) with a direct check on `bifrostResp.Output` for `ResponsesMessageTypeFunctionCall`, making the detection more reliable and consistent with the Responses API data model. - **Azure config redaction**: Fixed a panic/incorrect redaction when `AzureKeyConfig.Endpoint` is not sourced from an environment variable. The endpoint is now only redacted when `IsFromEnv()` is true; otherwise the original value is preserved as-is. - **JSON parser plugin test**: Added missing `Params` with `json_object` format to the Responses stream end-to-end test to properly exercise the parser plugin. - **Migration tests – v1.5.4 columns**: Added dynamic column update blocks for three new v1.5.4 migrations — `governance_virtual_key_provider_configs.blacklisted_models`, `governance_virtual_keys.created_by_user_id`, and `logs.inc_number` — for both PostgreSQL and SQLite paths. Also added `azure_api_version` to the list of dropped columns on `config_keys` for snapshot comparison. ## Type of change - [x] Bug fix - [ ] Feature - [x] Refactor - [ ] Documentation - [x] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [x] Plugins - [ ] UI (React) - [ ] Docs ## How to test ```sh go test ./core/providers/gemini/... go test ./core/providers/anthropic/... go test ./core/providers/bedrock/... go test ./framework/configstore/... go test ./plugins/jsonparser/... ``` For migration tests, run the migration test workflow against a PostgreSQL and SQLite target and verify that v1.5.4 column additions and the `azure_api_version` column drop are handled without snapshot mismatches. ## Breaking changes - [x] Yes - [ ] No The Gemini tool schema wire format changes from `parameters` to `parametersJsonSchema`. Clients or tests that assert on the exact wire key or rely on the previous union-type/`anyOf` rewriting behavior will need to be updated. The Anthropic stop reason values (`end_turn`, `tool_use`, `max_tokens`) are replaced with normalized values (`stop`, `tool_calls`, `length`); any downstream code matching on the raw Anthropic strings will need to be updated. ## Security considerations The Azure endpoint redaction fix ensures that plain (non-env-var) endpoint values are not incorrectly processed through the `Redacted()` path, preventing potential nil-pointer panics and ensuring the correct value is returned in config responses. ## 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
## ✨ Features
- **Azure v1 API Migration** — Migrated Azure provider to the v1 API:
removed the `api-version` query parameter and the
`/openai/deployments/{model}/...` URL pattern in favor of
`/openai/v1/{operation}`; the `api_version` field has been dropped from
`AzureKeyConfig` (#3661, #3756)
- **EnvVar Support for OTEL & Prometheus Configs** — `CollectorURL`,
`MetricsEndpoint`, headers, push gateway URL, and basic auth credentials
can now be sourced from environment variables (e.g.,
`env.OTEL_COLLECTOR_URL`); added a new `ConfigMarshallerPlugin`
interface that lets plugins control storage/redaction round-trips
(#3651)
- **OTel Extra Header Forwarding** — `x-bf-eh-*` extra headers forwarded
to upstream providers are now also emitted on the request span under
`gen_ai.request.extra_header.*` for end-to-end tracing (#3730)
- **OTel Semantic Conventions** — Aligned OTel attribute keys with the
OpenTelemetry GenAI spec (canonical `gen_ai.*` and new `bifrost.*`
attributes); legacy attributes are retained in parallel to avoid
breaking existing dashboards (#3732)
- **VK Quota with Provider Configs** — `GetVirtualKeyQuotaByValue` and
the `getVirtualKeyQuota` HTTP response now include `provider_configs`
with their budgets and rate limits (#3721)
- **MCP Temp Token Non-Auth Toggle** — Added
`mcp_enable_temp_token_auth` client config flag to gate short-lived MCP
token minting for non-authenticated users (#3720)
- **Responses Stream in JSON Parser** — `jsonparser` plugin now handles
OpenAI Responses API streaming (`ResponsesStreamRequest`) in addition to
chat completions (#3749)
- **Session API Rework** — Logout now calls both the password-based
session logout and OAuth logout endpoints and resets all RTK Query cache
state (#3698)
## 🐞 Fixed
- **Streaming Latency for Observability** — Deferred root span
termination to the trace completer callback for streaming requests so
request latency is no longer inflated by header-flush time (#3762)
- **Stream Cancellation Race** — Set `BifrostContextKeyConnectionClosed`
before closing the stream and short-circuit `idleTimeoutReader.Read`
when the connection is already closed to avoid panics and hangs on
cancellation (#3733)
- **Bedrock Cache Points** — Strip cache points from Bedrock requests
for models that do not support prompt caching (e.g., GLM, Llama) to
avoid Converse API errors (#3754)
- **Bedrock Empty Text Blocks** — Skip empty/nil text blocks during
Bedrock response conversion to avoid invalid messages (#3747)
- **Bedrock Reasoning + Tools** — Preserve reasoning content blocks on
assistant turns that also contain tool calls in the Bedrock chat
converter (#3690)
- **Bedrock Search Content & Video** — Restored search content and video
parts that were being dropped from Bedrock-native passthrough requests
(#3729)
- **Structured Output Stop Reason** — Fixed an incorrect `tool_calls`
finish reason when structured output is combined with extended-thinking
tools (#3685)
- **Gemini Tool Schema Passthrough** — Forward full tool parameter
schemas via `parametersJsonSchema` instead of the lossy `parameters`
form; corrected tool response role to `user`; resolved structured output
+ tools conflict (#3761)
- **Anthropic Stop Reason & Tool Versions** — Normalized stop reason
mapping (`end_turn` to `stop`, `tool_use` to `tool_calls`, `max_tokens`
to `length`) and upgraded `text_editor_20250124`/`str_replace_editor` to
`text_editor_20250728` for computer-use tools (#3761)
- **Azure Endpoint Redaction** — Fixed a panic when
`AzureKeyConfig.Endpoint` is a literal value rather than an env
reference (#3761)
- **Auth Middleware Path Match** — Match temp-token auth middleware
whitelist against the request path only, not the full URI with query
parameters (#3737)
- **Governance Blocked Models UI** — Restored the missing Blocked Models
create/edit UI in the VK provider config sheet (#3750)
- **Logging Plugin Cleanup Drain** — Fixed a shutdown race where
`batchWriter` could drop in-flight log entries; `Cleanup` now drains
both the recovered batch and remaining queue within a 30-second budget
(#3717)
- **Model Rankings Empty Entries** — Excluded entries with empty `model`
values from model rankings matview queries so blank rows no longer
surface in the UI (#3758)
- **User Filter Duplicates** — Recreated `mv_filter_users` matview to
require non-empty `user_name`, eliminating duplicate filter dropdown
entries (#3764)
- **User Filter Display Name** — Use `user_name` instead of `user_id` as
the display label for users in logging filters (#3691)
- **Large Numeric ID Precision** — Preserve large numeric IDs in URL
search params by skipping JSON parsing for plain strings (#3692)
## 🔧 Refactors & Chores
- **Error Propagation for GetAvailable\* APIs** — `GetAvailable*`
methods on `LoggerPlugin`/`LogManager` now return wrapped errors instead
of silently logging and returning empty slices (#3759)
- **Governance Blocklist Matching** — Use `slices.Contains` for VK
blocked-model matching for clearer code with identical semantics (#3727)
- **Exported `ResolvePeriod`** — Renamed `resolvePeriod` to
`ResolvePeriod` so external packages can reuse the period parsing
(#3763)
## 📚 Docs
- **OTEL Env Var Documentation** — Documented `env.VAR_NAME` support for
`collector_url`, `metrics_endpoint`, and headers in OTEL/Prometheus
plugin docs
- **OTEL OSS Features & Examples** — Added OTEL documentation to the OSS
features list with usage examples (#3731)
- **Anthropic Auth Recommendation** — Recommend `ANTHROPIC_AUTH_TOKEN`
over `ANTHROPIC_CUSTOM_HEADERS` for Claude Code authentication (#3686)
## Summary
This PR releases Bifrost OSS `v1.5.5` and Enterprise `v1.4.4`, bumping all module pins from `v1.5.12`/`v1.3.12` to `v1.5.13`/`v1.3.13` across core, framework, and all plugins. It also hardens the Docker manifest shell scripts, expands CI egress allowlists, and updates documentation to reflect the new SCIM-based user provisioning feature.
## Changes
- **Module version bumps**: All `go.mod`/`go.sum` files updated from `core v1.5.12` → `v1.5.13`, `framework v1.3.12` → `v1.3.13`, and all plugin versions incremented accordingly (`compat`, `governance`, `jsonparser`, `logging`, `maxim`, `mocker`, `otel`, `prompts`, `semanticcache`, `telemetry`).
- **Docker manifest scripts**: Added `#!/usr/bin/env bash` shebang and `set -euo pipefail` to `create-docker-manifest.sh` and `create-docker-manifest-ubi9.sh`; quoted all variable expansions and switched `jq -r` to `jq -er` to fail on null digests.
- **CI egress allowlist**: Added `production.cloudfront.docker.com:443` to Docker-related job allowlists, and added `_https._tcp.dl.google.com:443` and `motd.ubuntu.com:443` to the Ubuntu package job allowlist.
- **Changelog files**: Cleared per-module `changelog.md` files (content moved into the new versioned docs). Added `docs/changelogs/v1.5.5.mdx` and `docs/changelogs/ent-v1.4.4.mdx` with full release notes, and registered both in `docs/docs.json`.
- **Documentation**: Replaced the SSO Integration link with a User Provisioning (SCIM) link in both `README.md` and `transports/README.md`.
- **Enterprise v1.4.4 highlights** (documented): Kafka and Google Cloud Pub/Sub observability sinks, chunked streaming with a 100 MB inter-node message ceiling, BigQuery custom labels via env vars using the new `ConfigMarshallerPlugin` interface, temporary access token expiry extensions, and a multi-node cluster integration harness.
- **OSS v1.5.5 highlights** (documented): Azure v1 API migration, env-var support for OTel/Prometheus configs, OTel extra-header forwarding and semantic-convention alignment, virtual key quota including provider configs, Responses API streaming in `jsonparser`, and a batch of Bedrock, Gemini, Anthropic, Azure, and logging plugin fixes.
## Type of change
- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [x] Documentation
- [x] Chore/CI
## Affected areas
- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [ ] UI (React)
- [x] Docs
## How to test
```sh
# Core/Transports
go version
go test ./...
# Verify Docker manifest scripts exit on error
bash -n .github/workflows/scripts/create-docker-manifest.sh
bash -n .github/workflows/scripts/create-docker-manifest-ubi9.sh
```
Validate that the new changelog pages (`changelogs/v1.5.5` and `changelogs/ent-v1.4.4`) render correctly in the docs site.
## Screenshots/Recordings
N/A
## Breaking changes
- [x] Yes
- [ ] No
The Azure provider no longer accepts `api_version` in `AzureKeyConfig` and has migrated to the `/openai/v1/{operation}` URL pattern. See the [v1.4.0 Migration Guide](https://docs.getbifrost.ai/enterprise/migration-guides/v1.4.0) for full details.
## Related issues
#3661, #3756, #3651, #3730, #3732, #3754, #3747, #3690, #3729, #3685, #3733, #3761, #3735, #3721, #3720, #3749, #3698, #3762, #3750, #3727, #3717, #3759, #3758, #3764, #3691, #3692, #3737, #3763
## Security considerations
- The `ConfigMarshallerPlugin` interface redacts secrets (OTel collector URLs, Prometheus push gateway credentials, BigQuery labels) at config storage time and rehydrates them at load time, preventing plaintext secret persistence.
- Docker manifest scripts now use `set -euo pipefail`, preventing silent failures that could result in malformed or missing image manifests being pushed.
## 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
## Summary This PR delivers a collection of fixes and improvements across the Gemini provider, Anthropic provider, Bedrock Responses API, Azure config redaction, and migration test infrastructure for v1.5.4. ## Changes - **Gemini – tool schema passthrough via `ParametersJSONSchema`**: Tool parameter schemas are now forwarded to Gemini using the `parametersJsonSchema` wire key instead of the structured `parameters` field. This removes the previous schema-transformation layer (union-type expansion, `anyOf` rewriting, sibling-field stripping, `nullable` injection) and passes the raw JSON Schema through unchanged. As a result, array-typed unions, sibling fields alongside `anyOf`, and `description` fields are all preserved. The `propertyOrdering` field is no longer emitted separately; property order is maintained by the underlying `OrderedMap` serialization. - **Gemini – tool response role corrected to `"user"`**: Function/tool response content blocks were being emitted with role `"model"`; they are now correctly emitted with role `"user"` across both the Chat and Responses API paths. - **Gemini – structured output + tools conflict**: When both tools and a JSON response format are present for Gemini 2.5, `responseJsonSchema` is now also dropped (previously only `responseMimeType` was dropped). - **Anthropic – stop reason normalization**: `end_turn` → `stop`, `tool_use` → `tool_calls`, `max_tokens` → `length` to align with the normalized Bifrost stop-reason vocabulary. Tests updated accordingly. - **Anthropic – computer-use tool version mapping**: `text_editor_20250124`/`str_replace_editor` is now upgraded to `text_editor_20250728`/`str_replace_based_edit_tool` for `claude-sonnet-4-5` models. Test names and expectations updated to reflect the corrected behavior. - **Bedrock – Responses API `hasToolUse` detection**: Replaced the content-block scan (which checked for unmatched `toolUse` blocks) with a direct check on `bifrostResp.Output` for `ResponsesMessageTypeFunctionCall`, making the detection more reliable and consistent with the Responses API data model. - **Azure config redaction**: Fixed a panic/incorrect redaction when `AzureKeyConfig.Endpoint` is not sourced from an environment variable. The endpoint is now only redacted when `IsFromEnv()` is true; otherwise the original value is preserved as-is. - **JSON parser plugin test**: Added missing `Params` with `json_object` format to the Responses stream end-to-end test to properly exercise the parser plugin. - **Migration tests – v1.5.4 columns**: Added dynamic column update blocks for three new v1.5.4 migrations — `governance_virtual_key_provider_configs.blacklisted_models`, `governance_virtual_keys.created_by_user_id`, and `logs.inc_number` — for both PostgreSQL and SQLite paths. Also added `azure_api_version` to the list of dropped columns on `config_keys` for snapshot comparison. ## Type of change - [x] Bug fix - [ ] Feature - [x] Refactor - [ ] Documentation - [x] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [x] Plugins - [ ] UI (React) - [ ] Docs ## How to test ```sh go test ./core/providers/gemini/... go test ./core/providers/anthropic/... go test ./core/providers/bedrock/... go test ./framework/configstore/... go test ./plugins/jsonparser/... ``` For migration tests, run the migration test workflow against a PostgreSQL and SQLite target and verify that v1.5.4 column additions and the `azure_api_version` column drop are handled without snapshot mismatches. ## Breaking changes - [x] Yes - [ ] No The Gemini tool schema wire format changes from `parameters` to `parametersJsonSchema`. Clients or tests that assert on the exact wire key or rely on the previous union-type/`anyOf` rewriting behavior will need to be updated. The Anthropic stop reason values (`end_turn`, `tool_use`, `max_tokens`) are replaced with normalized values (`stop`, `tool_calls`, `length`); any downstream code matching on the raw Anthropic strings will need to be updated. ## Security considerations The Azure endpoint redaction fix ensures that plain (non-env-var) endpoint values are not incorrectly processed through the `Redacted()` path, preventing potential nil-pointer panics and ensuring the correct value is returned in config responses. ## 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
## ✨ Features
- **Azure v1 API Migration** — Migrated Azure provider to the v1 API:
removed the `api-version` query parameter and the
`/openai/deployments/{model}/...` URL pattern in favor of
`/openai/v1/{operation}`; the `api_version` field has been dropped from
`AzureKeyConfig` (maximhq#3661, maximhq#3756)
- **EnvVar Support for OTEL & Prometheus Configs** — `CollectorURL`,
`MetricsEndpoint`, headers, push gateway URL, and basic auth credentials
can now be sourced from environment variables (e.g.,
`env.OTEL_COLLECTOR_URL`); added a new `ConfigMarshallerPlugin`
interface that lets plugins control storage/redaction round-trips
(maximhq#3651)
- **OTel Extra Header Forwarding** — `x-bf-eh-*` extra headers forwarded
to upstream providers are now also emitted on the request span under
`gen_ai.request.extra_header.*` for end-to-end tracing (maximhq#3730)
- **OTel Semantic Conventions** — Aligned OTel attribute keys with the
OpenTelemetry GenAI spec (canonical `gen_ai.*` and new `bifrost.*`
attributes); legacy attributes are retained in parallel to avoid
breaking existing dashboards (maximhq#3732)
- **VK Quota with Provider Configs** — `GetVirtualKeyQuotaByValue` and
the `getVirtualKeyQuota` HTTP response now include `provider_configs`
with their budgets and rate limits (maximhq#3721)
- **MCP Temp Token Non-Auth Toggle** — Added
`mcp_enable_temp_token_auth` client config flag to gate short-lived MCP
token minting for non-authenticated users (maximhq#3720)
- **Responses Stream in JSON Parser** — `jsonparser` plugin now handles
OpenAI Responses API streaming (`ResponsesStreamRequest`) in addition to
chat completions (maximhq#3749)
- **Session API Rework** — Logout now calls both the password-based
session logout and OAuth logout endpoints and resets all RTK Query cache
state (maximhq#3698)
## 🐞 Fixed
- **Streaming Latency for Observability** — Deferred root span
termination to the trace completer callback for streaming requests so
request latency is no longer inflated by header-flush time (maximhq#3762)
- **Stream Cancellation Race** — Set `BifrostContextKeyConnectionClosed`
before closing the stream and short-circuit `idleTimeoutReader.Read`
when the connection is already closed to avoid panics and hangs on
cancellation (maximhq#3733)
- **Bedrock Cache Points** — Strip cache points from Bedrock requests
for models that do not support prompt caching (e.g., GLM, Llama) to
avoid Converse API errors (maximhq#3754)
- **Bedrock Empty Text Blocks** — Skip empty/nil text blocks during
Bedrock response conversion to avoid invalid messages (maximhq#3747)
- **Bedrock Reasoning + Tools** — Preserve reasoning content blocks on
assistant turns that also contain tool calls in the Bedrock chat
converter (maximhq#3690)
- **Bedrock Search Content & Video** — Restored search content and video
parts that were being dropped from Bedrock-native passthrough requests
(maximhq#3729)
- **Structured Output Stop Reason** — Fixed an incorrect `tool_calls`
finish reason when structured output is combined with extended-thinking
tools (maximhq#3685)
- **Gemini Tool Schema Passthrough** — Forward full tool parameter
schemas via `parametersJsonSchema` instead of the lossy `parameters`
form; corrected tool response role to `user`; resolved structured output
+ tools conflict (maximhq#3761)
- **Anthropic Stop Reason & Tool Versions** — Normalized stop reason
mapping (`end_turn` to `stop`, `tool_use` to `tool_calls`, `max_tokens`
to `length`) and upgraded `text_editor_20250124`/`str_replace_editor` to
`text_editor_20250728` for computer-use tools (maximhq#3761)
- **Azure Endpoint Redaction** — Fixed a panic when
`AzureKeyConfig.Endpoint` is a literal value rather than an env
reference (maximhq#3761)
- **Auth Middleware Path Match** — Match temp-token auth middleware
whitelist against the request path only, not the full URI with query
parameters (maximhq#3737)
- **Governance Blocked Models UI** — Restored the missing Blocked Models
create/edit UI in the VK provider config sheet (maximhq#3750)
- **Logging Plugin Cleanup Drain** — Fixed a shutdown race where
`batchWriter` could drop in-flight log entries; `Cleanup` now drains
both the recovered batch and remaining queue within a 30-second budget
(maximhq#3717)
- **Model Rankings Empty Entries** — Excluded entries with empty `model`
values from model rankings matview queries so blank rows no longer
surface in the UI (maximhq#3758)
- **User Filter Duplicates** — Recreated `mv_filter_users` matview to
require non-empty `user_name`, eliminating duplicate filter dropdown
entries (maximhq#3764)
- **User Filter Display Name** — Use `user_name` instead of `user_id` as
the display label for users in logging filters (maximhq#3691)
- **Large Numeric ID Precision** — Preserve large numeric IDs in URL
search params by skipping JSON parsing for plain strings (maximhq#3692)
## 🔧 Refactors & Chores
- **Error Propagation for GetAvailable\* APIs** — `GetAvailable*`
methods on `LoggerPlugin`/`LogManager` now return wrapped errors instead
of silently logging and returning empty slices (maximhq#3759)
- **Governance Blocklist Matching** — Use `slices.Contains` for VK
blocked-model matching for clearer code with identical semantics (maximhq#3727)
- **Exported `ResolvePeriod`** — Renamed `resolvePeriod` to
`ResolvePeriod` so external packages can reuse the period parsing
(maximhq#3763)
## 📚 Docs
- **OTEL Env Var Documentation** — Documented `env.VAR_NAME` support for
`collector_url`, `metrics_endpoint`, and headers in OTEL/Prometheus
plugin docs
- **OTEL OSS Features & Examples** — Added OTEL documentation to the OSS
features list with usage examples (maximhq#3731)
- **Anthropic Auth Recommendation** — Recommend `ANTHROPIC_AUTH_TOKEN`
over `ANTHROPIC_CUSTOM_HEADERS` for Claude Code authentication (maximhq#3686)
## Summary This PR delivers a collection of fixes and improvements across the Gemini provider, Anthropic provider, Bedrock Responses API, Azure config redaction, and migration test infrastructure for v1.5.4. ## Changes - **Gemini – tool schema passthrough via `ParametersJSONSchema`**: Tool parameter schemas are now forwarded to Gemini using the `parametersJsonSchema` wire key instead of the structured `parameters` field. This removes the previous schema-transformation layer (union-type expansion, `anyOf` rewriting, sibling-field stripping, `nullable` injection) and passes the raw JSON Schema through unchanged. As a result, array-typed unions, sibling fields alongside `anyOf`, and `description` fields are all preserved. The `propertyOrdering` field is no longer emitted separately; property order is maintained by the underlying `OrderedMap` serialization. - **Gemini – tool response role corrected to `"user"`**: Function/tool response content blocks were being emitted with role `"model"`; they are now correctly emitted with role `"user"` across both the Chat and Responses API paths. - **Gemini – structured output + tools conflict**: When both tools and a JSON response format are present for Gemini 2.5, `responseJsonSchema` is now also dropped (previously only `responseMimeType` was dropped). - **Anthropic – stop reason normalization**: `end_turn` → `stop`, `tool_use` → `tool_calls`, `max_tokens` → `length` to align with the normalized Bifrost stop-reason vocabulary. Tests updated accordingly. - **Anthropic – computer-use tool version mapping**: `text_editor_20250124`/`str_replace_editor` is now upgraded to `text_editor_20250728`/`str_replace_based_edit_tool` for `claude-sonnet-4-5` models. Test names and expectations updated to reflect the corrected behavior. - **Bedrock – Responses API `hasToolUse` detection**: Replaced the content-block scan (which checked for unmatched `toolUse` blocks) with a direct check on `bifrostResp.Output` for `ResponsesMessageTypeFunctionCall`, making the detection more reliable and consistent with the Responses API data model. - **Azure config redaction**: Fixed a panic/incorrect redaction when `AzureKeyConfig.Endpoint` is not sourced from an environment variable. The endpoint is now only redacted when `IsFromEnv()` is true; otherwise the original value is preserved as-is. - **JSON parser plugin test**: Added missing `Params` with `json_object` format to the Responses stream end-to-end test to properly exercise the parser plugin. - **Migration tests – v1.5.4 columns**: Added dynamic column update blocks for three new v1.5.4 migrations — `governance_virtual_key_provider_configs.blacklisted_models`, `governance_virtual_keys.created_by_user_id`, and `logs.inc_number` — for both PostgreSQL and SQLite paths. Also added `azure_api_version` to the list of dropped columns on `config_keys` for snapshot comparison. ## Type of change - [x] Bug fix - [ ] Feature - [x] Refactor - [ ] Documentation - [x] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [x] Plugins - [ ] UI (React) - [ ] Docs ## How to test ```sh go test ./core/providers/gemini/... go test ./core/providers/anthropic/... go test ./core/providers/bedrock/... go test ./framework/configstore/... go test ./plugins/jsonparser/... ``` For migration tests, run the migration test workflow against a PostgreSQL and SQLite target and verify that v1.5.4 column additions and the `azure_api_version` column drop are handled without snapshot mismatches. ## Breaking changes - [x] Yes - [ ] No The Gemini tool schema wire format changes from `parameters` to `parametersJsonSchema`. Clients or tests that assert on the exact wire key or rely on the previous union-type/`anyOf` rewriting behavior will need to be updated. The Anthropic stop reason values (`end_turn`, `tool_use`, `max_tokens`) are replaced with normalized values (`stop`, `tool_calls`, `length`); any downstream code matching on the raw Anthropic strings will need to be updated. ## Security considerations The Azure endpoint redaction fix ensures that plain (non-env-var) endpoint values are not incorrectly processed through the `Redacted()` path, preventing potential nil-pointer panics and ensuring the correct value is returned in config responses. ## 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
## ✨ Features
- **Azure v1 API Migration** — Migrated Azure provider to the v1 API:
removed the `api-version` query parameter and the
`/openai/deployments/{model}/...` URL pattern in favor of
`/openai/v1/{operation}`; the `api_version` field has been dropped from
`AzureKeyConfig` (maximhq#3661, maximhq#3756)
- **EnvVar Support for OTEL & Prometheus Configs** — `CollectorURL`,
`MetricsEndpoint`, headers, push gateway URL, and basic auth credentials
can now be sourced from environment variables (e.g.,
`env.OTEL_COLLECTOR_URL`); added a new `ConfigMarshallerPlugin`
interface that lets plugins control storage/redaction round-trips
(maximhq#3651)
- **OTel Extra Header Forwarding** — `x-bf-eh-*` extra headers forwarded
to upstream providers are now also emitted on the request span under
`gen_ai.request.extra_header.*` for end-to-end tracing (maximhq#3730)
- **OTel Semantic Conventions** — Aligned OTel attribute keys with the
OpenTelemetry GenAI spec (canonical `gen_ai.*` and new `bifrost.*`
attributes); legacy attributes are retained in parallel to avoid
breaking existing dashboards (maximhq#3732)
- **VK Quota with Provider Configs** — `GetVirtualKeyQuotaByValue` and
the `getVirtualKeyQuota` HTTP response now include `provider_configs`
with their budgets and rate limits (maximhq#3721)
- **MCP Temp Token Non-Auth Toggle** — Added
`mcp_enable_temp_token_auth` client config flag to gate short-lived MCP
token minting for non-authenticated users (maximhq#3720)
- **Responses Stream in JSON Parser** — `jsonparser` plugin now handles
OpenAI Responses API streaming (`ResponsesStreamRequest`) in addition to
chat completions (maximhq#3749)
- **Session API Rework** — Logout now calls both the password-based
session logout and OAuth logout endpoints and resets all RTK Query cache
state (maximhq#3698)
## 🐞 Fixed
- **Streaming Latency for Observability** — Deferred root span
termination to the trace completer callback for streaming requests so
request latency is no longer inflated by header-flush time (maximhq#3762)
- **Stream Cancellation Race** — Set `BifrostContextKeyConnectionClosed`
before closing the stream and short-circuit `idleTimeoutReader.Read`
when the connection is already closed to avoid panics and hangs on
cancellation (maximhq#3733)
- **Bedrock Cache Points** — Strip cache points from Bedrock requests
for models that do not support prompt caching (e.g., GLM, Llama) to
avoid Converse API errors (maximhq#3754)
- **Bedrock Empty Text Blocks** — Skip empty/nil text blocks during
Bedrock response conversion to avoid invalid messages (maximhq#3747)
- **Bedrock Reasoning + Tools** — Preserve reasoning content blocks on
assistant turns that also contain tool calls in the Bedrock chat
converter (maximhq#3690)
- **Bedrock Search Content & Video** — Restored search content and video
parts that were being dropped from Bedrock-native passthrough requests
(maximhq#3729)
- **Structured Output Stop Reason** — Fixed an incorrect `tool_calls`
finish reason when structured output is combined with extended-thinking
tools (maximhq#3685)
- **Gemini Tool Schema Passthrough** — Forward full tool parameter
schemas via `parametersJsonSchema` instead of the lossy `parameters`
form; corrected tool response role to `user`; resolved structured output
+ tools conflict (maximhq#3761)
- **Anthropic Stop Reason & Tool Versions** — Normalized stop reason
mapping (`end_turn` to `stop`, `tool_use` to `tool_calls`, `max_tokens`
to `length`) and upgraded `text_editor_20250124`/`str_replace_editor` to
`text_editor_20250728` for computer-use tools (maximhq#3761)
- **Azure Endpoint Redaction** — Fixed a panic when
`AzureKeyConfig.Endpoint` is a literal value rather than an env
reference (maximhq#3761)
- **Auth Middleware Path Match** — Match temp-token auth middleware
whitelist against the request path only, not the full URI with query
parameters (maximhq#3737)
- **Governance Blocked Models UI** — Restored the missing Blocked Models
create/edit UI in the VK provider config sheet (maximhq#3750)
- **Logging Plugin Cleanup Drain** — Fixed a shutdown race where
`batchWriter` could drop in-flight log entries; `Cleanup` now drains
both the recovered batch and remaining queue within a 30-second budget
(maximhq#3717)
- **Model Rankings Empty Entries** — Excluded entries with empty `model`
values from model rankings matview queries so blank rows no longer
surface in the UI (maximhq#3758)
- **User Filter Duplicates** — Recreated `mv_filter_users` matview to
require non-empty `user_name`, eliminating duplicate filter dropdown
entries (maximhq#3764)
- **User Filter Display Name** — Use `user_name` instead of `user_id` as
the display label for users in logging filters (maximhq#3691)
- **Large Numeric ID Precision** — Preserve large numeric IDs in URL
search params by skipping JSON parsing for plain strings (maximhq#3692)
## 🔧 Refactors & Chores
- **Error Propagation for GetAvailable\* APIs** — `GetAvailable*`
methods on `LoggerPlugin`/`LogManager` now return wrapped errors instead
of silently logging and returning empty slices (maximhq#3759)
- **Governance Blocklist Matching** — Use `slices.Contains` for VK
blocked-model matching for clearer code with identical semantics (maximhq#3727)
- **Exported `ResolvePeriod`** — Renamed `resolvePeriod` to
`ResolvePeriod` so external packages can reuse the period parsing
(maximhq#3763)
## 📚 Docs
- **OTEL Env Var Documentation** — Documented `env.VAR_NAME` support for
`collector_url`, `metrics_endpoint`, and headers in OTEL/Prometheus
plugin docs
- **OTEL OSS Features & Examples** — Added OTEL documentation to the OSS
features list with usage examples (maximhq#3731)
- **Anthropic Auth Recommendation** — Recommend `ANTHROPIC_AUTH_TOKEN`
over `ANTHROPIC_CUSTOM_HEADERS` for Claude Code authentication (maximhq#3686)

Summary
This PR delivers a collection of fixes and improvements across the Gemini provider, Anthropic provider, Bedrock Responses API, Azure config redaction, and migration test infrastructure for v1.5.4.
Changes
ParametersJSONSchema: Tool parameter schemas are now forwarded to Gemini using theparametersJsonSchemawire key instead of the structuredparametersfield. This removes the previous schema-transformation layer (union-type expansion,anyOfrewriting, sibling-field stripping,nullableinjection) and passes the raw JSON Schema through unchanged. As a result, array-typed unions, sibling fields alongsideanyOf, anddescriptionfields are all preserved. ThepropertyOrderingfield is no longer emitted separately; property order is maintained by the underlyingOrderedMapserialization."user": Function/tool response content blocks were being emitted with role"model"; they are now correctly emitted with role"user"across both the Chat and Responses API paths.responseJsonSchemais now also dropped (previously onlyresponseMimeTypewas dropped).end_turn→stop,tool_use→tool_calls,max_tokens→lengthto align with the normalized Bifrost stop-reason vocabulary. Tests updated accordingly.text_editor_20250124/str_replace_editoris now upgraded totext_editor_20250728/str_replace_based_edit_toolforclaude-sonnet-4-5models. Test names and expectations updated to reflect the corrected behavior.hasToolUsedetection: Replaced the content-block scan (which checked for unmatchedtoolUseblocks) with a direct check onbifrostResp.OutputforResponsesMessageTypeFunctionCall, making the detection more reliable and consistent with the Responses API data model.AzureKeyConfig.Endpointis not sourced from an environment variable. The endpoint is now only redacted whenIsFromEnv()is true; otherwise the original value is preserved as-is.Paramswithjson_objectformat to the Responses stream end-to-end test to properly exercise the parser plugin.governance_virtual_key_provider_configs.blacklisted_models,governance_virtual_keys.created_by_user_id, andlogs.inc_number— for both PostgreSQL and SQLite paths. Also addedazure_api_versionto the list of dropped columns onconfig_keysfor snapshot comparison.Type of change
Affected areas
How to test
For migration tests, run the migration test workflow against a PostgreSQL and SQLite target and verify that v1.5.4 column additions and the
azure_api_versioncolumn drop are handled without snapshot mismatches.Breaking changes
The Gemini tool schema wire format changes from
parameterstoparametersJsonSchema. Clients or tests that assert on the exact wire key or rely on the previous union-type/anyOfrewriting behavior will need to be updated. The Anthropic stop reason values (end_turn,tool_use,max_tokens) are replaced with normalized values (stop,tool_calls,length); any downstream code matching on the raw Anthropic strings will need to be updated.Security considerations
The Azure endpoint redaction fix ensures that plain (non-env-var) endpoint values are not incorrectly processed through the
Redacted()path, preventing potential nil-pointer panics and ensuring the correct value is returned in config responses.Checklist
docs/contributing/README.mdand followed the guidelines