fix: prevent duplicate update prompt spam in gateway watcher (#8343)

The _watch_update_progress() poll loop never deleted .update_prompt.json
after forwarding the prompt to the user, causing the same prompt to be
re-sent every poll cycle (2s). Two fixes:

1. Delete .update_prompt.json after forwarding — the update process only
   polls for .update_response, it doesn't need the prompt file to persist.
2. Guard re-sends with _update_prompt_pending check — belt-and-suspenders
   to prevent duplicates even under race conditions.

Add regression test asserting the prompt is sent exactly once.
This commit is contained in:
Teknium 2026-04-12 04:52:59 -07:00 committed by GitHub
parent 7a67b13506
commit 4eecaf06e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 2 deletions

View file

@ -6668,8 +6668,12 @@ class GatewayRunner:
if buffer.strip() and (loop.time() - last_stream_time) >= stream_interval:
await _flush_buffer()
# Check for prompts
if prompt_path.exists() and session_key:
# Check for prompts — only forward if we haven't already sent
# one that's still awaiting a response. Without this guard the
# watcher would re-read the same .update_prompt.json every poll
# cycle and spam the user with duplicate prompt messages.
if (prompt_path.exists() and session_key
and not self._update_prompt_pending.get(session_key)):
try:
prompt_data = json.loads(prompt_path.read_text())
prompt_text = prompt_data.get("prompt", "")
@ -6701,6 +6705,11 @@ class GatewayRunner:
f"or type your answer directly."
)
self._update_prompt_pending[session_key] = True
# Remove the prompt file so it isn't re-read on the
# next poll cycle. The update process only needs
# .update_response to continue — it doesn't re-check
# .update_prompt.json while waiting.
prompt_path.unlink(missing_ok=True)
logger.info("Forwarded update prompt to %s: %s", session_key, prompt_text[:80])
except (json.JSONDecodeError, OSError) as e:
logger.debug("Failed to read update prompt: %s", e)