v10.13.8: read-vs-write loop detection replaces same-file counting
This commit is contained in:
@@ -5896,26 +5896,36 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
|||||||
f"{_ANTIGRAVITY_MAX_TOOL_CALLS_PER_TASK - cumulative_calls} remaining before forced stop. "
|
f"{_ANTIGRAVITY_MAX_TOOL_CALLS_PER_TASK - cumulative_calls} remaining before forced stop. "
|
||||||
f"STOP READING FILES AND APPLY YOUR EDITS NOW."}]})
|
f"STOP READING FILES AND APPLY YOUR EDITS NOW."}]})
|
||||||
|
|
||||||
# CHANGE 2: File-path read-loop detection
|
# CHANGE 2: Read-vs-write loop detection
|
||||||
|
_READ_CMDS = ("cat ", "head ", "tail ", "less ", "more ", "grep ", "find ", "ls ", "sed -n", "wc ", "file ", "stat ", "du ", "pwd", "which ", "type ", "python3 -c \"\nwith open(", "python3 -c \"\nimport re; open(", ".read(", "read_file", "view_file", "search_file", "list_dir")
|
||||||
|
_WRITE_CMDS = ("write(", ".write", " > ", " >> ", "sed -i", "patch ", "mv ", "cp ", "install ", "mkdir ", "rm ", "chmod ", "chown ", "truncate", "insert_text", "replace_text", "write_file", "create_file")
|
||||||
with _ANTIGRAVITY_LOOP_TRACKER_LOCK:
|
with _ANTIGRAVITY_LOOP_TRACKER_LOCK:
|
||||||
if ag_key not in _ANTIGRAVITY_FILE_TRACKER:
|
if ag_key not in _ANTIGRAVITY_FILE_TRACKER:
|
||||||
_ANTIGRAVITY_FILE_TRACKER[ag_key] = {"last_path": None, "path_counts": {}, "total_reads": 0}
|
_ANTIGRAVITY_FILE_TRACKER[ag_key] = {"reads": 0, "writes": 0, "write_detected": False}
|
||||||
ft = _ANTIGRAVITY_FILE_TRACKER[ag_key]
|
ft = _ANTIGRAVITY_FILE_TRACKER[ag_key]
|
||||||
for item in reversed(input_data):
|
for item in input_data:
|
||||||
if isinstance(item, dict) and item.get("type") == "function_call":
|
if isinstance(item, dict) and item.get("type") == "function_call":
|
||||||
args_str = json.dumps(item.get("arguments", {}))
|
args_str = item.get("arguments", "{}")
|
||||||
file_match = re.search(r'(/[\w/.-]+\.(?:html|py|js|ts|css|json|md|yaml|yml|xml|txt|sh))', args_str)
|
if not isinstance(args_str, str):
|
||||||
if file_match:
|
args_str = json.dumps(args_str)
|
||||||
detected_path = file_match.group(1)
|
args_lower = args_str.lower()
|
||||||
ft["total_reads"] += 1
|
is_read = any(k in args_lower for k in _READ_CMDS)
|
||||||
ft["path_counts"][detected_path] = ft["path_counts"].get(detected_path, 0) + 1
|
is_write = any(k in args_lower for k in _WRITE_CMDS)
|
||||||
ft["last_path"] = detected_path
|
if is_write:
|
||||||
if ft["path_counts"][detected_path] >= 8 or ft["total_reads"] > 40:
|
ft["writes"] += 1
|
||||||
ag_state["force_finalize"] = True
|
ft["write_detected"] = True
|
||||||
print(f"[antigravity-loop] FILE READ LOOP: {detected_path} read "
|
elif is_read:
|
||||||
f"{ft['path_counts'][detected_path]}x, total={ft['total_reads']}",
|
ft["reads"] += 1
|
||||||
file=sys.stderr)
|
n_reads = ft["reads"]
|
||||||
break
|
n_writes = ft["writes"]
|
||||||
|
if n_reads >= 12 and n_writes == 0:
|
||||||
|
ag_state["force_finalize"] = True
|
||||||
|
print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads} reads, {n_writes} writes — model never writes", file=sys.stderr)
|
||||||
|
elif n_reads >= 8 and n_writes == 0 and not ag_state.get("force_finalize"):
|
||||||
|
contents.append({"role": "user", "parts": [{"text":
|
||||||
|
f"WARNING: You have made {n_reads} tool calls and ZERO writes. "
|
||||||
|
f"You MUST apply your edit NOW using exec_command with a python write. "
|
||||||
|
f"Do NOT read any more files. WRITE YOUR CHANGES IMMEDIATELY."}]})
|
||||||
|
|
||||||
null_tool_names = {"get_goal", "get_remaining_tokens", "get_completion_budget", "status"}
|
null_tool_names = {"get_goal", "get_remaining_tokens", "get_completion_budget", "status"}
|
||||||
consecutive_null = 0
|
consecutive_null = 0
|
||||||
@@ -6731,22 +6741,31 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
with _ANTIGRAVITY_LOOP_TRACKER_LOCK:
|
with _ANTIGRAVITY_LOOP_TRACKER_LOCK:
|
||||||
if ag_key not in _ANTIGRAVITY_FILE_TRACKER:
|
if ag_key not in _ANTIGRAVITY_FILE_TRACKER:
|
||||||
_ANTIGRAVITY_FILE_TRACKER[ag_key] = {"last_path": None, "path_counts": {}, "total_reads": 0}
|
_ANTIGRAVITY_FILE_TRACKER[ag_key] = {"reads": 0, "writes": 0, "write_detected": False}
|
||||||
ft = _ANTIGRAVITY_FILE_TRACKER[ag_key]
|
ft = _ANTIGRAVITY_FILE_TRACKER[ag_key]
|
||||||
for item in reversed(input_data):
|
for item in input_data:
|
||||||
if isinstance(item, dict) and item.get("type") == "function_call":
|
if isinstance(item, dict) and item.get("type") == "function_call":
|
||||||
args_str = json.dumps(item.get("arguments", {}))
|
args_str = item.get("arguments", "{}")
|
||||||
file_match = re.search(r'(/[\w/.-]+\.(?:html|py|js|ts|css|json|md|yaml|yml|xml|txt|sh))', args_str)
|
if not isinstance(args_str, str):
|
||||||
if file_match:
|
args_str = json.dumps(args_str)
|
||||||
dp = file_match.group(1)
|
args_lower = args_str.lower()
|
||||||
ft["total_reads"] += 1
|
is_read = any(k in args_lower for k in _READ_CMDS)
|
||||||
ft["path_counts"][dp] = ft["path_counts"].get(dp, 0) + 1
|
is_write = any(k in args_lower for k in _WRITE_CMDS)
|
||||||
ft["last_path"] = dp
|
if is_write:
|
||||||
if ft["path_counts"][dp] >= 8 or ft["total_reads"] > 40:
|
ft["writes"] += 1
|
||||||
ag_state["force_finalize"] = True
|
ft["write_detected"] = True
|
||||||
print(f"[antigravity-loop] FILE READ LOOP: {dp} read "
|
elif is_read:
|
||||||
f"{ft['path_counts'][dp]}x, total={ft['total_reads']}", file=sys.stderr)
|
ft["reads"] += 1
|
||||||
break
|
n_reads = ft["reads"]
|
||||||
|
n_writes = ft["writes"]
|
||||||
|
if n_reads >= 12 and n_writes == 0:
|
||||||
|
ag_state["force_finalize"] = True
|
||||||
|
print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads} reads, {n_writes} writes — model never writes", file=sys.stderr)
|
||||||
|
elif n_reads >= 8 and n_writes == 0 and not ag_state.get("force_finalize"):
|
||||||
|
contents.append({"role": "user", "parts": [{"text":
|
||||||
|
f"WARNING: You have made {n_reads} tool calls and ZERO writes. "
|
||||||
|
f"You MUST apply your edit NOW using exec_command with a python write. "
|
||||||
|
f"Do NOT read any more files. WRITE YOUR CHANGES IMMEDIATELY."}]})
|
||||||
|
|
||||||
null_tool_names = {"get_goal", "get_remaining_tokens", "get_completion_budget", "status"}
|
null_tool_names = {"get_goal", "get_remaining_tokens", "get_completion_budget", "status"}
|
||||||
consecutive_null = 0
|
consecutive_null = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user