Skip to content

fix(#3996): drop gateway SSE keepalive frames before the genai parser - #4022

Draft
aheritier wants to merge 2 commits into
title-generation-model-filterfrom
gemini-gateway-transport
Draft

fix(#3996): drop gateway SSE keepalive frames before the genai parser#4022
aheritier wants to merge 2 commits into
title-generation-model-filterfrom
gemini-gateway-transport

Conversation

@aheritier

@aheritier aheritier commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

What

Filters gateway SSE keepalive frames before they reach the Gemini genai parser, while retaining normal response events.

Why

Gateway transport heartbeats are not model events and can otherwise cause parser failures or corrupt streaming behavior.

Validation

task test; HTTP SSE filter and Gemini transport tests.

Test instructions

Run:

task test

Stream a Gemini response containing gateway SSE keepalive frames followed by content and a terminal event. Expected: keepalive frames are discarded before parsing, content remains intact, and the stream terminates normally.

@aheritier aheritier added area/providers/gemini Google Gemini provider support kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Aug 22, 2026
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from 30bb441 to 01ecbc9 Compare August 24, 2026 15:13
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from 01ecbc9 to c3771e3 Compare August 25, 2026 07:58
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from c3771e3 to e69c90a Compare August 25, 2026 20:24
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from e69c90a to c064d65 Compare August 26, 2026 11:08
@aheritier
aheritier force-pushed the gemini-gateway-transport branch 2 times, most recently from 2aeb274 to c064d65 Compare September 1, 2026 16:16
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from c064d65 to a4ac3c3 Compare September 1, 2026 16:29
aheritier

This comment was marked as resolved.

@aheritier
aheritier force-pushed the gemini-gateway-transport branch from a4ac3c3 to cb11ede Compare September 6, 2026 16:14
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from cb11ede to b6673c4 Compare September 7, 2026 11:19
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from b6673c4 to 5f3d225 Compare September 7, 2026 11:34
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from 5f3d225 to 2a91635 Compare September 7, 2026 16:13
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from 2a91635 to 0c7381a Compare September 7, 2026 16:47
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from 0c7381a to d4c26ba Compare September 8, 2026 06:17
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from d4c26ba to d5981c4 Compare September 8, 2026 07:57
Capture actual GenerateContentStream JSON on gateway and direct Gemini API.
Use a populated private catalogue to assert omitted/empty declaration
resolution, explicit false precedence, unknown-off behavior, explicit true,
and utility omission. Reject incompatible request shapes before dispatch.

Test the resolved-capability predicate for gateway, direct API, Vertex AI,
and unknown/empty surfaces. Vertex coverage here is the predicate, not a
captured Vertex wire request or live provider call. All fixtures use local
servers and require no provider credentials or generated image response.
During long generations (e.g. Gemini image output) the Docker AI Gateway
emits `event: keepalive` + `data: {}` frames. google.golang.org/genai
treats any `event:` line as a fatal invalid stream chunk, so a single
keepalive killed the whole stream.

Add an opt-in httpclient.WithSSEKeepaliveFilter that makes the shared SSE
filter transport also drop payload-free keepalive frames, and enable it
only on the Gemini gateway HTTP client. The shared default path is
unchanged: Anthropic-style named events with meaningful data still pass
through verbatim, and only the gateway surface — never direct
Gemini/Vertex — gets the new behavior.
@aheritier
aheritier force-pushed the gemini-gateway-transport branch from d5981c4 to 601da3b Compare September 8, 2026 17:31
@aheritier aheritier added the status/needs-rebase PR has merge conflicts or is out of date with main label Sep 8, 2026
@aheritier

Copy link
Copy Markdown
Collaborator Author

👋 This PR has merge conflicts with the base branch. Please rebase or merge the latest base branch and resolve them. I've moved it to draft and added status/needs-rebase; it'll be picked back up automatically once the conflicts are cleared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/providers/gemini Google Gemini provider support kind/fix PR fixes a bug (maps to fix:). Use on PRs only. status/needs-rebase PR has merge conflicts or is out of date with main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant