Class: RailsConsoleAi::Tools::MemoryTools

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_console_ai/tools/memory_tools.rb

Constant Summary collapse

MEMORIES_DIR =
'memories'

Instance Method Summary collapse

Constructor Details

#initialize(storage = nil) ⇒ MemoryTools

Returns a new instance of MemoryTools.



8
9
10
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 8

def initialize(storage = nil)
  @storage = storage || RailsConsoleAi.storage
end

Instance Method Details

#delete_memory(name:) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 37

def delete_memory(name:)
  key = memory_key(name)
  unless @storage.exists?(key)
    # Try to find by name match across all memory files
    found_key = find_memory_key_by_name(name)
    return "No memory found: \"#{name}\"" unless found_key
    key = found_key
  end

  memory = load_memory(key)
  @storage.delete(key)
  "Memory deleted: \"#{memory ? memory['name'] : name}\""
rescue Storage::StorageError => e
  "FAILED to delete memory (#{e.message})."
end

#memory_summariesObject



98
99
100
101
102
103
104
105
106
107
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 98

def memory_summaries
  memories = load_all_memories
  return nil if memories.empty?

  memories.map { |m|
    tags = Array(m['tags'])
    tag_str = tags.empty? ? '' : " [#{tags.join(', ')}]"
    "- #{m['name']}#{tag_str}"
  }
end

#recall_memories(query: nil, tag: nil) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 67

def recall_memories(query: nil, tag: nil)
  memories = load_all_memories
  return "No memories stored yet." if memories.empty?

  results = memories
  if tag && !tag.empty?
    results = results.select { |m|
      Array(m['tags']).any? { |t| t.downcase.include?(tag.downcase) }
    }
  end
  if query && !query.empty?
    words = query.downcase.split(/\s+/)
    results = results.select { |m|
      searchable = [
        m['name'].to_s.downcase,
        m['description'].to_s.downcase,
        Array(m['tags']).map(&:downcase).join(' ')
      ].join(' ')
      words.all? { |w| searchable.include?(w) }
    }
  end

  return "No memories matching your search." if results.empty?

  results.map { |m|
    line = "**#{m['name']}**\n#{m['description']}"
    line += "\nTags: #{m['tags'].join(', ')}" if m['tags'] && !m['tags'].empty?
    line
  }.join("\n\n---\n\n")
end

#recall_memory(name:) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 53

def recall_memory(name:)
  key = memory_key(name)
  memory = load_memory(key)
  # Fall back to case-insensitive name search
  unless memory
    memory = load_all_memories.find { |m| m['name'].to_s.downcase == name.downcase }
  end
  return "No memory found: \"#{name}\"" unless memory

  line = "**#{memory['name']}**\n#{memory['description']}"
  line += "\nTags: #{memory['tags'].join(', ')}" if memory['tags'] && !memory['tags'].empty?
  line
end

#save_memory(name:, description:, tags: []) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rails_console_ai/tools/memory_tools.rb', line 12

def save_memory(name:, description:, tags: [])
  key = memory_key(name)
  existing = load_memory(key)

  frontmatter = {
    'name' => name,
    'tags' => Array(tags).empty? && existing ? (existing['tags'] || []) : Array(tags),
    'created_at' => existing ? existing['created_at'] : Time.now.utc.iso8601
  }
  frontmatter['updated_at'] = Time.now.utc.iso8601 if existing

  content = "---\n#{YAML.dump(frontmatter).sub("---\n", '').strip}\n---\n\n#{description}\n"
  @storage.write(key, content)

  path = @storage.respond_to?(:root_path) ? File.join(@storage.root_path, key) : key
  if existing
    "Memory updated: \"#{name}\" (#{path})"
  else
    "Memory saved: \"#{name}\" (#{path})"
  end
rescue Storage::StorageError => e
  "FAILED to save (#{e.message}). Add this manually to .rails_console_ai/#{key}:\n" \
  "---\nname: #{name}\ntags: #{Array(tags).inspect}\n---\n\n#{description}"
end