Skip to content

Commit 4372d1b

Browse files
committed
fix: include initial ask in condense summarization (#8293)
1 parent d3d0967 commit 4372d1b

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

pr-body.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<!--
2+
Thank you for contributing to Roo Code!
3+
-->
4+
5+
### Related GitHub Issue
6+
7+
Closes: #8293
8+
9+
### Roo Code Task Context (Optional)
10+
11+
_No Roo Code task context for this PR_
12+
13+
### Description
14+
15+
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.
16+
17+
### Changes Made
18+
19+
- 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).
20+
- Harden SUMMARY_PROMPT to explicitly require the initial user ask be included, in [src/core/condense/index.ts](src/core/condense/index.ts).
21+
- 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).
22+
23+
### Test Procedure
24+
25+
- Run focused tests:
26+
27+
```bash
28+
cd src
29+
npx vitest run core/condense/__tests__/index.spec.ts core/condense/__tests__/condense.spec.ts
30+
```
31+
32+
- Run full test suite:
33+
34+
```bash
35+
cd src
36+
npx vitest run
37+
```
38+
39+
All tests pass locally.
40+
41+
### Verification of Acceptance Criteria
42+
43+
- [x] Summaries include the initial user ask so task resume maintains correct context.
44+
- [x] Applies to manual condense flow (Task -> summarizeConversation) and automatic condense flow (sliding window -> summarizeConversation when thresholds trigger).
45+
- [x] Guard ensures new context tokens do not exceed previous, preserving safety.
46+
47+
### Pre-Submission Checklist
48+
49+
- [x] Issue Linked
50+
- [x] Scope focused on linked issue
51+
- [x] Self-review completed
52+
- [x] Tests added/updated and passing
53+
- [x] Documentation impact considered
54+
- [x] No breaking changes
55+
56+
### Screenshots / Videos
57+
58+
_No UI changes in this PR_
59+
60+
### Documentation Updates
61+
62+
- [x] No documentation updates are required.
63+
64+
### Additional Notes
65+
66+
- Minimal, targeted change; fallback behavior and token safety rails unchanged.
67+
- Potential slight increase in summarization input length is bounded and protected by existing safeguards.
68+
69+
### Get in Touch
70+
71+
@roomote

src/core/condense/__tests__/index.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,32 @@ describe("summarizeConversation", () => {
283283
const mockCallArgs = (maybeRemoveImageBlocks as Mock).mock.calls[0][0] as any[]
284284
expect(mockCallArgs[mockCallArgs.length - 1]).toEqual(expectedFinalMessage)
285285
})
286+
it("should include the original first user message in summarization input", async () => {
287+
const messages: ApiMessage[] = [
288+
{ role: "user", content: "Initial ask", ts: 1 },
289+
{ role: "assistant", content: "Ack", ts: 2 },
290+
{ role: "user", content: "Follow-up", ts: 3 },
291+
{ role: "assistant", content: "Response", ts: 4 },
292+
{ role: "user", content: "More", ts: 5 },
293+
{ role: "assistant", content: "Later", ts: 6 },
294+
{ role: "user", content: "Newest", ts: 7 },
295+
]
296+
297+
await summarizeConversation(messages, mockApiHandler, defaultSystemPrompt, taskId, DEFAULT_PREV_CONTEXT_TOKENS)
298+
299+
const mockCallArgs = (maybeRemoveImageBlocks as Mock).mock.calls[0][0] as any[]
300+
301+
// Expect the original first user message to be present in the messages sent to the summarizer
302+
const hasInitialAsk = mockCallArgs.some(
303+
(m) =>
304+
m.role === "user" &&
305+
(typeof m.content === "string"
306+
? m.content === "Initial ask"
307+
: Array.isArray(m.content) &&
308+
m.content.some((b: any) => b.type === "text" && b.text === "Initial ask")),
309+
)
310+
expect(hasInitialAsk).toBe(true)
311+
})
286312

287313
it("should calculate newContextTokens correctly with systemPrompt", async () => {
288314
const messages: ApiMessage[] = [

src/core/condense/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This summary should be thorough in capturing technical details, code patterns, a
1717
1818
Your summary should be structured as follows:
1919
Context: The context to continue the conversation with. If applicable based on the current task, this should include:
20-
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.
20+
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.
2121
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.
2222
3. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for continuing with this work.
2323
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(
104104
// Always preserve the first message (which may contain slash command content)
105105
const firstMessage = messages[0]
106106
// Get messages to summarize, excluding the first message and last N messages
107-
const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(1, -N_MESSAGES_TO_KEEP))
107+
const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(0, -N_MESSAGES_TO_KEEP))
108108

109109
if (messagesToSummarize.length <= 1) {
110110
const error =

0 commit comments

Comments
 (0)