intelligence 0.5.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +555 -0
  3. data/intelligence.gemspec +1 -1
  4. data/lib/intelligence/adapter/base.rb +23 -3
  5. data/lib/intelligence/adapter/class_methods.rb +15 -0
  6. data/lib/intelligence/adapter/{construction_methods.rb → module_methods.rb} +8 -4
  7. data/lib/intelligence/adapter.rb +2 -2
  8. data/lib/intelligence/adapters/anthropic/adapter.rb +21 -30
  9. data/lib/intelligence/adapters/anthropic/chat_request_methods.rb +189 -0
  10. data/lib/intelligence/adapters/anthropic/{chat_methods.rb → chat_response_methods.rb} +8 -124
  11. data/lib/intelligence/adapters/cerebras.rb +17 -17
  12. data/lib/intelligence/adapters/generic/adapter.rb +1 -12
  13. data/lib/intelligence/adapters/generic/chat_methods.rb +42 -11
  14. data/lib/intelligence/adapters/generic.rb +1 -1
  15. data/lib/intelligence/adapters/google/adapter.rb +33 -35
  16. data/lib/intelligence/adapters/google/chat_request_methods.rb +233 -0
  17. data/lib/intelligence/adapters/google/{chat_methods.rb → chat_response_methods.rb} +52 -162
  18. data/lib/intelligence/adapters/groq.rb +46 -28
  19. data/lib/intelligence/adapters/hyperbolic.rb +13 -13
  20. data/lib/intelligence/adapters/legacy/adapter.rb +0 -2
  21. data/lib/intelligence/adapters/legacy/chat_methods.rb +22 -6
  22. data/lib/intelligence/adapters/mistral.rb +57 -0
  23. data/lib/intelligence/adapters/open_ai/adapter.rb +38 -45
  24. data/lib/intelligence/adapters/open_ai/chat_request_methods.rb +186 -0
  25. data/lib/intelligence/adapters/open_ai/{chat_methods.rb → chat_response_methods.rb} +60 -131
  26. data/lib/intelligence/adapters/open_ai.rb +1 -1
  27. data/lib/intelligence/adapters/open_router.rb +62 -0
  28. data/lib/intelligence/adapters/samba_nova.rb +13 -13
  29. data/lib/intelligence/adapters/together_ai.rb +21 -19
  30. data/lib/intelligence/chat_request.rb +57 -7
  31. data/lib/intelligence/chat_result.rb +4 -0
  32. data/lib/intelligence/chat_result_choice.rb +4 -2
  33. data/lib/intelligence/conversation.rb +38 -9
  34. data/lib/intelligence/message.rb +103 -20
  35. data/lib/intelligence/message_content/base.rb +3 -0
  36. data/lib/intelligence/message_content/binary.rb +6 -0
  37. data/lib/intelligence/message_content/file.rb +35 -0
  38. data/lib/intelligence/message_content/text.rb +5 -0
  39. data/lib/intelligence/message_content/tool_call.rb +12 -1
  40. data/lib/intelligence/message_content/tool_result.rb +15 -3
  41. data/lib/intelligence/message_content.rb +12 -3
  42. data/lib/intelligence/tool.rb +139 -0
  43. data/lib/intelligence/version.rb +1 -1
  44. data/lib/intelligence.rb +6 -4
  45. metadata +18 -9
@@ -7,19 +7,19 @@ module Intelligence
7
7
 
8
8
  chat_request_uri "https://api.hyperbolic.xyz/v1/chat/completions"
9
9
 
10
- configuration do
11
- parameter :key, String, required: true
12
- group :chat_options do
13
- parameter :model, String
14
- parameter :temperature, Float
15
- parameter :top_p, Float
16
- parameter :n, Integer
17
- parameter :max_tokens, Integer
18
- parameter :stop, String, array: true
19
- parameter :stream, [ TrueClass, FalseClass ]
20
- parameter :frequency_penalty, Float
21
- parameter :presence_penalty, Float
22
- parameter :user, String
10
+ schema do
11
+ key String
12
+ chat_options do
13
+ model String
14
+ temperature Float
15
+ top_p Float
16
+ n Integer
17
+ max_tokens Integer
18
+ stop String, array: true
19
+ stream [ TrueClass, FalseClass ]
20
+ frequency_penalty Float
21
+ presence_penalty Float
22
+ user String
23
23
  end
24
24
  end
25
25
 
