Class: Durable::Llm::Providers::Google

Inherits:
Base
  • Object
show all
Defined in:
lib/durable/llm/providers/google.rb

Overview

Google Generative AI provider for accessing Gemini language models.

Provides completion, embedding, and streaming capabilities with proper error handling and response normalization for Google's Generative Language API.

Defined Under Namespace

Classes: GoogleChoice, GoogleEmbeddingResponse, GoogleMessage, GoogleResponse, GoogleStreamChoice, GoogleStreamDelta, GoogleStreamResponse

Constant Summary collapse

BASE_URL =
'https://generativelanguage.googleapis.com'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

models, options, #stream?

Constructor Details

#initialize(api_key: nil) ⇒ Google

Returns a new instance of Google.



31
32
33
34
35
36
37
38
# File 'lib/durable/llm/providers/google.rb', line 31

def initialize(api_key: nil)
  @api_key = api_key || default_api_key
  @conn = Faraday.new(url: BASE_URL) do |faraday|
    faraday.request :json
    faraday.response :json
    faraday.adapter Faraday.default_adapter
  end
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



29
30
31
# File 'lib/durable/llm/providers/google.rb', line 29

def api_key
  @api_key
end

Class Method Details

.stream?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/durable/llm/providers/google.rb', line 106

def self.stream?
  true
end

Instance Method Details

#completion(options) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/durable/llm/providers/google.rb', line 40

def completion(options)
  model = options[:model]
  url = "/v1beta/models/#{model}:generateContent?key=#{@api_key}"

  # Transform options to Google's format
  request_body = transform_options(options)

  response = @conn.post(url) do |req|
    req.body = request_body
  end

  handle_response(response)
end

#default_api_keyObject



21
22
23
24
25
26
27
# File 'lib/durable/llm/providers/google.rb', line 21

def default_api_key
  begin
    Durable::Llm.configuration.google&.api_key
  rescue NoMethodError
    nil
  end || ENV['GOOGLE_API_KEY']
end

#embedding(model:, input:, **_options) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/durable/llm/providers/google.rb', line 54

def embedding(model:, input:, **_options)
  url = "/v1beta/models/#{model}:embedContent?key=#{@api_key}"

  request_body = {
    content: {
      parts: [{ text: input }]
    }
  }

  response = @conn.post(url) do |req|
    req.body = request_body
  end

  handle_response(response, GoogleEmbeddingResponse)
end

#modelsObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/durable/llm/providers/google.rb', line 70

def models
  # Google doesn't provide a public models API, so return hardcoded list
  [
    'gemini-1.5-flash',
    'gemini-1.5-flash-001',
    'gemini-1.5-flash-002',
    'gemini-1.5-flash-8b',
    'gemini-1.5-flash-8b-001',
    'gemini-1.5-flash-8b-latest',
    'gemini-1.5-flash-latest',
    'gemini-1.5-pro',
    'gemini-1.5-pro-001',
    'gemini-1.5-pro-002',
    'gemini-1.5-pro-latest',
    'gemini-2.0-flash',
    'gemini-2.0-flash-001',
    'gemini-2.0-flash-exp',
    'gemini-2.0-flash-lite',
    'gemini-2.0-flash-lite-001',
    'gemini-2.0-flash-live-001',
    'gemini-2.0-flash-preview-image-generation',
    'gemini-2.5-flash',
    'gemini-2.5-flash-exp-native-audio-thinking-dialog',
    'gemini-2.5-flash-lite',
    'gemini-2.5-flash-lite-06-17',
    'gemini-2.5-flash-preview-05-20',
    'gemini-2.5-flash-preview-native-audio-dialog',
    'gemini-2.5-flash-preview-tts',
    'gemini-2.5-pro',
    'gemini-2.5-pro-preview-tts',
    'gemini-live-2.5-flash-preview',
    'text-embedding-004',
    'text-multilingual-embedding-002'
  ]
end

#stream(options) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/durable/llm/providers/google.rb', line 110

def stream(options)
  model = options[:model]
  url = "/v1beta/models/#{model}:streamGenerateContent?key=#{@api_key}&alt=sse"

  request_body = transform_options(options)

  response = @conn.post(url) do |req|
    req.headers['Accept'] = 'text/event-stream'
    req.body = request_body

    user_proc = proc do |chunk, _size, _total|
      yield GoogleStreamResponse.new(chunk)
    end

    req.options.on_data = to_json_stream(user_proc: user_proc)
  end

  handle_response(response)
end