llm proxy: add --disable-streaming flag to force stream:false for clients that don't handle SSE
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2.2k
- Forks
- 300
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 184
Description
Summary
thv llm proxy start cannot be used as a drop-in backend for Gemini CLI because Gemini CLI sends requests in native Gemini API format, which is incompatible with the AI gateway's OpenAI-compatible endpoint.
Root Cause (discovered via debugging)
When GOOGLE_GEMINI_BASE_URL is set, Gemini CLI sends requests to:
POST /v1beta/models/gemini-2.5-flash-lite:generateContent
{"contents":[{"parts":[{"text":"..."}]}]}
The AI gateway only accepts:
POST /v1/chat/completions
{"model":"...","messages":[{"role":"user","content":"..."}]}
These are fundamentally different protocols. The proxy cannot bridge this gap without implementing a full Gemini↔OpenAI request/response translation layer.
What was investigated
During debugging, several proxy-level fixes were attempted and partially implemented:
- Path rewriting:
/v1beta/openai/...→/v1/...(works for some requests but not the main chat path) --disable-streamingflag: strips/replacesdata: [DONE]sentinel from SSE responses (valid fix for OpenAI-compatible clients that mishandle SSE, but doesn't address the protocol mismatch)- Forcing
stream:falsefor requests without an explicitstreamfield (valid for OpenAI-compatible clients sending non-streaming requests)
The [DONE] JSON parse error seen in earlier testing was a symptom of a different request path (generateJson in NumericalClassifierStrategy), not the main chat stream.
Real fix options
-
Gateway level (preferred): The AI gateway should accept native Gemini API paths (
/v1beta/models/{model}:generateContent) and translate them to its backend format. This makes the gateway a true drop-in replacement forgenerativelanguage.googleapis.com. -
Translation layer in proxy: Add a full Gemini↔OpenAI translation layer to
thv llm proxy. Significant complexity — different request schema, response schema, streaming format, error format, tool call format. -
Gemini CLI configuration: If Gemini CLI supports an OpenAI-compatible mode (some versions do via a different URL/auth configuration), configure it to send OpenAI-format requests instead of native Gemini format.
Related
- The
--disable-streamingflag implemented during this investigation is still useful for OpenAI-compatible clients (e.g. Cursor, VS Code extensions) that don't handle SSE[DONE]correctly. That work should be kept.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the thv llm proxy start command entry point and trace its existing request and streaming-response handling. Confirm the intended --disable-streaming behavior for OpenAI-compatible clients, including forcing stream:false where applicable and handling the SSE [DONE] sentinel; the Gemini protocol mismatch is out of scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100