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
17 changes: 16 additions & 1 deletion droidrun/agent/droid/droid_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- When reasoning=True: Uses Manager (planning) + Executor (action) workflows
"""

import json
import logging
from typing import TYPE_CHECKING, Type, Awaitable, Union

Expand Down Expand Up @@ -762,9 +763,23 @@ async def handle_executor_result(
"""
Process Executor result and continue.

Checks for error escalation and loops back to Manager.
Checks for error escalation, repeated action loops, and loops back to Manager.
Note: Max steps check is now done in run_manager pre-flight.
"""
# Check for repeated action loop (same action N times in a row)
repeat_thresh = 3
if len(self.shared_state.action_pool) >= repeat_thresh:
recent_actions = self.shared_state.action_pool[-repeat_thresh:]
try:
normalized = [json.dumps(a, sort_keys=True) for a in recent_actions]
if len(set(normalized)) == 1:
logger.warning(
f"⚠️ Executor stuck: same action repeated {repeat_thresh} times in a row: {normalized[0]}"
)
self.shared_state.error_flag_plan = True
except (TypeError, ValueError):
pass # Non-serializable actions, skip detection

# Check error escalation and reset flag when errors are resolved
err_thresh = self.shared_state.err_to_manager_thresh

Expand Down
4 changes: 3 additions & 1 deletion droidrun/config/prompts/executor/system.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ No actions have been taken yet.
Whatever the current subgoal says to do, do that EXACTLY. Do not substitute with what you think is better. Do not optimize. Do not consider screen state. Parse the subgoal text literally and execute the matching atomic action.

IMPORTANT:
1. Do NOT repeat previously failed actions multiple times. Try changing to another action.
1. Do NOT repeat previously failed actions multiple times. If an action failed, try a DIFFERENT action or approach.
2. Must do the current subgoal.
3. If you have tried the same action 2+ times and it keeps failing, try a completely different approach. If truly stuck with no viable action, use `{"action": "wait", "duration": 1.0}` as a fallback and explain why in the Description (e.g., "No actionable element found for subgoal").
4. ALWAYS output a valid action. There is no "skip" or "do nothing" option — use `wait` with duration 1.0 if uncertain.

Provide your output in the following format, which contains three parts:

Expand Down