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>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user