mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-04 19:45:34 +08:00
feat(ui): add Gemini Native provider preset and api format option
- Add gemini_native to ClaudeApiFormat type and ProviderMeta.apiFormat - Add "Gemini Native" provider preset with default Google AI endpoints - Show Gemini-specific endpoint hints and full-URL mode guidance - Add gemini_native option to API format selector in ClaudeFormFields - Add i18n strings for zh/en/ja
This commit is contained in:
@@ -106,7 +106,7 @@ interface ClaudeFormFieldsProps {
|
|||||||
// Speed Test Endpoints
|
// Speed Test Endpoints
|
||||||
speedTestEndpoints: EndpointCandidate[];
|
speedTestEndpoints: EndpointCandidate[];
|
||||||
|
|
||||||
// API Format (for third-party providers that use OpenAI Chat Completions format)
|
// API Format (for Claude-compatible providers that need request/response conversion)
|
||||||
apiFormat: ClaudeApiFormat;
|
apiFormat: ClaudeApiFormat;
|
||||||
onApiFormatChange: (format: ClaudeApiFormat) => void;
|
onApiFormatChange: (format: ClaudeApiFormat) => void;
|
||||||
|
|
||||||
@@ -418,7 +418,14 @@ export function ClaudeFormFields({
|
|||||||
? t("providerForm.apiHintResponses")
|
? t("providerForm.apiHintResponses")
|
||||||
: apiFormat === "openai_chat"
|
: apiFormat === "openai_chat"
|
||||||
? t("providerForm.apiHintOAI")
|
? t("providerForm.apiHintOAI")
|
||||||
: t("providerForm.apiHint")
|
: apiFormat === "gemini_native"
|
||||||
|
? t("providerForm.apiHintGeminiNative")
|
||||||
|
: t("providerForm.apiHint")
|
||||||
|
}
|
||||||
|
fullUrlHint={
|
||||||
|
apiFormat === "gemini_native"
|
||||||
|
? t("providerForm.fullUrlHintGeminiNative")
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
onManageClick={() => onEndpointModalToggle(true)}
|
onManageClick={() => onEndpointModalToggle(true)}
|
||||||
showFullUrlToggle={true}
|
showFullUrlToggle={true}
|
||||||
@@ -493,6 +500,11 @@ export function ClaudeFormFields({
|
|||||||
defaultValue: "OpenAI Responses API (需转换)",
|
defaultValue: "OpenAI Responses API (需转换)",
|
||||||
})}
|
})}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
<SelectItem value="gemini_native">
|
||||||
|
{t("providerForm.apiFormatGeminiNative", {
|
||||||
|
defaultValue: "Gemini Native generateContent (需转换)",
|
||||||
|
})}
|
||||||
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface EndpointFieldProps {
|
|||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
hint?: string;
|
hint?: string;
|
||||||
|
fullUrlHint?: string;
|
||||||
showManageButton?: boolean;
|
showManageButton?: boolean;
|
||||||
onManageClick?: () => void;
|
onManageClick?: () => void;
|
||||||
manageButtonLabel?: string;
|
manageButtonLabel?: string;
|
||||||
@@ -26,6 +27,7 @@ export function EndpointField({
|
|||||||
onChange,
|
onChange,
|
||||||
placeholder,
|
placeholder,
|
||||||
hint,
|
hint,
|
||||||
|
fullUrlHint,
|
||||||
showManageButton = true,
|
showManageButton = true,
|
||||||
onManageClick,
|
onManageClick,
|
||||||
manageButtonLabel,
|
manageButtonLabel,
|
||||||
@@ -40,7 +42,8 @@ export function EndpointField({
|
|||||||
});
|
});
|
||||||
const effectiveHint =
|
const effectiveHint =
|
||||||
showFullUrlToggle && isFullUrl
|
showFullUrlToggle && isFullUrl
|
||||||
? t("providerForm.fullUrlHint", {
|
? fullUrlHint ||
|
||||||
|
t("providerForm.fullUrlHint", {
|
||||||
defaultValue:
|
defaultValue:
|
||||||
"💡 请填写完整请求 URL,并且必须开启代理后使用;代理将直接使用此 URL,不拼接路径",
|
"💡 请填写完整请求 URL,并且必须开启代理后使用;代理将直接使用此 URL,不拼接路径",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,7 +49,12 @@ export interface ProviderPreset {
|
|||||||
// - "anthropic" (默认): Anthropic Messages API 格式,直接透传
|
// - "anthropic" (默认): Anthropic Messages API 格式,直接透传
|
||||||
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
||||||
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
||||||
apiFormat?: "anthropic" | "openai_chat" | "openai_responses";
|
// - "gemini_native": Gemini Native generateContent API 格式,需要格式转换
|
||||||
|
apiFormat?:
|
||||||
|
| "anthropic"
|
||||||
|
| "openai_chat"
|
||||||
|
| "openai_responses"
|
||||||
|
| "gemini_native";
|
||||||
|
|
||||||
// 供应商类型标识(用于特殊供应商检测)
|
// 供应商类型标识(用于特殊供应商检测)
|
||||||
// - "github_copilot": GitHub Copilot 供应商(需要 OAuth 认证)
|
// - "github_copilot": GitHub Copilot 供应商(需要 OAuth 认证)
|
||||||
@@ -79,6 +84,27 @@ export const providerPresets: ProviderPreset[] = [
|
|||||||
icon: "anthropic",
|
icon: "anthropic",
|
||||||
iconColor: "#D4915D",
|
iconColor: "#D4915D",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Gemini Native",
|
||||||
|
websiteUrl: "https://ai.google.dev/gemini-api",
|
||||||
|
apiKeyUrl: "https://aistudio.google.com/app/apikey",
|
||||||
|
apiKeyField: "ANTHROPIC_API_KEY",
|
||||||
|
settingsConfig: {
|
||||||
|
env: {
|
||||||
|
ANTHROPIC_BASE_URL: "https://generativelanguage.googleapis.com",
|
||||||
|
ANTHROPIC_API_KEY: "",
|
||||||
|
ANTHROPIC_MODEL: "gemini-2.5-pro",
|
||||||
|
ANTHROPIC_DEFAULT_HAIKU_MODEL: "gemini-2.5-flash",
|
||||||
|
ANTHROPIC_DEFAULT_SONNET_MODEL: "gemini-2.5-pro",
|
||||||
|
ANTHROPIC_DEFAULT_OPUS_MODEL: "gemini-2.5-pro",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
category: "third_party",
|
||||||
|
apiFormat: "gemini_native",
|
||||||
|
endpointCandidates: ["https://generativelanguage.googleapis.com"],
|
||||||
|
icon: "gemini",
|
||||||
|
iconColor: "#4285F4",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "DeepSeek",
|
name: "DeepSeek",
|
||||||
websiteUrl: "https://platform.deepseek.com",
|
websiteUrl: "https://platform.deepseek.com",
|
||||||
|
|||||||
@@ -746,6 +746,7 @@
|
|||||||
"modelHint": "💡 Leave blank to use provider's default model",
|
"modelHint": "💡 Leave blank to use provider's default model",
|
||||||
"apiHint": "💡 Fill in Claude API compatible service endpoint, avoid trailing slash",
|
"apiHint": "💡 Fill in Claude API compatible service endpoint, avoid trailing slash",
|
||||||
"apiHintOAI": "💡 Fill in OpenAI Chat Completions compatible service endpoint, avoid trailing slash",
|
"apiHintOAI": "💡 Fill in OpenAI Chat Completions compatible service endpoint, avoid trailing slash",
|
||||||
|
"apiHintGeminiNative": "💡 Prefer a Gemini Native base URL such as https://generativelanguage.googleapis.com or https://generativelanguage.googleapis.com/v1beta; the proxy will append models/*:generateContent automatically",
|
||||||
"codexApiHint": "💡 Fill in service endpoint compatible with OpenAI Response format",
|
"codexApiHint": "💡 Fill in service endpoint compatible with OpenAI Response format",
|
||||||
"fillSupplierName": "Please fill in provider name",
|
"fillSupplierName": "Please fill in provider name",
|
||||||
"fillConfigContent": "Please fill in configuration content",
|
"fillConfigContent": "Please fill in configuration content",
|
||||||
@@ -768,9 +769,11 @@
|
|||||||
"fullUrlEnabled": "Full URL Mode",
|
"fullUrlEnabled": "Full URL Mode",
|
||||||
"fullUrlDisabled": "Mark as Full URL",
|
"fullUrlDisabled": "Mark as Full URL",
|
||||||
"fullUrlHint": "💡 Enter the full request URL. This mode requires the proxy to be enabled, and the proxy will use the URL as-is without appending a path",
|
"fullUrlHint": "💡 Enter the full request URL. This mode requires the proxy to be enabled, and the proxy will use the URL as-is without appending a path",
|
||||||
|
"fullUrlHintGeminiNative": "💡 In Gemini Native full URL mode, two inputs are supported: 1. official/structured Gemini URLs, which will still be normalized to the requested model and streaming method; 2. opaque custom relay URLs, which will be used mostly as-is with only query parameters appended",
|
||||||
"apiFormatAnthropic": "Anthropic Messages (Native)",
|
"apiFormatAnthropic": "Anthropic Messages (Native)",
|
||||||
"apiFormatOpenAIChat": "OpenAI Chat Completions (Requires proxy)",
|
"apiFormatOpenAIChat": "OpenAI Chat Completions (Requires proxy)",
|
||||||
"apiFormatOpenAIResponses": "OpenAI Responses API (Requires proxy)",
|
"apiFormatOpenAIResponses": "OpenAI Responses API (Requires proxy)",
|
||||||
|
"apiFormatGeminiNative": "Gemini Native generateContent (Requires proxy)",
|
||||||
"authField": "Auth Field",
|
"authField": "Auth Field",
|
||||||
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN (Default)",
|
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN (Default)",
|
||||||
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
||||||
|
|||||||
@@ -746,6 +746,7 @@
|
|||||||
"modelHint": "💡 空欄ならプロバイダーのデフォルトモデルを使用します",
|
"modelHint": "💡 空欄ならプロバイダーのデフォルトモデルを使用します",
|
||||||
"apiHint": "💡 Claude API 互換サービスのエンドポイントを入力してください。末尾にスラッシュを付けないでください",
|
"apiHint": "💡 Claude API 互換サービスのエンドポイントを入力してください。末尾にスラッシュを付けないでください",
|
||||||
"apiHintOAI": "💡 OpenAI Chat Completions 互換サービスのエンドポイントを入力してください。末尾にスラッシュを付けないでください",
|
"apiHintOAI": "💡 OpenAI Chat Completions 互換サービスのエンドポイントを入力してください。末尾にスラッシュを付けないでください",
|
||||||
|
"apiHintGeminiNative": "💡 Gemini Native では https://generativelanguage.googleapis.com または https://generativelanguage.googleapis.com/v1beta のような base URL を推奨します。プロキシが models/*:generateContent を自動補完します",
|
||||||
"codexApiHint": "💡 OpenAI Response 互換のサービスエンドポイントを入力してください",
|
"codexApiHint": "💡 OpenAI Response 互換のサービスエンドポイントを入力してください",
|
||||||
"fillSupplierName": "プロバイダー名を入力してください",
|
"fillSupplierName": "プロバイダー名を入力してください",
|
||||||
"fillConfigContent": "設定内容を入力してください",
|
"fillConfigContent": "設定内容を入力してください",
|
||||||
@@ -768,9 +769,11 @@
|
|||||||
"fullUrlEnabled": "フル URL モード",
|
"fullUrlEnabled": "フル URL モード",
|
||||||
"fullUrlDisabled": "フル URL として設定",
|
"fullUrlDisabled": "フル URL として設定",
|
||||||
"fullUrlHint": "💡 完全なリクエスト URL を入力してください。このモードはプロキシを有効にして使用する必要があり、プロキシはこの URL をそのまま使用し、パスを追加しません",
|
"fullUrlHint": "💡 完全なリクエスト URL を入力してください。このモードはプロキシを有効にして使用する必要があり、プロキシはこの URL をそのまま使用し、パスを追加しません",
|
||||||
|
"fullUrlHintGeminiNative": "💡 Gemini Native のフル URL モードでは 2 種類の入力を扱えます。1. 公式/構造化された Gemini URL は、要求されたモデルやストリーミング方式に合わせて正規化されます。2. カスタム relay の opaque な完全 URL は、主にそのまま使用され、必要なクエリだけ追加されます",
|
||||||
"apiFormatAnthropic": "Anthropic Messages(ネイティブ)",
|
"apiFormatAnthropic": "Anthropic Messages(ネイティブ)",
|
||||||
"apiFormatOpenAIChat": "OpenAI Chat Completions(プロキシが必要)",
|
"apiFormatOpenAIChat": "OpenAI Chat Completions(プロキシが必要)",
|
||||||
"apiFormatOpenAIResponses": "OpenAI Responses API(プロキシが必要)",
|
"apiFormatOpenAIResponses": "OpenAI Responses API(プロキシが必要)",
|
||||||
|
"apiFormatGeminiNative": "Gemini Native generateContent(プロキシが必要)",
|
||||||
"authField": "認証フィールド",
|
"authField": "認証フィールド",
|
||||||
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN(デフォルト)",
|
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN(デフォルト)",
|
||||||
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
||||||
|
|||||||
@@ -746,6 +746,7 @@
|
|||||||
"modelHint": "💡 留空将使用供应商的默认模型",
|
"modelHint": "💡 留空将使用供应商的默认模型",
|
||||||
"apiHint": "💡 填写兼容 Claude API 的服务端点地址,不要以斜杠结尾",
|
"apiHint": "💡 填写兼容 Claude API 的服务端点地址,不要以斜杠结尾",
|
||||||
"apiHintOAI": "💡 填写兼容 OpenAI Chat Completions 的服务端点地址,不要以斜杠结尾",
|
"apiHintOAI": "💡 填写兼容 OpenAI Chat Completions 的服务端点地址,不要以斜杠结尾",
|
||||||
|
"apiHintGeminiNative": "💡 建议填写 Gemini Native 的 base URL,例如 https://generativelanguage.googleapis.com 或 https://generativelanguage.googleapis.com/v1beta;代理会自动补全 models/*:generateContent",
|
||||||
"codexApiHint": "💡 填写兼容 OpenAI Response 格式的服务端点地址",
|
"codexApiHint": "💡 填写兼容 OpenAI Response 格式的服务端点地址",
|
||||||
"fillSupplierName": "请填写供应商名称",
|
"fillSupplierName": "请填写供应商名称",
|
||||||
"fillConfigContent": "请填写配置内容",
|
"fillConfigContent": "请填写配置内容",
|
||||||
@@ -768,9 +769,11 @@
|
|||||||
"fullUrlEnabled": "完整 URL 模式",
|
"fullUrlEnabled": "完整 URL 模式",
|
||||||
"fullUrlDisabled": "标记为完整 URL",
|
"fullUrlDisabled": "标记为完整 URL",
|
||||||
"fullUrlHint": "💡 请填写完整请求 URL,并且必须开启代理后使用;代理将直接使用此 URL,不拼接路径",
|
"fullUrlHint": "💡 请填写完整请求 URL,并且必须开启代理后使用;代理将直接使用此 URL,不拼接路径",
|
||||||
|
"fullUrlHintGeminiNative": "💡 Gemini Native 下,完整 URL 模式同时兼容两类地址:1. 官方/标准 Gemini URL,代理会按模型和流式参数自动归一化;2. 自定义 relay 的完整 URL,代理会尽量原样使用,只补查询参数,不再强行追加 models 路径",
|
||||||
"apiFormatAnthropic": "Anthropic Messages (原生)",
|
"apiFormatAnthropic": "Anthropic Messages (原生)",
|
||||||
"apiFormatOpenAIChat": "OpenAI Chat Completions (需开启代理)",
|
"apiFormatOpenAIChat": "OpenAI Chat Completions (需开启代理)",
|
||||||
"apiFormatOpenAIResponses": "OpenAI Responses API (需开启代理)",
|
"apiFormatOpenAIResponses": "OpenAI Responses API (需开启代理)",
|
||||||
|
"apiFormatGeminiNative": "Gemini Native generateContent (需开启代理)",
|
||||||
"authField": "认证字段",
|
"authField": "认证字段",
|
||||||
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN(默认)",
|
"authFieldAuthToken": "ANTHROPIC_AUTH_TOKEN(默认)",
|
||||||
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
"authFieldApiKey": "ANTHROPIC_API_KEY",
|
||||||
|
|||||||
+12
-2
@@ -159,7 +159,12 @@ export interface ProviderMeta {
|
|||||||
// - "anthropic": 原生 Anthropic Messages API 格式,直接透传
|
// - "anthropic": 原生 Anthropic Messages API 格式,直接透传
|
||||||
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
||||||
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
||||||
apiFormat?: "anthropic" | "openai_chat" | "openai_responses";
|
// - "gemini_native": Gemini Native generateContent API 格式,需要格式转换
|
||||||
|
apiFormat?:
|
||||||
|
| "anthropic"
|
||||||
|
| "openai_chat"
|
||||||
|
| "openai_responses"
|
||||||
|
| "gemini_native";
|
||||||
// 通用认证绑定
|
// 通用认证绑定
|
||||||
authBinding?: AuthBinding;
|
authBinding?: AuthBinding;
|
||||||
// Claude 认证字段名
|
// Claude 认证字段名
|
||||||
@@ -181,7 +186,12 @@ export type SkillSyncMethod = "auto" | "symlink" | "copy";
|
|||||||
// - "anthropic": 原生 Anthropic Messages API 格式,直接透传
|
// - "anthropic": 原生 Anthropic Messages API 格式,直接透传
|
||||||
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
// - "openai_chat": OpenAI Chat Completions 格式,需要格式转换
|
||||||
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
// - "openai_responses": OpenAI Responses API 格式,需要格式转换
|
||||||
export type ClaudeApiFormat = "anthropic" | "openai_chat" | "openai_responses";
|
// - "gemini_native": Gemini Native generateContent API 格式,需要格式转换
|
||||||
|
export type ClaudeApiFormat =
|
||||||
|
| "anthropic"
|
||||||
|
| "openai_chat"
|
||||||
|
| "openai_responses"
|
||||||
|
| "gemini_native";
|
||||||
|
|
||||||
// Claude 认证字段类型
|
// Claude 认证字段类型
|
||||||
export type ClaudeApiKeyField = "ANTHROPIC_AUTH_TOKEN" | "ANTHROPIC_API_KEY";
|
export type ClaudeApiKeyField = "ANTHROPIC_AUTH_TOKEN" | "ANTHROPIC_API_KEY";
|
||||||
|
|||||||
Reference in New Issue
Block a user