class RubyLLM::Browser::Act
One host-approved browser action. Disabled unless the host configures an {ApprovalStore} and issues a matching single-use {Approval}. Currently simulation-only: {Engine} refuses all non-fake Act backends until the required same-session/target approval protocol is implemented.
‘Act` is opt-in and must never be registered by default. Two gates protect it:
-
RubyLLM’s ‘requires_approval` pauses the tool call, and this class’s instance approval resolver reads the host {ApprovalStore} — a side-effect-free read, because
RubyLLMmay call the resolver several times. A bare ‘Chat#approve` records no host approval and therefore dispatches nothing. -
Immediately before dispatch, the {Engine} re-normalizes the action against policy and atomically consumes the approval exactly once, bound to this actor, run, URL, page revision and exact action digest. A replayed, expired, revoked, cross-actor or stale-page approval denies without dispatching.
Purchases, posts, account changes, credential entry and access-control bypass stay outside the allowed set even with a broad approval. A provider timeout after dispatch is an ‘unknown` outcome that requires a new explicit decision, never an automatic retry.
Public Instance Methods
The instance-level resolver so it can read this tool’s host {ApprovalStore}.
It only reads: it never consumes an approval and never dispatches. Returning ‘true` merely lets the call proceed to {Engine#act}, which performs the authoritative, atomic, fully-bound check immediately before dispatch.
# File lib/ruby_llm/browser/tools/act.rb, line 70 def approval_resolver lambda do |tool_call| approve?(tool_call.arguments) end end
# File lib/ruby_llm/browser/tools/act.rb, line 50 def execute(url:, approval_id:, method:, selector:, description: nil, arguments: nil) report("Checking an approved browser action") action = { "method" => method, "selector" => selector, "description" => description, "arguments" => Array(arguments).map(&:to_s) } engine.act(url: url, approval_id: approval_id, action: action).to_h rescue Error => e failure(e) rescue StandardError unexpected_failure end