• Mohamed Aziz Mejri's avatar
    Persist todos across chat turns (#2713) · dd7718f3
    Mohamed Aziz Mejri 提交于
    ## Summary
    Add persistence layer for todos so they survive across multiple turns in
    a chat session. Todos are now saved to disk after each update and
    automatically loaded and injected into the conversation context when a
    new turn begins.
    
    ## Key Changes
    - **New module `todo_persistence.ts`**: Provides utilities to save,
    load, and delete todo JSON files stored in `.dyad/todos/<chatId>.json`
      - `getTodosFilePath()`: Constructs the file path for a chat's todos
    - `saveTodos()`: Persists todos to disk with metadata (updatedAt
    timestamp)
    - `loadTodos()`: Loads previously saved todos, gracefully handling
    missing or corrupted files
      - `deleteTodos()`: Removes the todos file when all todos are completed
    
    - **Updated `local_agent_handler.ts`**: 
      - Load persisted todos at the start of each turn
    - Emit loaded todos to the renderer immediately so the UI reflects them
    - Initialize the agent context with persisted todos instead of an empty
    array
    - Inject a synthetic system message reminding the LLM of incomplete
    todos from the previous turn, following the same pattern as existing
    todo reminder logic
      - Ensure `.dyad/` directory is gitignored (idempotent operation)
    
    - **Updated `update_todos.ts`**:
      - Persist todos to disk after each tool execution
      - Delete the todos file when all todos are marked as completed
    
    ## Implementation Details
    - Todos are stored as JSON with an `updatedAt` timestamp for potential
    future use
    - File I/O errors are logged as warnings but don't interrupt the agent
    flow (graceful degradation)
    - The synthetic message injection for persisted todos only occurs if
    there are incomplete todos, avoiding unnecessary context pollution
    - The `.dyad/` gitignore step is idempotent and aligns with existing
    patterns in the codebase
    
    <!-- devin-review-badge-begin -->
    
    ---
    
    <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2713"
    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 -->
    
    ---------
    Co-authored-by: 's avatarClaude <noreply@anthropic.com>
    Co-authored-by: 's avatarMohamed Aziz Mejri <mohamedazizmejri@Mohameds-Mac-mini.local>
    dd7718f3
context_compaction.spec.ts 3.0 KB