From 315803688dea43676a038cbdd2f4a9dcb4bbd14f Mon Sep 17 00:00:00 2001 From: "paseo-bot[bot]" <266920839+paseo-bot[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:10:09 +0200 Subject: [PATCH] Update and restart a daemon whose provider checks take over 1.5s (#5372) The host settings Update and Restart buttons read the worker's status before sending the request, with a 1500 ms timeout. The daemon answers status only after probing each provider CLI with --version, which may take up to 2 s per provider. On a host where one provider CLI starts slowly, the pre-check always timed out and the request was never sent. Read the status with the client's default request timeout, the same full status read the supervisor restart test already exercises. Closes #5367 Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com> --- .../app/e2e/browser/daemon-lifecycle.spec.ts | 39 +++++++++++++++++++ .../app/src/screens/settings/host-page.tsx | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/app/e2e/browser/daemon-lifecycle.spec.ts b/packages/app/e2e/browser/daemon-lifecycle.spec.ts index 440b22d3e0..bded30cb81 100644 --- a/packages/app/e2e/browser/daemon-lifecycle.spec.ts +++ b/packages/app/e2e/browser/daemon-lifecycle.spec.ts @@ -1,4 +1,7 @@ import { randomUUID } from "node:crypto"; +import { mkdtemp, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; import { expect, test } from "../support/fixtures"; import { startIsolatedHostDaemon } from "../support/helpers/isolated-host-daemon"; import { @@ -25,3 +28,39 @@ test("settings restart waits for a replacement worker while retaining the superv await daemon.close(); } }); + +test("settings restart replaces the worker when a provider CLI answers --version slowly", async ({ + page, +}) => { + test.skip(process.platform === "win32", "The slow provider stub is a POSIX script"); + const daemon = await startIsolatedHostDaemon(randomUUID(), { + paseoHome: await createHomeWithSlowProvider(1_800), + }); + try { + const previousWorker = await readWorkerPid(daemon); + await openDaemonOverview(page, daemon); + await restartDaemonInSettings(page); + await expectDaemonRestartComplete(page); + expect(await readWorkerPid(daemon)).not.toBe(previousWorker); + } finally { + await daemon.close(); + } +}); + +async function createHomeWithSlowProvider(versionDelayMs: number): Promise { + const paseoHome = await mkdtemp(path.join(tmpdir(), "paseo-e2e-slow-provider-")); + const provider = path.join(paseoHome, "slow-provider"); + await writeFile( + provider, + `#!${process.execPath}\nsetTimeout(() => console.log("provider 1.0.0"), ${versionDelayMs});\n`, + { mode: 0o700 }, + ); + await writeFile( + path.join(paseoHome, "config.json"), + `${JSON.stringify({ + version: 1, + agents: { providers: { claude: { command: { mode: "replace", argv: [provider] } } } }, + })}\n`, + ); + return paseoHome; +} diff --git a/packages/app/src/screens/settings/host-page.tsx b/packages/app/src/screens/settings/host-page.tsx index 23c7815294..c080e60de1 100644 --- a/packages/app/src/screens/settings/host-page.tsx +++ b/packages/app/src/screens/settings/host-page.tsx @@ -622,7 +622,7 @@ function RestartDaemonCard({ host }: { host: HostProfile }) { { restartServer: (reason) => daemonClient.restartServer(reason), getStatus: async () => ({ - ...(await daemonClient.getDaemonStatus({ timeout: 1500 })), + ...(await daemonClient.getDaemonStatus()), serverId: daemonClient.getLastServerInfoMessage()?.serverId ?? "", version: daemonClient.getLastServerInfoMessage()?.version ?? null, }), @@ -766,7 +766,7 @@ function UpdateDaemonCard({ host }: { host: HostProfile }) { void updateDaemonFromSettings(host.serverId, { updateDaemon: () => daemonClient.updateDaemon(requestId), getStatus: async () => ({ - ...(await daemonClient.getDaemonStatus({ timeout: 1500 })), + ...(await daemonClient.getDaemonStatus()), serverId: daemonClient.getLastServerInfoMessage()?.serverId ?? "", version: daemonClient.getLastServerInfoMessage()?.version ?? null, }),