feat(gemini): ship gemini_oauth plugin + fix Code Assist streaming#523
Open
chucky5o wants to merge 1 commit into
Open
feat(gemini): ship gemini_oauth plugin + fix Code Assist streaming#523chucky5o wants to merge 1 commit into
chucky5o wants to merge 1 commit into
Conversation
model_factory.py already references code_puppy.plugins.gemini_oauth for
the "gemini_oauth" model type, but the plugin was never shipped. This adds
it, so Gemini models work through the local Gemini/Antigravity CLI's OAuth
login (~/.gemini/oauth_creds.json) with no API key.
The plugin exposes the three symbols model_factory expects:
- GEMINI_OAUTH_CONFIG (Code Assist base URL + version)
- get_valid_access_token() — reads ~/.gemini/oauth_creds.json,
auto-refreshes expired tokens, writes back with chmod 600
- get_project_id() — discovers the managed GCP project via the
loadCodeAssist API and caches it
OAuth client credentials (the public installed-app values from the Gemini
CLI) are read from GEMINI_OAUTH_CLIENT_ID / GEMINI_OAUTH_CLIENT_SECRET env
vars rather than hardcoded, so no secret is committed. The README explains
how to extract them from a local gemini install to enable auto-refresh.
Also fixes two bugs in gemini_code_assist.py that broke streaming (the
default path the agent runtime uses):
- request_stream() was missing the run_context parameter the runtime
passes, raising "takes 4 positional arguments but 5 were given"
- the streaming response class didn't inherit from pydantic_ai's
StreamedResponse ABC, so the runtime hit "'StreamedResponse' object
has no attribute 'get'". Replaced with CodeAssistStreamedResponse
(a proper @DataClass subclass implementing _get_event_iterator).
Docs: adds docs/LOCAL_PROVIDERS.md (how to wire Ollama, Claude Code, and
Gemini/Antigravity from their local CLIs) and a plugin README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
|
Please make linters + tests pass and remove claude code authorship |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
model_factory.pyalready referencescode_puppy.plugins.gemini_oauthfor thegemini_oauthmodel type, but the plugin was never shipped — so that modeltype is a dangling import today. This PR ships the plugin and fixes two
streaming bugs, letting users run Gemini models through their local
Gemini / Antigravity CLI's existing OAuth login — no API key.
Changes
1. New
gemini_oauthplugin (code_puppy/plugins/gemini_oauth/)Reuses the token the Gemini CLI stores at
~/.gemini/oauth_creds.jsonand callsthe Code Assist API (
cloudcode-pa.googleapis.com). Exposes the three symbolsmodel_factoryexpects:GEMINI_OAUTH_CONFIG— Code Assist base URL + API versionget_valid_access_token()— reads the CLI creds, auto-refreshes when expired, writes backchmod 600get_project_id()— discovers the managed GCP project vialoadCodeAssistand caches itClient credentials (the public installed-app values from the Gemini CLI) are read
from
GEMINI_OAUTH_CLIENT_ID/GEMINI_OAUTH_CLIENT_SECRETenv vars — nosecret is committed. The plugin README explains how to extract them from a
local
geminiinstall to enable auto-refresh.2. Fix streaming in
gemini_code_assist.pyTwo bugs broke the streaming path (which is what the agent runtime uses by default):
request_stream()was missing therun_contextparameter the runtime passes→
TypeError: takes 4 positional arguments but 5 were givenStreamedResponseABC →
'StreamedResponse' object has no attribute 'get'. Replaced withCodeAssistStreamedResponse, a proper@dataclasssubclass implementing_get_event_iterator()(mirrors the existingGeminiStreamingResponse).3. Docs
docs/LOCAL_PROVIDERS.md— how to wire Ollama, Claude Code, andGemini/Antigravity from their local CLIs, all switchable via
/model.code_puppy/plugins/gemini_oauth/README.md— plugin setup + troubleshooting.Testing
Verified end-to-end through the
code-puppyCLI against a real account:/model antigravity-flash→ livegenerateContentcall returns a response~/.gemini/oauth_creds.jsonworksloadCodeAssistand cachedNotes for the maintainer
~/.code_puppy/extra_models.json(not committed).vars, that's a one-line change — I used env vars to keep secret scanners happy.
🤖 Generated with Claude Code