From 5e9116db952a3c6cc871f038d589a1a5b976465a Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Mon, 13 Jul 2026 01:28:48 +0000 Subject: [PATCH] Release exp: no false no-response after final tool (#5990, closes #5686). Thanks @jtstothard. Final-answer detection understands structured content parts (text after tool-use boundaries); genuine empty completions still show no_response; terminal provider error still surfaces as apperror (never masked). Codex SAFE round2 (3 precedence findings fixed), stream-gate GREEN all modes. Maintainer: updated the #5940 source- assert test for the _captured_terminal_failure rename. --- CHANGELOG.md | 2 ++ tests/test_issue5940_terminal_error_surfaced.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb61aad8..97944c7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Fixed +- **No more false "No response from provider" after a completed answer that used tools.** When an assistant turn ended with a real final answer delivered as structured content following tool calls (common with reasoning models and multi-tool turns), the completion detector could miss the final text and render a spurious "No response from provider" card under the finished reply. Final-answer detection now understands structured content parts (text after tool-use boundaries), while genuine empty completions still correctly show the no-response notice, and a real terminal provider error still surfaces as an error (never masked as a final answer). Thanks @jtstothard. (#5990, #5686) + - **Cron unread ("Tasks") dots are now scoped to the active profile — no more ghost dots after switching.** In multi-profile setups, the session-sidebar unread dot and the Tasks badge could keep showing a cron completion from a *different* profile after you switched, and the count could resurrect from a stale poll. Cron completion markers now carry their source + owning profile, are cleared for the profile you switch away from (including legacy/untagged markers), and a previous-profile poll response can no longer restore a stale unread. Non-cron completion unread and the current profile's own cron unread are preserved; default ↔ renamed-root aliases are treated as the same profile so a root cron marker is neither wrongly cleared nor wrongly kept. Thanks @jbbottoms. (#5975, #5960) - **The Docker "manual update" banner instruction is now localized.** On Docker/no-git deployments the update banner shows the manual update command; that guidance string was hardcoded in English. It now goes through the i18n system, so it renders in the active language (English fallback where a translation isn't present yet). Thanks @jbbottoms. (#5973, #5959) diff --git a/tests/test_issue5940_terminal_error_surfaced.py b/tests/test_issue5940_terminal_error_surfaced.py index b3769693..9eefdfbd 100644 --- a/tests/test_issue5940_terminal_error_surfaced.py +++ b/tests/test_issue5940_terminal_error_surfaced.py @@ -76,5 +76,6 @@ def test_captured_terminal_error_seeds_last_err_on_completion(): """At turn completion, the captured terminal error must seed `_last_err` when the agent/result carried no error — so the classifier runs on the real cause instead of silent_failure=True.""" - assert "if not _last_err and _captured_terminal_error[0]:" in STREAMING_PY + assert "_captured_terminal_failure = bool(_captured_terminal_error[0])" in STREAMING_PY + assert "if not _last_err and _captured_terminal_failure:" in STREAMING_PY assert "_last_err = _captured_terminal_error[0]" in STREAMING_PY