ruby_llm 1.14.1 → 1.15.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.
- checksums.yaml +4 -4
- data/README.md +1 -3
- data/lib/generators/ruby_llm/generator_helpers.rb +8 -0
- data/lib/generators/ruby_llm/tool/templates/tool.rb.tt +1 -1
- data/lib/ruby_llm/active_record/acts_as.rb +3 -0
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +52 -25
- data/lib/ruby_llm/active_record/chat_methods.rb +39 -22
- data/lib/ruby_llm/active_record/message_methods.rb +17 -1
- data/lib/ruby_llm/active_record/model_methods.rb +7 -9
- data/lib/ruby_llm/active_record/payload_helpers.rb +3 -0
- data/lib/ruby_llm/active_record/tool_call_methods.rb +3 -0
- data/lib/ruby_llm/agent.rb +3 -2
- data/lib/ruby_llm/aliases.json +34 -4
- data/lib/ruby_llm/attachment.rb +11 -27
- data/lib/ruby_llm/chat.rb +62 -21
- data/lib/ruby_llm/cost.rb +224 -0
- data/lib/ruby_llm/image.rb +37 -4
- data/lib/ruby_llm/message.rb +20 -0
- data/lib/ruby_llm/model/info.rb +17 -0
- data/lib/ruby_llm/model/pricing_category.rb +13 -2
- data/lib/ruby_llm/models.json +25168 -20374
- data/lib/ruby_llm/models.rb +2 -1
- data/lib/ruby_llm/models_schema.json +3 -0
- data/lib/ruby_llm/provider.rb +10 -3
- data/lib/ruby_llm/providers/anthropic/tools.rb +4 -1
- data/lib/ruby_llm/providers/bedrock/chat.rb +24 -13
- data/lib/ruby_llm/providers/bedrock/streaming.rb +4 -1
- data/lib/ruby_llm/providers/gemini/chat.rb +8 -1
- data/lib/ruby_llm/providers/gemini/images.rb +2 -2
- data/lib/ruby_llm/providers/gemini/streaming.rb +4 -1
- data/lib/ruby_llm/providers/gemini/tools.rb +3 -1
- data/lib/ruby_llm/providers/mistral/capabilities.rb +6 -1
- data/lib/ruby_llm/providers/mistral/chat.rb +55 -4
- data/lib/ruby_llm/providers/openai/capabilities.rb +82 -12
- data/lib/ruby_llm/providers/openai/chat.rb +45 -6
- data/lib/ruby_llm/providers/openai/images.rb +58 -6
- data/lib/ruby_llm/providers/openai/streaming.rb +5 -6
- data/lib/ruby_llm/providers/openrouter/chat.rb +30 -6
- data/lib/ruby_llm/providers/openrouter/images.rb +2 -2
- data/lib/ruby_llm/providers/openrouter/models.rb +1 -1
- data/lib/ruby_llm/providers/openrouter/streaming.rb +5 -6
- data/lib/ruby_llm/railtie.rb +6 -0
- data/lib/ruby_llm/tokens.rb +8 -0
- data/lib/ruby_llm/tool.rb +24 -7
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm.rb +2 -4
- data/lib/tasks/models.rake +13 -12
- metadata +19 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3cfdd21451b6e3daac0463dfdb7655892967e5a4da6b00846f353809a9abe18a
|
|
4
|
+
data.tar.gz: e1505ddd57326601298bb8975c20049a195eb87babd62b08ac0e6340c9e653f6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7222e575d4f1e5cf620fdc37f4c255c7ededeee945d7b77fac4129c2947d6f78f7d5641b45ed39470180e5bf2dfd48b36e0a6c16579e4e4835564c48b6907920
|
|
7
|
+
data.tar.gz: ce3fb0f0e8b3665fafe56717cf8fcb10733008821633b024013d0f6e5d0bc90ef47f25b0109aa0e80ee3df4002e2f9b6a20cd98595031aa57235588cb4677052
|
data/README.md
CHANGED
|
@@ -86,9 +86,7 @@ RubyLLM.moderate "Check if this text is safe"
|
|
|
86
86
|
```ruby
|
|
87
87
|
# Let AI use your code
|
|
88
88
|
class Weather < RubyLLM::Tool
|
|
89
|
-
|
|
90
|
-
param :latitude
|
|
91
|
-
param :longitude
|
|
89
|
+
desc "Get current weather"
|
|
92
90
|
|
|
93
91
|
def execute(latitude:, longitude:)
|
|
94
92
|
url = "https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}¤t=temperature_2m,wind_speed_10m"
|
|
@@ -87,6 +87,7 @@ module RubyLLM
|
|
|
87
87
|
|
|
88
88
|
add_association_params(params, :message, message_table_name, message_model_name,
|
|
89
89
|
owner_table: tool_call_table_name, owner_model_name: tool_call_model_name)
|
|
90
|
+
add_result_foreign_key_param(params)
|
|
90
91
|
|
|
91
92
|
"acts_as_tool_call#{" #{params.join(', ')}" if params.any?}"
|
|
92
93
|
end
|
|
@@ -178,6 +179,13 @@ module RubyLLM
|
|
|
178
179
|
"#{owner_model_name.demodulize.underscore}_id"
|
|
179
180
|
end
|
|
180
181
|
|
|
182
|
+
def add_result_foreign_key_param(params)
|
|
183
|
+
foreign_key = "#{tool_call_table_name.singularize}_id"
|
|
184
|
+
default_foreign_key = "#{tool_call_model_name.demodulize.underscore}_id"
|
|
185
|
+
|
|
186
|
+
params << "result_foreign_key: :#{foreign_key}" if foreign_key != default_foreign_key
|
|
187
|
+
end
|
|
188
|
+
|
|
181
189
|
# Convert namespaced model names to proper table names
|
|
182
190
|
# e.g., "Assistant::Chat" -> "assistant_chats" (not "assistant/chats")
|
|
183
191
|
def table_name_for(model_name)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
require 'active_support/inflector'
|
|
5
|
+
|
|
3
6
|
module RubyLLM
|
|
4
7
|
module ActiveRecord
|
|
5
8
|
# Adds chat and message persistence capabilities to ActiveRecord models.
|
|
@@ -160,27 +163,33 @@ module RubyLLM
|
|
|
160
163
|
self
|
|
161
164
|
end
|
|
162
165
|
|
|
163
|
-
def on_new_message(&
|
|
164
|
-
to_llm
|
|
166
|
+
def on_new_message(&)
|
|
167
|
+
to_llm.on_new_message(&)
|
|
168
|
+
self
|
|
169
|
+
end
|
|
165
170
|
|
|
166
|
-
|
|
171
|
+
def on_end_message(&)
|
|
172
|
+
to_llm.on_end_message(&)
|
|
173
|
+
self
|
|
174
|
+
end
|
|
167
175
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
block&.call
|
|
171
|
-
end
|
|
176
|
+
def before_message(...)
|
|
177
|
+
to_llm.before_message(...)
|
|
172
178
|
self
|
|
173
179
|
end
|
|
174
180
|
|
|
175
|
-
def
|
|
176
|
-
to_llm
|
|
181
|
+
def after_message(...)
|
|
182
|
+
to_llm.after_message(...)
|
|
183
|
+
self
|
|
184
|
+
end
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
def before_tool_call(...)
|
|
187
|
+
to_llm.before_tool_call(...)
|
|
188
|
+
self
|
|
189
|
+
end
|
|
179
190
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
block&.call(msg)
|
|
183
|
-
end
|
|
191
|
+
def after_tool_result(...)
|
|
192
|
+
to_llm.after_tool_result(...)
|
|
184
193
|
self
|
|
185
194
|
end
|
|
186
195
|
|
|
@@ -319,8 +328,8 @@ module RubyLLM
|
|
|
319
328
|
def setup_persistence_callbacks
|
|
320
329
|
return @chat if @chat.instance_variable_get(:@_persistence_callbacks_setup)
|
|
321
330
|
|
|
322
|
-
@chat.
|
|
323
|
-
@chat.
|
|
331
|
+
@chat.before_message { persist_new_message }
|
|
332
|
+
@chat.after_message { |msg| persist_message_completion(msg) }
|
|
324
333
|
|
|
325
334
|
@chat.instance_variable_set(:@_persistence_callbacks_setup, true)
|
|
326
335
|
@chat
|
|
@@ -383,8 +392,8 @@ module RubyLLM
|
|
|
383
392
|
case attachment
|
|
384
393
|
when ActionDispatch::Http::UploadedFile, ActiveStorage::Blob
|
|
385
394
|
attachment
|
|
386
|
-
when ActiveStorage::Attached::One, ActiveStorage::Attached::Many
|
|
387
|
-
attachment
|
|
395
|
+
when ActiveStorage::Attachment, ActiveStorage::Attached::One, ActiveStorage::Attached::Many
|
|
396
|
+
active_storage_blobs(attachment)
|
|
388
397
|
when Hash
|
|
389
398
|
attachment.values.map { |v| prepare_for_active_storage(v) }
|
|
390
399
|
else
|
|
@@ -398,16 +407,28 @@ module RubyLLM
|
|
|
398
407
|
|
|
399
408
|
attachment = source.is_a?(RubyLLM::Attachment) ? source : RubyLLM::Attachment.new(source)
|
|
400
409
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
410
|
+
if attachment.active_storage?
|
|
411
|
+
active_storage_blobs(attachment.source)
|
|
412
|
+
else
|
|
413
|
+
{
|
|
414
|
+
io: StringIO.new(attachment.content),
|
|
415
|
+
filename: attachment.filename,
|
|
416
|
+
content_type: attachment.mime_type
|
|
417
|
+
}
|
|
418
|
+
end
|
|
406
419
|
rescue StandardError => e
|
|
407
420
|
RubyLLM.logger.warn "Failed to process attachment #{source}: #{e.message}"
|
|
408
421
|
nil
|
|
409
422
|
end
|
|
410
423
|
|
|
424
|
+
def active_storage_blobs(attachment)
|
|
425
|
+
case attachment
|
|
426
|
+
when ActiveStorage::Blob then attachment
|
|
427
|
+
when ActiveStorage::Attachment, ActiveStorage::Attached::One then attachment.blob
|
|
428
|
+
when ActiveStorage::Attached::Many then attachment.blobs
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
411
432
|
def build_content(message, attachments)
|
|
412
433
|
return message if content_like?(message)
|
|
413
434
|
|
|
@@ -473,9 +494,15 @@ module RubyLLM
|
|
|
473
494
|
end
|
|
474
495
|
|
|
475
496
|
def extract_content
|
|
476
|
-
|
|
497
|
+
text_content = if content.respond_to?(:to_plain_text)
|
|
498
|
+
content.to_plain_text
|
|
499
|
+
else
|
|
500
|
+
content
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
return text_content unless respond_to?(:attachments) && attachments.attached?
|
|
477
504
|
|
|
478
|
-
RubyLLM::Content.new(
|
|
505
|
+
RubyLLM::Content.new(text_content).tap do |content_obj|
|
|
479
506
|
@_tempfiles = []
|
|
480
507
|
|
|
481
508
|
attachments.each do |attachment|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
|
|
3
5
|
module RubyLLM
|
|
4
6
|
module ActiveRecord
|
|
5
7
|
# Methods mixed into chat models.
|
|
@@ -154,27 +156,33 @@ module RubyLLM
|
|
|
154
156
|
self
|
|
155
157
|
end
|
|
156
158
|
|
|
157
|
-
def on_new_message(&
|
|
158
|
-
to_llm
|
|
159
|
+
def on_new_message(&)
|
|
160
|
+
to_llm.on_new_message(&)
|
|
161
|
+
self
|
|
162
|
+
end
|
|
159
163
|
|
|
160
|
-
|
|
164
|
+
def on_end_message(&)
|
|
165
|
+
to_llm.on_end_message(&)
|
|
166
|
+
self
|
|
167
|
+
end
|
|
161
168
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
block&.call
|
|
165
|
-
end
|
|
169
|
+
def before_message(...)
|
|
170
|
+
to_llm.before_message(...)
|
|
166
171
|
self
|
|
167
172
|
end
|
|
168
173
|
|
|
169
|
-
def
|
|
170
|
-
to_llm
|
|
174
|
+
def after_message(...)
|
|
175
|
+
to_llm.after_message(...)
|
|
176
|
+
self
|
|
177
|
+
end
|
|
171
178
|
|
|
172
|
-
|
|
179
|
+
def before_tool_call(...)
|
|
180
|
+
to_llm.before_tool_call(...)
|
|
181
|
+
self
|
|
182
|
+
end
|
|
173
183
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
block&.call(msg)
|
|
177
|
-
end
|
|
184
|
+
def after_tool_result(...)
|
|
185
|
+
to_llm.after_tool_result(...)
|
|
178
186
|
self
|
|
179
187
|
end
|
|
180
188
|
|
|
@@ -208,6 +216,10 @@ module RubyLLM
|
|
|
208
216
|
message_record
|
|
209
217
|
end
|
|
210
218
|
|
|
219
|
+
def cost
|
|
220
|
+
RubyLLM::Cost.aggregate(messages_association.map(&:cost))
|
|
221
|
+
end
|
|
222
|
+
|
|
211
223
|
def create_user_message(content, with: nil)
|
|
212
224
|
add_message(role: :user, content: build_content(content, with))
|
|
213
225
|
end
|
|
@@ -258,8 +270,8 @@ module RubyLLM
|
|
|
258
270
|
def setup_persistence_callbacks
|
|
259
271
|
return @chat if @chat.instance_variable_get(:@_persistence_callbacks_setup)
|
|
260
272
|
|
|
261
|
-
@chat.
|
|
262
|
-
@chat.
|
|
273
|
+
@chat.before_message { persist_new_message }
|
|
274
|
+
@chat.after_message { |msg| persist_message_completion(msg) }
|
|
263
275
|
|
|
264
276
|
@chat.instance_variable_set(:@_persistence_callbacks_setup, true)
|
|
265
277
|
@chat
|
|
@@ -402,8 +414,8 @@ module RubyLLM
|
|
|
402
414
|
case attachment
|
|
403
415
|
when ActionDispatch::Http::UploadedFile, ActiveStorage::Blob
|
|
404
416
|
attachment
|
|
405
|
-
when ActiveStorage::Attached::One, ActiveStorage::Attached::Many
|
|
406
|
-
attachment
|
|
417
|
+
when ActiveStorage::Attachment, ActiveStorage::Attached::One, ActiveStorage::Attached::Many
|
|
418
|
+
active_storage_blobs(attachment)
|
|
407
419
|
when Hash
|
|
408
420
|
attachment.values.map { |v| prepare_for_active_storage(v) }
|
|
409
421
|
else
|
|
@@ -418,10 +430,7 @@ module RubyLLM
|
|
|
418
430
|
attachment = source.is_a?(RubyLLM::Attachment) ? source : RubyLLM::Attachment.new(source)
|
|
419
431
|
|
|
420
432
|
if attachment.active_storage?
|
|
421
|
-
|
|
422
|
-
when ActiveStorage::Blob then attachment.source
|
|
423
|
-
when ActiveStorage::Attached::One, ActiveStorage::Attached::Many then attachment.source.blobs
|
|
424
|
-
end
|
|
433
|
+
active_storage_blobs(attachment.source)
|
|
425
434
|
else
|
|
426
435
|
{
|
|
427
436
|
io: StringIO.new(attachment.content),
|
|
@@ -434,6 +443,14 @@ module RubyLLM
|
|
|
434
443
|
nil
|
|
435
444
|
end
|
|
436
445
|
|
|
446
|
+
def active_storage_blobs(attachment)
|
|
447
|
+
case attachment
|
|
448
|
+
when ActiveStorage::Blob then attachment
|
|
449
|
+
when ActiveStorage::Attachment, ActiveStorage::Attached::One then attachment.blob
|
|
450
|
+
when ActiveStorage::Attached::Many then attachment.blobs
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
437
454
|
def build_content(message, attachments)
|
|
438
455
|
return message if content_like?(message)
|
|
439
456
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
require 'ruby_llm/active_record/payload_helpers'
|
|
5
|
+
|
|
3
6
|
module RubyLLM
|
|
4
7
|
module ActiveRecord
|
|
5
8
|
# Methods mixed into message models.
|
|
@@ -40,6 +43,18 @@ module RubyLLM
|
|
|
40
43
|
)
|
|
41
44
|
end
|
|
42
45
|
|
|
46
|
+
def cost
|
|
47
|
+
RubyLLM::Cost.new(tokens:, model: model_association)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def cache_read_tokens
|
|
51
|
+
cached_value
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def cache_write_tokens
|
|
55
|
+
cache_creation_value
|
|
56
|
+
end
|
|
57
|
+
|
|
43
58
|
def to_partial_path
|
|
44
59
|
partial_prefix = self.class.name.underscore.pluralize
|
|
45
60
|
role_partial = if to_llm.tool_call?
|
|
@@ -99,7 +114,8 @@ module RubyLLM
|
|
|
99
114
|
def extract_content
|
|
100
115
|
return RubyLLM::Content::Raw.new(content_raw) if has_attribute?(:content_raw) && content_raw.present?
|
|
101
116
|
|
|
102
|
-
content_value =
|
|
117
|
+
content_value = content
|
|
118
|
+
content_value = content_value.to_plain_text if content_value.respond_to?(:to_plain_text)
|
|
103
119
|
|
|
104
120
|
return content_value unless respond_to?(:attachments) && attachments.attached?
|
|
105
121
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
require 'active_support/core_ext/module/delegation'
|
|
5
|
+
|
|
3
6
|
module RubyLLM
|
|
4
7
|
module ActiveRecord
|
|
5
8
|
# Methods mixed into model registry models.
|
|
@@ -10,15 +13,7 @@ module RubyLLM
|
|
|
10
13
|
def refresh!
|
|
11
14
|
RubyLLM.models.refresh!
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
RubyLLM.models.all.each do |model_info|
|
|
15
|
-
model = find_or_initialize_by(
|
|
16
|
-
model_id: model_info.id,
|
|
17
|
-
provider: model_info.provider
|
|
18
|
-
)
|
|
19
|
-
model.update!(from_llm_attributes(model_info))
|
|
20
|
-
end
|
|
21
|
-
end
|
|
16
|
+
save_to_database
|
|
22
17
|
end
|
|
23
18
|
|
|
24
19
|
def save_to_database
|
|
@@ -76,8 +71,11 @@ module RubyLLM
|
|
|
76
71
|
|
|
77
72
|
delegate :supports?, :supports_vision?, :supports_functions?, :type,
|
|
78
73
|
:input_price_per_million, :output_price_per_million,
|
|
74
|
+
:cache_read_input_price_per_million, :cache_write_input_price_per_million,
|
|
75
|
+
:cached_input_price_per_million, :cache_creation_input_price_per_million,
|
|
79
76
|
:function_calling?, :structured_output?, :batch?,
|
|
80
77
|
:reasoning?, :citations?, :streaming?, :provider_class, :label,
|
|
78
|
+
:cost_for,
|
|
81
79
|
to: :to_llm
|
|
82
80
|
end
|
|
83
81
|
end
|
data/lib/ruby_llm/agent.rb
CHANGED
|
@@ -359,7 +359,8 @@ module RubyLLM
|
|
|
359
359
|
|
|
360
360
|
def_delegators :chat, :model, :messages, :tools, :params, :headers, :schema, :ask, :say, :with_tool, :with_tools,
|
|
361
361
|
:with_model, :with_temperature, :with_thinking, :with_context, :with_params, :with_headers,
|
|
362
|
-
:with_schema, :on_new_message, :on_end_message, :on_tool_call, :on_tool_result, :
|
|
363
|
-
:
|
|
362
|
+
:with_schema, :on_new_message, :on_end_message, :on_tool_call, :on_tool_result, :before_message,
|
|
363
|
+
:after_message, :before_tool_call, :after_tool_result, :each, :complete, :add_message,
|
|
364
|
+
:reset_messages!, :cost
|
|
364
365
|
end
|
|
365
366
|
end
|
data/lib/ruby_llm/aliases.json
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
},
|
|
10
10
|
"claude-3-5-sonnet": {
|
|
11
11
|
"anthropic": "claude-3-5-sonnet-20241022",
|
|
12
|
-
"openrouter": "anthropic/claude-3.5-sonnet",
|
|
13
12
|
"bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
14
13
|
},
|
|
15
14
|
"claude-3-7-sonnet": {
|
|
@@ -17,9 +16,6 @@
|
|
|
17
16
|
"openrouter": "anthropic/claude-3.7-sonnet",
|
|
18
17
|
"bedrock": "anthropic.claude-3-7-sonnet-20250219-v1:0"
|
|
19
18
|
},
|
|
20
|
-
"claude-3-7-sonnet-latest": {
|
|
21
|
-
"anthropic": "claude-3-7-sonnet-latest"
|
|
22
|
-
},
|
|
23
19
|
"claude-3-haiku": {
|
|
24
20
|
"anthropic": "claude-3-haiku-20240307",
|
|
25
21
|
"openrouter": "anthropic/claude-3-haiku",
|
|
@@ -64,6 +60,12 @@
|
|
|
64
60
|
"bedrock": "anthropic.claude-opus-4-6-v1",
|
|
65
61
|
"azure": "claude-opus-4-6"
|
|
66
62
|
},
|
|
63
|
+
"claude-opus-4-7": {
|
|
64
|
+
"anthropic": "claude-opus-4-7",
|
|
65
|
+
"openrouter": "anthropic/claude-opus-4.7",
|
|
66
|
+
"bedrock": "anthropic.claude-opus-4-7",
|
|
67
|
+
"azure": "claude-opus-4-7"
|
|
68
|
+
},
|
|
67
69
|
"claude-sonnet-4": {
|
|
68
70
|
"anthropic": "claude-sonnet-4-20250514",
|
|
69
71
|
"openrouter": "anthropic/claude-sonnet-4",
|
|
@@ -88,6 +90,14 @@
|
|
|
88
90
|
"deepseek": "deepseek-chat",
|
|
89
91
|
"openrouter": "deepseek/deepseek-chat"
|
|
90
92
|
},
|
|
93
|
+
"deepseek-v4-flash": {
|
|
94
|
+
"deepseek": "deepseek-v4-flash",
|
|
95
|
+
"openrouter": "deepseek/deepseek-v4-flash"
|
|
96
|
+
},
|
|
97
|
+
"deepseek-v4-pro": {
|
|
98
|
+
"deepseek": "deepseek-v4-pro",
|
|
99
|
+
"openrouter": "deepseek/deepseek-v4-pro"
|
|
100
|
+
},
|
|
91
101
|
"gemini-1.5-flash": {
|
|
92
102
|
"gemini": "gemini-1.5-flash",
|
|
93
103
|
"vertexai": "gemini-1.5-flash"
|
|
@@ -207,6 +217,10 @@
|
|
|
207
217
|
"gemini": "gemini-embedding-001",
|
|
208
218
|
"vertexai": "gemini-embedding-001"
|
|
209
219
|
},
|
|
220
|
+
"gemini-embedding-2": {
|
|
221
|
+
"gemini": "gemini-embedding-2",
|
|
222
|
+
"vertexai": "gemini-embedding-2"
|
|
223
|
+
},
|
|
210
224
|
"gemini-flash": {
|
|
211
225
|
"gemini": "gemini-flash-latest",
|
|
212
226
|
"vertexai": "gemini-flash-latest"
|
|
@@ -231,6 +245,14 @@
|
|
|
231
245
|
"gemini": "gemma-3n-e4b-it",
|
|
232
246
|
"openrouter": "google/gemma-3n-e4b-it"
|
|
233
247
|
},
|
|
248
|
+
"gemma-4-26b-a4b-it": {
|
|
249
|
+
"gemini": "gemma-4-26b-a4b-it",
|
|
250
|
+
"openrouter": "google/gemma-4-26b-a4b-it"
|
|
251
|
+
},
|
|
252
|
+
"gemma-4-31b-it": {
|
|
253
|
+
"gemini": "gemma-4-31b-it",
|
|
254
|
+
"openrouter": "google/gemma-4-31b-it"
|
|
255
|
+
},
|
|
234
256
|
"gpt-3.5-turbo": {
|
|
235
257
|
"openai": "gpt-3.5-turbo",
|
|
236
258
|
"openrouter": "openai/gpt-3.5-turbo"
|
|
@@ -378,6 +400,14 @@
|
|
|
378
400
|
"openai": "gpt-5.4-pro",
|
|
379
401
|
"openrouter": "openai/gpt-5.4-pro"
|
|
380
402
|
},
|
|
403
|
+
"gpt-5.5": {
|
|
404
|
+
"openai": "gpt-5.5",
|
|
405
|
+
"openrouter": "openai/gpt-5.5"
|
|
406
|
+
},
|
|
407
|
+
"gpt-5.5-pro": {
|
|
408
|
+
"openai": "gpt-5.5-pro",
|
|
409
|
+
"openrouter": "openai/gpt-5.5-pro"
|
|
410
|
+
},
|
|
381
411
|
"gpt-audio": {
|
|
382
412
|
"openai": "gpt-audio",
|
|
383
413
|
"openrouter": "openai/gpt-audio"
|
data/lib/ruby_llm/attachment.rb
CHANGED
|
@@ -32,6 +32,7 @@ module RubyLLM
|
|
|
32
32
|
return false unless defined?(ActiveStorage)
|
|
33
33
|
|
|
34
34
|
@source.is_a?(ActiveStorage::Blob) ||
|
|
35
|
+
@source.is_a?(ActiveStorage::Attachment) ||
|
|
35
36
|
@source.is_a?(ActiveStorage::Attached::One) ||
|
|
36
37
|
@source.is_a?(ActiveStorage::Attached::Many)
|
|
37
38
|
end
|
|
@@ -148,16 +149,7 @@ module RubyLLM
|
|
|
148
149
|
def load_content_from_active_storage
|
|
149
150
|
return unless defined?(ActiveStorage)
|
|
150
151
|
|
|
151
|
-
@content =
|
|
152
|
-
when ActiveStorage::Blob
|
|
153
|
-
@source.download
|
|
154
|
-
when ActiveStorage::Attached::One
|
|
155
|
-
@source.blob&.download
|
|
156
|
-
when ActiveStorage::Attached::Many
|
|
157
|
-
# For multiple attachments, just take the first one
|
|
158
|
-
# This maintains the single-attachment interface
|
|
159
|
-
@source.blobs.first&.download
|
|
160
|
-
end
|
|
152
|
+
@content = active_storage_blob&.download
|
|
161
153
|
end
|
|
162
154
|
|
|
163
155
|
def source_type_cast
|
|
@@ -192,31 +184,23 @@ module RubyLLM
|
|
|
192
184
|
end
|
|
193
185
|
end
|
|
194
186
|
|
|
195
|
-
def extract_filename_from_active_storage
|
|
187
|
+
def extract_filename_from_active_storage
|
|
196
188
|
return 'attachment' unless defined?(ActiveStorage)
|
|
197
189
|
|
|
198
|
-
|
|
199
|
-
when ActiveStorage::Blob
|
|
200
|
-
@source.filename.to_s
|
|
201
|
-
when ActiveStorage::Attached::One
|
|
202
|
-
@source.blob&.filename&.to_s || 'attachment'
|
|
203
|
-
when ActiveStorage::Attached::Many
|
|
204
|
-
@source.blobs.first&.filename&.to_s || 'attachment'
|
|
205
|
-
else
|
|
206
|
-
'attachment'
|
|
207
|
-
end
|
|
190
|
+
active_storage_blob&.filename&.to_s || 'attachment'
|
|
208
191
|
end
|
|
209
192
|
|
|
210
193
|
def active_storage_content_type
|
|
211
194
|
return unless defined?(ActiveStorage)
|
|
212
195
|
|
|
196
|
+
active_storage_blob&.content_type
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def active_storage_blob
|
|
213
200
|
case @source
|
|
214
|
-
when ActiveStorage::Blob
|
|
215
|
-
|
|
216
|
-
when ActiveStorage::Attached::
|
|
217
|
-
@source.blob&.content_type
|
|
218
|
-
when ActiveStorage::Attached::Many
|
|
219
|
-
@source.blobs.first&.content_type
|
|
201
|
+
when ActiveStorage::Blob then @source
|
|
202
|
+
when ActiveStorage::Attachment, ActiveStorage::Attached::One then @source.blob
|
|
203
|
+
when ActiveStorage::Attached::Many then @source.blobs.first
|
|
220
204
|
end
|
|
221
205
|
end
|
|
222
206
|
end
|