Class: RailsAiBridge::ToolResultCache
- Inherits:
-
Object
- Object
- RailsAiBridge::ToolResultCache
- Defined in:
- lib/rails_ai_bridge/tool_result_cache.rb
Overview
Caches MCP tool call results keyed by a stable fingerprint of the arguments.
The cache is in-memory, per-process, and TTL-based. It ignores server_context
when fingerprinting so identical client requests share the same cached response.
Enable by setting config.mcp.tool_result_cache_ttl to a positive number of seconds.
Defined Under Namespace
Classes: CachedTool
Constant Summary collapse
- NON_CACHEABLE =
Tool names that must never be cached because their results may change between calls (external provider data) or represent live network state.
Set[ 'rails_get_provider_context' ].freeze
Class Method Summary collapse
-
.enabled? ⇒ Boolean
Whether tool result caching is enabled.
-
.fetch_response(tool_name, arguments) ⇒ MCP::Tool::Response
Fetches a cached response or yields to compute it.
-
.maybe_wrap(tool_class) ⇒ Class, CachedTool
Wraps a tool class if caching is enabled; otherwise returns the class unchanged.
-
.reset! ⇒ void
Clears all cached tool results.
-
.wrap(tool_class) ⇒ CachedTool
Wraps a tool class so every call goes through the cache.
Class Method Details
.enabled? ⇒ Boolean
Returns whether tool result caching is enabled.
123 124 125 |
# File 'lib/rails_ai_bridge/tool_result_cache.rb', line 123 def enabled? RailsAiBridge.configuration.mcp.tool_result_cache_ttl.to_i.positive? end |
.fetch_response(tool_name, arguments) ⇒ MCP::Tool::Response
Fetches a cached response or yields to compute it.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rails_ai_bridge/tool_result_cache.rb', line 94 def fetch_response(tool_name, arguments) return yield unless enabled? key = cache_key(tool_name, arguments) fingerprint = key.split(':', 2).last mutex.synchronize do entry = cache[key] if entry && ttl_valid?(entry) Instrumentation.instrument('tool.result_cache_hit', tool_name: tool_name, fingerprint: fingerprint) return entry[:response] end end Instrumentation.instrument('tool.result_cache_miss', tool_name: tool_name, fingerprint: fingerprint) do response = yield mutex.synchronize { cache[key] = { response: response, fetched_at: monotonic_now } } response end end |
.maybe_wrap(tool_class) ⇒ Class, CachedTool
Wraps a tool class if caching is enabled; otherwise returns the class unchanged.
73 74 75 76 77 78 |
# File 'lib/rails_ai_bridge/tool_result_cache.rb', line 73 def maybe_wrap(tool_class) return tool_class unless enabled? return tool_class if NON_CACHEABLE.include?(tool_class.tool_name) wrap(tool_class) end |
.reset! ⇒ void
This method returns an undefined value.
Clears all cached tool results.
118 119 120 |
# File 'lib/rails_ai_bridge/tool_result_cache.rb', line 118 def reset! mutex.synchronize { @cache = {} } end |
.wrap(tool_class) ⇒ CachedTool
Wraps a tool class so every call goes through the cache.
84 85 86 |
# File 'lib/rails_ai_bridge/tool_result_cache.rb', line 84 def wrap(tool_class) CachedTool.new(tool_class) end |