Skip to content
Source
Sign inSign up
Open History to see the last commit

orchestrationTiming.ts

37 lines1.5 KB

1import { isOrchestrationV2WorkActive, type OrchestrationV2Subagent } from "@t3tools/contracts";
2​
3export function deriveSubagentElapsedMs(
4 agent: {
5 readonly status: OrchestrationV2Subagent["status"];
6 readonly startedAt: string | null;
7 readonly completedAt: string | null;
8 },
9 nowMs: number,
10): number | null {
11 if (agent.startedAt === null) return null;
12 const end = isOrchestrationV2WorkActive(agent.status)
13 ? nowMs
14 : agent.completedAt === null
15 ? null
16 : Date.parse(agent.completedAt);
17 if (end === null) return null;
18 const start = Date.parse(agent.startedAt);
19 return Number.isFinite(start) && Number.isFinite(end) ? Math.max(0, end - start) : null;
21​
22export function formatDuration(durationMs: number): string {
23 if (!Number.isFinite(durationMs) || durationMs < 0) return "0ms";
24 if (durationMs < 1_000) return `${Math.max(1, Math.round(durationMs))}ms`;
25 if (durationMs < 10_000) return `${Math.round(durationMs / 100) / 10}s`;
26 const totalSeconds = Math.round(durationMs / 1_000);
27 // Choose the unit after rounding so 59.5 seconds never renders as "60s".
28 if (totalSeconds < 60) return `${totalSeconds}s`;
29 const hours = Math.floor(totalSeconds / 3_600);
30 const minutes = Math.floor((totalSeconds % 3_600) / 60);
31 const seconds = totalSeconds % 60;
32 const parts: string[] = [];
33 if (hours > 0) parts.push(`${hours}h`);
34 if (minutes > 0) parts.push(`${minutes}m`);
35 if (seconds > 0 || minutes > 0) parts.push(`${seconds}s`);
36 return parts.join(" ");