From 5a6c62e36c9f615e23a40b811c3e9cff65b71d10 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Tue, 23 Jun 2026 01:42:06 +0000 Subject: [PATCH] launch-upgrader: fix false completion detection (prompt contains the marker) _completed() grepped the log for UPGRADE RUN COMPLETE, but the kickoff/resume PROMPT (a user message) contains that string verbatim, so it false-positived 'done' while the run was still going. Check the model's ASSISTANT message output via the web server API instead (log grep only as an offline, prompt-excluding fallback). Co-Authored-By: Claude Opus 4.8 --- cc-ci-plan/launch-upgrader.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/cc-ci-plan/launch-upgrader.py b/cc-ci-plan/launch-upgrader.py index 5c637a1..ed4dcf0 100644 --- a/cc-ci-plan/launch-upgrader.py +++ b/cc-ci-plan/launch-upgrader.py @@ -245,9 +245,26 @@ def _run_pids(): return out def _completed(): + # The run is done only when the MODEL prints DONE_MARKER — i.e. it appears in an ASSISTANT + # message's output. NOT a log grep: the kickoff/resume PROMPT (a user message) also contains + # the marker (it instructs the model to print it), which would false-positive. + sid = _session_id() + msgs = _server_get(f"/session/{sid}/message") if sid else None + if msgs is not None: + msgs = msgs if isinstance(msgs, list) else msgs.get("data", []) + for m in msgs: + if ((m.get("info") or {}).get("role")) != "assistant": + continue + for part in (m.get("parts") or []): + t = part.get("text") + if isinstance(t, str) and DONE_MARKER in t: + return True + return False + # Server unreachable → conservative log fallback that excludes the prompt's own mention. try: with open(LOG_FILE, errors="ignore") as f: - f.seek(0, 2); f.seek(max(0, f.tell() - 20000)); return DONE_MARKER in f.read() + f.seek(0, 2); f.seek(max(0, f.tell() - 20000)) + return any(DONE_MARKER in ln and "print" not in ln and "'" not in ln for ln in f) except Exception: return False