Class: Llmemory::LongTerm::FileBased::Storages::FileStorage

Inherits:
Base
  • Object
show all
Defined in:
lib/llmemory/long_term/file_based/storages/file_storage.rb

Instance Method Summary collapse

Methods inherited from Base

#get_items_around, #get_resources_around

Constructor Details

#initialize(base_path: nil) ⇒ FileStorage

Returns a new instance of FileStorage.



12
13
14
15
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 12

def initialize(base_path: nil)
  @base_path = base_path || Llmemory.configuration.long_term_storage_path || "./llmemory_data"
  @base_path = File.expand_path(@base_path)
end

Instance Method Details

#archive_items(user_id, item_ids) ⇒ Object



121
122
123
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 121

def archive_items(user_id, item_ids)
  item_ids.each { |id| File.delete(item_path(user_id, id)) if File.file?(item_path(user_id, id)) }
end

#archive_resources(user_id, resource_ids) ⇒ Object



125
126
127
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 125

def archive_resources(user_id, resource_ids)
  resource_ids.each { |id| File.delete(resource_path(user_id, id)) if File.file?(resource_path(user_id, id)) }
end

#count_items(user_id:) ⇒ Object



169
170
171
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 169

def count_items(user_id:)
  get_all_items(user_id).size
end

#get_all_items(user_id) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 84

def get_all_items(user_id)
  dir = user_path(user_id, "items")
  return [] unless Dir.exist?(dir)
  Dir.children(dir).select { |f| f.end_with?(".json") }.map do |f|
    data = JSON.parse(File.read(File.join(dir, f)), symbolize_names: true)
    data[:created_at] = parse_time(data[:created_at])
    data
  end.sort_by { |i| i[:created_at] }
end

#get_all_resources(user_id) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 94

def get_all_resources(user_id)
  dir = user_path(user_id, "resources")
  return [] unless Dir.exist?(dir)
  Dir.children(dir).select { |f| f.end_with?(".json") }.map do |f|
    data = JSON.parse(File.read(File.join(dir, f)), symbolize_names: true)
    id = File.basename(f, ".json")
    data[:id] = id
    data[:created_at] = parse_time(data[:created_at])
    data
  end.sort_by { |r| r[:created_at] }
end

#get_items_older_than(user_id, days:) ⇒ Object



79
80
81
82
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 79

def get_items_older_than(user_id, days:)
  cutoff = Time.now - (days * 86400)
  get_all_items(user_id).select { |i| parse_time(i[:created_at] || i["created_at"]) < cutoff }
end

#get_items_since(user_id, hours:) ⇒ Object



106
107
108
109
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 106

def get_items_since(user_id, hours:)
  cutoff = Time.now - (hours * 3600)
  get_all_items(user_id).select { |i| parse_time(i[:created_at]) >= cutoff }
end

#get_resources_since(user_id, hours:) ⇒ Object



74
75
76
77
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 74

def get_resources_since(user_id, hours:)
  cutoff = Time.now - (hours * 3600)
  get_all_resources(user_id).select { |r| parse_time(r[:created_at] || r["created_at"]) >= cutoff }
end

#list_categories(user_id) ⇒ Object



58
59
60
61
62
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 58

def list_categories(user_id)
  dir = user_path(user_id, "categories")
  return [] unless Dir.exist?(dir)
  Dir.children(dir).select { |f| f.end_with?(".md") }.map { |f| File.basename(f, ".md") }
end

#list_items(user_id:, category: nil, limit: nil) ⇒ Object



162
163
164
165
166
167
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 162

def list_items(user_id:, category: nil, limit: nil)
  list = get_all_items(user_id)
  list = list.select { |i| (i[:category] || i["category"]).to_s == category.to_s } if category
  list = list.take(limit) if limit
  list
end

#list_resources(user_id:, limit: nil) ⇒ Object



157
158
159
160
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 157

def list_resources(user_id:, limit: nil)
  list = get_all_resources(user_id)
  limit ? list.take(limit) : list
end

