• wwwillchen-bot's avatar
    feat: ensure local agent completes todos before ending turn (#2601) · 54444ddf
    wwwillchen-bot 提交于
    ## 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: 's avatarWill Chen <willchen90@gmail.com>
    Co-authored-by: 's avatarClaude Opus 4.5 <noreply@anthropic.com>
    54444ddf
local_agent_todo_followup.spec.ts_after-todo-followup.txt 311 Bytes