From 050e56f20b5469be8a1f897d5908ccc01011a02b Mon Sep 17 00:00:00 2001 From: Arden Hermawan Date: Thu, 7 May 2026 16:17:03 +0700 Subject: [PATCH] Fix compatible provider API key setup (#925) --- .../providers/[id]/AddApiKeyModal.js | 24 ++- .../dashboard/providers/[id]/page.js | 67 +++++-- .../compatible-provider-connections.test.js | 170 ++++++++++++++++++ 3 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 tests/unit/compatible-provider-connections.test.js diff --git a/src/app/(dashboard)/dashboard/providers/[id]/AddApiKeyModal.js b/src/app/(dashboard)/dashboard/providers/[id]/AddApiKeyModal.js index e1056439..cef80318 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/AddApiKeyModal.js +++ b/src/app/(dashboard)/dashboard/providers/[id]/AddApiKeyModal.js @@ -4,7 +4,7 @@ import { useState } from "react"; import PropTypes from "prop-types"; import { Button, Badge, Input, Modal, Select } from "@/shared/components"; -export default function AddApiKeyModal({ isOpen, provider, providerName, isCompatible, isAnthropic, authType, authHint, website, proxyPools, onSave, onClose }) { +export default function AddApiKeyModal({ isOpen, provider, providerName, isCompatible, isAnthropic, authType, authHint, website, proxyPools, error, onSave, onClose }) { const NONE_PROXY_POOL_VALUE = "__none__"; const isOllamaLocal = provider === "ollama-local"; const isCookie = authType === "cookie"; @@ -19,6 +19,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa const [formData, setFormData] = useState({ name: "", apiKey: "", + defaultModel: "", priority: 1, proxyPoolId: NONE_PROXY_POOL_VALUE, ollamaHostUrl: "", @@ -76,6 +77,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa // Non-ollama providers require a name if (!formData.name) return; } + if (isCompatible && !formData.defaultModel.trim()) return; setSaving(true); try { @@ -100,6 +102,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa await onSave({ name: formData.name || (isOllamaLocal ? "Ollama Local" : ""), apiKey: formData.apiKey, + defaultModel: isCompatible ? formData.defaultModel.trim() : undefined, priority: formData.priority, proxyPoolId: formData.proxyPoolId === NONE_PROXY_POOL_VALUE ? null : formData.proxyPoolId, testStatus: isValid ? "active" : "unknown", @@ -167,6 +170,14 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa )}

)} + {isCompatible && ( + setFormData({ ...formData, defaultModel: e.target.value })} + placeholder={isAnthropic ? "claude-3-5-sonnet-latest" : "gpt-4o-mini"} + /> + )} {isOllamaLocal && (

Leave blank to use http://localhost:11434. For remote Ollama, enter the full host URL (e.g. http://192.168.1.10:11434). @@ -177,12 +188,12 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa {validationResult === "success" ? "Valid" : "Invalid"} )} + {error && ( +

{error}

+ )} {isCompatible && (

- {isAnthropic - ? `Validation checks ${providerName || "Anthropic Compatible"} by verifying the API key.` - : `Validation checks ${providerName || "OpenAI Compatible"} via /models on your base URL.` - } + Enter the model ID exactly as your compatible endpoint expects it. This model will be saved as the connection default.

)} {isCloudflareAi && ( @@ -260,7 +271,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa

-
- {!isCompatible && ( -
- {providerId === "iflow" && ( - - )} - -
- )} + )} + + ) : ( <> @@ -1060,7 +1086,14 @@ export default function ProviderDetailPage() {