deerflow2/backend/app/channels
Nan Gao dcc6f1e678
feat(loop-detection): defer warning injection (#2752)
* fix(loop-detection): defer warn injection to wrap_model_call

The warn branch in LoopDetectionMiddleware injected a HumanMessage
into state from after_model. The tools node had not yet produced
ToolMessage responses to the previous AIMessage(tool_calls=...), so
the new HumanMessage landed *between* the assistant's tool_calls and
their responses. OpenAI/Moonshot reject the next request with
"tool_call_ids did not have response messages" because their
validators require tool_calls to be followed immediately by tool
messages.

Detection now runs in after_model as before, but only enqueues the
warning into a per-thread list. Injection happens in wrap_model_call,
where every prior ToolMessage is already present in request.messages.
The warning is appended at the end as HumanMessage(name="loop_warning")
— pairing intact, AIMessage semantics untouched, no SystemMessage
issues for Anthropic.

Closes #2029, addresses #2255 #2293 #2304 #2511.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(channels): remove loop warning display filter

* feat(loop-detection): scope pending warnings by run

* docs(loop-detection): update docs

* test(loop-detection): assert deferred warnings are queued

* fix(loop-detection): cap transient warning state

* docs: update docs

* add async awrap_model_call test coverage

* docs(loop-detection): document transient warnings

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 14:36:07 +08:00
..
__init__.py Refactor DeerFlow to use Gateway's LangGraph-compatible API 2026-04-26 20:38:34 +08:00
base.py feat(channels): add DingTalk channel integration (#2628) 2026-04-30 11:25:33 +08:00
commands.py fix: avoid treating Feishu file paths as commands (#1654) 2026-04-01 23:23:00 +08:00
dingtalk.py feat(channels): add DingTalk channel integration (#2628) 2026-04-30 11:25:33 +08:00
discord.py feat(channels): enhance Discord with mention-only mode, thread routing, and typing indicators (#2842) 2026-05-15 22:30:05 +08:00
feishu.py feat(channels): add DingTalk channel integration (#2628) 2026-04-30 11:25:33 +08:00
manager.py feat(loop-detection): defer warning injection (#2752) 2026-05-21 14:36:07 +08:00
message_bus.py refactor: split backend into harness (deerflow.*) and app (app.*) (#1131) 2026-03-14 22:55:52 +08:00
service.py feat(channels): enhance Discord with mention-only mode, thread routing, and typing indicators (#2842) 2026-05-15 22:30:05 +08:00
slack.py fix(channels): accept single slack allowed user (#2481) 2026-04-25 19:40:52 +08:00
store.py refactor: split backend into harness (deerflow.*) and app (app.*) (#1131) 2026-03-14 22:55:52 +08:00
telegram.py Improve Python reliability in channel retries and thread typing (#1776) 2026-04-03 07:50:11 +08:00
wechat.py feat: add WeChat channel integration (#1869) 2026-04-10 20:49:28 +08:00
wecom.py feat(channels): add DingTalk channel integration (#2628) 2026-04-30 11:25:33 +08:00