#list_usersObject



152
153
154
155
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 152

def list_users
  return [] unless Dir.exist?(@base_path)
  Dir.children(@base_path).select { |e| File.directory?(File.join(@base_path, e)) && !e.start_with?(".") }
end

#load_category(user_id, category_name) ⇒ Object



45
46
47
48
49
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 45

def load_category(user_id, category_name)
  path = category_path(user_id, category_name)
  return "" unless File.file?(path)
  File.read(path)
end

#load_daily_logs(user_id, from_date:, to_date:) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 138

def load_daily_logs(user_id, from_date:, to_date:)
  from_date = Date.parse(from_date.to_s) if from_date.is_a?(String)
  to_date = Date.parse(to_date.to_s) if to_date.is_a?(String)
  dir = user_path(user_id, "memory")
  return [] unless Dir.exist?(dir)

  (from_date..to_date).filter_map do |d|
    path = daily_log_path(user_id, d)
    next unless File.file?(path)

    { date: d, content: File.read(path) }
  end
end

#replace_items(user_id, ids_to_remove, merged_item) ⇒ Object



111
112
113
114
115
116
117
118
119
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 111

def replace_items(user_id, ids_to_remove, merged_item)
  ids_to_remove.each { |id| File.delete(item_path(user_id, id)) if File.file?(item_path(user_id, id)) }
  merged_item = merged_item.merge(created_at: Time.now) unless merged_item.key?(:created_at)
  seq = next_seq(user_id, "item_id_seq")
  id = "item_#{seq}"
  path = item_path(user_id, id)
  data = merged_item.merge(id: id).transform_values { |v| v.respond_to?(:iso8601) ? v.iso8601 : v }
  File.write(path, JSON.generate(data))
end

#save_category(user_id, category_name, content) ⇒ Object



51
52
53
54
55
56
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 51

def save_category(user_id, category_name, content)
  ensure_user_dir(user_id, "categories")
  path = category_path(user_id, category_name)
  File.write(path, content)
  true
end

#save_daily_log_entry(user_id, date, content) ⇒ Object



129
130
131
132
133
134
135
136
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 129

def save_daily_log_entry(user_id, date, content)
  ensure_user_dir(user_id, "memory")
  path = daily_log_path(user_id, date)
  existing = File.file?(path) ? File.read(path) : ""
  entry = "#{Time.now.strftime('%H:%M')} #{content}\n"
  File.write(path, existing + entry)
  true
end

#save_item(user_id, category:, content:, source_resource_id:, importance: 0.7, provenance: nil) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 27

def save_item(user_id, category:, content:, source_resource_id:, importance: 0.7, provenance: nil)
  ensure_user_dir(user_id)
  seq = next_seq(user_id, "item_id_seq")
  id = "item_#{seq}"
  path = item_path(user_id, id)
  data = {
    id: id,
    category: category,
    content: content,
    source_resource_id: source_resource_id,
    importance: importance,
    provenance: provenance,
    created_at: Time.now.iso8601
  }
  File.write(path, JSON.generate(data))
  id
end

#save_resource(user_id, text) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 17

def save_resource(user_id, text)
  ensure_user_dir(user_id)
  seq = next_seq(user_id, "resource_id_seq")
  id = "res_#{seq}"
  path = resource_path(user_id, id)
  data = { text: text, created_at: Time.now.iso8601 }
  File.write(path, JSON.generate(data))
  id
end

#search_items(user_id, query) ⇒ Object



64
65
66
67
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 64

def search_items(user_id, query)
  query_lower = query.downcase
  get_all_items(user_id).select { |i| (i[:content] || i["content"]).to_s.downcase.include?(query_lower) }
end

#search_resources(user_id, query) ⇒ Object



69
70
71
72
# File 'lib/llmemory/long_term/file_based/storages/file_storage.rb', line 69

def search_resources(user_id, query)
  query_lower = query.downcase
  get_all_resources(user_id).select { |r| (r[:text] || r["text"]).to_s.downcase.include?(query_lower) }
end