dify_llm 1.7.0 → 1.7.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26ba52438e460fd7cb45ccae2718eef3f210288bda1c0964a9a3533b3abbb104
4
- data.tar.gz: 36fc10f694fa81a5ce3cc1736a15bb7cbf7fa8f90c835f010ed0d3a4dd2ce924
3
+ metadata.gz: d0f99a2d917ed4eec1d713f9485558da63d1682463151199705a11c067580d00
4
+ data.tar.gz: c78eef62613a3295db307362b497367affc65687ed295889bd1bb87f2ec1898c
5
5
  SHA512:
6
- metadata.gz: cded1cb65b8e6e3e5f21bcfcdc7d9acf1d2d9c448fa2f2852e06ff58fc85ec9577dc57cdd6e35bba3c61585cb78c33a534621e987d182cb42b8e48cc5fa8af3e
7
- data.tar.gz: be43b11c4c108f31171ddb0cf27f4335ac506ac74fd25fd970e6cdc09aae182cd1678a91e4c322a5976512eca6572363c19f0bb8538efa97a04dd32a29a3072f
6
+ metadata.gz: 6cccd8779101a2f72b73e65aec7b84def9ac63368fd4a07e36347c3c544e687a03ea44ccc7ad85208833e8e7058ccb76d8316d86507951d4adc21be98a7edc1d
7
+ data.tar.gz: 4627baa37a9e94b0569ab25b7d7e39ceb5119022f13092c81f34c0a589c11f22d30b82cf02adf33e11914cf01b1304db111c4fc3253529dc91d7dc734631be0f
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLLM
4
+ # Shared helpers for RubyLLM generators
5
+ module GeneratorHelpers
6
+ def parse_model_mappings
7
+ @model_names = {
8
+ chat: 'Chat',
9
+ message: 'Message',
10
+ tool_call: 'ToolCall',
11
+ model: 'Model'
12
+ }
13
+
14
+ model_mappings.each do |mapping|
15
+ if mapping.include?(':')
16
+ key, value = mapping.split(':', 2)
17
+ @model_names[key.to_sym] = value.classify
18
+ end
19
+ end
20
+
21
+ @model_names
22
+ end
23
+
24
+ %i[chat message tool_call model].each do |type|
25
+ define_method("#{type}_model_name") do
26
+ @model_names ||= parse_model_mappings
27
+ @model_names[type]
28
+ end
29
+
30
+ define_method("#{type}_table_name") do
31
+ table_name_for(send("#{type}_model_name"))
32
+ end
33
+ end
34
+
35
+ def acts_as_chat_declaration
36
+ params = []
37
+
38
+ add_association_params(params, :messages, message_table_name, message_model_name, plural: true)
39
+ add_association_params(params, :model, model_table_name, model_model_name)
40
+
41
+ "acts_as_chat#{" #{params.join(', ')}" if params.any?}"
42
+ end
43
+
44
+ def acts_as_message_declaration
45
+ params = []
46
+
47
+ add_association_params(params, :chat, chat_table_name, chat_model_name)
48
+ add_association_params(params, :tool_calls, tool_call_table_name, tool_call_model_name, plural: true)
49
+ add_association_params(params, :model, model_table_name, model_model_name)
50
+
51
+ "acts_as_message#{" #{params.join(', ')}" if params.any?}"
52
+ end
53
+
54
+ def acts_as_model_declaration
55
+ params = []
56
+
57
+ add_association_params(params, :chats, chat_table_name, chat_model_name, plural: true)
58
+
59
+ "acts_as_model#{" #{params.join(', ')}" if params.any?}"
60
+ end
61
+
62
+ def acts_as_tool_call_declaration
63
+ params = []
64
+
65
+ add_association_params(params, :message, message_table_name, message_model_name)
66
+
67
+ "acts_as_tool_call#{" #{params.join(', ')}" if params.any?}"
68
+ end
69
+
70
+ def create_namespace_modules
71
+ namespaces = []
72
+
73
+ [chat_model_name, message_model_name, tool_call_model_name, model_model_name].each do |model_name|
74
+ if model_name.include?('::')
75
+ namespace = model_name.split('::').first
76
+ namespaces << namespace unless namespaces.include?(namespace)
77
+ end
78
+ end
79
+
80
+ namespaces.each do |namespace|
81
+ module_path = "app/models/#{namespace.underscore}.rb"
82
+ next if File.exist?(Rails.root.join(module_path))
83
+
84
+ create_file module_path do
85
+ <<~RUBY
86
+ module #{namespace}
87
+ def self.table_name_prefix
88
+ "#{namespace.underscore}_"
89
+ end
90
+ end
91
+ RUBY
92
+ end
93
+ end
94
+ end
95
+
96
+ def migration_version
97
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
98
+ end
99
+
100
+ def postgresql?
101
+ ::ActiveRecord::Base.connection.adapter_name.downcase.include?('postgresql')
102
+ rescue StandardError
103
+ false
104
+ end
105
+
106
+ def table_exists?(table_name)
107
+ ::ActiveRecord::Base.connection.table_exists?(table_name)
108
+ rescue StandardError
109
+ false
110
+ end
111
+
112
+ private
113
+
114
+ def add_association_params(params, default_assoc, table_name, model_name, plural: false)
115
+ assoc = plural ? table_name.to_sym : table_name.singularize.to_sym
116
+
117
+ return if assoc == default_assoc
118
+
119
+ params << "#{default_assoc}: :#{assoc}"
120
+ params << "#{default_assoc.to_s.singularize}_class: '#{model_name}'" if model_name != assoc.to_s.classify
121
+ end
122
+
123
+ def table_name_for(model_name)
124
+ # Convert namespaced model names to proper table names
125
+ # e.g., "Assistant::Chat" -> "assistant_chats" (not "assistant/chats")
126
+ model_name.underscore.pluralize.tr('/', '_')
127
+ end
128
+ end
129
+ end
@@ -2,11 +2,13 @@
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
  # Generator for RubyLLM Rails models and migrations
8
9
  class InstallGenerator < Rails::Generators::Base
9
10
  include Rails::Generators::Migration
11
+ include RubyLLM::GeneratorHelpers
10
12
 
11
13
  namespace 'ruby_llm:install'
12
14
 
@@ -24,127 +26,6 @@ module RubyLLM
24
26
  ::ActiveRecord::Generators::Base.next_migration_number(dirname)
25
27
  end
26
28
 
27
- def migration_version
28
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
29
- end
30
-
31
- def postgresql?
32
- ::ActiveRecord::Base.connection.adapter_name.downcase.include?('postgresql')
33
- rescue StandardError
34
- false
35
- end
36
-
37
- def parse_model_mappings
38
- @model_names = {
39
- chat: 'Chat',
40
- message: 'Message',
41
- tool_call: 'ToolCall',
42
- model: 'Model'
43
- }
44
-
45
- model_mappings.each do |mapping|
46
- if mapping.include?(':')
47
- key, value = mapping.split(':', 2)
48
- @model_names[key.to_sym] = value.classify
49
- end
50
- end
51
-
52
- @model_names
53
- end
54
-
55
- %i[chat message tool_call model].each do |type|
56
- define_method("#{type}_model_name") do
57
- @model_names ||= parse_model_mappings
58
- @model_names[type]
59
- end
60
-
61
- define_method("#{type}_table_name") do
62
- table_name_for(send("#{type}_model_name"))
63
- end
64
- end
65
-
66
- def acts_as_chat_declaration
67
- acts_as_chat_params = []
68
- messages_assoc = message_model_name.tableize.to_sym
69
- model_assoc = model_model_name.underscore.to_sym
70
-
71
- if messages_assoc != :messages
72
- acts_as_chat_params << "messages: :#{messages_assoc}"
73
- if message_model_name != messages_assoc.to_s.classify
74
- acts_as_chat_params << "message_class: '#{message_model_name}'"
75
- end
76
- end
77
-
78
- if model_assoc != :model
79
- acts_as_chat_params << "model: :#{model_assoc}"
80
- acts_as_chat_params << "model_class: '#{model_model_name}'" if model_model_name != model_assoc.to_s.classify
81
- end
82
-
83
- if acts_as_chat_params.any?
84
- "acts_as_chat #{acts_as_chat_params.join(', ')}"
85
- else
86
- 'acts_as_chat'
87
- end
88
- end
89
-
90
- def acts_as_message_declaration
91
- params = []
92
-
93
- add_message_association_params(params, :chat, chat_model_name)
94
- add_message_association_params(params, :tool_calls, tool_call_model_name, tableize: true)
95
- add_message_association_params(params, :model, model_model_name)
96
-
97
- params.any? ? "acts_as_message #{params.join(', ')}" : 'acts_as_message'
98
- end
99
-
100
- private
101
-
102
- def add_message_association_params(params, default_assoc, model_name, tableize: false)
103
- assoc = tableize ? model_name.tableize.to_sym : model_name.underscore.to_sym
104
-
105
- return if assoc == default_assoc
106
-
107
- params << "#{default_assoc}: :#{assoc}"
108
- expected_class = assoc.to_s.classify
109
- params << "#{default_assoc.to_s.singularize}_class: '#{model_name}'" if model_name != expected_class
110
- end
111
-
112
- public
113
-
114
- def acts_as_tool_call_declaration
115
- acts_as_tool_call_params = []
116
- message_assoc = message_model_name.underscore.to_sym
117
-
118
- if message_assoc != :message
119
- acts_as_tool_call_params << "message: :#{message_assoc}"
120
- if message_model_name != message_assoc.to_s.classify
121
- acts_as_tool_call_params << "message_class: '#{message_model_name}'"
122
- end
123
- end
124
-
125
- if acts_as_tool_call_params.any?
126
- "acts_as_tool_call #{acts_as_tool_call_params.join(', ')}"
127
- else
128
- 'acts_as_tool_call'
129
- end
130
- end
131
-
132
- def acts_as_model_declaration
133
- acts_as_model_params = []
134
- chats_assoc = chat_model_name.tableize.to_sym
135
-
136
- if chats_assoc != :chats
137
- acts_as_model_params << "chats: :#{chats_assoc}"
138
- acts_as_model_params << "chat_class: '#{chat_model_name}'" if chat_model_name != chats_assoc.to_s.classify
139
- end
140
-
141
- if acts_as_model_params.any?
142
- "acts_as_model #{acts_as_model_params.join(', ')}"
143
- else
144
- 'acts_as_model'
145
- end
146
- end
147
-
148
29
  def create_migration_files
