diff --git a/CHANGELOG.md b/CHANGELOG.md index c8983ae939..e43e8e0630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,9 @@ ### Fixed +- **providers/pollinations:** route to `gen.pollinations.ai/v1` instead of the + retired `text.pollinations.ai` host, which now returns `404 "legacy API"` for + all models. The gen gateway is the current OpenAI-compatible endpoint. (#2987) - **executors/codex:** drop the CLI-injected `image_generation` hosted tool for free-plan Codex accounts (`workspacePlanType === "free"`), which can't run it server-side and would otherwise get an upstream 400. Paid plans keep it. diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index 2258d55ff2..212902ab15 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -3441,13 +3441,11 @@ export const REGISTRY: Record = { alias: "pol", format: "openai", executor: "pollinations", - // Primary endpoint is text.pollinations.ai. gen.pollinations.ai is the current - // OpenAI-compatible fallback used when the primary edge is rate-limited or unavailable. - baseUrl: "https://text.pollinations.ai/openai/chat/completions", - baseUrls: [ - "https://text.pollinations.ai/openai/chat/completions", - "https://gen.pollinations.ai/v1/chat/completions", - ], + // #2987: Pollinations retired the legacy text.pollinations.ai host (it now + // returns 404 "This is our legacy API"). The current OpenAI-compatible gateway + // is gen.pollinations.ai/v1, so route there as the primary endpoint. + baseUrl: "https://gen.pollinations.ai/v1/chat/completions", + baseUrls: ["https://gen.pollinations.ai/v1/chat/completions"], authType: "apikey", authHeader: "bearer", models: [ diff --git a/open-sse/executors/pollinations.ts b/open-sse/executors/pollinations.ts index e3f14f08e9..eae763e458 100644 --- a/open-sse/executors/pollinations.ts +++ b/open-sse/executors/pollinations.ts @@ -11,7 +11,7 @@ export class PollinationsExecutor extends BaseExecutor { buildUrl(_model: string, _stream: boolean, urlIndex = 0, _credentials = null): string { const baseUrls = this.getBaseUrls(); return ( - baseUrls[urlIndex] || baseUrls[0] || "https://text.pollinations.ai/openai/chat/completions" + baseUrls[urlIndex] || baseUrls[0] || "https://gen.pollinations.ai/v1/chat/completions" ); } diff --git a/tests/unit/executor-pollinations.test.ts b/tests/unit/executor-pollinations.test.ts index bf21aaed98..875d7027d2 100644 --- a/tests/unit/executor-pollinations.test.ts +++ b/tests/unit/executor-pollinations.test.ts @@ -3,12 +3,15 @@ import assert from "node:assert/strict"; import { PollinationsExecutor } from "../../open-sse/executors/pollinations.ts"; -test("PollinationsExecutor.buildUrl uses the primary endpoint and the gen fallback", () => { +test("#2987 PollinationsExecutor.buildUrl uses the gen.pollinations.ai gateway (not the legacy text host)", () => { const executor = new PollinationsExecutor(); + // Legacy text.pollinations.ai now 404s ("legacy API"); gen.pollinations.ai/v1 + // is the current OpenAI-compatible endpoint and must be the primary. assert.equal( executor.buildUrl("openai", true), - "https://text.pollinations.ai/openai/chat/completions" + "https://gen.pollinations.ai/v1/chat/completions" ); + // No legacy text.pollinations.ai endpoint should remain in the rotation. assert.equal( executor.buildUrl("openai", true, 1), "https://gen.pollinations.ai/v1/chat/completions"