Skip to content

feat: support custom base_url for Gemini native adapter#21747

Open
li0near wants to merge 1 commit into
NousResearch:mainfrom
li0near:fix/gemini-custom-base-url
Open

feat: support custom base_url for Gemini native adapter#21747
li0near wants to merge 1 commit into
NousResearch:mainfrom
li0near:fix/gemini-custom-base-url

Conversation

@li0near

@li0near li0near commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

When provider: "gemini" is explicitly configured, use the native Gemini REST adapter (models/{model}:generateContent) for any base_url that doesn't end in /openai — matching how other providers work unconditionally in _create_openai_client().

Gemini was the only provider with a domain-based gate:

Provider Client creation Gated?
copilot-acp CopilotACPClient No
google-gemini-cli GeminiCloudCodeClient No
gemini GeminiNativeClient Yes (relaxed by this PR)
openai/custom OpenAI() No
anthropic build_anthropic_client() No

Problem

Previously, is_native_gemini_base_url() checked for generativelanguage.googleapis.com in the URL before using the native adapter. With a custom base_url (e.g. a local proxy that speaks Gemini's native REST protocol), the check would fail and silently fall through to the OpenAI-compatible client — sending /v1/chat/completions format instead of /models/{model}:generateContent.

Fix

Replaced the domain-based is_native_gemini_base_url() check with a simpler /openai suffix check:

# Before:
if is_native_gemini_base_url(base_url):  # requires googleapis.com domain

# After:
if not base_url.rstrip('/').lower().endswith('/openai'):  # only skip for OpenAI-compat endpoints
  • Any base_url (including custom proxies) → native Gemini adapter
  • URLs ending in /openai (e.g. generativelanguage.googleapis.com/v1beta/openai) → OpenAI client (these speak OpenAI format)
  • Empty base_url → native adapter (defaults to Google's endpoint internally)

Example config (cli-config.yaml)

model:
  default: "gemini-2.5-flash"
  provider: "gemini"
  base_url: "http://localhost:8900/gemini"
  api_key: "your-proxy-api-key"

Test plan

  • Updated test_gemini_custom_base_url to assert native client is used
  • test_gemini_openai_compat_base_url_keeps_openai_client unchanged (verifies /openai suffix fallback)
  • Verify provider: "gemini" with no base_url still defaults to Google's endpoint
  • Verify provider: "gemini" with custom base_url uses native adapter
  • Verify other providers are unaffected

@li0near li0near force-pushed the fix/gemini-custom-base-url branch 2 times, most recently from 4078f6c to 7f4c3ef Compare May 8, 2026 08:01
@alt-glitch alt-glitch added type/feature New feature or request provider/gemini Google Gemini (AI Studio, Cloud Code) comp/agent Core agent loop, run_agent.py, prompt builder P3 Low — cosmetic, nice to have labels May 8, 2026
@li0near li0near force-pushed the fix/gemini-custom-base-url branch 2 times, most recently from 1b8da05 to 49a5e27 Compare May 8, 2026 08:53
When provider is explicitly set to "gemini", use the native Gemini REST
adapter for any base_url that doesn't end in /openai — matching how
other providers (Anthropic, OpenAI, Copilot) work unconditionally.

Previously, is_native_gemini_base_url() gated the native adapter on
the presence of "generativelanguage.googleapis.com" in the URL. This
made Gemini the only provider with a domain-based gate in
_create_openai_client(). With a custom base_url (e.g. a local proxy),
the domain check would fail and silently fall through to the OpenAI-
compatible client, sending the wrong request format to endpoints
expecting Gemini's native models/{model}:generateContent REST API.

URLs ending in /openai (e.g. generativelanguage.googleapis.com/v1beta/
openai) continue to fall through to the OpenAI client, as those
endpoints speak OpenAI format by design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P3 Low — cosmetic, nice to have provider/gemini Google Gemini (AI Studio, Cloud Code) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants