feat: ensure local agent completes todos before ending turn (#2601)
## Summary
- When a local agent ends its turn with incomplete todos (pending or
in_progress), a reminder message is now injected telling it to continue
and complete the remaining tasks
- This only happens once per turn to avoid infinite loops
- Added `hasIncompleteTodos()` and `buildTodoReminderMessage()` helpers
to prepare_step_utils.ts
- Added `TodoReminderState` to track whether a reminder has already been
sent this turn
Fixes #2600
## Test plan
- Unit tests added for:
- `hasIncompleteTodos()` - correctly detects pending/in_progress todos
- `buildTodoReminderMessage()` - builds proper reminder message listing
incomplete todos
- `prepareStepMessages()` with todoContext:
- Injects reminder when agent finishes with incomplete todos
- Does not inject reminder when already reminded this turn
- Does not inject reminder when all todos are completed
- Does not inject reminder when agent has pending tool calls
- Combines reminder with existing injected messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- devin-review-badge-begin -->
---
<a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2601"
target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
</picture>
</a>
<!-- devin-review-badge-end -->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Ensures the local agent completes remaining todos before ending a turn
by running a one-time outer-loop follow-up pass that adds a reminder.
The reminder is not persisted. Meets #2600.
- **New Features**
- Outer-loop detection via shouldRunTodoFollowUpPass: runs one follow-up
pass when the final step has no tool calls and incomplete todos remain;
skips in read-only and plan modes.
- Helpers hasIncompleteTodos() and buildTodoReminderMessage();
multi-pass E2E fixture and test; fake LLM server scans all user messages
and counts todo reminders to drive passes.
- **Refactors**
- Removed inner-loop reminder injection from prepareStepMessages; tests
cleaned up.
- Restructured local_agent_handler into a controlled pass loop with
createdAt guards, baseMessageHistoryCount and compaction state reset
each pass, AI messages persisted across passes, and synthetic todo
reminders excluded from aiMessagesJson; updated compaction test to
include toolCalls in mock steps.
<sup>Written for commit 70b9c5a6595c5b024d25665e785d93dd77a3076f.
Summary will update on new commits.</sup>
<!-- End of auto-generated description by cubic. -->
---------
Co-authored-by:
Will Chen <willchen90@gmail.com>
Co-authored-by:
Claude Opus 4.5 <noreply@anthropic.com>
正在显示
请
注册
或者
登录
后发表评论