Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class PolicyResolver
"token_spike_window_minutes" => 10
},
"stuck_detection" => {
"enabled" => false,
"enabled" => true,
"task_stuck_threshold_minutes" => 30, # Task running for > N minutes
"creative_stall_threshold_minutes" => 120, # Creative no progress for > N minutes
"create_system_comment" => true # Create system comment on escalation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ def auto_recover_stuck_tasks(stuck_items)
next unless task.status == "running"

task.update!(status: "failed")
minutes_stuck = ((Time.current - stuck_item.stuck_since) / 60).round
Rails.logger.info(
"[StuckDetector] Auto-recovered task #{task.id} (agent=#{task.agent_id}): " \
"marked as failed after #{((Time.current - stuck_item.stuck_since) / 60).round} minutes"
"marked as failed after #{minutes_stuck} minutes"
)

# Release resources held by the stuck task
Expand Down Expand Up @@ -93,7 +94,6 @@ def detect_stuck_tasks(config)
.where("updated_at < ?", threshold_time)

stuck_tasks.filter_map do |task|
# Skip if already escalated recently
next if recently_escalated?(task)

escalation_targets = find_escalation_targets(task)
Expand Down Expand Up @@ -254,7 +254,6 @@ def build_message(stuck_item)
when :task
task = stuck_item.item
minutes_stuck = ((Time.current - stuck_item.stuck_since) / 60).round

[
"collavre.stuck_detection.task_stuck",
{
Expand Down