fix: GUI improvements, CROF gate, data dir consolidation, sticky proxy port

- GUI: add Clear Log, Restart Proxy, View Log (opens requests.log) buttons
- CROF: skip entirely unless TARGET_URL contains crof.ai (no logs pollution)
- Consolidate all data dirs into codex-proxy (remove codex-desktop, codex-launcher)
- Proxy port persists across restarts via .last-proxy-port file
- Adaptive compact budget raised from 60% to 80% context window
- Startup config cleanup moved after _init_runtime() to avoid deleting active config
This commit is contained in:
cobra91
2026-05-25 15:43:49 +02:00
Unverified
parent f9dc0d16d9
commit 88e0183ddc
4 changed files with 77 additions and 21 deletions

View File

@@ -259,11 +259,6 @@ try:
for _f in os.listdir(_REQUESTS_DIR):
if _f.endswith(".tmp"):
os.remove(os.path.join(_REQUESTS_DIR, _f))
for _f in os.listdir(_LOG_DIR):
if _f.startswith("proxy-") and _f.endswith(".json"):
os.remove(os.path.join(_LOG_DIR, _f))
if _f.startswith("models-") and _f.endswith(".json"):
os.remove(os.path.join(_LOG_DIR, _f))
except Exception:
pass
_stats_path = os.path.join(_LOG_DIR, "usage-stats.json")
@@ -723,7 +718,6 @@ _GEMINI_AGENT_GUARDRAIL = (
"Always emit the actual tool call in the same response."
)
_LOG_FILE = None
_LOG_FILE_LOCK = threading.Lock()
def _fetch_antigravity_version():
@@ -1302,8 +1296,8 @@ _COMPACT_KEEP_RECENT = 10
_CROF_ADAPTIVE = {
"fail_history": [],
"model_limits": {},
"global_item_limit": 30,
"min_keep_recent": 4,
"global_item_limit": 80,
"min_keep_recent": 6,
}
_BGP_STATS_PATH = os.path.join(_LOG_DIR, "bgp-route-stats.json")
@@ -1371,6 +1365,8 @@ def _sorted_bgp_routes():
return sorted(BGP_ROUTES, key=lambda r: _score_route(r, stats))
def _crof_record(model, n_items, success):
if TARGET_URL and "crof.ai" not in TARGET_URL:
return
if not isinstance(n_items, int) or n_items < 1:
return
entry = {"model": model, "items": n_items, "ok": success}
@@ -1396,7 +1392,8 @@ def _crof_record(model, n_items, success):
global_limit = v["limit"]
_CROF_ADAPTIVE["global_item_limit"] = global_limit
print(f"[crof-adaptive] model={model} items={n_items} {'OK' if success else 'FAIL'} -> limit={ml.get('limit',30)} global={global_limit}", file=sys.stderr)
if TARGET_URL and "crof.ai" in TARGET_URL:
print(f"[crof-adaptive] model={model} items={n_items} {'OK' if success else 'FAIL'} -> limit={ml.get('limit',30)} global={global_limit}", file=sys.stderr)
def _crof_item_limit(model):
ml = _CROF_ADAPTIVE["model_limits"].get(model, {})
@@ -1441,7 +1438,8 @@ def _crof_compact_for_retry(input_data, model):
summary_lines.append(_item_summary(item, max_len=120))
summary_msg = {"type": "message", "role": "user", "content": [{"type": "input_text", "text": "\n".join(summary_lines)}]}
print(f"[crof-adaptive] RETRY compact: {len(input_data)} -> {len(head)+1+len(tail)} (limit={limit}, keep={len(tail)})", file=sys.stderr)
if TARGET_URL and "crof.ai" in TARGET_URL:
print(f"[crof-adaptive] RETRY compact: {len(input_data)} -> {len(head)+1+len(tail)} (limit={limit}, keep={len(tail)})", file=sys.stderr)
return head + [summary_msg] + tail
def _item_summary(item, max_len=200):
@@ -1652,7 +1650,7 @@ def _estimate_tokens(obj):
def _adaptive_compact(input_data, model, policy=None):
policy = policy or {}
context_size = int(policy.get("context_size", _context_limit_for_model(model)))
input_budget = int(context_size * 0.60)
input_budget = int(context_size * 0.80)
estimated = _estimate_tokens(input_data)
if estimated <= input_budget:
return input_data, False
@@ -4296,7 +4294,8 @@ class Handler(http.server.BaseHTTPRequestHandler):
body["input"] = input_data
crof_limit = _crof_item_limit(model)
if not compacted and isinstance(input_data, list) and len(input_data) > crof_limit:
_crof_eligible = TARGET_URL and "crof.ai" in TARGET_URL
if _crof_eligible and not compacted and isinstance(input_data, list) and len(input_data) > crof_limit:
print(f"[crof-adaptive] proactive compact: {len(input_data)} items > limit {crof_limit}", file=sys.stderr)
input_data = _crof_compact_for_retry(input_data, model)
body = dict(body)
@@ -5090,7 +5089,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
print(f"[provider-sensor] synthetic retry failed: {e}", file=sys.stderr)
# Auto-retry on finish_reason=length with no content due to too much context.
if finish_reason == "length" and not has_content and isinstance(input_data, list) and len(input_data) > 5:
if finish_reason == "length" and not has_content and isinstance(input_data, list) and len(input_data) > 5 and TARGET_URL and "crof.ai" in TARGET_URL:
print(f"[crof-adaptive] RETRY: finish_reason=length with no content, compacting {n_items} items", file=sys.stderr)
new_input = _crof_compact_for_retry(input_data, model)
if len(new_input) < len(input_data):
@@ -6029,6 +6028,15 @@ def main():
global SERVER, _START_TIME
_START_TIME = time.time()
_init_runtime()
try:
_current_cfg = os.path.basename(args.config) if args.config else ""
for _f in os.listdir(_LOG_DIR):
if _f.startswith("proxy-") and _f.endswith(".json") and _f != _current_cfg:
os.remove(os.path.join(_LOG_DIR, _f))
if _f.startswith("models-") and _f.endswith(".json"):
os.remove(os.path.join(_LOG_DIR, _f))
except Exception:
pass
signal.signal(signal.SIGINT, _handle_shutdown_signal)
if _IS_WINDOWS:
if hasattr(signal, "SIGBREAK"):