Repository navigation
Conversation
The background wakeup path runs the same step_until_done loop as the cron path but never checked runner.state, so a run that failed inside the runner (e.g. malformed function call at max steps) was persisted as a normal "finished" history note and the error never surfaced. Mirror the cron guard from AstrBotDevs#9980: raise with the completion detail so the failure is logged by the background task wrapper instead of being recorded as a success. The failover test pinned the old asymmetry (only cron raised); extend the expectation to both wakeup entrypoints and add a regression test that an ERROR-state result run raises and skips persist_agent_history.
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="astrbot/core/astr_agent_tool_exec.py" line_range="658" />
<code_context>
# agent will send message to user via using tools
pass
llm_resp = runner.get_final_llm_resp()
+ if runner.state == AgentState.ERROR:
+ # The result run failed (e.g. malformed function call at max steps)
+ # but no exception escapes the runner; without this the failure was
</code_context>
<issue_to_address>
**Delivered messages disappear from history**
When the background agent sends a user-facing message during one step and enters ERROR on a later step, `_wake_main_agent_for_background_result` raises before `persist_agent_history` runs, so the already-delivered message is omitted from conversation history and later turns can repeat or contradict it.
Persist the delivered message before raising for the background agent's ERROR state.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: astrbot/core/astr_agent_tool_exec.py:658
| # agent will send message to user via using tools | ||
| pass | ||
| llm_resp = runner.get_final_llm_resp() | ||
| if runner.state == AgentState.ERROR: |
There was a problem hiding this comment.
🟡 Medium · Delivered messages disappear from history
When the background agent sends a user-facing message during one step and enters ERROR on a later step, _wake_main_agent_for_background_result raises before persist_agent_history runs, so the already-delivered message is omitted from conversation history and later turns can repeat or contradict it.
Persist the delivered message before raising for the background agent's ERROR state.
Prompt for AI agents
In `astrbot/core/astr_agent_tool_exec.py` at line 658:
**Delivered messages disappear from history**
When the background agent sends a user-facing message during one step and enters ERROR on a later step, `_wake_main_agent_for_background_result` raises before `persist_agent_history` runs, so the already-delivered message is omitted from conversation history and later turns can repeat or contradict it.
Persist the delivered message before raising for the background agent's ERROR state.|
On the sourcery blocking finding (delivered messages allegedly disappearing from history): I checked the persistence path, and the mechanism it assumes does not exist.
What the raise does skip on failure is the synthetic "finished" note, and that is the point of this PR. Before it, a failed result run was persisted as a normal finished note with the runner's error text appended as if it were the result ("I finished the task, here is the result: "), which is the exact shape #9980 fixed on the cron path. The failure now surfaces as an exception from the wake instead of being written into the user's conversation as a fake success. If the project would rather record failures inside conversation history too, that is a product decision and a small follow-up; I kept the #9987 semantics on purpose so both wake paths agree. |
Problem
Sibling of #9980. When a background task finishes,
_wake_main_agent_for_background_resultbuilds a main agent to process and deliver the result. That path runs the samestep_until_doneloop as the cron wakeup, but never checksrunner.stateafterwards.A run that fails inside the runner (e.g. a malformed function call at max steps, or every provider failing) raises no exception. The cron path got a guard in #9987 that raises so the job is recorded as failed; the background twin still falls through and:
[BackgroundTask] ... finishedhistory note, appending the runner's error text as if it were a result ("I finished the task, here is the result: "), andFix
Mirror the cron guard: after the loop, if
runner.state == AgentState.ERROR, raiseRuntimeErrorwith the completion text as detail. The raise propagates to the_run_in_background/_run_handoff_in_backgroundwrappers, which already log the failure with the task id, instead of recording a misleading success in history.Tests
persist_agent_historyis not called.test_proactive_agent_uses_session_fallback_modelspinned the old asymmetry (pytest.raisesonly for the cron entrypoint even though it parametrizes both entrypoints); extended the expectation to both paths via the shared message substring.test_astr_agent_tool_exec.pynow declarestate = AgentState.DONEto match the real runner interface.Local:
pytest tests/unit1527 passed, ruff format/check clean.Summary by Sourcery
Propagate failures from background result agent runs so errored tasks are reported instead of presented as successful completions.
Bug Fixes:
Tests: