2025-11-04 05:17:27 +01:00
|
|
|
from pr.config import MAX_AUTONOMOUS_ITERATIONS
|
|
|
|
|
from pr.ui import Colors
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def is_task_complete(response, iteration):
|
2025-11-04 08:09:12 +01:00
|
|
|
if "error" in response:
|
2025-11-04 05:17:27 +01:00
|
|
|
return True
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
if "choices" not in response or not response["choices"]:
|
2025-11-04 05:17:27 +01:00
|
|
|
return True
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
message = response["choices"][0]["message"]
|
|
|
|
|
content = message.get("content", "").lower()
|
2025-11-04 05:17:27 +01:00
|
|
|
|
|
|
|
|
completion_keywords = [
|
2025-11-04 08:09:12 +01:00
|
|
|
"task complete",
|
|
|
|
|
"task is complete",
|
|
|
|
|
"finished",
|
|
|
|
|
"done",
|
|
|
|
|
"successfully completed",
|
|
|
|
|
"task accomplished",
|
|
|
|
|
"all done",
|
|
|
|
|
"implementation complete",
|
|
|
|
|
"setup complete",
|
|
|
|
|
"installation complete",
|
2025-11-04 05:17:27 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
error_keywords = [
|
2025-11-04 08:09:12 +01:00
|
|
|
"cannot proceed",
|
|
|
|
|
"unable to continue",
|
|
|
|
|
"fatal error",
|
|
|
|
|
"cannot complete",
|
|
|
|
|
"impossible to",
|
2025-11-04 05:17:27 +01:00
|
|
|
]
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
has_tool_calls = "tool_calls" in message and message["tool_calls"]
|
2025-11-04 05:17:27 +01:00
|
|
|
mentions_completion = any(keyword in content for keyword in completion_keywords)
|
|
|
|
|
mentions_error = any(keyword in content for keyword in error_keywords)
|
|
|
|
|
|
|
|
|
|
if mentions_error:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if mentions_completion and not has_tool_calls:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if iteration > 5 and not has_tool_calls:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if iteration >= MAX_AUTONOMOUS_ITERATIONS:
|
|
|
|
|
print(f"{Colors.YELLOW}⚠ Maximum iterations reached{Colors.RESET}")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
return False
|