diff --git a/api/background_process.py b/api/background_process.py index 946598c36..ab82083fa 100644 --- a/api/background_process.py +++ b/api/background_process.py @@ -350,7 +350,7 @@ def _truncate(text: str, limit: int) -> str: return s[:limit] + "\n…(truncated)" -def format_wakeup_prompt(evt: dict) -> str | None: +def format_wakeup_prompt(evt: object) -> str | None: """Build the synthetic [IMPORTANT: …] message the agent will see. Mirrors ``cli._format_process_notification`` so wakeup payloads look the @@ -362,6 +362,10 @@ def format_wakeup_prompt(evt: dict) -> str | None: evt_type = evt.get("type", "completion") sid = str(evt.get("session_id") or "").strip() cmd = str(evt.get("command") or "").strip() + # The current server-side wakeup drain drops global watch-overflow events + # before this formatter because they intentionally carry no session_key. + # Keep this branch defensive so any future routable overflow summary is not + # mis-rendered as a fake process completion. if evt_type in {"watch_overflow_tripped", "watch_overflow_released"}: msg = str(evt.get("message") or "").strip() return f"[IMPORTANT: {msg}]" if msg else None diff --git a/tests/test_background_process_wakeup_format.py b/tests/test_background_process_wakeup_format.py index cb8368a1d..16e2bcf13 100644 --- a/tests/test_background_process_wakeup_format.py +++ b/tests/test_background_process_wakeup_format.py @@ -5,11 +5,35 @@ def test_format_wakeup_prompt_skips_empty_event(): assert format_wakeup_prompt({}) is None +def test_format_wakeup_prompt_skips_non_dict_event(): + assert format_wakeup_prompt(None) is None + assert format_wakeup_prompt(42) is None + + def test_format_wakeup_prompt_skips_unknown_event_type(): evt = {"type": "unknown_event", "message": "do not inject me"} assert format_wakeup_prompt(evt) is None +def test_format_wakeup_prompt_handles_watch_disabled(): + evt = { + "type": "watch_disabled", + "session_id": "proc_abc", + "session_key": "webui-session", + "command": "tail -f log", + "message": "Watch patterns disabled for process proc_abc.", + } + assert ( + format_wakeup_prompt(evt) + == "[IMPORTANT: Watch patterns disabled for process proc_abc.]" + ) + + +def test_format_wakeup_prompt_skips_blank_watch_disabled(): + assert format_wakeup_prompt({"type": "watch_disabled"}) is None + assert format_wakeup_prompt({"type": "watch_disabled", "message": ""}) is None + + def test_format_wakeup_prompt_handles_watch_overflow_tripped(): evt = { "type": "watch_overflow_tripped",