@@ -3,11 +3,9 @@ require_relative 'chat_methods'
3
3
 
4
4
  module Intelligence
5
5
  module Legacy
6
-
7
6
  class Adapter < Generic::Adapter
8
7
  include ChatMethods
9
8
  end
10
-
11
9
  end
12
10
  end
13
11
 
@@ -3,20 +3,36 @@ module Intelligence
3
3
  module ChatMethods
4
4
 
5
5
  def chat_request_body( conversation, options = {} )
6
- result = self.chat_options.merge( options ).compact
6
+ options = @options.merge( to_options( options ) )
7
+
8
+ result = options[ :chat_options ]&.compact || {}
7
9
  result[ :messages ] = []
8
10
 
9
11
  system_message = system_message_to_s( conversation[ :system_message ] )
10
12
  result[ :messages ] << { role: 'system', content: system_message } if system_message
11
-
12
- conversation[ :messages ]&.each do | message |
13
- result[ :messages ] << chat_request_message_attributes( message )
13
+
14
+ # detect if the conversation has any non-text content; this handles the sittuation
15
+ # where non-vision models only support the legacy message schema while the vision
16
+ # models only support the modern message schema
17
+ has_non_text_content = conversation[ :messages ]&.find do | message |
18
+ message[ :contents ]&.find do | content |
19
+ content[ :type ] != nil && content[ :type ] != :text
20
+ end
21
+ end
22
+
23
+ if has_non_text_content
24
+ conversation[ :messages ]&.each do | message |
25
+ result[ :messages ] << chat_request_message_attributes( message )
26
+ end
27
+ else
28
+ conversation[ :messages ]&.each do | message |
29
+ result[ :messages ] << chat_request_legacy_message_attributes( message )
30
+ end
14
31
  end
15
-
16
32
  JSON.generate( result )
17
33
  end
18
34
 
19
- def chat_request_message_attributes( message )
35
+ def chat_request_legacy_message_attributes( message )
20
36
  result_message = { role: message[ :role ] }
21
37
  result_message_content = ""
22
38
 
@@ -0,0 +1,57 @@
1
+ require_relative 'legacy/adapter'
2
+
3
+ module Intelligence
4
+ module Mistral
5
+
6
+ class Adapter < Legacy::Adapter
7
+
8
+ chat_request_uri "https://api.mistral.ai/v1/chat/completions"
9
+
10
+ schema do
11
+ key String
12
+ chat_options do
13
+ model String
14
+ temperature Float
15
+ top_p Float
16
+ max_tokens Integer
17
+ min_tokens Integer
18
+ seed Integer, as: :random_seed
19
+ stop String, array: true
20
+ stream [ TrueClass, FalseClass ]
21
+
22
+ random_seed Integer
23
+ response_format do
24
+ type String
25
+ end
26
+ tool_choice do
27
+ type String
28
+ function do
29
+ name String
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ alias chat_request_generic_message_attributes chat_request_message_attributes
36
+
37
+ # mistral vision models only support the legacy Open AI message schema for the assistant
38
+ # messages while supporting the modern message schema for user messages :facepalm:
39
+ def chat_request_message_attributes( message )
40
+ role = message[ :role ]&.to_sym
41
+ case role
42
+ when :user
43
+ chat_request_generic_message_attributes( message )
44
+ when :assistant
45
+ chat_request_legacy_message_attributes( message )
46
+ else
47
+ raise UnsupportedContentError.new(
48
+ :mistral,
49
+ 'only supports user and assistant message roles'
50
+ )
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
@@ -1,74 +1,67 @@
1
- require_relative 'chat_methods'
1
+ require_relative 'chat_request_methods'
2
+ require_relative 'chat_response_methods'
2
3
 
3
4
  module Intelligence
4
5
  module OpenAi
5
6
  class Adapter < Adapter::Base
6
7
 
7
- configuration do
8
+ schema do
8
9
 
9
10
  # normalized properties for all endpoints
10
- parameter :key, String, required: true
11
+ key String
11
12
 
12
13
  # openai properties for all endpoints
13
- parameter :organization
14
- parameter :project
14
+ organization String
15
+ project String
15
16
 
16
17
  # properties for generative text endpoints
17
- group :chat_options do
18
+ chat_options do
18
19
 
19
20
  # normalized properties for openai generative text endpoint
