Skip to content

Commit 3e24e21

Browse files
SannidhyaSahSannidhya
andauthored
fix: preserve condensation summary during task resume (#11487) (#11488)
Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
1 parent 77ed60a commit 3e24e21

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/core/condense/__tests__/rewind-after-condense.spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,4 +518,56 @@ describe("Rewind After Condense - Issue #8295", () => {
518518
})
519519
})
520520
})
521+
522+
describe("Resume after condense preserves summary", () => {
523+
it("should keep condensed messages filtered when a new user message is added after summary", () => {
524+
const condenseId = "summary-resume-test"
525+
526+
// Simulate post-condensation state: all old messages tagged, summary at end,
527+
// then a new user message added after resume (the fix preserves summary)
528+
const historyAfterResume: ApiMessage[] = [
529+
{ role: "user", content: "Original task", ts: 100, condenseParent: condenseId },
530+
{ role: "assistant", content: "Response 1", ts: 200, condenseParent: condenseId },
531+
{ role: "user", content: "Follow-up", ts: 300, condenseParent: condenseId },
532+
{ role: "assistant", content: "Response 2", ts: 400, condenseParent: condenseId },
533+
{
534+
role: "user",
535+
content: [{ type: "text", text: "## Conversation Summary\nSummary of work done" }],
536+
ts: 401,
537+
isSummary: true,
538+
condenseId,
539+
},
540+
// New user message added after resume (no isSummary, no condenseId)
541+
{ role: "user", content: [{ type: "text", text: "Please continue with the next step" }], ts: 500 },
542+
]
543+
544+
const effective = getEffectiveApiHistory(historyAfterResume)
545+
546+
// Should only include summary + new message (fresh start model)
547+
expect(effective).toHaveLength(2)
548+
expect(effective[0].isSummary).toBe(true)
549+
expect(effective[1].ts).toBe(500)
550+
})
551+
552+
it("should restore ALL messages if summary is missing (the bug scenario before fix)", () => {
553+
const condenseId = "summary-bug-demo"
554+
555+
// Simulate the bug: summary was stripped during resume, replaced with regular message.
556+
// condenseParent tags still exist but point to a non-existent summary.
557+
const historyWithoutSummary: ApiMessage[] = [
558+
{ role: "user", content: "Original task", ts: 100, condenseParent: condenseId },
559+
{ role: "assistant", content: "Response 1", ts: 200, condenseParent: condenseId },
560+
{ role: "user", content: "Follow-up", ts: 300, condenseParent: condenseId },
561+
{ role: "assistant", content: "Response 2", ts: 400, condenseParent: condenseId },
562+
// Summary was REMOVED and replaced with a regular user message (no isSummary)
563+
{ role: "user", content: [{ type: "text", text: "Summary content merged with new input" }], ts: 500 },
564+
]
565+
566+
const effective = getEffectiveApiHistory(historyWithoutSummary)
567+
568+
// Without the summary, ALL messages are restored (orphaned condenseParent)
569+
// This demonstrates the bug: condensation is effectively undone
570+
expect(effective).toHaveLength(5)
571+
})
572+
})
521573
})

src/core/task/Task.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,17 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
20992099
if (existingApiConversationHistory.length > 0) {
21002100
const lastMessage = existingApiConversationHistory[existingApiConversationHistory.length - 1]
21012101

2102-
if (lastMessage.role === "assistant") {
2102+
if (lastMessage.isSummary) {
2103+
// IMPORTANT: If the last message is a condensation summary, we must preserve it
2104+
// intact. The summary message carries critical metadata (isSummary, condenseId)
2105+
// that getEffectiveApiHistory() uses to filter out condensed messages.
2106+
// Removing or merging it would destroy this metadata, causing all condensed
2107+
// messages to become "orphaned" and restored to active status — effectively
2108+
// undoing the condensation and sending the full history to the API.
2109+
// See: https://github.com/RooCodeInc/Roo-Code/issues/11487
2110+
modifiedApiConversationHistory = [...existingApiConversationHistory]
2111+
modifiedOldUserContent = []
2112+
} else if (lastMessage.role === "assistant") {
21032113
const content = Array.isArray(lastMessage.content)
21042114
? lastMessage.content
21052115
: [{ type: "text", text: lastMessage.content }]

0 commit comments

Comments
 (0)