Skip to content

feat(adk): native Gemini factory for Format=Gemini proxies - #693

Merged
tbolis-at-mulesoft merged 1 commit into
developfrom
feat/691-adk-native-gemini
Sep 29, 2026
Merged

tbolis-at-mulesoft merged 1 commit into
developfrom
feat/691-adk-native-gemini

Conversation

@tbolis-at-mulesoft

@tbolis-at-mulesoft tbolis-at-mulesoft commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #691

Summary

  • donkey.adk.gemini("gemini-2.5-flash", **kw) and the module-level donkey_kit.integrations.adk.gemini return ADK's native google.adk.models.Gemini, bound to a Format=Gemini proxy. The shared DonkeyAsyncClient is injected through HttpOptions.httpx_async_client (BG §1.8). gemini_connection_kwargs() is the manual-equivalent escape hatch. model() is unchanged (LiteLLM).
  • Core (§1.1, still framework-free):
    • core/transport.py reads the requested model from the Gemini URL path (models/<m>:generateContent|streamGenerateContent) when the body has none.
    • core/lastcall.py parses Gemini usageMetadata, both buffered and SSE.
    • Result: spans, usage, per-run correlation and last_call all work, and gemini() records no conformance exemption. The ADK KNOWN_LIMITATIONS rows are now scoped to model().
  • Live-verified 2026-09-29 against ddk-gemini-inbound (§0.3):
    • x-goog-api-key coexists with client_id/client_secret.
    • SSE streaming and tool calling work.
    • Bad secret → 401, which classifies as AuthError. Unknown model → Google's 404, which classifies as UpstreamRequestError, via classify(exc.response). The native APIError is not wrapped.
    • The gateway ignores a body model field.
    • Redacted fixtures were added under tests/fixtures/anypoint/gemini_inbound/.
  • verify_frameworks.py has a new adk.gemini row. The live check runs when DONKEY_GEMINI_PROXY_URL is set; it reported VERIFIED (LIVE) here.

Docs (ddk-docs-sync)

  • docs/verified-apis.md: the §2 Gemini row was re-probed and "no SDK adapter" removed; §8 has a new ADK-native-Gemini row, VERIFIED (LIVE). Maintainer sign-off on that row = approving this PR.
  • frameworks/adk.mdx has a new Native Gemini section: the three forms, the manual equivalent, base_url, which last_call fields stay None, reading last_call in after_model_callback, classify(exc.response), and one Donkey per event loop.
  • Also updated:
    • frameworks/index.mdx (Format mapping and injection table)
    • feature-overview, telemetry, reference/last-call, and examples/{adk,gemini}
    • both READMEs' exemption rows, ARCHITECTURE.md and CONTRIBUTING.md
    • python/examples/adk, the fixture README and the docstrings
    • website/public (regenerated)
  • examples/general/gateway-identity.mdx was left unchanged: it is captured demo output and is still accurate for model().

Test plan

  • pytest -q: 780 passed, 10 skipped
  • mypy, ruff check ., lint-imports (5/5 contracts kept)
  • verify_frameworks.py --only adk: both rows signature-confirmed offline; --only adk.gemini --live → VERIFIED (LIVE)
  • website: next build passes (61 pages)

Post-deploy steps

  • Acceptance repo: add test_adk_builds_a_native_gemini_model and its coverage.toml entry once a release containing gemini() is published (follow-up: Donkey-Development-Kit/donkey-development-kit-acceptance#10).
  • Known limitation, not new: the shared httpx pool is bound to its first event loop, so reusing one Donkey across asyncio.run calls fails. It is documented.
  • Rotate the ddk-gemini-inbound consumer pair used for the live run.

Add donkey.adk.gemini() and the module-level integrations.adk.gemini():
they return ADK's native google.adk.models.Gemini bound to a Format=Gemini
proxy, with the shared DonkeyAsyncClient injected via
HttpOptions.httpx_async_client (BG §1.8). model() stays on LiteLLM.

Core, so gemini() records no conformance exemption:
- transport: read the requested model from the Gemini URL path
  (models/<m>:generateContent|streamGenerateContent) when the body has none.
- lastcall: parse Gemini usageMetadata (buffered and SSE).

Live-verified 2026-09-29 against ddk-gemini-inbound (§0.3): x-goog-api-key
coexists with client_id/secret, streaming, tool calling, 401/404 refusals
(classify(exc.response)), body model ignored. Redacted fixtures added.
verify_frameworks gains an adk.gemini row (VERIFIED LIVE). Docs, ledger
(§2, §8), READMEs and website updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tbolis-at-mulesoft
tbolis-at-mulesoft merged commit 5de18e8 into develop Sep 29, 2026
13 checks passed
@tbolis-at-mulesoft
tbolis-at-mulesoft deleted the feat/691-adk-native-gemini branch September 29, 2026 19:57
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.

ADK: donkey.adk.gemini() — native Gemini model bound to a Format=Gemini proxy

1 participant