ruby_llm_community 1.1.0 → 1.2.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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -5
  3. data/lib/generators/ruby_llm/generator_helpers.rb +129 -0
  4. data/lib/generators/ruby_llm/install/install_generator.rb +12 -129
  5. data/lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt +9 -0
  6. data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +0 -1
  7. data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +0 -3
  8. data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +1 -4
  9. data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +0 -1
  10. data/lib/generators/ruby_llm/upgrade_to_v1_7/templates/migration.rb.tt +8 -0
  11. data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +47 -96
  12. data/lib/ruby_llm/attachment.rb +5 -0
  13. data/lib/ruby_llm/configuration.rb +4 -0
  14. data/lib/ruby_llm/mime_type.rb +4 -0
  15. data/lib/ruby_llm/model/info.rb +4 -0
  16. data/lib/ruby_llm/models.json +780 -511
  17. data/lib/ruby_llm/models.rb +7 -3
  18. data/lib/ruby_llm/moderation.rb +56 -0
  19. data/lib/ruby_llm/provider.rb +6 -0
  20. data/lib/ruby_llm/providers/gemini/capabilities.rb +5 -0
  21. data/lib/ruby_llm/providers/openai/moderation.rb +34 -0
  22. data/lib/ruby_llm/providers/openai_base.rb +1 -0
  23. data/lib/ruby_llm/providers/red_candle/capabilities.rb +124 -0
  24. data/lib/ruby_llm/providers/red_candle/chat.rb +317 -0
  25. data/lib/ruby_llm/providers/red_candle/models.rb +121 -0
  26. data/lib/ruby_llm/providers/red_candle/streaming.rb +40 -0
  27. data/lib/ruby_llm/providers/red_candle.rb +90 -0
  28. data/lib/ruby_llm/railtie.rb +1 -1
  29. data/lib/ruby_llm/version.rb +1 -1
  30. data/lib/ruby_llm_community.rb +32 -0
  31. metadata +10 -1
@@ -2,10 +2,12 @@
2
2
 
3
3
  require 'rails/generators'
4
4
  require 'rails/generators/active_record'
5
+ require_relative '../generator_helpers'
5
6
 
6
7
  module RubyLLM
7
8
  class UpgradeToV17Generator < Rails::Generators::Base # rubocop:disable Style/Documentation
8
9
  include Rails::Generators::Migration
10
+ include RubyLLM::GeneratorHelpers
9
11
 
10
12
  namespace 'ruby_llm:upgrade_to_v1_7'
11
13
  source_root File.expand_path('templates', __dir__)
@@ -27,38 +29,11 @@ module RubyLLM
27
29
  ::ActiveRecord::Generators::Base.next_migration_number(dirname)
28
30
  end
29
31
 
30
- def parse_model_mappings
31
- @model_names = {
32
- chat: 'Chat',
33
- message: 'Message',
34
- tool_call: 'ToolCall',
35
- model: 'Model'
36
- }
37
-
38
- model_mappings.each do |mapping|
39
- if mapping.include?(':')
40
- key, value = mapping.split(':', 2)
41
- @model_names[key.to_sym] = value.classify
42
- end
43
- end
44
-
45
- @model_names
46
- end
47
-
48
- %i[chat message tool_call model].each do |type|
49
- define_method("#{type}_model_name") do
50
- @model_names ||= parse_model_mappings
51
- @model_names[type]
52
- end
53
-
54
- define_method("#{type}_table_name") do
55
- table_name_for(send("#{type}_model_name"))
56
- end
57
- end
58
-
59
32
  def create_migration_file
33
+ @model_table_already_existed = table_exists?(table_name_for(model_model_name))
34
+
60
35
  # First check if models table exists, if not create it
61
- unless table_exists?(table_name_for(model_model_name))
36
+ unless @model_table_already_existed
62
37
  migration_template 'create_models_migration.rb.tt',
63
38
  "db/migrate/create_#{table_name_for(model_model_name)}.rb",
64
39
  migration_version: migration_version,
@@ -73,98 +48,74 @@ module RubyLLM
73
48
  chat_model_name: chat_model_name,
