export function normalizeFetchTimeoutMs(value, fallback = 5_000) { const numeric = Number(value); if (!Number.isFinite(numeric) || numeric <= 0) { return fallback; } return Math.max(50, Math.min(60_000, Math.round(numeric))); } export async function fetchWithTimeout(url, init = {}, options = {}) { const timeoutMs = normalizeFetchTimeoutMs(options.timeoutMs); const timeoutMessage = String(options.timeoutMessage || "LOCAL_AGENT_FETCH_TIMEOUT"); const controller = new AbortController(); const timeout = setTimeout(() => { controller.abort(new Error(timeoutMessage)); }, timeoutMs); try { return await fetch(url, { ...init, signal: init.signal ?? controller.signal, }); } catch (error) { if (controller.signal.aborted) { throw new Error(timeoutMessage); } throw error; } finally { clearTimeout(timeout); } }