fix(session): keep todo state out of the system prompt - #209
Merged
Conversation
The legacy session loop rendered SessionTodo.context(...) into the system array on every step. Each todowrite changed that text, so the request after it sent a different system prompt and lost the provider's cached prefix. The task list now rides the last user message as a synthetic reminder, the same way the goal does in SessionReminders.apply, with the same text. The system prompt keeps only the static todo guidance. The loop reviews the list once per step: a todo continuation carries its review into the step it starts instead of reading again. Regression test drives the fake provider through a todowrite and asserts the system messages of the following requests are identical to the first, while the task state appears in the last user message of the next request. Claude-Session: https://claude.ai/code/session_01KAcoL6wpgVEs2ebUrUGpHS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The legacy session loop (
packages/redcode/src/session/prompt.ts) rebuilt thesystemarray every step and includedSessionTodo.context(...), which embeds the live task list. Everytodowritetherefore changed the system prompt and invalidated the provider prompt-cache prefix for the next request. The goal, by contrast, was already re-rendered into the last user message viaSessionReminders.apply, which keeps the system prompt stable.Fix
SessionReminders.applytakes an optionaltodoslist and appendsSessionTodo.context(todos)to the last user message as a synthetic part, right after the goal reminder. Same text as before, so model behaviour is unchanged.todos.reviewonce per step and passes the list to the reminders; thesystemarray keeps only the staticSessionTodo.guidance. A todo continuation carries its review into the step it starts instead of reading again..changeset/todo-reminder-context.md(@reddb-io/redcode: patch).Out of scope on purpose: the daily date line and instruction/MCP/skills inputs are left as they are.
Test
New
packages/redcode/test/session/prompt.test.tscase: the fake provider replies with atodowrite, then text, then a continuation. The test asserts the role-systemmessages of requests 2 and 3 aretoEqualthose of request 1, that the system prompt no longer contains the task-state block, and that request 2's last user message carriesCurrent task state from storage: 0/1 completedwith the task text.No tracked tasks yetreplaced by the task-state block; after the fix it passes.test/session: 513 pass, 0 fail.bun run typecheckclean.https://claude.ai/code/session_01KAcoL6wpgVEs2ebUrUGpHS
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.