class RailsAiAdmin::Configuration
Declares host adapters as names so development reload resolves fresh classes.
Constants
- INTERNAL_PATH
- OPTIONAL_GEMS
-
Gems an opt-in feature needs in the host’s own Gemfile. The gemspec does not depend on them, so a conventional install pulls no AI code; boot enforces the supported range instead (RAA-026).
- PROVIDER_NAME
Attributes
Public Class Methods
Source
# File lib/rails_ai_admin/configuration.rb, line 56 def initialize @authentication_path = nil @context_adapter = nil @authorization_adapter = "RailsAiAdmin::Authorization::Adapter" @resources = [] @title = "Administration" @intent_ttl = 15.minutes @work_handlers = {} @outbox_auto_dispatch = false @collection_auto_dispatch = false @field_types = {} @surfaces = false @queue_name = "rails_ai_admin" @validation_messages = :model @assistant = false @assistant_adapter = nil @assistant_model = nil @assistant_provider = nil @assistant_protocol = nil @assistant_daily_message_limit = 100 @assistant_streaming = true @export_limit = 10_000 @import_limit = 500 @mcp = false end
Source
# File lib/rails_ai_admin/configuration.rb, line 17 def self.optional_gem_problem(name, feature, version: OPTIONAL_GEMS.fetch(name).fetch(:constant).safe_constantize) requirement = Gem::Requirement.new(*OPTIONAL_GEMS.fetch(name).fetch(:requirement)) return if version && requirement.satisfied_by?(Gem::Version.new(version)) "#{feature} needs #{name} #{requirement} in the host Gemfile (#{version ? "#{version} is loaded" : 'it is not loaded'})" end
Nil when the loaded version of an optional gem is supported, otherwise a message naming the feature, the range and what is loaded.
Public Instance Methods
Source
# File lib/rails_ai_admin/configuration.rb, line 83 def finalize! [ context_adapter, authorization_adapter ].compact.each do |name| raise ConfigurationError, "Adapters must be constant name strings" unless name.is_a?(String) && name.match?(/\A[A-Z]\w*(?:::[A-Z]\w*)*\z/) end unless resources.is_a?(Array) && resources.all? { |name| name.is_a?(String) } raise ConfigurationError, "resources must contain constant name strings" end raise ConfigurationError, "intent_ttl must be between 60 and 3600 seconds" unless (60..3600).cover?(intent_ttl) unless work_handlers.is_a?(Hash) && work_handlers.all? { |kind, name| kind.is_a?(String) && kind.match?(/\A[a-z][a-z0-9_.-]{0,99}\z/) && name.is_a?(String) && name.match?(/\A[A-Z]\w*(?:::[A-Z]\w*)*\z/) } && [ true, false ].include?(outbox_auto_dispatch) raise ConfigurationError, "work_handlers needs stable string keys/class names and outbox_auto_dispatch must be boolean" end raise ConfigurationError, "collection_auto_dispatch must be boolean" unless [ true, false ].include?(collection_auto_dispatch) raise ConfigurationError, "surfaces must be boolean" unless [ true, false ].include?(surfaces) unless environment_label.nil? || environment_label.is_a?(String) && environment_label.valid_encoding? && environment_label.length.between?(1, 40) && !environment_label.match?(/[[:cntrl:]]/) raise ConfigurationError, "environment_label must be nil or 1 to 40 characters of plain text" end environment_label&.freeze raise ConfigurationError, "validation_messages must be :model or :generic" unless %i[model generic].include?(validation_messages) raise ConfigurationError, "export_limit must be an Integer from 1 to 100000" unless export_limit.is_a?(Integer) && export_limit.between?(1, 100_000) raise ConfigurationError, "import_limit must be an Integer from 1 to 5000" unless import_limit.is_a?(Integer) && import_limit.between?(1, 5_000) unless (queue_name.is_a?(String) || queue_name.is_a?(Symbol)) && queue_name.to_s.match?(/\A[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}\z/) raise ConfigurationError, "queue_name must be a short queue name" end self.queue_name = queue_name.to_s.freeze if surfaces && !defined?(::RailsToolViews::Engine) raise ConfigurationError, "surfaces requires the host to load rails_tool_views (add it to the Gemfile and run its installer)" end if surfaces && (problem = self.class.optional_gem_problem("rails_tool_views", "surfaces")) raise ConfigurationError, problem end if surfaces && (problem = surfaces_parent_controller_problem) raise ConfigurationError, problem end validate_assistant! raise ConfigurationError, "mcp must be boolean" unless [ true, false ].include?(mcp) raise ConfigurationError, "assistant_streaming must be boolean" unless [ true, false ].include?(assistant_streaming) raise ConfigurationError, "mcp requires config.assistant (its tables, ruby_llm and resolve_job)" if mcp && !assistant unless authentication_path.nil? || authentication_path.is_a?(String) && authentication_path.valid_encoding? && authentication_path.ascii_only? && authentication_path.match?(INTERNAL_PATH) raise ConfigurationError, "authentication_path must be a fixed internal path without query or fragment" end authentication_path&.freeze Fields::Registry.new(field_types).validate! field_types.each { |key, name| key.freeze; name.freeze } field_types.freeze work_handlers.each { |kind, name| kind.freeze; name.freeze } work_handlers.freeze resources.each(&:freeze) resources.freeze title.freeze context_adapter&.freeze authorization_adapter.freeze [ assistant_adapter, assistant_model, assistant_provider, assistant_protocol ].each { |value| value&.freeze } freeze end
Validates and freezes the boot configuration without reading domain tables.
Source
# File lib/rails_ai_admin/configuration.rb, line 142 def surfaces_parent_controller_problem return unless defined?(::RailsToolViews) && ::RailsToolViews.respond_to?(:configuration) name = ::RailsToolViews.configuration.parent_controller.to_s parent = name.safe_constantize return if parent.is_a?(Class) && parent <= ::ActionController::Base "surfaces needs rails_tool_views' parent_controller (#{name.inspect}) to name an ActionController::Base subclass. " \ "Add that controller, or set config.parent_controller in your RailsToolViews.configure block." end
rails_tool_views’ own controller inherits its parent_controller when the host eager loads; a missing “::ApplicationController” (an API-only or minimal host) would otherwise fail production boot with a bare NameError (RAA-009, DEP-010). Returns nil when the parent resolves.