Class: LexLLM::Provider
- Inherits:
-
Object
- Object
- LexLLM::Provider
- Includes:
- Streaming
- Defined in:
- lib/lex_llm/provider.rb
Overview
Base class for LLM providers.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
Class Method Summary collapse
- .assume_models_exist? ⇒ Boolean
- .capabilities ⇒ Object
- .configuration_options ⇒ Object
- .configuration_requirements ⇒ Object
- .configured?(config) ⇒ Boolean
- .configured_providers(config) ⇒ Object
- .configured_remote_providers(config) ⇒ Object
- .for(model) ⇒ Object
- .local? ⇒ Boolean
- .local_providers ⇒ Object
- .name ⇒ Object
- .providers ⇒ Object
- .register(name, provider_class) ⇒ Object
- .remote? ⇒ Boolean
- .remote_providers ⇒ Object
- .resolve(name) ⇒ Object
-
.resolve_model_id(model_id, config: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument.
- .slug ⇒ Object
Instance Method Summary collapse
- #api_base ⇒ Object
- #assume_models_exist? ⇒ Boolean
- #capabilities ⇒ Object
-
#complete(messages, tools:, temperature:, model:, params: {}, headers: {}, schema: nil, thinking: nil, tool_prefs: nil) ⇒ Object
rubocop:disable Metrics/ParameterLists.
- #configuration_requirements ⇒ Object
- #configured? ⇒ Boolean
- #embed(text, model:, dimensions:) ⇒ Object
- #format_messages(messages) ⇒ Object
- #format_tool_calls(_tool_calls) ⇒ Object
- #headers ⇒ Object
-
#initialize(config) ⇒ Provider
constructor
A new instance of Provider.
-
#list_models ⇒ Object
rubocop:enable Metrics/ParameterLists.
- #local? ⇒ Boolean
- #moderate(input, model:) ⇒ Object
- #name ⇒ Object
-
#paint(prompt, model:, size:, with: nil, mask: nil, params: {}) ⇒ Object
rubocop:disable Metrics/ParameterLists.
- #parse_error(response) ⇒ Object
- #parse_tool_calls(_tool_calls) ⇒ Object
- #remote? ⇒ Boolean
- #slug ⇒ Object
- #transcribe(audio_file, model:, language:) ⇒ Object
Methods included from Streaming
build_on_data_handler, build_stream_error_response, error_chunk?, faraday_1?, handle_data, handle_error_chunk, handle_error_event, handle_failed_response, handle_json_error_chunk, handle_parsed_error, handle_sse, handle_stream, json_error_payload?, parse_error_from_json, parse_streaming_error, process_stream_chunk, stream_response
Constructor Details
#initialize(config) ⇒ Provider
Returns a new instance of Provider.
10 11 12 13 14 |
# File 'lib/lex_llm/provider.rb', line 10 def initialize(config) @config = config ensure_configured! @connection = Connection.new(self, @config) end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
8 9 10 |
# File 'lib/lex_llm/provider.rb', line 8 def config @config end |
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
8 9 10 |
# File 'lib/lex_llm/provider.rb', line 8 def connection @connection end |
Class Method Details
.assume_models_exist? ⇒ Boolean
180 181 182 |
# File 'lib/lex_llm/provider.rb', line 180 def assume_models_exist? false end |
.capabilities ⇒ Object
160 161 162 |
# File 'lib/lex_llm/provider.rb', line 160 def capabilities nil end |
.configuration_options ⇒ Object
168 169 170 |
# File 'lib/lex_llm/provider.rb', line 168 def [] end |
.configuration_requirements ⇒ Object
164 165 166 |
# File 'lib/lex_llm/provider.rb', line 164 def configuration_requirements [] end |
.configured?(config) ⇒ Boolean
188 189 190 |
# File 'lib/lex_llm/provider.rb', line 188 def configured?(config) configuration_requirements.all? { |req| config.send(req) } end |
.configured_providers(config) ⇒ Object
220 221 222 223 224 |
# File 'lib/lex_llm/provider.rb', line 220 def configured_providers(config) providers.select do |_slug, provider_class| provider_class.configured?(config) end.values end |
.configured_remote_providers(config) ⇒ Object
226 227 228 229 230 |
# File 'lib/lex_llm/provider.rb', line 226 def configured_remote_providers(config) providers.select do |_slug, provider_class| provider_class.remote? && provider_class.configured?(config) end.values end |
.for(model) ⇒ Object
203 204 205 206 |
# File 'lib/lex_llm/provider.rb', line 203 def for(model) model_info = Models.find(model) resolve model_info.provider end |
.local? ⇒ Boolean
172 173 174 |
# File 'lib/lex_llm/provider.rb', line 172 def local? false end |
.local_providers ⇒ Object
212 213 214 |
# File 'lib/lex_llm/provider.rb', line 212 def local_providers providers.select { |_slug, provider_class| provider_class.local? } end |
.name ⇒ Object
152 153 154 |
# File 'lib/lex_llm/provider.rb', line 152 def name to_s.split('::').last end |
.providers ⇒ Object
208 209 210 |
# File 'lib/lex_llm/provider.rb', line 208 def providers @providers ||= {} end |
.register(name, provider_class) ⇒ Object
192 193 194 195 |
# File 'lib/lex_llm/provider.rb', line 192 def register(name, provider_class) providers[name.to_sym] = provider_class LexLLM::Configuration.(provider_class.) end |
.remote? ⇒ Boolean
176 177 178 |
# File 'lib/lex_llm/provider.rb', line 176 def remote? !local? end |
.remote_providers ⇒ Object
216 217 218 |
# File 'lib/lex_llm/provider.rb', line 216 def remote_providers providers.select { |_slug, provider_class| provider_class.remote? } end |
.resolve(name) ⇒ Object
197 198 199 200 201 |
# File 'lib/lex_llm/provider.rb', line 197 def resolve(name) return nil if name.nil? providers[name.to_sym] end |
.resolve_model_id(model_id, config: nil) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument
184 185 186 |
# File 'lib/lex_llm/provider.rb', line 184 def resolve_model_id(model_id, config: nil) # rubocop:disable Lint/UnusedMethodArgument model_id end |
.slug ⇒ Object
156 157 158 |
# File 'lib/lex_llm/provider.rb', line 156 def slug name.downcase end |
Instance Method Details
#api_base ⇒ Object
16 17 18 |
# File 'lib/lex_llm/provider.rb', line 16 def api_base raise NotImplementedError end |
#assume_models_exist? ⇒ Boolean
110 111 112 |
# File 'lib/lex_llm/provider.rb', line 110 def assume_models_exist? self.class.assume_models_exist? end |
#capabilities ⇒ Object
32 33 34 |
# File 'lib/lex_llm/provider.rb', line 32 def capabilities self.class.capabilities end |
#complete(messages, tools:, temperature:, model:, params: {}, headers: {}, schema: nil, thinking: nil, tool_prefs: nil) ⇒ Object
rubocop:disable Metrics/ParameterLists
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/lex_llm/provider.rb', line 41 def complete(, tools:, temperature:, model:, params: {}, headers: {}, schema: nil, thinking: nil, tool_prefs: nil, &) normalized_temperature = maybe_normalize_temperature(temperature, model) payload = Utils.deep_merge( render_payload( , tools: tools, tool_prefs: tool_prefs, temperature: normalized_temperature, model: model, stream: block_given?, schema: schema, thinking: thinking ), params ) if block_given? stream_response @connection, payload, headers, & else sync_response @connection, payload, headers end end |
#configuration_requirements ⇒ Object
36 37 38 |
# File 'lib/lex_llm/provider.rb', line 36 def configuration_requirements self.class.configuration_requirements end |
#configured? ⇒ Boolean
98 99 100 |
# File 'lib/lex_llm/provider.rb', line 98 def configured? configuration_requirements.all? { |req| @config.send(req) } end |
#embed(text, model:, dimensions:) ⇒ Object
72 73 74 75 76 |
# File 'lib/lex_llm/provider.rb', line 72 def (text, model:, dimensions:) payload = (text, model:, dimensions:) response = @connection.post((model:), payload) (response, model:, text:) end |
#format_messages(messages) ⇒ Object
134 135 136 137 138 139 140 141 |
# File 'lib/lex_llm/provider.rb', line 134 def () .map do |msg| { role: msg.role.to_s, content: msg.content } end end |
#format_tool_calls(_tool_calls) ⇒ Object
143 144 145 |
# File 'lib/lex_llm/provider.rb', line 143 def format_tool_calls(_tool_calls) nil end |
#headers ⇒ Object
20 21 22 |
# File 'lib/lex_llm/provider.rb', line 20 def headers {} end |
#list_models ⇒ Object
rubocop:enable Metrics/ParameterLists
67 68 69 70 |
# File 'lib/lex_llm/provider.rb', line 67 def list_models response = @connection.get models_url parse_list_models_response response, slug, capabilities end |
#local? ⇒ Boolean
102 103 104 |
# File 'lib/lex_llm/provider.rb', line 102 def local? self.class.local? end |
#moderate(input, model:) ⇒ Object
78 79 80 81 82 |
# File 'lib/lex_llm/provider.rb', line 78 def moderate(input, model:) payload = render_moderation_payload(input, model:) response = @connection.post moderation_url, payload parse_moderation_response(response, model:) end |
#name ⇒ Object
28 29 30 |
# File 'lib/lex_llm/provider.rb', line 28 def name self.class.name end |
#paint(prompt, model:, size:, with: nil, mask: nil, params: {}) ⇒ Object
rubocop:disable Metrics/ParameterLists
84 85 86 87 88 89 |
# File 'lib/lex_llm/provider.rb', line 84 def paint(prompt, model:, size:, with: nil, mask: nil, params: {}) # rubocop:disable Metrics/ParameterLists validate_paint_inputs!(with:, mask:) payload = render_image_payload(prompt, model:, size:, with:, mask:, params:) response = @connection.post images_url(with:, mask:), payload parse_image_response(response, model:) end |
#parse_error(response) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/lex_llm/provider.rb', line 114 def parse_error(response) return if response.body.empty? body = try_parse_json(response.body) case body when Hash error = body['error'] return error if error.is_a?(String) body.dig('error', 'message') when Array body.map do |part| error = part['error'] error.is_a?(String) ? error : part.dig('error', 'message') end.join('. ') else body end end |
#parse_tool_calls(_tool_calls) ⇒ Object
147 148 149 |
# File 'lib/lex_llm/provider.rb', line 147 def parse_tool_calls(_tool_calls) nil end |
#remote? ⇒ Boolean
106 107 108 |
# File 'lib/lex_llm/provider.rb', line 106 def remote? self.class.remote? end |
#slug ⇒ Object
24 25 26 |
# File 'lib/lex_llm/provider.rb', line 24 def slug self.class.slug end |
#transcribe(audio_file, model:, language:) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/lex_llm/provider.rb', line 91 def transcribe(audio_file, model:, language:, **) file_part = build_audio_file_part(audio_file) payload = render_transcription_payload(file_part, model:, language:, **) response = @connection.post transcription_url, payload parse_transcription_response(response, model:) end |