diff --git a/open-sse/executors/default.ts b/open-sse/executors/default.ts
index 491ea48e75..3dd2ac39af 100644
--- a/open-sse/executors/default.ts
+++ b/open-sse/executors/default.ts
@@ -201,6 +201,10 @@ export class DefaultExecutor extends BaseExecutor {
const baseUrl = credentials?.providerSpecificData?.baseUrl || this.config.baseUrl;
return buildMaritalkChatUrl(baseUrl);
}
+ case "siliconflow": {
+ const baseUrl = credentials?.providerSpecificData?.baseUrl || this.config.baseUrl;
+ return normalizeOpenAIChatUrl(baseUrl);
+ }
case "lm-studio":
case "modal":
case "reka":
diff --git a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx
index 44b672c032..4271047502 100644
--- a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx
+++ b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx
@@ -788,6 +788,7 @@ interface AddApiKeyModalProps {
isOpen: boolean;
provider?: string;
providerName?: string;
+ initialBaseUrl?: string;
isCompatible?: boolean;
isAnthropic?: boolean;
isCcCompatible?: boolean;
@@ -821,6 +822,11 @@ type CommandCodeAuthFlowState = {
message?: string;
};
+const SILICONFLOW_ENDPOINTS = [
+ { id: "siliconflow", label: "Global", baseUrl: "https://api.siliconflow.com/v1" },
+ { id: "siliconflow-cn", label: "China", baseUrl: "https://api.siliconflow.cn/v1" },
+] as const;
+
interface EditConnectionModalConnection {
id?: string;
name?: string;
@@ -1361,6 +1367,8 @@ export default function ProviderDetailPage() {
const [showOAuthModal, _setShowOAuthModal] = useState(false);
const [reauthConnection, setReauthConnection] = useState(null);
const [showAddApiKeyModal, setShowAddApiKeyModal] = useState(false);
+ const [showSiliconFlowEndpointModal, setShowSiliconFlowEndpointModal] = useState(false);
+ const [siliconFlowInitialBaseUrl, setSiliconFlowInitialBaseUrl] = useState();
const [showRiskNoticeModal, setShowRiskNoticeModal] = useState(false);
const [commandCodeAuthState, setCommandCodeAuthState] = useState({
phase: "idle",
@@ -1959,13 +1967,21 @@ export default function ProviderDetailPage() {
setShowOAuthModal(false);
}, [fetchConnections]);
+ const openApiKeyAddFlow = useCallback(() => {
+ if (providerId === "siliconflow") {
+ setShowSiliconFlowEndpointModal(true);
+ return;
+ }
+ setShowAddApiKeyModal(true);
+ }, [providerId]);
+
const openPrimaryAddFlow = useCallback(() => {
if (isOAuth) {
setShowOAuthModal(true);
return;
}
- setShowAddApiKeyModal(true);
- }, [isOAuth]);
+ openApiKeyAddFlow();
+ }, [isOAuth, openApiKeyAddFlow]);
const gateConnectionFlow = useCallback(
(callback: () => void) => {
@@ -2008,6 +2024,7 @@ export default function ProviderDetailPage() {
const handleCloseAddApiKeyModal = useCallback(() => {
clearCommandCodeAuthTimer();
+ setSiliconFlowInitialBaseUrl(undefined);
commandCodeAuthWindowRef.current?.close?.();
commandCodeAuthWindowRef.current = null;
setCommandCodeAuthState({
@@ -2255,6 +2272,7 @@ export default function ProviderDetailPage() {
const newConnection = connectionData?.connection;
await fetchConnections();
setShowAddApiKeyModal(false);
+ setSiliconFlowInitialBaseUrl(undefined);
// For Gemini: show progress dialog and sync models from endpoint
if (providerId === "gemini" && newConnection?.id) {
@@ -3915,11 +3933,7 @@ export default function ProviderDetailPage() {
-