Class: SkillBench::Services::ResponseCache
- Inherits:
-
Object
- Object
- SkillBench::Services::ResponseCache
- Defined in:
- lib/skill_bench/services/response_cache.rb
Overview
Content-addressed, in-memory cache for LLM responses.
The cache is opt-in and disabled by default. When enabled it lets repeated,
identical LLM requests reuse a previously computed response instead of
hitting the network again. The canonical example is compare, which runs
the skill-less baseline twice with identical inputs.
The backing store is a process-lifetime Hash keyed by a stable SHA-256 digest of the request, so the same logical request always maps to the same entry regardless of hash-key ordering. Access to the store is serialized with a mutex so concurrent callers (e.g. Parallel-driven agents) cannot corrupt it or double-store a key.
Constant Summary collapse
- ENV_FLAG =
Environment variable that opts caching on when set to a truthy value.
'SKILL_BENCH_CACHE'- TRUTHY_VALUES =
Raw env values treated as "on".
%w[1 true yes on].freeze
- MUTEX =
Guards every read/write of the shared store. Concurrent agents/judges run on separate threads; without this, the membership check and the write in fetch could interleave and store a key more than once.
Mutex.new
Class Method Summary collapse
-
.clear ⇒ void
Removes every cached entry.
-
.enabled? ⇒ Boolean
Whether response caching is currently enabled.
-
.fetch(key) { ... } ⇒ Object
Returns the cached value for a key, computing and storing it on a miss.
-
.key(provider:, model:, system_prompt:, messages:, tools: nil, temperature: nil, provider_config: {}) ⇒ String
Computes a stable content-addressed cache key for a request.
Class Method Details
.clear ⇒ void
This method returns an undefined value.
Removes every cached entry.
95 96 97 |
# File 'lib/skill_bench/services/response_cache.rb', line 95 def clear MUTEX.synchronize { store.clear } end |
.enabled? ⇒ Boolean
Whether response caching is currently enabled.
Enabled when ENV_FLAG is set to a truthy value (one of TRUTHY_VALUES); disabled when unset or set to anything else.
39 40 41 42 |
# File 'lib/skill_bench/services/response_cache.rb', line 39 def enabled? raw = ENV.fetch(ENV_FLAG, '').to_s.strip.downcase TRUTHY_VALUES.include?(raw) end |
.fetch(key) { ... } ⇒ Object
Returns the cached value for a key, computing and storing it on a miss.
The value is computed outside the lock so requests for distinct keys run concurrently; the store read and the store write are each serialized by MUTEX, and a missing key is written exactly once (first writer wins).
84 85 86 87 88 89 90 |
# File 'lib/skill_bench/services/response_cache.rb', line 84 def fetch(key) hit = MUTEX.synchronize { store[key] } return hit unless hit.nil? value = yield MUTEX.synchronize { store[key] ||= value } end |
.key(provider:, model:, system_prompt:, messages:, tools: nil, temperature: nil, provider_config: {}) ⇒ String
Computes a stable content-addressed cache key for a request.
The inputs are assembled into a canonical structure (hash keys sorted and stringified recursively) and hashed, so semantically identical requests always produce the same digest. Request-affecting provider configuration (endpoint/base URL/etc.) is included so two providers that share a name but target different endpoints never collide.
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/skill_bench/services/response_cache.rb', line 61 def key(provider:, model:, system_prompt:, messages:, tools: nil, temperature: nil, provider_config: {}) payload = { provider: provider.to_s, model: model, system_prompt: system_prompt, messages: , tools: tools, temperature: temperature, provider_config: provider_config } Digest::SHA256.hexdigest(JSON.generate(canonicalize(payload))) end |