Class: SolidLoop::Dialects::Gemini
- Inherits:
-
Object
- Object
- SolidLoop::Dialects::Gemini
- Defined in:
- app/services/solid_loop/dialects/gemini.rb
Instance Method Summary collapse
- #apply_reasoning_strategies!(messages, strategies) ⇒ Object
- #auth_headers(_api_token) ⇒ Object
- #completion_url(base_url) ⇒ Object
- #extract_message_data(data) ⇒ Object
- #normalize_response(data, fallback_text: "", fallback_messages_text: "") ⇒ Object
- #render_payload(payload) ⇒ Object
Instance Method Details
#apply_reasoning_strategies!(messages, strategies) ⇒ Object
28 29 30 31 32 33 34 35 36 37 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 28 def apply_reasoning_strategies!(, strategies) return unless .is_a?(Array) # Gemini filter: only keep gemini-specific and universal XML strategies filtered = strategies.select { |s| [:gemini_signed, :xml, :xml!].include?(s) } .each do |msg| SolidLoop::Dialects::ReasoningPacker.pack(msg, filtered) end end |
#auth_headers(_api_token) ⇒ Object
10 11 12 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 10 def auth_headers(_api_token) {} # Gemini uses ?key= query param, not a header end |
#completion_url(base_url) ⇒ Object
6 7 8 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 6 def completion_url(base_url) base_url.to_s.gsub(/\/+$/, "") + "/v1beta/models" end |
#extract_message_data(data) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 39 def (data) candidate = data.dig("candidates", 0) || {} content_obj = candidate.dig("content") || {} parts = content_obj.dig("parts") || [] text_part = parts.find { |p| p["text"].present? } thought_part = parts.find { |p| p["thought"].present? } tool_calls_part = parts.select { |p| p["functionCall"].present? } { content: text_part&.dig("text"), reasoning: thought_part&.dig("thought"), tool_calls: map_tool_calls_from_gemini(tool_calls_part), metadata: { thought_signature: candidate.dig("thoughtSignature") }.compact } end |
#normalize_response(data, fallback_text: "", fallback_messages_text: "") ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 56 def normalize_response(data, fallback_text: "", fallback_messages_text: "") res = (data) usage_data = if data["usageMetadata"].is_a?(Hash) SolidLoop::LlmUsageParser::Gemini.call(data["usageMetadata"]) else SolidLoop::LlmUsageParser.estimate(fallback_text, ) end { content: res[:content], reasoning: res[:reasoning], tool_calls: res[:tool_calls], usage: usage_data, metadata: res[:metadata].merge({ "model" => data["modelVersion"].presence }.compact) } end |
#render_payload(payload) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'app/services/solid_loop/dialects/gemini.rb', line 14 def render_payload(payload) gemini_payload = { contents: payload[:messages].map { |m| (m) }, generationConfig: { temperature: payload[:temperature], maxOutputTokens: payload[:max_tokens] }.compact } if payload[:tools]&.any? gemini_payload[:tools] = [{ function_declarations: payload[:tools].map { |t| map_tool(t) } }] end gemini_payload end |