mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(scripts): clamp openwebui probe timers
This commit is contained in:
@@ -7,14 +7,15 @@ const email = process.env.OPENWEBUI_ADMIN_EMAIL ?? "";
|
||||
const password = process.env.OPENWEBUI_ADMIN_PASSWORD ?? "";
|
||||
const expectedNonce = process.env.OPENWEBUI_EXPECTED_NONCE ?? "";
|
||||
const prompt = process.env.OPENWEBUI_PROMPT ?? "";
|
||||
const MAX_TIMER_TIMEOUT_MS = 2_147_000_000;
|
||||
const modelAttempts = readPositiveInt("OPENWEBUI_MODEL_ATTEMPTS", 72);
|
||||
const modelRetryMs = readNonNegativeInt("OPENWEBUI_MODEL_RETRY_MS", 5000);
|
||||
const fetchTimeoutMs = readPositiveInt("OPENWEBUI_FETCH_TIMEOUT_MS", 720000);
|
||||
const controlTimeoutMs = readPositiveInt(
|
||||
const modelRetryMs = readNonNegativeTimerMs("OPENWEBUI_MODEL_RETRY_MS", 5000);
|
||||
const fetchTimeoutMs = readPositiveTimerMs("OPENWEBUI_FETCH_TIMEOUT_MS", 720000);
|
||||
const controlTimeoutMs = readPositiveTimerMs(
|
||||
"OPENWEBUI_CONTROL_TIMEOUT_MS",
|
||||
Math.min(fetchTimeoutMs, 30000),
|
||||
);
|
||||
const chatTimeoutMs = readPositiveInt("OPENWEBUI_CHAT_TIMEOUT_MS", fetchTimeoutMs);
|
||||
const chatTimeoutMs = readPositiveTimerMs("OPENWEBUI_CHAT_TIMEOUT_MS", fetchTimeoutMs);
|
||||
const responseBodyMaxBytes = readPositiveInt("OPENWEBUI_RESPONSE_BODY_MAX_BYTES", 1024 * 1024);
|
||||
const smokeMode =
|
||||
process.env.OPENWEBUI_SMOKE_MODE ?? process.env.OPENCLAW_OPENWEBUI_SMOKE_MODE ?? "chat";
|
||||
@@ -65,6 +66,20 @@ function readNonNegativeInt(name, fallback) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function clampTimerTimeoutMs(valueMs, minMs = 1) {
|
||||
const min = Math.max(0, Math.floor(minMs));
|
||||
const value = Number.isFinite(valueMs) ? valueMs : min;
|
||||
return Math.min(Math.max(Math.floor(value), min), MAX_TIMER_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
function readPositiveTimerMs(name, fallback) {
|
||||
return clampTimerTimeoutMs(readPositiveInt(name, fallback));
|
||||
}
|
||||
|
||||
function readNonNegativeTimerMs(name, fallback) {
|
||||
return clampTimerTimeoutMs(readNonNegativeInt(name, fallback), 0);
|
||||
}
|
||||
|
||||
function createTimeoutError(label, timeoutMs) {
|
||||
const error = new Error(`${label} timed out after ${timeoutMs}ms`);
|
||||
error.code = "ETIMEDOUT";
|
||||
@@ -72,14 +87,15 @@ function createTimeoutError(label, timeoutMs) {
|
||||
}
|
||||
|
||||
async function withRequestTimeout(label, timeoutMs, run) {
|
||||
const resolvedTimeoutMs = clampTimerTimeoutMs(timeoutMs);
|
||||
const controller = new AbortController();
|
||||
const timeoutError = createTimeoutError(label, timeoutMs);
|
||||
const timeoutError = createTimeoutError(label, resolvedTimeoutMs);
|
||||
let timer;
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
timer = setTimeout(() => {
|
||||
controller.abort(timeoutError);
|
||||
reject(timeoutError);
|
||||
}, timeoutMs);
|
||||
}, resolvedTimeoutMs);
|
||||
timer.unref?.();
|
||||
});
|
||||
try {
|
||||
@@ -138,7 +154,7 @@ function buildAuthHeaders(token, cookie) {
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
setTimeout(resolve, clampTimerTimeoutMs(ms, 0));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { readFileSync } from "node:fs";
|
||||
import { createServer, type IncomingMessage, type Server as HttpServer } from "node:http";
|
||||
import { createServer as createTcpServer, type Server as TcpServer, type Socket } from "node:net";
|
||||
import path from "node:path";
|
||||
import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createBoundedChildOutput } from "../../../helpers/bounded-child-output.js";
|
||||
|
||||
@@ -361,11 +362,13 @@ describe("scripts/e2e/openwebui-probe.mjs", () => {
|
||||
it("passes in models mode when Open WebUI exposes the OpenClaw model", async () => {
|
||||
const server = createServer((request, response) => {
|
||||
if (request.url === "/api/v1/auths/signin") {
|
||||
response.writeHead(200, {
|
||||
"content-type": "application/json",
|
||||
"set-cookie": "openwebui-session=test; Path=/",
|
||||
});
|
||||
response.end(JSON.stringify({ token: "test-token" }));
|
||||
setTimeout(() => {
|
||||
response.writeHead(200, {
|
||||
"content-type": "application/json",
|
||||
"set-cookie": "openwebui-session=test; Path=/",
|
||||
});
|
||||
response.end(JSON.stringify({ token: "test-token" }));
|
||||
}, 25);
|
||||
return;
|
||||
}
|
||||
if (request.url === "/api/models") {
|
||||
@@ -379,7 +382,10 @@ describe("scripts/e2e/openwebui-probe.mjs", () => {
|
||||
});
|
||||
const baseUrl = await listen(server);
|
||||
try {
|
||||
const result = await runProbe(baseUrl);
|
||||
const result = await runProbe(baseUrl, {
|
||||
OPENWEBUI_CONTROL_TIMEOUT_MS: String(MAX_TIMER_TIMEOUT_MS + 1),
|
||||
OPENWEBUI_FETCH_TIMEOUT_MS: String(MAX_TIMER_TIMEOUT_MS + 1),
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(JSON.parse(result.stdout)).toMatchObject({
|
||||
|
||||
Reference in New Issue
Block a user