Skip to content

Conversation

@rabi
Copy link
Contributor

@rabi rabi commented Dec 19, 2025

Summary

  • Add stream() and supports_streaming() to GoogleProvider
  • Use streamGenerateContent?alt=sse endpoint for SSE streaming
  • Implement response_to_streaming_message for SSE format parsing
  • Handle text chunks, function calls, thinking content, and usage
  • Add mid-stream error detection and propagation
  • Trust thoughtSignature for thinking content classification
  • Add tests for streaming text, function calls, and error handling
  • Fix fragmented streaming output in desktop UI by generating a consistent message ID for all chunks within a streaming session

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

  • This PR was created or reviewed with AI assistance

Testing

Unit and manual testing with provider

@rabi
Copy link
Contributor Author

rabi commented Dec 20, 2025

@DOsinga @alexhancock Hi, Apologies for the direct ping for review. I don't seem to have permissions to request a review. Probably need an invite to join the github organization.

@pkos98
Copy link

pkos98 commented Dec 22, 2025

image

Geese admirer here:

  • Testing this PR immediately shows a regression: one LLM response is now split into several messages. Have you actually tested your PR?
  • Also, looking at the code, it destroys basic formatting.

IMO more work is needed before one of the main contributors spends their valuable time reviewing this.

@rabi
Copy link
Contributor Author

rabi commented Dec 22, 2025

Testing this PR immediately shows a regression: one LLM response is now split into several messages.

What model are you testing with? I don't see any such issue.

image

@pkos98
Copy link

pkos98 commented Dec 22, 2025

I've tested using gemini-2.0-flash (as well as gemini-3-flash-preview after merging #6187)

@rabi
Copy link
Contributor Author

rabi commented Dec 22, 2025

I've tested using gemini-2.0-flash (as well as gemini-3-flash-preview after merging #6187)

Here is what I see with gemini-2.0 flash. Are you using cli, web or some third-party UI?

$ GOOSE_PROVIDER=google GOOSE_MODEL=gemini-2.0-flash  ./target/debug/goose session
starting session | provider: google model: gemini-2.0-flash
    session id: 20251222_55
    working directory: /home/ramishra/work/LLM/goose

goose is running! Enter your instructions, or try asking what goose can do.

Context: ○○○○○○○○○○ 0% (0/1000000 tokens)
( O)> can you write a 100 line poem about anything?

The clock ticks on, a steady beat,
In shadows deep, where secrets meet.
A world unseen, a whispered dream,
Reflects within a moonlit stream.

The wind it sighs through barren trees,
A symphony of rustling pleas.
The stars ignite, a distant fire,
A cosmic dance of pure desire.

The mountains rise, in silent grace,
A timeless watch upon this place.
The valleys sleep, in velvet dark,
Awaiting dawn's ascending spark.

The ocean roars, a restless soul,
Its waves crash on, beyond control.
The sandy shore, a fragile line,
Where water meets the fading shine.

A single bird, in lonely flight,
Across the canvas of the night.
Its mournful call, a haunting sound,
As echoes softly drift around.

The city sleeps, a concrete maze,
Where neon lights begin to blaze.
A hidden world, of hopes and fears,
Reflected in a million tears.

The poet's pen, it starts to flow,
With words that dance, and softly glow.
A tapestry of thoughts unfolds,
A story that the heart beholds.

The moon ascends, a silver sphere,
Dispelling darkness, calming fear.
A gentle light, upon the land,
A guiding hand, a helping hand.

The world awakes, in gentle hues,
As morning light the dark subdues.
A new beginning, fresh and bright,
A promise whispered in the light.

The poem ends, the words take flight,
A fleeting glimpse, into the night.
A memory held, a moment shared,
A world of wonder, now declared.


⏱️  Elapsed time: 4.09s
Context: ○○○○○○○○○○ 1% (5118/1000000 tokens)

@pkos98
Copy link

pkos98 commented Dec 22, 2025