20
- parameter :model, String, required: true
21
- parameter :n, Integer
22
- parameter :max_tokens, Integer, as: :max_completion_tokens
23
- parameter :temperature, Float
24
- parameter :top_p, Float
25
- parameter :seed, Integer
26
- parameter :stop, String, array: true
27
- parameter :stream, [ TrueClass, FalseClass ]
21
+ model String, requried: true
22
+ n Integer
23
+ max_tokens Integer, as: :max_completion_tokens
24
+ temperature Float
25
+ top_p Float
26
+ seed Integer
27
+ stop String, array: true
28
+ stream [ TrueClass, FalseClass ]
28
29
 
29
- parameter :frequency_penalty, Float
30
- parameter :presence_penalty, Float
30
+ frequency_penalty Float
31
+ presence_penalty Float
31
32
 
32
33
  # openai variant of normalized properties for openai generative text endpoints
33
- parameter :max_completion_tokens, Integer
34
+ max_completion_tokens Integer
34
35
 
35
36
  # openai properties for openai generative text endpoint
36
- parameter :logit_bias
37
- parameter :logprobs, [ TrueClass, FalseClass ]
38
- parameter :parallel_tool_calls, [ TrueClass, FalseClass ]
39
- group :response_format do
37
+ audio do
38
+ voice String
39
+ format String
40
+ end
41
+ logit_bias
42
+ logprobs [ TrueClass, FalseClass ]
43
+ modalities String, array: true
44
+ # the parallel_tool_calls parameter is only allowed when 'tools' are specified
45
+ parallel_tool_calls [ TrueClass, FalseClass ]
46
+ response_format do
40
47
  # 'text' and 'json_schema' are the only supported types
41
- parameter :type, String
42
- parameter :json_schema
48
+ type Symbol, in: [ :text, :json_schema ]
49
+ json_schema
43
50
  end
44
- parameter :service_tier, String
45
- group :stream_options do
46
- parameter :include_usage, [ TrueClass, FalseClass ]
51
+ service_tier String
52
+ stream_options do
53
+ include_usage [ TrueClass, FalseClass ]
47
54
  end
48
- parameter :tool_choice
49
- # the parallel_tool_calls parameter is only allowed when 'tools' are specified
50
- parameter :top_logprobs, Integer
51
- parameter :user
55
+ tool_choice
56
+ top_logprobs Integer
57
+ user
52
58
 
53
59
  end
54
60
 
55
61
  end
56
62
 
57
- attr_reader :key
58
- attr_reader :organization
59
- attr_reader :project
60
- attr_reader :chat_options
61
-
62
-
63
- def initialize( attributes = nil, &block )
64
- configuration = self.class.configure( attributes, &block )
65
- @key = configuration[ :key ]
66
- @organization = configuration[ :organization ]
67
- @project = configuration[ :project ]
68
- @chat_options = configuration[ :chat_options ] || {}
69
- end
70
-
71
- include ChatMethods
63
+ include ChatRequestMethods
64
+ include ChatResponseMethods
72
65
 
73
66
  end
74
67
  end
