| 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 | 1170 | })), |
| 1171 | 1171 | ]; |
| 1172 | 1172 | |
| 1173 | const rows = deriveMessagesTimelineRows({ | |
| 1174 | timelineEntries, | |
| 1173 | const input = { | |
| 1175 | 1174 | latestTurn: { |
| 1176 | 1175 | turnId, |
| 1177 | state: "error", | |
| 1176 | state: "error" as const, | |
| 1178 | 1177 | startedAt: "2026-01-01T00:00:00Z", |
| 1179 | 1178 | completedAt: "2026-01-01T00:00:10Z", |
| 1180 | 1179 | }, |
| ... | ... | @@ -1182,7 +1181,8 @@ describe("deriveMessagesTimelineRows", () => { |
| 1182 | 1181 | activeTurnStartedAt: null, |
| 1183 | 1182 | turnDiffSummaryByAssistantMessageId: new Map(), |
| 1184 | 1183 | revertTurnCountByUserMessageId: new Map(), |
| 1185 | }); | |
| 1184 | }; | |
| 1185 | const rows = deriveMessagesTimelineRows({ ...input, timelineEntries }); | |
| 1186 | 1186 | |
| 1187 | 1187 | expect(rows.map((row) => row.id)).toEqual([ |
| 1188 | 1188 | "turn-fold:turn-1", |
| ... | ... | @@ -1205,6 +1205,11 @@ describe("deriveMessagesTimelineRows", () => { |
| 1205 | 1205 | showAssistantMeta: false, |
| 1206 | 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 | 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 | 542 | |
| 543 | 543 | /** |
| 544 | 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 | |
| 546 | * failed or interrupted turns do not hide their trailing tool-call summary. | |
| 545 | * a "Worked for ..." row. A single ordinary activity after that message joins | |
| 546 | * the fold, while larger groups and failures stay visible as a trailing summary. | |
| 547 | 547 | */ |
| 548 | 548 | function deriveTurnFolds(input: { |
| 549 | 549 | timelineEntries: ReadonlyArray<TimelineEntry>; |
| ... | ... | @@ -623,7 +623,11 @@ function deriveTurnFolds(input: { |
| 623 | 623 | } |
| 624 | 624 | const isCompaction = |
| 625 | 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 | 631 | continue; |
| 628 | 632 | } |
| 629 | 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 | 1135 | label: "Ran command", |
| 1136 | 1136 | tone: "tool", |
| 1137 | 1137 | itemType: "command_execution", |
| 1138 | toolLifecycleStatus: "completed", | |
| 1138 | toolLifecycleStatus: "failed", | |
| 1139 | 1139 | }, |
| 1140 | 1140 | }, |
| 1141 | 1141 | ]} |