Module: Boxcars::OpenAIClient
- Defined in:
- lib/boxcars/openai_client.rb
Overview
Centralized factory for OpenAI-compatible clients used by multiple engines (OpenAI, Groq, Ollama, Gemini-compatible endpoints, etc.).
Defined Under Namespace
Modules: ClientMethods
Class Attribute Summary collapse
-
.official_client_builder ⇒ Object
Returns the value of attribute official_client_builder.
Class Method Summary collapse
- .build(access_token:, uri_base: nil, organization_id: nil, log_errors: nil) ⇒ Object
-
.call_chat(client, parameters) ⇒ Object
————————————————————————– Request helpers used by ClientMethods ————————————————————————–.
- .call_completions(client, parameters) ⇒ Object
- .call_embeddings(client, parameters) ⇒ Object
- .call_responses(client, parameters) ⇒ Object
- .decorate_client(client) ⇒ Object
- .install_official_client_builder!(client_class: nil) ⇒ Object
- .normalize_response(obj) ⇒ Object
- .validate_client_configuration! ⇒ Object
Class Attribute Details
.official_client_builder ⇒ Object
Returns the value of attribute official_client_builder.
32 33 34 |
# File 'lib/boxcars/openai_client.rb', line 32 def official_client_builder @official_client_builder end |
Class Method Details
.build(access_token:, uri_base: nil, organization_id: nil, log_errors: nil) ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/boxcars/openai_client.rb', line 43 def self.build(access_token:, uri_base: nil, organization_id: nil, log_errors: nil) raw_client = build_official_openai_client( access_token:, uri_base:, organization_id:, log_errors: ) decorate_client(raw_client) end |
.call_chat(client, parameters) ⇒ Object
Request helpers used by ClientMethods
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/boxcars/openai_client.rb', line 108 def self.call_chat(client, parameters) raise Boxcars::ConfigurationError, "Official OpenAI client does not expose #chat" unless client.respond_to?(:chat) chat_resource = client.chat return chat_resource if chat_resource.is_a?(Hash) if chat_resource.respond_to?(:completions) call_create(chat_resource.completions, parameters) elsif chat_resource.respond_to?(:create) call_create(chat_resource, parameters) else raise Boxcars::ConfigurationError, "Official OpenAI client chat resource does not support #create" end end |
.call_completions(client, parameters) ⇒ Object
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/boxcars/openai_client.rb', line 123 def self.call_completions(client, parameters) unless client.respond_to?(:completions) raise Boxcars::ConfigurationError, "Official OpenAI client does not expose #completions" end completions_resource = client.completions return completions_resource if completions_resource.is_a?(Hash) call_create(completions_resource, parameters) end |
.call_embeddings(client, parameters) ⇒ Object
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/boxcars/openai_client.rb', line 142 def self.(client, parameters) unless client.respond_to?(:embeddings) raise Boxcars::ConfigurationError, "Official OpenAI client does not expose #embeddings" end = client. return if .is_a?(Hash) call_create(, parameters) end |
.call_responses(client, parameters) ⇒ Object
134 135 136 137 138 139 140 |
# File 'lib/boxcars/openai_client.rb', line 134 def self.call_responses(client, parameters) unless client.respond_to?(:responses) raise StandardError, "OpenAI Responses API not supported by the official OpenAI client." end call_create(client.responses, parameters) end |
.decorate_client(client) ⇒ Object
170 171 172 173 174 175 176 |
# File 'lib/boxcars/openai_client.rb', line 170 def self.decorate_client(client) client.extend(ClientMethods) client rescue TypeError raise Boxcars::ConfigurationError, "Official OpenAI client object must be extensible or already implement *_create methods." end |
.install_official_client_builder!(client_class: nil) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/boxcars/openai_client.rb', line 70 def self.install_official_client_builder!(client_class: nil) ensure_openai_dependency! klass = client_class || detect_official_client_class return false unless klass self.official_client_builder = lambda do |access_token:, uri_base:, organization_id:, log_errors:| build_with_official_client_class( klass:, access_token:, uri_base:, organization_id:, log_errors: ) end true end |
.normalize_response(obj) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/boxcars/openai_client.rb', line 153 def self.normalize_response(obj) case obj when Hash obj.each_with_object({}) do |(k, v), memo| memo[k.to_s] = normalize_response(v) end when Array obj.map { |v| normalize_response(v) } else if obj.respond_to?(:to_h) normalize_response(obj.to_h) else obj end end end |
.validate_client_configuration! ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/boxcars/openai_client.rb', line 54 def self.validate_client_configuration! ensure_openai_dependency! builder = official_client_builder || Boxcars.configuration.openai_official_client_builder return true if builder return true if detect_official_client_class if official_client_requires_native? raise Boxcars::ConfigurationError, "Official OpenAI client path is configured in native-only mode, but no native official OpenAI client was detected." end raise Boxcars::ConfigurationError, "Official OpenAI client path selected but no official client builder is configured " \ "and no compatible OpenAI::Client was detected." end |