Class: RailsAiBridge::Registry::ContextProviderClient
- Inherits:
-
Object
- Object
- RailsAiBridge::Registry::ContextProviderClient
- Defined in:
- lib/rails_ai_bridge/registry/context_provider_client.rb
Overview
Performs one provider exchange through an MCP HTTP transport.
The client owns policy verification, remote tool metadata checks, result normalization, and safe error translation. It never stores credentials and closes the transport in an ensure block.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- DEFAULT_CLEANUP_DEADLINE_SECONDS =
Upper bound on time to wait for transport.close in the ensure block. Callers may pass a smaller value, but never a larger one.
5.0
Instance Method Summary collapse
-
#call_tool(tool_name, arguments: {}) ⇒ Result
Calls a single remote tool and returns a typed result.
- #initialize(provider:, policy:, transport_factory:, auth_resolver:, timeout_seconds: nil, cleanup_deadline_seconds: DEFAULT_CLEANUP_DEADLINE_SECONDS) ⇒ ContextProviderClient constructor
-
#probe(timeout: nil) ⇒ Result
Lightweight reachability probe: validates the endpoint, opens a transport, lists tools, and closes.
Constructor Details
#initialize(provider:, policy:, transport_factory:, auth_resolver:, timeout_seconds: nil, cleanup_deadline_seconds: DEFAULT_CLEANUP_DEADLINE_SECONDS) ⇒ ContextProviderClient
34 35 36 37 38 39 40 41 |
# File 'lib/rails_ai_bridge/registry/context_provider_client.rb', line 34 def initialize(provider:, policy:, transport_factory:, auth_resolver:, timeout_seconds: nil, cleanup_deadline_seconds: DEFAULT_CLEANUP_DEADLINE_SECONDS) @provider = provider @policy = policy @transport_factory = transport_factory @auth_resolver = auth_resolver @timeout_seconds = timeout_seconds @cleanup_deadline_seconds = clamp_cleanup_deadline(cleanup_deadline_seconds, timeout_seconds) end |
Instance Method Details
#call_tool(tool_name, arguments: {}) ⇒ Result
Calls a single remote tool and returns a typed result.
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 |
# File 'lib/rails_ai_bridge/registry/context_provider_client.rb', line 48 def call_tool(tool_name, arguments: {}) endpoint = @provider.endpoint transport = nil tool_label = tool_name.inspect begin with_timeout(@timeout_seconds, 'provider call timed out') do policy_result = @policy.call(endpoint) return Result.new(status: :error, error: policy_result.error) unless policy_result.success? return Result.new(status: :error, error: RemoteToolError.new("tool #{tool_label} is not declared in the provider manifest")) unless tool_declared?(tool_name) canonical_uri = policy_result.uri headers = resolve_auth(endpoint, canonical_uri) transport = @transport_factory.call(canonical_uri, policy_result.addresses, headers) transport.connect remote_tool = find_tool(transport, tool_name) return Result.new(status: :error, error: RemoteToolError.new("tool #{tool_label} is not allowed")) unless remote_tool raw = transport.call_tool(name: tool_name, arguments: arguments) content = raw.is_a?(Hash) && raw.key?('result') ? raw.dig('result', 'content') : raw Result.new(status: :success, content: sanitize_content(content), provenance: provenance_for(canonical_uri), error: nil) end rescue RailsAiBridge::Registry::ContextProviderError => error Result.new(status: :error, error: error) rescue Timeout::Error Result.new(status: :error, error: RailsAiBridge::Registry::TimeoutError.new('provider call timed out')) rescue StandardError => error Result.new(status: :error, error: RailsAiBridge::Registry::ConnectionError.new("provider call failed (#{error.class}): #{(error.)}")) ensure close_transport(transport) end end |
#probe(timeout: nil) ⇒ Result
Lightweight reachability probe: validates the endpoint, opens a transport, lists tools, and closes. Does not call any tool.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rails_ai_bridge/registry/context_provider_client.rb', line 86 def probe(timeout: nil) endpoint = @provider.endpoint transport = nil effective_timeout = timeout || @timeout_seconds begin with_timeout(effective_timeout, 'provider probe timed out') do policy_result = @policy.call(endpoint) return Result.new(status: :error, error: policy_result.error) unless policy_result.success? canonical_uri = policy_result.uri headers = resolve_auth(endpoint, canonical_uri) transport = @transport_factory.call(canonical_uri, policy_result.addresses, headers) transport.connect transport.tools Result.new(status: :success, content: nil, provenance: provenance_for(canonical_uri), error: nil) end rescue RailsAiBridge::Registry::ContextProviderError => error Result.new(status: :error, error: error) rescue Timeout::Error Result.new(status: :error, error: RailsAiBridge::Registry::TimeoutError.new('provider probe timed out')) rescue StandardError => error Result.new(status: :error, error: RailsAiBridge::Registry::ConnectionError.new("provider probe failed (#{error.class}): #{(error.)}")) ensure close_transport(transport) end end |