From 4372d1b6ba0dbd45b2914194a28d3301510aa0c5 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Wed, 24 Sep 2025 20:19:57 -0600 Subject: [PATCH 1/5] fix: include initial ask in condense summarization (#8293) --- pr-body.md | 71 +++++++++++++++++++++++ src/core/condense/__tests__/index.spec.ts | 26 +++++++++ src/core/condense/index.ts | 4 +- 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 pr-body.md diff --git a/pr-body.md b/pr-body.md new file mode 100644 index 00000000000..6951b687aa5 --- /dev/null +++ b/pr-body.md @@ -0,0 +1,71 @@ + + +### Related GitHub Issue + +Closes: #8293 + +### Roo Code Task Context (Optional) + +_No Roo Code task context for this PR_ + +### Description + +Condense currently preserves the initial user message visually but excludes it from the LLM's summarization input, causing summaries to omit the original ask. This leads to resume re-answering the initial ask instead of continuing the current work. This PR ensures the initial ask is included in the condense summarization input and hardens the prompt to always capture it. + +### Changes Made + +- Include the original first user message in LLM summarization input by changing the slice from messages.slice(1, -N_MESSAGES_TO_KEEP) to messages.slice(0, -N_MESSAGES_TO_KEEP) in [src/core/condense/index.ts](src/core/condense/index.ts). +- Harden SUMMARY_PROMPT to explicitly require the initial user ask be included, in [src/core/condense/index.ts](src/core/condense/index.ts). +- Add a unit test to assert the initial ask is present in the summarization input when no prior summary exists: [src/core/condense/**tests**/index.spec.ts](src/core/condense/__tests__/index.spec.ts). + +### Test Procedure + +- Run focused tests: + +```bash +cd src +npx vitest run core/condense/__tests__/index.spec.ts core/condense/__tests__/condense.spec.ts +``` + +- Run full test suite: + +```bash +cd src +npx vitest run +``` + +All tests pass locally. + +### Verification of Acceptance Criteria + +- [x] Summaries include the initial user ask so task resume maintains correct context. +- [x] Applies to manual condense flow (Task -> summarizeConversation) and automatic condense flow (sliding window -> summarizeConversation when thresholds trigger). +- [x] Guard ensures new context tokens do not exceed previous, preserving safety. + +### Pre-Submission Checklist + +- [x] Issue Linked +- [x] Scope focused on linked issue +- [x] Self-review completed +- [x] Tests added/updated and passing +- [x] Documentation impact considered +- [x] No breaking changes + +### Screenshots / Videos + +_No UI changes in this PR_ + +### Documentation Updates + +- [x] No documentation updates are required. + +### Additional Notes + +- Minimal, targeted change; fallback behavior and token safety rails unchanged. +- Potential slight increase in summarization input length is bounded and protected by existing safeguards. + +### Get in Touch + +@roomote diff --git a/src/core/condense/__tests__/index.spec.ts b/src/core/condense/__tests__/index.spec.ts index d86b500f902..6a03298aa69 100644 --- a/src/core/condense/__tests__/index.spec.ts +++ b/src/core/condense/__tests__/index.spec.ts @@ -283,6 +283,32 @@ describe("summarizeConversation", () => { const mockCallArgs = (maybeRemoveImageBlocks as Mock).mock.calls[0][0] as any[] expect(mockCallArgs[mockCallArgs.length - 1]).toEqual(expectedFinalMessage) }) + it("should include the original first user message in summarization input", async () => { + const messages: ApiMessage[] = [ + { role: "user", content: "Initial ask", ts: 1 }, + { role: "assistant", content: "Ack", ts: 2 }, + { role: "user", content: "Follow-up", ts: 3 }, + { role: "assistant", content: "Response", ts: 4 }, + { role: "user", content: "More", ts: 5 }, + { role: "assistant", content: "Later", ts: 6 }, + { role: "user", content: "Newest", ts: 7 }, + ] + + await summarizeConversation(messages, mockApiHandler, defaultSystemPrompt, taskId, DEFAULT_PREV_CONTEXT_TOKENS) + + const mockCallArgs = (maybeRemoveImageBlocks as Mock).mock.calls[0][0] as any[] + + // Expect the original first user message to be present in the messages sent to the summarizer + const hasInitialAsk = mockCallArgs.some( + (m) => + m.role === "user" && + (typeof m.content === "string" + ? m.content === "Initial ask" + : Array.isArray(m.content) && + m.content.some((b: any) => b.type === "text" && b.text === "Initial ask")), + ) + expect(hasInitialAsk).toBe(true) + }) it("should calculate newContextTokens correctly with systemPrompt", async () => { const messages: ApiMessage[] = [ diff --git a/src/core/condense/index.ts b/src/core/condense/index.ts index 166a8ba4cad..63c75ca76a2 100644 --- a/src/core/condense/index.ts +++ b/src/core/condense/index.ts @@ -17,7 +17,7 @@ This summary should be thorough in capturing technical details, code patterns, a Your summary should be structured as follows: Context: The context to continue the conversation with. If applicable based on the current task, this should include: - 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user. This should be written to allow someone to be able to follow the general overarching conversation flow. + 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user, and explicitly include the conversation's initial user ask verbatim or a precise summary so the result can stand alone. This should be written to allow someone to be able to follow the general overarching conversation flow. 2. Current Work: Describe in detail what was being worked on prior to this request to summarize the conversation. Pay special attention to the more recent messages in the conversation. 3. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for continuing with this work. 4. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes. @@ -104,7 +104,7 @@ export async function summarizeConversation( // Always preserve the first message (which may contain slash command content) const firstMessage = messages[0] // Get messages to summarize, excluding the first message and last N messages - const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(1, -N_MESSAGES_TO_KEEP)) + const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(0, -N_MESSAGES_TO_KEEP)) if (messagesToSummarize.length <= 1) { const error = From ff709f890a2def5d54232f623499c9a48569ae2d Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Wed, 24 Sep 2025 21:46:16 -0600 Subject: [PATCH 2/5] fix: include initial user ask in condense summarization --- pr-body.md | 71 ------------------------------------------------------ 1 file changed, 71 deletions(-) delete mode 100644 pr-body.md diff --git a/pr-body.md b/pr-body.md deleted file mode 100644 index 6951b687aa5..00000000000 --- a/pr-body.md +++ /dev/null @@ -1,71 +0,0 @@ - - -### Related GitHub Issue - -Closes: #8293 - -### Roo Code Task Context (Optional) - -_No Roo Code task context for this PR_ - -### Description - -Condense currently preserves the initial user message visually but excludes it from the LLM's summarization input, causing summaries to omit the original ask. This leads to resume re-answering the initial ask instead of continuing the current work. This PR ensures the initial ask is included in the condense summarization input and hardens the prompt to always capture it. - -### Changes Made - -- Include the original first user message in LLM summarization input by changing the slice from messages.slice(1, -N_MESSAGES_TO_KEEP) to messages.slice(0, -N_MESSAGES_TO_KEEP) in [src/core/condense/index.ts](src/core/condense/index.ts). -- Harden SUMMARY_PROMPT to explicitly require the initial user ask be included, in [src/core/condense/index.ts](src/core/condense/index.ts). -- Add a unit test to assert the initial ask is present in the summarization input when no prior summary exists: [src/core/condense/**tests**/index.spec.ts](src/core/condense/__tests__/index.spec.ts). - -### Test Procedure - -- Run focused tests: - -```bash -cd src -npx vitest run core/condense/__tests__/index.spec.ts core/condense/__tests__/condense.spec.ts -``` - -- Run full test suite: - -```bash -cd src -npx vitest run -``` - -All tests pass locally. - -### Verification of Acceptance Criteria - -- [x] Summaries include the initial user ask so task resume maintains correct context. -- [x] Applies to manual condense flow (Task -> summarizeConversation) and automatic condense flow (sliding window -> summarizeConversation when thresholds trigger). -- [x] Guard ensures new context tokens do not exceed previous, preserving safety. - -### Pre-Submission Checklist - -- [x] Issue Linked -- [x] Scope focused on linked issue -- [x] Self-review completed -- [x] Tests added/updated and passing -- [x] Documentation impact considered -- [x] No breaking changes - -### Screenshots / Videos - -_No UI changes in this PR_ - -### Documentation Updates - -- [x] No documentation updates are required. - -### Additional Notes - -- Minimal, targeted change; fallback behavior and token safety rails unchanged. -- Potential slight increase in summarization input length is bounded and protected by existing safeguards. - -### Get in Touch - -@roomote From e5353cf0adbf704e2007de00c0b42bf7f0c815f9 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Wed, 24 Sep 2025 21:52:38 -0600 Subject: [PATCH 3/5] fix: refine summary structure by removing redundancy in previous conversation description --- src/core/condense/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/condense/index.ts b/src/core/condense/index.ts index 63c75ca76a2..624edf1f658 100644 --- a/src/core/condense/index.ts +++ b/src/core/condense/index.ts @@ -17,8 +17,7 @@ This summary should be thorough in capturing technical details, code patterns, a Your summary should be structured as follows: Context: The context to continue the conversation with. If applicable based on the current task, this should include: - 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user, and explicitly include the conversation's initial user ask verbatim or a precise summary so the result can stand alone. This should be written to allow someone to be able to follow the general overarching conversation flow. - 2. Current Work: Describe in detail what was being worked on prior to this request to summarize the conversation. Pay special attention to the more recent messages in the conversation. + 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user. This should be written to allow someone to be able to follow the general overarching conversation flow. 2. Current Work: Describe in detail what was being worked on prior to this request to summarize the conversation. Pay special attention to the more recent messages in the conversation. 3. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for continuing with this work. 4. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes. 5. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts. From ac00eef5159c5030fdf016f4acfed29db81fbc8b Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Wed, 24 Sep 2025 22:29:04 -0600 Subject: [PATCH 4/5] Update src/core/condense/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/core/condense/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/condense/index.ts b/src/core/condense/index.ts index 624edf1f658..ebd30d76828 100644 --- a/src/core/condense/index.ts +++ b/src/core/condense/index.ts @@ -102,7 +102,7 @@ export async function summarizeConversation( // Always preserve the first message (which may contain slash command content) const firstMessage = messages[0] - // Get messages to summarize, excluding the first message and last N messages + // Get messages to summarize, including the first message and excluding the last N messages const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(0, -N_MESSAGES_TO_KEEP)) if (messagesToSummarize.length <= 1) { From 100cdad55ab8879d9fc581e6972fe53aec9177e4 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Wed, 24 Sep 2025 22:56:28 -0600 Subject: [PATCH 5/5] Update src/core/condense/index.ts Co-authored-by: Matt Rubens --- src/core/condense/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/condense/index.ts b/src/core/condense/index.ts index ebd30d76828..86cfa7ab1e5 100644 --- a/src/core/condense/index.ts +++ b/src/core/condense/index.ts @@ -17,7 +17,8 @@ This summary should be thorough in capturing technical details, code patterns, a Your summary should be structured as follows: Context: The context to continue the conversation with. If applicable based on the current task, this should include: - 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user. This should be written to allow someone to be able to follow the general overarching conversation flow. 2. Current Work: Describe in detail what was being worked on prior to this request to summarize the conversation. Pay special attention to the more recent messages in the conversation. + 1. Previous Conversation: High level details about what was discussed throughout the entire conversation with the user. This should be written to allow someone to be able to follow the general overarching conversation flow. + 2. Current Work: Describe in detail what was being worked on prior to this request to summarize the conversation. Pay special attention to the more recent messages in the conversation. 3. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for continuing with this work. 4. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes. 5. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.