diff --git a/src/agents/auth-health.e2e.test.ts b/src/agents/auth-health.e2e.test.ts index 35b56303d70..97da6f280f8 100644 --- a/src/agents/auth-health.e2e.test.ts +++ b/src/agents/auth-health.e2e.test.ts @@ -1,5 +1,9 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import { buildAuthHealthSummary, DEFAULT_OAUTH_WARN_MS } from "./auth-health.js"; +import { + buildAuthHealthSummary, + DEFAULT_OAUTH_WARN_MS, + formatRemainingShort, +} from "./auth-health.js"; describe("buildAuthHealthSummary", () => { const now = 1_700_000_000_000; @@ -87,3 +91,10 @@ describe("buildAuthHealthSummary", () => { expect(statuses["google:no-refresh"]).toBe("expired"); }); }); + +describe("formatRemainingShort", () => { + it("supports an explicit under-minute label override", () => { + expect(formatRemainingShort(20_000)).toBe("1m"); + expect(formatRemainingShort(20_000, { underMinuteLabel: "soon" })).toBe("soon"); + }); +}); diff --git a/src/agents/auth-health.ts b/src/agents/auth-health.ts index ed3f763b75d..13781618cfe 100644 --- a/src/agents/auth-health.ts +++ b/src/agents/auth-health.ts @@ -43,14 +43,23 @@ export function resolveAuthProfileSource(_profileId: string): AuthProfileSource return "store"; } -export function formatRemainingShort(remainingMs?: number): string { +export function formatRemainingShort( + remainingMs?: number, + opts?: { + underMinuteLabel?: string; + }, +): string { if (remainingMs === undefined || Number.isNaN(remainingMs)) { return "unknown"; } if (remainingMs <= 0) { return "0m"; } - const minutes = Math.max(1, Math.round(remainingMs / 60_000)); + const roundedMinutes = Math.round(remainingMs / 60_000); + if (roundedMinutes < 1) { + return opts?.underMinuteLabel ?? "1m"; + } + const minutes = roundedMinutes; if (minutes < 60) { return `${minutes}m`; } diff --git a/src/auto-reply/reply/directive-handling.auth.ts b/src/auto-reply/reply/directive-handling.auth.ts index e767bae979c..7d1af2acde9 100644 --- a/src/auto-reply/reply/directive-handling.auth.ts +++ b/src/auto-reply/reply/directive-handling.auth.ts @@ -1,3 +1,4 @@ +import { formatRemainingShort } from "../../agents/auth-health.js"; import { isProfileInCooldown, resolveAuthProfileDisplayLabel, @@ -32,23 +33,8 @@ export const resolveAuthLabel = async ( const lastGood = findNormalizedProviderValue(store.lastGood, providerKey); const nextProfileId = order[0]; const now = Date.now(); - - const formatUntil = (timestampMs: number) => { - const remainingMs = Math.max(0, timestampMs - now); - const minutes = Math.round(remainingMs / 60_000); - if (minutes < 1) { - return "soon"; - } - if (minutes < 60) { - return `${minutes}m`; - } - const hours = Math.round(minutes / 60); - if (hours < 48) { - return `${hours}h`; - } - const days = Math.round(hours / 24); - return `${days}d`; - }; + const formatUntil = (timestampMs: number) => + formatRemainingShort(timestampMs - now, { underMinuteLabel: "soon" }); if (order.length > 0) { if (mode === "compact") {