diff --git a/tests/unit/blackbox-web.test.ts b/tests/unit/blackbox-web.test.ts index cd7f88704c..049a6f7530 100644 --- a/tests/unit/blackbox-web.test.ts +++ b/tests/unit/blackbox-web.test.ts @@ -59,11 +59,11 @@ function mockFetchCapture(status = 200, text = "Hello from Blackbox") { }; } -test("BlackboxWebExecutor is registered in executor index", () => { +test("BlackboxWebExecutor is registered in executor index", async () => { assert.ok(hasSpecializedExecutor("blackbox-web")); assert.ok(hasSpecializedExecutor("bb-web")); - const executor = getExecutor("blackbox-web"); - const alias = getExecutor("bb-web"); + const executor = await getExecutor("blackbox-web"); + const alias = await getExecutor("bb-web"); assert.ok(executor instanceof BlackboxWebExecutor); assert.ok(alias instanceof BlackboxWebExecutor); }); diff --git a/tests/unit/chatcore-executor-proxy.test.ts b/tests/unit/chatcore-executor-proxy.test.ts index a67e23a4f1..dd4cc6e2fa 100644 --- a/tests/unit/chatcore-executor-proxy.test.ts +++ b/tests/unit/chatcore-executor-proxy.test.ts @@ -41,7 +41,7 @@ after(() => { test("no config (disabled by default) returns the provider's own executor", async () => { clearUpstreamProxyConfigCache("openai"); const exec = await resolveExecutorWithProxy("openai"); - assert.equal(exec, getExecutor("openai")); + assert.equal(exec, await getExecutor("openai")); }); test("mode 'native' returns the provider's own executor", async () => { @@ -52,7 +52,7 @@ test("mode 'native' returns the provider's own executor", async () => { }); clearUpstreamProxyConfigCache("openai"); const exec = await resolveExecutorWithProxy("openai"); - assert.equal(exec, getExecutor("openai")); + assert.equal(exec, await getExecutor("openai")); }); test("mode 'cliproxyapi' returns the CLIProxyAPI passthrough executor", async () => { @@ -63,7 +63,7 @@ test("mode 'cliproxyapi' returns the CLIProxyAPI passthrough executor", async () }); clearUpstreamProxyConfigCache("anthropic"); const exec = await resolveExecutorWithProxy("anthropic"); - assert.equal(exec, getExecutor("cliproxyapi")); + assert.equal(exec, await getExecutor("cliproxyapi")); }); test("mode 'fallback' returns a distinct wrapper owning its own execute()", async () => { @@ -74,8 +74,8 @@ test("mode 'fallback' returns a distinct wrapper owning its own execute()", asyn }); clearUpstreamProxyConfigCache("openai"); const exec = await resolveExecutorWithProxy("openai"); - assert.notEqual(exec, getExecutor("openai")); - assert.notEqual(exec, getExecutor("cliproxyapi")); + assert.notEqual(exec, await getExecutor("openai")); + assert.notEqual(exec, await getExecutor("cliproxyapi")); assert.equal(typeof exec.execute, "function"); }); @@ -94,7 +94,7 @@ test("connection override 'claude-native' selects CLIProxyAPI even when provider const exec = await resolveExecutorWithProxy("openai", undefined, { cliproxyapiMode: "claude-native", }); - assert.equal(exec, getExecutor("cliproxyapi")); + assert.equal(exec, await getExecutor("cliproxyapi")); }); test("connection override 'claude-native' selects CLIProxyAPI even with no provider config (default)", async () => { @@ -102,7 +102,7 @@ test("connection override 'claude-native' selects CLIProxyAPI even with no provi const exec = await resolveExecutorWithProxy("anthropic", undefined, { cliproxyapiMode: "claude-native", }); - assert.equal(exec, getExecutor("cliproxyapi")); + assert.equal(exec, await getExecutor("cliproxyapi")); }); test("no connection override + provider mode native → native executor (unchanged)", async () => { @@ -115,13 +115,13 @@ test("no connection override + provider mode native → native executor (unchang const exec = await resolveExecutorWithProxy("openai", undefined, { someOtherField: "x", }); - assert.equal(exec, getExecutor("openai")); + assert.equal(exec, await getExecutor("openai")); }); test("connection override absent (undefined providerSpecificData) preserves default behaviour", async () => { clearUpstreamProxyConfigCache("openai"); const exec = await resolveExecutorWithProxy("openai"); - assert.equal(exec, getExecutor("openai")); + assert.equal(exec, await getExecutor("openai")); }); test("connection override wins over provider mode 'fallback'", async () => { @@ -135,5 +135,5 @@ test("connection override wins over provider mode 'fallback'", async () => { cliproxyapiMode: "claude-native", }); // Connection override short-circuits to the passthrough executor, not the fallback wrapper. - assert.equal(exec, getExecutor("cliproxyapi")); + assert.equal(exec, await getExecutor("cliproxyapi")); }); diff --git a/tests/unit/chatcore-translation-paths.test.ts b/tests/unit/chatcore-translation-paths.test.ts index 6ecb048788..aa4fce1922 100644 --- a/tests/unit/chatcore-translation-paths.test.ts +++ b/tests/unit/chatcore-translation-paths.test.ts @@ -456,7 +456,7 @@ test("chatCore times out upstream execution before provider response headers", a // (fresh-DB default leaves it off → the waitFor below would never resolve; // failed deterministically on CI and on an isolated run, incl. at v3.8.18). await settingsDb.updateSettings({ call_log_pipeline_enabled: true }); - const executor = getExecutor("openai"); + const executor = await getExecutor("openai"); const originalGetTimeoutMs = executor.getTimeoutMs?.bind(executor); executor.getTimeoutMs = () => 200; diff --git a/tests/unit/chatgpt-web.test.ts b/tests/unit/chatgpt-web.test.ts index 267c0eb6dc..13814f1353 100644 --- a/tests/unit/chatgpt-web.test.ts +++ b/tests/unit/chatgpt-web.test.ts @@ -370,16 +370,16 @@ function reset() { // ─── Registration ─────────────────────────────────────────────────────────── -test("ChatGptWebExecutor is registered in executor index", () => { +test("ChatGptWebExecutor is registered in executor index", async () => { assert.ok(hasSpecializedExecutor("chatgpt-web")); assert.ok(hasSpecializedExecutor("cgpt-web")); - const executor = getExecutor("chatgpt-web"); + const executor = await getExecutor("chatgpt-web"); assert.ok(executor instanceof ChatGptWebExecutor); }); -test("ChatGptWebExecutor alias resolves to same type", () => { - const a = getExecutor("chatgpt-web"); - const b = getExecutor("cgpt-web"); +test("ChatGptWebExecutor alias resolves to same type", async () => { + const a = await getExecutor("chatgpt-web"); + const b = await getExecutor("cgpt-web"); assert.ok(a instanceof ChatGptWebExecutor); assert.ok(b instanceof ChatGptWebExecutor); }); diff --git a/tests/unit/chipotle-executor.test.ts b/tests/unit/chipotle-executor.test.ts index 07a093cd01..ff0f1308b9 100644 --- a/tests/unit/chipotle-executor.test.ts +++ b/tests/unit/chipotle-executor.test.ts @@ -63,14 +63,14 @@ describe("ChipotleExecutor", () => { it("is registered in executor index", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const exec = getExecutor("chipotle"); + const exec = await getExecutor("chipotle"); assert.ok(exec, "chipotle executor should be registered"); assert.ok(exec instanceof ChipotleExecutor); }); it("pepper alias works", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const exec = getExecutor("pepper"); + const exec = await getExecutor("pepper"); assert.ok(exec, "pepper alias should be registered"); assert.ok(exec instanceof ChipotleExecutor); }); diff --git a/tests/unit/claude-web.test.ts b/tests/unit/claude-web.test.ts index 043ff129e6..1ec40feb13 100644 --- a/tests/unit/claude-web.test.ts +++ b/tests/unit/claude-web.test.ts @@ -22,14 +22,14 @@ test("B: ClaudeWebExecutor alias cw-web is registered", () => { assert.ok(hasSpecializedExecutor("cw-web")); }); -test("C: ClaudeWebExecutor can be retrieved from executor registry", () => { - const executor = getExecutor("claude-web"); +test("C: ClaudeWebExecutor can be retrieved from executor registry", async () => { + const executor = await getExecutor("claude-web"); assert.ok(executor instanceof ClaudeWebExecutor); }); -test("D: ClaudeWebExecutor cw-web alias resolves to same type", () => { - const a = getExecutor("claude-web"); - const b = getExecutor("cw-web"); +test("D: ClaudeWebExecutor cw-web alias resolves to same type", async () => { + const a = await getExecutor("claude-web"); + const b = await getExecutor("cw-web"); assert.ok(a instanceof ClaudeWebExecutor); assert.ok(b instanceof ClaudeWebExecutor); }); diff --git a/tests/unit/codex-quota-sync-no-proactive-refresh.test.ts b/tests/unit/codex-quota-sync-no-proactive-refresh.test.ts index e82f9de0dc..9a2e7496a5 100644 --- a/tests/unit/codex-quota-sync-no-proactive-refresh.test.ts +++ b/tests/unit/codex-quota-sync-no-proactive-refresh.test.ts @@ -31,7 +31,7 @@ const { getExecutor } = await import("../../open-sse/executors/index.ts"); const { refreshAndUpdateCredentials } = await import("../../src/lib/usage/providerLimits.ts"); test("codex: quota-sync must NOT proactively rotate the refresh_token (Auth0 family-revocation cascade guard)", async () => { - const exec = getExecutor("codex"); + const exec = await getExecutor("codex"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; let refreshCalls = 0; @@ -68,7 +68,7 @@ test("codex: quota-sync must NOT proactively rotate the refresh_token (Auth0 fam }); test("non-rotating OAuth provider is still refreshed proactively from quota-sync (gate is not over-broad)", async () => { - const exec = getExecutor("cursor"); + const exec = await getExecutor("cursor"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; let refreshCalls = 0; diff --git a/tests/unit/command-code-executor.test.ts b/tests/unit/command-code-executor.test.ts index e9b305468d..14cb0ae5a6 100644 --- a/tests/unit/command-code-executor.test.ts +++ b/tests/unit/command-code-executor.test.ts @@ -91,15 +91,15 @@ test("Command Code provider catalog has pinned models and alias lookup", () => { assert.equal(getRegistryEntry("cmd"), entry); }); -test("getExecutor returns the specialized Command Code executor", () => { +test("getExecutor returns the specialized Command Code executor", async () => { assert.equal(hasSpecializedExecutor("command-code"), true); - assert.ok(getExecutor("command-code") instanceof CommandCodeExecutor); - assert.ok(getExecutor("cmd") instanceof CommandCodeExecutor); + assert.ok((await getExecutor("command-code")) instanceof CommandCodeExecutor); + assert.ok((await getExecutor("cmd")) instanceof CommandCodeExecutor); }); test("Command Code executor posts a flat OpenAI body + standard headers to /provider/v1/chat/completions (#10265)", async () => { const calls = captureFetch({}); - const executor = getExecutor("command-code"); + const executor = await getExecutor("command-code"); const { response, url, headers } = await executor.execute({ model: "gpt-5.4-mini", stream: false, @@ -143,7 +143,7 @@ test("Command Code executor posts a flat OpenAI body + standard headers to /prov test("Command Code executor passes reasoning/thinking fields through at the top level of the OpenAI body", async () => { const calls = captureFetch({}); - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "deepseek/deepseek-v4-pro", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -166,7 +166,7 @@ test("Command Code executor passes reasoning/thinking fields through at the top test("Command Code executor honors body.model rewrite from payload rules", async () => { const calls = captureFetch({}); - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "deepseek-v4-pro-max", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -187,7 +187,7 @@ test("Command Code executor maps unsupported minimal reasoning_effort to low (up const calls = captureFetch({}); // `minimal` (a Muse Spark catalog tier) must be downgraded to `low` before // the wire body is built, on BOTH the combo and single-model paths. - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "poolside/laguna-s-2.1-free", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -232,7 +232,7 @@ test("Command Code executor passes the upstream OpenAI SSE stream through untouc }); }; - const { response } = await getExecutor("command-code").execute({ + const { response } = (await getExecutor("command-code")).execute({ model: "gpt-5.4", stream: true, credentials: { apiKey: "cc_test_key" }, @@ -266,7 +266,7 @@ test("Command Code executor passes the upstream OpenAI JSON through untouched (n }); }; - const { response } = await getExecutor("command-code").execute({ + const { response } = (await getExecutor("command-code")).execute({ model: "gpt-5.4-mini", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -279,7 +279,7 @@ test("Command Code executor passes the upstream OpenAI JSON through untouched (n test("Command Code executor surfaces upstream errors", async () => { globalThis.fetch = async () => new Response("bad key", { status: 401, statusText: "Unauthorized" }); - const upstreamFailure = await getExecutor("command-code").execute({ + const upstreamFailure = (await getExecutor("command-code")).execute({ model: "gpt-5.4-mini", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -291,7 +291,7 @@ test("Command Code executor surfaces upstream errors", async () => { test("Command Code executor omits max_tokens when the client does not supply one", async () => { const calls = captureFetch({}); - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "zai-org/GLM-5.1", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -305,7 +305,7 @@ test("Command Code executor omits max_tokens when the client does not supply one test("Command Code executor clamps an oversized client-supplied max_tokens to the endpoint ceiling", async () => { const calls = captureFetch({}); // A client asking for more than the 200000 endpoint ceiling is clamped down. - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "deepseek/deepseek-v4-pro", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -316,7 +316,7 @@ test("Command Code executor clamps an oversized client-supplied max_tokens to th test("Command Code executor honors a smaller client-provided max_tokens", async () => { const calls = captureFetch({}); - await getExecutor("command-code").execute({ + (await getExecutor("command-code")).execute({ model: "zai-org/GLM-5.1", stream: false, credentials: { apiKey: "cc_test_key" }, @@ -350,7 +350,7 @@ test("Command Code stream preserves the upstream OpenAI usage chunk (passthrough globalThis.fetch = async () => new Response(sse, { status: 200, headers: { "Content-Type": "text/event-stream" } }); - const { response } = await getExecutor("command-code").execute({ + const { response } = (await getExecutor("command-code")).execute({ model: "gpt-5.4-mini", stream: true, credentials: { apiKey: "cc_test_key" }, diff --git a/tests/unit/deepseek-web.test.ts b/tests/unit/deepseek-web.test.ts index af1fc82c49..17266edf00 100644 --- a/tests/unit/deepseek-web.test.ts +++ b/tests/unit/deepseek-web.test.ts @@ -18,13 +18,13 @@ test("DeepSeekWebExecutor registered as deepseek-web and ds-web", () => { assert.ok(hasSpecializedExecutor("ds-web")); }); -test("getExecutor returns DeepSeekWebWithAutoRefreshExecutor", () => { - const exec = getExecutor("deepseek-web"); +test("getExecutor returns DeepSeekWebWithAutoRefreshExecutor", async () => { + const exec = await getExecutor("deepseek-web"); assert.ok(exec instanceof DeepSeekWebWithAutoRefreshExecutor); }); -test("alias ds-web resolves same executor", () => { - assert.ok(getExecutor("ds-web") instanceof DeepSeekWebWithAutoRefreshExecutor); +test("alias ds-web resolves same executor", async () => { + assert.ok(await getExecutor("ds-web") instanceof DeepSeekWebWithAutoRefreshExecutor); }); test("provider name is deepseek-web", () => { diff --git a/tests/unit/duckduckgo-web-executor.test.ts b/tests/unit/duckduckgo-web-executor.test.ts index 5469185cc7..62438cae1e 100644 --- a/tests/unit/duckduckgo-web-executor.test.ts +++ b/tests/unit/duckduckgo-web-executor.test.ts @@ -241,7 +241,7 @@ describe("DuckDuckGoWebExecutor", () => { it("should be registered in executor index", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const executor = getExecutor("duckduckgo-web"); + const executor = await getExecutor("duckduckgo-web"); assert.ok(executor, "executor should be registered in index"); assert.equal( typeof executor.execute, diff --git a/tests/unit/executor-registry.test.ts b/tests/unit/executor-registry.test.ts index c05128681b..b1c82c8099 100644 --- a/tests/unit/executor-registry.test.ts +++ b/tests/unit/executor-registry.test.ts @@ -21,13 +21,13 @@ test.after(() => { fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true }); }); -test("built-ins are registered at module load and resolve through the registry", () => { +test("built-ins are registered at module load and resolve through the registry", async () => { const aliases = listExecutorAliases(); assert.ok(aliases.length >= 100, `expected the built-in table, got ${aliases.length} aliases`); for (const alias of ["antigravity", "kiro", "glm", "9router", "conol-web"]) { assert.ok(hasRegisteredExecutor(alias), `missing built-in: ${alias}`); - assert.equal(getExecutor(alias), getRegisteredExecutor(alias)); - assert.ok(getExecutor(alias) instanceof BaseExecutor); + assert.equal(await getExecutor(alias), getRegisteredExecutor(alias)); + assert.ok((await getExecutor(alias)) instanceof BaseExecutor); } }); @@ -37,21 +37,21 @@ test("registerExecutor throws on duplicate alias", () => { }); }); -test("registering a new alias makes it resolvable via getExecutor and hasSpecializedExecutor", () => { +test("registering a new alias makes it resolvable via getExecutor and hasSpecializedExecutor", async () => { const alias = "registry-test-provider"; assert.equal(hasSpecializedExecutor(alias), false); const instance = new DefaultExecutor(alias); registerExecutor(alias, instance); assert.equal(hasSpecializedExecutor(alias), true); - assert.equal(getExecutor(alias), instance); + assert.equal(await getExecutor(alias), instance); }); -test("registry lookup is exact — Object.prototype names are not executors", () => { +test("registry lookup is exact — Object.prototype names are not executors", async () => { // The old object-literal lookup (`executors[provider]`) leaked prototype // members: getExecutor("constructor") returned Object's constructor. The Map // registry must treat these as unknown providers (DefaultExecutor fallback). for (const name of ["constructor", "toString", "hasOwnProperty", "__proto__"]) { assert.equal(hasSpecializedExecutor(name), false, name); - assert.ok(getExecutor(name) instanceof DefaultExecutor, name); + assert.ok((await getExecutor(name)) instanceof DefaultExecutor, name); } }); diff --git a/tests/unit/free-tier-providers-phase3-integration.test.ts b/tests/unit/free-tier-providers-phase3-integration.test.ts index 89c3141d8b..6bbf9d5862 100644 --- a/tests/unit/free-tier-providers-phase3-integration.test.ts +++ b/tests/unit/free-tier-providers-phase3-integration.test.ts @@ -20,7 +20,7 @@ const providers = [ ] as const; for (const [id, alias, endpoint] of providers) { - test(`${id} is wired through registry, metadata, endpoint and default executor`, () => { + test(`${id} is wired through registry, metadata, endpoint and default executor`, async () => { const registry = REGISTRY[id]; const metadata = APIKEY_PROVIDERS[id]; @@ -35,7 +35,7 @@ for (const [id, alias, endpoint] of providers) { assert.equal(metadata.hasFree, true); assert.equal(metadata.passthroughModels, true); assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0); - assert.ok(getExecutor(id) instanceof DefaultExecutor); + assert.ok((await getExecutor(id)) instanceof DefaultExecutor); assert.equal(isValidModel(id, "future/live-catalog-model"), true); assert.equal(isValidModel(alias, "future/live-catalog-model"), true); }); diff --git a/tests/unit/free-tier-providers-wave2-integration.test.ts b/tests/unit/free-tier-providers-wave2-integration.test.ts index 83128bd3c0..aeca3ab67b 100644 --- a/tests/unit/free-tier-providers-wave2-integration.test.ts +++ b/tests/unit/free-tier-providers-wave2-integration.test.ts @@ -25,7 +25,7 @@ const providers = [ ] as const; for (const [id, endpoint, modelIds] of providers) { - test(`${id} is wired through registry, metadata, endpoint and default executor`, () => { + test(`${id} is wired through registry, metadata, endpoint and default executor`, async () => { const registry = REGISTRY[id]; const metadata = APIKEY_PROVIDERS[id]; @@ -41,7 +41,7 @@ for (const [id, endpoint, modelIds] of providers) { assert.equal(metadata.passthroughModels, true); assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0); assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true); - assert.ok(getExecutor(id) instanceof DefaultExecutor); + assert.ok((await getExecutor(id)) instanceof DefaultExecutor); assert.equal(isValidModel(id, "future/live-catalog-model"), true); assert.deepEqual( registry.models.map((model) => model.id), diff --git a/tests/unit/free-tier-providers-wave3-integration.test.ts b/tests/unit/free-tier-providers-wave3-integration.test.ts index ec8ae79cf3..41a84082df 100644 --- a/tests/unit/free-tier-providers-wave3-integration.test.ts +++ b/tests/unit/free-tier-providers-wave3-integration.test.ts @@ -20,7 +20,7 @@ const providers = [ ] as const; for (const [id, endpoint] of providers) { - test(`${id} is wired through registry, metadata, endpoint and default executor`, () => { + test(`${id} is wired through registry, metadata, endpoint and default executor`, async () => { const registry = REGISTRY[id]; const metadata = APIKEY_PROVIDERS[id]; @@ -36,7 +36,8 @@ for (const [id, endpoint] of providers) { assert.equal(metadata.passthroughModels, true); assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0); assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true); - assert.ok(getExecutor(id) instanceof DefaultExecutor); + const executor = await getExecutor(id); + assert.ok(executor instanceof DefaultExecutor); assert.equal(isValidModel(id, "future/live-catalog-model"), true); assert.deepEqual(registry.models, []); }); diff --git a/tests/unit/free-tier-providers-wave4-integration.test.ts b/tests/unit/free-tier-providers-wave4-integration.test.ts index 743e188271..dd3a96a7b4 100644 --- a/tests/unit/free-tier-providers-wave4-integration.test.ts +++ b/tests/unit/free-tier-providers-wave4-integration.test.ts @@ -17,7 +17,7 @@ const providers = [ ] as const; for (const [id, endpoint] of providers) { - test(`${id} is fully wired without a specialized executor`, () => { + test(`${id} is fully wired without a specialized executor`, async () => { const registry = REGISTRY[id]; const metadata = APIKEY_PROVIDERS[id]; @@ -33,7 +33,7 @@ for (const [id, endpoint] of providers) { assert.equal(metadata.passthroughModels, true); assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true); assert.equal(hasSpecializedExecutor(id), false); - const executor = getExecutor(id); + const executor = await getExecutor(id); assert.ok(executor instanceof DefaultExecutor); assert.equal(executor.buildUrl("live-model", false), endpoint); assert.equal(isValidModel(id, "future/live-catalog-model"), true); diff --git a/tests/unit/free-tier-providers-wave5-integration.test.ts b/tests/unit/free-tier-providers-wave5-integration.test.ts index 48d24c2081..02a2bbc4b1 100644 --- a/tests/unit/free-tier-providers-wave5-integration.test.ts +++ b/tests/unit/free-tier-providers-wave5-integration.test.ts @@ -27,7 +27,7 @@ const providers = [ ] as const; for (const { id, endpoint, modelsUrl, hasFree } of providers) { - test(`${id} is fully wired through the public provider interfaces`, () => { + test(`${id} is fully wired through the public provider interfaces`, async () => { const registry = REGISTRY[id]; const metadata = APIKEY_PROVIDERS[id]; @@ -52,7 +52,7 @@ for (const { id, endpoint, modelsUrl, hasFree } of providers) { assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true); assert.equal(hasSpecializedExecutor(id), false); - const executor = getExecutor(id); + const executor = await getExecutor(id); assert.ok(executor instanceof DefaultExecutor); assert.equal(executor.buildUrl("live-model", false), endpoint); assert.equal(isValidModel(id, "future/live-catalog-model"), true); diff --git a/tests/unit/g4f-space-gateway-6650.test.ts b/tests/unit/g4f-space-gateway-6650.test.ts index bf946886c6..728b436699 100644 --- a/tests/unit/g4f-space-gateway-6650.test.ts +++ b/tests/unit/g4f-space-gateway-6650.test.ts @@ -73,8 +73,8 @@ for (const [id, subPath] of Object.entries(SUB_PATHS)) { ); }); - test(`#6650 ${id} resolves through getExecutor() as a DefaultExecutor instance`, () => { - const executor = getExecutor(id); + test(`#6650 ${id} resolves through getExecutor() as a DefaultExecutor instance`, async () => { + const executor = await getExecutor(id); assert.ok( executor instanceof DefaultExecutor, `${id} has no custom executor — must fall through to DefaultExecutor` diff --git a/tests/unit/gemini-web.test.ts b/tests/unit/gemini-web.test.ts index b8f31f4faa..bab367a1c1 100644 --- a/tests/unit/gemini-web.test.ts +++ b/tests/unit/gemini-web.test.ts @@ -7,9 +7,9 @@ const { getExecutor, hasSpecializedExecutor } = await import("../../open-sse/exe // ─── Registration ─────────────────────────────────────────────────────────── -test("GeminiWebExecutor is registered in executor index", () => { +test("GeminiWebExecutor is registered in executor index", async () => { assert.ok(hasSpecializedExecutor("gemini-web")); - const executor = getExecutor("gemini-web"); + const executor = await getExecutor("gemini-web"); assert.ok(executor instanceof GeminiWebExecutor); }); diff --git a/tests/unit/grok-web.test.ts b/tests/unit/grok-web.test.ts index e87d9c74a5..273e728179 100644 --- a/tests/unit/grok-web.test.ts +++ b/tests/unit/grok-web.test.ts @@ -83,9 +83,9 @@ test.afterEach(() => { // ─── Registration ─────────────────────────────────────────────────────────── -test("GrokWebExecutor is registered in executor index", () => { +test("GrokWebExecutor is registered in executor index", async () => { assert.ok(hasSpecializedExecutor("grok-web")); - const executor = getExecutor("grok-web"); + const executor = await getExecutor("grok-web"); assert.ok(executor instanceof GrokWebExecutor); }); diff --git a/tests/unit/ninerouter-executor.test.ts b/tests/unit/ninerouter-executor.test.ts index 3a9ef88e76..515077d6cc 100644 --- a/tests/unit/ninerouter-executor.test.ts +++ b/tests/unit/ninerouter-executor.test.ts @@ -498,13 +498,13 @@ describe("NineRouterExecutor", () => { describe("getExecutor registration", () => { it("getExecutor('9router') returns a NineRouterExecutor", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const exec = getExecutor("9router"); + const exec = await getExecutor("9router"); assert.equal(exec.getProvider(), "9router"); }); it("getExecutor('nr') alias resolves to NineRouterExecutor", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const exec = getExecutor("nr"); + const exec = await getExecutor("nr"); assert.equal(exec.getProvider(), "9router"); }); }); diff --git a/tests/unit/perplexity-web.test.ts b/tests/unit/perplexity-web.test.ts index f6f4b7f7a7..1ab1ab3d10 100644 --- a/tests/unit/perplexity-web.test.ts +++ b/tests/unit/perplexity-web.test.ts @@ -91,16 +91,16 @@ function mockFetchError(error) { // ─── Test: Executor registration ──────────────────────────────────────────── -test("PerplexityWebExecutor is registered in executor index", () => { +test("PerplexityWebExecutor is registered in executor index", async () => { assert.ok(hasSpecializedExecutor("perplexity-web")); assert.ok(hasSpecializedExecutor("pplx-web")); - const executor = getExecutor("perplexity-web"); + const executor = await getExecutor("perplexity-web"); assert.ok(executor instanceof PerplexityWebExecutor); }); -test("PerplexityWebExecutor alias resolves to same type", () => { - const a = getExecutor("perplexity-web"); - const b = getExecutor("pplx-web"); +test("PerplexityWebExecutor alias resolves to same type", async () => { + const a = await getExecutor("perplexity-web"); + const b = await getExecutor("pplx-web"); assert.ok(a instanceof PerplexityWebExecutor); assert.ok(b instanceof PerplexityWebExecutor); }); diff --git a/tests/unit/poe-api-executor-regression.test.ts b/tests/unit/poe-api-executor-regression.test.ts index 8ce969b981..85cda39850 100644 --- a/tests/unit/poe-api-executor-regression.test.ts +++ b/tests/unit/poe-api-executor-regression.test.ts @@ -47,17 +47,18 @@ function headerRecord(headers: Record): Record { return out; } -test("#8969: getExecutor(poe) selects DefaultExecutor, not PoeWebExecutor", () => { +test("#8969: getExecutor(poe) selects DefaultExecutor, not PoeWebExecutor", async () => { assert.equal(hasSpecializedExecutor("poe"), false); - const executor = getExecutor("poe"); + const executor = await getExecutor("poe"); assert.ok(executor instanceof DefaultExecutor); assert.equal(executor instanceof PoeWebExecutor, false); assert.equal(executor.provider, "poe"); }); -test("#8969: getExecutor(poe-web) still selects PoeWebExecutor", () => { +test("#8969: getExecutor(poe-web) still selects PoeWebExecutor", async () => { assert.equal(hasSpecializedExecutor("poe-web"), true); - assert.ok(getExecutor("poe-web") instanceof PoeWebExecutor); + const executor = await getExecutor("poe-web"); + assert.ok(executor instanceof PoeWebExecutor); }); test("#8969: registry declares API-key executor + all three Poe protocol URLs", () => { @@ -80,8 +81,8 @@ test("#8969: registry declares API-key executor + all three Poe protocol URLs", assert.notEqual(gpt.targetFormat, "claude"); }); -test("#8969: buildUrl routes chat / responses / messages correctly", () => { - const executor = getExecutor("poe") as DefaultExecutor; +test("#8969: buildUrl routes chat / responses / messages correctly", async () => { + const executor = (await getExecutor("poe")) as DefaultExecutor; const creds = { apiKey: "poe-test-key", providerSpecificData: {} }; assert.equal(executor.buildUrl("gemma-4-31b", false, 0, creds), CHAT_URL); @@ -175,8 +176,8 @@ test("#8969: resolvePoeUpstreamUrl normalizes registry-default / bare-host /v1/ } }); -test("#8969: buildHeaders uses Bearer auth and never sends Cookie", () => { - const executor = getExecutor("poe") as DefaultExecutor; +test("#8969: buildHeaders uses Bearer auth and never sends Cookie", async () => { + const executor = (await getExecutor("poe")) as DefaultExecutor; for (const stream of [false, true]) { const headers = headerRecord( executor.buildHeaders({ apiKey: "poe-test-key", providerSpecificData: {} }, stream) @@ -200,7 +201,7 @@ test("#8969: resolveExecutionCredentials forces responses upstream for poe", () }); test("#8969: mocked execute posts Chat Completions with Bearer, no Cookie, stripped model", async () => { - const executor = getExecutor("poe") as DefaultExecutor; + const executor = (await getExecutor("poe")) as DefaultExecutor; const originalFetch = globalThis.fetch; const seen: Array<{ url: string; @@ -259,7 +260,7 @@ test("#8969: mocked execute posts Chat Completions with Bearer, no Cookie, strip }); test("#8969: mocked execute routes Responses + Messages fixtures to the right URLs", async () => { - const executor = getExecutor("poe") as DefaultExecutor; + const executor = (await getExecutor("poe")) as DefaultExecutor; const originalFetch = globalThis.fetch; let lastUrl = ""; @@ -326,7 +327,7 @@ test("#8969: mocked execute routes Responses + Messages fixtures to the right UR }); test("#8969: mocked upstream 405 is preserved (not swallowed)", async () => { - const executor = getExecutor("poe") as DefaultExecutor; + const executor = (await getExecutor("poe")) as DefaultExecutor; const originalFetch = globalThis.fetch; globalThis.fetch = (async () => { diff --git a/tests/unit/provider-limits-accesstoken-fallback-on-refresh-failure.test.ts b/tests/unit/provider-limits-accesstoken-fallback-on-refresh-failure.test.ts index df8fd531c8..89f23b7983 100644 --- a/tests/unit/provider-limits-accesstoken-fallback-on-refresh-failure.test.ts +++ b/tests/unit/provider-limits-accesstoken-fallback-on-refresh-failure.test.ts @@ -39,7 +39,7 @@ function geminiConnection() { } test("falls back to the existing accessToken for a non-github provider when refreshCredentials returns null", async () => { - const exec = getExecutor("gemini"); + const exec = await getExecutor("gemini"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; exec.needsRefresh = () => true; // force the refresh attempt @@ -65,7 +65,7 @@ test("falls back to the existing accessToken for a non-github provider when refr }); test("still throws when refresh fails AND there is no accessToken to fall back on", async () => { - const exec = getExecutor("gemini"); + const exec = await getExecutor("gemini"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; exec.needsRefresh = () => true; diff --git a/tests/unit/provider-limits-force-refresh-imported.test.ts b/tests/unit/provider-limits-force-refresh-imported.test.ts index 7e3717503f..041b01064f 100644 --- a/tests/unit/provider-limits-force-refresh-imported.test.ts +++ b/tests/unit/provider-limits-force-refresh-imported.test.ts @@ -33,7 +33,7 @@ function importedCodexConnection() { } test("force re-mints an imported rotating account that needsRefresh would skip (#3019 reactive)", async () => { - const exec = getExecutor("codex"); + const exec = await getExecutor("codex"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; let refreshCalls = 0; @@ -65,7 +65,7 @@ test("force re-mints an imported rotating account that needsRefresh would skip ( }); test("force does NOT override the bulk #3019 guard (no allowRotatingRefresh → no mint)", async () => { - const exec = getExecutor("codex"); + const exec = await getExecutor("codex"); const origNeeds = exec.needsRefresh; const origRefresh = exec.refreshCredentials; let refreshCalls = 0; diff --git a/tests/unit/provider-registry-freetheai.test.ts b/tests/unit/provider-registry-freetheai.test.ts index 2df8061a4f..0a18e0cdc3 100644 --- a/tests/unit/provider-registry-freetheai.test.ts +++ b/tests/unit/provider-registry-freetheai.test.ts @@ -33,8 +33,8 @@ test("#6670 freetheai is registered in the executor registry with an OpenAI-comp assert.ok(Array.isArray(entry.models) && entry.models.length > 0, "must seed a fallback model list"); }); -test("#6670 freetheai resolves through getExecutor() as a DefaultExecutor instance", () => { - const executor = getExecutor("freetheai"); +test("#6670 freetheai resolves through getExecutor() as a DefaultExecutor instance", async () => { + const executor = await getExecutor("freetheai"); assert.ok(executor instanceof DefaultExecutor, "freetheai has no custom executor — must fall through to DefaultExecutor"); }); diff --git a/tests/unit/provider-request-failure-pipeline.test.ts b/tests/unit/provider-request-failure-pipeline.test.ts index 34bac642f4..2b6684f452 100644 --- a/tests/unit/provider-request-failure-pipeline.test.ts +++ b/tests/unit/provider-request-failure-pipeline.test.ts @@ -153,7 +153,7 @@ test("network failure persisted call log includes providerRequest in pipeline pa test("network timeout persisted call log includes providerRequest in pipeline payloads", async () => { const { getExecutor } = await import("../../open-sse/executors/index.ts"); - const executor = getExecutor("openai"); + const executor = await getExecutor("openai"); const originalGetTimeoutMs = executor.getTimeoutMs?.bind(executor); executor.getTimeoutMs = () => 200; diff --git a/tests/unit/providers-g4f-batch3.test.ts b/tests/unit/providers-g4f-batch3.test.ts index a64860bd70..40969c2180 100644 --- a/tests/unit/providers-g4f-batch3.test.ts +++ b/tests/unit/providers-g4f-batch3.test.ts @@ -68,8 +68,8 @@ for (const [id, info] of Object.entries(PROVIDERS)) { assert.equal(entry.passthroughModels, true); }); - test(`#6674 ${id} resolves through getExecutor() as a DefaultExecutor instance`, () => { - const executor = getExecutor(id); + test(`#6674 ${id} resolves through getExecutor() as a DefaultExecutor instance`, async () => { + const executor = await getExecutor(id); assert.ok( executor instanceof DefaultExecutor, `${id} has no custom executor — must fall through to DefaultExecutor` diff --git a/tests/unit/providers-yuanbao-web.test.ts b/tests/unit/providers-yuanbao-web.test.ts index 03fae5084e..a8a00411f0 100644 --- a/tests/unit/providers-yuanbao-web.test.ts +++ b/tests/unit/providers-yuanbao-web.test.ts @@ -39,11 +39,11 @@ test("yuanbao-web appears in the web-cookie catalog with a cookie authHint", () assert.match(String(entry.website), /yuanbao\.tencent\.com/); }); -test("YuanbaoWebExecutor is wired under id and alias", () => { +test("YuanbaoWebExecutor is wired under id and alias", async () => { assert.ok(hasSpecializedExecutor("yuanbao-web")); assert.ok(hasSpecializedExecutor("ybw")); - assert.ok(getExecutor("yuanbao-web") instanceof YuanbaoWebExecutor); - assert.ok(getExecutor("ybw") instanceof YuanbaoWebExecutor); + assert.ok(await getExecutor("yuanbao-web") instanceof YuanbaoWebExecutor); + assert.ok(await getExecutor("ybw") instanceof YuanbaoWebExecutor); }); // ── Behavioral: SSE → OpenAI translation (mocked upstream) ───────────────────── diff --git a/tests/unit/t3-chat-web.test.ts b/tests/unit/t3-chat-web.test.ts index c0d28ac49f..1de24fc454 100644 --- a/tests/unit/t3-chat-web.test.ts +++ b/tests/unit/t3-chat-web.test.ts @@ -20,13 +20,13 @@ test("hasSpecializedExecutor returns true for t3chat alias", () => { assert.ok(hasSpecializedExecutor("t3chat")); }); -test("getExecutor returns T3ChatWebExecutor for t3-web", () => { - const exec = getExecutor("t3-web"); +test("getExecutor returns T3ChatWebExecutor for t3-web", async () => { + const exec = await getExecutor("t3-web"); assert.ok(exec instanceof T3ChatWebExecutor); }); -test("getExecutor returns T3ChatWebExecutor for t3chat alias", () => { - const exec = getExecutor("t3chat"); +test("getExecutor returns T3ChatWebExecutor for t3chat alias", async () => { + const exec = await getExecutor("t3chat"); assert.ok(exec instanceof T3ChatWebExecutor); }); diff --git a/tests/unit/web-cookie-providers-new.test.ts b/tests/unit/web-cookie-providers-new.test.ts index 1c199a5dab..14e3a2860a 100644 --- a/tests/unit/web-cookie-providers-new.test.ts +++ b/tests/unit/web-cookie-providers-new.test.ts @@ -110,49 +110,51 @@ const noopExecuteInput = { // ── Registration Tests ─────────────────────────────────────────────────────── -test("HuggingChat executor is registered", () => { +test("HuggingChat executor is registered", async () => { assert.ok(hasSpecializedExecutor("huggingchat")); assert.ok(hasSpecializedExecutor("hc")); - const executor = getExecutor("huggingchat"); + const executor = await getExecutor("huggingchat"); assert.ok(executor instanceof HuggingChatExecutor); }); -test("Poe Web executor is registered", () => { +test("Poe Web executor is registered", async () => { assert.ok(hasSpecializedExecutor("poe-web")); - const executor = getExecutor("poe-web"); + const executor = await getExecutor("poe-web"); assert.ok(executor instanceof PoeWebExecutor); // #8969: canonical API-key `poe` must not route through PoeWebExecutor. assert.equal(hasSpecializedExecutor("poe"), false); - assert.ok(!(getExecutor("poe") instanceof PoeWebExecutor)); + const poeApiExecutor = await getExecutor("poe"); + assert.ok(!(poeApiExecutor instanceof PoeWebExecutor)); }); -test("Venice Web executor is registered", () => { +test("Venice Web executor is registered", async () => { assert.ok(hasSpecializedExecutor("venice-web")); assert.ok(hasSpecializedExecutor("ven")); - const executor = getExecutor("venice-web"); + const executor = await getExecutor("venice-web"); assert.ok(executor instanceof VeniceWebExecutor); }); -test("v0 Vercel Web executor is registered", () => { +test("v0 Vercel Web executor is registered", async () => { assert.ok(hasSpecializedExecutor("v0-vercel-web")); assert.ok(hasSpecializedExecutor("v0")); - const executor = getExecutor("v0-vercel-web"); + const executor = await getExecutor("v0-vercel-web"); assert.ok(executor instanceof V0VercelWebExecutor); }); -test("Kimi Web executor is registered", () => { - assert.ok(getExecutor("kimi-web") instanceof KimiWebExecutor); +test("Kimi Web executor is registered", async () => { + const kimiWebExecutor = await getExecutor("kimi-web"); + assert.ok(kimiWebExecutor instanceof KimiWebExecutor); // #4699: the legacy `kimi` API-key id must never route through Kimi Web. assert.ok(hasSpecializedExecutor("kimi")); - const legacyExecutor = getExecutor("kimi"); + const legacyExecutor = await getExecutor("kimi"); assert.ok(legacyExecutor instanceof MoonshotExecutor); assert.ok(!(legacyExecutor instanceof KimiWebExecutor)); }); -test("Doubao Web executor is registered", () => { +test("Doubao Web executor is registered", async () => { assert.ok(hasSpecializedExecutor("doubao-web")); assert.ok(hasSpecializedExecutor("db")); - const executor = getExecutor("doubao-web"); + const executor = await getExecutor("doubao-web"); assert.ok(executor instanceof DoubaoWebExecutor); }); @@ -190,9 +192,9 @@ test("Doubao Web sets correct provider", () => { // ── Registration Tests (Qwen Web) ──────────────────────────────────────────── -test("Qwen Web executor is registered", () => { +test("Qwen Web executor is registered", async () => { assert.ok(hasSpecializedExecutor("qwen-web")); - const executor = getExecutor("qwen-web"); + const executor = await getExecutor("qwen-web"); assert.ok(executor instanceof QwenWebExecutor); });