fix: handle whitespace-only cron responses

This commit is contained in:
joe102084 2026-05-18 20:08:06 -07:00 committed by Teknium
parent 34f34ba322
commit 6143013f5b
2 changed files with 23 additions and 2 deletions

View file

@ -1842,7 +1842,10 @@ def tick(verbose: bool = True, adapters=None, loop=None) -> int:
# If the agent responded with [SILENT], skip delivery (but
# output is already saved above). Failed jobs always deliver.
deliver_content = final_response if success else f"⚠️ Cron job '{job.get('name', job['id'])}' failed:\n{error}"
should_deliver = bool(deliver_content)
# Treat whitespace-only final responses the same as empty
# responses: do not deliver a blank message, and let the
# empty-response guard below mark the run as a soft failure.
should_deliver = bool(deliver_content.strip())
if should_deliver and success and SILENT_MARKER in deliver_content.strip().upper():
logger.info("Job '%s': agent returned %s — skipping delivery", job["id"], SILENT_MARKER)
should_deliver = False
@ -1858,7 +1861,7 @@ def tick(verbose: bool = True, adapters=None, loop=None) -> int:
# Treat empty final_response as a soft failure so last_status
# is not "ok" — the agent ran but produced nothing useful.
# (issue #8585)
if success and not final_response:
if success and not final_response.strip():
success = False
error = "Agent completed but produced empty response (model error, timeout, or misconfiguration)"

View file

@ -1773,6 +1773,24 @@ class TestSilentDelivery:
save_mock.assert_called_once_with("monitor-job", "# full output")
deliver_mock.assert_not_called()
def test_whitespace_only_response_is_marked_failed_not_delivered(self):
"""Whitespace-only final responses should behave like empty responses."""
with patch("cron.scheduler.get_due_jobs", return_value=[self._make_job()]), \
patch("cron.scheduler.run_job", return_value=(True, "# output", " \n\t ", None)), \
patch("cron.scheduler.save_job_output", return_value="/tmp/out.md"), \
patch("cron.scheduler._deliver_result") as deliver_mock, \
patch("cron.scheduler.mark_job_run") as mark_mock:
from cron.scheduler import tick
tick(verbose=False)
deliver_mock.assert_not_called()
mark_mock.assert_called_once_with(
"monitor-job",
False,
"Agent completed but produced empty response (model error, timeout, or misconfiguration)",
delivery_error=None,
)
class TestBuildJobPromptSilentHint:
"""Verify _build_job_prompt always injects [SILENT] guidance."""