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

XFEstudio/gpt4free

Remove login url from error message Remove print in CablyAI Fix Vision Support in HuggingSpace provider Support images in BackendApi provider Add missing import in Blackbox provider

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

代码差异

10 个文件 +55 -29
Modified g4f/Provider/Blackbox.py +1 -1
@@ -15,7 +15,7 @@ from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
15 15 from ..image import to_data_uri
16 16 from ..cookies import get_cookies_dir
17 17 from .helper import format_prompt, format_image_prompt
18 from ..providers.response import JsonConversation, ImageResponse
18 from ..providers.response import JsonConversation, ImageResponse, Reasoning
19 19
20 20 class Conversation(JsonConversation):
21 21 validated_value: str = None
Modified g4f/Provider/CablyAI.py +0 -1
@@ -87,7 +87,6 @@ class CablyAI(AsyncGeneratorProvider, ProviderModelMixin):
87 87 continue
88 88
89 89 line = line.decode('utf-8').strip()
90 print(line)
91 90
92 91 if not line.startswith("data: "):
93 92 continue
Modified g4f/Provider/hf/HuggingFaceInference.py +1 -1
@@ -148,7 +148,7 @@ class HuggingFaceInference(AsyncGeneratorProvider, ProviderModelMixin):
148 148 if response.headers["content-type"].startswith("image/"):
149 149 base64_data = base64.b64encode(b"".join([chunk async for chunk in response.iter_content()]))
150 150 url = f"data:{response.headers['content-type']};base64,{base64_data.decode()}"
151 yield ImageResponse(url, prompt)
151 yield ImageResponse(url, inputs)
152 152 else:
153 153 yield (await response.json())[0]["generated_text"].strip()
154 154
Modified g4f/Provider/hf_space/G4F.py +20 -6
@@ -2,14 +2,16 @@ from __future__ import annotations
2 2
3 3 from aiohttp import ClientSession
4 4 import time
5 import asyncio
5 6
6 7 from ...typing import AsyncResult, Messages
7 from ...providers.response import ImageResponse
8 from ...providers.response import ImageResponse, Reasoning
8 9 from ...requests.raise_for_status import raise_for_status
9 10 from ..helper import format_image_prompt, get_random_string
10 11 from .Janus_Pro_7B import Janus_Pro_7B, JsonConversation, get_zerogpu_token
11 12
12 13 class G4F(Janus_Pro_7B):
14 label = "G4F framework"
13 15 space = "roxky/Janus-Pro-7B"
14 16 url = f"https://huggingface.co/spaces/roxky/g4f-space"
15 17 api_url = "https://roxky-janus-pro-7b.hf.space"
@@ -62,13 +64,25 @@ class G4F(Janus_Pro_7B):
62 64 "trigger_id": 10
63 65 }
64 66 async with ClientSession() as session:
67 yield Reasoning(status="Acquiring GPU Token")
65 68 zerogpu_uuid, zerogpu_token = await get_zerogpu_token(cls.space, session, JsonConversation(), cookies)
66 69 headers = {
67 70 "x-zerogpu-token": zerogpu_token,
68 71 "x-zerogpu-uuid": zerogpu_uuid,
69 72 }
70 async with session.post(cls.url_flux, json=payload, proxy=proxy, headers=headers) as response:
71 await raise_for_status(response)
72 response_data = await response.json()
73 image_url = response_data["data"][0]['url']
74 yield ImageResponse(images=[image_url], alt=prompt)
73 async def generate():
74 async with session.post(cls.url_flux, json=payload, proxy=proxy, headers=headers) as response:
75 await raise_for_status(response)
76 response_data = await response.json()
77 image_url = response_data["data"][0]['url']
78 return ImageResponse(images=[image_url], alt=prompt)
79 background_tasks = set()
80 started = time.time()
81 task = asyncio.create_task(generate())
82 background_tasks.add(task)
83 task.add_done_callback(background_tasks.discard)
84 while background_tasks:
85 yield Reasoning(status=f"Generating {time.time() - started:.2f}s")
86 await asyncio.sleep(0.2)
87 yield await task
88 yield Reasoning(status=f"Finished {time.time() - started:.2f}s")
Modified g4f/Provider/hf_space/Janus_Pro_7B.py +2 -3
@@ -82,10 +82,8 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
82 82 method = "post"
83 83 if model == cls.default_image_model or prompt is not None:
84 84 method = "image"
85
86 85 prompt = format_prompt(messages) if prompt is None and conversation is None else prompt
87 86 prompt = format_image_prompt(messages, prompt)
88
89 87 if seed is None:
90 88 seed = int(time.time())
91 89
@@ -139,7 +137,8 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
139 137
140 138 if json_data.get('msg') == 'process_completed':
141 139 if 'output' in json_data and 'error' in json_data['output']:
142 raise ResponseError("Missing image input" if json_data['output']['error'] and "AttributeError" in json_data['output']['error'] else json_data['output']['error'])
140 json_data['output']['error'] = json_data['output']['error'].split(" <a ")[0]
141 raise ResponseError("Missing images input" if json_data['output']['error'] and "AttributeError" in json_data['output']['error'] else json_data['output']['error'])
143 142 if 'output' in json_data and 'data' in json_data['output']:
144 143 yield Reasoning(status="Finished")
145 144 if "image" in json_data['output']['data'][0][0]:
Modified g4f/Provider/hf_space/__init__.py +9 -5
@@ -27,10 +27,14 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
27 27 default_image_model = BlackForestLabsFlux1Dev.default_model
28 28 default_vision_model = Qwen_QVQ_72B.default_model
29 29 providers = [
30 BlackForestLabsFlux1Dev, BlackForestLabsFlux1Schnell,
30 BlackForestLabsFlux1Dev,
31 BlackForestLabsFlux1Schnell,
31 32 VoodoohopFlux1Schnell,
32 CohereForAI, Janus_Pro_7B,
33 Qwen_QVQ_72B, Qwen_Qwen_2_5M_Demo, Qwen_Qwen_2_72B_Instruct,
33 CohereForAI,
34 Janus_Pro_7B,
35 Qwen_QVQ_72B,
36 Qwen_Qwen_2_5M_Demo,
37 Qwen_Qwen_2_72B_Instruct,
34 38 StableDiffusion35Large,
35 39 G4F
36 40 ]
@@ -70,7 +74,7 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
70 74 random.shuffle(cls.providers)
71 75 for provider in cls.providers:
72 76 if model in provider.model_aliases:
73 async for chunk in provider.create_async_generator(provider.model_aliases[model], messages, **kwargs):
77 async for chunk in provider.create_async_generator(provider.model_aliases[model], messages, images=images, **kwargs):
74 78 is_started = True
75 79 yield chunk
76 80 if is_started:
@@ -79,7 +83,7 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
79 83 for provider in cls.providers:
80 84 if model in provider.get_models():
81 85 try:
82 async for chunk in provider.create_async_generator(model, messages, **kwargs):
86 async for chunk in provider.create_async_generator(model, messages, images=images, **kwargs):
83 87 is_started = True
84 88 yield chunk
85 89 if is_started:
Modified g4f/gui/client/index.html +7 -2
@@ -68,12 +68,17 @@
68 68 const currSlideElement = lightbox.pswp.currSlide.data.element;
69 69 if (currSlideElement) {
70 70 const img = currSlideElement.querySelector('img');
71 el.innerText = img.getAttribute('alt');
72 71 const download = document.createElement("a");
73 72 download.setAttribute("href", img.getAttribute('src'));
74 download.setAttribute("download", `${img.getAttribute('alt')}${lightbox.pswp.currSlide.index}.jpg`);
73 let extension = img.getAttribute('src').includes(".webp") ? ".webp" : ".jpg";
74 download.setAttribute("download", `${img.getAttribute('alt')} ${lightbox.pswp.currSlide.index}${extension}`);
75 download.style.float = "right";
75 76 download.innerHTML = '<i class="fa-solid fa-download"></i>';
77 let span = document.createElement("span");
78 span.innerText = img.getAttribute('alt');
79 el.innerHTML = '';
76 80 el.appendChild(download);
81 el.appendChild(span);
77 82 }
78 83 });
79 84 }
Modified g4f/gui/client/static/css/style.css +4 -0
@@ -1165,6 +1165,10 @@ ul {
1165 1165 .settings h3 {
1166 1166 text-align: center;
1167 1167 }
1168
1169 .field.collapsible {
1170 flex-direction: column;
1171 }
1168 1172 }
1169 1173
1170 1174 .shown {
Modified g4f/gui/client/static/js/chat.v1.js +4 -6
@@ -1023,14 +1023,11 @@ const ask_gpt = async (message_id, message_index = -1, regenerate = false, provi
1023 1023 let api_key;
1024 1024 if (is_demo && provider == "Feature") {
1025 1025 api_key = localStorage.getItem("user");
1026 } else if (is_demo && provider != "Custom") {
1026 } else if (is_demo) {
1027 1027 api_key = localStorage.getItem("HuggingFace-api_key");
1028 1028 } else {
1029 1029 api_key = get_api_key_by_provider(provider);
1030 1030 }
1031 if (is_demo && !api_key) {
1032 api_key = localStorage.getItem("HuggingFace-api_key");
1033 }
1034 1031 if (is_demo && !api_key) {
1035 1032 location.href = "/";
1036 1033 return;
@@ -2005,7 +2002,9 @@ async function on_api() {
2005 2002 providerSelect.innerHTML = `
2006 2003 <option value="">Demo Mode</option>
2007 2004 <option value="Feature">Feature Provider</option>
2008 <option value="Custom">Custom Provider</option>`;
2005 <option value="G4F">G4F framework</option>
2006 <option value="HuggingFace">HuggingFace</option>
2007 <option value="HuggingSpace">HuggingSpace</option>`;
2009 2008 providerSelect.selectedIndex = 0;
2010 2009 document.getElementById("pin").disabled = true;
2011 2010 document.getElementById("refine")?.parentElement.classList.add("hidden")
@@ -2018,7 +2017,6 @@ async function on_api() {
2018 2017 }
2019 2018 });
2020 2019 login_urls = {
2021 "Custom": ["Custom Provider", "", []],
2022 2020 "HuggingFace": ["HuggingFace", "", []],
2023 2021 };
2024 2022 } else {
Modified g4f/gui/server/backend_api.py +7 -4
@@ -116,7 +116,7 @@ class Backend_Api(Api):
116 116 }
117 117 for model, providers in models.demo_models.values()]
118 118
119 def handle_conversation():
119 def handle_conversation(limiter_check: callable = None):
120 120 """
121 121 Handles conversation requests and streams responses back.
122 122
@@ -135,7 +135,7 @@ class Backend_Api(Api):
135 135 else:
136 136 json_data = request.json
137 137
138 if app.demo and json_data.get("provider") not in ["Custom", "Feature"]:
138 if app.demo and json_data.get("provider") not in ["Custom", "Feature", "HuggingFace", "HuggingSpace", "G4F"]:
139 139 model = json_data.get("model")
140 140 if model != "default" and model in models.demo_models:
141 141 json_data["provider"] = random.choice(models.demo_models[model][1])
@@ -143,6 +143,10 @@ class Backend_Api(Api):
143 143 if not model or model == "default":
144 144 json_data["model"] = models.demo_models["default"][0].name
145 145 json_data["provider"] = random.choice(models.demo_models["default"][1])
146 if limiter_check is not None and json_data.get("provider") in ["Feature"]:
147 limiter_check()
148 if "images" in json_data:
149 kwargs["images"] = json_data["images"]
146 150 kwargs = self._prepare_conversation_kwargs(json_data, kwargs)
147 151 return self.app.response_class(
148 152 self._create_response_stream(
@@ -158,8 +162,7 @@ class Backend_Api(Api):
158 162 @app.route('/backend-api/v2/conversation', methods=['POST'])
159 163 @limiter.limit("2 per minute")
160 164 def _handle_conversation():
161 limiter.check()
162 return handle_conversation()
165 return handle_conversation(limiter.check)
163 166 else:
164 167 @app.route('/backend-api/v2/conversation', methods=['POST'])
165 168 def _handle_conversation():