mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
fix(agents): apply provider-class idle ceilings to explicit run budgets
This commit is contained in:
parent
048f2096d2
commit
e4949996d1
2 changed files with 40 additions and 16 deletions
|
|
@ -520,6 +520,27 @@ describe("resolveLlmIdleTimeoutMs", () => {
|
|||
expect(resolveLlmIdleTimeoutMs({ cfg, model })).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["local keeps no class ceiling", { baseUrl: "http://127.0.0.1:11434" }, 900_000],
|
||||
[
|
||||
"self-hosted keeps the 300s tier",
|
||||
{ provider: "vllm", baseUrl: "https://gpu.example.com/v1" },
|
||||
300_000,
|
||||
],
|
||||
["cloud keeps the 120s default", { provider: "openai" }, 120_000],
|
||||
])("explicit run timeout above the tiers: %s", (_label, model, expected) => {
|
||||
expect(resolveLlmIdleTimeoutMs({ runTimeoutMs: 900_000, model })).toBe(expected);
|
||||
});
|
||||
|
||||
it("explicit run timeouts below the class tier still bound self-hosted idle", () => {
|
||||
expect(
|
||||
resolveLlmIdleTimeoutMs({
|
||||
runTimeoutMs: 90_000,
|
||||
model: { provider: "vllm", baseUrl: "https://gpu.example.com/v1" },
|
||||
}),
|
||||
).toBe(90_000);
|
||||
});
|
||||
|
||||
it("cron exempts provider-id self-hosted models from the 60s clamp", () => {
|
||||
expect(
|
||||
resolveLlmIdleTimeoutMs({
|
||||
|
|
|
|||
|
|
@ -249,8 +249,6 @@ export function resolveLlmIdleTimeoutMs(params?: {
|
|||
model?: { baseUrl?: string; id?: string; provider?: string };
|
||||
}): number {
|
||||
const clampTimeoutMs = (valueMs: number) => clampTimerTimeoutMs(valueMs) ?? 1;
|
||||
const clampImplicitTimeoutMs = (valueMs: number) =>
|
||||
clampTimeoutMs(Math.min(valueMs, DEFAULT_LLM_IDLE_TIMEOUT_MS));
|
||||
|
||||
const runTimeoutMs = params?.runTimeoutMs;
|
||||
const agentTimeoutSeconds = params?.cfg?.agents?.defaults?.timeoutSeconds;
|
||||
|
|
@ -276,6 +274,23 @@ export function resolveLlmIdleTimeoutMs(params?: {
|
|||
value < MAX_TIMER_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
// Run/agent budgets bound idle from below the provider-class ceiling; they
|
||||
// must not shrink class tolerance (local has no ceiling, self-hosted 300s).
|
||||
// Clamping every class to the cloud default reopened #85826-style kills for
|
||||
// self-hosted users with explicit budgets above 120s.
|
||||
const clampToClassIdleCeiling = (budgetMs: number): number => {
|
||||
if (isLocalRuntimeModel) {
|
||||
return clampTimeoutMs(budgetMs);
|
||||
}
|
||||
const classIdleTimeoutMs =
|
||||
isSelfHostedRuntimeModel ||
|
||||
isExplicitLocalHostnameRuntimeModel ||
|
||||
isSelfHostedHostnameRuntimeModel
|
||||
? SELF_HOSTED_LLM_IDLE_TIMEOUT_MS
|
||||
: DEFAULT_LLM_IDLE_TIMEOUT_MS;
|
||||
return clampTimeoutMs(Math.min(budgetMs, classIdleTimeoutMs));
|
||||
};
|
||||
|
||||
// Explicit per-model idle timeout (`models.providers.<id>.timeoutSeconds`) wins
|
||||
// over the NO_TIMEOUT_MS sentinel that runTimeoutMs may carry when the caller
|
||||
// declared "run is unlimited". The two are independent: an unlimited run does
|
||||
|
|
@ -314,23 +329,11 @@ export function resolveLlmIdleTimeoutMs(params?: {
|
|||
}
|
||||
return clampTimeoutMs(Math.min(runTimeoutMs, CRON_LLM_IDLE_TIMEOUT_MS));
|
||||
}
|
||||
return clampImplicitTimeoutMs(runTimeoutMs);
|
||||
return clampToClassIdleCeiling(runTimeoutMs);
|
||||
}
|
||||
|
||||
if (agentTimeoutMs !== undefined) {
|
||||
// The agent budget bounds idle from below the provider-class ceiling; it
|
||||
// must not shrink class tolerance (local has no ceiling, self-hosted 300s).
|
||||
// Clamping every class to the cloud default here reopened #85826-style kills.
|
||||
if (isLocalRuntimeModel) {
|
||||
return clampTimeoutMs(agentTimeoutMs);
|
||||
}
|
||||
const classIdleTimeoutMs =
|
||||
isSelfHostedRuntimeModel ||
|
||||
isExplicitLocalHostnameRuntimeModel ||
|
||||
isSelfHostedHostnameRuntimeModel
|
||||
? SELF_HOSTED_LLM_IDLE_TIMEOUT_MS
|
||||
: DEFAULT_LLM_IDLE_TIMEOUT_MS;
|
||||
return clampTimeoutMs(Math.min(agentTimeoutMs, classIdleTimeoutMs));
|
||||
return clampToClassIdleCeiling(agentTimeoutMs);
|
||||
}
|
||||
|
||||
// The default watchdog is a network-silence-as-hang guard for cloud providers.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue