class RubyLLM::Browser::InMemoryApprovalStore

Thread-safe, in-process {ApprovalStore}.

A fixture for a single process. Production use needs a durable store so an approval survives a worker restart and cannot be replayed by a second process.

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 10
def initialize
  super()
  @mutex = Mutex.new
  @approvals = {}
end

Public Instance Methods

all() click to toggle source
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 56
def all
  synchronize { @approvals.values.dup }
end
consume_once(id, actor_id:, run_id:, url:, action_digest:, now:, page_revision: nil, operation_id: nil, session_id: nil) click to toggle source
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 28
def consume_once(id, actor_id:, run_id:, url:, action_digest:, now:, page_revision: nil,
                 operation_id: nil, session_id: nil)
  synchronize do
    approval = @approvals[id]
    raise ApprovalRequired, "no approval #{id.inspect} was issued" if approval.nil?
    raise ApprovalStale, "approval #{id} was already consumed" if approval.consumed?
    raise ApprovalStale, "approval #{id} was revoked" if approval.revoked?
    raise ApprovalStale, "approval #{id} has expired" if approval.expired?(now)

    unless approval.binding_matches?(
      actor_id: actor_id, run_id: run_id, url: url, action_digest: action_digest,
      page_revision: page_revision, operation_id: operation_id, session_id: session_id
    )
      raise ApprovalStale, "approval #{id} does not authorize this actor, URL, page or action"
    end

    consumed = approval.consume!(now: now)
    @approvals[id] = consumed
  end
end
fetch(id) click to toggle source
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 24
def fetch(id)
  synchronize { @approvals[id] }
end
issue(approval) click to toggle source
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 16
def issue(approval)
  synchronize do
    raise InvalidInput, "approval #{approval.id} already exists" if @approvals.key?(approval.id)

    @approvals[approval.id] = approval
  end
end
revoke(id) click to toggle source
# File lib/ruby_llm/browser/in_memory_approval_store.rb, line 49
def revoke(id)
  synchronize do
    approval = @approvals.fetch(id) { raise ApprovalRequired, "no approval #{id.inspect} was issued" }
    @approvals[id] = approval.revoke!
  end
end