bep40 commited on
Commit
e538ea2
·
verified ·
1 Parent(s): 90bab83

Upload patch_agent_loop.py

Browse files
Files changed (1) hide show
  1. patch_agent_loop.py +95 -0
patch_agent_loop.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Patch agent_loop.py - detect task incomplete and send event."""
2
+
3
+ AGENT_LOOP = "/app/agent/core/agent_loop.py"
4
+
5
+ def patch():
6
+ import os
7
+ if not os.path.exists(AGENT_LOOP):
8
+ print(f"SKIP: {AGENT_LOOP} not found")
9
+ return
10
+
11
+ with open(AGENT_LOOP, "r", encoding="utf-8") as f:
12
+ content = f.read()
13
+
14
+ # Add import re if needed for detection
15
+ # Add _check_task_incomplete function before class Handlers
16
+
17
+ check_func = '''
18
+
19
+ def _check_task_incomplete(session: Session, llm_result: LLMResult) -> bool:
20
+ """Check if model stopped streaming but task is incomplete.
21
+
22
+ Returns True when:
23
+ - LLM finished without tool calls
24
+ - But there are unfinished plan items
25
+ """
26
+ if llm_result.tool_calls_acc:
27
+ return False # Has tool calls, task continues via tool execution
28
+
29
+ plan = getattr(session, "current_plan", None) or []
30
+ unfinished = [item for item in plan if item.get("status") in ("pending", "in_progress")]
31
+
32
+ # Also check if there are any pending actions in the loop
33
+ pending_actions = getattr(session, "pending_actions", None)
34
+
35
+ return len(unfinished) > 0 or bool(pending_actions)
36
+
37
+
38
+ def _unfinished_plan_items(session: Session) -> list[dict[str, str]]:
39
+ """Helper to get unfinished plan items."""
40
+ plan = getattr(session, "current_plan", None) or []
41
+ return [item for item in plan if item.get("status") in ("pending", "in_progress")]
42
+
43
+ '''
44
+
45
+ # Insert after LLMResult dataclass definition and before Handlers class
46
+ if "_check_task_incomplete" not in content:
47
+ content = content.replace(
48
+ "class Handlers:",
49
+ check_func + "\n\nclass Handlers:"
50
+ )
51
+
52
+ # Now we need to add the call in the run_agent method
53
+ # Find where LLM result is processed and check for incomplete task
54
+ check_call = '''
55
+ # === Check for incomplete task after LLM response ===
56
+ if not llm_result.tool_calls_acc and llm_result.content:
57
+ # Model finished without tool calls - check if task is done
58
+ unfinished = _unfinished_plan_items(session)
59
+ if unfinished:
60
+ await session.send_event(
61
+ Event(
62
+ event_type="task_incomplete",
63
+ data={
64
+ "incomplete_plan": unfinished,
65
+ "message": "Model phản hồi đã dừng nhưng nhiệm vụ chưa hoàn thành."
66
+ }
67
+ )
68
+ )
69
+ '''
70
+
71
+ # Insert this check after processing tool calls but before final_response check
72
+ # Look for pattern: iteration increment and session updates
73
+ if "task_incomplete" not in content:
74
+ # Find location after tool_calls processing
75
+ insert_marker = " # -- End of turn --"
76
+ if insert_marker in content:
77
+ content = content.replace(
78
+ insert_marker,
79
+ check_call + "\n" + insert_marker
80
+ )
81
+ else:
82
+ # Try another location - after llm_result processing
83
+ result_marker = "final_response = llm_result.content or None"
84
+ if result_marker in content:
85
+ content = content.replace(
86
+ result_marker,
87
+ result_marker + "\n" + check_call
88
+ )
89
+
90
+ with open(AGENT_LOOP, "w", encoding="utf-8") as f:
91
+ f.write(content)
92
+ print(f"OK: Patched {AGENT_LOOP}")
93
+
94
+ if __name__ == "__main__":
95
+ patch()