Class: RubyCoded::Tools::ExecutionPolicy
- Inherits:
-
Object
- Object
- RubyCoded::Tools::ExecutionPolicy
- 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
-
#initialize(state:, registry:) ⇒ ExecutionPolicy
constructor
A new instance of ExecutionPolicy.
-
#register_call!(tool_name) ⇒ Object
Records the call, enforces hard limits, and returns the risk level.
-
#requires_confirmation?(risk, mode) ⇒ Boolean
True when the user must confirm this call before it runs.
- #reset_counters! ⇒ Object
- #risk_for(tool_name) ⇒ Object
- #risk_label_for(risk) ⇒ Object
- #warn_if_approaching_limit! ⇒ Object
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.
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.(:system, "Approaching total tool call limit: #{remaining} calls remaining. " \ "Prioritize completing the most important work.") end |