mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
fix(providers): correct pollinations requests and provider dashboard state
Update Pollinations request transformation to send the selected model and stream flag so requests match the active endpoint behavior. Align the ChatGPT TLS client with shared proxy resolution so dashboard proxy context is honored before falling back to environment settings. Also refresh provider display names across dashboard pages, correct the Claude extra-usage toggle messaging and visual state, and mark Pollinations as offering a free public endpoint.
This commit is contained in:
@@ -52,8 +52,8 @@ AGENTS.md
|
||||
bun.lock
|
||||
|
||||
# Build artifacts (pre-built goes inside app/)
|
||||
.next/
|
||||
node_modules/
|
||||
/.next/
|
||||
/node_modules/
|
||||
|
||||
# Ignore large binary files and other build directories
|
||||
*.tgz
|
||||
|
||||
@@ -41,8 +41,10 @@ export class PollinationsExecutor extends BaseExecutor {
|
||||
return headers;
|
||||
}
|
||||
|
||||
transformRequest(model: string, body: any, _stream: boolean, _credentials: any): any {
|
||||
transformRequest(model: string, body: any, stream: boolean, _credentials: any): any {
|
||||
if (typeof body === "object" && body !== null) {
|
||||
body.model = model;
|
||||
body.stream = stream;
|
||||
body.jsonMode = true;
|
||||
}
|
||||
return body;
|
||||
|
||||
@@ -209,23 +209,24 @@ export interface TlsFetchOptions {
|
||||
proxyUrl?: string;
|
||||
}
|
||||
|
||||
import { resolveProxyForRequest } from "../utils/proxyFetch.ts";
|
||||
|
||||
/**
|
||||
* Resolve the proxy URL for a tls-client request. Per-call value wins;
|
||||
* otherwise we fall back to env. Returns undefined when no proxy is
|
||||
* configured (caller passes `undefined` through to tls-client-node, which
|
||||
* treats it as "no proxy").
|
||||
* otherwise we use the standard proxy fetch resolution which reads from
|
||||
* the dashboard AsyncLocalStorage context or falls back to env vars.
|
||||
*/
|
||||
function resolveProxyUrl(perCall: string | undefined): string | undefined {
|
||||
if (perCall && perCall.length > 0) return perCall;
|
||||
const fromEnv =
|
||||
process.env.OMNIROUTE_TLS_PROXY_URL ||
|
||||
process.env.HTTPS_PROXY ||
|
||||
process.env.https_proxy ||
|
||||
process.env.HTTP_PROXY ||
|
||||
process.env.http_proxy ||
|
||||
process.env.ALL_PROXY ||
|
||||
process.env.all_proxy;
|
||||
return fromEnv && fromEnv.length > 0 ? fromEnv : undefined;
|
||||
try {
|
||||
const proxyInfo = resolveProxyForRequest("https://chatgpt.com");
|
||||
if (proxyInfo && proxyInfo.proxyUrl) {
|
||||
return proxyInfo.proxyUrl;
|
||||
}
|
||||
} catch {
|
||||
// Ignore resolution errors
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface TlsFetchResult {
|
||||
|
||||
@@ -133,7 +133,7 @@ function resolveEnvProxyUrl(targetUrl) {
|
||||
return normalizeProxyUrl(proxyUrl, "environment proxy");
|
||||
}
|
||||
|
||||
function resolveProxyForRequest(targetUrl) {
|
||||
export function resolveProxyForRequest(targetUrl) {
|
||||
let target;
|
||||
try {
|
||||
target = new URL(targetUrl);
|
||||
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -25,6 +25,7 @@
|
||||
"express": "^5.2.1",
|
||||
"fetch-socks": "^1.3.3",
|
||||
"fuse.js": "^7.3.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"http-proxy-middleware": "^3.0.5",
|
||||
"https-proxy-agent": "^9.0.0",
|
||||
"ioredis": "^5.10.1",
|
||||
@@ -83,7 +84,6 @@
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-config-next": "16.2.6",
|
||||
"glob": "^13.0.6",
|
||||
"gray-matter": "^4.0.3",
|
||||
"husky": "^9.1.7",
|
||||
"jsdom": "^29.1.1",
|
||||
"lint-staged": "^16.4.0",
|
||||
@@ -8258,7 +8258,6 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"bin": {
|
||||
"esparse": "bin/esparse.js",
|
||||
@@ -8460,7 +8459,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extendable": "^0.1.0"
|
||||
@@ -9101,7 +9099,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
|
||||
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.13.1",
|
||||
@@ -9117,7 +9114,6 @@
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
@@ -9127,7 +9123,6 @@
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
@@ -9859,7 +9854,6 @@
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -10607,7 +10601,6 @@
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -13914,7 +13907,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
@@ -14386,7 +14378,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/stable-hash": {
|
||||
@@ -14672,7 +14663,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
|
||||
"integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Card, Button, Input, Modal, CardSkeleton, SegmentedControl } from "@/sh
|
||||
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
|
||||
import { useDisplayBaseUrl } from "@/shared/hooks";
|
||||
import { AI_PROVIDERS, getProviderByAlias } from "@/shared/constants/providers";
|
||||
import { getProviderDisplayName } from "@/lib/display/names";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const BUILD_TIME_CLOUD_URL = process.env.NEXT_PUBLIC_CLOUD_URL || null;
|
||||
@@ -2482,7 +2483,7 @@ function EndpointSection({
|
||||
|
||||
const resolveProvider = (id) => AI_PROVIDERS[id] || getProviderByAlias(id);
|
||||
const providerColor = (id) => resolveProvider(id)?.color || "#888";
|
||||
const providerName = (id) => resolveProvider(id)?.name || id;
|
||||
const providerName = (id) => getProviderDisplayName(id, resolveProvider(id));
|
||||
const copyId = `endpoint_${path}`;
|
||||
|
||||
return (
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { Card } from "@/shared/components";
|
||||
import { AI_PROVIDERS } from "@/shared/constants/providers";
|
||||
import { getProviderDisplayName } from "@/lib/display/names";
|
||||
import { useTranslations } from "next-intl";
|
||||
import TelemetryCard from "./TelemetryCard";
|
||||
|
||||
@@ -762,7 +763,7 @@ export default function HealthPage() {
|
||||
{unhealthy.map(([provider, cb]: [string, any]) => {
|
||||
const style = CB_STYLES[cb.state] || CB_STYLES.OPEN;
|
||||
const providerInfo = AI_PROVIDERS[provider];
|
||||
const displayName = providerInfo?.name || provider;
|
||||
const displayName = getProviderDisplayName(provider, providerInfo);
|
||||
return (
|
||||
<div
|
||||
key={provider}
|
||||
@@ -820,7 +821,7 @@ export default function HealthPage() {
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-2">
|
||||
{healthy.map(([provider]) => {
|
||||
const providerInfo = AI_PROVIDERS[provider];
|
||||
const displayName = providerInfo?.name || provider;
|
||||
const displayName = getProviderDisplayName(provider, providerInfo);
|
||||
return (
|
||||
<div
|
||||
key={provider}
|
||||
@@ -873,7 +874,7 @@ export default function HealthPage() {
|
||||
if (customName.length > 12) displayName += ` (${customName.slice(0, 8)}…)`;
|
||||
else if (customName) displayName += ` (${customName})`;
|
||||
} else {
|
||||
displayName = providerInfo?.name || providerId;
|
||||
displayName = getProviderDisplayName(providerId, providerInfo);
|
||||
}
|
||||
|
||||
return { providerId, displayName, providerInfo, connectionId, model };
|
||||
|
||||
@@ -1630,9 +1630,7 @@ export default function ProviderDetailPage() {
|
||||
: connection
|
||||
)
|
||||
);
|
||||
notify.success(
|
||||
enabled ? "Claude extra-usage blocking enabled" : "Claude extra-usage blocking disabled"
|
||||
);
|
||||
notify.success(enabled ? "Claude extra-usage blocked" : "Claude extra-usage allowed");
|
||||
} catch (error) {
|
||||
console.error("Error toggling Claude extra-usage policy:", error);
|
||||
notify.error("Failed to update Claude extra-usage policy");
|
||||
@@ -5377,7 +5375,7 @@ function ConnectionRow({
|
||||
<button
|
||||
onClick={() => onToggleClaudeExtraUsage?.(!claudeBlockExtraUsageEnabled)}
|
||||
className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium transition-all cursor-pointer ${
|
||||
claudeBlockExtraUsageEnabled
|
||||
!claudeBlockExtraUsageEnabled
|
||||
? "bg-amber-500/15 text-amber-500 hover:bg-amber-500/25"
|
||||
: "bg-black/[0.03] dark:bg-white/[0.03] text-text-muted/50 hover:text-text-muted hover:bg-black/[0.06] dark:hover:bg-white/[0.06]"
|
||||
}`}
|
||||
@@ -5385,7 +5383,7 @@ function ConnectionRow({
|
||||
>
|
||||
<span className="material-symbols-outlined text-[13px]">payments</span>
|
||||
{t("claudeExtraUsageShort")}{" "}
|
||||
{claudeBlockExtraUsageEnabled ? t("toggleOnShort") : t("toggleOffShort")}
|
||||
{!claudeBlockExtraUsageEnabled ? t("toggleOnShort") : t("toggleOffShort")}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -793,8 +793,9 @@ export const APIKEY_PROVIDERS = {
|
||||
color: "#4CAF50",
|
||||
textIcon: "PO",
|
||||
website: "https://pollinations.ai",
|
||||
hasFree: false,
|
||||
freeNote: "API key required. Spore tier: ~0.01 pollen/hour ($0.01/hr).",
|
||||
hasFree: true,
|
||||
freeNote:
|
||||
"No API key required for free public endpoint. Optional Spore tier: ~0.01 pollen/hour.",
|
||||
},
|
||||
puter: {
|
||||
id: "puter",
|
||||
|
||||
Reference in New Issue
Block a user