Spaces:
Running
Running
Claude Code Claude Opus 4.6 commited on
Commit Β·
5cbdd00
1
Parent(s): 0aa89f3
god: Fix manual terminate+task blocking - allow immediate task reassignment
Browse filesWhen Cain is in ERROR state and CC is working, agents were getting generic
"PLAN your next [TASK]" guidance instead of aggressive "push now" guidance.
This caused discussion loops with no task assignment when CC was stuck.
The fix: Check child ERROR state BEFORE cc_busy check. When Cain is broken,
agents get aggressive guidance to either terminate CC immediately or have an
exact [TASK] ready β no "planning" discussion allowed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- scripts/conversation-loop.py +36 -19
scripts/conversation-loop.py
CHANGED
|
@@ -1900,7 +1900,42 @@ def build_turn_message(speaker, other, ctx):
|
|
| 1900 |
recent_task_reminder = (last_completed, last_by, last_at)
|
| 1901 |
|
| 1902 |
# Now state-specific guidance
|
| 1903 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1904 |
parts.append(f"\nClaude Code is WORKING but no new output. PLAN your next [TASK] concretely β what exact changes will you assign?")
|
| 1905 |
parts.append(f"DO NOT discuss. Write specific file paths and function names for your next task.")
|
| 1906 |
elif cc_busy:
|
|
@@ -1951,24 +1986,6 @@ def build_turn_message(speaker, other, ctx):
|
|
| 1951 |
last_completed, last_by, last_at = recent_task_reminder
|
| 1952 |
parts.append(f"\nREMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1953 |
parts.append(f"When cooldown ends, FIRST review whether that fix worked before writing a new [TASK].")
|
| 1954 |
-
elif child_state["stage"] in ("RUNTIME_ERROR", "BUILD_ERROR", "CONFIG_ERROR"):
|
| 1955 |
-
if cc_status.get("result"):
|
| 1956 |
-
if recent_task_reminder:
|
| 1957 |
-
last_completed, last_by, last_at = recent_task_reminder
|
| 1958 |
-
parts.append(f"\n{CHILD_NAME} has {child_state['stage']}! REMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1959 |
-
parts.append(f"\nClaude Code JUST FINISHED with a result. FIRST: Review the result carefully to see if it fixes the issue. SECOND: If the fix looks correct, use [ACTION: restart] to restart Cain. ONLY THEN: write a new [TASK]...[/TASK] if the result was incomplete or wrong.")
|
| 1960 |
-
elif recent_task_reminder:
|
| 1961 |
-
last_completed, last_by, last_at = recent_task_reminder
|
| 1962 |
-
parts.append(f"\n{CHILD_NAME} has {child_state['stage']}!")
|
| 1963 |
-
parts.append(f"\nREMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1964 |
-
parts.append(f"FIRST: Review whether that fix actually worked. SECOND: If the fix was correct, use [ACTION: restart] to apply it. THIRD: Only write a new [TASK]...[/TASK] if the previous fix was incomplete or wrong.")
|
| 1965 |
-
else:
|
| 1966 |
-
parts.append(f"\nπ¨ {CHILD_NAME} has {child_state['stage']}!")
|
| 1967 |
-
parts.append(f"\nπ΄ CRITICAL: Focus ONLY on fixing this {child_state['stage']}.")
|
| 1968 |
-
parts.append(f"- DO NOT work on features, enhancements, or cosmetic changes.")
|
| 1969 |
-
parts.append(f"- ONLY push fixes that address the error itself.")
|
| 1970 |
-
parts.append(f"- Trial-and-error is GOOD β push a fix attempt, don't deliberate.")
|
| 1971 |
-
parts.append(f"Pushes so far: {_push_count} total, {_push_count_this_task} this task. Turns since last push: {_turns_since_last_push}. PUSH MORE.")
|
| 1972 |
elif child_state["alive"] and cc_status.get("result"):
|
| 1973 |
if recent_task_reminder:
|
| 1974 |
last_completed, last_by, last_at = recent_task_reminder
|
|
|
|
| 1900 |
recent_task_reminder = (last_completed, last_by, last_at)
|
| 1901 |
|
| 1902 |
# Now state-specific guidance
|
| 1903 |
+
# CRITICAL: Check child ERROR state FIRST, before cc_busy check
|
| 1904 |
+
# When Cain is broken, agents need aggressive "push now" guidance, not "plan and wait"
|
| 1905 |
+
if child_state["stage"] in ("RUNTIME_ERROR", "BUILD_ERROR", "CONFIG_ERROR"):
|
| 1906 |
+
if cc_status.get("result"):
|
| 1907 |
+
if recent_task_reminder:
|
| 1908 |
+
last_completed, last_by, last_at = recent_task_reminder
|
| 1909 |
+
parts.append(f"\n{CHILD_NAME} has {child_state['stage']}! REMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1910 |
+
parts.append(f"\nClaude Code JUST FINISHED with a result. FIRST: Review the result carefully to see if it fixes the issue. SECOND: If the fix looks correct, use [ACTION: restart] to restart Cain. ONLY THEN: write a new [TASK]...[/TASK] if the result was incomplete or wrong.")
|
| 1911 |
+
elif cc_busy:
|
| 1912 |
+
# Child in ERROR + CC WORKING = need aggressive action, not "planning"
|
| 1913 |
+
cc_elapsed = int(time.time() - cc_status.get("started", 0)) if cc_status.get("started", 0) > 0 else 0
|
| 1914 |
+
if _push_count_this_task == 0 and cc_elapsed > 20:
|
| 1915 |
+
parts.append(f"\nπ¨ CRITICAL: {CHILD_NAME} has {child_state['stage']}! CC has been running {cc_elapsed}s with ZERO pushes!")
|
| 1916 |
+
parts.append(f"CC is STUCK. Use [ACTION: terminate_cc] NOW, then immediately assign a new [TASK].")
|
| 1917 |
+
parts.append(f"π NO discussion. Trial-and-error means RAPID pushes, not waiting for stuck CC.")
|
| 1918 |
+
elif cc_elapsed > 40:
|
| 1919 |
+
parts.append(f"\nπ¨ CRITICAL: {CHILD_NAME} has {child_state['stage']}! CC has been running {cc_elapsed}s!")
|
| 1920 |
+
parts.append(f"If output looks stale, use [ACTION: terminate_cc] NOW. Otherwise, have your EXACT [TASK] ready.")
|
| 1921 |
+
parts.append(f"π NO discussion. Your next turn: either terminate CC OR write [TASK] immediately.")
|
| 1922 |
+
else:
|
| 1923 |
+
parts.append(f"\nπ¨ {CHILD_NAME} has {child_state['stage']}! CC is working ({cc_elapsed}s).")
|
| 1924 |
+
parts.append(f"π DO NOT discuss architecture. Have your EXACT [TASK] ready: file paths, function names, exact changes.")
|
| 1925 |
+
parts.append(f"When CC finishes: write [TASK] immediately, NO review turn. Trial-and-error > planning.")
|
| 1926 |
+
elif recent_task_reminder:
|
| 1927 |
+
last_completed, last_by, last_at = recent_task_reminder
|
| 1928 |
+
parts.append(f"\n{CHILD_NAME} has {child_state['stage']}!")
|
| 1929 |
+
parts.append(f"\nREMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1930 |
+
parts.append(f"FIRST: Review whether that fix actually worked. SECOND: If the fix was correct, use [ACTION: restart] to apply it. THIRD: Only write a new [TASK]...[/TASK] if the previous fix was incomplete or wrong.")
|
| 1931 |
+
else:
|
| 1932 |
+
parts.append(f"\nπ¨ {CHILD_NAME} has {child_state['stage']}!")
|
| 1933 |
+
parts.append(f"\nπ΄ CRITICAL: Focus ONLY on fixing this {child_state['stage']}.")
|
| 1934 |
+
parts.append(f"- DO NOT work on features, enhancements, or cosmetic changes.")
|
| 1935 |
+
parts.append(f"- ONLY push fixes that address the error itself.")
|
| 1936 |
+
parts.append(f"- Trial-and-error is GOOD β push a fix attempt, don't deliberate.")
|
| 1937 |
+
parts.append(f"Pushes so far: {_push_count} total, {_push_count_this_task} this task. Turns since last push: {_turns_since_last_push}. PUSH MORE.")
|
| 1938 |
+
elif cc_busy and _cc_stale_count >= 2:
|
| 1939 |
parts.append(f"\nClaude Code is WORKING but no new output. PLAN your next [TASK] concretely β what exact changes will you assign?")
|
| 1940 |
parts.append(f"DO NOT discuss. Write specific file paths and function names for your next task.")
|
| 1941 |
elif cc_busy:
|
|
|
|
| 1986 |
last_completed, last_by, last_at = recent_task_reminder
|
| 1987 |
parts.append(f"\nREMEMBER: {last_by} just completed '{last_completed}' ({int(time.time() - last_at)}s ago).")
|
| 1988 |
parts.append(f"When cooldown ends, FIRST review whether that fix worked before writing a new [TASK].")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1989 |
elif child_state["alive"] and cc_status.get("result"):
|
| 1990 |
if recent_task_reminder:
|
| 1991 |
last_completed, last_by, last_at = recent_task_reminder
|