Class: Collavre::Orchestration::PolicyResolver
- Inherits:
-
Object
- Object
- Collavre::Orchestration::PolicyResolver
- Defined in:
- app/services/collavre/orchestration/policy_resolver.rb
Overview
PolicyResolver finds and merges applicable policies for a given context.
Policy precedence (later overrides earlier):
-
Global policies
-
Creative-level policies
-
Topic-level policies
-
Agent-level policies (for scheduling)
Usage:
resolver = PolicyResolver.new(context)
resolver.arbitration_config
# => { "strategy" => "primary_first", "max_responders" => 1 }
Constant Summary collapse
- DEFAULTS =
Default configurations when no policy is set
{ "arbitration" => { "strategy" => "all", "max_responders" => nil # nil means unlimited }, "scheduling" => { "max_concurrent_jobs" => 5, "daily_token_limit" => 100_000, "rate_limit_per_minute" => 20, "backoff_strategy" => "exponential", "topic_max_concurrent_jobs" => 1, # Loop breaker settings "loop_breaker_enabled" => true, "ping_pong_threshold" => 5, # Max back-and-forth between same agents "creative_retry_threshold" => 10, # Max tasks on same creative in time window "creative_retry_window_minutes" => 30, "task_timeout_minutes" => 60, # Max time for a single task "token_spike_threshold" => 50_000, # Token usage spike in window "token_spike_window_minutes" => 10 }, "stuck_detection" => { "enabled" => false, "task_stuck_threshold_minutes" => 30, # Task running for > N minutes "creative_stall_threshold_minutes" => 120, # Creative no progress for > N minutes "queued_orphan_threshold_minutes" => 5, # Queued waiter with no live blocker for > N minutes "create_system_comment" => true # Create system comment on escalation }, "collaboration" => { "a2a_focus_instruction" => nil, # nil = locale default "a2a_completion_instruction" => nil, "a2a_followup_instruction" => nil, "mention_rule" => nil, "confidence_rule" => nil, "escalation_rule" => nil, "review_rule" => nil } }.freeze
Instance Method Summary collapse
-
#arbitration_config ⇒ Object
Get merged arbitration config.
-
#arbitration_strategy ⇒ Object
Convenience methods.
- #bid_fallback_enabled? ⇒ Boolean
-
#collaboration_config ⇒ Object
Collaboration config.
-
#confidence_threshold ⇒ Object
Bid strategy specific.
-
#initialize(context) ⇒ PolicyResolver
constructor
A new instance of PolicyResolver.
- #loop_breaker_config ⇒ Object
-
#loop_breaker_enabled? ⇒ Boolean
Loop breaker settings.
- #max_responders ⇒ Object
- #primary_agent_id ⇒ Object
-
#resolve(policy_type) ⇒ Object
Generic resolve method for any policy type.
-
#scheduling_config ⇒ Object
Get merged scheduling config (without agent-specific overrides).
-
#scheduling_config_for(agent) ⇒ Object
Get merged scheduling config for a specific agent.
- #stuck_detection_config ⇒ Object
-
#stuck_detection_enabled? ⇒ Boolean
Stuck detection settings.
-
#topic_max_concurrent_jobs ⇒ Object
Topic-level concurrency limit.
Constructor Details
#initialize(context) ⇒ PolicyResolver
Returns a new instance of PolicyResolver.
58 59 60 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 58 def initialize(context) @context = context end |
Instance Method Details
#arbitration_config ⇒ Object
Get merged arbitration config
63 64 65 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 63 def arbitration_config @arbitration_config ||= merge_policies("arbitration") end |
#arbitration_strategy ⇒ Object
Convenience methods
91 92 93 94 95 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 91 def arbitration_strategy return "primary_first" if topic_primary_agent_id.present? arbitration_config["strategy"] end |
#bid_fallback_enabled? ⇒ Boolean
110 111 112 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 110 def bid_fallback_enabled? arbitration_config["bid_fallback_enabled"] != false end |
#collaboration_config ⇒ Object
Collaboration config
132 133 134 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 132 def collaboration_config @collaboration_config ||= merge_policies("collaboration") end |
#confidence_threshold ⇒ Object
Bid strategy specific
106 107 108 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 106 def confidence_threshold arbitration_config["confidence_threshold"] end |
#loop_breaker_config ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 119 def loop_breaker_config { "enabled" => scheduling_config["loop_breaker_enabled"], "ping_pong_threshold" => scheduling_config["ping_pong_threshold"], "creative_retry_threshold" => scheduling_config["creative_retry_threshold"], "creative_retry_window_minutes" => scheduling_config["creative_retry_window_minutes"], "task_timeout_minutes" => scheduling_config["task_timeout_minutes"], "token_spike_threshold" => scheduling_config["token_spike_threshold"], "token_spike_window_minutes" => scheduling_config["token_spike_window_minutes"] } end |
#loop_breaker_enabled? ⇒ Boolean
Loop breaker settings
115 116 117 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 115 def loop_breaker_enabled? scheduling_config["loop_breaker_enabled"] == true end |
#max_responders ⇒ Object
97 98 99 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 97 def max_responders arbitration_config["max_responders"] end |
#primary_agent_id ⇒ Object
101 102 103 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 101 def primary_agent_id topic_primary_agent_id || arbitration_config["primary_agent_id"] end |
#resolve(policy_type) ⇒ Object
Generic resolve method for any policy type
146 147 148 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 146 def resolve(policy_type) merge_policies(policy_type) end |
#scheduling_config ⇒ Object
Get merged scheduling config (without agent-specific overrides)
81 82 83 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 81 def scheduling_config @scheduling_config ||= merge_policies("scheduling") end |
#scheduling_config_for(agent) ⇒ Object
Get merged scheduling config for a specific agent
68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 68 def scheduling_config_for(agent) base = merge_policies("scheduling") # Layer agent-specific policies on top agent_policies = OrchestratorPolicy.for_agent(agent.id, policy_type: "scheduling") agent_policies.each do |policy| base = base.merge(policy.config) end base end |
#stuck_detection_config ⇒ Object
141 142 143 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 141 def stuck_detection_config @stuck_detection_config ||= resolve("stuck_detection") end |
#stuck_detection_enabled? ⇒ Boolean
Stuck detection settings
137 138 139 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 137 def stuck_detection_enabled? stuck_detection_config["enabled"] == true end |
#topic_max_concurrent_jobs ⇒ Object
Topic-level concurrency limit
86 87 88 |
# File 'app/services/collavre/orchestration/policy_resolver.rb', line 86 def topic_max_concurrent_jobs scheduling_config["topic_max_concurrent_jobs"] end |