Class: Crystil::Wrappers::GeminiAI
- Inherits:
-
Object
- Object
- Crystil::Wrappers::GeminiAI
- Defined in:
- lib/crystil/wrappers/geminiai.rb,
sig/crystil/wrappers/geminiai.rbs
Overview
Wrapper for Google GenerativeAI Ruby client (gemini-ai gem version 4.3.0)
Instance Method Summary collapse
-
#initialize(config, collector, sentinel = nil) ⇒ GeminiAI
constructor
A new instance of GeminiAI.
- #register(client) ⇒ Object
- #validate_client!(client) ⇒ void
- #wrap_generate_content_method(client) ⇒ void
-
#wrap_stream_generate_content_method(client) ⇒ void
Handles the stream_generate_content from the client.
Constructor Details
#initialize(config, collector, sentinel = nil) ⇒ GeminiAI
Returns a new instance of GeminiAI.
9 10 11 12 13 |
# File 'lib/crystil/wrappers/geminiai.rb', line 9 def initialize(config, collector, sentinel = nil) @config = config @collector = collector @sentinel = sentinel end |
Instance Method Details
#register(client) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/crystil/wrappers/geminiai.rb', line 15 def register(client) validate_client!(client) # Prevent double registration return client if client.instance_variable_defined?(:@crystil_registered) # Store references in client instance client.instance_variable_set(:@crystil_config, @config) client.instance_variable_set(:@crystil_collector, @collector) client.instance_variable_set(:@crystil_sentinel, @sentinel) client.instance_variable_set(:@crystil_registered, true) # Wrap the generate_content and stream_generate_content methods wrap_generate_content_method(client) wrap_stream_generate_content_method(client) client end |
#validate_client!(client) ⇒ void
This method returns an undefined value.
36 37 38 39 40 41 42 |
# File 'lib/crystil/wrappers/geminiai.rb', line 36 def validate_client!(client) return if client.respond_to?(:generate_content) && client.respond_to?(:stream_generate_content) raise RegistrationError, "Client does not appear to be a valid Gemini AI client " \ "(missing generate_content or stream_generate_content method)" end |
#wrap_generate_content_method(client) ⇒ void
This method returns an undefined value.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 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/crystil/wrappers/geminiai.rb', line 44 def wrap_generate_content_method(client) client.singleton_class.class_eval do include Base alias_method :original_generate_content, :generate_content define_method(:generate_content) do |*args, **kwargs, &block| # Handle both positional hash and keyword arguments parameters = if args.first.is_a?(Hash) args.first elsif kwargs.any? kwargs else {} end start_time = Time.now version = defined?(::Gemini::GEM) && ::Gemini::GEM.is_a?(Hash) ? ::Gemini::GEM[:version] : nil sentinel = instance_variable_get(:@crystil_sentinel) sentinel&.raise_if_irrelevant!( title: GOOGLE_CLIENT_TITLE, request: parameters, version: version ) # Call original method response = original_generate_content(*args, **kwargs, &block) # Submit analytics crystil_submit_analytics( method: :generate_content, args: [], kwargs: parameters, response: response, start_time: start_time, end_time: Time.now, title: GOOGLE_CLIENT_TITLE, version: version ) response rescue CrystilRequestInterceptedError => e # We don't want to send intercepts to collector raise e rescue StandardError => e crystil_submit_error_analytics( method: :generate_content, args: [], kwargs: parameters, error: e, start_time: start_time, end_time: Time.now, title: GOOGLE_CLIENT_TITLE, version: version ) raise e end end end |
#wrap_stream_generate_content_method(client) ⇒ void
This method returns an undefined value.
Handles the stream_generate_content from the client. Note, that the Crystil backend does not expect the payload to be merged like the OpenAI payload is. So, all the results are just sent as an array.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/crystil/wrappers/geminiai.rb', line 110 def wrap_stream_generate_content_method(client) client.singleton_class.class_eval do include Base alias_method :original_stream_generate_content, :stream_generate_content define_method(:stream_generate_content) do |*args, **kwargs, &block| # Handle both positional hash and keyword arguments parameters = if args.first.is_a?(Hash) args.first elsif kwargs.any? kwargs else {} end start_time = Time.now version = defined?(::Gemini::GEM) && ::Gemini::GEM.is_a?(Hash) ? ::Gemini::GEM[:version] : nil sentinel = instance_variable_get(:@crystil_sentinel) sentinel&.raise_if_irrelevant!( title: GOOGLE_CLIENT_TITLE, request: parameters, version: version ) # Call original method with wrapped block response = original_stream_generate_content(*args, **kwargs, &block) # Submit analytics with accumulated response crystil_submit_analytics( method: :stream_generate_content, args: [], kwargs: parameters, response: response, start_time: start_time, end_time: Time.now, title: GOOGLE_CLIENT_TITLE, version: version ) response rescue CrystilRequestInterceptedError => e # We don't want to send intercepts to collector raise e rescue StandardError => e crystil_submit_error_analytics( method: :stream_generate_content, args: [], kwargs: parameters, error: e, start_time: start_time, end_time: Time.now, title: GOOGLE_CLIENT_TITLE, version: version ) raise e end end end |