ruby_llm_community 1.0.0 → 1.1.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 +18 -1
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +127 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +39 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +24 -0
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +14 -0
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +12 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +29 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt +11 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +23 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt +21 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +10 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +9 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +16 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +30 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +18 -0
- data/lib/generators/ruby_llm/install/install_generator.rb +227 -0
- data/lib/generators/ruby_llm/install/templates/chat_model.rb.tt +2 -2
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +4 -4
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +8 -7
- data/lib/generators/ruby_llm/install/templates/create_models_migration.rb.tt +12 -3
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +6 -5
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +9 -8
- data/lib/generators/ruby_llm/install/templates/message_model.rb.tt +4 -3
- data/lib/generators/ruby_llm/install/templates/model_model.rb.tt +2 -5
- data/lib/generators/ruby_llm/install/templates/tool_call_model.rb.tt +2 -2
- data/lib/generators/ruby_llm/upgrade_to_v1_7/templates/migration.rb.tt +137 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +170 -0
- data/lib/ruby_llm/active_record/acts_as.rb +108 -467
- data/lib/ruby_llm/active_record/acts_as_legacy.rb +403 -0
- data/lib/ruby_llm/active_record/chat_methods.rb +336 -0
- data/lib/ruby_llm/active_record/message_methods.rb +72 -0
- data/lib/ruby_llm/active_record/model_methods.rb +84 -0
- data/lib/ruby_llm/aliases.json +72 -6
- data/lib/ruby_llm/attachment.rb +22 -0
- data/lib/ruby_llm/configuration.rb +6 -0
- data/lib/ruby_llm/image_attachment.rb +12 -3
- data/lib/ruby_llm/message.rb +1 -1
- data/lib/ruby_llm/models.json +2640 -1756
- data/lib/ruby_llm/models.rb +5 -15
- data/lib/ruby_llm/provider.rb +6 -4
- data/lib/ruby_llm/providers/anthropic/media.rb +1 -1
- data/lib/ruby_llm/providers/bedrock/models.rb +19 -1
- data/lib/ruby_llm/providers/gemini/media.rb +1 -1
- data/lib/ruby_llm/providers/gpustack/media.rb +1 -1
- data/lib/ruby_llm/providers/ollama/media.rb +1 -1
- data/lib/ruby_llm/providers/openai/media.rb +4 -4
- data/lib/ruby_llm/providers/openai/response.rb +7 -6
- data/lib/ruby_llm/providers/openai/response_media.rb +1 -1
- data/lib/ruby_llm/providers/openai/streaming.rb +14 -11
- data/lib/ruby_llm/providers/openai/tools.rb +11 -6
- data/lib/ruby_llm/providers/vertexai.rb +1 -1
- data/lib/ruby_llm/providers/xai/capabilities.rb +166 -0
- data/lib/ruby_llm/providers/xai/chat.rb +15 -0
- data/lib/ruby_llm/providers/xai/models.rb +48 -0
- data/lib/ruby_llm/providers/xai.rb +46 -0
- data/lib/ruby_llm/railtie.rb +20 -3
- data/lib/ruby_llm/stream_accumulator.rb +0 -4
- data/lib/ruby_llm/utils.rb +5 -9
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm_community.rb +4 -3
- data/lib/tasks/models.rake +29 -5
- data/lib/tasks/ruby_llm.rake +15 -0
- data/lib/tasks/vcr.rake +2 -2
- metadata +32 -3
- data/lib/generators/ruby_llm/install/templates/INSTALL_INFO.md.tt +0 -108
- data/lib/generators/ruby_llm/install_generator.rb +0 -146
data/lib/ruby_llm/utils.rb
CHANGED
@@ -5,10 +5,6 @@ module RubyLLM
|
|
5
5
|
module Utils
|
6
6
|
module_function
|
7
7
|
|
8
|
-
def format_text_file_for_llm(text_file)
|
9
|
-
"<file name='#{text_file.filename}' mime_type='#{text_file.mime_type}'>#{text_file.content}</file>"
|
10
|
-
end
|
11
|
-
|
12
8
|
def hash_get(hash, key)
|
13
9
|
hash[key.to_sym] || hash[key.to_s]
|
14
10
|
end
|
@@ -36,12 +32,12 @@ module RubyLLM
|
|
36
32
|
value.is_a?(Date) ? value : Date.parse(value.to_s)
|
37
33
|
end
|
38
34
|
|
39
|
-
def deep_merge(
|
40
|
-
|
41
|
-
if
|
42
|
-
deep_merge(
|
35
|
+
def deep_merge(original, overrides)
|
36
|
+
original.merge(overrides) do |_key, original_value, overrides_value|
|
37
|
+
if original_value.is_a?(Hash) && overrides_value.is_a?(Hash)
|
38
|
+
deep_merge(original_value, overrides_value)
|
43
39
|
else
|
44
|
-
|
40
|
+
overrides_value
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
data/lib/ruby_llm/version.rb
CHANGED
data/lib/ruby_llm_community.rb
CHANGED
@@ -26,12 +26,12 @@ loader.inflector.inflect(
|
|
26
26
|
'mistral' => 'Mistral',
|
27
27
|
'pdf' => 'PDF',
|
28
28
|
'version' => 'VERSION',
|
29
|
-
'vertexai' => 'VertexAI'
|
29
|
+
'vertexai' => 'VertexAI',
|
30
|
+
'xai' => 'XAI',
|
31
|
+
'UI' => 'UI'
|
30
32
|
)
|
31
33
|
loader.ignore("#{__dir__}/shims")
|
32
34
|
loader.ignore("#{__dir__}/tasks")
|
33
|
-
loader.ignore("#{__dir__}/ruby_llm/railtie")
|
34
|
-
loader.ignore("#{__dir__}/ruby_llm/active_record")
|
35
35
|
loader.ignore("#{__dir__}/generators")
|
36
36
|
loader.setup
|
37
37
|
|
@@ -99,6 +99,7 @@ RubyLLM::Provider.register :openai, RubyLLM::Providers::OpenAI
|
|
99
99
|
RubyLLM::Provider.register :openrouter, RubyLLM::Providers::OpenRouter
|
100
100
|
RubyLLM::Provider.register :perplexity, RubyLLM::Providers::Perplexity
|
101
101
|
RubyLLM::Provider.register :vertexai, RubyLLM::Providers::VertexAI
|
102
|
+
RubyLLM::Provider.register :xai, RubyLLM::Providers::XAI
|
102
103
|
|
103
104
|
if defined?(Rails::Railtie)
|
104
105
|
require 'ruby_llm/railtie'
|
data/lib/tasks/models.rake
CHANGED
@@ -39,16 +39,19 @@ end
|
|
39
39
|
|
40
40
|
def configure_from_env
|
41
41
|
RubyLLM.configure do |config|
|
42
|
-
|
42
|
+
# Providers
|
43
43
|
config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil)
|
44
|
-
config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil)
|
45
44
|
config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil)
|
46
|
-
config.
|
47
|
-
config.openrouter_api_key = ENV.fetch('OPENROUTER_API_KEY', nil)
|
45
|
+
config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil)
|
48
46
|
config.mistral_api_key = ENV.fetch('MISTRAL_API_KEY', nil)
|
47
|
+
config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil)
|
48
|
+
config.openrouter_api_key = ENV.fetch('OPENROUTER_API_KEY', nil)
|
49
|
+
config.perplexity_api_key = ENV.fetch('PERPLEXITY_API_KEY', nil)
|
49
50
|
config.vertexai_location = ENV.fetch('GOOGLE_CLOUD_LOCATION', nil)
|
50
51
|
config.vertexai_project_id = ENV.fetch('GOOGLE_CLOUD_PROJECT', nil)
|
52
|
+
config.xai_api_key = ENV.fetch('XAI_API_KEY', nil)
|
51
53
|
configure_bedrock(config)
|
54
|
+
# Requests
|
52
55
|
config.request_timeout = 30
|
53
56
|
end
|
54
57
|
end
|
@@ -76,7 +79,7 @@ def refresh_models
|
|
76
79
|
validate_models!(models)
|
77
80
|
|
78
81
|
puts "Saving models.json (#{models.all.size} models)"
|
79
|
-
models.
|
82
|
+
models.save_to_json
|
80
83
|
end
|
81
84
|
|
82
85
|
@models = models
|
@@ -427,6 +430,27 @@ def generate_aliases # rubocop:disable Metrics/PerceivedComplexity
|
|
427
430
|
}
|
428
431
|
end
|
429
432
|
|
433
|
+
models['xai'].each do |model|
|
434
|
+
# xAI aliases
|
435
|
+
m = RubyLLM.models.find(model)
|
436
|
+
next unless m.metadata&.dig(:aliases)
|
437
|
+
|
438
|
+
m.metadata[:aliases].each do |alias_name|
|
439
|
+
aliases[alias_name] = { 'xai' => m.id }
|
440
|
+
end
|
441
|
+
|
442
|
+
# OpenRouter aliases.
|
443
|
+
# NOTE: OpenRouter uses "x-ai" as the provider slug
|
444
|
+
openrouter_model = "x-ai/#{model}"
|
445
|
+
next unless models['openrouter'].include?(openrouter_model)
|
446
|
+
|
447
|
+
alias_key = model.gsub('-latest', '').gsub(/-\d{4}/, '-4')
|
448
|
+
aliases[alias_key] = {
|
449
|
+
'xai' => alias_key,
|
450
|
+
'openrouter' => openrouter_model
|
451
|
+
}
|
452
|
+
end
|
453
|
+
|
430
454
|
sorted_aliases = aliases.sort.to_h
|
431
455
|
File.write(RubyLLM::Aliases.aliases_file, JSON.pretty_generate(sorted_aliases))
|
432
456
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :ruby_llm do
|
4
|
+
desc 'Load models from models.json into the database'
|
5
|
+
task load_models: :environment do
|
6
|
+
if RubyLLM.config.model_registry_class
|
7
|
+
RubyLLM.models.load_from_json!
|
8
|
+
model_class = RubyLLM.config.model_registry_class.constantize
|
9
|
+
model_class.save_to_database
|
10
|
+
puts "✅ Loaded #{model_class.count} models into database"
|
11
|
+
else
|
12
|
+
puts 'Model registry not configured. Run rails generate ruby_llm:install'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/tasks/vcr.rake
CHANGED
@@ -75,11 +75,11 @@ end
|
|
75
75
|
|
76
76
|
namespace :vcr do
|
77
77
|
desc 'Record VCR cassettes (rake vcr:record[all] or vcr:record[openai,anthropic])'
|
78
|
-
task :record,
|
78
|
+
task :record, :providers do |_, args|
|
79
79
|
require 'fileutils'
|
80
80
|
require 'ruby_llm'
|
81
81
|
|
82
|
-
providers = (args[:providers]
|
82
|
+
providers = args.extras.unshift(args[:providers]).compact.map(&:downcase)
|
83
83
|
cassette_dir = 'spec/fixtures/vcr_cassettes'
|
84
84
|
FileUtils.mkdir_p(cassette_dir)
|
85
85
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_llm_community
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Shippy
|
@@ -136,7 +136,23 @@ extra_rdoc_files: []
|
|
136
136
|
files:
|
137
137
|
- LICENSE
|
138
138
|
- README.md
|
139
|
-
- lib/generators/ruby_llm/
|
139
|
+
- lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb
|
140
|
+
- lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt
|
141
|
+
- lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt
|
142
|
+
- lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt
|
143
|
+
- lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt
|
144
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt
|
145
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt
|
146
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt
|
147
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt
|
148
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt
|
149
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt
|
150
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt
|
151
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt
|
152
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt
|
153
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt
|
154
|
+
- lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt
|
155
|
+
- lib/generators/ruby_llm/install/install_generator.rb
|
140
156
|
- lib/generators/ruby_llm/install/templates/chat_model.rb.tt
|
141
157
|
- lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt
|
142
158
|
- lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt
|
@@ -146,8 +162,13 @@ files:
|
|
146
162
|
- lib/generators/ruby_llm/install/templates/message_model.rb.tt
|
147
163
|
- lib/generators/ruby_llm/install/templates/model_model.rb.tt
|
148
164
|
- lib/generators/ruby_llm/install/templates/tool_call_model.rb.tt
|
149
|
-
- lib/generators/ruby_llm/
|
165
|
+
- lib/generators/ruby_llm/upgrade_to_v1_7/templates/migration.rb.tt
|
166
|
+
- lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb
|
150
167
|
- lib/ruby_llm/active_record/acts_as.rb
|
168
|
+
- lib/ruby_llm/active_record/acts_as_legacy.rb
|
169
|
+
- lib/ruby_llm/active_record/chat_methods.rb
|
170
|
+
- lib/ruby_llm/active_record/message_methods.rb
|
171
|
+
- lib/ruby_llm/active_record/model_methods.rb
|
151
172
|
- lib/ruby_llm/aliases.json
|
152
173
|
- lib/ruby_llm/aliases.rb
|
153
174
|
- lib/ruby_llm/attachment.rb
|
@@ -242,6 +263,10 @@ files:
|
|
242
263
|
- lib/ruby_llm/providers/vertexai/embeddings.rb
|
243
264
|
- lib/ruby_llm/providers/vertexai/models.rb
|
244
265
|
- lib/ruby_llm/providers/vertexai/streaming.rb
|
266
|
+
- lib/ruby_llm/providers/xai.rb
|
267
|
+
- lib/ruby_llm/providers/xai/capabilities.rb
|
268
|
+
- lib/ruby_llm/providers/xai/chat.rb
|
269
|
+
- lib/ruby_llm/providers/xai/models.rb
|
245
270
|
- lib/ruby_llm/railtie.rb
|
246
271
|
- lib/ruby_llm/stream_accumulator.rb
|
247
272
|
- lib/ruby_llm/streaming.rb
|
@@ -253,6 +278,7 @@ files:
|
|
253
278
|
- lib/shims/ruby_llm.rb
|
254
279
|
- lib/tasks/models.rake
|
255
280
|
- lib/tasks/release.rake
|
281
|
+
- lib/tasks/ruby_llm.rake
|
256
282
|
- lib/tasks/vcr.rake
|
257
283
|
homepage: https://rubyllm.com
|
258
284
|
licenses:
|
@@ -264,6 +290,9 @@ metadata:
|
|
264
290
|
documentation_uri: https://rubyllm.com
|
265
291
|
bug_tracker_uri: https://github.com/tpaulshippy/ruby_llm_community/issues
|
266
292
|
rubygems_mfa_required: 'true'
|
293
|
+
post_install_message: |
|
294
|
+
Upgrading from RubyLLM <= 1.6.x? Check the upgrade guide for new features and migration instructions
|
295
|
+
--> https://rubyllm.com/upgrading-to-1-7/
|
267
296
|
rdoc_options: []
|
268
297
|
require_paths:
|
269
298
|
- lib
|
@@ -1,108 +0,0 @@
|
|
1
|
-
# RubyLLM Rails Setup Complete!
|
2
|
-
|
3
|
-
Thanks for installing RubyLLM in your Rails application. Here's what was created:
|
4
|
-
|
5
|
-
## Models
|
6
|
-
|
7
|
-
- `<%= options[:chat_model_name] %>` - Stores chat sessions and their associated model ID
|
8
|
-
- `<%= options[:message_model_name] %>` - Stores individual messages in a chat
|
9
|
-
- `<%= options[:tool_call_model_name] %>` - Stores tool calls made by language models
|
10
|
-
|
11
|
-
**Note:** Do not add `validates :content, presence: true` to your Message model - RubyLLM creates empty assistant messages before API calls for streaming support.
|
12
|
-
|
13
|
-
## Configuration Options
|
14
|
-
|
15
|
-
The generator supports the following options to customize model names:
|
16
|
-
|
17
|
-
```bash
|
18
|
-
rails generate ruby_llm:install \
|
19
|
-
--chat-model-name=Conversation \
|
20
|
-
--message-model-name=ChatMessage \
|
21
|
-
--tool-call-model-name=FunctionCall
|
22
|
-
```
|
23
|
-
|
24
|
-
This is useful when you need to avoid namespace collisions with existing models in your application. Table names will be automatically derived from the model names following Rails conventions.
|
25
|
-
|
26
|
-
## Next Steps
|
27
|
-
|
28
|
-
1. **Run migrations:**
|
29
|
-
```bash
|
30
|
-
rails db:migrate
|
31
|
-
```
|
32
|
-
|
33
|
-
**Database Note:** The migrations use `jsonb` for PostgreSQL and `json` for MySQL/SQLite automatically.
|
34
|
-
|
35
|
-
2. **Set your API keys** in `config/initializers/ruby_llm.rb` or using environment variables:
|
36
|
-
```ruby
|
37
|
-
# config/initializers/ruby_llm.rb
|
38
|
-
RubyLLM.configure do |config|
|
39
|
-
config.openai_api_key = ENV['OPENAI_API_KEY']
|
40
|
-
config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
|
41
|
-
config.gemini_api_key = ENV['GEMINI_API_KEY']
|
42
|
-
# ... add other providers as needed
|
43
|
-
end
|
44
|
-
```
|
45
|
-
|
46
|
-
3. **Start using RubyLLM in your code:**
|
47
|
-
```ruby
|
48
|
-
# Basic usage
|
49
|
-
chat = <%= options[:chat_model_name] %>.create!(model_id: 'gpt-4.1-nano')
|
50
|
-
response = chat.ask("What is Ruby on Rails?")
|
51
|
-
|
52
|
-
# With file attachments (requires ActiveStorage setup)
|
53
|
-
chat.ask("What's in this file?", with: "report.pdf")
|
54
|
-
chat.ask("Analyze these files", with: ["image.jpg", "data.csv", "notes.txt"])
|
55
|
-
```
|
56
|
-
|
57
|
-
4. **For streaming responses** with Hotwire/Turbo:
|
58
|
-
```ruby
|
59
|
-
# app/models/<%= options[:message_model_name].underscore %>.rb
|
60
|
-
class <%= options[:message_model_name] %> < ApplicationRecord
|
61
|
-
acts_as_message
|
62
|
-
|
63
|
-
# Helper to broadcast chunks during streaming
|
64
|
-
def broadcast_append_chunk(chunk_content)
|
65
|
-
broadcast_append_to [ chat, "messages" ],
|
66
|
-
target: dom_id(self, "content"),
|
67
|
-
html: chunk_content
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# app/jobs/chat_stream_job.rb
|
72
|
-
class ChatStreamJob < ApplicationJob
|
73
|
-
def perform(chat_id, user_content)
|
74
|
-
chat = <%= options[:chat_model_name] %>.find(chat_id)
|
75
|
-
chat.ask(user_content) do |chunk|
|
76
|
-
assistant_message = chat.messages.last
|
77
|
-
if chunk.content && assistant_message
|
78
|
-
assistant_message.broadcast_append_chunk(chunk.content)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# In your controller
|
85
|
-
ChatStreamJob.perform_later(@chat.id, params[:content])
|
86
|
-
```
|
87
|
-
|
88
|
-
## Optional: ActiveStorage for Attachments
|
89
|
-
|
90
|
-
If you want to use file attachments (PDFs, images, etc.), set up ActiveStorage:
|
91
|
-
|
92
|
-
```bash
|
93
|
-
rails active_storage:install
|
94
|
-
rails db:migrate
|
95
|
-
```
|
96
|
-
|
97
|
-
Then add to your Message model:
|
98
|
-
```ruby
|
99
|
-
class <%= options[:message_model_name] %> < ApplicationRecord
|
100
|
-
acts_as_message
|
101
|
-
has_many_attached :attachments
|
102
|
-
end
|
103
|
-
```
|
104
|
-
|
105
|
-
## Learn More
|
106
|
-
|
107
|
-
- See the [Rails Integration Guide](https://rubyllm.com/guides/rails) for detailed examples
|
108
|
-
- Visit the [RubyLLM Documentation](https://rubyllm.com) for full API reference
|
@@ -1,146 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails/generators'
|
4
|
-
require 'rails/generators/active_record'
|
5
|
-
|
6
|
-
module RubyLLM
|
7
|
-
# Generator for RubyLLM Rails models and migrations
|
8
|
-
class InstallGenerator < Rails::Generators::Base
|
9
|
-
include Rails::Generators::Migration
|
10
|
-
|
11
|
-
namespace 'ruby_llm:install'
|
12
|
-
|
13
|
-
source_root File.expand_path('install/templates', __dir__)
|
14
|
-
|
15
|
-
class_option :chat_model_name, type: :string, default: 'Chat',
|
16
|
-
desc: 'Name of the Chat model class'
|
17
|
-
class_option :message_model_name, type: :string, default: 'Message',
|
18
|
-
desc: 'Name of the Message model class'
|
19
|
-
class_option :tool_call_model_name, type: :string, default: 'ToolCall',
|
20
|
-
desc: 'Name of the ToolCall model class'
|
21
|
-
class_option :model_model_name, type: :string, default: 'Model',
|
22
|
-
desc: 'Name of the Model model class (for model registry)'
|
23
|
-
class_option :skip_model, type: :boolean, default: false,
|
24
|
-
desc: 'Skip creating Model model for model registry persistence'
|
25
|
-
|
26
|
-
desc 'Creates models and migrations for RubyLLM Rails integration'
|
27
|
-
|
28
|
-
def self.next_migration_number(dirname)
|
29
|
-
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
30
|
-
end
|
31
|
-
|
32
|
-
def migration_version
|
33
|
-
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
34
|
-
end
|
35
|
-
|
36
|
-
def postgresql?
|
37
|
-
::ActiveRecord::Base.connection.adapter_name.downcase.include?('postgresql')
|
38
|
-
rescue StandardError
|
39
|
-
false
|
40
|
-
end
|
41
|
-
|
42
|
-
def acts_as_chat_declaration
|
43
|
-
acts_as_chat_params = []
|
44
|
-
if options[:message_model_name] != 'Message'
|
45
|
-
acts_as_chat_params << "message_class: \"#{options[:message_model_name]}\""
|
46
|
-
end
|
47
|
-
if options[:tool_call_model_name] != 'ToolCall'
|
48
|
-
acts_as_chat_params << "tool_call_class: \"#{options[:tool_call_model_name]}\""
|
49
|
-
end
|
50
|
-
if acts_as_chat_params.any?
|
51
|
-
"acts_as_chat #{acts_as_chat_params.join(', ')}"
|
52
|
-
else
|
53
|
-
'acts_as_chat'
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def acts_as_message_declaration
|
58
|
-
acts_as_message_params = []
|
59
|
-
acts_as_message_params << "chat_class: \"#{options[:chat_model_name]}\"" if options[:chat_model_name] != 'Chat'
|
60
|
-
if options[:tool_call_model_name] != 'ToolCall'
|
61
|
-
acts_as_message_params << "tool_call_class: \"#{options[:tool_call_model_name]}\""
|
62
|
-
end
|
63
|
-
if acts_as_message_params.any?
|
64
|
-
"acts_as_message #{acts_as_message_params.join(', ')}"
|
65
|
-
else
|
66
|
-
'acts_as_message'
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def acts_as_tool_call_declaration
|
71
|
-
acts_as_tool_call_params = []
|
72
|
-
if options[:message_model_name] != 'Message'
|
73
|
-
acts_as_tool_call_params << "message_class: \"#{options[:message_model_name]}\""
|
74
|
-
end
|
75
|
-
if acts_as_tool_call_params.any?
|
76
|
-
"acts_as_tool_call #{acts_as_tool_call_params.join(', ')}"
|
77
|
-
else
|
78
|
-
'acts_as_tool_call'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def acts_as_model_declaration
|
83
|
-
'acts_as_model'
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_migration_files
|
87
|
-
# Create migrations with timestamps to ensure proper order
|
88
|
-
# First create chats table
|
89
|
-
migration_template 'create_chats_migration.rb.tt',
|
90
|
-
"db/migrate/create_#{options[:chat_model_name].tableize}.rb"
|
91
|
-
|
92
|
-
# Then create messages table (must come before tool_calls due to foreign key)
|
93
|
-
sleep 1 # Ensure different timestamp
|
94
|
-
migration_template 'create_messages_migration.rb.tt',
|
95
|
-
"db/migrate/create_#{options[:message_model_name].tableize}.rb"
|
96
|
-
|
97
|
-
# Then create tool_calls table (references messages)
|
98
|
-
sleep 1 # Ensure different timestamp
|
99
|
-
migration_template 'create_tool_calls_migration.rb.tt',
|
100
|
-
"db/migrate/create_#{options[:tool_call_model_name].tableize}.rb"
|
101
|
-
|
102
|
-
# Finally create models table (for model registry)
|
103
|
-
return if options[:skip_model]
|
104
|
-
|
105
|
-
sleep 1 # Ensure different timestamp
|
106
|
-
migration_template 'create_models_migration.rb.tt',
|
107
|
-
"db/migrate/create_#{options[:model_model_name].tableize}.rb"
|
108
|
-
end
|
109
|
-
|
110
|
-
def create_model_files
|
111
|
-
template 'chat_model.rb.tt', "app/models/#{options[:chat_model_name].underscore}.rb"
|
112
|
-
template 'message_model.rb.tt', "app/models/#{options[:message_model_name].underscore}.rb"
|
113
|
-
template 'tool_call_model.rb.tt', "app/models/#{options[:tool_call_model_name].underscore}.rb"
|
114
|
-
|
115
|
-
return if options[:skip_model]
|
116
|
-
|
117
|
-
template 'model_model.rb.tt', "app/models/#{options[:model_model_name].underscore}.rb"
|
118
|
-
end
|
119
|
-
|
120
|
-
def create_initializer
|
121
|
-
template 'initializer.rb.tt', 'config/initializers/ruby_llm.rb'
|
122
|
-
end
|
123
|
-
|
124
|
-
def show_install_info
|
125
|
-
say "\n ✅ RubyLLM installed!", :green
|
126
|
-
|
127
|
-
say "\n Next steps:", :yellow
|
128
|
-
say ' 1. Run: rails db:migrate'
|
129
|
-
say ' 2. Set your API keys in config/initializers/ruby_llm.rb'
|
130
|
-
say " 3. Start chatting: #{options[:chat_model_name]}.create!(model_id: 'gpt-4.1-nano').ask('Hello!')"
|
131
|
-
|
132
|
-
unless options[:skip_model]
|
133
|
-
say " 4. Sync models: #{options[:model_model_name]}.sync!"
|
134
|
-
say "\n 🚀 Model registry is database-backed!", :cyan
|
135
|
-
say ' Models will automatically load from the database'
|
136
|
-
end
|
137
|
-
|
138
|
-
say "\n 📚 Full docs: https://rubyllm.com", :cyan
|
139
|
-
|
140
|
-
say "\n ❤️ Love RubyLLM?", :magenta
|
141
|
-
say ' • ⭐ Star on GitHub: https://github.com/crmne/ruby_llm'
|
142
|
-
say ' • 💖 Sponsor: https://github.com/sponsors/crmne'
|
143
|
-
say "\n"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|