Skip to content

fix(cron): treat an explicit stream error chunk as a delivery failure - #1899

Closed
sclfcz wants to merge 1 commit into
TencentCloud:developfrom
sclfcz:fix/cron-delivery-error
Closed

sclfcz wants to merge 1 commit into
TencentCloud:developfrom
sclfcz:fix/cron-delivery-error

Conversation

@sclfcz

@sclfcz sclfcz commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #1881

问题

CronDeliveryService._deliver_agent 处理了 token/delta 与 hitl_required,但没有记录显式 error chunk:

async for chunk in self._agent_manager.stream(command.agent_id, request):
    ...
    if kind in ("token", "delta"):
        parts.append(...)
    elif kind == "hitl_required":
        interaction_required = True
if interaction_required:
    raise RuntimeError("cron agent run requires user interaction")
outbound = strip_thinking("".join(parts)).strip()
if not outbound:
    raise RuntimeError("cron agent run produced no visible response")

于是当 stream 先输出文本、再 yield 一个 {"type": "error"}、然后正常结束迭代时,outbound 非空 → 成功路径照常执行(record_turn_usage + push_session_text + 成功通知)→ 失败的运行被当作完成投递。

(本报告只限定「error 作为 chunk 返回」这一情形,不涉及生成器直接 raise。)

改动

在 chunk 分支里记录显式流错误,并在用量与成功通知之前抛错;finally 里的轨迹落库保持不变:

elif kind == "error":
    stream_error = str(chunk.get("message") or "cron agent stream failed")
...
if stream_error is not None:
    raise RuntimeError(stream_error)

测试

在 tests/unit/cron/test_cron_delivery.py 里追加(沿用该文件既有的 cron delivery fixture 与 _stream 替身写法):

  • 部分文本 → error:必须抛 RuntimeError("synthetic failure")、不得 push、且轨迹里仍投影了 prompt(与既有 test_agent_empty_reply_does_not_push 同构);
  • 只有 error:同样抛错且不 push;
  • 对照:正常文本:没有 error chunk 时仍照常 push(行为不变)。

pytest tests/unit/cron/test_cron_delivery.py -k "stream_error or error_only or plain_text" → 3 passed;把 error 分支与抛错去掉后,恰好第一条失败、其余两条通过。

备注

ruff check src tests 与 ruff format --check src tests 均通过。附件投递缺失是另一个问题(#1880),按报告建议分开修。

_deliver_agent handled token/delta and hitl_required but ignored error chunks, so a
stream that emitted partial text and then failed still satisfied the success path
and the failed run was pushed as a completed delivery. Record the explicit error
and raise before the usage/success notification, keeping the trajectory write in
the finally block.
@jubaoliang jubaoliang closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants