Last updated 2026-05-17

Google Gemini (AI Studio) Provider

The gemini provider talks to Google's AI Studio endpoint — the API-key-based, consumer-facing side of Gemini. Use this provider for prototypes, side projects, and small-scale production where IAM / VPC-SC are not required. For project-scoped quota and enterprise controls, use the Vertex AI provider instead.

Capabilities: chat (Provider), embeddings (Embedder), TTS (Speaker), and STT via audio understanding (Transcriber). Gemini is the only chat-first provider that ships all four interfaces in v0.3.

Import path

import (
"github.com/elloloop/llmrouter"
"github.com/elloloop/llmrouter/providers/gemini"
)

Construction

p, err := gemini.New(
llmrouter.WithAPIKey(os.Getenv("GOOGLE_API_KEY")),
)
if err != nil {
log.Fatal(err)
}

Default endpoint: https://generativelanguage.googleapis.com/v1beta. Auth is via the x-goog-api-key header.

Models

  • gemini-2.0-flash — fast, multimodal, recommended default.
  • gemini-2.0-flash-lite — cheapest, text-only.
  • gemini-2.5-pro — frontier reasoning, longer context.
  • gemini-2.5-flash — balanced cost/quality.
  • text-embedding-004 / text-embedding-005 — embeddings.

Chat example

stream, err := p.CompletionStream(ctx, llmrouter.ChatRequest{
Model: "gemini-2.0-flash",
Messages: []llmrouter.Message{
llmrouter.TextMessage("system", "Reply in haiku."),
llmrouter.TextMessage("user", "Describe a server room."),
},
})
for chunk := range stream.Chunks() {
for _, c := range chunk.Choices {
fmt.Print(c.Delta.Content)
}
}

The provider translates the OpenAI-shaped request into Gemini's {contents:[{role, parts:[{text}]}]} body and the :streamGenerateContent SSE stream back to llmrouter.Chunk.

Embeddings

resp, err := p.Embed(ctx, llmrouter.EmbedRequest{
Model: "text-embedding-005",
Inputs: []string{"What is a transformer?"},
TaskType: "RETRIEVAL_QUERY",
})

TaskType is passed through verbatim because Gemini uses the canonical Vertex vocabulary.

TTS

Gemini 2.0 Flash supports speech generation via the same model endpoint. The provider wraps it behind Speak:

stream, err := p.Speak(ctx, llmrouter.SpeechRequest{
Model: "gemini-2.0-flash",
Input: "Hello from Gemini.",
Voice: "Aoede",
})
out, _ := os.Create("gemini.wav")
defer out.Close()
for chunk := range stream.Chunks() {
out.Write(chunk.Data)
}

Available voice names depend on the model version; consult Google's docs. The library does not validate voice names locally.

STT (audio understanding)

Gemini accepts audio as an input modality and can return a transcript. The provider wraps this behind Transcribe:

f, _ := os.Open("meeting.mp3")
defer f.Close()
stream, err := p.Transcribe(ctx, llmrouter.TranscribeRequest{
Model: "gemini-2.0-flash",
Audio: f,
AudioFormat: "audio/mpeg",
Prompt: "Transcribe this audio verbatim.",
})
for seg := range stream.Segments() {
fmt.Println(seg.Text)
}

Note this is not a dedicated STT model — it's Gemini being asked to transcribe audio it understands. Accuracy is solid for English; for production STT prefer Deepgram Nova or OpenAI Whisper.

Error handling

Non-2xx responses surface as *llmrouter.ErrUpstream with Provider == "gemini". Common cases:

  • 403 — API key not enabled for the model.
  • 400 — safety filter (response body has promptFeedback).
  • 429 — per-API-key rate limit.

Caveats

  • API in v1beta. Gemini's REST API is still in beta; expect occasional non-breaking changes upstream.
  • Safety filters. AI Studio applies a more conservative default than Vertex. Tune via safetySettings on Raw.
  • No SLA on free tier. For production, either pay per-token or move to Vertex.

See also