From 3157e8a7ad10c2ecd728d68751bf9abddf5506c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouzbeh=E2=80=A0?= <78313022+rqzbeh@users.noreply.github.com> Date: Sat, 22 Aug 2026 22:29:31 +0330 Subject: [PATCH] fix(providers): require API key for Pollinations and fix optional key i18n labels (#11096) (#11117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picked the value commit (0e918816) onto the current tip, dropping the stale base-red sync commits. Focused tests: pollinations-api-key-required 1/1 plus the whole optional-key suite 142/142 (two legacy assertions in provider-route-schemas flipped to the new key-required contract, commented with the PR). Fixes #11096 — Pollinations answers 401 anonymously now. Thank you @rqzbeh! --- src/i18n/messages/en.json | 4 ++-- src/shared/constants/providers.ts | 1 - .../unit/pollinations-api-key-required-11096.test.ts | 11 +++++++++++ tests/unit/provider-route-schemas.test.ts | 10 ++++++---- 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 tests/unit/pollinations-api-key-required-11096.test.ts diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index ec091011e9..ff778753c6 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -5692,8 +5692,8 @@ "aggregatorsGateways": "Aggregators Gateways", "enterpriseCloud": "Enterprise & Cloud", "apiFormatLabel": "Api Format Label", - "apiKeyOptionalHint": "Api Key Optional Hint", - "apiKeyOptionalLabel": "Api Key Optional Label", + "apiKeyOptionalHint": "Leave empty if your local setup or provider does not require authentication.", + "apiKeyOptionalLabel": "API Key (optional)", "apiRegionChina": "Api Region China", "apiRegionHint": "Api Region Hint", "apiRegionInternational": "Api Region International", diff --git a/src/shared/constants/providers.ts b/src/shared/constants/providers.ts index 23f9c53b39..6b4fd86a50 100644 --- a/src/shared/constants/providers.ts +++ b/src/shared/constants/providers.ts @@ -237,7 +237,6 @@ export function isSelfHostedChatProvider(providerId: unknown): boolean { const EXPLICIT_OPTIONAL_APIKEY_PROVIDER_IDS = new Set([ "searxng-search", "firecrawl", - "pollinations", "copilot-web", "hackclub", "g4f-groq", diff --git a/tests/unit/pollinations-api-key-required-11096.test.ts b/tests/unit/pollinations-api-key-required-11096.test.ts new file mode 100644 index 0000000000..8b69fb8331 --- /dev/null +++ b/tests/unit/pollinations-api-key-required-11096.test.ts @@ -0,0 +1,11 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { providerAllowsOptionalApiKey } from "../../src/shared/constants/providers.js"; + +test("pollinations provider requires an API key and does not allow optional API key", () => { + assert.equal( + providerAllowsOptionalApiKey("pollinations"), + false, + "pollinations must require an API key because anonymous completions are no longer supported" + ); +}); diff --git a/tests/unit/provider-route-schemas.test.ts b/tests/unit/provider-route-schemas.test.ts index ca61c4f28d..30b5d4bd8c 100644 --- a/tests/unit/provider-route-schemas.test.ts +++ b/tests/unit/provider-route-schemas.test.ts @@ -5,17 +5,19 @@ const { createProviderSchema, providersBatchTestSchema } = await import("../../src/shared/validation/schemas.ts"); const { providerAllowsOptionalApiKey } = await import("../../src/shared/constants/providers.ts"); -test("Pollinations is treated as a keyless-capable provider", () => { - assert.equal(providerAllowsOptionalApiKey("pollinations"), true); +// #11117: Pollinations no longer serves anonymous requests (401 without a key), +// so it left EXPLICIT_OPTIONAL_APIKEY_PROVIDER_IDS — key is now required. +test("Pollinations requires an API key", () => { + assert.equal(providerAllowsOptionalApiKey("pollinations"), false); }); -test("createProviderSchema allows Pollinations without apiKey", () => { +test("createProviderSchema rejects Pollinations without apiKey", () => { const result = createProviderSchema.safeParse({ provider: "pollinations", name: "Pollinations", }); - assert.equal(result.success, true); + assert.equal(result.success, false); }); test("providersBatchTestSchema accepts cloud-agent batch mode", () => {