Class: AIHype::Memory
- Inherits:
-
Object
- Object
- AIHype::Memory
- Defined in:
- lib/aihype/memory.rb
Constant Summary collapse
- SEMVER_REGEX =
/^\d+\.\d+\.\d+$/
Class Method Summary collapse
- .create_default ⇒ Object
- .extract_list_items(section) ⇒ Object
- .extract_rules(markdown_content) ⇒ Object
- .load(file_path) ⇒ Object
- .parse(content) ⇒ Object
- .parse_datetime(value) ⇒ Object
- .save(file_path, memory_file) ⇒ Object
- .validate_frontmatter!(frontmatter) ⇒ Object
- .validate_rules!(rules) ⇒ Object
Class Method Details
.create_default ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/aihype/memory.rb', line 43 def self.create_default now = Time.now.utc safety_rules = Defaults::SAFETY_RULES.map { |rule| "- #{rule}" }.join("\n") <<~MARKDOWN --- version: #{Defaults::DEFAULT_VERSION} created: #{now.iso8601} updated: #{now.iso8601} --- # AIHype Blacklist Rules ## Default Safety Rules #{safety_rules} ## User Rules - #{Defaults::USER_RULES_PLACEHOLDER} MARKDOWN end |
.extract_list_items(section) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/aihype/memory.rb', line 105 def self.extract_list_items(section) return [] unless section items = section.split("\n").select { |line| line.strip.start_with?('-') }.map do |line| line.sub(/^-\s*/, '').strip end # Validate items before filtering placeholders items.each do |item| # Skip placeholder validation next if item == Defaults::USER_RULES_PLACEHOLDER raise InvalidMemoryFileError, 'Rule cannot be empty' if item.strip.empty? end # Filter out empty items and placeholders items.reject { |item| item.empty? || item == Defaults::USER_RULES_PLACEHOLDER } end |
.extract_rules(markdown_content) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/aihype/memory.rb', line 87 def self.extract_rules(markdown_content) raise InvalidMemoryFileError, 'Missing "Default Safety Rules" section' unless markdown_content.include?('## Default Safety Rules') sections = markdown_content.split(/^## /) default_section = sections.find { |s| s.start_with?('Default Safety Rules') } user_section = sections.find { |s| s.start_with?('User Rules') } default_rules = extract_list_items(default_section) user_rules = extract_list_items(user_section) validate_rules!(default_rules + user_rules) min_rules = Defaults::MIN_SAFETY_RULES raise InvalidMemoryFileError, "Default Safety Rules must contain at least #{min_rules} rules" if default_rules.length < min_rules [default_rules, user_rules] end |
.load(file_path) ⇒ Object
15 16 17 18 19 20 |
# File 'lib/aihype/memory.rb', line 15 def self.load(file_path) content = File.read(file_path) parse(content) rescue Errno::ENOENT nil end |
.parse(content) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/aihype/memory.rb', line 22 def self.parse(content) parts = content.split(/^---$/) raise InvalidMemoryFileError, 'Missing YAML frontmatter' if parts.length < 3 yaml_content = parts[1].strip markdown_content = parts[2..].join('---').strip frontmatter = YAML.safe_load(yaml_content, permitted_classes: [Time]) validate_frontmatter!(frontmatter) default_rules, user_rules = extract_rules(markdown_content) MemoryFile.new( version: frontmatter['version'], created: parse_datetime(frontmatter['created']), updated: parse_datetime(frontmatter['updated']), default_rules: default_rules, user_rules: user_rules ) end |
.parse_datetime(value) ⇒ Object
82 83 84 85 |
# File 'lib/aihype/memory.rb', line 82 def self.parse_datetime(value) return value if value.is_a?(Time) Time.parse(value) end |
.save(file_path, memory_file) ⇒ Object
64 65 66 67 |
# File 'lib/aihype/memory.rb', line 64 def self.save(file_path, memory_file) FileUtils.mkdir_p(File.dirname(file_path)) File.write(file_path, memory_file.to_markdown) end |
.validate_frontmatter!(frontmatter) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/aihype/memory.rb', line 69 def self.validate_frontmatter!(frontmatter) raise InvalidMemoryFileError, 'Missing version field' unless frontmatter['version'] version = frontmatter['version'].to_s raise InvalidMemoryFileError, 'Invalid semver version' unless version =~ SEMVER_REGEX # Parse or validate datetime fields (they might already be Time objects from YAML) parse_datetime(frontmatter['created']) parse_datetime(frontmatter['updated']) rescue ArgumentError => e raise InvalidMemoryFileError, "Invalid datetime: #{e.}" end |
.validate_rules!(rules) ⇒ Object
124 125 126 127 128 129 |
# File 'lib/aihype/memory.rb', line 124 def self.validate_rules!(rules) rules.each do |rule| raise InvalidMemoryFileError, 'Rule cannot be empty' if rule.strip.empty? raise InvalidMemoryFileError, 'Rule exceeds 500 characters' if rule.length > 500 end end |