fixes generateContent to keep safetyRatings and avgLogprobs - #5877
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change preserves Gemini response IDs, safety ratings, and average log probabilities through standard and streaming conversions. It also updates bug investigation guidance to require red-before-green testing and result reporting. ChangesGemini response metadata preservation
Bug investigation workflow
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Gemini
participant BifrostResponses
participant ProviderExtraFields
Gemini->>BifrostResponses: responseId, safetyRatings, avgLogprobs
BifrostResponses->>ProviderExtraFields: store provider metadata
ProviderExtraFields->>BifrostResponses: restore provider metadata
BifrostResponses->>Gemini: reconstructed response
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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" Comment |
There was a problem hiding this comment.
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/gemini/responses.go`:
- Around line 283-299: Preserve terminal candidate metadata and completion
events for empty or error responses: in
core/providers/gemini/responses.go:283-299, assign ProviderExtraFields before
every error-finish return; in ToGeminiResponsesResponse at
core/providers/gemini/responses.go:566-575, create or populate a candidate
whenever preserved metadata exists even when Output is empty; and in the stream
conversion at core/providers/gemini/responses.go:1179-1205, emit
response.completed for terminal chunks without text or tool items. Add
empty/error and ProviderExtraFields JSON round-trip coverage in
core/providers/gemini/gemini_test.go:3981-4035, plus a terminal-only
safety/error stream case in
core/providers/gemini/safetyratingsstream_test.go:50-89.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9589b562-6d97-4056-a0a0-1e3f8f49810f
📒 Files selected for processing (4)
.claude/skills/investigate-issue/SKILL.mdcore/providers/gemini/gemini_test.gocore/providers/gemini/responses.gocore/providers/gemini/safetyratingsstream_test.go
82445b3 to
9cfd415
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
Merge activity
|
## Summary `candidates[0].safetyRatings`, `candidates[0].avgLogprobs`, and the native Gemini `responseId` were silently dropped when a Gemini/Vertex response passed through Bifrost's OpenAI-shaped Responses schema. Because Bifrost's schema has no fields for these values, they need to be round-tripped via `ProviderExtraFields` and restored on egress. This fix covers both the non-streaming (`generateContent`) and streaming (`streamGenerateContent`) paths. Closes #5843 ## Changes - **`responses.go`** **— non-streaming path**: `ToResponsesBifrostResponsesResponse` now stashes `responseId`, `safetyRatings`, and `avgLogprobs` into `ProviderExtraFields` when converting inbound Gemini responses to Bifrost format. `ToGeminiResponsesResponse` reads them back out and restores them onto the outbound `GenerateContentResponse`. - **`responses.go`** **— streaming path**: `GeminiResponsesStreamState` gains `SafetyRatings` and `AvgLogprobs` fields. `ToBifrostResponsesStream` captures these from the terminal chunk (the only chunk that carries them, alongside `finishReason`). `closeGeminiOpenItems` writes them into `ProviderExtraFields` on the `response.completed` event. `ToGeminiResponsesStreamResponse` restores them onto the outbound stream chunk. - **`extractGeminiSafetyRatings`** **/** **`extractGeminiAvgLogprobs`**: Two helper functions handle both the in-memory pointer form (normal path) and the JSON-decoded `[]interface{}`/`map` form that can appear after a JSON round-trip. - **`gemini_test.go`**: Regression test `TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip` covers the non-streaming round-trip, asserting all three fields survive `ToResponsesBifrostResponsesResponse` → `ToGeminiResponsesResponse`. - **`safetyratingsstream_test.go`**: New test file with `TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip`, which drives a two-chunk stream through the full forward (`ToBifrostResponsesStream`) and reverse (`ToGeminiResponsesStreamResponse`) conversion loop and asserts `safetyRatings`, `avgLogprobs`, and `responseId` are present on the terminal chunk. - **`SKILL.md`**: The investigate-issue skill now enforces AGENTS.md's "red before green" rule for Bug-classified issues — tests are written and confirmed failing before any fix code is applied, and the todo list ordering reflects this sequence. ## Type of change - [x] Bug fix ## Affected areas - [x] Core (Go) - [x] Providers/Integrations ## How to test ```sh go test ./core/providers/gemini/... -run TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... -run TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... ``` Both new tests should pass. The streaming test validates that `safetyRatings`, `avgLogprobs`, and `responseId` appear on the `response.completed` chunk after a two-chunk stream round-trip. The non-streaming test validates the same fields survive a single `GenerateContentResponse` → Bifrost → `GenerateContentResponse` round-trip. ## Breaking changes - [x] No ## Related issues Closes #5843 ## Security considerations None. The change only preserves existing provider-supplied metadata through an internal schema boundary; no new data is introduced or exposed. ## 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
…5877) ## Summary `candidates[0].safetyRatings`, `candidates[0].avgLogprobs`, and the native Gemini `responseId` were silently dropped when a Gemini/Vertex response passed through Bifrost's OpenAI-shaped Responses schema. Because Bifrost's schema has no fields for these values, they need to be round-tripped via `ProviderExtraFields` and restored on egress. This fix covers both the non-streaming (`generateContent`) and streaming (`streamGenerateContent`) paths. Closes maximhq#5843 ## Changes - **`responses.go`** **— non-streaming path**: `ToResponsesBifrostResponsesResponse` now stashes `responseId`, `safetyRatings`, and `avgLogprobs` into `ProviderExtraFields` when converting inbound Gemini responses to Bifrost format. `ToGeminiResponsesResponse` reads them back out and restores them onto the outbound `GenerateContentResponse`. - **`responses.go`** **— streaming path**: `GeminiResponsesStreamState` gains `SafetyRatings` and `AvgLogprobs` fields. `ToBifrostResponsesStream` captures these from the terminal chunk (the only chunk that carries them, alongside `finishReason`). `closeGeminiOpenItems` writes them into `ProviderExtraFields` on the `response.completed` event. `ToGeminiResponsesStreamResponse` restores them onto the outbound stream chunk. - **`extractGeminiSafetyRatings`** **/** **`extractGeminiAvgLogprobs`**: Two helper functions handle both the in-memory pointer form (normal path) and the JSON-decoded `[]interface{}`/`map` form that can appear after a JSON round-trip. - **`gemini_test.go`**: Regression test `TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip` covers the non-streaming round-trip, asserting all three fields survive `ToResponsesBifrostResponsesResponse` → `ToGeminiResponsesResponse`. - **`safetyratingsstream_test.go`**: New test file with `TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip`, which drives a two-chunk stream through the full forward (`ToBifrostResponsesStream`) and reverse (`ToGeminiResponsesStreamResponse`) conversion loop and asserts `safetyRatings`, `avgLogprobs`, and `responseId` are present on the terminal chunk. - **`SKILL.md`**: The investigate-issue skill now enforces AGENTS.md's "red before green" rule for Bug-classified issues — tests are written and confirmed failing before any fix code is applied, and the todo list ordering reflects this sequence. ## Type of change - [x] Bug fix ## Affected areas - [x] Core (Go) - [x] Providers/Integrations ## How to test ```sh go test ./core/providers/gemini/... -run TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... -run TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... ``` Both new tests should pass. The streaming test validates that `safetyRatings`, `avgLogprobs`, and `responseId` appear on the `response.completed` chunk after a two-chunk stream round-trip. The non-streaming test validates the same fields survive a single `GenerateContentResponse` → Bifrost → `GenerateContentResponse` round-trip. ## Breaking changes - [x] No ## Related issues Closes maximhq#5843 ## Security considerations None. The change only preserves existing provider-supplied metadata through an internal schema boundary; no new data is introduced or exposed. ## 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
…5877) ## Summary `candidates[0].safetyRatings`, `candidates[0].avgLogprobs`, and the native Gemini `responseId` were silently dropped when a Gemini/Vertex response passed through Bifrost's OpenAI-shaped Responses schema. Because Bifrost's schema has no fields for these values, they need to be round-tripped via `ProviderExtraFields` and restored on egress. This fix covers both the non-streaming (`generateContent`) and streaming (`streamGenerateContent`) paths. Closes maximhq#5843 ## Changes - **`responses.go`** **— non-streaming path**: `ToResponsesBifrostResponsesResponse` now stashes `responseId`, `safetyRatings`, and `avgLogprobs` into `ProviderExtraFields` when converting inbound Gemini responses to Bifrost format. `ToGeminiResponsesResponse` reads them back out and restores them onto the outbound `GenerateContentResponse`. - **`responses.go`** **— streaming path**: `GeminiResponsesStreamState` gains `SafetyRatings` and `AvgLogprobs` fields. `ToBifrostResponsesStream` captures these from the terminal chunk (the only chunk that carries them, alongside `finishReason`). `closeGeminiOpenItems` writes them into `ProviderExtraFields` on the `response.completed` event. `ToGeminiResponsesStreamResponse` restores them onto the outbound stream chunk. - **`extractGeminiSafetyRatings`** **/** **`extractGeminiAvgLogprobs`**: Two helper functions handle both the in-memory pointer form (normal path) and the JSON-decoded `[]interface{}`/`map` form that can appear after a JSON round-trip. - **`gemini_test.go`**: Regression test `TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip` covers the non-streaming round-trip, asserting all three fields survive `ToResponsesBifrostResponsesResponse` → `ToGeminiResponsesResponse`. - **`safetyratingsstream_test.go`**: New test file with `TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip`, which drives a two-chunk stream through the full forward (`ToBifrostResponsesStream`) and reverse (`ToGeminiResponsesStreamResponse`) conversion loop and asserts `safetyRatings`, `avgLogprobs`, and `responseId` are present on the terminal chunk. - **`SKILL.md`**: The investigate-issue skill now enforces AGENTS.md's "red before green" rule for Bug-classified issues — tests are written and confirmed failing before any fix code is applied, and the todo list ordering reflects this sequence. ## Type of change - [x] Bug fix ## Affected areas - [x] Core (Go) - [x] Providers/Integrations ## How to test ```sh go test ./core/providers/gemini/... -run TestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... -run TestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip go test ./core/providers/gemini/... ``` Both new tests should pass. The streaming test validates that `safetyRatings`, `avgLogprobs`, and `responseId` appear on the `response.completed` chunk after a two-chunk stream round-trip. The non-streaming test validates the same fields survive a single `GenerateContentResponse` → Bifrost → `GenerateContentResponse` round-trip. ## Breaking changes - [x] No ## Related issues Closes maximhq#5843 ## Security considerations None. The change only preserves existing provider-supplied metadata through an internal schema boundary; no new data is introduced or exposed. ## 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
candidates[0].safetyRatings,candidates[0].avgLogprobs, and the native GeminiresponseIdwere silently dropped when a Gemini/Vertex response passed through Bifrost's OpenAI-shaped Responses schema. Because Bifrost's schema has no fields for these values, they need to be round-tripped viaProviderExtraFieldsand restored on egress. This fix covers both the non-streaming (generateContent) and streaming (streamGenerateContent) paths.Closes #5843
Changes
responses.go— non-streaming path:ToResponsesBifrostResponsesResponsenow stashesresponseId,safetyRatings, andavgLogprobsintoProviderExtraFieldswhen converting inbound Gemini responses to Bifrost format.ToGeminiResponsesResponsereads them back out and restores them onto the outboundGenerateContentResponse.responses.go— streaming path:GeminiResponsesStreamStategainsSafetyRatingsandAvgLogprobsfields.ToBifrostResponsesStreamcaptures these from the terminal chunk (the only chunk that carries them, alongsidefinishReason).closeGeminiOpenItemswrites them intoProviderExtraFieldson theresponse.completedevent.ToGeminiResponsesStreamResponserestores them onto the outbound stream chunk.extractGeminiSafetyRatings/extractGeminiAvgLogprobs: Two helper functions handle both the in-memory pointer form (normal path) and the JSON-decoded[]interface{}/mapform that can appear after a JSON round-trip.gemini_test.go: Regression testTestGenAISafetyRatingsAvgLogprobsResponseIDStreamRoundTripcovers the non-streaming round-trip, asserting all three fields surviveToResponsesBifrostResponsesResponse→ToGeminiResponsesResponse.safetyratingsstream_test.go: New test file withTestGeminiSafetyRatingsAvgLogprobsResponseIDStreamRoundTrip, which drives a two-chunk stream through the full forward (ToBifrostResponsesStream) and reverse (ToGeminiResponsesStreamResponse) conversion loop and assertssafetyRatings,avgLogprobs, andresponseIdare present on the terminal chunk.SKILL.md: The investigate-issue skill now enforces AGENTS.md's "red before green" rule for Bug-classified issues — tests are written and confirmed failing before any fix code is applied, and the todo list ordering reflects this sequence.Type of change
Affected areas
How to test
Both new tests should pass. The streaming test validates that
safetyRatings,avgLogprobs, andresponseIdappear on theresponse.completedchunk after a two-chunk stream round-trip. The non-streaming test validates the same fields survive a singleGenerateContentResponse→ Bifrost →GenerateContentResponseround-trip.Breaking changes
Related issues
Closes #5843
Security considerations
None. The change only preserves existing provider-supplied metadata through an internal schema boundary; no new data is introduced or exposed.
Checklist
docs/contributing/README.mdand followed the guidelines