@@ -0,0 +1,186 @@
1
+ module Intelligence
2
+ module OpenAi
3
+ module ChatRequestMethods
4
+
5
+ CHAT_REQUEST_URI = "https://api.openai.com/v1/chat/completions"
6
+
7
+ SUPPORTED_CONTENT_TYPES = [ 'image/jpeg', 'image/png' ]
8
+
9
+ def chat_request_uri( options )
10
+ CHAT_REQUEST_URI
11
+ end
12
+
13
+ def chat_request_headers( options = {} )
14
+ options = @options.merge( build_options( options ) )
15
+ result = {}
16
+
17
+ key = options[ :key ]
18
+ organization = options[ :organization ]
19
+ project = options[ :project ]
20
+
21
+ raise ArgumentError.new( "An OpenAI key is required to build an OpenAI chat request." ) \
22
+ if key.nil?
23
+
24
+ result[ 'Content-Type' ] = 'application/json'
25
+ result[ 'Authorization' ] = "Bearer #{key}"
26
+ result[ 'OpenAI-Organization' ] = organization unless organization.nil?
27
+ result[ 'OpenAI-Project' ] = project unless project.nil?
28
+
29
+ result
30
+ end
31
+
32
+ def chat_request_body( conversation, options = {} )
33
+ options = @options.merge( build_options( options ) )
34
+ result = options[ :chat_options ]&.compact || {}
35
+ result[ :messages ] = []
36
+
37
+ system_message = to_open_ai_system_message( conversation[ :system_message ] )
38
+ result[ :messages ] << { role: 'system', content: system_message } if system_message
39
+
40
+ conversation[ :messages ]&.each do | message |
41
+
42
+ result_message = { role: message[ :role ] }
43
+ result_message_content = []
44
+
45
+ message[ :contents ]&.each do | content |
46
+ case content[ :type ]
47
+ when :text
48
+ result_message_content << { type: 'text', text: content[ :text ] }
49
+ when :binary
50
+ content_type = content[ :content_type ]
51
+ bytes = content[ :bytes ]
52
+ if content_type && bytes
53
+ if SUPPORTED_CONTENT_TYPES.include?( content_type )
54
+ result_message_content << {
55
+ type: 'image_url',
56
+ image_url: {
57
+ url: "data:#{content_type};base64,#{Base64.strict_encode64( bytes )}".freeze
58
+ }
59
+ }
60
+ else
61
+ raise UnsupportedContentError.new(
62
+ :open_ai,
63
+ "only supports content of type #{SUPPORTED_CONTENT_TYPES.join( ', ' )}"
64
+ )
65
+ end
66
+ else
67
+ raise UnsupportedContentError.new(
68
+ :open_ai,
69
+ 'requires binary content to include content type and ( packed ) bytes'
70
+ )
71
+ end
72
+ when :file
73
+ content_type = content[ :content_type ]
74
+ uri = content[ :uri ]
75
+ if content_type && uri
76
+ if SUPPORTED_CONTENT_TYPES.include?( content_type )
77
+ result_message_content << {
78
+ type: 'image_url',
79
+ image_url: {
80
+ url: uri
81
+ }
82
+ }
83
+ else
84
+ raise UnsupportedContentError.new(
85
+ :open_ai,
86
+ "only supports content of type #{SUPPORTED_CONTENT_TYPES.join( ', ' )}"
87
+ )
88
+ end
89
+ else
90
+ raise UnsupportedContentError.new(
91
+ :open_ai,
92
+ 'requires file content to include content type and uri'
93
+ )
94
+ end
95
+ when :tool_call
96
+ tool_calls = result_message[ :tool_calls ] || []
97
+ function = {
98
+ name: content[ :tool_name ]
99
+ }
100
+ function[ :arguments ] = JSON.generate( content[ :tool_parameters ] || {} )
101
+ tool_calls << { id: content[ :tool_call_id ], type: 'function', function: function }
102
+ result_message[ :tool_calls ] = tool_calls
103
+ when :tool_result
104
+ # open-ai returns tool results as a message with a role of 'tool'
105
+ result[ :messages ] << {
106
+ role: :tool,
107
+ tool_call_id: content[ :tool_call_id ],
108
+ content: content[ :tool_result ]
109
+ }
110
+ else
111
+ raise InvalidContentError.new( :open_ai )
112
+ end
113
+
114
+ end
115
+
116
+ result_message[ :content ] = result_message_content
117
+ result[ :messages ] << result_message \
118
+ if result_message[ :content ]&.any? || result_message[ :tool_calls ]&.any?
119
+ result
120
+
121
+ end
122
+
123
+ tools_attributes = chat_request_tools_attributes( conversation[ :tools ] )
124
+ result[ :tools ] = tools_attributes if tools_attributes && tools_attributes.length > 0
125
+
126
+ JSON.generate( result )
127
+ end
128
+
129
+ def chat_request_tools_attributes( tools )
130
+ properties_array_to_object = lambda do | properties |
131
+ return nil unless properties&.any?
132
+ object = {}
133
+ required = []
134
+ properties.each do | property |
135
+ name = property.delete( :name )
136
+ required << name if property.delete( :required )
137
+ if property[ :properties ]&.any?
138
+ property_properties, property_required =
139
+ properties_array_to_object.call( property[ :properties ] )
140
+ property[ :properties ] = property_properties
141
+ property[ :required ] = property_required if property_required.any?
142
+ end
143
+ object[ name ] = property
144
+ end
145
+ [ object, required.compact ]
146
+ end
147
+
148
+ tools&.map do | tool |
149
+ function = {
150
+ type: 'function',
151
+ function: {
152
+ name: tool[ :name ],
153
+ description: tool[ :description ],
154
+ }
155
+ }
156
+
157
+ if tool[ :properties ]&.any?
158
+ properties_object, properties_required =
159
+ properties_array_to_object.call( tool[ :properties ] )
160
+ function[ :function ][ :parameters ] = {
161
+ type: 'object',
162
+ properties: properties_object
163
+ }
164
+ function[ :function ][ :parameters ][ :required ] = properties_required \
165
+ if properties_required.any?
166
+ end
167
+ function
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ def to_open_ai_system_message( system_message )
174
+ return nil if system_message.nil?
175
+
176
+ result = ''
177
+ system_message[ :contents ].each do | content |
178
+ result += content[ :text ] if content[ :type ] == :text
179
+ end
180
+
181
+ result.empty? ? nil : result
182
+ end
183
+
184
+ end
185
+ end
186
+ end
@@ -1,85 +1,9 @@
1
1
  module Intelligence
