Skip to content

feat: inject active todos into model context after compaction and session resume #55

@platypusrex

Description

@platypusrex

Problem

Todos persist in SQLite but are never re-injected into the model's context after two critical events:

  1. Context compactiontodo_write/todo_read tool call messages get compacted away. The model loses all knowledge that todos exist. Nothing prompts it to call todo_read.

  2. Session resume — the system prompt includes todo documentation (how to use the tools) but never the actual todo state. The model must independently decide to call todo_read, but nothing tells it active todos exist from a previous turn.

The todos are visible in the sidebar UI (use-session.ts loads them via getTodos), but the model is blind to them after either event.

Root Cause

  • compactSimple and compactWithSummary in src/agent/compaction.ts operate purely on the Message[] array with zero awareness of the todos table
  • buildInitialMessages in src/agent/index.ts constructs [system prompt, ...history, user message] without reading todo state
  • getTodos(sessionId) is called in 4 places — all UI-facing (sidebar refresh). None inject into the model's context window.

Proposed Solution

A. Post-compaction injection (critical)

In src/agent/index.ts (~line 467), after messages.push(...result.messages), check for active todos:

const activeTodos = getTodos(args.sessionId).filter(
  t => t.status === 'pending' || t.status === 'in_progress'
);
if (activeTodos.length > 0) {
  messages.push({
    role: 'system',
    content: `You have ${activeTodos.length} active todos for this session. Call todo_read to review your task list before continuing.`,
  });
}

B. Session resume injection (significant)

In buildInitialMessages or the agent loop entry point, when building messages for a session with active todos, append a system message after history so the model knows to check.

C. Compaction preservation (optional, lower priority)

In shouldPreserve (compaction.ts lines 75-116), recognize todo_write tool calls as high-value messages worth preserving longer in context. This is a softer complement to A — the injection approach is more reliable on its own.

Scope

  • ~30 lines across src/agent/index.ts and src/agent/compaction.ts
  • A and B are the high-value changes
  • C is nice-to-have

Context

Discovered during side panel todo overhaul work on fix/tui-issues. Related to TODO_ENFORCEMENT_SUGGESTIONS.md analysis — the persistence gap is the higher-impact problem compared to prompt enforcement for capable models like GLM-4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions