From a4b92768d927694c042d468488484d1864081116 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 13 Aug 2026 18:51:37 +0200 Subject: [PATCH] fix(providers): allow two minutes for catalog refreshes Provider catalog discovery can exceed one minute during cold startup. Increase the default deadline while preserving explicit config and environment overrides. --- docs/custom-providers.md | 2 +- .../agent/provider-snapshot-manager.test.ts | 34 +++++++++++++++++++ .../server/agent/provider-snapshot-manager.ts | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/custom-providers.md b/docs/custom-providers.md index acf882657..924d1bc06 100644 --- a/docs/custom-providers.md +++ b/docs/custom-providers.md @@ -17,7 +17,7 @@ Provider definitions live under `agents.providers` in config.json: Provider IDs must be lowercase alphanumeric with hyphens (`/^[a-z][a-z0-9-]*$/`). -Each provider catalog refresh waits up to 60 seconds. If a provider loads many plugins or a large +Each provider catalog refresh waits up to 2 minutes. If a provider loads many plugins or a large agent catalog during startup, raise the limit in milliseconds: ```json diff --git a/packages/server/src/server/agent/provider-snapshot-manager.test.ts b/packages/server/src/server/agent/provider-snapshot-manager.test.ts index ed67290b0..a73d8f3e0 100644 --- a/packages/server/src/server/agent/provider-snapshot-manager.test.ts +++ b/packages/server/src/server/agent/provider-snapshot-manager.test.ts @@ -442,6 +442,40 @@ describe("ProviderSnapshotManager public surface", () => { } }); + test("defaults provider refreshes to a two-minute deadline", async () => { + vi.useFakeTimers(); + const manager = new ProviderSnapshotManager({ + logger: createTestLogger(), + providerOverrides: { + claude: { enabled: false }, + copilot: { enabled: false }, + opencode: { enabled: false }, + pi: { enabled: false }, + }, + extraClients: { + codex: createExtraClient("codex", { isAvailable: waitUntilAborted }), + }, + }); + + try { + const entryPromise = manager.getProvider({ + cwd: "/tmp/project", + provider: "codex", + wait: true, + }); + + await vi.advanceTimersByTimeAsync(120_000); + + await expect(entryPromise).resolves.toMatchObject({ + status: "error", + error: "Timed out refreshing Codex after 120000ms; pending: availability", + }); + } finally { + manager.destroy(); + vi.useRealTimers(); + } + }); + test("one refresh timeout covers availability and catalog discovery", async () => { vi.useFakeTimers(); const manager = new ProviderSnapshotManager({ diff --git a/packages/server/src/server/agent/provider-snapshot-manager.ts b/packages/server/src/server/agent/provider-snapshot-manager.ts index 60f7850a6..f0985348a 100644 --- a/packages/server/src/server/agent/provider-snapshot-manager.ts +++ b/packages/server/src/server/agent/provider-snapshot-manager.ts @@ -45,7 +45,7 @@ import { validateAgentConfigurationAgainstProvider, } from "./agent-configuration-validator.js"; -const DEFAULT_REFRESH_TIMEOUT_MS = 60_000; +const DEFAULT_REFRESH_TIMEOUT_MS = 120_000; const MAX_REFRESH_TIMEOUT_MS = 2_147_483_647; const DEFAULT_DIAGNOSTIC_TIMEOUT_MS = 120_000; const REFRESH_TIMEOUT_ENV_VAR = "PASEO_PROVIDER_REFRESH_TIMEOUT_MS";