22
23
24
25
26
27
28
29
30
31
32
33
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
60
61
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/rager/chat/providers/openai.rb', line 22
def chat(messages, options)
api_key = options.api_key || ENV["OPENAI_API_KEY"]
raise Rager::Errors::CredentialsError.new("OpenAI", env_var: ["OPENAI_API_KEY"]) if api_key.nil?
base_url = options.url || ENV["OPENAI_URL"] || "https://api.openai.com/v1"
body = {
model: options.model || "gpt-4.1",
messages: build_openai_messages(messages, options.history, options.system_prompt)
}.tap do |b|
b[:n] = options.n if options.n
b[:max_tokens] = options.max_tokens if options.max_tokens
b[:temperature] = options.temperature if options.temperature
b[:stream] = options.stream if options.stream
b[:seed] = options.seed if options.seed
if options.schema && options.schema_name
b[:response_format] = {
type: "json_schema",
json_schema: {
name: T.must(options.schema_name).downcase,
strict: true,
schema: Rager::Chat::Schema.dry_schema_to_json_schema(T.must(options.schema))
}
}
end
end
= {"Content-Type" => "application/json"}
["Authorization"] = "Bearer #{api_key}" if api_key
request = Rager::Http::Request.new(
verb: Rager::Http::Verb::Post,
url: "#{base_url}/chat/completions",
headers: ,
body: body.to_json,
streaming: options.stream || false,
timeout: options.timeout || Rager.config.timeout
)
response = Rager.config.http_adapter.make_request(request)
response_body = T.must(response.body)
raise Rager::Errors::HttpError.new(Rager.config.http_adapter, request.url, response.status, body: T.cast(response_body, String)) if response.status != 200
case response_body
when String then handle_non_stream_body(response_body)
when Enumerator then handle_stream_body(response_body)
end
end
|