0.0
No release in over 3 years
A Ruby-native SDK for Google's Generative AI (Gemini) APIs, providing text generation, chat, streaming, multimodal content, and image generation (Nano Banana) support.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

~> 2.0
 Project Readme

Aigen::Google

Ruby SDK for Google's Gemini API - build AI-powered applications with text generation, chat, streaming, and multimodal content support.

Gem Version Build Status

Features

  • Text Generation: Generate content from text prompts
  • Chat with History: Multi-turn conversations with context preservation
  • Streaming: Real-time response delivery with progressive chunks
  • Multimodal Content: Combine text and images in requests
  • Generation Config: Control output with temperature, top_p, top_k, max_output_tokens
  • Safety Settings: Configure content filtering for harm categories
  • Comprehensive Error Handling: Automatic retries with exponential backoff for rate limits and server errors
  • Ruby 3.1+ Support: Modern Ruby idioms with frozen string literals

Installation

Add this line to your application's Gemfile:

gem 'aigen-google'

And then execute:

bundle install

Or install it yourself as:

gem install aigen-google

Quick Start

require 'aigen/google'

# Configure with your API key
Aigen::Google.configure do |config|
  config.api_key = ENV['GOOGLE_API_KEY']
end

# Generate content
client = Aigen::Google::Client.new
response = client.generate_content(prompt: "Explain quantum computing in simple terms")
puts response["candidates"][0]["content"]["parts"][0]["text"]

Configuration

Block-based Configuration (Recommended)

Aigen::Google.configure do |config|
  config.api_key = ENV['GOOGLE_API_KEY']
  config.default_model = "gemini-pro"
  config.timeout = 60
end

client = Aigen::Google::Client.new

Instance-based Configuration

client = Aigen::Google::Client.new(
  api_key: "your-api-key",
  model: "gemini-pro",
  timeout: 60
)

Available Configuration Options

Option Type Default Description
api_key String ENV['GOOGLE_API_KEY'] Your Google AI API key (Get one here)
default_model String "gemini-pro" Default model to use for requests
timeout Integer 30 HTTP request timeout in seconds
retry_count Integer 3 Number of retry attempts for rate limits/server errors

Usage Examples

Basic Text Generation

client = Aigen::Google::Client.new

response = client.generate_content(prompt: "Write a haiku about Ruby programming")
text = response["candidates"][0]["content"]["parts"][0]["text"]
puts text

Chat with History

chat = client.start_chat

# First message
chat.send_message("What is Ruby?")

# Follow-up with context
response = chat.send_message("What are its main features?")
text = response["candidates"][0]["content"]["parts"][0]["text"]
puts text

# View conversation history
puts chat.history

Streaming Responses

Stream responses as they're generated for real-time feedback:

# With block (immediate processing)
client.generate_content_stream(prompt: "Tell me a story") do |chunk|
  text = chunk["candidates"][0]["content"]["parts"][0]["text"]
  print text
end

# With Enumerator (lazy evaluation)
stream = client.generate_content_stream(prompt: "Count to 10")
stream.each do |chunk|
  text = chunk["candidates"][0]["content"]["parts"][0]["text"]
  print text
end

Chat Streaming

chat = client.start_chat

chat.send_message_stream("Tell me a joke") do |chunk|
  text = chunk["candidates"][0]["content"]["parts"][0]["text"]
  print text
end
# History is updated after streaming completes

Multimodal Content (Text + Images)

require 'base64'

# Prepare image data
image_data = Base64.strict_encode64(File.read("photo.jpg"))

# Create multimodal content
text_content = Aigen::Google::Content.text("What is in this image?")
image_content = Aigen::Google::Content.image(
  data: image_data,
  mime_type: "image/jpeg"
)

# Generate content with both
response = client.generate_content(contents: [text_content.to_h, image_content.to_h])
text = response["candidates"][0]["content"]["parts"][0]["text"]
puts text

Configuring Generation Parameters

Control output quality and randomness:

response = client.generate_content(
  prompt: "Write a creative story",
  temperature: 0.9,      # Higher = more creative (0.0-1.0)
  top_p: 0.95,           # Nucleus sampling (0.0-1.0)
  top_k: 40,             # Top-k sampling
  max_output_tokens: 1024 # Maximum response length
)

Safety Settings

Configure content filtering:

# Use default settings (BLOCK_MEDIUM_AND_ABOVE for all categories)
settings = Aigen::Google::SafetySettings.default

# Or customize
settings = Aigen::Google::SafetySettings.new([
  {
    category: Aigen::Google::SafetySettings::HARM_CATEGORY_HATE_SPEECH,
    threshold: Aigen::Google::SafetySettings::BLOCK_LOW_AND_ABOVE
  },
  {
    category: Aigen::Google::SafetySettings::HARM_CATEGORY_DANGEROUS_CONTENT,
    threshold: Aigen::Google::SafetySettings::BLOCK_MEDIUM_AND_ABOVE
  }
])

