Module: RubyLLM::Generators::GeneratorHelpers
- Included in:
- ChatUIGenerator, InstallGenerator, ToolGenerator, UpgradeGenerator
- Defined in:
- lib/generators/ruby_llm/generator_helpers.rb
Overview
Shared helpers for RubyLLM generators
Constant Summary collapse
- APPLICATION_MODEL_TYPES =
%w[chat message].freeze
- DEFAULT_MODEL_NAMES =
{ chat: 'Chat', message: 'Message' }.freeze
Instance Method Summary collapse
- #acts_as_chat_declaration ⇒ Object
- #acts_as_message_declaration ⇒ Object
- #chat_controller_class_name ⇒ Object
- #chat_job_class_name ⇒ Object
- #create_migration_class_name(table_name) ⇒ Object
- #create_namespace_modules ⇒ Object
- #gem_in_bundle?(gem_name) ⇒ Boolean
- #message_controller_class_name ⇒ Object
- #migration_version ⇒ Object
- #model_controller_class_name ⇒ Object
-
#model_model_name ⇒ Object
Models remain a UI resource even though RubyLLM owns their persistence.
-
#model_resource_name ⇒ Object
Routes, view paths and DOM ids for the models UI.
- #model_variable_name ⇒ Object
- #mysql? ⇒ Boolean
- #parse_model_mappings(allowed_types: APPLICATION_MODEL_TYPES, defaults: DEFAULT_MODEL_NAMES) ⇒ Object
- #postgresql? ⇒ Boolean
- #reference_type ⇒ Object
- #table_exists?(table_name) ⇒ Boolean
- #tailwind_available? ⇒ Boolean
- #tool_call_variable_name ⇒ Object
- #ui_template(template_path) ⇒ Object
- #ui_variant ⇒ Object
-
#unprocessable_content_status ⇒ Object
Rack 3.1 renamed the 422 symbol and Rails mirrors the rename from 7.2 on.
- #usage_operations_sql ⇒ Object
- #usage_statuses_sql ⇒ Object
- #validate_model_mapping!(mapping, key, value, allowed_types) ⇒ Object
Instance Method Details
#acts_as_chat_declaration ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 86 def acts_as_chat_declaration params = [] add_association_params(params, :messages, , , owner_table: chat_table_name, owner_model_name: chat_model_name, plural: true) "acts_as_chat#{" #{params.join(', ')}" if params.any?}" end |
#acts_as_message_declaration ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 94 def params = [] add_association_params(params, :chat, chat_table_name, chat_model_name, owner_table: , owner_model_name: ) "acts_as_message#{" #{params.join(', ')}" if params.any?}" end |
#chat_controller_class_name ⇒ Object
70 71 72 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 70 def chat_controller_class_name controller_class_name_for(chat_model_name) end |
#chat_job_class_name ⇒ Object
82 83 84 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 82 def chat_job_class_name "#{chat_variable_name.camelize}ResponseJob" end |
#create_migration_class_name(table_name) ⇒ Object
147 148 149 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 147 def create_migration_class_name(table_name) "create_#{table_name}".camelize end |
#create_namespace_modules ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 102 def create_namespace_modules namespaces = [] [chat_model_name, ].each do |model_name| if model_name.include?('::') namespace = model_name.split('::').first namespaces << namespace unless namespaces.include?(namespace) end end namespaces.each do |namespace| module_path = "app/models/#{namespace.underscore}.rb" next if File.exist?(Rails.root.join(module_path)) create_file module_path do <<~RUBY module #{namespace} def self.table_name_prefix "#{namespace.underscore}_" end end RUBY end end end |
#gem_in_bundle?(gem_name) ⇒ Boolean
196 197 198 199 200 201 202 203 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 196 def gem_in_bundle?(gem_name) gemfile_path = Rails.root.join('Gemfile') lockfile_path = Rails.root.join('Gemfile.lock') [gemfile_path, lockfile_path].any? do |path| path.exist? && path.read.include?(gem_name) end end |
#message_controller_class_name ⇒ Object
74 75 76 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 74 def controller_class_name_for() end |
#migration_version ⇒ Object
128 129 130 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 128 def migration_version "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" end |
#model_controller_class_name ⇒ Object
78 79 80 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 78 def model_controller_class_name controller_class_name_for(model_model_name) end |
#model_model_name ⇒ Object
Models remain a UI resource even though RubyLLM owns their persistence. Keep that resource beside a namespaced chat without implying that the application has a corresponding ActiveRecord model.
54 55 56 57 58 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 54 def model_model_name return 'Model' unless chat_model_name.include?('::') "#{chat_model_name.deconstantize}::Model" end |
#model_resource_name ⇒ Object
Routes, view paths and DOM ids for the models UI. Deliberately not a table name: models live in ruby_llm_models whatever the app calls this resource, and they are reached through the :model association.
63 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 63 def model_resource_name = table_name_for(model_model_name) |
#model_variable_name ⇒ Object
64 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 64 def model_variable_name = variable_name_for(model_model_name) |
#mysql? ⇒ Boolean
157 158 159 160 161 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 157 def mysql? ::ActiveRecord::Base.connection.adapter_name.downcase.include?('mysql') rescue StandardError false end |
#parse_model_mappings(allowed_types: APPLICATION_MODEL_TYPES, defaults: DEFAULT_MODEL_NAMES) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 13 def parse_model_mappings(allowed_types: APPLICATION_MODEL_TYPES, defaults: DEFAULT_MODEL_NAMES) @model_names = defaults.dup @explicit_model_mappings = [] model_mappings.each do |mapping| key, value = mapping.split(':', 2) validate_model_mapping!(mapping, key, value, allowed_types) raise Thor::Error, "Duplicate model mapping: #{key}" if @explicit_model_mappings.include?(key.to_sym) @explicit_model_mappings << key.to_sym @model_names[key.to_sym] = value.classify end @model_names end |
#postgresql? ⇒ Boolean
151 152 153 154 155 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 151 def postgresql? ::ActiveRecord::Base.connection.adapter_name.downcase.include?('postgresql') rescue StandardError false end |
#reference_type ⇒ Object
140 141 142 143 144 145 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 140 def reference_type application = Rails.application if Rails.respond_to?(:application) return :bigint unless application application.config.generators..dig(:active_record, :primary_key_type) || :bigint end |
#table_exists?(table_name) ⇒ Boolean
163 164 165 166 167 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 163 def table_exists?(table_name) ::ActiveRecord::Base.connection.table_exists?(table_name) rescue StandardError false end |
#tailwind_available? ⇒ Boolean
189 190 191 192 193 194 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 189 def tailwind_available? Rails.root.join('app/assets/tailwind/application.css').exist? || Rails.root.join('config/tailwind.config.js').exist? || gem_in_bundle?('tailwindcss-rails') || gem_in_bundle?('cssbundling-rails') end |
#tool_call_variable_name ⇒ Object
68 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 68 def tool_call_variable_name = 'tool_call' |
#ui_template(template_path) ⇒ Object
180 181 182 183 184 185 186 187 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 180 def ui_template(template_path) return template_path unless ui_variant == :tailwind # Keep Tailwind templates as a separate set so we can mirror Rails/Tailwind # scaffold conventions without complicating scaffold templates. tailwind_template = "tailwind/#{template_path}" File.exist?(File.join(self.class.source_root, "#{tailwind_template}.tt")) ? tailwind_template : template_path end |
#ui_variant ⇒ Object
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 169 def ui_variant @ui_variant ||= case [:ui] when 'tailwind' :tailwind when 'auto' tailwind_available? ? :tailwind : :scaffold else :scaffold end end |
#unprocessable_content_status ⇒ Object
Rack 3.1 renamed the 422 symbol and Rails mirrors the rename from 7.2 on.
133 134 135 136 137 138 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 133 def unprocessable_content_status constants = ::ActionDispatch::Constants return :unprocessable_entity unless constants.const_defined?(:UNPROCESSABLE_CONTENT) constants::UNPROCESSABLE_CONTENT end |
#usage_operations_sql ⇒ Object
66 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 66 def usage_operations_sql = sql_string_list(::RubyLLM::Accounting::Usage::Entry::OPERATIONS) |
#usage_statuses_sql ⇒ Object
67 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 67 def usage_statuses_sql = sql_string_list(::RubyLLM::Accounting::Usage::Entry::STATUSES) |
#validate_model_mapping!(mapping, key, value, allowed_types) ⇒ Object
29 30 31 32 33 34 |
# File 'lib/generators/ruby_llm/generator_helpers.rb', line 29 def validate_model_mapping!(mapping, key, value, allowed_types) return if allowed_types.include?(key) && value.present? expected = allowed_types.map { |type| "#{type}:ModelName" }.join(', ') raise Thor::Error, "Invalid model mapping #{mapping.inspect}. Expected one of: #{expected}" end |