Module: RailsConsoleAi::Storage::DatabaseStorage
- Defined in:
- lib/rails_console_ai/storage/database_storage.rb
Overview
Thin facade over the AR-backed Skill / Memory tables.
Not a drop-in Storage::Base adapter: the loaders read & write structured records, not opaque Markdown blobs, so we expose a small typed API instead. All methods are safe to call before ‘ai_db_setup` has run — they detect missing tables and return empty results / nil rather than raising.
Class Method Summary collapse
- .active_record_connection ⇒ Object
- .agents_available? ⇒ Boolean
-
.all_agents ⇒ Object
— Agents —.
-
.all_memories ⇒ Object
— Memories —.
-
.all_skills ⇒ Object
— Skills —.
- .available? ⇒ Boolean
- .delete_agent_by_name(name) ⇒ Object
- .delete_memory_by_name(name) ⇒ Object
- .delete_skill_by_name(name) ⇒ Object
- .ensure_tables!(kind) ⇒ Object
- .find_agent_by_name(name) ⇒ Object
- .find_memory_by_name(name) ⇒ Object
- .find_skill_by_name(name) ⇒ Object
- .memories_available? ⇒ Boolean
- .save_agent(name:, description:, body:, max_rounds: nil, model: nil, tools: [], edited_by: nil, change_note: nil) ⇒ Object
- .save_memory(name:, description:, tags: [], edited_by: nil, change_note: nil) ⇒ Object
- .save_skill(name:, description:, body:, tags: [], bypass_guards_for_methods: [], edited_by: nil, change_note: nil) ⇒ Object
-
.table_exists?(table_name) ⇒ Boolean
Ask the connection directly so we don’t depend on the AR model being autoloaded yet.
- .warn_failure(method, error) ⇒ Object
Class Method Details
.active_record_connection ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 37 def active_record_connection klass = RailsConsoleAi.configuration.connection_class if klass klass = Object.const_get(klass) if klass.is_a?(String) klass.connection else ::ActiveRecord::Base.connection end end |
.agents_available? ⇒ Boolean
20 21 22 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 20 def agents_available? table_exists?('rails_console_ai_agents') end |
.all_agents ⇒ Object
— Agents —
139 140 141 142 143 144 145 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 139 def all_agents return [] unless agents_available? RailsConsoleAi::Agent.alphabetical.map(&:to_hash) rescue => e warn_failure(:all_agents, e) [] end |
.all_memories ⇒ Object
— Memories —
95 96 97 98 99 100 101 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 95 def all_memories return [] unless memories_available? RailsConsoleAi::Memory.alphabetical.map(&:to_hash) rescue => e warn_failure(:all_memories, e) [] end |
.all_skills ⇒ Object
— Skills —
49 50 51 52 53 54 55 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 49 def all_skills return [] unless available? RailsConsoleAi::Skill.alphabetical.map(&:to_hash) rescue => e warn_failure(:all_skills, e) [] end |
.available? ⇒ Boolean
12 13 14 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 12 def available? table_exists?('rails_console_ai_skills') end |
.delete_agent_by_name(name) ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 176 def delete_agent_by_name(name) return false unless agents_available? record = RailsConsoleAi::Agent.where('LOWER(name) = ?', name.to_s.downcase).first return false unless record record.destroy true end |
.delete_memory_by_name(name) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 129 def delete_memory_by_name(name) return false unless memories_available? record = RailsConsoleAi::Memory.where('LOWER(name) = ?', name.to_s.downcase).first return false unless record record.destroy true end |
.delete_skill_by_name(name) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 85 def delete_skill_by_name(name) return false unless available? record = RailsConsoleAi::Skill.where('LOWER(name) = ?', name.to_s.downcase).first return false unless record record.destroy true end |
.ensure_tables!(kind) ⇒ Object
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 184 def ensure_tables!(kind) ready = case kind when :skills then available? when :memories then memories_available? when :agents then agents_available? else false end return if ready raise StorageError, "rails_console_ai_#{kind} table does not exist. Run `ai_db_setup` in your console." end |
.find_agent_by_name(name) ⇒ Object
147 148 149 150 151 152 153 154 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 147 def find_agent_by_name(name) return nil unless agents_available? record = RailsConsoleAi::Agent.where('LOWER(name) = ?', name.to_s.downcase).first record&.to_hash rescue => e warn_failure(:find_agent_by_name, e) nil end |
.find_memory_by_name(name) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 103 def find_memory_by_name(name) return nil unless memories_available? record = RailsConsoleAi::Memory.where('LOWER(name) = ?', name.to_s.downcase).first record&.to_hash rescue => e warn_failure(:find_memory_by_name, e) nil end |
.find_skill_by_name(name) ⇒ Object
57 58 59 60 61 62 63 64 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 57 def find_skill_by_name(name) return nil unless available? record = RailsConsoleAi::Skill.where('LOWER(name) = ?', name.to_s.downcase).first record&.to_hash rescue => e warn_failure(:find_skill_by_name, e) nil end |
.memories_available? ⇒ Boolean
16 17 18 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 16 def memories_available? table_exists?('rails_console_ai_memories') end |
.save_agent(name:, description:, body:, max_rounds: nil, model: nil, tools: [], edited_by: nil, change_note: nil) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 156 def save_agent(name:, description:, body:, max_rounds: nil, model: nil, tools: [], edited_by: nil, change_note: nil) ensure_tables!(:agents) record = RailsConsoleAi::Agent.where('LOWER(name) = ?', name.to_s.downcase).first record ||= RailsConsoleAi::Agent.new was_new = record.new_record? record.update_with_version!( { name: name, description: description, body: body, max_rounds: max_rounds, model: model, tools: Array(tools) }, edited_by: edited_by, change_note: change_note ) [record, was_new] end |
.save_memory(name:, description:, tags: [], edited_by: nil, change_note: nil) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 112 def save_memory(name:, description:, tags: [], edited_by: nil, change_note: nil) ensure_tables!(:memories) record = RailsConsoleAi::Memory.where('LOWER(name) = ?', name.to_s.downcase).first record ||= RailsConsoleAi::Memory.new was_new = record.new_record? record.update_with_version!( { name: name, description: description, tags: Array() }, edited_by: edited_by, change_note: change_note ) [record, was_new] end |
.save_skill(name:, description:, body:, tags: [], bypass_guards_for_methods: [], edited_by: nil, change_note: nil) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 66 def save_skill(name:, description:, body:, tags: [], bypass_guards_for_methods: [], edited_by: nil, change_note: nil) ensure_tables!(:skills) record = RailsConsoleAi::Skill.where('LOWER(name) = ?', name.to_s.downcase).first record ||= RailsConsoleAi::Skill.new was_new = record.new_record? record.update_with_version!( { name: name, description: description, body: body, tags: Array(), bypass_guards_for_methods: Array(bypass_guards_for_methods) }, edited_by: edited_by, change_note: change_note ) [record, was_new] end |
.table_exists?(table_name) ⇒ Boolean
Ask the connection directly so we don’t depend on the AR model being autoloaded yet. In a Rails console, the models in app/models are autoloaded lazily — the constant is ‘defined?`-false until first reference. Going through the connection avoids that timing trap.
28 29 30 31 32 33 34 35 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 28 def table_exists?(table_name) return false unless defined?(::ActiveRecord) conn = active_record_connection return false unless conn conn.table_exists?(table_name) rescue ::ActiveRecord::ActiveRecordError, ::ActiveRecord::NoDatabaseError, NoMethodError false end |
.warn_failure(method, error) ⇒ Object
195 196 197 198 |
# File 'lib/rails_console_ai/storage/database_storage.rb', line 195 def warn_failure(method, error) return unless defined?(RailsConsoleAi.logger) && RailsConsoleAi.logger RailsConsoleAi.logger.warn("RailsConsoleAi::Storage::DatabaseStorage##{method} failed: #{error.class}: #{error.}") end |