Skip to content

Add Google Gemini API provider (via LiteLLM proxy) - #272

Open
zwanski-start wants to merge 2 commits into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-94-barbara
Open

zwanski-start wants to merge 2 commits into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-94-barbara

Conversation

@zwanski-start

Copy link
Copy Markdown

Closes #94

What changed

Adds Google Gemini as a selectable API provider, built on the existing provider system (API_PROVIDERS in registry.py → get_effective_sdk_env()). That is the provider abstraction the issue asks for, so no new layer was added.

AutoForge runs every agent through the Claude Agent SDK / Claude Code CLI, which only speaks the Anthropic Messages API. Gemini has no Anthropic-compatible endpoint (Google only offers native and OpenAI-compatible APIs). So the new provider sends requests to a LiteLLM proxy, which translates /v1/messages into Gemini calls.

  • registry.py: new gemini provider. Default base URL is http://localhost:4000, the proxy master key is sent as ANTHROPIC_AUTH_TOKEN (so a real ANTHROPIC_API_KEY is cleared and never reaches the proxy), and the models are gemini-2.5-pro (default) and gemini-2.5-flash.
  • SettingsView.tsx / SettingsModal.tsx: info text for Gemini. The base URL field and the custom-model input are shown, because proxy host and model_name aliases vary per setup.
  • examples/litellm_gemini_config.yaml: a ready-to-run proxy config (drop_params: true so Anthropic-only fields don't fail requests).
  • README.md / CLAUDE.md: setup steps.
  • test_api_providers.py: tests that the Gemini settings map to the right SDK env vars (defaults and overrides).

Verification

  • pytest test_api_providers.py: 3 passed. ruff check . is clean, mypy is clean, and python test_security.py passes.
  • npm run lint shows 0 errors (the 6 warnings were already there). npm run build succeeds.
  • Ran the backend with an isolated HOME on port 5443 and opened Settings in Playwright. "Google Gemini" appears in the provider list. Selecting it fills in the base URL http://localhost:4000, shows the API key field, both Gemini models and the custom model input.
  • Not tested: a full agent session against a live Gemini key and LiteLLM proxy. No credentials were available.

Assumptions / notes

  • LiteLLM was chosen because it is the most widely used Anthropic→Gemini translation proxy. Any other Anthropic-compatible proxy also works by changing the base URL.
  • Gemini's tool-use behaviour under Claude Code's prompts is not tuned. The README says to expect lower pass rates than with Claude.
  • Assistant, spec and expand chats use the same get_effective_sdk_env(), so they also follow the provider setting.

🤖 Generated with Claude Code

zwanski-start and others added 2 commits October 22, 2026 07:05
Gemini has no Anthropic Messages API, so the new 'gemini' provider points
the Claude Agent SDK at an Anthropic-compatible LiteLLM proxy (default
http://localhost:4000) using ANTHROPIC_AUTH_TOKEN. The Settings UI shows
the base URL and custom model input for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zwanski-start

Copy link
Copy Markdown
Author

🔍 QA report: ✅ Passed

Tester: Dennis (cubefarm agent, in a fresh session) · Round: 1 · Author: Barbara

Adds Google Gemini as an API provider, reached through a LiteLLM proxy and built on the existing API_PROVIDERS / get_effective_sdk_env() system. Choosing it sets the base URL to http://localhost:4000 and the default model to gemini-2.5-pro, and sends the proxy key as ANTHROPIC_AUTH_TOKEN while clearing ANTHROPIC_API_KEY and the Vertex variables. I checked this through the REST API, the SDK env output and the Settings UI in a real browser; tests, ruff, the UI build and lint pass, and mypy shows the same 24 errors as master. A live Gemini agent run and the e2e suite were not run (no credentials; the Playwright browser download was stuck on a cache lock).

Check Details
✅ Issue: Gemini usable as an LLM backend behind the provider abstraction The new 'gemini' entry in API_PROVIDERS uses the existing get_effective_sdk_env() path, which agents and the assistant/spec/expand chats already use. With provider=gemini the SDK env is ANTHROPIC_BASE_URL=http://localhost:4000, ANTHROPIC_AUTH_TOKEN set, ANTHROPIC_API_KEY='' and the Vertex vars cleared, with all three ANTHROPIC_DEFAULT_*_MODEL set to the chosen model.
✅ Settings API: switching provider and validation /api/settings/providers lists gemini with both models. PATCH api_provider=gemini auto-set api_base_url=http://localhost:4000 and api_model=gemini-2.5-pro. api_base_url='ftp://x' got a 422. The auth token never appears in responses or the server log.
✅ Settings UI: Gemini provider in the browser The Google Gemini button shows the LiteLLM info text, API key field, base URL http://localhost:4000, the Gemini 2.5 Pro/Flash buttons and the custom model input. Setting the custom model 'gemini-2.5-flash-lite' and changing the base URL to http://127.0.0.1:4001 both saved (confirmed through GET /api/settings). No console errors or warnings.
✅ Responsive layout at 390px The provider section still renders and works at phone width. The page is squeezed because the sidebar doesn't collapse on narrow screens; that predates this PR and isn't caused by it.
⏭️ SettingsModal.tsx change It is the same change as in SettingsView, but SettingsModal isn't rendered anywhere in the app, so it was only checked by the TypeScript build.
✅ Security, database and path regressions No changes to security.py, the localhost-only middleware, the database schema or subprocess handling. No hardcoded OS paths. The existing credential-clearing logic covers the new provider.
✅ Example LiteLLM config examples/litellm_gemini_config.yaml parses as YAML; its model_name aliases match the provider's model IDs.
⏭️ UI e2e suite The Playwright Chromium binary was missing and playwright install hung for over 13 minutes on the shared ~/.cache/ms-playwright lock (probably held by another session), so I stopped it. Not related to this change; neither existing spec (conversation-history, tooltip) touches Settings.
⏭️ Live Gemini agent session through a LiteLLM proxy No Gemini credentials or proxy available, and QA must not depend on paid API calls. The env mapping is covered by unit tests and checked by hand instead.
🧪 Commands run
Command Result
ruff check . All checks passed
mypy . 24 errors in 9 files; master (throwaway worktree) has the same 24, none in files this PR changes
python -m pytest -q test_api_providers.py test_client.py test_dependency_resolver.py test_rate_limit_utils.py 58 passed
python test_security.py ALL TESTS PASSED
python test_security_integration.py ALL INTEGRATION TESTS PASSED
npm --prefix ui run build tsc -b && vite build succeeded
npm --prefix ui run lint 0 errors, 6 warnings (already on master)
HOME=<scratch> uvicorn server.main:app --host 127.0.0.1 --port 5247 + curl GET/PATCH /api/settings, /api/settings/providers, /api/projects 200s; invalid base URL gave 422; token not echoed or logged
python -c 'from registry import get_effective_sdk_env; ...' (provider=gemini) correct ANTHROPIC_* env mapping; API key cleared
VITE_API_PORT=5247 CI=1 npx playwright test (ui) not run: Chromium binary missing; install hung on a shared cache lock and was stopped

No browser screenshots were taken in this round.

Posted by cubefarm · merges automatically once GitHub's checks pass

cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 8, 2026
Adaptations: manual merge with AutoForgeAI#241 — test_api_providers.py keeps both the GLM
tests and the Gemini tests; the Settings base-URL / custom-model fields show for
GLM and Gemini.

Integrates AutoForgeAI#272

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 8, 2026
… keys and URLs

Adaptations:
- manual merge with AutoForgeAI#241/AutoForgeAI#272 (provider lists, test file, Settings texts);
- the Base URL field now shows for Moonshot too (its help text asks China users
  to change the URL, which the UI did not allow);
- a provider switch also clears the saved auth token: base URL and token are
  global settings shared by every provider, so the previous provider's secret
  key was sent to the new provider's server (and the UI showed it as set).
  test_settings_provider_switch covers the router.

Integrates AutoForgeAI#308

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
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.

Feature request: Support Google Gemini as an LLM backend

1 participant