diff --git a/frontend/src/components/Agent/ProvidersSettings.tsx b/frontend/src/components/Agent/ProvidersSettings.tsx
index 46ebebd..d3bd6e0 100644
--- a/frontend/src/components/Agent/ProvidersSettings.tsx
+++ b/frontend/src/components/Agent/ProvidersSettings.tsx
@@ -181,7 +181,6 @@ export function ProvidersSettings() {
className="w-full bg-slate-50 border border-slate-200 text-sm rounded-lg px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all cursor-pointer"
>
-
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
index 662d5fe..1308952 100644
--- a/frontend/src/types/index.ts
+++ b/frontend/src/types/index.ts
@@ -14,7 +14,7 @@ export interface User {
// Provider types
export interface Provider {
- provider_type: 'openai' | 'gemini' | 'claude' | 'local' | 'deepseek';
+ provider_type: 'openai' | 'claude' | 'local' | 'deepseek';
provider_title: string;
provider_url?: string;
provider_owner?: string;
@@ -25,7 +25,7 @@ export interface Provider {
}
export interface ProviderRegisterRequest {
- provider_type: 'openai' | 'gemini' | 'claude' | 'local' | 'deepseek';
+ provider_type: 'openai' | 'claude' | 'local' | 'deepseek';
provider_title: string;
provider_url: string;
provider_apikey: string;
diff --git a/pretor/adapter/model_adapter/agent_factory.py b/pretor/adapter/model_adapter/agent_factory.py
index db281a3..725769f 100644
--- a/pretor/adapter/model_adapter/agent_factory.py
+++ b/pretor/adapter/model_adapter/agent_factory.py
@@ -14,10 +14,8 @@
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
-from pydantic_ai.models.google import GoogleModel
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.openai import OpenAIProvider
-from pydantic_ai.providers.google import GoogleProvider
from pydantic_ai.providers.anthropic import AnthropicProvider
from pretor.adapter.model_adapter.deepseek_reasoner import DeepSeekReasonerAgent
from pretor.core.global_state_machine.model_provider import Provider
@@ -27,7 +25,6 @@ from pretor.utils.error import ModelNotExistError
class AgentFactory:
def __init__(self):
self._models_mapping = {"openai": (OpenAIChatModel, OpenAIProvider),
- "gemini": (GoogleModel, GoogleProvider),
"claude": (AnthropicModel, AnthropicProvider),
"deepseek": (OpenAIChatModel, OpenAIProvider),}
diff --git a/pretor/adapter/model_adapter/deepseek_reasoner.py b/pretor/adapter/model_adapter/deepseek_reasoner.py
index 753354c..ee3193c 100644
--- a/pretor/adapter/model_adapter/deepseek_reasoner.py
+++ b/pretor/adapter/model_adapter/deepseek_reasoner.py
@@ -104,6 +104,11 @@ class DeepSeekReasonerAgent(Generic[T]):
except json.JSONDecodeError as e:
raise ValueError(f"返回的不是合法的 JSON:{e}")
+
+ def __getattr__(self, item):
+ # Delegate any unknown attributes (like .system_prompt, .tool) to the underlying pydantic_ai Agent
+ return getattr(self.agent, item)
+
async def run(self, user_prompt: str, deps: Any = None, message_history: list = None, **kwargs) -> Any:
# Custom retry loop
current_history = message_history or []
diff --git a/pretor/api/provider.py b/pretor/api/provider.py
index 07f3285..3ebfba5 100644
--- a/pretor/api/provider.py
+++ b/pretor/api/provider.py
@@ -25,7 +25,7 @@ from pretor.utils.ray_hook import ray_actor_hook
provider_router = APIRouter(prefix="/api/v1/provider", tags=["provider"])
class ProviderRegister(BaseModel):
- provider_type: Literal["openai", "gemini", "claude", "deepseek"]
+ provider_type: Literal["openai", "claude", "deepseek"]
provider_title: str
provider_url: str
provider_apikey: str
diff --git a/pretor/core/global_state_machine/model_provider/__init__.py b/pretor/core/global_state_machine/model_provider/__init__.py
index 77aded4..5cb81a3 100644
--- a/pretor/core/global_state_machine/model_provider/__init__.py
+++ b/pretor/core/global_state_machine/model_provider/__init__.py
@@ -14,7 +14,6 @@
from pretor.core.global_state_machine.model_provider.base_provider import Provider, ProviderArgs
from pretor.core.global_state_machine.model_provider.openai_provider import OpenAIProvider
-from pretor.core.global_state_machine.model_provider.gemini_provider import GeminiProvider
from pretor.core.global_state_machine.model_provider.claude_provider import ClaudeProvider
from pretor.core.global_state_machine.model_provider.deepseek_provider import DeepseekProvider
-__all__ = ["Provider", "ProviderArgs", "OpenAIProvider", "GeminiProvider", "ClaudeProvider", "DeepseekProvider"]
+__all__ = ["Provider", "ProviderArgs", "OpenAIProvider", "ClaudeProvider", "DeepseekProvider"]
diff --git a/pretor/core/global_state_machine/model_provider/gemini_provider.py b/pretor/core/global_state_machine/model_provider/gemini_provider.py
deleted file mode 100644
index b2ad340..0000000
--- a/pretor/core/global_state_machine/model_provider/gemini_provider.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from pretor.utils.retry import retry_on_retryable_error
-# Copyright 2026 zhaoxi826
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from pretor.core.global_state_machine.model_provider.base_provider import BaseProvider, Provider, ProviderArgs
-import httpx
-from typing import List
-
-class GeminiProvider(BaseProvider):
- @staticmethod
- async def create_provider(provider_args: ProviderArgs) -> Provider:
- provider_models: List[str] = await GeminiProvider._load_models(provider_args)
- provider: Provider = GeminiProvider._return_provider(provider_args, provider_models)
- return provider
-
- @staticmethod
- @retry_on_retryable_error()
- async def _load_models(provider_args: ProviderArgs) -> List[str]:
- # Google Gemini 原生鉴权通常使用 x-goog-api-key 或 query parameter
- headers = {
- "x-goog-api-key": provider_args.provider_apikey,
- "Content-Type": "application/json"
- }
- # 官方路径通常是 v1beta/models
- url = f"{provider_args.provider_url.rstrip('/')}/v1beta/models"
-
- try:
- async with httpx.AsyncClient(timeout=10.0) as client:
- response = await client.get(url, headers=headers)
- if response.status_code != 200:
- print(f"[{provider_args.provider_title}] 获取 Gemini 模型失败: {response.status_code}")
- return []
-
- data = response.json()
- # Gemini 返回的结构中模型 ID 通常带 "models/" 前缀
- raw_models = data.get("models", [])
- model_ids = [m["name"].split("/")[-1] for m in raw_models if
- "generateContent" in m.get("supportedGenerationMethods", [])]
- return sorted(list(set(model_ids)))
- except httpx.RequestError as e:
- from pretor.utils.error import RetryableError
- print(f"[{provider_args.provider_title}] 网络请求异常: {e}")
- raise RetryableError(f"[{provider_args.provider_title}] 网络请求异常: {e}") from e
- except Exception as e:
- print(f"[{provider_args.provider_title}] 获取 Gemini 模型列表错误: {e}")
- return []
-
- @staticmethod
- def _return_provider(provider_args: ProviderArgs, provider_models: List[str]) -> Provider:
- return Provider(provider_title=provider_args.provider_title,
- provider_apikey=provider_args.provider_apikey,
- provider_url=provider_args.provider_url,
- provider_models=provider_models,
- provider_type="gemini")
\ No newline at end of file
diff --git a/pretor/core/global_state_machine/provider_manager.py b/pretor/core/global_state_machine/provider_manager.py
index fa5ef25..b714700 100644
--- a/pretor/core/global_state_machine/provider_manager.py
+++ b/pretor/core/global_state_machine/provider_manager.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from pretor.core.global_state_machine.model_provider import Provider, OpenAIProvider,GeminiProvider, ClaudeProvider, DeepseekProvider
+from pretor.core.global_state_machine.model_provider import Provider, OpenAIProvider, ClaudeProvider, DeepseekProvider
from typing import Dict, Type
class ProviderManager:
@@ -28,7 +28,6 @@ class ProviderManager:
"""供应商注册表:键为用户自定义别名,值为已实例化的 Provider 对象。"""
def __init__(self, postgres):
self.provider_mapper = {"openai": OpenAIProvider,
- "gemini": GeminiProvider,
"claude": ClaudeProvider,
"deepseek": DeepseekProvider}
self.provider_register = {}
diff --git a/tests/core/global_state_machine/model_provider/gemini_provider_test.py b/tests/core/global_state_machine/model_provider/gemini_provider_test.py
deleted file mode 100644
index b1f7f61..0000000
--- a/tests/core/global_state_machine/model_provider/gemini_provider_test.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import pytest
-from unittest.mock import patch, MagicMock, AsyncMock
-from pretor.core.global_state_machine.model_provider.gemini_provider import GeminiProvider, ProviderArgs
-
-
-@pytest.fixture
-def provider_args():
- return ProviderArgs(
- provider_title="TestGemini",
- provider_url="https://generativelanguage.googleapis.com",
- provider_apikey="testkey",
- provider_owner="1"
- )
-
-
-@pytest.mark.asyncio
-@patch("pretor.core.global_state_machine.model_provider.gemini_provider.httpx.AsyncClient")
-async def test_load_models_success(mock_client, provider_args):
- mock_response = MagicMock()
- mock_response.status_code = 200
- mock_response.json.return_value = {
- "models": [
- {"name": "models/gemini-1.5-pro", "supportedGenerationMethods": ["generateContent"]},
- {"name": "models/gemini-1.5-flash", "supportedGenerationMethods": ["generateContent"]},
- {"name": "models/other", "supportedGenerationMethods": []}
- ]
- }
-
- mock_client_instance = AsyncMock()
- mock_client_instance.get.return_value = mock_response
- mock_client.return_value.__aenter__.return_value = mock_client_instance
-
- models = await GeminiProvider._load_models(provider_args)
- assert models == ["gemini-1.5-flash", "gemini-1.5-pro"]
-
-
-@pytest.mark.asyncio
-@patch("pretor.core.global_state_machine.model_provider.gemini_provider.httpx.AsyncClient")
-async def test_load_models_status_error(mock_client, provider_args):
- mock_response = MagicMock()
- mock_response.status_code = 401
-
- mock_client_instance = AsyncMock()
- mock_client_instance.get.return_value = mock_response
- mock_client.return_value.__aenter__.return_value = mock_client_instance
-
- models = await GeminiProvider._load_models(provider_args)
- assert models == []
-
-
-@pytest.mark.asyncio
-@patch("pretor.core.global_state_machine.model_provider.gemini_provider.httpx.AsyncClient")
-async def test_load_models_error(mock_client, provider_args):
- mock_client_instance = AsyncMock()
- mock_client_instance.get.side_effect = Exception("network error")
- mock_client.return_value.__aenter__.return_value = mock_client_instance
-
- models = await GeminiProvider._load_models(provider_args)
- assert models == []
-
-
-@pytest.mark.asyncio
-@patch("pretor.core.global_state_machine.model_provider.gemini_provider.GeminiProvider._load_models",
- return_value=["gemini-1"])
-async def test_create_provider(mock_load, provider_args):
- provider = await GeminiProvider.create_provider(provider_args)
- assert provider.provider_title == "TestGemini"
- assert provider.provider_models == ["gemini-1"]
- assert provider.provider_type == "gemini"
diff --git a/tests/core/global_state_machine/provider_manager_test.py b/tests/core/global_state_machine/provider_manager_test.py
index 27c3fa3..1111dd1 100644
--- a/tests/core/global_state_machine/provider_manager_test.py
+++ b/tests/core/global_state_machine/provider_manager_test.py
@@ -21,7 +21,6 @@ async def test_provider_manager_init():
await manager.init_provider_register(mock_postgres)
assert "openai" in manager.provider_mapper
- assert "gemini" in manager.provider_mapper
assert "claude" in manager.provider_mapper
assert manager.provider_register["title1"] == mock_provider1