Nous.Providers.Gemini (nous v0.16.3)

View Source

Google Gemini provider implementation.

Supports Gemini models via the Google AI Generative Language API.

Usage

# Basic usage
{:ok, response} = Nous.Providers.Gemini.chat(%{
  model: "gemini-2.0-flash-exp",
  contents: [%{"role" => "user", "parts" => [%{"text" => "Hello"}]}]
})

# With system instruction
{:ok, response} = Nous.Providers.Gemini.chat(%{
  model: "gemini-2.0-flash-exp",
  systemInstruction: %{"parts" => [%{"text" => "You are helpful."}]},
  contents: [%{"role" => "user", "parts" => [%{"text" => "Hello"}]}],
  generationConfig: %{"temperature" => 0.7, "maxOutputTokens" => 1024}
})

# Streaming
{:ok, stream} = Nous.Providers.Gemini.chat_stream(params)
Enum.each(stream, fn event -> IO.inspect(event) end)

Configuration

# In config.exs
config :nous, :gemini,
  api_key: "AIza...",
  base_url: "https://generativelanguage.googleapis.com/v1beta"  # optional

Note on Authentication

The API key is sent via the x-goog-api-key request header (not the URL query string), so it does not leak into proxy/load-balancer access logs, tracing spans, or redirect logs.

Thinking (Gemini 2.5/3.x)

For models that support extended thinking, pass :thinking_config in default_settings. Both the Elixir shape (snake_case atoms) and the native Vertex shape (camelCase strings) are accepted:

# Elixir shape (recommended)
Nous.new("gemini:gemini-2.5-pro",
  default_settings: %{
    thinking_config: %{thinking_budget: 1024, include_thoughts: true}
  }
)

# Native Vertex shape
Nous.new("gemini:gemini-2.5-pro",
  default_settings: %{
    thinking_config: %{"thinkingBudget" => 1024, "includeThoughts" => true}
  }
)

When include_thoughts: true, thought summaries arrive as Message.reasoning_content. For tool-using thinking models, Vertex emits a thoughtSignature on each tool call; Nous preserves it in tool_call["metadata"]["thought_signature"] and echoes it back on the next turn automatically — required for multi-turn thinking + tool loops to keep working.

See https://ai.google.dev/gemini-api/docs/thinking for the Gemini-side docs and https://cloud.google.com/vertex-ai/generative-ai/docs/thinking for the Vertex equivalent.

Summary

Functions

Get the API key from options, environment, or application config.

Get the base URL from options, application config, or default.

Count tokens in messages (rough estimate).

High-level request with message conversion, telemetry, and error wrapping.

High-level streaming request with message conversion and telemetry.

Functions

api_key(opts \\ [])

@spec api_key(keyword()) :: String.t() | nil

Get the API key from options, environment, or application config.

Lookup order:

  1. :api_key option passed directly
  2. Environment variable (GOOGLE_AI_API_KEY)
  3. Application config: config :nous, gemini, api_key: "..."

base_url(opts \\ [])

@spec base_url(keyword()) :: String.t()

Get the base URL from options, application config, or default.

Lookup order:

  1. :base_url option passed directly
  2. Application config: config :nous, gemini, base_url: "..."
  3. Default: https://generativelanguage.googleapis.com/v1beta

count_tokens(messages)

@spec count_tokens(list()) :: integer()

Count tokens in messages (rough estimate).

Override this in your provider for more accurate counting.

request(model, messages, settings)

High-level request with message conversion, telemetry, and error wrapping.

Default implementation that:

  1. Converts messages to provider format
  2. Builds request params
  3. Calls chat/2
  4. Parses response
  5. Emits telemetry events
  6. Wraps errors

request_stream(model, messages, settings)

High-level streaming request with message conversion and telemetry.