diff --git a/translate-proxy.py b/translate-proxy.py index c40e92e..f1436de 100755 --- a/translate-proxy.py +++ b/translate-proxy.py @@ -5979,36 +5979,31 @@ class Handler(http.server.BaseHTTPRequestHandler): f"{_mp_max_calls - cumulative_calls} remaining before forced stop. " f"STOP READING FILES AND APPLY YOUR EDITS NOW."}]}) - # CHANGE 2: Read-vs-write loop detection + # CHANGE 2: Read-vs-write loop detection (snapshot, no accumulation) _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: - if ag_key not in _ANTIGRAVITY_FILE_TRACKER: - _ANTIGRAVITY_FILE_TRACKER[ag_key] = {"reads": 0, "writes": 0, "write_detected": False} - ft = _ANTIGRAVITY_FILE_TRACKER[ag_key] - for item in input_data: - if isinstance(item, dict) and item.get("type") == "function_call": - args_str = item.get("arguments", "{}") - if not isinstance(args_str, str): - args_str = json.dumps(args_str) - args_lower = args_str.lower() - is_read = any(k in args_lower for k in _READ_CMDS) - is_write = any(k in args_lower for k in _WRITE_CMDS) - if is_write: - ft["writes"] += 1 - ft["write_detected"] = True - elif is_read: - ft["reads"] += 1 - n_reads = ft["reads"] - n_writes = ft["writes"] - if n_reads >= _mp_max_reads and n_writes == 0: - ag_state["force_finalize"] = True - print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads} reads, {n_writes} writes (model={model}, limit={_mp_max_reads})", file=sys.stderr) - elif n_reads >= _mp_warn_reads 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."}]}) + n_reads = 0 + n_writes = 0 + for item in input_data: + if isinstance(item, dict) and item.get("type") == "function_call": + args_str = item.get("arguments", "{}") + if not isinstance(args_str, str): + args_str = json.dumps(args_str) + args_lower = args_str.lower() + is_read = any(k in args_lower for k in _READ_CMDS) + is_write = any(k in args_lower for k in _WRITE_CMDS) + if is_write: + n_writes += 1 + elif is_read: + n_reads += 1 + if n_reads >= _mp_max_reads and n_writes == 0: + ag_state["force_finalize"] = True + print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads} reads, {n_writes} writes in context (model={model}, limit={_mp_max_reads})", file=sys.stderr) + elif n_reads >= _mp_warn_reads 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"} consecutive_null = 0 @@ -6828,33 +6823,28 @@ class Handler(http.server.BaseHTTPRequestHandler): f"{_mp_max - cumulative_calls} remaining. " f"STOP READING AND WRITE NOW."}]}) - with _ANTIGRAVITY_LOOP_TRACKER_LOCK: - if ag_key not in _ANTIGRAVITY_FILE_TRACKER: - _ANTIGRAVITY_FILE_TRACKER[ag_key] = {"reads": 0, "writes": 0, "write_detected": False} - ft = _ANTIGRAVITY_FILE_TRACKER[ag_key] - for item in input_data: - if isinstance(item, dict) and item.get("type") == "function_call": - args_str = item.get("arguments", "{}") - if not isinstance(args_str, str): - args_str = json.dumps(args_str) - args_lower = args_str.lower() - is_read = any(k in args_lower for k in _READ_CMDS) - is_write = any(k in args_lower for k in _WRITE_CMDS) - if is_write: - ft["writes"] += 1 - ft["write_detected"] = True - elif is_read: - ft["reads"] += 1 - n_reads = ft["reads"] - n_writes = ft["writes"] - if n_reads >= _mp_maxr and n_writes == 0: - ag_state["force_finalize"] = True - print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads} reads, {n_writes} writes (model={model}, limit={_mp_maxr})", file=sys.stderr) - elif n_reads >= _mp_warnr 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."}]}) + n_reads_oa = 0 + n_writes_oa = 0 + for item in input_data: + if isinstance(item, dict) and item.get("type") == "function_call": + args_str = item.get("arguments", "{}") + if not isinstance(args_str, str): + args_str = json.dumps(args_str) + args_lower = args_str.lower() + is_read = any(k in args_lower for k in _READ_CMDS) + is_write = any(k in args_lower for k in _WRITE_CMDS) + if is_write: + n_writes_oa += 1 + elif is_read: + n_reads_oa += 1 + if n_reads_oa >= _mp_maxr and n_writes_oa == 0: + ag_state["force_finalize"] = True + print(f"[antigravity-loop] READ-WRITE IMBALANCE: {n_reads_oa} reads, {n_writes_oa} writes in context (model={model}, limit={_mp_maxr})", file=sys.stderr) + elif n_reads_oa >= _mp_warnr and n_writes_oa == 0 and not ag_state.get("force_finalize"): + contents.append({"role": "user", "parts": [{"text": + f"WARNING: You have made {n_reads_oa} 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"} consecutive_null = 0