Skip to content

feat(openab-agent): add Google Gemini provider (API key)#6

Open
Joseph19820124 wants to merge 2 commits into
mainfrom
feat/gemini-provider-only
Open

feat(openab-agent): add Google Gemini provider (API key)#6
Joseph19820124 wants to merge 2 commits into
mainfrom
feat/gemini-provider-only

Conversation

@Joseph19820124
Copy link
Copy Markdown
Owner

What

Adds a Google Gemini provider to openab-agent, mirroring the existing AnthropicProvider API-key pattern.

The Gemini provider

GeminiProvider in openab-agent/src/llm.rs, modeled exactly on AnthropicProvider:

  • Credentials: from_env() reads GEMINI_API_KEY, falling back to GOOGLE_API_KEY — same shape as AnthropicProvider reading ANTHROPIC_API_KEY. No OAuth.
  • Format mapping: internal Anthropic-shaped Message/ContentBlock → Gemini generateContent: role assistantmodel, tool_usefunctionCall, tool_resultfunctionResponse.
  • Two impedance mismatches handled:
    • Gemini keys a functionResponse by function name, not an id → recovered from the originating tool_use (gemini_tool_name).
    • Gemini functionCalls carry no id → a stable call_<name>_<idx> id is synthesized so the agent loop can pair the eventual tool_result back.
  • Retries: 429 / 503 with exponential backoff, like the other providers.
  • Wiring (acp.rs): explicit OPENAB_AGENT_PROVIDER=gemini/google, plus auto-detect chain Anthropic key → Gemini key → Codex OAuth; error message updated.
  • Config: OPENAB_AGENT_MODEL (default gemini-2.0-flash), OPENAB_AGENT_GEMINI_BASE_URL.

Tests & checks

  • cargo test30 passed / 0 failed (5 new Gemini tests: role mapping, tool_result keyed-by-name, error field, parse text/functionCall, error envelope).
  • cargo build, cargo fmt --check, cargo clippy — clean (Gemini code: 0 warnings).
  • docs/native-agent.md updated (env-var table + auth section).

Scope

base = upstream-main (a pinned snapshot of current openabdev/openab@main), so the diff is exactly the single Gemini commit — independent of the Agent Skills PR (does not contain skills code).

🤖 Generated with Claude Code

@github-actions github-actions Bot added closing-soon pending-screening PR awaiting automated screening labels May 31, 2026
@github-actions
Copy link
Copy Markdown

⚠️ This PR is missing a Discord Discussion URL in the body.

All PRs must reference a prior Discord discussion to ensure community alignment before implementation.

Please edit the PR description to include a link like:

Discord Discussion URL: https://discord.com/channels/...

This PR will be automatically closed in 3 days if the link is not added.

@Joseph19820124 Joseph19820124 added enhancement New feature or request documentation Improvements or additions to documentation labels May 31, 2026
@Joseph19820124
Copy link
Copy Markdown
Owner Author

Updated: ported Gemini 3.x thoughtSignature handling from the parallel feat/gemini-provider branch into this contained impl, and bumped the default model to gemini-2.5-flash.

  • thought_signature: Option<String> added to ContentBlock::ToolUse / LlmEvent::ToolUse (serde-skipped when None; inert for Anthropic/OpenAI).
  • Captured in parse_gemini_response, threaded through the agent loop, echoed back on the functionCall part. Gemini 3.x rejects multi-turn tool calls without it; ≤2.5 ignores it.
  • Auth kept as x-goog-api-key header (not ?key= query param), GOOGLE_API_KEY fallback and configurable base URL retained.

cargo test 26 passed / 0 failed (incl. 2 new thoughtSignature tests); fmt clean; Gemini code clippy-clean.

Joseph Chen and others added 2 commits May 31, 2026 14:26
Mirror the AnthropicProvider API-key pattern for Google Gemini:

- GeminiProvider::from_env() reads GEMINI_API_KEY (falls back to
  GOOGLE_API_KEY), mirroring AnthropicProvider's ANTHROPIC_API_KEY path.
- Maps our Anthropic-shaped Message/ContentBlock model onto Gemini's
  generateContent format: role assistant->model, tool_use->functionCall,
  tool_result->functionResponse. Gemini keys functionResponse by function
  NAME (not id), so the name is recovered from the originating tool_use;
  function-call ids are synthesized (call_<name>_<idx>) so the agent loop
  can still pair results back.
- Retries on 429/503 with exponential backoff, like the other providers.
- Wired into acp.rs provider selection: explicit 'gemini'/'google', plus
  the auto-detect chain (Anthropic key -> Gemini key -> Codex OAuth).
- Configurable via OPENAB_AGENT_MODEL (default gemini-2.0-flash) and
  OPENAB_AGENT_GEMINI_BASE_URL. Docs + 5 unit tests added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-flash

Ports the thoughtSignature handling from the parallel feat/gemini-provider
branch into this contained implementation:

- Add optional thought_signature to ContentBlock::ToolUse and
  LlmEvent::ToolUse (serde-skipped when None; no effect on other providers).
- parse_gemini_response captures the per-call thoughtSignature; the agent
  loop threads it onto the assistant ToolUse block; build_request_body
  echoes it back on the functionCall part. Gemini 3.x rejects multi-turn
  tool calls without this; <=2.5 ignores it.
- Bump default Gemini model 2.0-flash -> 2.5-flash (docs + code).
- 2 new tests (capture + echo); all existing provider sites updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Joseph19820124 Joseph19820124 force-pushed the feat/gemini-provider-only branch from 5f315b8 to ae44ea1 Compare May 31, 2026 14:30
@Joseph19820124 Joseph19820124 changed the base branch from upstream-main to main May 31, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request pending-maintainer pending-screening PR awaiting automated screening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant