diff --git a/src/components/settings/provider-presets.tsx b/src/components/settings/provider-presets.tsx
index d726871b..9299472f 100644
--- a/src/components/settings/provider-presets.tsx
+++ b/src/components/settings/provider-presets.tsx
@@ -25,6 +25,22 @@ import Ollama from "@lobehub/icons/es/Ollama";
import OpenAI from "@lobehub/icons/es/OpenAI";
import XAI from "@lobehub/icons/es/XAI";
+// Requesty has no brand icon in @lobehub/icons yet, so mirror the approach the
+// model-selector already uses for the `requesty` provider and render its logo
+// from models.dev. Same `size` prop shape as the lobehub icon components so the
+// two icon maps below can treat it uniformly.
+function RequestyIcon({ size = 18 }: { size?: number }): ReactNode {
+ return (
+
+ );
+}
+
// ---------------------------------------------------------------------------
// Brand icon resolver
// ---------------------------------------------------------------------------
@@ -36,6 +52,7 @@ import XAI from "@lobehub/icons/es/XAI";
*/
const ICON_BY_KEY: Record = {
openrouter: ,
+ requesty: ,
zhipu: ,
kimi: ,
moonshot: ,
@@ -92,6 +109,7 @@ function resolveIcon(iconKey: string): ReactNode {
const ICON_MAP: Record = {
anthropic: ,
openrouter: ,
+ requesty: ,
zhipu: ,
kimi: ,
moonshot: ,
diff --git a/src/lib/provider-catalog.ts b/src/lib/provider-catalog.ts
index 2efe170c..d0bcbe07 100644
--- a/src/lib/provider-catalog.ts
+++ b/src/lib/provider-catalog.ts
@@ -720,6 +720,46 @@ export const VENDOR_PRESETS: VendorPreset[] = [
},
},
+ // ── Requesty ──
+ // Requesty is an OpenAI-compatible model router (like OpenRouter, but its
+ // gateway speaks the OpenAI Chat Completions wire protocol at
+ // `https://router.requesty.ai/v1`). It therefore rides the generic
+ // `openai-compatible` path — CodePilot / Codex runtimes via the AI SDK chat
+ // transport — rather than OpenRouter's Anthropic-skin `protocol: 'openrouter'`.
+ // Because the base URL ends in `/v1` and the preset is not catalog-only, the
+ // "搜索并添加模型" dialog reaches Requesty's `/v1/models` through the generic
+ // reliable-provider probe (canReliablyFetchModels / canSearchUpstreamModels),
+ // so no dedicated catalog fetcher is needed. `provider/model` naming matches
+ // OpenRouter. `defaultModels` is an intentional alias-only bootstrap (a few
+ // popular SKUs); user-added models are normal usage, not drift — so no
+ // `fixedCatalog`/`modelDiscoveryMode` gate.
+ {
+ key: 'requesty',
+ name: 'Requesty',
+ description: 'Use Requesty to access multiple models',
+ descriptionZh: '通过 Requesty 访问多种模型',
+ protocol: 'openai-compatible',
+ authStyle: 'api_key',
+ baseUrl: 'https://router.requesty.ai/v1',
+ defaultEnvOverrides: {},
+ defaultModels: [
+ { modelId: 'openai/gpt-4o-mini', displayName: 'GPT-4o mini', role: 'default', capabilities: { toolUse: true, vision: true } },
+ { modelId: 'openai/gpt-4o', displayName: 'GPT-4o', capabilities: { toolUse: true, vision: true } },
+ { modelId: 'anthropic/claude-sonnet-4-5', displayName: 'Claude Sonnet 4.5', capabilities: { toolUse: true, vision: true, reasoning: true } },
+ { modelId: 'google/gemini-2.5-flash', displayName: 'Gemini 2.5 Flash', capabilities: { toolUse: true, vision: true } },
+ { modelId: 'deepseek/deepseek-chat', displayName: 'DeepSeek Chat', capabilities: { toolUse: true } },
+ ],
+ defaultRoleModels: { default: 'openai/gpt-4o-mini' },
+ fields: ['api_key'],
+ iconKey: 'requesty',
+ meta: {
+ apiKeyUrl: 'https://app.requesty.ai/api-keys',
+ docsUrl: 'https://docs.requesty.ai',
+ pricingUrl: 'https://app.requesty.ai/router/list',
+ billingModel: 'pay_as_you_go',
+ },
+ },
+
// ── Zhipu GLM (China) ──
{
key: 'glm-cn',
diff --git a/src/lib/provider-icon-rule.ts b/src/lib/provider-icon-rule.ts
index 5d92cab5..f969667f 100644
--- a/src/lib/provider-icon-rule.ts
+++ b/src/lib/provider-icon-rule.ts
@@ -15,6 +15,7 @@
export type ProviderIconKey =
| "openrouter"
+ | "requesty"
| "zhipu"
| "kimi"
| "moonshot"
@@ -39,6 +40,10 @@ export function getProviderIconKey(name: string, baseUrl: string): ProviderIconK
const url = baseUrl.toLowerCase();
if (lower.includes("openrouter")) return "openrouter";
+ // Requesty — OpenAI-compatible model router. Scoped to brand-unique
+ // fragments (`requesty.ai` host / `requesty` name) so it can't steal
+ // another vendor's icon.
+ if (url.includes("requesty.ai") || lower.includes("requesty")) return "requesty";
// OpenCode Go: the provider name carries a protocol suffix — "OpenCode Go
// (OpenAI)" / "(Anthropic)". Match BEFORE the openai / anthropic name
// matchers below, which would otherwise steal the wrong brand logo