2
2
  module OpenAi
3
- module ChatMethods
4
-
5
- CHAT_REQUEST_URI = "https://api.openai.com/v1/chat/completions"
6
-
7
- def chat_request_uri( options )
8
- CHAT_REQUEST_URI
9
- end
10
-
11
- def chat_request_headers( options = {} )
12
- result = {}
13
-
14
- key = options[ :key ] || self.key
15
- organization = options[ :organization ] || self.organization
16
- project = options[ :project ] || self.project
17
-
18
- raise ArgumentError.new( "An OpenAI key is required to build an OpenAI chat request." ) \
19
- if key.nil?
20
-
21
- result[ 'Content-Type' ] = 'application/json'
22
- result[ 'Authorization' ] = "Bearer #{key}"
23
- result[ 'OpenAI-Organization' ] = organization unless organization.nil?
24
- result[ 'OpenAI-Project' ] = project unless project.nil?
25
-
26
- result
27
- end
28
-
29
- def chat_request_body( conversation, options = {} )
30
- result = self.chat_options.merge( options ).compact
31
- result[ :messages ] = []
32
-
33
- system_message = translate_system_message( conversation[ :system_message ] )
34
- result[ :messages ] << { role: 'system', content: system_message } if system_message
35
-
36
- conversation[ :messages ]&.each do | message |
37
-
38
- result_message = { role: message[ :role ] }
39
- result_message_content = []
40
-
41
- message[ :contents ]&.each do | content |
42
- case content[ :type ]
43
- when :text
44
- result_message_content << { type: 'text', text: content[ :text ] }
45
- when :binary
46
- content_type = content[ :content_type ]
47
- bytes = content[ :bytes ]
48
- if content_type && bytes
49
- mime_type = MIME::Types[ content_type ].first
50
- if mime_type&.media_type == 'image'
51
- result_message_content << {
52
- type: 'image_url',
53
- image_url: {
54
- url: "data:#{content_type};base64,#{Base64.strict_encode64( bytes )}".freeze
55
- }
56
- }
57
- else
58
- raise UnsupportedContentError.new(
59
- :open_ai,
60
- 'only supports content of type image/*'
61
- )
62
- end
63
- else
64
- raise UnsupportedContentError.new(
65
- :open_ai,
66
- 'requires binary content to include content type and ( packed ) bytes'
67
- )
68
- end
69
- end
70
- end
71
-
72
- result_message[ :content ] = result_message_content
73
- result[ :messages ] << result_message
74
-
75
- end
76
-
77
- JSON.generate( result )
78
- end
3
+ module ChatResponseMethods
79
4
 
80
5
  def chat_result_attributes( response )
81
6
  return nil unless response.success?
82
-
83
7
  response_json = JSON.parse( response.body, symbolize_names: true ) rescue nil
84
8
  return nil \
85
9
  if response_json.nil? || response_json[ :choices ].nil?
@@ -89,15 +13,31 @@ module Intelligence
89
13
 
90
14
  ( response_json[ :choices ] || [] ).each do | json_choice |
91
15
  json_message = json_choice[ :message ]
