XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Update provider configurations to set 'working' status to False; refactor tool handling in GeminiCLI and enhance response structure in Usage class

aa0aade9
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

11 个文件 +60 -21
Modified g4f/Provider/GLM.py +1 -1
@@ -18,7 +18,7 @@ from .base_provider import AsyncGeneratorProvider, ProviderModelMixin, AuthFileM
18 18 class GLM(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
19 19 url = "https://chat.z.ai"
20 20 api_endpoint = "https://chat.z.ai/api/chat/completions"
21 working = True
21 working = False
22 22 active_by_default = True
23 23 default_model = "GLM-4.5"
24 24
Modified g4f/Provider/LambdaChat.py +1 -2
@@ -11,7 +11,6 @@ from ..requests import raise_for_status
11 11 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
12 12 from .helper import get_last_user_message
13 13 from ..providers.response import TitleGeneration, Reasoning, FinishReason
14 from ..errors import ModelNotFoundError
15 14 from .. import debug
16 15
17 16
@@ -20,7 +19,7 @@ class LambdaChat(AsyncGeneratorProvider, ProviderModelMixin):
20 19 url = "https://lambda.chat"
21 20 conversation_url = f"{url}/conversation"
22 21
23 working = True
22 working = False
24 23 active_by_default = True
25 24
26 25 default_model = "deepseek-llama3.3-70b"
Modified g4f/Provider/PollinationsAI.py +3 -3
@@ -18,7 +18,7 @@ from ..requests.aiohttp import get_connector
18 18 from ..image import use_aspect_ratio
19 19 from ..providers.response import ImageResponse, Reasoning, TitleGeneration, SuggestedFollowups, JsonRequest
20 20 from ..tools.media import render_messages
21 from ..config import STATIC_URL
21 from ..config import REFFERER_URL
22 22 from .template.OpenaiTemplate import read_response
23 23 from .. import debug
24 24
@@ -168,7 +168,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
168 168 stream: bool = True,
169 169 proxy: str = None,
170 170 cache: bool = None,
171 referrer: str = STATIC_URL,
171 referrer: str = REFFERER_URL,
172 172 api_key: str = None,
173 173 extra_body: dict = None,
174 174 # Image generation parameters
@@ -422,7 +422,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
422 422 frequency_penalty=frequency_penalty,
423 423 response_format=response_format,
424 424 stream=stream,
425 seed=None if model == "grok" else seed,
425 seed=None if "tools" in extra_body else seed,
426 426 referrer=referrer,
427 427 **extra_body
428 428 )
Modified g4f/Provider/PollinationsImage.py +2 -2
@@ -4,7 +4,7 @@ from typing import Optional
4 4
5 5 from .helper import format_media_prompt
6 6 from ..typing import AsyncResult, Messages, MediaListType
7 from ..config import STATIC_URL
7 from ..config import REFFERER_URL
8 8 from .PollinationsAI import PollinationsAI
9 9
10 10 class PollinationsImage(PollinationsAI):
@@ -37,7 +37,7 @@ class PollinationsImage(PollinationsAI):
37 37 messages: Messages,
38 38 media: MediaListType = None,
39 39 proxy: str = None,
40 referrer: str = STATIC_URL,
40 referrer: str = REFFERER_URL,
41 41 api_key: str = None,
42 42 prompt: str = None,
43 43 aspect_ratio: str = None,
Modified g4f/Provider/needs_auth/GeminiCLI.py +32 -9
@@ -353,6 +353,21 @@ class GeminiCLIProvider():
353 353 if system_prompt:
354 354 requestData["system_instruction"] = {"parts": {"text": system_prompt}}
355 355
356 # Convert OpenAI-style tools to Gemini format
357 gemini_tools = None
358 if tools:
359 function_declarations = []
360 for tool in tools:
361 if tool.get("type") == "function" and "function" in tool:
362 func = tool["function"]
363 function_declarations.append({
364 "name": func.get("name"),
365 "description": func.get("description", ""),
366 "parameters": func.get("parameters", {})
367 })
368 if function_declarations:
369 gemini_tools = [{"functionDeclarations": function_declarations}]
370
356 371 # Compose request body
357 372 req_body = {
358 373 "model": model,
@@ -373,13 +388,13 @@ class GeminiCLIProvider():
373 388 "includeThoughts": True
374 389 } if thinking_budget else None,
375 390 },
376 "tools": tools or [],
391 "tools": gemini_tools,
377 392 "toolConfig": {
378 393 "functionCallingConfig": {
379 394 "mode": tool_choice.upper(),
380 "allowedFunctionNames": [tool["function"]["name"] for tool in tools]
395 "allowedFunctionNames": [fd["name"] for fd in function_declarations]
381 396 }
382 } if tool_choice else None,
397 } if tool_choice and gemini_tools else None,
383 398 **requestData
384 399 },
385 400 }
@@ -485,12 +500,20 @@ class GeminiCLIProvider():
485 500 yield ImageResponse(file_data.get("fileUri"))
486 501
487 502 if tool_calls:
488 yield ToolCalls(tool_calls)
489 if usage_metadata:
490 yield Usage(
491 promptTokens=usage_metadata.get("promptTokenCount", 0),
492 completionTokens=usage_metadata.get("candidatesTokenCount", 0),
493 )
503 # Convert Gemini tool calls to OpenAI format
504 openai_tool_calls = []
505 for i, tc in enumerate(tool_calls):
506 openai_tool_calls.append({
507 "id": f"call_{i}_{tc.get('name', 'unknown')}",
508 "type": "function",
509 "function": {
510 "name": tc.get("name"),
511 "arguments": json.dumps(tc.get("args", {}))
512 }
513 })
514 yield ToolCalls(openai_tool_calls)
515 if usage_metadata:
516 yield Usage(**usage_metadata)
494 517
495 518 class GeminiCLI(AsyncGeneratorProvider, ProviderModelMixin):
496 519 label = "Google Gemini CLI"
Modified g4f/Provider/needs_auth/GeminiPro.py +1 -3
@@ -31,10 +31,8 @@ class GeminiPro(AsyncGeneratorProvider, ProviderModelMixin):
31 31 default_model = "gemini-2.5-flash"
32 32 default_vision_model = default_model
33 33 fallback_models = [
34 "gemini-2.0-flash",
35 "gemini-2.0-flash-lite",
36 "gemini-2.0-flash-thinking-exp",
37 34 "gemini-2.5-flash",
35 "gemini-2.5-flash-lite",
38 36 "gemma-3-1b-it",
39 37 "gemma-3-12b-it",
40 38 "gemma-3-27b-it",
Modified g4f/Provider/needs_auth/LMArena.py +6 -0
@@ -598,6 +598,12 @@ class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
598 598 button = await page.select('[type="submit"]:has([data-sentry-element="ArrowUp"])')
599 599 if button:
600 600 await button.click()
601 button = await page.find("Agree")
602 if button:
603 await button.click()
604 else:
605 debug.log("No 'Agree' button found, skipping.")
606 await asyncio.sleep(1)
601 607 element = await page.select('[style="display: grid;"]')
602 608 if element:
603 609 await click_trunstile(page, 'document.querySelector(\'[style="display: grid;"]\')')
Modified g4f/Provider/needs_auth/hf/HuggingChat.py +1 -0
@@ -36,6 +36,7 @@ class HuggingChat(AsyncAuthedProvider, ProviderModelMixin):
36 36 url = f"{origin}/chat"
37 37
38 38 working = True
39 active_by_default = True
39 40 use_nodriver = True
40 41 supports_stream = True
41 42 needs_auth = True
Modified g4f/config.py +2 -1
@@ -25,7 +25,8 @@ CUSTOM_COOKIES_DIR = "./har_and_cookies"
25 25 ORGANIZATION = "gpt4free"
26 26 GITHUB_REPOSITORY = f"xtekky/{ORGANIZATION}"
27 27 STATIC_DOMAIN = f"{PACKAGE_NAME}.dev"
28 STATIC_URL = f"https://static.{STATIC_DOMAIN}/"
28 STATIC_URL = f"https://{ORGANIZATION}.github.io/"
29 REFFERER_URL = f"https://{STATIC_DOMAIN}/"
29 30 DIST_DIR = f"./{STATIC_DOMAIN}/dist"
30 31 DEFAULT_MODEL = "openai/gpt-oss-120b"
31 32 JSDELIVR_URL = "https://cdn.jsdelivr.net/"
Modified g4f/gui/server/api.py +2 -0
@@ -275,6 +275,8 @@ class Api:
275 275 yield self._format_json("log", chunk.log)
276 276 elif isinstance(chunk, ContinueResponse):
277 277 yield self._format_json("continue", chunk.log)
278 elif isinstance(chunk, ToolCalls):
279 yield self._format_json("tool_calls", chunk.list)
278 280 elif isinstance(chunk, RawResponse):
279 281 yield self._format_json(chunk.type, **chunk.get_dict())
280 282 elif isinstance(chunk, JsonRequest):
Modified g4f/providers/response.py +9 -0
@@ -204,6 +204,9 @@ class Usage(JsonMixin, HiddenResponse):
204 204 input_tokens: int = None,
205 205 output_tokens: int = None,
206 206 output_tokens_details: Dict = None,
207 promptTokenCount: int = None,
208 candidatesTokenCount: int = None,
209 totalTokenCount: int = None,
207 210 **kwargs
208 211 ):
209 212 if promptTokens is not None:
@@ -214,6 +217,12 @@ class Usage(JsonMixin, HiddenResponse):
214 217 kwargs["prompt_tokens"] = input_tokens
215 218 if output_tokens is not None:
216 219 kwargs["completion_tokens"] = output_tokens
220 if promptTokenCount is not None:
221 kwargs["prompt_tokens"] = promptTokenCount
222 if candidatesTokenCount is not None:
223 kwargs["completion_tokens"] = candidatesTokenCount
224 if totalTokenCount is not None:
225 kwargs["total_tokens"] = totalTokenCount
217 226 if output_tokens_details is not None:
218 227 for key, value in output_tokens_details.items():
219 228 kwargs[key] = value