| author | |
| committer | |
| log | cfc9bf34156ddcc4a98b7f5c67193adb5aedce06 |
| tree | 969c241f03318f1c87fdc6525f33e453c05205e4 |
| parent | c8f77e0d441264efb0acfac312e852c81ae3da83 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>3 files changed, 17 insertions(+), 8 deletions(-)
apps/web/src/components/chat/MessagesTimeline.logic.test.ts+9-4| ... | @@ -1170,11 +1170,10 @@ describe("deriveMessagesTimelineRows", () => { | ... | @@ -1170,11 +1170,10 @@ describe("deriveMessagesTimelineRows", () => { |
| 1170 | })), | 1170 | })), |
| 1171 | ]; | 1171 | ]; |
| 1172 | 1172 | ||
| 1173 | const rows = deriveMessagesTimelineRows({ | 1173 | const input = { |
| 1174 | timelineEntries, | ||
| 1175 | latestTurn: { | 1174 | latestTurn: { |
| 1176 | turnId, | 1175 | turnId, |
| 1177 | state: "error", | 1176 | state: "error" as const, |
| 1178 | startedAt: "2026-01-01T00:00:00Z", | 1177 | startedAt: "2026-01-01T00:00:00Z", |
| 1179 | completedAt: "2026-01-01T00:00:10Z", | 1178 | completedAt: "2026-01-01T00:00:10Z", |
| 1180 | }, | 1179 | }, |
| ... | @@ -1182,7 +1181,8 @@ describe("deriveMessagesTimelineRows", () => { | ... | @@ -1182,7 +1181,8 @@ describe("deriveMessagesTimelineRows", () => { |
| 1182 | activeTurnStartedAt: null, | 1181 | activeTurnStartedAt: null, |
| 1183 | turnDiffSummaryByAssistantMessageId: new Map(), | 1182 | turnDiffSummaryByAssistantMessageId: new Map(), |
| 1184 | revertTurnCountByUserMessageId: new Map(), | 1183 | revertTurnCountByUserMessageId: new Map(), |
| 1185 | }); | 1184 | }; |
| 1185 | const rows = deriveMessagesTimelineRows({ ...input, timelineEntries }); | ||
| 1186 | 1186 | ||
| 1187 | expect(rows.map((row) => row.id)).toEqual([ | 1187 | expect(rows.map((row) => row.id)).toEqual([ |
| 1188 | "turn-fold:turn-1", | 1188 | "turn-fold:turn-1", |
| ... | @@ -1205,6 +1205,11 @@ describe("deriveMessagesTimelineRows", () => { | ... | @@ -1205,6 +1205,11 @@ describe("deriveMessagesTimelineRows", () => { |
| 1205 | showAssistantMeta: false, | 1205 | showAssistantMeta: false, |
| 1206 | showAssistantCopyButton: false, | 1206 | showAssistantCopyButton: false, |
| 1207 | }); | 1207 | }); |
| 1208 | expect( | ||
| 1209 | deriveMessagesTimelineRows({ ...input, timelineEntries: timelineEntries.slice(0, 3) }).map( | ||
| 1210 | (row) => row.id, | ||
| 1211 | ), | ||
| 1212 | ).toEqual(["turn-fold:turn-1", "assistant-final-entry"]); | ||
| 1208 | }); | 1213 | }); |
| 1209 | 1214 | ||
| 1210 | it("folds all assistant messages before the terminal message", () => { | 1215 | it("folds all assistant messages before the terminal message", () => { |
apps/web/src/components/chat/MessagesTimeline.logic.ts+7-3| ... | @@ -542,8 +542,8 @@ function workEntryIsActiveTurnActivity(entry: WorkLogEntry): boolean { | ... | @@ -542,8 +542,8 @@ function workEntryIsActiveTurnActivity(entry: WorkLogEntry): boolean { |
| 542 | 542 | ||
| 543 | /** | 543 | /** |
| 544 | * Settled turns fold activity before their terminal assistant message behind | 544 | * Settled turns fold activity before their terminal assistant message behind |
| 545 | * a "Worked for ..." row. Work that lands after that message stays visible so | 545 | * a "Worked for ..." row. A single ordinary activity after that message joins |
| 546 | * failed or interrupted turns do not hide their trailing tool-call summary. | 546 | * the fold, while larger groups and failures stay visible as a trailing summary. |
| 547 | */ | 547 | */ |
| 548 | function deriveTurnFolds(input: { | 548 | function deriveTurnFolds(input: { |
| 549 | timelineEntries: ReadonlyArray<TimelineEntry>; | 549 | timelineEntries: ReadonlyArray<TimelineEntry>; |
| ... | @@ -623,7 +623,11 @@ function deriveTurnFolds(input: { | ... | @@ -623,7 +623,11 @@ function deriveTurnFolds(input: { |
| 623 | } | 623 | } |
| 624 | const isCompaction = | 624 | const isCompaction = |
| 625 | entry.kind === "work" && entry.entry.sourceActivityKind === "context-compaction"; | 625 | entry.kind === "work" && entry.entry.sourceActivityKind === "context-compaction"; |
| 626 | if (!isCompaction && index > terminalEntryIndex) { | 626 | const isSingleTrailingActivity = |
| 627 | group.entries.length === terminalEntryIndex + 2 && | ||
| 628 | entry.kind === "work" && | ||
| 629 | !workEntryDisplayIndicatesToolFailure(entry.entry); | ||
| 630 | if (!isCompaction && index > terminalEntryIndex && !isSingleTrailingActivity) { | ||
| 627 | continue; | 631 | continue; |
| 628 | } | 632 | } |
| 629 | // Agent-spawn CTA rows never fold: workflows outlive their launching | 633 | // Agent-spawn CTA rows never fold: workflows outlive their launching |
apps/web/src/components/chat/MessagesTimeline.test.tsx+1-1| ... | @@ -1135,7 +1135,7 @@ describe("MessagesTimeline", () => { | ... | @@ -1135,7 +1135,7 @@ describe("MessagesTimeline", () => { |
| 1135 | label: "Ran command", | 1135 | label: "Ran command", |
| 1136 | tone: "tool", | 1136 | tone: "tool", |
| 1137 | itemType: "command_execution", | 1137 | itemType: "command_execution", |
| 1138 | toolLifecycleStatus: "completed", | 1138 | toolLifecycleStatus: "failed", |
| 1139 | }, | 1139 | }, |
| 1140 | }, | 1140 | }, |
| 1141 | ]} | 1141 | ]} |