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.
103 104 105 106 107 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 103 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.
130 131 132 133 134 135 136 137 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 130 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.
143 144 145 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 143 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 96 |
# 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 "\u26A0\uFE0F 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 "\u26A0\uFE0F First run — storing prompt fingerprints." store_fingerprint(fingerprint, hashes) return true end c = Term::ANSIColor prompt = <<~EOT.chomp << ' ' #{c.bold{'Tip'}}: /prompt sync adopts shipped defaults into local config. Seen these changes? (y = stop nagging, n = ask again next boot) %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.
151 152 153 154 |
# File 'lib/ollama_chat/database/models/app_state.rb', line 151 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 |