deerflow2/backend/packages/harness/deerflow/agents
Octopus e4f896e90d
fix(todo-middleware): prevent premature agent exit with incomplete todos (#2135)
* fix(todo-middleware): prevent premature agent exit with incomplete todos

When plan mode is active (is_plan_mode=True), the agent occasionally
exits the loop and outputs a final response while todo items are still
incomplete. This happens because the routing edge only checks for
tool_calls, not todo completion state.

Fixes #2112

Add an after_model override to TodoMiddleware with
@hook_config(can_jump_to=["model"]). When the model produces a
response with no tool calls but there are still incomplete todos, the
middleware injects a todo_completion_reminder HumanMessage and returns
jump_to=model to force another model turn. A cap of 2 reminders
prevents infinite loops when the agent cannot make further progress.

Also adds _completion_reminder_count() helper and 14 new unit tests
covering all edge cases of the new after_model / aafter_model logic.

* Remove unnecessary blank line in test file

* Fix runtime argument annotation in before_model

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 11:11:26 +08:00
..
checkpointer Move async SQLite mkdir off the event loop (#1921) 2026-04-07 10:47:20 +08:00
lead_agent feat(dx): Setup Wizard + doctor command — closes #2030 (#2034) 2026-04-10 17:43:39 +08:00
memory feat: switch memory updater to async LLM calls (#2138) 2026-04-14 11:10:42 +08:00
middlewares fix(todo-middleware): prevent premature agent exit with incomplete todos (#2135) 2026-04-14 11:11:26 +08:00
__init__.py fix(skill): make skill prompt cache refresh nonblocking (#1924) 2026-04-07 10:50:34 +08:00
factory.py style: format unformatted files and add .omc/ to prettierignore (#1539) 2026-03-29 16:45:31 +08:00
features.py feat: add create_deerflow_agent SDK entry point (Phase 1) (#1203) 2026-03-29 15:31:18 +08:00
thread_state.py refactor: split backend into harness (deerflow.*) and app (app.*) (#1131) 2026-03-14 22:55:52 +08:00