返回提交历史
Modified
etc/unittest/mcp.py
+2
-2
Modified
etc/unittest/models.py
+10
-7
Modified
g4f/Provider/needs_auth/LMArena.py
+2
-2
Modified
g4f/Provider/template/OpenaiTemplate.py
+2
-2
Modified
g4f/mcp/server.py
+2
-2
Modified
g4f/models.py
+1
-1
XFEstudio/gpt4free
Enhance MCP server tests to reflect updated tool count; improve model fetching with timeout handling in providers
af56ac0c
代码差异
6 个文件
+19
-16
@@ -22,7 +22,7 @@ class TestMCPServer(unittest.IsolatedAsyncioTestCase):
22
22
server = MCPServer()
23
23
self.assertIsNotNone(server)
24
24
self.assertEqual(server.server_info["name"], "gpt4free-mcp-server")
25
self.assertEqual(len(server.tools), 3)
25
self.assertEqual(len(server.tools), 5)
26
26
self.assertIn('web_search', server.tools)
27
27
self.assertIn('web_scrape', server.tools)
28
28
self.assertIn('image_generation', server.tools)
@@ -57,7 +57,7 @@ class TestMCPServer(unittest.IsolatedAsyncioTestCase):
57
57
self.assertEqual(response.id, 2)
58
58
self.assertIsNotNone(response.result)
59
59
self.assertIn("tools", response.result)
60
self.assertEqual(len(response.result["tools"]), 3)
60
self.assertEqual(len(response.result["tools"]), 5)
61
61
62
62
# Check tool structure
63
63
tool_names = [tool["name"] for tool in response.result["tools"]]
@@ -1,6 +1,6 @@
1
1
import unittest
2
2
from typing import Type
3
import asyncio
3
from requests.exceptions import RequestException
4
4
5
5
from g4f.models import __models__
6
6
from g4f.providers.base_provider import BaseProvider, ProviderModelMixin
@@ -15,12 +15,15 @@ class TestProviderHasModel(unittest.TestCase):
15
15
if provider.needs_auth:
16
16
continue
17
17
if issubclass(provider, ProviderModelMixin):
18
provider.get_models() # Update models
19
if model.name in provider.model_aliases:
20
model_name = provider.model_aliases[model.name]
21
else:
22
model_name = model.get_long_name()
23
self.provider_has_model(provider, model_name)
18
try:
19
provider.get_models(timeout=5) # Update models
20
if model.name in provider.model_aliases:
21
model_name = provider.model_aliases[model.name]
22
else:
23
model_name = model.get_long_name()
24
self.provider_has_model(provider, model_name)
25
except RequestException:
26
continue
24
27
25
28
def provider_has_model(self, provider: Type[BaseProvider], model: str):
26
29
if provider.__name__ not in self.cache:
@@ -502,7 +502,7 @@ class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
502
502
_models_loaded = False
503
503
504
504
@classmethod
505
def get_models(cls) -> list[str]:
505
def get_models(cls, timeout: int = None) -> list[str]:
506
506
if not cls._models_loaded and has_curl_cffi:
507
507
cache_file = cls.get_cache_file()
508
508
args = {}
@@ -516,7 +516,7 @@ class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
516
516
args = {}
517
517
if not args:
518
518
return cls.models
519
response = curl_cffi.get(f"{cls.url}/?mode=direct", **args)
519
response = curl_cffi.get(f"{cls.url}/?mode=direct", **args, timeout=timeout)
520
520
if response.ok:
521
521
for line in response.text.splitlines():
522
522
if "initialModels" in line:
@@ -31,7 +31,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
31
31
max_tokens: int = None
32
32
33
33
@classmethod
34
def get_models(cls, api_key: str = None, api_base: str = None) -> list[str]:
34
def get_models(cls, api_key: str = None, api_base: str = None, timeout: int = None) -> list[str]:
35
35
if not cls.models:
36
36
try:
37
37
if api_base is None:
@@ -42,7 +42,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
42
42
api_key = AuthManager.load_api_key(cls)
43
43
if cls.models_needs_auth and not api_key:
44
44
raise MissingAuthError('Add a "api_key"')
45
response = requests.get(f"{api_base}/models", headers=cls.get_headers(False, api_key), verify=cls.ssl)
45
response = requests.get(f"{api_base}/models", headers=cls.get_headers(False, api_key), verify=cls.ssl, timeout=timeout)
46
46
raise_for_status(response)
47
47
data = response.json()
48
48
data = data.get("data", data.get("models")) if isinstance(data, dict) else data
@@ -18,8 +18,6 @@ from dataclasses import dataclass
18
18
19
19
from ..debug import enable_logging
20
20
21
enable_logging()
22
23
21
from .tools import MarkItDownTool, TextToAudioTool, WebSearchTool, WebScrapeTool, ImageGenerationTool
24
22
from .tools import WebSearchTool, WebScrapeTool, ImageGenerationTool
25
23
@@ -214,6 +212,8 @@ class MCPServer:
214
212
sys.stderr.write("Error: aiohttp is required for HTTP transport\n")
215
213
sys.stderr.write("Install it with: pip install aiohttp\n")
216
214
sys.exit(1)
215
216
enable_logging()
217
217
218
218
async def handle_mcp_request(request: web.Request) -> web.Response:
219
219
nonlocal origin
@@ -213,7 +213,7 @@ gpt_4o = VisionModel(
213
213
gpt_4o_mini = Model(
214
214
name = 'gpt-4o-mini',
215
215
base_provider = 'OpenAI',
216
best_provider = IterListProvider([Chatai, OIVSCodeSer2, Startnest, OpenaiChat, OIVSCodeSer0501])
216
best_provider = IterListProvider([Chatai, OIVSCodeSer2, Startnest, OpenaiChat])
217
217
)
218
218
219
219
gpt_4o_mini_audio = AudioModel(