Class: SolidLoop::Dialects::OpenAi

Inherits:
Object
  • Object
show all
Defined in:
app/services/solid_loop/dialects/open_ai.rb

Instance Method Summary collapse

Instance Method Details

#apply_reasoning_strategies!(messages, strategies) ⇒ Object



14
15
16
17
18
19
20
21
22
23
# File 'app/services/solid_loop/dialects/open_ai.rb', line 14

def apply_reasoning_strategies!(messages, strategies)
  return unless messages.is_a?(Array)

  # OpenAI filter: remove Gemini-specific strategies, allow XML and string fields
  filtered = strategies.reject { |s| s == :gemini_signed }

  messages.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/open_ai.rb', line 10

def auth_headers(api_token)
  api_token.present? ? { "Authorization" => "Bearer #{api_token}" } : {}
end

#completion_url(base_url) ⇒ Object



6
7
8
# File 'app/services/solid_loop/dialects/open_ai.rb', line 6

def completion_url(base_url)
  base_url.to_s.gsub(/\/+$/, "") + "/v1/chat/completions"
end

#extract_message_data(data) ⇒ Object



25
26
27
28
29
30
31
32
# File 'app/services/solid_loop/dialects/open_ai.rb', line 25

def extract_message_data(data)
  choice = data.dig("choices", 0, "message") || data.dig("choices", 0, "delta") || {}
  {
    content: choice["content"],
    reasoning: choice["reasoning_content"] || choice["reasoning"] || choice["thought"],
    tool_calls: choice["tool_calls"] || []
  }
end

#normalize_response(data, fallback_text: "", fallback_messages_text: "") ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/services/solid_loop/dialects/open_ai.rb', line 34

def normalize_response(data, fallback_text: "", fallback_messages_text: "")
  choice = data.dig("choices", 0, "message") || data.dig("choices", 0, "delta") || {}

  usage_data =
    if data["usage"].is_a?(Hash) && data["usage"]["total_tokens"].to_i > 0
      SolidLoop::LlmUsageParser::Openai.call(data["usage"])
    elsif data["timings"].is_a?(Hash)
      SolidLoop::LlmUsageParser::Llama.call(data["timings"])
    else
      SolidLoop::LlmUsageParser.estimate(fallback_text, fallback_messages_text)
    end

  reasoning_field =
    if choice["reasoning_content"] then "reasoning_content"
    elsif choice["reasoning"] then "reasoning"
    elsif choice["thought"] then "thought"
    end

  {
    content: choice["content"],
    reasoning: choice[reasoning_field],
    tool_calls: choice["tool_calls"] || [],
    usage: usage_data,
    metadata: { "reasoning_field" => reasoning_field, "model" => data["model"].presence }.compact
  }
end