Class: OllamaChat::Database::Models::AppState
- Inherits:
-
Object
- Object
- OllamaChat::Database::Models::AppState
- Defined in:
- lib/ollama_chat/database/models/app_state.rb
Overview
Represents a key/value pair of persistent application state stored in the database.
This model provides a generic, JSON-backed store for small bits of runtime state that need to survive across sessions—such as the XOR-SHA256 fingerprint of the shipped default prompts used for boot drift detection.
Class Method Summary collapse
-
.acknowledge(chat) ⇒ Object
Acknowledges the current shipped-prompt state, suppressing the boot drift notification.
-
.compute_hashes(prompts_config) ⇒ Hash{String => String}
Builds a per-prompt SHA256 hash map from a prompts config object.
-
.fingerprint_from(hashes) ⇒ String
Computes an XOR fingerprint from a hash map.
-
.get(key) ⇒ Hash?
Retrieves the JSON payload stored under the given key.
-
.seed(chat) ⇒ Object
Computes per-prompt SHA256 hashes and an XOR fingerprint of all shipped default prompts.
-
.set(key, value) ⇒ OllamaChat::Database::Models::AppState
Creates or updates the JSON payload stored under the given key.
-
.store_fingerprint(fingerprint, hashes) ⇒ Object
Stores the fingerprint and hash map under the standard state key.
Instance Method Summary collapse
-
#validate ⇒ Object
Validates the application state entry.
Class Method Details
.acknowledge(chat) ⇒ Object
Acknowledges the current shipped-prompt state, suppressing the boot
drift notification. Called after /prompt sync so the user is not
nagged again on the next launch.
102 103 104 105 106 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 102 def self.acknowledge(chat) hashes = compute_hashes(chat.config.prompts) fingerprint = fingerprint_from(hashes) store_fingerprint(fingerprint, hashes) end |
.compute_hashes(prompts_config) ⇒ Hash{String => String}
Builds a per-prompt SHA256 hash map from a prompts config object.
129 130 131 132 133 134 135 136 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 129 def self.compute_hashes(prompts_config) prompts_config.to_h.each_with_object({}) do |(context, prompts), hashes| prompts.each do |name, content| hashes["#{context}/#{name}"] = Digest::SHA256.hexdigest(content.to_s) end end end |
.fingerprint_from(hashes) ⇒ String
Computes an XOR fingerprint from a hash map.
142 143 144 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 142 def self.fingerprint_from(hashes) hashes.values.reduce(0) { |sum, hex| sum ^ hex.to_i(16) }.to_s(16) end |
.get(key) ⇒ Hash?
Retrieves the JSON payload stored under the given key.
29 30 31 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 29 def self.get(key) where(key: key.to_s).first&.value end |
.seed(chat) ⇒ Object
Computes per-prompt SHA256 hashes and an XOR fingerprint of all shipped default prompts.
At boot, if the stored fingerprint differs from the current one, a detail report (modified / added / removed) is printed to STDERR and the user is prompted to accept the new fingerprint. If declined, the old fingerprint is retained and the notice will reappear on the next boot.
This method is invoked automatically by the model seeding loop in
OllamaChat::Database.setup_models.
60 61 62 63 64 65 66 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 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 60 def self.seed(chat) stored = get(:prompt_defaults_fingerprint) stored_fingerprint = stored&.dig('fingerprint') hashes = compute_hashes(chat.config.prompts) fingerprint = fingerprint_from(hashes) return true if fingerprint == stored_fingerprint if stored&.dig('hashes') old = stored['hashes'] added = hashes.keys - old.keys removed = old.keys - hashes.keys changed = hashes.select { |k, v| old[k] && old[k] != v }.keys STDERR.puts "⚠️ Shipped prompts changed since last boot:" changed.each { |k| STDERR.puts " ~ #{k} (modified)" } added.each { |k| STDERR.puts " + #{k} (new)" } removed.each { |k| STDERR.puts " - #{k} (removed)" } elsif !OllamaChat.test_mode? STDERR.puts '⚠️ First run — storing prompt fingerprints.' store_fingerprint(fingerprint, hashes) return true end prompt = <<~EOT.chomp << ' ' Keep local prompts (stop nagging)? Consider adopting via /prompt sync or just ignore? (y/n) %s EOT if OllamaChat.test_mode? || chat.confirm?(prompt:, yes: /\Ay/i, timeout: 5) store_fingerprint(fingerprint, hashes) end true end |
.set(key, value) ⇒ OllamaChat::Database::Models::AppState
Creates or updates the JSON payload stored under the given key.
38 39 40 41 42 43 44 45 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 38 def self.set(key, value) if found = where(key: key.to_s).first found.update(value:) found else create(key: key.to_s, value:) end end |
.store_fingerprint(fingerprint, hashes) ⇒ Object
Stores the fingerprint and hash map under the standard state key.
150 151 152 153 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 150 def self.store_fingerprint(fingerprint, hashes) set(:prompt_defaults_fingerprint, { fingerprint:, hashes:, computed_at: Time.now.iso8601 }) end |
Instance Method Details
#validate ⇒ Object
Validates the application state entry.
Ensures that the key is present and unique.
18 19 20 21 22 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 18 def validate super validates_presence :key validates_unique :key end |