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:
@@ -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"):
|
||||
|
||||
Reference in New Issue
Block a user