1import type { ProviderDriverKind, ServerProvider } from "@t3tools/contracts";
2import { BotIcon, type LucideIcon } from "lucide-react";
3import { cn } from "../../lib/utils";
4import { ProviderInstanceIcon } from "./ProviderInstanceIcon";
5
6export function threadRelationshipStatusLabel(status: string | null): string {
7 switch (status) {
8 case "preparing":
9 case "starting":
10 return "Starting";
11 case "running":
12 case "in_progress":
13 return "Running";
14 case "pending":
15 case "queued":
16 return "Queued";
17 case "waiting":
18 case "blocked":
19 return "Waiting";
20 case "completed":
21 return "Done";
22 case "failed":
23 case "error":
24 return "Failed";
25 case "cancelled":
26 case "interrupted":
27 return "Stopped";
28 case "rolled_back":
29 return "Reverted";
30 case "resolved_native":
31 return "Resolved (native)";
32 case "resolved_portable":
33 return "Resolved (portable)";
34 case "consumed":
35 return "Consumed";
36 case "superseded":
37 return "Superseded";
38 case "idle":
39 return "Idle";
40 default:
41 return "Unknown";
42 }
43}
44
45/** Shared by lineage and timeline links, including the provider glyph and status badge. */
46export function ThreadRelationshipIcon({
47 driver,
48 provider,
49 status,
50 fallbackIcon: FallbackIcon = BotIcon,
51}: {
52 driver?: ProviderDriverKind | undefined;
53 provider?: ServerProvider | undefined;
54 status: string | null;
55 fallbackIcon?: LucideIcon;
56}) {
57 const iconClassName = "size-4 shrink-0 text-muted-foreground";
58 return (
59 <span className="relative inline-flex size-4 shrink-0 items-center justify-center">
60 {driver ? (
61 <ProviderInstanceIcon
62 driverKind={driver}
63 displayName={provider?.displayName ?? driver}
64 acpRegistryIconUrl={provider?.iconUrl}
65 iconClassName={iconClassName}
66 className="z-auto"
67 />
68 ) : (
69 <FallbackIcon className={iconClassName} />
70 )}
71 <span
72 className={cn(
73 "absolute -bottom-1 -right-1 size-2 rounded-full border-2 border-card",
74 status === "running" ||
75 status === "in_progress" ||
76 status === "pending" ||
77 status === "waiting"
78 ? "bg-info"
79 : status === "failed" || status === "error"
80 ? "bg-destructive"
81 : status === "completed"
82 ? "bg-success"
83 : "bg-muted-foreground/45",
84 )}
85 aria-hidden="true"
86 />
87 </span>
88 );
89}