class RubyLLM::Browser::Capabilities
What a backend can actually guarantee.
Capabilities are the Gem’s fail-closed gate. Policy refuses to start a session unless a backend claims enforced egress isolation; a URL allowlist in Ruby can never substitute for it. Local mode needs a host-pinned server binary, and the Stagehand SDK always merges STAGEHAND_CUSTOM_HEADERS, so those headers must be host-approved before any session starts.
Constants
- EGRESS_ISOLATION
Supported egress-isolation postures.
-
‘:enforced` every initiated request stays within approved destinations and
public address ranges at connection time
-
‘:unverified` not proven; the Gem treats this as unusable for live sessions
-
- SERVER_MODES
Server/topology modes.
Attributes
egress_isolation[R]
server_mode[R]
Public Class Methods
new(server_mode: :remote, egress_isolation: :unverified, local_binary_pinned: false, custom_headers_present: false, custom_headers_approved: false, act_supported: false)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 25 def initialize(server_mode: :remote, egress_isolation: :unverified, local_binary_pinned: false, custom_headers_present: false, custom_headers_approved: false, act_supported: false) @server_mode = symbolize!(server_mode, SERVER_MODES, :server_mode) @egress_isolation = symbolize!(egress_isolation, EGRESS_ISOLATION, :egress_isolation) @local_binary_pinned = !!local_binary_pinned @custom_headers_present = !!custom_headers_present @custom_headers_approved = !!custom_headers_approved @act_supported = !!act_supported freeze end
Public Instance Methods
==(other)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 57 def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end
act_supported?(= @act_supported)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 42 def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end end end
custom_headers_approved?(= @custom_headers_approved)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 41 def custom_headers_approved? = @custom_headers_approved def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end end
custom_headers_present?(= @custom_headers_present)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 40 def custom_headers_present? = @custom_headers_present def custom_headers_approved? = @custom_headers_approved def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end
digest(= Redactor.digest(to_h))
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 55 def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end end end end
enforced_egress?(= egress_isolation == :enforced)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 38 def enforced_egress? = egress_isolation == :enforced def local_binary_pinned? = @local_binary_pinned def custom_headers_present? = @custom_headers_present def custom_headers_approved? = @custom_headers_approved def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}"
hash(= to_h.hash)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 62 def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end end end
inspect(= "
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 64 def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end end
local_binary_pinned?(= @local_binary_pinned)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 39 def local_binary_pinned? = @local_binary_pinned def custom_headers_present? = @custom_headers_present def custom_headers_approved? = @custom_headers_approved def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end
local_mode?(= server_mode == :local)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 37 def local_mode? = server_mode == :local def enforced_egress? = egress_isolation == :enforced def local_binary_pinned? = @local_binary_pinned def custom_headers_present? = @custom_headers_present def custom_headers_approved? = @custom_headers_approved def act_supported? = @act_supported def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end def digest = Redactor.digest(to_h) def ==(other) other.is_a?(Capabilities) && to_h == other.to_h end alias eql? == def hash = to_h.hash def inspect = "#<#{self.class} #{to_h.map { |k, v| "#{k}=#{v}" }.join(" ")}>" private def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput,
symbolize!(value, allowed, name)
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 68 def symbolize!(value, allowed, name) symbol = value.to_sym return symbol if allowed.include?(symbol) raise InvalidInput, "#{name} must be one of #{allowed.inspect}" end
to_h()
click to toggle source
# File lib/ruby_llm/browser/capabilities.rb, line 44 def to_h { server_mode: server_mode, egress_isolation: egress_isolation, local_binary_pinned: @local_binary_pinned, custom_headers_present: @custom_headers_present, custom_headers_approved: @custom_headers_approved, act_supported: @act_supported } end