Class: GeminiAI::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/gemini_ai.rb

Constant Summary collapse

BASE_URL =
'https://generativelanguage.googleapis.com/v1/models'
MODELS =
{
  pro: 'gemini-2.0-flash',
  flash: 'gemini-2.0-flash',
  flash_lite: 'gemini-2.0-flash-lite'
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key = nil, model: :pro) ⇒ Client

Returns a new instance of Client.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/gemini_ai.rb', line 29

def initialize(api_key = nil, model: :pro)
  # Prioritize passed API key, then environment variable
  @api_key = api_key || ENV['GEMINI_API_KEY']
  
  # Extensive logging for debugging
  self.class.logger.debug("Initializing Client")
  self.class.logger.debug("API Key present: #{!@api_key.nil?}")
  self.class.logger.debug("API Key length: #{@api_key&.length}")
  
  # Validate API key
  validate_api_key!
  
  @model = MODELS.fetch(model) { 
    self.class.logger.warn("Invalid model: #{model}, defaulting to pro")
    MODELS[:pro] 
  }
  
  self.class.logger.debug("Selected model: #{@model}")
end

Class Method Details

.loggerObject

Configure logging



18
19
20
21
22
23
24
25
26
27
# File 'lib/gemini_ai.rb', line 18

def self.logger
  @logger ||= Logger.new(STDOUT).tap do |log|
    log.level = Logger::DEBUG  # Changed to DEBUG for more information
    log.formatter = proc do |severity, datetime, progname, msg|
      # Mask any potential API key in logs
      masked_msg = msg.to_s.gsub(/AIza[a-zA-Z0-9_-]{35,}/, '[REDACTED]')
      "#{datetime}: #{severity} -- #{masked_msg}\n"
    end
  end
end

Instance Method Details

#chat(messages, options = {}) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/gemini_ai.rb', line 76

def chat(messages, options = {})
  request_body = {
    contents: messages.map { |msg| { role: msg[:role], parts: [{ text: msg[:content] }] } },
    generationConfig: build_generation_config(options)
  }

  send_request(request_body)
end

#generate_image_text(image_base64, prompt, options = {}) ⇒ Object

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gemini_ai.rb', line 60

def generate_image_text(image_base64, prompt, options = {})
  raise Error, "Image is required" if image_base64.nil? || image_base64.empty?
  
  request_body = {
    contents: [
      { parts: [
        { inline_data: { mime_type: 'image/jpeg', data: image_base64 } },
        { text: prompt }
      ]}
    ],
    generationConfig: build_generation_config(options)
  }

  send_request(request_body, model: :pro_vision)
end

#generate_text(prompt, options = {}) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/gemini_ai.rb', line 49

def generate_text(prompt, options = {})
  validate_prompt!(prompt)

  request_body = {
    contents: [{ parts: [{ text: prompt }] }],
    generationConfig: build_generation_config(options)
  }

  send_request(request_body)
end