-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Intelligent Context Condensation v2 #10873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Re-review in progress for
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
c0fa042 to
859fb14
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary
- Condense is now non-destructive: older messages are tagged with condenseParent and filtered via getEffectiveApiHistory(), while rewind/edit semantics keep the original message boundaries.
- New API-only shaping merges consecutive user turns via mergeConsecutiveApiMessages() to reduce token overhead without mutating stored history.
- Slash-command mention parsing now returns slashCommandHelp separately and processUserContentMentions() appends it as a dedicated text block (instead of mixing it into the main user text).
Tested
- cd src && npx vitest run core/task/tests/mergeConsecutiveApiMessages.spec.ts core/condense/tests/condense.spec.ts core/condense/tests/index.spec.ts core/condense/tests/rewind-after-condense.spec.ts core/mentions/tests/processUserContentMentions.spec.ts tests/command-mentions.spec.ts core/webview/tests/webviewMessageHandler.delete.spec.ts
- cd apps/web-roo-code && npm run lint && npm run check-types
- cd apps/web-evals && npm run lint && npm run check-types && npx vitest run
bb3fb35 to
9ea6b3f
Compare
9ea6b3f to
06f2a8b
Compare
6a47719 to
17d6649
Compare
a654a9a to
a64318e
Compare
f56bced to
dca5f66
Compare
…iveApiHistory - Update comment to accurately describe variable content structure (optional command block) - Remove redundant O(n*m) loop that duplicated the .has() check for condenseParent filtering
… simple instruction as system prompt
…clearer sections - Add <analysis> step before summary for structured thinking - Restructure sections for clarity and completeness - Add new sections: 'Errors and fixes', 'All user messages' - Separate 'Pending Tasks' and 'Optional Next Step' sections - Add example output formatting with XML-style tags - Include instructions for handling additional summarization instructions
…oduction Replace task-specific summarization instruction with a more neutral AI assistant prompt that describes the assistant's role for summarization.
- Fix orphan tool_result filtering after fresh start condensation - Add CRITICAL instructions to SUMMARY_PROMPT and CONDENSE template to prevent tool calls during condensing - Inject synthetic tool_results for orphan tool_calls before condensing - Pass tools/metadata to condensation API call - Use standard ErrorRow with Details button for condensation errors - Remove stack trace from error details - Separate summary content into multiple text blocks - Update tests for fresh start model behavior
- Add missing await to this.say() in condenseContext() error path to prevent race conditions with persistence/UI updates - Update comment at line 4075 to accurately reflect that mergeConsecutiveApiMessages() excludes summary messages
The mergeConsecutiveApiMessages function now allows merging a regular user message that follows a summary message. Since this is API-only shaping (storage is unaffected), rewind semantics remain intact. - Remove !prev.isSummary guard to allow merge INTO summary - Keep !msg.isSummary guard to prevent merging a summary INTO something - Update tests to reflect new expected behavior
32e7ab5 to
757dfcf
Compare
webview-ui/src/components/chat/context-management/CondensationErrorRow.tsx
Outdated
Show resolved
Hide resolved
41f43bc to
757dfcf
Compare
Remove unused functions and types that were part of the old condensation model: - getKeepMessagesWithToolBlocks function - KeepMessagesResult type - N_MESSAGES_TO_KEEP constant - hasToolResultBlocks helper - getToolResultBlocks helper - findToolUseBlockById helper - getReasoningBlocks helper These were relics of the old model that kept trailing N messages after the summary. The fresh start model no longer needs them.
- Remove unnecessary JSON encoding in Task.ts when calling say() for condense_context_error - now passes error message directly - Simplify CondensationErrorRow component: remove JSON parsing logic and ErrorRow dependency, just display errorText directly with inline styling - Reduces code complexity while maintaining the same user-facing behavior
| cost, | ||
| newContextTokens = 0, | ||
| error, | ||
| errorDetails, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Task.condenseContext(), summarizeConversation() returns errorDetails, but the error path drops it and only calls say("condense_context_error", error). This effectively hides the detailed API diagnostics (status/body/stack) that were intentionally captured, making condense failures much harder to debug.
Fix it with Roo Code or mention @roomote and request a fix.
When a user sets a custom condensing prompt, it should control what instructions are sent to the model. Previously, the code used the custom prompt only for the system prompt while the user message content was hardcoded to supportPrompt.default.CONDENSE. Now the custom prompt (or default CONDENSE) is used as the finalRequestMessage content, ensuring user customization is respected. Updated tests to verify the custom prompt appears in the user message.
|
Yes, this was an unintentional bug. I've pushed a fix (commit 7a361ae) that now properly uses the Before: The custom prompt was only used for the system prompt, while the user message was hardcoded to After: The custom prompt (or default) is now used as the |
| cost, | ||
| newContextTokens = 0, | ||
| error, | ||
| errorDetails, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Task.condenseContext(), summarizeConversation() now returns errorDetails, but the error branch drops it and only displays error. This makes condense failures harder to debug; consider threading errorDetails into the UI payload (e.g., include it in the condense_context_error message so the webview can show/copy it).
Fix it with Roo Code or mention @roomote and request a fix.
Summary
This PR implements a "Fresh Start Model" for context condensation - a fundamental architectural change where summary messages transition from
assistantrole touserrole. This simplifies the condensation architecture by eliminating several workarounds while introducing targeted mechanisms for command preservation and orphan cleanup.What Changed
Fresh Start Model
The core change: summary messages now have
role: "user"instead ofrole: "assistant".Before:
assistantmessage inserted before kept messagesAfter:
usermessage placed at the end of message historyCommand Block Preservation
New
extractCommandBlocks()function extracts<command>XML blocks from the original task and injects them into summaries wrapped in<system-reminder>tags. This ensures workflow directives (like/prr #123) survive multiple condensation cycles.Orphan Tool Result Filtering
getEffectiveApiHistory()now filters orphantool_resultblocks that referencetool_useIDs from condensed-away messages. This prevents API validation errors that would occur when tool_result blocks have no matching tool_use.Consecutive User Message Merging
New
mergeConsecutiveApiMessages()utility non-destructively merges consecutive user messages for API requests only. This handles the case where a user summary followed by a user message would create invalid consecutive same-role messages.Slash Command Help Separation
parseMentions()now returnsslashCommandHelpseparately from the maintext. This allows selective extraction of command blocks during condensation while keeping the user's actual message content clean.Improved Error Handling
messageanddetailsfields (JSON structure)CondensationErrorRowuses sharedErrorRowcomponent with copy functionalitycondense_api_failedfor API error messagesRestructured CONDENSE Prompt
Completely rewritten with a highly structured XML format:
Breaking Changes
role: "user"instead ofrole: "assistant"N_MESSAGES_TO_KEEPconstant removedlastMsgTs + 1instead offirstKeptTs - 1Why This Approach
extractCommandBlocks()preserves<command>blocksmergeConsecutiveApiMessages()for API requests onlyErrorRowcomponent integrationDependency Graph
Important
Transition summary messages from
assistanttouserrole for context condensation, simplifying architecture and improving functionality.role: "user"instead ofrole: "assistant".extractCommandBlocks()function to preserve<command>blocks in summaries.getEffectiveApiHistory()filters orphantool_resultblocks.mergeConsecutiveApiMessages()utility merges consecutive user messages for API requests.condense.spec.tsandindex.spec.tsto reflect new behavior.extractCommandBlocks()andmergeConsecutiveApiMessages().N_MESSAGES_TO_KEEPconstant removed.lastMsgTs + 1instead offirstKeptTs - 1.This description was created by
for 7a361ae. You can customize this summary. It will automatically update as commits are pushed.