rager 0.6.0 → 0.7.0

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -27
  3. data/lib/rager/chat/message.rb +10 -0
  4. data/lib/rager/chat/message_content.rb +7 -0
  5. data/lib/rager/chat/message_delta.rb +7 -0
  6. data/lib/rager/chat/options.rb +6 -7
  7. data/lib/rager/chat/providers/openai.rb +49 -34
  8. data/lib/rager/chat/schema.rb +0 -2
  9. data/lib/rager/config.rb +12 -20
  10. data/lib/rager/context.rb +302 -186
  11. data/lib/rager/context_options.rb +23 -0
  12. data/lib/rager/embed/options.rb +3 -3
  13. data/lib/rager/embed/providers/openai.rb +7 -3
  14. data/lib/rager/errors/options_error.rb +1 -1
  15. data/lib/rager/http/adapters/async_http.rb +0 -2
  16. data/lib/rager/http/adapters/mock.rb +0 -2
  17. data/lib/rager/http/adapters/net_http.rb +18 -19
  18. data/lib/rager/{image_gen → image}/options.rb +4 -4
  19. data/lib/rager/{image_gen → image}/output_format.rb +1 -1
  20. data/lib/rager/{image_gen → image}/providers/abstract.rb +4 -4
  21. data/lib/rager/{image_gen → image}/providers/replicate.rb +14 -10
  22. data/lib/rager/{logger.rb → log_strategy.rb} +2 -1
  23. data/lib/rager/{mesh_gen → mesh}/options.rb +3 -3
  24. data/lib/rager/{mesh_gen → mesh}/providers/abstract.rb +4 -4
  25. data/lib/rager/{mesh_gen → mesh}/providers/replicate.rb +13 -9
  26. data/lib/rager/operation.rb +2 -2
  27. data/lib/rager/options.rb +1 -1
  28. data/lib/rager/outcome.rb +25 -0
  29. data/lib/rager/providers.rb +37 -25
  30. data/lib/rager/rerank/input.rb +20 -0
  31. data/lib/rager/rerank/options.rb +2 -2
  32. data/lib/rager/rerank/providers/abstract.rb +2 -3
  33. data/lib/rager/rerank/providers/cohere.rb +19 -13
  34. data/lib/rager/rerank/result.rb +20 -0
  35. data/lib/rager/result.rb +92 -122
  36. data/lib/rager/search/options.rb +3 -2
  37. data/lib/rager/search/providers/jina.rb +16 -15
  38. data/lib/rager/search/result.rb +21 -0
  39. data/lib/rager/template/input.rb +20 -0
  40. data/lib/rager/template/options.rb +1 -1
  41. data/lib/rager/template/providers/abstract.rb +2 -3
  42. data/lib/rager/template/providers/erb.rb +4 -5
  43. data/lib/rager/template/providers/mustache.rb +30 -0
  44. data/lib/rager/types.rb +31 -24
  45. data/lib/rager/utils/http.rb +73 -15
  46. data/lib/rager/utils/replicate.rb +28 -6
  47. data/lib/rager/utils/runtime.rb +21 -0
  48. data/lib/rager/version.rb +1 -1
  49. metadata +18 -12
  50. data/lib/rager/rerank/output.rb +0 -13
  51. data/lib/rager/search/output.rb +0 -14
data/lib/rager/context.rb CHANGED
@@ -15,18 +15,46 @@ module Rager
15
15
  sig { returns(T.nilable(String)) }
16
16
  attr_reader :name
17
17
 
18
+ sig { returns(T::Array[String]) }
19
+ attr_reader :tags
20
+
18
21
  sig { returns(Integer) }
19
22
  attr_reader :max_retries
20
23
 
21
- sig { returns(Float) }
24
+ sig { returns(Numeric) }
22
25
  attr_reader :backoff
23
26
 
24
- sig { params(id: T.nilable(String), name: T.nilable(String), max_retries: T.nilable(Integer), backoff: T.nilable(Float)).void }
25
- def initialize(id: nil, name: nil, max_retries: nil, backoff: nil)
27
+ sig {
28
+ params(
29
+ id: T.nilable(String),
30
+ name: T.nilable(String),
31
+ tags: T::Array[String],
32
+ max_retries: T.nilable(Integer),
33
+ backoff: T.nilable(Numeric)
34
+ ).void
35
+ }
36
+ def initialize(id: nil, name: nil, tags: [], max_retries: nil, backoff: nil)
26
37
  @id = T.let(id || SecureRandom.uuid, String)
27
38
  @name = T.let(name, T.nilable(String))
39
+ @tags = T.let(tags, T::Array[String])
28
40
  @max_retries = T.let(max_retries || 0, Integer)
29
- @backoff = T.let(backoff || 1.0, Float)
41
+ @backoff = T.let(backoff || 1.0, Numeric)
42
+ end
43
+
44
+ sig do
45
+ params(
46
+ max_retries: T.nilable(Integer),
47
+ backoff: T.nilable(Numeric)
48
+ ).returns(Rager::Context)
49
+ end
50
+ def with_options(max_retries: nil, backoff: nil)
51
+ Context.new(
52
+ id: @id,
53
+ name: @name,
54
+ tags: @tags,
55
+ max_retries: max_retries || @max_retries,
56
+ backoff: backoff || @backoff
57
+ )
30
58
  end
31
59
 
32
60
  sig do
@@ -36,26 +64,32 @@ module Rager
36
64
  ).returns(Rager::Result)
37
65
  end
38
66
  def chat(messages, **kwargs)
39
- execute(
40
- Rager::Operation::Chat,
41
- Rager::Chat::Options,
42
- kwargs,
43
- messages
44
- ) { |options, normalized_input|
45
- final_input = if normalized_input.is_a?(String)
46
- [
47
- Rager::Chat::Message.new(
48
- role: Rager::Chat::MessageRole::User,
49
- content: normalized_input
50
- )
51
- ]
52
- else
53
- normalized_input
54
- end
67
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
68
+ options = Rager::Chat::Options.new(**kwargs)
69
+ options.validate
55
70
 
56
- provider = Rager::Providers.get_provider(:chat, options.provider, options)
57
- provider.chat(final_input, options)
58
- }
71
+ normalized_input, input_ids = normalize(messages, context_options.input_ids)
72
+
73
+ if normalized_input.is_a?(String)
74
+ normalized_input = [
75
+ Rager::Chat::Message.new(
76
+ role: Rager::Chat::MessageRole::User,
77
+ content: normalized_input
78
+ )
79
+ ]
80
+ end
81
+
82
+ execute(
83
+ operation: Rager::Operation::Chat,
84
+ input: normalized_input,
85
+ options: options,
86
+ context_options: context_options,
87
+ input_ids: input_ids
88
+ ) do |input, opts|
89
+ Rager::Providers
90
+ .get_provider(Rager::Operation::Chat, opts.provider, opts)
91
+ .chat(input, opts)
92
+ end
59
93
  end
60
94
 
61
95
  sig do
@@ -65,57 +99,77 @@ module Rager
65
99
  ).returns(Rager::Result)
66
100
  end
67
101
  def embed(text, **kwargs)
68
- execute(
69
- Rager::Operation::Embed,
70
- Rager::Embed::Options,
71
- kwargs,
72
- text
73
- ) { |options, normalized_input|
74
- final_input = if normalized_input.is_a?(String)
75
- [normalized_input]
76
- else
77
- normalized_input
78
- end
102
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
103
+ options = Rager::Embed::Options.new(**kwargs)
104
+ options.validate
79
105
 
80
- provider = Rager::Providers.get_provider(:embed, options.provider, options)
81
- provider.embed(final_input, options)
82
- }
106
+ normalized_input, input_ids = normalize(text, context_options.input_ids)
107
+
108
+ normalized_input = [normalized_input] if normalized_input.is_a?(String)
109
+
110
+ execute(
111
+ operation: Rager::Operation::Embed,
112
+ input: normalized_input,
113
+ options: options,
114
+ context_options: context_options,
115
+ input_ids: input_ids
116
+ ) do |input, opts|
117
+ Rager::Providers
118
+ .get_provider(Rager::Operation::Embed, opts.provider, opts)
119
+ .embed(input, opts)
120
+ end
83
121
  end
