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

XFEstudio/gpt4free

Show only free providers by default

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

代码差异

14 个文件 +84 -59
Modified g4f/Provider/PollinationsAI.py +6 -3
@@ -123,9 +123,6 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
123 123 if model not in cls.image_models:
124 124 raise
125 125
126 if not cache and seed is None:
127 seed = random.randint(1000, 999999)
128
129 126 if model in cls.image_models:
130 127 async for chunk in cls._generate_image(
131 128 model=model,
@@ -134,6 +131,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
134 131 width=width,
135 132 height=height,
136 133 seed=seed,
134 cache=cache,
137 135 nologo=nologo,
138 136 private=private,
139 137 enhance=enhance,
@@ -165,11 +163,14 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
165 163 width: int,
166 164 height: int,
167 165 seed: Optional[int],
166 cache: bool,
168 167 nologo: bool,
169 168 private: bool,
170 169 enhance: bool,
171 170 safe: bool
172 171 ) -> AsyncResult:
172 if not cache and seed is None:
173 seed = random.randint(9999, 99999999)
173 174 params = {
174 175 "seed": str(seed) if seed is not None else None,
175 176 "width": str(width),
@@ -207,6 +208,8 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
207 208 seed: Optional[int],
208 209 cache: bool
209 210 ) -> AsyncResult:
211 if not cache and seed is None:
212 seed = random.randint(9999, 99999999)
210 213 json_mode = False
211 214 if response_format and response_format.get("type") == "json_object":
212 215 json_mode = True
Modified g4f/Provider/PollinationsImage.py +2 -0
@@ -28,6 +28,7 @@ class PollinationsImage(PollinationsAI):
28 28 width: int = 1024,
29 29 height: int = 1024,
30 30 seed: Optional[int] = None,
31 cache: bool = False,
31 32 nologo: bool = True,
32 33 private: bool = False,
33 34 enhance: bool = False,
@@ -41,6 +42,7 @@ class PollinationsImage(PollinationsAI):
41 42 width=width,
42 43 height=height,
43 44 seed=seed,
45 cache=cache,
44 46 nologo=nologo,
45 47 private=private,
46 48 enhance=enhance,
Modified g4f/Provider/hf/HuggingChat.py +2 -1
@@ -8,7 +8,8 @@ import base64
8 8 from typing import AsyncIterator
9 9
10 10 try:
11 from curl_cffi.requests import Session, CurlMime
11 from curl_cffi.requests import Session
12 from curl_cffi import CurlMime
12 13 has_curl_cffi = True
13 14 except ImportError:
14 15 has_curl_cffi = False
Modified g4f/Provider/hf/HuggingFaceAPI.py +9 -7
@@ -4,6 +4,7 @@ from ...providers.types import Messages
4 4 from ...typing import ImagesType
5 5 from ...requests import StreamSession, raise_for_status
6 6 from ...errors import ModelNotSupportedError
7 from ...providers.helper import get_last_user_message
7 8 from ..template.OpenaiTemplate import OpenaiTemplate
8 9 from .models import model_aliases, vision_models, default_vision_model
9 10 from .HuggingChat import HuggingChat
@@ -22,7 +23,7 @@ class HuggingFaceAPI(OpenaiTemplate):
22 23 vision_models = vision_models
23 24 model_aliases = model_aliases
24 25
25 pipeline_tag: dict[str, str] = {}
26 pipeline_tags: dict[str, str] = {}
26 27
27 28 @classmethod
28 29 def get_models(cls, **kwargs):
@@ -36,8 +37,8 @@ class HuggingFaceAPI(OpenaiTemplate):
36 37
37 38 @classmethod
38 39 async def get_pipline_tag(cls, model: str, api_key: str = None):
39 if model in cls.pipeline_tag:
40 return cls.pipeline_tag[model]
40 if model in cls.pipeline_tags:
41 return cls.pipeline_tags[model]
41 42 async with StreamSession(
42 43 timeout=30,
43 44 headers=cls.get_headers(False, api_key),
@@ -45,8 +46,8 @@ class HuggingFaceAPI(OpenaiTemplate):
45 46 async with session.get(f"https://huggingface.co/api/models/{model}") as response:
46 47 await raise_for_status(response)
47 48 model_data = await response.json()
48 cls.pipeline_tag[model] = model_data.get("pipeline_tag")
49 return cls.pipeline_tag[model]
49 cls.pipeline_tags[model] = model_data.get("pipeline_tag")
50 return cls.pipeline_tags[model]
50 51
51 52 @classmethod
52 53 async def create_async_generator(
@@ -73,10 +74,11 @@ class HuggingFaceAPI(OpenaiTemplate):
73 74 if len(messages) > 6:
74 75 messages = messages[:3] + messages[-3:]
75 76 if calculate_lenght(messages) > max_inputs_lenght:
77 last_user_message = [{"role": "user", "content": get_last_user_message(messages)}]
76 78 if len(messages) > 2:
77 messages = [m for m in messages if m["role"] == "system"] + messages[-1:]
79 messages = [m for m in messages if m["role"] == "system"] + last_user_message
78 80 if len(messages) > 1 and calculate_lenght(messages) > max_inputs_lenght:
79 messages = [messages[-1]]
81 messages = last_user_message
80 82 debug.log(f"Messages trimmed from: {start} to: {calculate_lenght(messages)}")
81 83 async for chunk in super().create_async_generator(model, messages, api_base=api_base, api_key=api_key, max_tokens=max_tokens, images=images, **kwargs):
82 84 yield chunk
Modified g4f/Provider/hf/HuggingFaceInference.py +41 -32
@@ -7,7 +7,7 @@ import requests
7 7
8 8 from ...typing import AsyncResult, Messages
9 9 from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, format_prompt
10 from ...errors import ModelNotFoundError, ModelNotSupportedError, ResponseError
10 from ...errors import ModelNotSupportedError, ResponseError
11 11 from ...requests import StreamSession, raise_for_status
12 12 from ...providers.response import FinishReason, ImageResponse
13 13 from ..helper import format_image_prompt, get_last_user_message
@@ -24,6 +24,8 @@ class HuggingFaceInference(AsyncGeneratorProvider, ProviderModelMixin):
24 24 model_aliases = model_aliases
25 25 image_models = image_models
26 26
27 model_data: dict[str, dict] = {}
28
27 29 @classmethod
28 30 def get_models(cls) -> list[str]:
29 31 if not cls.models:
@@ -43,6 +45,17 @@ class HuggingFaceInference(AsyncGeneratorProvider, ProviderModelMixin):
43 45 cls.models = models
44 46 return cls.models
45 47
48 @classmethod
49 async def get_model_data(cls, session: StreamSession, model: str) -> str:
50 if model in cls.model_data:
51 return cls.model_data[model]
52 async with session.get(f"https://huggingface.co/api/models/{model}") as response:
53 if response.status == 404:
54 raise ModelNotSupportedError(f"Model is not supported: {model} in: {cls.__name__}")
55 await raise_for_status(response)
56 cls.model_data[model] = await response.json()
57 return cls.model_data[model]
58
46 59 @classmethod
47 60 async def create_async_generator(
48 61 cls,
@@ -96,41 +109,37 @@ class HuggingFaceInference(AsyncGeneratorProvider, ProviderModelMixin):
96 109 timeout=600
97 110 ) as session:
98 111 if payload is None:
99 async with session.get(f"https://huggingface.co/api/models/{model}") as response:
100 if response.status == 404:
101 raise ModelNotSupportedError(f"Model is not supported: {model} in: {cls.__name__}")
102 await raise_for_status(response)
103 model_data = await response.json()
104 pipeline_tag = model_data.get("pipeline_tag")
105 if pipeline_tag == "text-to-image":
106 stream = False
107 inputs = format_image_prompt(messages, prompt)
108 payload = {"inputs": inputs, "parameters": {"seed": random.randint(0, 2**32) if seed is None else seed, **extra_data}}
109 elif pipeline_tag in ("text-generation", "image-text-to-text"):
110 model_type = None
111 if "config" in model_data and "model_type" in model_data["config"]:
112 model_type = model_data["config"]["model_type"]
113 debug.log(f"Model type: {model_type}")
112 model_data = await cls.get_model_data(session, model)
113 pipeline_tag = model_data.get("pipeline_tag")
114 if pipeline_tag == "text-to-image":
115 stream = False
116 inputs = format_image_prompt(messages, prompt)
117 payload = {"inputs": inputs, "parameters": {"seed": random.randint(0, 2**32) if seed is None else seed, **extra_data}}
118 elif pipeline_tag in ("text-generation", "image-text-to-text"):
119 model_type = None
120 if "config" in model_data and "model_type" in model_data["config"]:
121 model_type = model_data["config"]["model_type"]
122 debug.log(f"Model type: {model_type}")
123 inputs = get_inputs(messages, model_data, model_type, do_continue)
124 debug.log(f"Inputs len: {len(inputs)}")
125 if len(inputs) > 4096:
126 if len(messages) > 6:
127 messages = messages[:3] + messages[-3:]
128 else:
129 messages = [m for m in messages if m["role"] == "system"] + [{"role": "user", "content": get_last_user_message(messages)}]
114 130 inputs = get_inputs(messages, model_data, model_type, do_continue)
115 debug.log(f"Inputs len: {len(inputs)}")
116 if len(inputs) > 4096:
117 if len(messages) > 6:
118 messages = messages[:3] + messages[-3:]
119 else:
120 messages = [m for m in messages if m["role"] == "system"] + [get_last_user_message(messages)]
121 inputs = get_inputs(messages, model_data, model_type, do_continue)
122 debug.log(f"New len: {len(inputs)}")
123 if model_type == "gpt2" and max_tokens >= 1024:
124 params["max_new_tokens"] = 512
125 if seed is not None:
126 params["seed"] = seed
127 payload = {"inputs": inputs, "parameters": params, "stream": stream}
128 else:
129 raise ModelNotSupportedError(f"Model is not supported: {model} in: {cls.__name__} pipeline_tag: {pipeline_tag}")
131 debug.log(f"New len: {len(inputs)}")
132 if model_type == "gpt2" and max_tokens >= 1024:
133 params["max_new_tokens"] = 512
134 if seed is not None:
135 params["seed"] = seed
136 payload = {"inputs": inputs, "parameters": params, "stream": stream}
137 else:
138 raise ModelNotSupportedError(f"Model is not supported: {model} in: {cls.__name__} pipeline_tag: {pipeline_tag}")
130 139
131 140 async with session.post(f"{api_base.rstrip('/')}/models/{model}", json=payload) as response:
132 141 if response.status == 404:
133 raise ModelNotFoundError(f"Model is not supported: {model}")
142 raise ModelNotSupportedError(f"Model is not supported: {model}")
134 143 await raise_for_status(response)
135 144 if stream:
136 145 first = True
Modified g4f/Provider/hf/__init__.py +1 -1
@@ -36,7 +36,7 @@ class HuggingFace(AsyncGeneratorProvider, ProviderModelMixin):
36 36 messages: Messages,
37 37 **kwargs
38 38 ) -> AsyncResult:
39 if "api_key" not in kwargs and "images" not in kwargs and random.random() >= 0.5:
39 if "images" not in kwargs and "deepseek" in model or random.random() >= 0.5:
40 40 try:
41 41 is_started = False
42 42 async for chunk in HuggingFaceInference.create_async_generator(model, messages, **kwargs):
Modified g4f/Provider/needs_auth/DeepSeekAPI.py +0 -1
@@ -13,7 +13,6 @@ from ...errors import MissingAuthError
13 13 from ...requests import get_args_from_nodriver, get_nodriver
14 14 from ...providers.response import AuthResult, RequestLogin, Reasoning, JsonConversation, FinishReason
15 15 from ...typing import AsyncResult, Messages
16 from ... import debug
17 16 try:
18 17 from curl_cffi import requests
19 18 from dsk.api import DeepSeekAPI, AuthenticationError, DeepSeekPOW
Modified g4f/Provider/needs_auth/OpenaiAccount.py +2 -1
@@ -4,4 +4,5 @@ from .OpenaiChat import OpenaiChat
4 4
5 5 class OpenaiAccount(OpenaiChat):
6 6 needs_auth = True
7 parent = "OpenaiChat"
7 parent = "OpenaiChat"
8 use_nodriver = False # Show (Auth) in the model name
Modified g4f/Provider/template/OpenaiTemplate.py +1 -1
@@ -65,7 +65,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
65 65 prompt: str = None,
66 66 headers: dict = None,
67 67 impersonate: str = None,
68 extra_parameters: list[str] = ["tools", "parallel_tool_calls", "", "reasoning_effort", "logit_bias"],
68 extra_parameters: list[str] = ["tools", "parallel_tool_calls", "tool_choice", "reasoning_effort", "logit_bias"],
69 69 extra_data: dict = {},
70 70 **kwargs
71 71 ) -> AsyncResult:
Modified g4f/client/__init__.py +2 -2
@@ -365,7 +365,7 @@ class Images:
365 365 break
366 366 except Exception as e:
367 367 error = e
368 debug.error(e, name=f"{provider.__name__} {type(e).__name__}")
368 debug.error(f"{provider.__name__} {type(e).__name__}: {e}")
369 369 else:
370 370 response = await self._generate_image_response(provider_handler, provider_name, model, prompt, **kwargs)
371 371
@@ -460,7 +460,7 @@ class Images:
460 460 break
461 461 except Exception as e:
462 462 error = e
463 debug.error(e, name=f"{provider.__name__} {type(e).__name__}")
463 debug.error(f"{provider.__name__} {type(e).__name__}: {e}")
464 464 else:
465 465 response = await self._generate_image_response(provider_handler, provider_name, model, prompt, **kwargs)
466 466
Modified g4f/gui/client/static/js/chat.v1.js +14 -6
@@ -1932,7 +1932,7 @@ const load_provider_option = (input, provider_name) => {
1932 1932 providerSelect.querySelectorAll(`option[data-parent="${provider_name}"]`).forEach(
1933 1933 (el) => el.removeAttribute("disabled")
1934 1934 );
1935 settings.querySelector(`.field:has(#${provider_name}-api_key)`)?.classList.remove("hidden");
1935 //settings.querySelector(`.field:has(#${provider_name}-api_key)`)?.classList.remove("hidden");
1936 1936 } else {
1937 1937 modelSelect.querySelectorAll(`option[data-providers*="${provider_name}"]`).forEach(
1938 1938 (el) => {
@@ -1947,7 +1947,7 @@ const load_provider_option = (input, provider_name) => {
1947 1947 providerSelect.querySelectorAll(`option[data-parent="${provider_name}"]`).forEach(
1948 1948 (el) => el.setAttribute("disabled", "disabled")
1949 1949 );
1950 settings.querySelector(`.field:has(#${provider_name}-api_key)`)?.classList.add("hidden");
1950 //settings.querySelector(`.field:has(#${provider_name}-api_key)`)?.classList.add("hidden");
1951 1951 }
1952 1952 };
1953 1953
@@ -2039,13 +2039,13 @@ async function on_api() {
2039 2039
2040 2040 if (provider.parent) {
2041 2041 if (!login_urls[provider.parent]) {
2042 login_urls[provider.parent] = [provider.label, provider.login_url, [provider.name]];
2042 login_urls[provider.parent] = [provider.label, provider.login_url, [provider.name], provider.auth];
2043 2043 } else {
2044 2044 login_urls[provider.parent][2].push(provider.name);
2045 2045 }
2046 2046 } else if (provider.login_url) {
2047 2047 if (!login_urls[provider.name]) {
2048 login_urls[provider.name] = [provider.label, provider.login_url, []];
2048 login_urls[provider.name] = [provider.label, provider.login_url, [], provider.auth];
2049 2049 } else {
2050 2050 login_urls[provider.name][0] = provider.label;
2051 2051 login_urls[provider.name][1] = provider.login_url;
@@ -2068,9 +2068,10 @@ async function on_api() {
2068 2068 if (!provider.parent) {
2069 2069 let option = document.createElement("div");
2070 2070 option.classList.add("provider-item");
2071 let api_key = appStorage.getItem(`${provider.name}-api_key`);
2071 2072 option.innerHTML = `
2072 2073 <span class="label">Enable ${provider.label}</span>
2073 <input id="Provider${provider.name}" type="checkbox" name="Provider${provider.name}" value="${provider.name}" class="provider" checked="">
2074 <input id="Provider${provider.name}" type="checkbox" name="Provider${provider.name}" value="${provider.name}" class="provider" ${'checked="checked"' ? !provider.auth || api_key : ''}/>
2074 2075 <label for="Provider${provider.name}" class="toogle" title="Remove provider from dropdown"></label>
2075 2076 `;
2076 2077 option.querySelector("input").addEventListener("change", (event) => load_provider_option(event.target, provider.name));
@@ -2102,7 +2103,7 @@ async function on_api() {
2102 2103 `;
2103 2104 settings.querySelector(".paper").appendChild(providersListContainer);
2104 2105
2105 for (let [name, [label, login_url, childs]] of Object.entries(login_urls)) {
2106 for (let [name, [label, login_url, childs, auth]] of Object.entries(login_urls)) {
2106 2107 if (!login_url && !is_demo) {
2107 2108 continue;
2108 2109 }
@@ -2113,6 +2114,13 @@ async function on_api() {
2113 2114 <label for="${name}-api_key" class="label" title="">${label}:</label>
2114 2115 <input type="text" id="${name}-api_key" name="${name}[api_key]" class="${childs}" placeholder="api_key" autocomplete="off"/>
2115 2116 ` + (login_url ? `<a href="${login_url}" target="_blank" title="Login to ${label}">Get API key</a>` : "");
2117 if (auth) {
2118 providerBox.querySelector("input").addEventListener("input", (event) => {
2119 const input = document.getElementById(`Provider${name}`);
2120 input.checked = !!event.target.value;
2121 load_provider_option(input, name);
2122 });
2123 }
2116 2124 providersListContainer.querySelector(".collapsible-content").appendChild(providerBox);
2117 2125 }
2118 2126
Modified g4f/gui/server/api.py +2 -2
@@ -143,7 +143,7 @@ class Api:
143 143 def decorated_log(text: str, file = None):
144 144 debug.logs.append(text)
145 145 if debug.logging:
146 debug.log_handler(text, file)
146 debug.log_handler(text, file=file)
147 147 debug.log = decorated_log
148 148 proxy = os.environ.get("G4F_PROXY")
149 149 provider = kwargs.get("provider")
@@ -187,7 +187,7 @@ class Api:
187 187 yield self._format_json("conversation_id", conversation_id)
188 188 elif isinstance(chunk, Exception):
189 189 logger.exception(chunk)
190 debug.error(e)
190 debug.error(chunk)
191 191 yield self._format_json('message', get_error_message(chunk), error=type(chunk).__name__)
192 192 elif isinstance(chunk, PreviewResponse):
193 193 yield self._format_json("preview", chunk.to_string())
Modified g4f/image/copy_images.py +1 -1
Modified g4f/providers/retry_provider.py +1 -1