From 35c5612d1fbb2d6a4184bbeb7e4373860c37c8db Mon Sep 17 00:00:00 2001 From: coso Date: Thu, 25 Dec 2025 00:12:10 +0800 Subject: [PATCH] chore: bump version to 0.17.9 --- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/src/commands/provider_pool_cmd.rs | 24 +++++++++++ src-tauri/src/lib.rs | 1 + src-tauri/tauri.conf.json | 2 +- .../provider-pool/AddCredentialModal.tsx | 42 ++++++++++++++++++- .../provider-pool/EditCredentialModal.tsx | 8 ++++ .../provider-pool/ProviderPoolPage.tsx | 17 ++++---- .../provider-pool/credential-forms/types.ts | 1 + src/lib/api/providerPool.ts | 25 ++++++++++- 11 files changed, 111 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 396fc3538..30c746510 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "proxycast", "private": true, - "version": "0.17.8", + "version": "0.17.9", "type": "module", "repository": { "type": "git", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 16111e583..414173bf4 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3377,7 +3377,7 @@ dependencies = [ [[package]] name = "proxycast" -version = "0.17.8" +version = "0.17.9" dependencies = [ "anyhow", "async-stream", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9a676c62f..9cbecd011 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "proxycast" -version = "0.17.8" +version = "0.17.9" description = "AI API Proxy Desktop App" authors = ["you"] edition = "2021" diff --git a/src-tauri/src/commands/provider_pool_cmd.rs b/src-tauri/src/commands/provider_pool_cmd.rs index 59f0ae68a..bad870e30 100644 --- a/src-tauri/src/commands/provider_pool_cmd.rs +++ b/src-tauri/src/commands/provider_pool_cmd.rs @@ -913,6 +913,30 @@ pub fn add_claude_key_credential( ) } +/// 添加 Gemini API Key 凭证 +#[tauri::command] +pub fn add_gemini_api_key_credential( + db: State<'_, DbConnection>, + pool_service: State<'_, ProviderPoolServiceState>, + api_key: String, + base_url: Option, + excluded_models: Option>, + name: Option, +) -> Result { + pool_service.0.add_credential( + &db, + "gemini_api_key", + CredentialData::GeminiApiKey { + api_key, + base_url, + excluded_models: excluded_models.unwrap_or_default(), + }, + name, + Some(true), + None, + ) +} + /// 添加 Codex OAuth 凭证(通过文件路径) #[tauri::command] pub fn add_codex_oauth_credential( diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c21bf255a..4f79d30d0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -2014,6 +2014,7 @@ pub fn run() { commands::provider_pool_cmd::add_antigravity_oauth_credential, commands::provider_pool_cmd::add_openai_key_credential, commands::provider_pool_cmd::add_claude_key_credential, + commands::provider_pool_cmd::add_gemini_api_key_credential, commands::provider_pool_cmd::add_codex_oauth_credential, commands::provider_pool_cmd::add_claude_oauth_credential, commands::provider_pool_cmd::add_iflow_oauth_credential, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 15b2274ea..9129e5afe 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "ProxyCast", -"version": "0.17.8", +"version": "0.17.9", "identifier": "com.proxycast.app", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/components/provider-pool/AddCredentialModal.tsx b/src/components/provider-pool/AddCredentialModal.tsx index 5c3f1149f..0d203d07e 100644 --- a/src/components/provider-pool/AddCredentialModal.tsx +++ b/src/components/provider-pool/AddCredentialModal.tsx @@ -42,10 +42,13 @@ export function AddCredentialModal({ // API Key 字段 const [apiKey, setApiKey] = useState(""); const [baseUrl, setBaseUrl] = useState(""); + const [excludedModels, setExcludedModels] = useState([]); // 判断是否为 OAuth 类型(不包括有特殊表单的 antigravity、codex、claude_oauth、qwen、iflow、gemini、kiro) const isSimpleOAuth: string[] = []; // Kiro 现在有自己的表单 - const isApiKey = ["openai", "claude"].includes(providerType); + const isApiKey = ["openai", "claude", "gemini_api_key"].includes( + providerType, + ); const handleSelectFile = async () => { try { @@ -197,6 +200,14 @@ export function AddCredentialModal({ trimmedName, ); break; + case "gemini_api_key": + await providerPoolApi.addGeminiApiKey( + apiKey, + baseUrl.trim() || undefined, + excludedModels.length > 0 ? excludedModels : undefined, + trimmedName, + ); + break; } } @@ -284,7 +295,9 @@ export function AddCredentialModal({ placeholder={ providerType === "openai" ? "https://api.openai.com/v1" - : "https://api.anthropic.com/v1" + : providerType === "claude" + ? "https://api.anthropic.com/v1" + : "https://generativelanguage.googleapis.com" } className="w-full rounded-lg border bg-background px-3 py-2 text-sm" /> @@ -292,6 +305,31 @@ export function AddCredentialModal({ 留空使用默认 URL,或输入自定义代理地址

+ + {providerType === "gemini_api_key" && ( +
+ + + setExcludedModels( + e.target.value + .split(",") + .map((s) => s.trim()) + .filter((s) => s), + ) + } + placeholder="gemini-1.5-pro, gemini-1.5-flash..." + className="w-full rounded-lg border bg-background px-3 py-2 text-sm" + /> +

+ 用逗号分隔多个模型名称,支持通配符(如 *-preview) +

+
+ )} ); diff --git a/src/components/provider-pool/EditCredentialModal.tsx b/src/components/provider-pool/EditCredentialModal.tsx index ccba24792..954e296a3 100644 --- a/src/components/provider-pool/EditCredentialModal.tsx +++ b/src/components/provider-pool/EditCredentialModal.tsx @@ -60,6 +60,14 @@ const providerModels: Record = { "claude-sonnet-4-20250514", ], // Claude OAuth iflow: ["deepseek-chat", "deepseek-reasoner"], // iFlow + gemini_api_key: [ + "gemini-2.5-flash", + "gemini-2.5-flash-lite", + "gemini-2.5-pro", + "gemini-2.5-pro-preview-06-05", + "gemini-2.5-flash-preview-09-2025", + "gemini-3-pro-preview", + ], // Gemini API Key }; export function EditCredentialModal({ diff --git a/src/components/provider-pool/ProviderPoolPage.tsx b/src/components/provider-pool/ProviderPoolPage.tsx index dd491a04c..8116dea46 100644 --- a/src/components/provider-pool/ProviderPoolPage.tsx +++ b/src/components/provider-pool/ProviderPoolPage.tsx @@ -44,8 +44,8 @@ const oauthProviderTypes: PoolProviderType[] = [ // API Key 类型凭证(直接填入 API Key) const apiKeyProviderTypes: PoolProviderType[] = ["openai", "claude"]; -// 配置类型 tab(非凭证池)- gemini_api 移到 API Key 分类下 -type ConfigTabType = "gemini_api" | "vertex" | "amp"; +// 配置类型 tab(非凭证池,存储在配置文件中) +type ConfigTabType = "vertex" | "amp" | "gemini_api_key"; // 所有 tab 类型 type TabType = PoolProviderType | ConfigTabType; @@ -60,17 +60,18 @@ const providerLabels: Record = { codex: "Codex (OAuth / API Key)", claude_oauth: "Claude OAuth", iflow: "iFlow", + gemini_api_key: "Gemini", }; const configTabLabels: Record = { - gemini_api: "Gemini", vertex: "Vertex AI", amp: "Amp CLI", + gemini_api_key: "Gemini API Key", }; // 判断是否为配置类型 tab const isConfigTab = (tab: TabType): tab is ConfigTabType => { - return ["gemini_api", "vertex", "amp"].includes(tab); + return ["vertex", "amp", "gemini_api_key"].includes(tab); }; // 分类类型 @@ -488,10 +489,10 @@ export const ProviderPoolPage = forwardRef( })} {/* Gemini API Key - 配置文件存储但归类到 API Key */}