84
122
 
85
123
  sig do
86
124
  params(
87
- prompt: T.any(Rager::Types::ImageGenInput, Rager::Result),
125
+ prompt: T.any(Rager::Types::ImageInput, Rager::Result),
88
126
  kwargs: T.untyped
89
127
  ).returns(Rager::Result)
90
128
  end
91
- def image_gen(prompt, **kwargs)
129
+ def image(prompt, **kwargs)
130
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
131
+ options = Rager::Image::Options.new(**kwargs)
132
+ options.validate
133
+
134
+ normalized_input, input_ids = normalize(prompt, context_options.input_ids)
135
+
92
136
  execute(
93
- Rager::Operation::ImageGen,
94
- Rager::ImageGen::Options,
95
- kwargs,
96
- prompt
97
- ) { |options, normalized_input|
98
- provider = Rager::Providers.get_provider(:image_gen, options.provider, options)
99
- provider.image_gen(T.cast(normalized_input, Rager::Types::ImageGenInput), options)
100
- }
137
+ operation: Rager::Operation::Image,
138
+ input: normalized_input,
139
+ options: options,
140
+ context_options: context_options,
141
+ input_ids: input_ids
142
+ ) do |input, opts|
143
+ Rager::Providers
144
+ .get_provider(Rager::Operation::Image, opts.provider, opts)
145
+ .image(input, opts)
146
+ end
101
147
  end
102
148
 
103
149
  sig do
104
150
  params(
105
- prompt: T.any(Rager::Types::MeshGenInput, Rager::Result),
151
+ prompt: T.any(Rager::Types::MeshInput, Rager::Result),
106
152
  kwargs: T.untyped
107
153
  ).returns(Rager::Result)
108
154
  end
109
- def mesh_gen(prompt, **kwargs)
155
+ def mesh(prompt, **kwargs)
156
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
157
+ options = Rager::Mesh::Options.new(**kwargs)
158
+ options.validate
159
+
160
+ normalized_input, input_ids = normalize(prompt, context_options.input_ids)
161
+
110
162
  execute(
111
- Rager::Operation::MeshGen,
112
- Rager::MeshGen::Options,
113
- kwargs,
114
- prompt
115
- ) { |options, normalized_input|
116
- provider = Rager::Providers.get_provider(:mesh_gen, options.provider, options)
117
- provider.mesh_gen(T.cast(normalized_input, Rager::Types::MeshGenInput), options)
118
- }
163
+ operation: Rager::Operation::Mesh,
164
+ input: normalized_input,
165
+ options: options,
166
+ context_options: context_options,
167
+ input_ids: input_ids
168
+ ) do |input, opts|
169
+ Rager::Providers
170
+ .get_provider(Rager::Operation::Mesh, opts.provider, opts)
171
+ .mesh(input, opts)
172
+ end
119
173
  end
120
174
 
121
175
  sig do
@@ -126,16 +180,29 @@ module Rager
126
180
  ).returns(Rager::Result)
127
181
  end
128
182
  def rerank(query, documents, **kwargs)
183
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
184
+ options = Rager::Rerank::Options.new(**kwargs)
185
+ options.validate
186
+
187
+ normalized_query, input_ids = normalize(query, context_options.input_ids)
188
+ normalized_documents, input_ids = normalize(documents, input_ids)
189
+
190
+ rerank_input = Rager::Rerank::Input.new(
191
+ query: normalized_query,
192
+ documents: normalized_documents
193
+ )
194
+
129
195
  execute(
130
- Rager::Operation::Rerank,
131
- Rager::Rerank::Options,
132
- kwargs,
133
- {query: query, documents: documents}
134
- ) { |options, normalized_input|
135
- provider = Rager::Providers.get_provider(:rerank, options.provider, options)
136
- input_hash = T.cast(normalized_input, T::Hash[Symbol, T.untyped])
137
- provider.rerank(input_hash[:query], input_hash[:documents], options)
138
- }
196
+ operation: Rager::Operation::Rerank,
197
+ input: rerank_input,
198
+ options: options,
199
+ context_options: context_options,
200
+ input_ids: input_ids
201
+ ) do |input, opts|
202
+ Rager::Providers
203
+ .get_provider(Rager::Operation::Rerank, opts.provider, opts)
204
+ .rerank(input, opts)
205
+ end
139
206
  end
140
207
 
141
208
  sig do
@@ -145,15 +212,23 @@ module Rager
145
212
  ).returns(Rager::Result)
146
213
  end
147
214
  def search(query, **kwargs)
215
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
216
+ options = Rager::Search::Options.new(**kwargs)
217
+ options.validate
218
+
219
+ normalized_input, input_ids = normalize(query, context_options.input_ids)
220
+
148
221
  execute(
149
- Rager::Operation::Search,
150
- Rager::Search::Options,
151
- kwargs,
152
- query
153
- ) { |options, normalized_input|
154
- provider = Rager::Providers.get_provider(:search, options.provider, options)
155
- provider.search(T.cast(normalized_input, Rager::Types::SearchInput), options)
156
- }
222
+ operation: Rager::Operation::Search,
223
+ input: normalized_input,
224
+ options: options,
225
+ context_options: context_options,
226
+ input_ids: input_ids
227
+ ) do |input, opts|
228
+ Rager::Providers
229
+ .get_provider(Rager::Operation::Search, opts.provider, opts)
230
+ .search(input, opts)
231
+ end
157
232
  end
158
233
 
159
234
  sig do
@@ -164,147 +239,188 @@ module Rager
164
239
  ).returns(Rager::Result)
165
240
  end
166
241
  def template(template, variables, **kwargs)
242
+ context_options = Rager::ContextOptions.new(**Rager::ContextOptions.extract_kwargs(kwargs))
243
+ options = Rager::Template::Options.new(**kwargs)
244
+ options.validate
245
+
246
+ normalized_template, input_ids = normalize(template, context_options.input_ids)
247
+ normalized_variables, input_ids = normalize(variables, input_ids)
248
+
249
+ template_input = Rager::Template::Input.new(
250
+ template: normalized_template,
251
+ variables: normalized_variables
252
+ )
253
+
167
254
  execute(
168
- Rager::Operation::Template,
169
- Rager::Template::Options,
170
- kwargs,
171
- {template: template, variables: variables}
172
- ) { |options, normalized_input|
173
- provider = Rager::Providers.get_provider(:template, options.provider, options)
174
- input_hash = T.cast(normalized_input, T::Hash[Symbol, T.untyped])
175
- provider.template(input_hash[:template], input_hash[:variables], options)
255
+ operation: Rager::Operation::Template,
256
+ input: template_input,
257
+ options: options,
258
+ context_options: context_options,
259
+ input_ids: input_ids
260
+ ) do |input, opts|
261
+ Rager::Providers
262
+ .get_provider(Rager::Operation::Template, opts.provider, opts)
263
+ .template(input, opts)
264
+ end
265
+ end
266
+
267
+ sig do
268
+ params(
269
+ value: Float,
270
+ feedback: T.nilable(String),
271
+ tags: T::Array[String]
272
+ ).void
273
+ end
274
+ def outcome(value, feedback: nil, tags: [])
275
+ Rager::Utils::Http.log_remote(
276
+ "outcomes",
277
+ {
278
+ version: "1",
279
+ data: Rager::Outcome.new(
280
+ context_id: @id,
281
+ value: value,
282
+ feedback: feedback,
283
+ tags: tags
284
+ )
285
+ }.to_json
286
+ )
287
+ end
288
+
289
+ sig { returns(T::Hash[Symbol, T.untyped]) }
290
+ def to_h
291
+ {
292
+ id: @id,
293
+ name: @name,
294
+ tags: @tags,
295
+ max_retries: @max_retries,
296
+ backoff: @backoff
176
297
  }
177
298
  end
178
299
 
300
+ sig { params(hash: T::Hash[Symbol, T.untyped], max_retries: T.nilable(Integer), backoff: T.nilable(Float)).returns(Rager::Context) }
301
+ def self.from_h(hash, max_retries: nil, backoff: nil)
302
+ new(
303
+ id: hash[:id],
304
+ name: hash[:name],
305
+ tags: hash[:tags],
306
+ max_retries: max_retries || hash[:max_retries],
307
+ backoff: backoff || hash[:backoff]
308
+ )
309
+ end
310
+
179
311
  private
180
312
 
181
313
  sig do
182
314
  params(
183
315
  operation: Rager::Operation,
184
- options_struct: T::Class[Rager::Options],
185
- kwargs: T.untyped,
186
- input: T.any(Rager::Types::Input, Rager::Result, T::Hash[Symbol, T.untyped]),
187
- block: T.proc.params(options: T.untyped, normalized_input: Rager::Types::Input).returns(T.untyped)
316
+ input: Rager::Types::Input,
317
+ options: Rager::Types::Options,
318
+ context_options: Rager::ContextOptions,
319
+ input_ids: T::Array[String],
320
+ block: T.proc.params(
321
+ input: Rager::Types::Input,
322
+ options: Rager::Types::Options
323
+ ).returns(Rager::Types::Output)
188
324
  ).returns(Rager::Result)
189
325
  end
190
- def execute(operation, options_struct, kwargs, input, &block)
191
- name = kwargs.delete(:name)
192
- tags = kwargs.delete(:tags) || []
193
-
194
- existing_input_ids = kwargs.delete(:input_ids) || []
195
- normalized_input, new_input_ids = normalize_input(input)
196
- input_ids = (existing_input_ids + new_input_ids).uniq
197
-
198
- options = options_struct.new(**kwargs)
199
- options.validate
200
-
326
+ def execute(operation:, input:, options:, context_options:, input_ids:, &block)
201
327
  start_time = Time.now
202
- errors = []
203
328
  attempt = 0
329
+ errors = []
330
+ last_error = nil
204
331
 
205
332
  begin
206
- output = yield(options, normalized_input)
207
-
208
- Result.new(
209
- id: SecureRandom.uuid,
210
- context_id: @id,
211
- operation: operation,
212
- input: normalized_input,
213
- output: output,
214
- options: options,
215
- start_time: start_time.to_i,
216
- end_time: Time.now.to_i,
217
- name: name,
218
- context_name: @name,
219
- tags: tags,
220
- input_ids: input_ids,
221
- errors: errors,
222
- attempt: attempt
223
- ).tap(&:log)
224
- rescue => e
333
+ output = yield(input, options)
334
+ rescue Rager::Errors::HttpError => e
225
335
  errors << e.message
336
+ last_error = e
226
337
  attempt += 1
227
338
 
228
- if attempt < @max_retries
229
- delay = @backoff * 2**attempt
230
- Rager::Utils::Http.sleep(delay)
339
+ if attempt <= @max_retries
340
+ jitter = @backoff * rand(0.0..1.0)
341
+ delay = @backoff * (2**(attempt - 1)) + jitter
342
+ Rager.config.logger.warn("Retrying in #{delay.round(2)}s after failure #{attempt}/#{@max_retries}: #{e.message}")
343
+
344
+ Rager::Utils::Runtime.sleep(delay)
345
+
231
346
  retry
232
347
  else
233
- Result.new(
234
- id: SecureRandom.uuid,
235
- context_id: @id,
236
- operation: operation,
237
- input: normalized_input,
238
- output: nil,
239
- options: options,
240
- start_time: start_time.to_i,
241
- end_time: Time.now.to_i,
242
- name: name,
243
- context_name: @name,
244
- tags: tags,
245
- input_ids: input_ids,
246
- errors: errors,
247
- attempt: attempt
248
- ).tap(&:log)
249
-
250
- raise e
348
+ output = nil
251
349
  end
252
350
  end
351
+
352
+ result = Result.new(
353
+ id: SecureRandom.uuid,
354
+ context_id: @id,
355
+ operation: operation,
356
+ input: input,
357
+ output: output,
358
+ options: options,
359
+ start_time: start_time.to_i,
360
+ end_time: Time.now.to_i,
361
+ attempt: attempt,
362
+ errors: errors,
363
+ input_ids: input_ids.uniq,
364
+ name: context_options.name,
365
+ tags: context_options.tags,
366
+ context_name: @name,
367
+ context_tags: @tags
368
+ ).tap(&:log)
369
+
370
+ raise last_error if last_error
371
+
372
+ result
373
+ end
374
+
375
+ sig {
376
+ params(
377
+ input: T.untyped,
378
+ ids: T.nilable(T::Array[String])
379
+ ).returns([T.untyped, T::Array[String]])
380
+ }
381
+ def normalize(input, ids = nil)
382
+ collected_ids = (ids || []).to_set
383
+ visited = Set.new
384
+
385
+ normalized_input = normalize_item(input, collected_ids, visited)
386
+ [normalized_input, collected_ids.to_a]
253
387
  end
254
388
 
255
- sig { params(input: T.untyped, ids: T::Array[String]).returns([T.untyped, T::Array[String]]) }
256
- def normalize_input(input, ids: [])
257
- case input
389
+ sig {
390
+ params(
391
+ item: T.untyped,
392
+ collected_ids: T::Set[String],
393
+ visited: T::Set[Integer]
394
+ ).returns(T.untyped)
395
+ }
396
+ def normalize_item(item, collected_ids, visited)
397
+ case item
258
398
  when Rager::Result
259
- ids << input.id unless ids.include?(input.id)
260
-
261
- materialized_output = input.mat
262
- normalized_output = case materialized_output
263
- when Rager::Search::Output
264
- materialized_output.contents
265
- when Rager::Rerank::Output
266
- materialized_output.documents
267
- else
268
- materialized_output
269
- end
399
+ collected_ids.add(item.id)
400
+ normalize_item(item.value, collected_ids, visited)
401
+ when Array
402
+ object_id = item.object_id
403
+ return item if visited.include?(object_id)
404
+ visited.add(object_id)
270
405
 
271
- [normalized_output, ids]
406
+ item.map { |i| normalize_item(i, collected_ids, visited) }
272
407
  when Hash
273
- normalized_hash = {}
274
- input.each do |key, value|
275
- normalized_value, ids = normalize_input(value, ids: ids)
276
- normalized_hash[key] = normalized_value
277
- end
278
- [normalized_hash, ids]
279
- when Array
280
- normalized_array = []
281
- input.each do |item|
282
- normalized_item, ids = normalize_input(item, ids: ids)
283
- normalized_array << normalized_item
284
- end
285
- [normalized_array, ids]
286
- else
287
- [input, ids]
288
- end
289
- end
408
+ object_id = item.object_id
409
+ return item if visited.include?(object_id)
410
+ visited.add(object_id)
290
411
 
291
- sig { returns(String) }
292
- def to_json
293
- {
294
- id: @id,
295
- name: @name,
296
- max_retries: @max_retries,
297
- backoff: @backoff
298
- }.to_json
299
- end
412
+ item.transform_values { |value| normalize_item(value, collected_ids, visited) }
413
+ when T::Struct
414
+ object_id = item.object_id
415
+ return item if visited.include?(object_id)
416
+ visited.add(object_id)
300
417
 
301
- sig { params(json: String, id: T.nilable(String), name: T.nilable(String), max_retries: T.nilable(Integer), backoff: T.nilable(Float)).returns(Rager::Context) }
302
- def from_json(json, id: nil, name: nil, max_retries: nil, backoff: nil)
303
- JSON.parse(json, symbolize_names: true).tap do |data|
304
- @id = id || data[:id]
305
- @name = name || data[:name]
306
- @max_retries = max_retries || data[:max_retries]
307
- @backoff = backoff || data[:backoff]
418
+ transformed_props = item.class.props.each_key.each_with_object({}) do |prop_name, acc|
419
+ acc[prop_name] = normalize_item(item.send(prop_name), collected_ids, visited)
420
+ end
421
+ item.class.new(transformed_props)
422
+ else
423
+ item
308
424
  end
309
425
  end
310
426
  end
@@ -0,0 +1,23 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Rager
7
+ class ContextOptions < T::Struct
8
+ extend T::Sig
9
+
10
+ const :input_ids, T::Array[String], default: []
11
+ const :tags, T::Array[T.untyped], default: []
12
+ const :name, T.nilable(String)
13
+
14
+ sig { params(kwargs: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
15
+ def self.extract_kwargs(kwargs)
16
+ {
17
+ input_ids: kwargs.delete(:input_ids),
18
+ tags: kwargs.delete(:tags),
19
+ name: kwargs.delete(:name)
20
+ }.compact
21
+ end
22
+ end
23
+ end
@@ -9,11 +9,11 @@ module Rager
9
9
  extend T::Sig
10
10
  include Rager::Options
11
11
 
12
- const :provider, String, default: "openai"
13
- const :url, T.nilable(String)
12
+ const :provider, Symbol, default: :openai
14
13
  const :model, T.nilable(String)
15
- const :api_key, T.nilable(String)
16
14
  const :seed, T.nilable(Integer)
15
+ const :url, T.nilable(String)
16
+ const :api_key, T.nilable(String)
17
17
  const :timeout, T.nilable(Numeric)
18
18
  end
19
19
  end
@@ -22,9 +22,13 @@ module Rager
22
22
  raise Rager::Errors::CredentialsError.new("OpenAI", env_var: ["OPENAI_API_KEY"]) if api_key.nil?
23
23
 
24
24
  base_url = options.url || ENV["OPENAI_URL"] || "https://api.openai.com/v1"
25
+ url = "#{base_url}/embeddings"
25
26
 
26
- headers = {"Content-Type" => "application/json"}
27
- headers["Authorization"] = "Bearer #{api_key}" if api_key
27
+ headers = {
28
+ "Content-Type" => "application/json"
29
+ }.tap do |h|
30
+ h["Authorization"] = "Bearer #{api_key}" if api_key
31
+ end
28
32
 
29
33
  body = {
30
34
  model: options.model || "text-embedding-3-large",
@@ -33,7 +37,7 @@ module Rager
33
37
 
34
38
  request = Rager::Http::Request.new(
35
39
  verb: Rager::Http::Verb::Post,
36
- url: "#{base_url}/embeddings",
40
+ url: url,
37
41
  headers: headers,
38
42
  body: body.to_json,
39
43
  timeout: options.timeout || Rager.config.timeout
@@ -8,7 +8,7 @@ module Rager
8
8
  class OptionsError < Rager::Error
9
9
  extend T::Sig
10
10
 
11
- sig { params(options: Rager::Options, invalid_keys: T::Array[String], details: T.nilable(String)).void }
11
+ sig { params(options: Rager::Types::Options, invalid_keys: T::Array[String], details: T.nilable(String)).void }
12
12
  def initialize(options, invalid_keys, details: nil)
13
13
  error_data = {
14
14
  type: "options",
@@ -90,8 +90,6 @@ module Rager
90
90
  )
91
91
  end
92
92
 
93
- private
94
-
95
93
  sig { params(timeout: T.nilable(Numeric), block: T.proc.returns(T.untyped)).returns(T.untyped) }
96
94
  def wrap_if_timeout(timeout, &block)
97
95
  if timeout
@@ -35,8 +35,6 @@ module Rager
35
35
  cached_entry ? build_response_from_cache(cached_entry) : fetch_and_cache_response(request, key)
36
36
  end
37
37
 
38
- private
39
-
40
38
  sig { params(request: Rager::Http::Request, key: String).returns(Rager::Http::Response) }
41
39
  def fetch_and_cache_response(request, key)
42
40
  response = @fallback_adapter.make_request(request)