import type { OrchestrationV2TurnItem, ThreadTokenUsageSnapshot } from "@t3tools/contracts"; import * as DateTime from "effect/DateTime"; function asFiniteNumber(value: unknown): number | null { return typeof value === "number" && Number.isFinite(value) ? value : null; } type NullableContextWindowUsage = { readonly [Key in keyof ThreadTokenUsageSnapshot]: undefined extends ThreadTokenUsageSnapshot[Key] ? Exclude | null : ThreadTokenUsageSnapshot[Key]; }; export type ContextWindowSnapshot = NullableContextWindowUsage & { readonly remainingTokens: number | null; readonly usedPercentage: number | null; readonly remainingPercentage: number | null; readonly updatedAt: string; }; /** Map a provider driver kind to a user-facing display name. */ export function formatProviderDisplayName(provider: string | null | undefined): string { if (!provider) return "This agent"; switch (provider) { case "claudeAgent": case "claude": return "Claude"; case "codex": return "Codex"; case "cursor": return "Cursor"; case "opencode": return "OpenCode"; default: { // Title-case unknown driver kinds so they read reasonably. const trimmed = provider.replace(/Agent$/i, "").trim(); if (trimmed.length === 0) return provider; return trimmed.charAt(0).toUpperCase() + trimmed.slice(1); } } } export function deriveLatestContextWindowSnapshot( entries: ReadonlyArray<{ readonly item: OrchestrationV2TurnItem; }>, ): ContextWindowSnapshot | null { for (let index = entries.length - 1; index >= 0; index -= 1) { const entry = entries[index]; if (!entry || entry.item.type !== "compaction") { continue; } const payload = entry.item; const usedTokens = asFiniteNumber(payload.afterTokenCount); if (usedTokens === null || usedTokens < 0) { continue; } const maxTokens = null; const usedPercentage = maxTokens !== null && maxTokens > 0 ? Math.min(100, (usedTokens / maxTokens) * 100) : null; const remainingTokens = maxTokens !== null ? Math.max(0, Math.round(maxTokens - usedTokens)) : null; const remainingPercentage = usedPercentage !== null ? Math.max(0, 100 - usedPercentage) : null; return { usedTokens, totalProcessedTokens: asFiniteNumber(payload.beforeTokenCount), maxTokens, remainingTokens, usedPercentage, remainingPercentage, inputTokens: null, cachedInputTokens: null, outputTokens: null, reasoningOutputTokens: null, lastUsedTokens: null, lastInputTokens: null, lastCachedInputTokens: null, lastOutputTokens: null, lastReasoningOutputTokens: null, toolUses: null, durationMs: null, compactsAutomatically: true, updatedAt: DateTime.formatIso(payload.startedAt ?? payload.updatedAt), }; } return null; } export function formatContextWindowTokens(value: number | null): string { if (value === null || !Number.isFinite(value)) { return "0"; } if (value < 1_000) { return `${Math.round(value)}`; } if (value < 10_000) { return `${(value / 1_000).toFixed(1).replace(/\.0$/, "")}k`; } if (value < 1_000_000) { return `${Math.round(value / 1_000)}k`; } return `${(value / 1_000_000).toFixed(1).replace(/\.0$/, "")}m`; }