Class: RubyCoded::Tools::ExecutionPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_coded/tools/execution_policy.rb

Overview

Centralizes runtime safety policy for tool execution:

  • risk lookup (delegated to the registry),
  • call budgeting (write vs total rounds, warning threshold),
  • confirmation requirement based on risk, mode, and auto-approve.

Both LLMBridge and CodexBridge share a policy instance so limits and approval rules stay consistent across backends.

Constant Summary collapse

MAX_WRITE_TOOL_ROUNDS =
50
MAX_TOTAL_TOOL_ROUNDS =
200
WARNING_THRESHOLD_RATIO =
0.8

Instance Method Summary collapse

Constructor Details

#initialize(state:, registry:) ⇒ ExecutionPolicy

Returns a new instance of ExecutionPolicy.



21
22
23
24
25
# File 'lib/ruby_coded/tools/execution_policy.rb', line 21

def initialize(state:, registry:)
  @state = state
  @registry = registry
  reset_counters!
end

Instance Method Details

#register_call!(tool_name) ⇒ Object

Records the call, enforces hard limits, and returns the risk level. Raises AgentIterationLimitError when the total budget is exceeded.



38
39
40
41
42
43
44
# File 'lib/ruby_coded/tools/execution_policy.rb', line 38

def register_call!(tool_name)
  risk = risk_for(tool_name)
  @tool_call_count += 1
  @write_tool_call_count += 1 unless risk == BaseTool::SAFE_RISK
  enforce_limits!
  risk
end

#requires_confirmation?(risk, mode) ⇒ Boolean

True when the user must confirm this call before it runs.

Returns:

  • (Boolean)


57
58
59
60
61
62
# File 'lib/ruby_coded/tools/execution_policy.rb', line 57

def requires_confirmation?(risk, mode)
  return false if risk == BaseTool::SAFE_RISK
  return false if @state.auto_approve_tools?

  mode.requires_confirmation?
end

#reset_counters!Object



27
28
29
30
# File 'lib/ruby_coded/tools/execution_policy.rb', line 27

def reset_counters!
  @tool_call_count = 0
  @write_tool_call_count = 0
end

#risk_for(tool_name) ⇒ Object



32
33
34
# File 'lib/ruby_coded/tools/execution_policy.rb', line 32

def risk_for(tool_name)
  @registry.risk_level_for(tool_name)
end

#risk_label_for(risk) ⇒ Object



64
65
66
# File 'lib/ruby_coded/tools/execution_policy.rb', line 64

def risk_label_for(risk)
  risk == BaseTool::DANGEROUS_RISK ? "DANGEROUS" : "WRITE"
end

#warn_if_approaching_limit!Object



46
47
48
49
50
51
52
53
54
# File 'lib/ruby_coded/tools/execution_policy.rb', line 46

def warn_if_approaching_limit!
  threshold = warning_threshold
  return unless @tool_call_count == threshold

  remaining = MAX_TOTAL_TOOL_ROUNDS - threshold
  @state.add_message(:system,
                     "Approaching total tool call limit: #{remaining} calls remaining. " \
                     "Prioritize completing the most important work.")
end