diff --git a/apps/server/src/config.ts b/apps/server/src/config.ts index 720d8ea96..c8efda0b3 100644 --- a/apps/server/src/config.ts +++ b/apps/server/src/config.ts @@ -79,6 +79,13 @@ export function assertApiDeploymentConfig( ); } +/** Accept a full worker URL, or host:port from a platform that omits the scheme. */ +export function browserWorkerUrl(value?: string): string | undefined { + const trimmed = value?.trim(); + if (!trimmed) return undefined; + return trimmed.includes("://") ? trimmed : `http://${trimmed}`; +} + // Provider SDKs retry transient failures before the response starts, with // exponential backoff: OpenAI and Anthropic retry HTTP 408, 409, 429, 5xx and // connection errors and honor retry-after; Gemini retries 408, 429, 500, 502, @@ -124,7 +131,7 @@ export function readConfig(): Config { googleClientId: process.env.GOOGLE_CLIENT_ID, googleClientSecret: process.env.GOOGLE_CLIENT_SECRET, googleRedirectUri: `${publicUrl}/api/google/callback`, - workerUrl: process.env.BROWSER_WORKER_URL, + workerUrl: browserWorkerUrl(process.env.BROWSER_WORKER_URL), workerToken: process.env.WORKER_TOKEN, taskWorkerEnabled: process.env.TASK_WORKER_ENABLED !== "false", computerEnabled: process.env.COMPUTER_ENABLED === "true", diff --git a/tests/config.test.ts b/tests/config.test.ts index 3e38f2241..148720749 100644 --- a/tests/config.test.ts +++ b/tests/config.test.ts @@ -2,6 +2,7 @@ import assert from "node:assert/strict"; import { test } from "node:test"; import { assertApiDeploymentConfig, + browserWorkerUrl, type Config, shadowedEnvKeys, } from "../apps/server/src/config.ts"; @@ -79,6 +80,14 @@ test("Jev mode is off by default and validates explicit modes", async () => { } }); +test("browser worker URL keeps an existing scheme and adds http to host:port", () => { + assert.equal(browserWorkerUrl(undefined), undefined); + assert.equal(browserWorkerUrl(" "), undefined); + assert.equal(browserWorkerUrl("http://127.0.0.1:8790"), "http://127.0.0.1:8790"); + assert.equal(browserWorkerUrl("https://browser.internal:8790"), "https://browser.internal:8790"); + assert.equal(browserWorkerUrl("openmuse-browser-h4fx:8790"), "http://openmuse-browser-h4fx:8790"); +}); + test("environment variables that override a different .env value are reported by name", () => { const file = { OPENAI_API_KEY: "sk-or-file", MODEL: "openai/gpt-5", PORT: "8787", EMPTY: "" }; const env = { OPENAI_API_KEY: "sk-proj-system", MODEL: "openai/gpt-5", EMPTY: "set" };