74
49
  message_model_name: message_model_name,
75
50
  tool_call_model_name: tool_call_model_name,
76
- model_model_name: model_model_name
51
+ model_model_name: model_model_name,
52
+ model_table_already_existed: @model_table_already_existed
77
53
  end
78
54
 
79
55
  def create_model_file
80
- # Check if Model file already exists
81
- model_path = "app/models/#{model_model_name.underscore}.rb"
82
-
83
- if File.exist?(Rails.root.join(model_path))
84
- say_status :skip, model_path, :yellow
85
- else
86
- create_file model_path do
87
- <<~RUBY
88
- class #{model_model_name} < ApplicationRecord
89
- #{acts_as_model_declaration}
90
- end
91
- RUBY
92
- end
93
- end
56
+ create_namespace_modules
57
+
58
+ template 'model_model.rb.tt', "app/models/#{model_model_name.underscore}.rb"
94
59
  end
95
60
 
96
- def acts_as_model_declaration
97
- acts_as_model_params = []
98
- chats_assoc = chat_model_name.tableize.to_sym
61
+ def update_existing_models
62
+ update_model_acts_as(chat_model_name, 'acts_as_chat', acts_as_chat_declaration)
63
+ update_model_acts_as(message_model_name, 'acts_as_message', acts_as_message_declaration)
64
+ update_model_acts_as(tool_call_model_name, 'acts_as_tool_call', acts_as_tool_call_declaration)
65
+ end
99
66
 
100
- if chats_assoc != :chats
101
- acts_as_model_params << "chats: :#{chats_assoc}"
102
- acts_as_model_params << "chat_class: '#{chat_model_name}'" if chat_model_name != chats_assoc.to_s.classify
103
- end
67
+ def update_initializer
68
+ initializer_path = 'config/initializers/ruby_llm.rb'
104
69
 
105
- if acts_as_model_params.any?
106
- "acts_as_model #{acts_as_model_params.join(', ')}"
107
- else
108
- 'acts_as_model'
70
+ unless File.exist?(initializer_path)
71
+ say_status :warning, 'No initializer found. Creating one...', :yellow
72
+ template 'initializer.rb.tt', initializer_path
73
+ return
109
74
  end
110
- end
111
75
 
112
- def update_initializer
113
- initializer_content = File.read('config/initializers/ruby_llm.rb')
114
-
115
- unless initializer_content.include?('config.use_new_acts_as')
116
- inject_into_file 'config/initializers/ruby_llm.rb', before: /^end/ do
117
- lines = ["\n # Enable the new Rails-like API", ' config.use_new_acts_as = true']
118
- lines << " config.model_registry_class = \"#{model_model_name}\"" if model_model_name != 'Model'
119
- lines << "\n"
120
- lines.join("\n")
121
- end
76
+ initializer_content = File.read(initializer_path)
77
+
78
+ return if initializer_content.include?('config.use_new_acts_as')
79
+
80
+ inject_into_file initializer_path, before: /^end/ do
81
+ lines = ["\n # Enable the new Rails-like API", ' config.use_new_acts_as = true']
82
+ lines << " config.model_registry_class = \"#{model_model_name}\"" if model_model_name != 'Model'
83
+ lines << "\n"
84
+ lines.join("\n")
122
85
  end
123
- rescue Errno::ENOENT
124
- say_status :error, 'config/initializers/ruby_llm.rb not found', :red
125
86
  end
126
87
 
127
88
  def show_next_steps
128
- say_status :success, 'Migration created!', :green
89
+ say_status :success, 'Upgrade prepared!', :green
129
90
  say <<~INSTRUCTIONS
130
91
 
131
92
  Next steps:
