Class: Llmemory::LLM::OpenAI

Inherits:
Base
  • Object
show all
Defined in:
lib/llmemory/llm/openai.rb

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.openai.com/v1"

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, model: nil, base_url: nil) ⇒ OpenAI

Returns a new instance of OpenAI.



12
13
14
15
16
# File 'lib/llmemory/llm/openai.rb', line 12

def initialize(api_key: nil, model: nil, base_url: nil)
  @api_key = api_key || config.llm_api_key
  @model = model || config.llm_model
  @base_url = base_url || config.llm_base_url || DEFAULT_BASE_URL
end

Instance Method Details

#invoke(prompt) ⇒ Object

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/llmemory/llm/openai.rb', line 18

def invoke(prompt)
  response = connection.post("chat/completions") do |req|
    req.body = {
      model: @model,
      messages: [{ role: "user", content: prompt }],
      temperature: 0.3
    }.to_json
    req.headers["Content-Type"] = "application/json"
    req.headers["Authorization"] = "Bearer #{@api_key}"
  end

  raise Llmemory::LLMError, "OpenAI API error: #{response.body}" unless response.success?

  body = response.body.is_a?(Hash) ? response.body : JSON.parse(response.body.to_s)
  body.dig("choices", 0, "message", "content")&.strip || ""
end

#invoke_with_json_schema(prompt, json_schema) ⇒ Object

Calls the model with response_format json_schema (Structured Outputs). Returns the parsed JSON hash. Use when the model supports structured outputs (e.g. gpt-4o, gpt-4o-mini 2024-08-06 and later).



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/llmemory/llm/openai.rb', line 38

def invoke_with_json_schema(prompt, json_schema)
  payload = {
    model: @model,
    messages: [{ role: "user", content: prompt }],
    temperature: 0,
    response_format: {
      type: "json_schema",
      json_schema: {
        strict: true,
        name: json_schema[:name] || "extraction",
        schema: json_schema[:schema] || json_schema["schema"]
      }
    }
  }
  response = connection.post("chat/completions") do |req|
    req.body = payload.to_json
    req.headers["Content-Type"] = "application/json"
    req.headers["Authorization"] = "Bearer #{@api_key}"
  end

  raise Llmemory::LLMError, "OpenAI API error: #{response.body}" unless response.success?

  body = response.body.is_a?(Hash) ? response.body : JSON.parse(response.body.to_s)
  content = body.dig("choices", 0, "message", "content")&.strip
  return {} if content.nil? || content.empty?
  JSON.parse(content)
rescue JSON::ParserError => e
  raise Llmemory::LLMError, "Failed to parse JSON response: #{e.message}"
end