/**
 * Streaming headers-timeout budget.
 *
 * The streaming upstream fetch arms a fail-fast timer that aborts only while
 * waiting for the response *headers* (it is cleared the moment a Response
 * arrives — the body stream's deadline then belongs to the first-token
 * watchdog + per-chunk idle guard in handleMessagesStream). A flat 30s budget
 * is correct for cloud (catch a stuck connect quickly) but too tight for a
 * loopback runtime: a small local model fed a large agent tool payload can
 * spend 30–60s on CPU prefill before emitting the first byte, so the guard
 * fires spuriously and the fallback chain escalates to a heavier model
 * (Issue #2 dogfood). Loopback endpoints therefore get a longer budget,
 * capped by the request's own timeout; everything else keeps the 30s default.
 */
/** Fail-fast budget for cloud / non-loopback upstreams. */
export const CLOUD_HEADERS_TIMEOUT_MS = 30_000;
/** Headers budget for loopback runtimes — room for slow local CPU prefill. */
export const LOCAL_HEADERS_TIMEOUT_MS = 120_000;
/** True when the endpoint host is a loopback address (a local runtime). */
export function isLoopbackEndpoint(endpointUrl) {
    try {
        const { hostname } = new URL(endpointUrl);
        return (hostname === '127.0.0.1' ||
            hostname === 'localhost' ||
            hostname === '::1' ||
            hostname === '[::1]');
    }
    catch {
        return false;
    }
}
/**
 * Resolve the headers-phase timeout for a streaming upstream fetch.
 *
 * - Loopback endpoint → min(LOCAL_HEADERS_TIMEOUT_MS, routeTimeoutMs): a longer
 *   budget for slow local prefill, but never beyond the request's own timeout.
 * - Otherwise → CLOUD_HEADERS_TIMEOUT_MS (unchanged 30s fail-fast).
 */
export function resolveHeadersTimeoutMs(opts) {
    if (isLoopbackEndpoint(opts.endpointUrl)) {
        return Math.min(LOCAL_HEADERS_TIMEOUT_MS, Math.max(0, opts.routeTimeoutMs));
    }
    return CLOUD_HEADERS_TIMEOUT_MS;
}
//# sourceMappingURL=headers-timeout.js.map