Class: RubyLLM::MCP::Handlers::ApprovalDecision

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_llm/mcp/handlers/approval_decision.rb

Overview

Normalized decision returned by human-in-the-loop handlers.

Constant Summary collapse

VALID_STATUSES =
%i[approved denied deferred].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status:, reason: nil, approval_id: nil, timeout: nil, promise: nil) ⇒ ApprovalDecision

Returns a new instance of ApprovalDecision.



12
13
14
15
16
17
18
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 12

def initialize(status:, reason: nil, approval_id: nil, timeout: nil, promise: nil)
  @status = status.to_sym
  @reason = reason
  @approval_id = approval_id
  @timeout = timeout
  @promise = promise
end

Instance Attribute Details

#approval_idObject (readonly)

Returns the value of attribute approval_id.



10
11
12
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 10

def approval_id
  @approval_id
end

#promiseObject (readonly)

Returns the value of attribute promise.



10
11
12
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 10

def promise
  @promise
end

#reasonObject (readonly)

Returns the value of attribute reason.



10
11
12
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 10

def reason
  @reason
end

#statusObject (readonly)

Returns the value of attribute status.



10
11
12
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 10

def status
  @status
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



10
11
12
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 10

def timeout
  @timeout
end

Class Method Details

.approvedObject



20
21
22
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 20

def self.approved
  new(status: :approved)
end

.deferred(approval_id:, timeout:) ⇒ Object



28
29
30
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 28

def self.deferred(approval_id:, timeout:)
  new(status: :deferred, approval_id: approval_id, timeout: timeout)
end

.denied(reason: "Denied by user") ⇒ Object



24
25
26
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 24

def self.denied(reason: "Denied by user")
  new(status: :denied, reason: reason)
end

.from_handler_result(result, approval_id:, default_timeout: nil) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 32

def self.from_handler_result(result, approval_id:, default_timeout: nil)
  unless result.is_a?(Hash)
    raise Errors::InvalidApprovalDecision.new(
      message: "Human-in-the-loop handler must return a Hash, got #{result.class}"
    )
  end

  status = (result[:status] || result["status"])&.to_sym
  unless VALID_STATUSES.include?(status)
    raise Errors::InvalidApprovalDecision.new(
      message: "Human-in-the-loop handler returned invalid status '#{status.inspect}'"
    )
  end

  case status
  when :approved
    approved
  when :denied
    denied(reason: result[:reason] || result["reason"] || "Denied by user")
  when :deferred
    timeout = result[:timeout] || result["timeout"] || default_timeout
    validate_timeout!(timeout)
    deferred(approval_id: approval_id, timeout: timeout.to_f)
  end
end

Instance Method Details

#approved?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 68

def approved?
  status == :approved
end

#deferred?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 76

def deferred?
  status == :deferred
end

#denied?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 72

def denied?
  status == :denied
end

#with_promise(promise) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/ruby_llm/mcp/handlers/approval_decision.rb', line 58

def with_promise(promise)
  self.class.new(
    status: status,
    reason: reason,
    approval_id: approval_id,
    timeout: timeout,
    promise: promise
  )
end