@@ -249,8 +249,6 @@ export function resolveLlmIdleTimeoutMs(params?: {
249249 model ?: { baseUrl ?: string ; id ?: string ; provider ?: string } ;
250250} ) : number {
251251 const clampTimeoutMs = ( valueMs : number ) => clampTimerTimeoutMs ( valueMs ) ?? 1 ;
252- const clampImplicitTimeoutMs = ( valueMs : number ) =>
253- clampTimeoutMs ( Math . min ( valueMs , DEFAULT_LLM_IDLE_TIMEOUT_MS ) ) ;
254252
255253 const runTimeoutMs = params ?. runTimeoutMs ;
256254 const agentTimeoutSeconds = params ?. cfg ?. agents ?. defaults ?. timeoutSeconds ;
@@ -276,6 +274,23 @@ export function resolveLlmIdleTimeoutMs(params?: {
276274 value < MAX_TIMER_TIMEOUT_MS ,
277275 ) ;
278276
277+ // Run/agent budgets bound idle from below the provider-class ceiling; they
278+ // must not shrink class tolerance (local has no ceiling, self-hosted 300s).
279+ // Clamping every class to the cloud default reopened #85826-style kills for
280+ // self-hosted users with explicit budgets above 120s.
281+ const clampToClassIdleCeiling = ( budgetMs : number ) : number => {
282+ if ( isLocalRuntimeModel ) {
283+ return clampTimeoutMs ( budgetMs ) ;
284+ }
285+ const classIdleTimeoutMs =
286+ isSelfHostedRuntimeModel ||
287+ isExplicitLocalHostnameRuntimeModel ||
288+ isSelfHostedHostnameRuntimeModel
289+ ? SELF_HOSTED_LLM_IDLE_TIMEOUT_MS
290+ : DEFAULT_LLM_IDLE_TIMEOUT_MS ;
291+ return clampTimeoutMs ( Math . min ( budgetMs , classIdleTimeoutMs ) ) ;
292+ } ;
293+
279294 // Explicit per-model idle timeout (`models.providers.<id>.timeoutSeconds`) wins
280295 // over the NO_TIMEOUT_MS sentinel that runTimeoutMs may carry when the caller
281296 // declared "run is unlimited". The two are independent: an unlimited run does
@@ -314,23 +329,11 @@ export function resolveLlmIdleTimeoutMs(params?: {
314329 }
315330 return clampTimeoutMs ( Math . min ( runTimeoutMs , CRON_LLM_IDLE_TIMEOUT_MS ) ) ;
316331 }
317- return clampImplicitTimeoutMs ( runTimeoutMs ) ;
332+ return clampToClassIdleCeiling ( runTimeoutMs ) ;
318333 }
319334
320335 if ( agentTimeoutMs !== undefined ) {
321- // The agent budget bounds idle from below the provider-class ceiling; it
322- // must not shrink class tolerance (local has no ceiling, self-hosted 300s).
323- // Clamping every class to the cloud default here reopened #85826-style kills.
324- if ( isLocalRuntimeModel ) {
325- return clampTimeoutMs ( agentTimeoutMs ) ;
326- }
327- const classIdleTimeoutMs =
328- isSelfHostedRuntimeModel ||
329- isExplicitLocalHostnameRuntimeModel ||
330- isSelfHostedHostnameRuntimeModel
331- ? SELF_HOSTED_LLM_IDLE_TIMEOUT_MS
332- : DEFAULT_LLM_IDLE_TIMEOUT_MS ;
333- return clampTimeoutMs ( Math . min ( agentTimeoutMs , classIdleTimeoutMs ) ) ;
336+ return clampToClassIdleCeiling ( agentTimeoutMs ) ;
334337 }
335338
336339 // The default watchdog is a network-silence-as-hang guard for cloud providers.
0 commit comments