response = client.generate_content(
  prompt: "Hello",
  safety_settings: settings.to_h
)

Image Generation (Nano Banana 🍌)

Generate images using Gemini's image generation models (nicknamed "Nano Banana"):

# Use an image generation model
client = Aigen::Google::Client.new(model: 'gemini-2.5-flash-image')

# Simple image generation
response = client.generate_image("A serene mountain landscape at sunset")

if response.success?
  response.save("landscape.png")
  puts "Image saved!"
  puts "Description: #{response.text}"
else
  puts "Generation failed: #{response.failure_message}"
end

With Size and Aspect Ratio

response = client.generate_image(
  "A futuristic cityscape with flying cars",
  aspect_ratio: "16:9",  # Options: "1:1", "16:9", "9:16", "4:3", "3:4", "5:4", "4:5"
  size: "2K"             # Options: "1K", "2K", "4K"
)

response.save("city.png") if response.success?

ImageResponse Helper Methods

The generate_image method returns an ImageResponse object with convenient helpers:

response = client.generate_image("A cute puppy")

# Check success
response.success?              # => true/false
response.has_image?            # => true/false

# Access image data
response.image_data            # => Binary image data
response.mime_type             # => "image/png"
response.text                  # => Text description

# Save image
response.save("output.png")

# Handle failures
unless response.success?
  puts response.failure_reason   # => "IMAGE_OTHER", "SAFETY", etc.
  puts response.failure_message  # => Detailed error message
end

# Access raw response
response.raw_response           # => Full API response hash

Available Models

  • gemini-2.5-flash-image - Standard image generation (up to 2K)
  • gemini-2.0-flash-exp - Experimental with native image generation
  • gemini-3-pro-image-preview - Preview with 4K support

Error Handling

The SDK provides comprehensive error handling with automatic retries:

Exception Types

Exception When Raised Retry Behavior
Aigen::Google::AuthenticationError Invalid API key (401/403) No retry
Aigen::Google::InvalidRequestError Malformed request (400/404) No retry
Aigen::Google::RateLimitError Rate limit exceeded (429) Automatic retry with backoff
Aigen::Google::ServerError Server error (500-599) Automatic retry with backoff
Aigen::Google::TimeoutError Request timeout Automatic retry with backoff
Aigen::Google::ApiError Other API errors No retry

Retry Behavior

The SDK automatically retries rate limit (429) and server errors (500-599) with exponential backoff:

  • Attempt 1: Wait 1 second, retry
  • Attempt 2: Wait 2 seconds, retry
  • Attempt 3: Wait 4 seconds, raise error if fails

Maximum retry attempts: 3 (configurable via retry_count)

Handling Errors

begin
  response = client.generate_content(prompt: "Hello")
rescue Aigen::Google::AuthenticationError => e
  puts "Invalid API key: #{e.message}"
  puts "Get your API key at: https://makersuite.google.com/app/apikey"
rescue Aigen::Google::RateLimitError => e
  puts "Rate limit exceeded: #{e.message}"
  puts "Try reducing request rate or increasing quota"
rescue Aigen::Google::ServerError => e
  puts "Server error (#{e.status_code}): #{e.message}"
  puts "Try again later - the API may be experiencing issues"
rescue Aigen::Google::TimeoutError => e
  puts "Request timed out: #{e.message}"
rescue Aigen::Google::ApiError => e
  puts "API error (#{e.status_code}): #{e.message}"
end

API Reference

Full API documentation is available at https://rubydoc.info/gems/aigen-google (YARD documentation).

Key Classes

  • Aigen::Google::Client - Main client for API requests
  • Aigen::Google::Chat - Multi-turn conversation management
  • Aigen::Google::Content - Multimodal content builder
  • Aigen::Google::GenerationConfig - Generation parameter configuration
  • Aigen::Google::SafetySettings - Content filtering configuration
  • Aigen::Google::Configuration - Global configuration

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Running Tests

# Run all tests
bundle exec rspec

# Run with coverage report
COVERAGE=true bundle exec rspec

# Run linter
bundle exec rake standard

# Run both tests and linter
bundle exec rake

Code Quality

  • Test Coverage: >= 90% (enforced with SimpleCov)
  • Code Style: StandardRB (0 offenses required)
  • Ruby Version: >= 3.1.0

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/neuralmux/aigen-google.

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

The gem is available as open source under the terms of the MIT License.

Changelog

See CHANGELOG.md for version history and release notes.

Resources