import { Box, Paper, Stack, Text } from "@mantine/core";
import {
IconCurrencyDollar,
IconHistory,
IconHourglass,
IconStack2,
} from "@tabler/icons-react";
import { mergeProjectedTurns, turnPresentation } from "../../state.js";
import { turnReportedWorkView, turnUsageMetricsView } from "../presentation";
import type { Task, TaskTurn } from "../types";
import { useEffect, useState } from "react";
import { RelativeTime } from "./RelativeTime";
import { LinkedText } from "./LinkedText";
import { ShimmerText } from "./ShimmerText";
import { StatCell, StaticStat, StatsGrid } from "./StatsGrid";
import { StatusBadge } from "./StatusBadge";
export function ActivityTimeline({ highlightTurnRef, task }: { highlightTurnRef: string | null; task: Task }) {
const turns = mergeProjectedTurns(task, []) as Task["turns"];
if (!turns?.length) return No turn history has been recorded.;
return (
{[...turns].reverse().map((turn, index) => {
const presentation = turnPresentation(turn);
const identity = turn.turnRef ?? turn.turnId ?? `turn-${index}`;
const highlighted = identity === highlightTurnRef;
const usage = turnUsageMetricsView(task, turn);
return (
{presentation.sourceLabel}
Request
Result
{presentation.status === "working"
? {presentation.summary}
: }
}
label="Turn update time"
value={presentation.updatedAt}
/>
}
title="Tokens"
value={usage.tokens.value}
/>
}
title="Estimated cost"
value={usage.cost.value}
/>
{usage.note && {usage.note}}
);
})}
);
}
function TurnReportedWork({ turn }: { turn: TaskTurn }) {
const now = useLiveNow(turn.result === null);
const elapsed = turnReportedWorkView(turn, now);
return (
}
title="Duration"
value={elapsed.value}
/>
);
}
function useLiveNow(active: boolean) {
const [now, setNow] = useState(() => Date.now());
useEffect(() => {
if (!active) return undefined;
setNow(Date.now());
const interval = window.setInterval(() => setNow(Date.now()), 1_000);
return () => window.clearInterval(interval);
}, [active]);
return now;
}