components/providers/google.rb in nano-bots-2.2.0 vs components/providers/google.rb in nano-bots-2.3.0

- old
+ new

@@ -4,10 +4,12 @@ require_relative 'base' require_relative '../../logic/providers/google/tools' require_relative '../../logic/providers/google/tokens' +require_relative '../../logic/helpers/hash' +require_relative '../../logic/cartridge/default' require_relative 'tools' module NanoBot module Components @@ -24,13 +26,23 @@ attr_reader :settings def initialize(options, settings, credentials, _environment) @settings = settings + gemini_options = options.transform_keys { |key| key.to_s.gsub('-', '_').to_sym } + + unless gemini_options.key?(:stream) + gemini_options[:stream] = Logic::Helpers::Hash.fetch( + Logic::Cartridge::Default.instance.values, %i[provider settings stream] + ) + end + + gemini_options[:server_sent_events] = gemini_options.delete(:stream) + @client = Gemini.new( credentials: credentials.transform_keys { |key| key.to_s.gsub('-', '_').to_sym }, - options: options.transform_keys { |key| key.to_s.gsub('-', '_').to_sym } + options: gemini_options ) end def evaluate(input, streaming, cartridge, &feedback) messages = input[:history].map do |event| @@ -103,10 +115,13 @@ if streaming content = '' tools = [] stream_call_back = proc do |event, _parsed, _raw| + # TODO: How to better handle finishReason == 'OTHER'? + return if event.dig('candidates', 0, 'finishReason') == 'OTHER' + partial_content = event.dig('candidates', 0, 'content', 'parts').filter do |part| part.key?('text') end.map { |part| part['text'] }.join partial_tools = event.dig('candidates', 0, 'content', 'parts').filter do |part| @@ -130,11 +145,11 @@ end end @client.stream_generate_content( Logic::Google::Tokens.apply_policies!(cartridge, payload), - stream: true, &stream_call_back + server_sent_events: true, &stream_call_back ) if tools&.size&.positive? feedback.call( { should_be_stored: true, @@ -154,10 +169,10 @@ finished: true } ) else result = @client.stream_generate_content( Logic::Google::Tokens.apply_policies!(cartridge, payload), - stream: false + server_sent_events: false ) tools = result.dig(0, 'candidates', 0, 'content', 'parts').filter do |part| part.key?('functionCall') end