feat(llm): native Google Gemini provider via OpenAI-compatible endpoint#57
Merged
elder-plinius merged 1 commit intoJul 9, 2026
Merged
Conversation
Add a first-class `gemini` provider so operators can drive missions with a direct GEMINI_API_KEY, instead of only reaching Gemini through OpenRouter. Gemini is wired exactly like xAI: dispatched through OpenAIAdapter against Google's OpenAI-compatible surface. The base URL is https://generativelanguage.googleapis.com/v1beta/openai — the `/openai` segment is required because OpenAIAdapter posts to `${baseUrl}/chat/completions`; without it requests hit `/v1beta/chat/completions`, which Google does not serve. Wires the provider through the type union, adapter factory, config (interface, defaults, model catalog, key env map, getLLMConfig, fallback chain, redaction, .env template), and adds regression tests pinning the `/openai` base-URL segment.
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.
Fixes #52.
What's broken
src/config/index.tsadvertisesprovider: 'Google'Gemini models, but there is no way to actually run Gemini with a direct key:'google'/'gemini'isn't a member of theLLMProviderunion andcreateAdapter()has no matching case, so it falls through todefault → throw "Unknown LLM provider". Setting a Gemini key just leaves LLM features disabled. (Thegoogle/gemini-*ids underopenrouterdo work — but only through an OpenRouter key, not a direct Gemini key.)The fix
Add a first-class
geminiprovider, wired exactly like the existing xAI provider: dispatched throughOpenAIAdapteragainst Google's OpenAI-compatible surface. No new adapter class needed.The one detail that matters: the base URL is
https://generativelanguage.googleapis.com/v1beta/openai.OpenAIAdapterposts to`${baseUrl}/chat/completions`, so the/openaipath segment is required — with a bare/v1betabase, requests resolve to/v1beta/chat/completions, which Google does not serve (that root is the nativegenerateContentREST API, not the OpenAI shim). A regression test pins this exact path.Selection:
LLM_PROVIDER=gemini+GEMINI_API_KEY.Changes
src/types/index.ts— add'gemini'toLLMProvidersrc/llm/index.ts—case 'gemini' → OpenAIAdaptersrc/config/index.ts— interface, defaults (correct/v1beta/openaibase URL,gemini-2.5-flashdefault), native model catalog (bare ids),GEMINI_API_KEYenv map,getLLMConfig, fallback chain, redaction,.envtemplatesrc/__tests__/gemini-provider.test.ts— regression tests, including the/openaibase-URL guardVerification
npm run typecheck— cleannpm test— 371 passing (34 files), incl. 4 new Gemini testsnpm run lint— 0 errorsRelation to existing PRs
This overlaps #55 and #45, which also add Gemini. It differs deliberately: #55 sets the base URL to
.../v1beta(missing/openai), so OpenAI-shaped calls would hit an endpoint Google doesn't serve; #45 introduces a LiteLLM gateway (a larger architectural dependency). This PR is the minimal native fix that matches the repo's existing xAI OpenAI-compat pattern. Happy to close in favor of either if a maintainer prefers that direction — flagging the base-URL detail regardless, since it's easy to miss.