+ {row.kind === "work" &&
+ (() => {
+ const groupId = row.id;
+ const groupedEntries = row.groupedEntries;
+ const isExpanded = expandedWorkGroups[groupId] ?? false;
+ const hasOverflow = groupedEntries.length > MAX_VISIBLE_WORK_LOG_ENTRIES;
+ const visibleEntries =
+ hasOverflow && !isExpanded
+ ? groupedEntries.slice(-MAX_VISIBLE_WORK_LOG_ENTRIES)
+ : groupedEntries;
+ const hiddenCount = groupedEntries.length - visibleEntries.length;
+ const onlyToolEntries = groupedEntries.every((entry) => entry.tone === "tool");
+ const groupLabel = onlyToolEntries
+ ? groupedEntries.length === 1
+ ? "Tool call"
+ : `Tool calls (${groupedEntries.length})`
+ : groupedEntries.length === 1
+ ? "Work event"
+ : `Work log (${groupedEntries.length})`;
+
+ return (
+
+
+
+ {groupLabel}
+
+ {hasOverflow && (
+ )}
+
+
+ {visibleEntries.map((workEntry) => (
+
- {(() => {
- const stat =
- typeof file.additions === "number" &&
- typeof file.deletions === "number"
- ? { additions: file.additions, deletions: file.deletions }
- : file.diff
- ? countDiffStat(file.diff)
- : null;
- if (!stat) {
- return file.path;
- }
- return (
+
+
+ {workEntry.detail ? (
<>
- {file.path}
- (
- +{stat.additions}
- /
- -{stat.deletions}
- )
+ {workEntry.label}
+
+ {workEntry.detail}
+
>
- );
- })()}
-
+ ) : (
+ workEntry.label
+ )}
+
+
))}
- ) : !isCheckpointDiffLoading ? (
-
No changed files.
- ) : null}
+
+ );
+ })()}
+
+ {row.kind === "message" &&
+ row.message.role === "user" &&
+ (() => {
+ const userImages = row.message.attachments ?? [];
+ const canRevertAgentWork = revertTurnCountByUserMessageId.has(row.message.id);
+ return (
+
+
+ {userImages.length > 0 && (
+
+ {userImages.map(
+ (image: NonNullable
[number]) => (
+
+ {image.previewUrl ? (
+

+ onImageExpand({ src: image.previewUrl!, name: image.name })
+ }
+ />
+ ) : (
+
+ {image.name}
+
+ )}
+
+ ),
+ )}
+
+ )}
+ {row.message.text && (
+
+ {row.message.text}
+
+ )}
+
+ {canRevertAgentWork && (
+
+ )}
+
+ {formatTimestamp(row.message.createdAt)}
+
+
+
+
+ );
+ })()}
+
+ {row.kind === "message" &&
+ row.message.role === "assistant" &&
+ (() => {
+ const messageText =
+ row.message.text || (row.message.streaming ? "" : "(empty response)");
+ return (
+ <>
+ {row.showCompletionDivider && (
+
+
+
+ {completionSummary ? `Response • ${completionSummary}` : "Response"}
+
+
+
+ )}
+
+
+ {(() => {
+ const turnSummary = turnDiffSummaryByAssistantMessageId.get(
+ row.message.id,
+ );
+ if (!turnSummary) return null;
+ const isCheckpointDiffLoading =
+ !turnSummary.checkpointDiffLoaded && turnSummary.files.length === 0;
+ const summaryStat = turnSummary.unifiedDiff
+ ? countDiffStat(turnSummary.unifiedDiff)
+ : turnSummary.files.reduce(
+ (acc, file) => {
+ const next =
+ typeof file.additions === "number" &&
+ typeof file.deletions === "number"
+ ? { additions: file.additions, deletions: file.deletions }
+ : file.diff
+ ? countDiffStat(file.diff)
+ : null;
+ if (!next) {
+ return acc;
+ }
+ return {
+ additions: acc.additions + next.additions,
+ deletions: acc.deletions + next.deletions,
+ };
+ },
+ { additions: 0, deletions: 0 },
+ );
+ const changedFileCountLabel = isCheckpointDiffLoading
+ ? "..."
+ : String(turnSummary.files.length);
+ return (
+
+
+
+ Changed files ({changedFileCountLabel})
+ {!isCheckpointDiffLoading &&
+ (summaryStat.additions > 0 || summaryStat.deletions > 0) && (
+ <>
+ •
+
+ +{summaryStat.additions}
+
+ /
+
+ -{summaryStat.deletions}
+
+ >
+ )}
+
+
+
+ {isCheckpointDiffLoading && (
+
+ Loading checkpoint diff...
+
+ )}
+ {turnSummary.files.length > 0 ? (
+
+ {turnSummary.files.map((file) => (
+
+ ))}
+
+ ) : !isCheckpointDiffLoading ? (
+
+ No changed files.
+
+ ) : null}
+
+ );
+ })()}
+
+ {formatMessageMeta(
+ row.message.createdAt,
+ row.message.streaming
+ ? formatElapsed(row.message.createdAt, nowIso)
+ : formatElapsed(
+ row.message.createdAt,
+ assistantCompletionByItemId.get(row.message.id),
+ ),
+ )}
+
+
+ >
+ );
+ })()}
+
+ {row.kind === "working" && (
+
+
+
+
+
+
+
+
- );
- })()}
-
- {formatMessageMeta(
- timelineEntry.message.createdAt,
- timelineEntry.message.streaming
- ? formatElapsed(timelineEntry.message.createdAt, nowIso)
- : formatElapsed(
- timelineEntry.message.createdAt,
- assistantCompletionByItemId.get(timelineEntry.message.id),
- ),
- )}
-
+
+ )}