Class: SemanticCache::Cache
- Inherits:
-
Object
- Object
- SemanticCache::Cache
- Defined in:
- lib/semantic_cache/cache.rb
Instance Attribute Summary collapse
-
#stats ⇒ Object
readonly
Returns the value of attribute stats.
Instance Method Summary collapse
-
#clear ⇒ Object
Clear all cached entries.
-
#current_stats ⇒ Object
Return current cache statistics as a Hash.
-
#detailed_stats ⇒ Object
Return a formatted stats report string.
-
#fetch(query, ttl: nil, tags: [], model: nil, metadata: {}, &block) ⇒ Object
Fetch a cached response or execute the block and cache the result.
- #fetch_anthropic(query, model: "claude-sonnet-4-20250514", **options, &block) ⇒ Object
- #fetch_gemini(query, model: "gemini-pro", **options, &block) ⇒ Object
-
#fetch_openai(query, model: "gpt-4o", **options, &block) ⇒ Object
Convenience methods for specific providers.
-
#initialize(similarity_threshold: nil, embedding_model: nil, store: nil, store_options: {}, default_ttl: nil, namespace: nil, track_costs: nil, max_size: nil) ⇒ Cache
constructor
A new instance of Cache.
-
#invalidate(tags:) ⇒ Object
Invalidate cached entries by tags.
-
#savings_report ⇒ Object
Savings report string.
-
#size ⇒ Object
Number of entries currently in the cache.
Constructor Details
#initialize(similarity_threshold: nil, embedding_model: nil, store: nil, store_options: {}, default_ttl: nil, namespace: nil, track_costs: nil, max_size: nil) ⇒ Cache
Returns a new instance of Cache.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/semantic_cache/cache.rb', line 9 def initialize( similarity_threshold: nil, embedding_model: nil, store: nil, store_options: {}, default_ttl: nil, namespace: nil, track_costs: nil, max_size: nil ) config = SemanticCache.configuration @threshold = similarity_threshold || config.similarity_threshold @default_ttl = default_ttl || config.default_ttl @track_costs = track_costs.nil? ? config.track_costs : track_costs @namespace = namespace || config.namespace @max_size = max_size || config.max_cache_size @embedding = Embedding.new( model: || config., api_key: config.openai_api_key ) @store = build_store(store || config.store, .empty? ? config. : ) @stats = Stats.new end |
Instance Attribute Details
#stats ⇒ Object (readonly)
Returns the value of attribute stats.
7 8 9 |
# File 'lib/semantic_cache/cache.rb', line 7 def stats @stats end |
Instance Method Details
#clear ⇒ Object
Clear all cached entries.
111 112 113 114 |
# File 'lib/semantic_cache/cache.rb', line 111 def clear @store.clear @stats.reset! end |
#current_stats ⇒ Object
Return current cache statistics as a Hash.
117 118 119 |
# File 'lib/semantic_cache/cache.rb', line 117 def current_stats @stats.to_h end |
#detailed_stats ⇒ Object
Return a formatted stats report string.
122 123 124 |
# File 'lib/semantic_cache/cache.rb', line 122 def detailed_stats @stats.report end |
#fetch(query, ttl: nil, tags: [], model: nil, metadata: {}, &block) ⇒ Object
Fetch a cached response or execute the block and cache the result.
cache.fetch("What is Ruby?") do
openai.chat(messages: [{ role: "user", content: "What is Ruby?" }])
end
Options:
ttl: - Time-to-live in seconds (overrides default)
tags: - Array of tags for grouped invalidation
model: - Model name for cost tracking
46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 |
# File 'lib/semantic_cache/cache.rb', line 46 def fetch(query, ttl: nil, tags: [], model: nil, metadata: {}, &block) raise ArgumentError, "A block is required" unless block_given? validate_query!(query) start_time = Time.now # Generate embedding for the query = @embedding.generate(query) # Search for a semantically similar cached entry match = find_similar() if match elapsed = ((Time.now - start_time) * 1000).round(2) saved_cost = estimate_cost(model) @stats.record_hit(saved_cost: saved_cost, response_time: elapsed) return match.response end # Cache miss — execute the block response = block.call elapsed = ((Time.now - start_time) * 1000).round(2) @stats.record_miss(response_time: elapsed) # Store the new entry entry = Entry.new( query: query, embedding: , response: response, model: model, tags: Array(), ttl: ttl || @default_ttl, metadata: ) key = generate_key(query) @store.write(key, entry) response end |
#fetch_anthropic(query, model: "claude-sonnet-4-20250514", **options, &block) ⇒ Object
94 95 96 |
# File 'lib/semantic_cache/cache.rb', line 94 def fetch_anthropic(query, model: "claude-sonnet-4-20250514", **, &block) fetch(query, model: model, **, &block) end |
#fetch_gemini(query, model: "gemini-pro", **options, &block) ⇒ Object
98 99 100 |
# File 'lib/semantic_cache/cache.rb', line 98 def fetch_gemini(query, model: "gemini-pro", **, &block) fetch(query, model: model, **, &block) end |
#fetch_openai(query, model: "gpt-4o", **options, &block) ⇒ Object
Convenience methods for specific providers
90 91 92 |
# File 'lib/semantic_cache/cache.rb', line 90 def fetch_openai(query, model: "gpt-4o", **, &block) fetch(query, model: model, **, &block) end |
#invalidate(tags:) ⇒ Object
Invalidate cached entries by tags.
cache.invalidate(tags: [:product_info])
cache.invalidate(tags: "user_data")
106 107 108 |
# File 'lib/semantic_cache/cache.rb', line 106 def invalidate(tags:) @store.(Array()) end |
#savings_report ⇒ Object
Savings report string.
127 128 129 130 |
# File 'lib/semantic_cache/cache.rb', line 127 def savings_report s = @stats "Total saved: #{format("$%.2f", s.total_savings)} (#{s.hits} cached calls)" end |
#size ⇒ Object
Number of entries currently in the cache.
133 134 135 |
# File 'lib/semantic_cache/cache.rb', line 133 def size @store.size end |