132
- 1. Review the migration: db/migrate/*_migrate_to_ruby_llm_model_references.rb
93
+ 1. Review the generated migrations
133
94
  2. Run: rails db:migrate
134
- 3. Update config/initializers/ruby_llm.rb as shown above
135
- 4. Test your application thoroughly
95
+ 3. Update your code to use the new API: #{chat_model_name}.create! now has the same signature as RubyLLM.chat
136
96
 
137
- The migration will:
138
- - Create the Models table if it doesn't exist
139
- - Load all models from models.json
140
- - Migrate your existing data to use foreign keys
141
- - Preserve all existing data (string columns renamed to model_id_string)
97
+ ⚠️ If you get "undefined method 'acts_as_model'" during migration:
98
+ Add this to config/application.rb BEFORE your Application class:
99
+
100
+ RubyLLM.configure do |config|
101
+ config.use_new_acts_as = true
102
+ end
103
+
104
+ 📚 See the full migration guide: https://rubyllm.com/upgrading-to-1-7/
142
105
 
143
106
  INSTRUCTIONS
144
107
  end
145
108
 
146
109
  private
147
110
 
148
- def migration_version
149
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
150
- end
151
-
152
- def table_name_for(model_name)
153
- # Convert namespaced model names to proper table names
154
- # e.g., "Assistant::Chat" -> "assistant_chats" (not "assistant/chats")
155
- model_name.underscore.pluralize.tr('/', '_')
156
- end
111
+ def update_model_acts_as(model_name, old_acts_as, new_acts_as)
112
+ model_path = "app/models/#{model_name.underscore}.rb"
113
+ return unless File.exist?(Rails.root.join(model_path))
157
114
 
158
- def table_exists?(table_name)
159
- ::ActiveRecord::Base.connection.table_exists?(table_name)
160
- rescue StandardError
161
- false
162
- end
115
+ content = File.read(Rails.root.join(model_path))
116
+ return unless content.match?(/^\s*#{old_acts_as}/)
163
117
 
164
- def postgresql?
165
- ::ActiveRecord::Base.connection.adapter_name.downcase.include?('postgresql')
166
- rescue StandardError
167
- false
118
+ gsub_file model_path, /^\s*#{old_acts_as}.*$/, " #{new_acts_as}"
168
119
  end
169
120
  end
170
121
  end
@@ -78,6 +78,7 @@ module RubyLLM
78
78
 
79
79
  def type
80
80
  return :image if image?
81
+ return :video if video?
81
82
  return :audio if audio?
82
83
  return :pdf if pdf?
83
84
  return :text if text?
@@ -89,6 +90,10 @@ module RubyLLM
89
90
  RubyLLM::MimeType.image? mime_type
90
91
  end
91
92
 
93
+ def video?
94
+ RubyLLM::MimeType.video? mime_type
95
+ end
96
+
92
97
  def audio?
93
98
  RubyLLM::MimeType.audio? mime_type
94
99
  end
@@ -24,9 +24,12 @@ module RubyLLM
24
24
  :gpustack_api_base,
25
25
  :gpustack_api_key,
26
26
  :mistral_api_key,
27
+ # Red Candle configuration
28
+ :red_candle_device,
27
29
  # Default models
28
30
  :default_model,
29
31
  :default_embedding_model,
32
+ :default_moderation_model,
30
33
  :default_image_model,
31
34
  # Model registry
32
35
  :model_registry_class,
@@ -55,6 +58,7 @@ module RubyLLM
55
58
 
56
59
  @default_model = 'gpt-4.1-nano'
57
60
  @default_embedding_model = 'text-embedding-3-small'
61
+ @default_moderation_model = 'omni-moderation-latest'
58
62
  @default_image_model = 'gpt-image-1'
59
63
 
60
64
  @model_registry_class = 'Model'
@@ -15,6 +15,10 @@ module RubyLLM
15
15
  type.start_with?('image/')
16
16
  end
17
17
 
18
+ def video?(type)
19
+ type.start_with?('video/')
20
+ end
21
+
18
22
  def audio?(type)
19
23
  type.start_with?('audio/')
20
24
  end
@@ -56,6 +56,10 @@ module RubyLLM
56
56
  modalities.input.include?('image')
57
57
  end
58
58
 
59
+ def supports_video?
60
+ modalities.input.include?('video')
61
+ end
62
+
59
63
  def supports_functions?
60
64
  function_calling?
61
65
  end