Skip to content

fix: reset web search flag when recycling pooled gemini responses stream state - #5114

Merged
akshaydeo merged 1 commit into
maximhq:devfrom
fus3r:fix-gemini-stream-state-web-search-reset
Jul 12, 2026
Merged

fix: reset web search flag when recycling pooled gemini responses stream state#5114
akshaydeo merged 1 commit into
maximhq:devfrom
fus3r:fix-gemini-stream-state-web-search-reset

Conversation

@fus3r

@fus3r fus3r commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #5113. The Gemini responses stream converter emits grounding metadata as a web_search_call output item (queries, source list, lifecycle events) plus a rendered content message, guarded by a HasEmittedWebSearch flag on the pooled GeminiResponsesStreamState so a stream emits the item only once. flush(), the reset both acquireGeminiResponsesStreamState and releaseGeminiResponsesStreamState run when recycling a state object, clears every field of the struct except that flag: it was added with the web search tool support in #1371 after flush() was last touched. The result is that only the first grounded streaming request served by a pooled object ever emits the web search lifecycle; every later grounded stream on a recycled object silently loses the web_search_call item, the sources, and the search suggestions block, both on the client SSE stream and in the accumulated message that feeds logging (items are appended on output_item.added). Vertex is affected too since it shares HandleGeminiResponsesStream. The non-streaming path and the chat completions surface are unaffected.

A CodeRabbit review comment on #2590 flagged this missing reset back in April with the same one-line suggestion, but that PR targets a different problem (safety filtering), is based on main, has been inactive since April, and never picked the suggestion up, so this PR carries the fix on dev with regression tests and a live reproduction.

Changes

  • Reset HasEmittedWebSearch in GeminiResponsesStreamState.flush(), alongside the other lifecycle flags, so a recycled state object emits web search events again. The flag keeps its in-stream deduplication role: it is still set after the first emission within a stream and only cleared when the state is recycled.
  • Regression tests, both failing on dev: a direct flush contract test (a state with the flag set is fully reset), and a recycle test that replays the same grounded chunk sequence twice through ToBifrostResponsesStream with a flush() in between (equivalent to the reset both release and acquire run) and asserts the second stream produces the same event lifecycle as the first, including the completed web_search_call item with its queries and sources. On dev the second stream emits 10 events instead of 17, dropping the whole web search lifecycle and the rendered content pair.
  • Changelog entry.

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

cd core
go test ./providers/gemini/ -run 'TestGeminiResponsesStream' -v

Both tests fail on dev and pass with this change: the flush test because the flag survives the reset, the recycle test because the second grounded stream is missing all seven web-search-related events (output_item.added, the three web_search_call.* lifecycle events, the output_item.done carrying queries and sources, and the rendered content added/done pair). The full ./providers/gemini/ suite is green, including the new tests under the race detector.

Also verified end to end against a real Gemini backend (gemini-2.5-flash with the google_search tool, gateway run with GOMAXPROCS=1 so pool reuse is deterministic for back-to-back requests): on dev the first grounded streamed request carries 8 web_search_call occurrences on the client SSE plus the rendered content message, the second and third identical requests carry zero of each, and the logged accumulated message loses the item the same way, while the identical non-streamed request keeps the item every time. With this change all three streamed runs carry the full web search lifecycle, and non-streamed behavior is unchanged.

Screenshots/Recordings

N/A

Breaking changes

  • Yes
  • No

The change is one flag reset on the pool recycle path. Streams without grounding are unchanged, and within a single stream the flag still deduplicates web search emission exactly as before.

Related issues

Fixes #5113

The missing reset was previously flagged in a review comment on #2590, which never picked it up.

Security considerations

None.

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)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0080c6fc-89bb-4bf3-8a2d-f2468299b2b4

📥 Commits

Reviewing files that changed from the base of the PR and between 65f33df and c14df27.

📒 Files selected for processing (3)
  • core/changelog.md
  • core/providers/gemini/responses.go
  • core/providers/gemini/websearchstreamstate_test.go

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where recycled streaming sessions could fail to emit web search events for grounded Gemini responses.
    • Ensured web search results continue to include the completed search event, query, and source URL after stream state is reused.
  • Tests

    • Added coverage for web search event behavior across streaming session reuse.

Walkthrough

Changes

Gemini web search stream recycling

Layer / File(s) Summary
Reset pooled stream state
core/providers/gemini/responses.go, core/changelog.md
flush() now clears HasEmittedWebSearch, with the fix documented in the changelog.
Validate recycled grounded streams
core/providers/gemini/websearchstreamstate_test.go
Tests replay grounded streams before and after state recycling and verify the web search lifecycle, query, and source URL output.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: akshaydeo, danpiths, roroghost17

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fix: resetting the pooled Gemini web search flag.
Description check ✅ Passed The PR description includes all required sections and provides concrete summary, changes, testing, and related-issue details.
Linked Issues check ✅ Passed The code and tests address #5113 by resetting HasEmittedWebSearch on recycle and preserving grounded streaming web_search_call output.
Out of Scope Changes check ✅ Passed The changes stay scoped to the bug fix, regression tests, and changelog entry, with no unrelated code paths introduced.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

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

🔧 golangci-lint (2.12.2)

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


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

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
core/providers/gemini/responses.go Resets the Gemini web-search emission flag during stream state flush.
core/providers/gemini/websearchstreamstate_test.go Adds targeted tests for recycled Gemini grounded streaming state.
core/changelog.md Documents the Gemini streamed web-search pooled-state fix.

Reviews (1): Last reviewed commit: "fix: reset web search flag when recyclin..." | Re-trigger Greptile

@akshaydeo
akshaydeo merged commit 90679c5 into maximhq:dev Jul 12, 2026
6 checks passed
@fus3r
fus3r deleted the fix-gemini-stream-state-web-search-reset branch July 12, 2026 13:45
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
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.

[Bug]: Gemini/Vertex streaming responses stop emitting web_search_call items after the first grounded request per pooled stream state

2 participants