Files
majordomo/docs/adr/0011-google-provider.md
T
steve 1ca607906d feat: Google (Gemini) provider on the official Gen AI SDK
Phase 4: provider/google on google.golang.org/genai v1.59.0 — lazy cached
client, FunctionResponse tool loop, raw-JSON-schema tools and structured
output, ThinkingLevel reasoning mapping, iter.Pull2 streaming, hermetic
httptest suite via HTTPOptions.BaseURL. Registry wires google + gemini
schemes to the real client; stub machinery deleted (all built-ins real).
ADR-0011; README matrix + CLAUDE.md synced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 13:04:28 +02:00

47 lines
2.2 KiB
Markdown

# ADR-0011: Google provider on the official Gen AI SDK
**Status:** Accepted — 2026-06-10
## Context
ADR-0007 approves exactly one third-party dependency: Google's surface
(auth modes, API versions, endpoint shapes) moves too much to hand-roll
profitably. The deprecated `github.com/google/generative-ai-go` is not an
option; `google.golang.org/genai` is the current official SDK.
## Decision
- Build `provider/google` on `google.golang.org/genai` **v1.59.0**,
`BackendGeminiAPI`, API key from `GOOGLE_API_KEY` then `GEMINI_API_KEY`
(the SDK's own precedence).
- The SDK client is created **lazily on first request** and cached;
construction of the Provider never fails (per ADR-0005). A missing key
is a synthetic 401 `APIError`, so chains fail over past it.
- Mappings (recorded in the package doc): assistant role → `model`;
tool results → `FunctionResponse` parts in a user content
(`{"output": ...}` / `{"error": ...}` payloads); tool schemas via
`FunctionDeclaration.ParametersJsonSchema` (raw JSON schema — no lossy
conversion to genai.Schema); structured output via `ResponseJsonSchema`
+ `application/json` MIME; `ToolChoice``FunctionCallingConfig` modes
(`required` → ANY, named → ANY + AllowedFunctionNames, `none` → tools
omitted); `ReasoningEffort``ThinkingConfig.ThinkingLevel`
(LOW/MEDIUM/HIGH); usage output = candidates + thoughts tokens; thought
parts are skipped in content.
- Streaming adapts the SDK's `iter.Seq2` to majordomo's pull-based
`Stream` with `iter.Pull2`; `Close` releases the iterator via its stop
function. Function calls arrive whole per chunk (no partial-args
assembly needed).
- Hermetic tests use the SDK's documented hooks:
`HTTPOptions.BaseURL` + `HTTPClient` pointed at `httptest` servers (the
same technique as the SDK's own test suite); streaming fixtures are SSE.
- Errors: `genai.APIError` (value type; `Code` = HTTP status) maps to
`llm.APIError{Status: Code, Code: Status}` so the standard classifier
applies.
## Consequences
- `go.mod` gains genai and its transitive tree (auth, grpc, protobuf) —
the one sanctioned dependency cost.
- Vertex AI backend is NOT wired (API-key Gemini only); adding it later is
an options-level change, not a redesign.