149
30
  # Create migrations with timestamps to ensure proper order
150
31
  # First create chats table
@@ -168,6 +49,8 @@ module RubyLLM
168
49
  end
169
50
 
170
51
  def create_model_files
52
+ create_namespace_modules
53
+
171
54
  template 'chat_model.rb.tt', "app/models/#{chat_model_name.underscore}.rb"
172
55
  template 'message_model.rb.tt', "app/models/#{message_model_name.underscore}.rb"
173
56
  template 'tool_call_model.rb.tt', "app/models/#{tool_call_model_name.underscore}.rb"
@@ -186,12 +69,6 @@ module RubyLLM
186
69
  rails_command 'active_storage:install'
187
70
  end
188
71
 
189
- def table_name_for(model_name)
190
- # Convert namespaced model names to proper table names
191
- # e.g., "Assistant::Chat" -> "assistant_chats" (not "assistant/chats")
192
- model_name.underscore.pluralize.tr('/', '_')
193
- end
194
-
195
72
  def show_install_info
196
73
  say "\n ✅ RubyLLM installed!", :green
197
74
 
@@ -34,10 +34,7 @@ class Create<%= model_model_name.gsub('::', '').pluralize %> < ActiveRecord::Mig
34
34
  # Load models from JSON
35
35
  say_with_time "Loading models from models.json" do
36
36
  RubyLLM.models.load_from_json!
37
- model_class = '<%= model_model_name %>'.constantize
38
- model_class.save_to_database
39
-
40
- "Loaded #{model_class.count} models"
37
+ <%= model_model_name %>.save_to_database
41
38
  end
42
39
  end
43
40
  end
@@ -3,6 +3,14 @@ class MigrateToRubyLLMModelReferences < ActiveRecord::Migration<%= migration_ver
3
3
  model_class = <%= model_model_name %>
4
4
  chat_class = <%= chat_model_name %>
5
5
  message_class = <%= message_model_name %>
6
+ <% if @model_table_already_existed %>
7
+ # Load models from models.json if Model table already existed
8
+ say_with_time "Loading models from models.json" do
9
+ RubyLLM.models.load_from_json!
10
+ model_class.save_to_database
11
+ "Loaded #{model_class.count} models"
12
+ end
13
+ <% end %>
6
14
 
7
15
  # Then check for any models in existing data that aren't in models.json
8
16
  say_with_time "Checking for additional models in existing data" do
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyLLM
4
- VERSION = '1.7.0'
4
+ VERSION = '1.7.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dify_llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carmine Paolino
@@ -152,6 +152,7 @@ files:
152
152
  - lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt
153
153
  - lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt
154
154
  - lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt
155
+ - lib/generators/ruby_llm/generator_helpers.rb
155
156
  - lib/generators/ruby_llm/install/install_generator.rb
156
157
  - lib/generators/ruby_llm/install/templates/chat_model.rb.tt
157
158
  - lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt
@@ -275,14 +276,14 @@ files:
275
276
  - lib/tasks/release.rake
276
277
  - lib/tasks/ruby_llm.rake
277
278
  - lib/tasks/vcr.rake
278
- homepage: https://rubyllm.com
279
+ homepage: https://github.com/crmne/ruby_llm/pull/168
279
280
  licenses:
280
281
  - MIT
281
282
  metadata:
282
- homepage_uri: https://rubyllm.com
283
+ homepage_uri: https://github.com/crmne/ruby_llm/pull/168
283
284
  source_code_uri: https://github.com/crmne/ruby_llm
284
285
  changelog_uri: https://github.com/crmne/ruby_llm/commits/main
285
- documentation_uri: https://rubyllm.com
286
+ documentation_uri: https://github.com/crmne/ruby_llm/pull/168
286
287
  bug_tracker_uri: https://github.com/crmne/ruby_llm/issues
287
288
  rubygems_mfa_required: 'true'
288
289
  post_install_message: |