Class: KairosMcp::Storage::FileBackend

Inherits:
Backend
  • Object
show all
Defined in:
lib/kairos_mcp/storage/file_backend.rb

Overview

File-based storage backend (default)

This is the default storage backend for KairosChain, suitable for individual use. Data is stored in JSON/JSONL files.

Storage locations:

  • Blockchain: storage/blockchain.json

  • Action logs: skills/action_log.jsonl

  • Knowledge metadata: extracted from *.md files (no separate storage)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Backend

create, default, load_config, register, unregister

Constructor Details

#initialize(config = {}) ⇒ FileBackend

Returns a new instance of FileBackend.



22
23
24
25
26
27
28
29
# File 'lib/kairos_mcp/storage/file_backend.rb', line 22

def initialize(config = {})
  @storage_dir = config[:storage_dir] || KairosMcp.storage_dir
  @blockchain_file = config[:blockchain_file] || KairosMcp.blockchain_path
  @action_log_file = config[:action_log_file] || KairosMcp.action_log_path

  FileUtils.mkdir_p(@storage_dir)
  FileUtils.mkdir_p(File.dirname(@action_log_file))
end

Instance Attribute Details

#action_log_fileObject (readonly)

Get the blockchain file path (for compatibility)



147
148
149
# File 'lib/kairos_mcp/storage/file_backend.rb', line 147

def action_log_file
  @action_log_file
end

#blockchain_fileObject (readonly)

Get the blockchain file path (for compatibility)



147
148
149
# File 'lib/kairos_mcp/storage/file_backend.rb', line 147

def blockchain_file
  @blockchain_file
end

#storage_dirObject (readonly)

Get the blockchain file path (for compatibility)



147
148
149
# File 'lib/kairos_mcp/storage/file_backend.rb', line 147

def storage_dir
  @storage_dir
end

Instance Method Details

#action_history(limit: 50) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/kairos_mcp/storage/file_backend.rb', line 86

def action_history(limit: 50)
  return [] unless File.exist?(@action_log_file)

  File.readlines(@action_log_file)
      .last(limit)
      .filter_map { |line| JSON.parse(line, symbolize_names: true) rescue nil }
end

#all_blocksObject



62
63
64
# File 'lib/kairos_mcp/storage/file_backend.rb', line 62

def all_blocks
  load_blocks || []
end

#backend_typeObject



142
143
144
# File 'lib/kairos_mcp/storage/file_backend.rb', line 142

def backend_type
  :file
end

#clear_action_log!Object



94
95
96
97
98
99
100
# File 'lib/kairos_mcp/storage/file_backend.rb', line 94

def clear_action_log!
  File.write(@action_log_file, '')
  true
rescue StandardError => e
  warn "[FileBackend] Failed to clear action log: #{e.message}"
  false
end

#delete_knowledge_meta(_name) ⇒ Object



124
125
126
127
# File 'lib/kairos_mcp/storage/file_backend.rb', line 124

def delete_knowledge_meta(_name)
  # No-op for file backend
  true
end

#get_knowledge_meta(_name) ⇒ Object



114
115
116
117
# File 'lib/kairos_mcp/storage/file_backend.rb', line 114

def get_knowledge_meta(_name)
  # No separate metadata storage - return nil
  nil
end

#list_knowledge_metaObject



119
120
121
122
# File 'lib/kairos_mcp/storage/file_backend.rb', line 119

def list_knowledge_meta
  # No separate metadata storage - return empty array
  []
end

#load_blocksObject

Block Operations



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/kairos_mcp/storage/file_backend.rb', line 35

def load_blocks
  return nil unless File.exist?(@blockchain_file)

  json_data = JSON.parse(File.read(@blockchain_file), symbolize_names: true)
  json_data.map do |block_data|
    normalize_block_data(block_data)
  end
rescue JSON::ParserError, ArgumentError => e
  warn "[FileBackend] Failed to load blocks: #{e.message}"
  nil
end

#ready?Boolean

Utility Methods

Returns:

  • (Boolean)


138
139
140
# File 'lib/kairos_mcp/storage/file_backend.rb', line 138

def ready?
  true
end

#record_action(entry) ⇒ Object

Action Log Operations



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/kairos_mcp/storage/file_backend.rb', line 70

def record_action(entry)
  normalized = {
    timestamp: entry[:timestamp] || Time.now.iso8601,
    action: entry[:action],
    skill_id: entry[:skill_id],
    details: entry[:details]
  }

  FileUtils.mkdir_p(File.dirname(@action_log_file))
  File.open(@action_log_file, 'a') { |f| f.puts(normalized.to_json) }
  true
rescue StandardError => e
  warn "[FileBackend] Failed to record action: #{e.message}"
  false
end

#save_all_blocks(blocks) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/kairos_mcp/storage/file_backend.rb', line 53

def save_all_blocks(blocks)
  FileUtils.mkdir_p(File.dirname(@blockchain_file))
  File.write(@blockchain_file, JSON.pretty_generate(blocks.map { |b| block_to_hash(b) }))
  true
rescue StandardError => e
  warn "[FileBackend] Failed to save blocks: #{e.message}"
  false
end

#save_block(block) ⇒ Object



47
48
49
50
51
# File 'lib/kairos_mcp/storage/file_backend.rb', line 47

def save_block(block)
  blocks = load_blocks || []
  blocks << block_to_hash(block)
  save_all_blocks(blocks)
end

#save_knowledge_meta(_name, _meta) ⇒ Object

Knowledge Meta Operations

For FileBackend, metadata is not stored separately. These methods are no-ops or return empty results. The actual metadata is extracted from *.md files by KnowledgeProvider.



109
110
111
112
# File 'lib/kairos_mcp/storage/file_backend.rb', line 109

def save_knowledge_meta(_name, _meta)
  # No-op for file backend - metadata is in the files
  true
end

#update_knowledge_archived(_name, _archived, reason: nil) ⇒ Object



129
130
131
132
# File 'lib/kairos_mcp/storage/file_backend.rb', line 129

def update_knowledge_archived(_name, _archived, reason: nil)
  # No-op for file backend - archiving is folder-based
  true
end