92
- result[ :choices ].push(
93
- {
94
- end_reason: translate_end_result( json_choice[ :finish_reason ] ),
95
- message: {
96
- role: json_message[ :role ],
97
- contents: [ { type: 'text', text: json_message[ :content ] } ]
98
- }
99
- }
100
- )
16
+ result_message = nil
17
+ if ( json_message )
18
+ result_message = { role: json_message[ :role ] }
19
+ if json_message[ :content ]
20
+ result_message[ :contents ] = [ { type: :text, text: json_message[ :content ] } ]
21
+ end
22
+ if json_message[ :tool_calls ] && !json_message[ :tool_calls ].empty?
23
+ result_message[ :contents ] ||= []
24
+ json_message[ :tool_calls ].each do | json_message_tool_call |
25
+ result_message_tool_call_parameters =
26
+ JSON.parse( json_message_tool_call[ :function ][ :arguments ], symbolize_names: true ) \
27
+ rescue json_message_tool_call[ :function ][ :arguments ]
28
+ result_message[ :contents ] << {
29
+ type: :tool_call,
30
+ tool_call_id: json_message_tool_call[ :id ],
31
+ tool_name: json_message_tool_call[ :function ][ :name ],
32
+ tool_parameters: result_message_tool_call_parameters
33
+ }
34
+ end
35
+ end
36
+ end
37
+ result[ :choices ].push( {
38
+ end_reason: translate_end_result( json_choice[ :finish_reason ] ),
39
+ message: result_message
40
+ } )
101
41
  end
102
42
 
103
43
  metrics_json = response_json[ :usage ]
@@ -244,26 +184,15 @@ module Intelligence
244
184
 
245
185
  alias_method :stream_result_error_attributes, :chat_result_error_attributes
246
186
 
247
- private; def translate_system_message( system_message )
187
+ private
248
188
 
249
- return nil if system_message.nil?
250
-
251
- result = ''
252
- system_message[ :contents ].each do | content |
253
- result += content[ :text ] if content[ :type ] == :text
254
- end
255
-
256
- result.empty? ? nil : result
257
-
258
- end
259
-
260
- private; def translate_end_result( end_result )
189
+ def translate_end_result( end_result )
261
190
  case end_result
262
191
  when 'stop'
263
192
  :ended
264
193
  when 'length'
265
194
  :token_limit_exceeded
266
- when 'function_call'
195
+ when 'tool_calls'
267
196
  :tool_called
268
197
  when 'content_filter'
269
198
  :filtered
@@ -274,37 +203,37 @@ module Intelligence
274
203
 
275
204
  def translate_error_response_status( status )
276
205
  case status
277
- when 400
278
- [ :invalid_request_error,
279
- "There was an issue with the format or content of your request." ]
280
- when 401
281
- [ :authentication_error,
282
- "There's an issue with your API key." ]
283
- when 403
284
- [ :permission_error,
285
- "Your API key does not have permission to use the specified resource." ]
286
- when 404
287
- [ :not_found_error,
288
- "The requested resource was not found." ]
289
- when 413
290
- [ :request_too_large,
291
- "Request exceeds the maximum allowed number of bytes." ]
292
- when 422
293
- [ :invalid_request_error,
294
- "There was an issue with the format or content of your request." ]
295
- when 429
296
- [ :rate_limit_error,
297
- "Your account has hit a rate limit." ]
298
- when 500, 502, 503
299
- [ :api_error,
300
- "An unexpected error has occurred internal to the providers systems." ]
301
- when 529
302
- [ :overloaded_error,
303
- "The providers server is temporarily overloaded." ]
304
- else
305
- [ :unknown_error, "
306
- An unknown error occurred." ]
307
- end
206
+ when 400
207
+ [ :invalid_request_error,
208
+ "There was an issue with the format or content of your request." ]
209
+ when 401
210
+ [ :authentication_error,
211
+ "There's an issue with your API key." ]
212
+ when 403
213
+ [ :permission_error,
214
+ "Your API key does not have permission to use the specified resource." ]
215
+ when 404
216
+ [ :not_found_error,
217
+ "The requested resource was not found." ]
218
+ when 413
219
+ [ :request_too_large,
220
+ "Request exceeds the maximum allowed number of bytes." ]
221
+ when 422
222
+ [ :invalid_request_error,
223
+ "There was an issue with the format or content of your request." ]
224
+ when 429
225
+ [ :rate_limit_error,
226
+ "Your account has hit a rate limit." ]
227
+ when 500, 502, 503
228
+ [ :api_error,
229
+ "An unexpected error has occurred internal to the providers systems." ]
230
+ when 529
231
+ [ :overloaded_error,
232
+ "The providers server is temporarily overloaded." ]
233
+ else
234
+ [ :unknown_error, "
235
+ An unknown error occurred." ]
236
+ end
308
237
  end
309
238
 
310
239
  end
@@ -1,2 +1,2 @@
1
1
  require_relative '../adapter'
2
- require_relative 'open_ai/adapter'
2
+ require_relative 'open_ai/adapter'