| import path from "node:path"; |
| import type { CliBackendConfig } from "../../config/types.js"; |
| import { |
| CLI_FRESH_WATCHDOG_DEFAULTS, |
| CLI_RESUME_WATCHDOG_DEFAULTS, |
| CLI_WATCHDOG_MIN_TIMEOUT_MS, |
| } from "../cli-watchdog-defaults.js"; |
|
|
| function pickWatchdogProfile( |
| backend: CliBackendConfig, |
| useResume: boolean, |
| ): { |
| noOutputTimeoutMs?: number; |
| noOutputTimeoutRatio: number; |
| minMs: number; |
| maxMs: number; |
| } { |
| const defaults = useResume ? CLI_RESUME_WATCHDOG_DEFAULTS : CLI_FRESH_WATCHDOG_DEFAULTS; |
| const configured = useResume |
| ? backend.reliability?.watchdog?.resume |
| : backend.reliability?.watchdog?.fresh; |
|
|
| const ratio = (() => { |
| const value = configured?.noOutputTimeoutRatio; |
| if (typeof value !== "number" || !Number.isFinite(value)) { |
| return defaults.noOutputTimeoutRatio; |
| } |
| return Math.max(0.05, Math.min(0.95, value)); |
| })(); |
| const minMs = (() => { |
| const value = configured?.minMs; |
| if (typeof value !== "number" || !Number.isFinite(value)) { |
| return defaults.minMs; |
| } |
| return Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(value)); |
| })(); |
| const maxMs = (() => { |
| const value = configured?.maxMs; |
| if (typeof value !== "number" || !Number.isFinite(value)) { |
| return defaults.maxMs; |
| } |
| return Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(value)); |
| })(); |
|
|
| return { |
| noOutputTimeoutMs: |
| typeof configured?.noOutputTimeoutMs === "number" && |
| Number.isFinite(configured.noOutputTimeoutMs) |
| ? Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, Math.floor(configured.noOutputTimeoutMs)) |
| : undefined, |
| noOutputTimeoutRatio: ratio, |
| minMs: Math.min(minMs, maxMs), |
| maxMs: Math.max(minMs, maxMs), |
| }; |
| } |
|
|
| export function resolveCliNoOutputTimeoutMs(params: { |
| backend: CliBackendConfig; |
| timeoutMs: number; |
| useResume: boolean; |
| }): number { |
| const profile = pickWatchdogProfile(params.backend, params.useResume); |
| |
| const cap = Math.max(CLI_WATCHDOG_MIN_TIMEOUT_MS, params.timeoutMs - 1_000); |
| if (profile.noOutputTimeoutMs !== undefined) { |
| return Math.min(profile.noOutputTimeoutMs, cap); |
| } |
| const computed = Math.floor(params.timeoutMs * profile.noOutputTimeoutRatio); |
| const bounded = Math.min(profile.maxMs, Math.max(profile.minMs, computed)); |
| return Math.min(bounded, cap); |
| } |
|
|
| export function buildCliSupervisorScopeKey(params: { |
| backend: CliBackendConfig; |
| backendId: string; |
| cliSessionId?: string; |
| }): string | undefined { |
| const commandToken = path |
| .basename(params.backend.command ?? "") |
| .trim() |
| .toLowerCase(); |
| const backendToken = params.backendId.trim().toLowerCase(); |
| const sessionToken = params.cliSessionId?.trim(); |
| if (!sessionToken) { |
| return undefined; |
| } |
| return `cli:${backendToken}:${commandToken}:${sessionToken}`; |
| } |
|
|