intelligence 0.5.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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'