Only tested the desktop electron app (just run-ui # or just make-ui).
Thanks for having a look!

@rabi
Copy link
Contributor Author

rabi commented Dec 23, 2025

Only tested the desktop electron app (just run-ui # or just make-ui). Thanks for having a look!

Right, I noticed that desktop UI aggregates streaming chunks into a single message bubble with metadata (timestamp, copy button, etc.) before rendering. It does this by matching message IDs which does not come in gemini response chunks (API does not povide it unlike other providers). I did not see the issue in cli as cli does not do any aggregation. I've fixed this by generating a consistent UUID at the start of each streaming session.

Also, can you elaborate what section of code you were referring to when you said "it destroys basic formatting"? This is all rustfmt checked.

- Add stream() and supports_streaming() to GoogleProvider
- Use streamGenerateContent?alt=sse endpoint for SSE streaming
- Implement response_to_streaming_message for SSE format parsing
- Handle text chunks, function calls, thinking content, and usage
- Add mid-stream error detection and propagation
- Trust thoughtSignature for thinking content classification
- Add tests for streaming text, function calls, and error handling

The Google/Gemini provider does not add a message ID to streaming
chunks, causing the desktop UI to display each chunk as a separate
message with its own timestamp instead of aggregating them.

The desktop UI aggregates streaming chunks by matching message IDs.
Other providers (OpenAI, Anthropic) get IDs from their APIs, but
Gemini's API doesn't provide one. We now generate a UUID at stream
start and use it for all chunks in that session.

Signed-off-by: rabi <[email protected]>
@pkos98
Copy link

pkos98 commented Dec 23, 2025

Looks like it's indeed working now (using gemini-3-flash-preview on desktop app).

Also, can you elaborate what section of code you were referring to when you said "it destroys basic formatting"? This is all rustfmt checked.

I just quickly compared some indention in the diff and it looked off, I re-compared and it's looking better now

rabi added a commit to rabi/goose that referenced this pull request Jan 7, 2026
OpenRouter with Gemini models now properly handles thoughtSignature:
- Use Google format for creating requests to include thoughtSignature
- Use Google format for parsing responses to extract thoughtSignature
- This enables proper thinking content echoing in the conversation loop
- Disable streaming for Google models until PR block#6191 is merged

Signed-off-by: rabi <[email protected]>
@rabi
Copy link
Contributor Author

rabi commented Jan 7, 2026

Folks PTAL. This would help us implement streaming in other providers like Vertex AI and OpenRouter etc.

@jamadeo jamadeo self-requested a review January 7, 2026 17:45
Copy link
Collaborator

@jamadeo jamadeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for the contribution!

I also ran test_providers.sh for gemini, and it passed.

@alexhancock
Copy link
Collaborator

Nice

@alexhancock alexhancock merged commit a4c7a74 into block:main Jan 7, 2026
18 checks passed
zanesq added a commit that referenced this pull request Jan 8, 2026
* 'main' of github.com:block/goose:
  Fixed fonts (#6389)
  Update confidence levels prompt injection detection to reduce false positive rates (#6390)
  Add ML-based prompt injection detection  (#5623)
  docs: update custom extensions tutorial (#6388)
  fix ResultsFormat error when loading old sessions (#6385)
  docs: add MCP Apps tutorial and documentation updates (#6384)
  changed z-index to make sure the search highlighter does not appear on modal overlay (#6386)
  Handling special claude model response in github copilot provider (#6369)
  fix: prevent duplicate rendering when tool returns both mcp-ui and mcp-apps resources (#6378)
  fix: update MCP Apps _meta.ui.resourceUri to use nested format (SEP-1865) (#6372)
  feat(providers): add streaming support for Google Gemini provider (#6191)
  Blog: edit links in mcp apps post (#6371)
  fix: prevent infinite loop of tool-input notifications in MCP Apps (#6374)
michaelneale added a commit that referenced this pull request Jan 8, 2026
* main: (31 commits)
  added validation and debug for invalid call tool result (#6368)
  Update MCP apps tutorial: fix _meta structure and version prereq (#6404)
  Fixed fonts (#6389)
  Update confidence levels prompt injection detection to reduce false positive rates (#6390)
  Add ML-based prompt injection detection  (#5623)
  docs: update custom extensions tutorial (#6388)
  fix ResultsFormat error when loading old sessions (#6385)
  docs: add MCP Apps tutorial and documentation updates (#6384)
  changed z-index to make sure the search highlighter does not appear on modal overlay (#6386)
  Handling special claude model response in github copilot provider (#6369)
  fix: prevent duplicate rendering when tool returns both mcp-ui and mcp-apps resources (#6378)
  fix: update MCP Apps _meta.ui.resourceUri to use nested format (SEP-1865) (#6372)
  feat(providers): add streaming support for Google Gemini provider (#6191)
  Blog: edit links in mcp apps post (#6371)
  fix: prevent infinite loop of tool-input notifications in MCP Apps (#6374)
  fix: Show platform-specific keyboard shortcuts in UI (#6323)
  fix: we load extensions when agent starts so don't do it up front (#6350)
  docs: credit HumanLayer in RPI tutorial (#6365)
  Blog: Goose Lands MCP Apps (#6172)
  Claude 3.7 is out. we had some harcoded stuff (#6197)
  ...
wpfleger96 added a commit that referenced this pull request Jan 9, 2026
* main: (89 commits)
  fix(google): treat signed text as regular content in streaming (#6400)
  Add frameDomains and baseUriDomains CSP support for MCP Apps (#6399)
  fix(ci): add missing dependencies to openapi-schema-check job (#6367)
  feat: http proxy support
  Add support for changing working dir and extensions in same window/session (#6057)
  Sort keys in canonical models (#6403)
  added validation and debug for invalid call tool result (#6368)
  Update MCP apps tutorial: fix _meta structure and version prereq (#6404)
  Fixed fonts (#6389)
  Update confidence levels prompt injection detection to reduce false positive rates (#6390)
  Add ML-based prompt injection detection  (#5623)
  docs: update custom extensions tutorial (#6388)
  fix ResultsFormat error when loading old sessions (#6385)
  docs: add MCP Apps tutorial and documentation updates (#6384)
  changed z-index to make sure the search highlighter does not appear on modal overlay (#6386)
  Handling special claude model response in github copilot provider (#6369)
  fix: prevent duplicate rendering when tool returns both mcp-ui and mcp-apps resources (#6378)
  fix: update MCP Apps _meta.ui.resourceUri to use nested format (SEP-1865) (#6372)
  feat(providers): add streaming support for Google Gemini provider (#6191)
  Blog: edit links in mcp apps post (#6371)
  ...
wpfleger96 added a commit that referenced this pull request Jan 9, 2026
* main: (89 commits)
  fix(google): treat signed text as regular content in streaming (#6400)
  Add frameDomains and baseUriDomains CSP support for MCP Apps (#6399)
  fix(ci): add missing dependencies to openapi-schema-check job (#6367)
  feat: http proxy support
  Add support for changing working dir and extensions in same window/session (#6057)
  Sort keys in canonical models (#6403)
  added validation and debug for invalid call tool result (#6368)
  Update MCP apps tutorial: fix _meta structure and version prereq (#6404)
  Fixed fonts (#6389)
  Update confidence levels prompt injection detection to reduce false positive rates (#6390)
  Add ML-based prompt injection detection  (#5623)
  docs: update custom extensions tutorial (#6388)
  fix ResultsFormat error when loading old sessions (#6385)
  docs: add MCP Apps tutorial and documentation updates (#6384)
  changed z-index to make sure the search highlighter does not appear on modal overlay (#6386)
  Handling special claude model response in github copilot provider (#6369)
  fix: prevent duplicate rendering when tool returns both mcp-ui and mcp-apps resources (#6378)
  fix: update MCP Apps _meta.ui.resourceUri to use nested format (SEP-1865) (#6372)
  feat(providers): add streaming support for Google Gemini provider (#6191)
  Blog: edit links in mcp apps post (#6371)
  ...
fbalicchia pushed a commit to fbalicchia/goose that referenced this pull request Jan 13, 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.

4 participants