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

XFEstudio/gpt4free

Add mew G4F provider

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

代码差异

9 个文件 +185 -41
Modified g4f/Provider/PollinationsAI.py +2 -1
@@ -75,7 +75,8 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
75 75
76 76 ### Image Models ###
77 77 "sdxl-turbo": "turbo",
78 "flux-schnell": "flux",
78 "flux-schnell": "flux",
79 "flux-dev": "flux",
79 80 }
80 81 text_models = []
81 82
Added g4f/Provider/hf_space/G4F.py +74 -0
@@ -0,0 +1,74 @@
1 from __future__ import annotations
2
3 from aiohttp import ClientSession
4 import time
5
6 from ...typing import AsyncResult, Messages
7 from ...providers.response import ImageResponse
8 from ...requests.raise_for_status import raise_for_status
9 from ..helper import format_image_prompt, get_random_string
10 from .Janus_Pro_7B import Janus_Pro_7B, JsonConversation, get_zerogpu_token
11
12 class G4F(Janus_Pro_7B):
13 space = "roxky/Janus-Pro-7B"
14 url = f"https://huggingface.co/spaces/roxky/g4f-space"
15 api_url = "https://roxky-janus-pro-7b.hf.space"
16 url_flux = "https://roxky-g4f-flux.hf.space/run/predict"
17 referer = f"{api_url}?__theme=light"
18
19 default_model = "flux"
20 model_aliases = {"flux-schnell": default_model, "flux-dev": default_model}
21 image_models = [Janus_Pro_7B.default_image_model, default_model, *model_aliases.keys()]
22 models = [Janus_Pro_7B.default_model, *image_models]
23
24 @classmethod
25 async def create_async_generator(
26 cls,
27 model: str,
28 messages: Messages,
29 proxy: str = None,
30 prompt: str = None,
31 width: int = 1024,
32 height: int = 1024,
33 seed: int = None,
34 cookies: dict = None,
35 **kwargs
36 ) -> AsyncResult:
37 if cls.default_model not in model:
38 async for chunk in super().create_async_generator(model, messages, prompt=prompt, seed=seed, cookies=cookies, **kwargs):
39 yield chunk
40 return
41
42 model = cls.get_model(model)
43 width = max(32, width - (width % 8))
44 height = max(32, height - (height % 8))
45 if prompt is None:
46 prompt = format_image_prompt(messages)
47 if seed is None:
48 seed = int(time.time())
49
50 payload = {
51 "data": [
52 prompt,
53 seed,
54 width,
55 height,
56 True,
57 1
58 ],
59 "event_data": None,
60 "fn_index": 3,
61 "session_hash": get_random_string(),
62 "trigger_id": 10
63 }
64 async with ClientSession() as session:
65 zerogpu_uuid, zerogpu_token = await get_zerogpu_token(cls.space, session, JsonConversation(), cookies)
66 headers = {
67 "x-zerogpu-token": zerogpu_token,
68 "x-zerogpu-uuid": zerogpu_uuid,
69 }
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)
Modified g4f/Provider/hf_space/Janus_Pro_7B.py +62 -34
@@ -3,21 +3,24 @@ from __future__ import annotations
3 3 import json
4 4 import uuid
5 5 import re
6 import time
6 7 from datetime import datetime, timezone, timedelta
7 8 import urllib.parse
8 9
9 from ...typing import AsyncResult, Messages, Cookies
10 from ...typing import AsyncResult, Messages, Cookies, ImagesType
10 11 from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
11 12 from ..helper import format_prompt, format_image_prompt
12 from ...providers.response import JsonConversation, ImageResponse, DebugResponse
13 from ...requests.aiohttp import StreamSession, StreamResponse
13 from ...providers.response import JsonConversation, ImageResponse, Reasoning
14 from ...requests.aiohttp import StreamSession, StreamResponse, FormData
14 15 from ...requests.raise_for_status import raise_for_status
16 from ...image import to_bytes, is_accepted_format
15 17 from ...cookies import get_cookies
16 18 from ...errors import ResponseError
17 19 from ... import debug
18 20
19 21 class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
20 url = "https://huggingface.co/spaces/deepseek-ai/Janus-Pro-7B"
22 space = "deepseek-ai/Janus-Pro-7B"
23 url = f"https://huggingface.co/spaces/{space}"
21 24 api_url = "https://deepseek-ai-janus-pro-7b.hf.space"
22 25 referer = f"{api_url}?__theme=light"
23 26
@@ -28,30 +31,27 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
28 31
29 32 default_model = "janus-pro-7b"
30 33 default_image_model = "janus-pro-7b-image"
34 default_vision_model = default_model
31 35 models = [default_model, default_image_model]
32 36 image_models = [default_image_model]
33 37
34 38 @classmethod
35 def run(cls, method: str, session: StreamSession, prompt: str, conversation: JsonConversation):
39 def run(cls, method: str, session: StreamSession, prompt: str, conversation: JsonConversation, image: dict = None, seed: int = 0):
40 headers = {
41 "content-type": "application/json",
42 "x-zerogpu-token": conversation.zerogpu_token,
43 "x-zerogpu-uuid": conversation.zerogpu_uuid,
44 "referer": cls.referer,
45 }
36 46 if method == "post":
37 47 return session.post(f"{cls.api_url}/gradio_api/queue/join?__theme=light", **{
38 "headers": {
39 "content-type": "application/json",
40 "x-zerogpu-token": conversation.zerogpu_token,
41 "x-zerogpu-uuid": conversation.zerogpu_uuid,
42 "referer": cls.referer,
43 },
44 "json": {"data":[None,prompt,42,0.95,0.1],"event_data":None,"fn_index":2,"trigger_id":10,"session_hash":conversation.session_hash},
48 "headers": {k: v for k, v in headers.items() if v is not None},
49 "json": {"data":[image,prompt,seed,0.95,0.1],"event_data":None,"fn_index":2,"trigger_id":10,"session_hash":conversation.session_hash},
45 50 })
46 51 elif method == "image":
47 52 return session.post(f"{cls.api_url}/gradio_api/queue/join?__theme=light", **{
48 "headers": {
49 "content-type": "application/json",
50 "x-zerogpu-token": conversation.zerogpu_token,
51 "x-zerogpu-uuid": conversation.zerogpu_uuid,
52 "referer": cls.referer,
53 },
54 "json": {"data":[prompt,1234,5,1],"event_data":None,"fn_index":3,"trigger_id":20,"session_hash":conversation.session_hash},
53 "headers": {k: v for k, v in headers.items() if v is not None},
54 "json": {"data":[prompt,seed,5,1],"event_data":None,"fn_index":3,"trigger_id":20,"session_hash":conversation.session_hash},
55 55 })
56 56 return session.get(f"{cls.api_url}/gradio_api/queue/data?session_hash={conversation.session_hash}", **{
57 57 "headers": {
@@ -66,11 +66,13 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
66 66 cls,
67 67 model: str,
68 68 messages: Messages,
69 images: ImagesType = None,
69 70 prompt: str = None,
70 71 proxy: str = None,
71 72 cookies: Cookies = None,
72 73 return_conversation: bool = False,
73 74 conversation: JsonConversation = None,
75 seed: int = None,
74 76 **kwargs
75 77 ) -> AsyncResult:
76 78 def generate_session_hash():
@@ -84,20 +86,43 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
84 86 prompt = format_prompt(messages) if prompt is None and conversation is None else prompt
85 87 prompt = format_image_prompt(messages, prompt)
86 88
89 if seed is None:
90 seed = int(time.time())
91
87 92 session_hash = generate_session_hash() if conversation is None else getattr(conversation, "session_hash")
88 93 async with StreamSession(proxy=proxy, impersonate="chrome") as session:
89 94 session_hash = generate_session_hash() if conversation is None else getattr(conversation, "session_hash")
90 zerogpu_uuid, zerogpu_token = await get_zerogpu_token(session, conversation, cookies)
95 zerogpu_uuid, zerogpu_token = await get_zerogpu_token(cls.space, session, conversation, cookies)
91 96 if conversation is None or not hasattr(conversation, "session_hash"):
92 97 conversation = JsonConversation(session_hash=session_hash, zerogpu_token=zerogpu_token, zerogpu_uuid=zerogpu_uuid)
93 98 conversation.zerogpu_token = zerogpu_token
94 99 if return_conversation:
95 100 yield conversation
96 101
97 async with cls.run(method, session, prompt, conversation) as response:
102 if images is not None:
103 data = FormData()
104 for i in range(len(images)):
105 images[i] = (to_bytes(images[i][0]), images[i][1])
106 for image, image_name in images:
107 data.add_field(f"files", image, filename=image_name)
108 async with session.post(f"{cls.api_url}/gradio_api/upload", params={"upload_id": session_hash}, data=data) as response:
109 await raise_for_status(response)
110 image_files = await response.json()
111 images = [{
112 "path": image_file,
113 "url": f"{cls.api_url}/gradio_api/file={image_file}",
114 "orig_name": images[i][1],
115 "size": len(images[i][0]),
116 "mime_type": is_accepted_format(images[i][0]),
117 "meta": {
118 "_type": "gradio.FileData"
119 }
120 } for i, image_file in enumerate(image_files)]
121
122 async with cls.run(method, session, prompt, conversation, None if images is None else images.pop(), seed) as response:
98 123 await raise_for_status(response)
99 124
100 async with cls.run("get", session, prompt, conversation) as response:
125 async with cls.run("get", session, prompt, conversation, None, seed) as response:
101 126 response: StreamResponse = response
102 127 async for line in response.iter_lines():
103 128 decoded_line = line.decode(errors="replace")
@@ -105,32 +130,34 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin):
105 130 try:
106 131 json_data = json.loads(decoded_line[6:])
107 132 if json_data.get('msg') == 'log':
108 yield DebugResponse(log=json_data["log"])
133 yield Reasoning(status=json_data["log"])
109 134
110 if json_data.get('msg') == 'process_generating':
111 if 'output' in json_data and 'data' in json_data['output']:
112 yield f"data: {json.dumps(json_data['output']['data'])}"
135 if json_data.get('msg') == 'progress':
136 if 'progress_data' in json_data and json_data['progress_data']:
137 progress = json_data['progress_data'][0]
138 yield Reasoning(status=f"{progress['desc']} {progress['index']}/{progress['length']}")
113 139
114 140 if json_data.get('msg') == 'process_completed':
115 141 if 'output' in json_data and 'error' in json_data['output']:
116 raise ResponseError("Text model is not working. Try out image model" if "AttributeError" in json_data['output']['error'] else json_data['output']['error'])
142 raise ResponseError("Missing image input" if json_data['output']['error'] and "AttributeError" in json_data['output']['error'] else json_data['output']['error'])
117 143 if 'output' in json_data and 'data' in json_data['output']:
144 yield Reasoning(status="Finished")
118 145 if "image" in json_data['output']['data'][0][0]:
119 146 yield ImageResponse([image["image"]["url"] for image in json_data['output']['data'][0]], prompt)
120 147 else:
121 yield f"data: {json.dumps(json_data['output']['data'])}"
148 yield json_data['output']['data'][0]
122 149 break
123 150
124 151 except json.JSONDecodeError:
125 152 debug.log("Could not parse JSON:", decoded_line)
126 153
127 async def get_zerogpu_token(session: StreamSession, conversation: JsonConversation, cookies: Cookies = None):
154 async def get_zerogpu_token(space: str, session: StreamSession, conversation: JsonConversation, cookies: Cookies = None):
128 155 zerogpu_uuid = None if conversation is None else getattr(conversation, "zerogpu_uuid", None)
129 156 zerogpu_token = "[object Object]"
130 157
131 158 cookies = get_cookies("huggingface.co", raise_requirements_error=False) if cookies is None else cookies
132 159 if zerogpu_uuid is None:
133 async with session.get(Janus_Pro_7B.url, cookies=cookies) as response:
160 async with session.get(f"https://huggingface.co/spaces/{space}", cookies=cookies) as response:
134 161 match = re.search(r"&quot;token&quot;:&quot;([^&]+?)&quot;", await response.text())
135 162 if match:
136 163 zerogpu_token = match.group(1)
@@ -141,8 +168,9 @@ async def get_zerogpu_token(session: StreamSession, conversation: JsonConversati
141 168 # Get current UTC time + 10 minutes
142 169 dt = (datetime.now(timezone.utc) + timedelta(minutes=10)).isoformat(timespec='milliseconds')
143 170 encoded_dt = urllib.parse.quote(dt)
144 async with session.get(f"https://huggingface.co/api/spaces/deepseek-ai/Janus-Pro-7B/jwt?expiration={encoded_dt}&include_pro_status=true", cookies=cookies) as response:
145 zerogpu_token = (await response.json())
146 zerogpu_token = zerogpu_token["token"]
147
171 async with session.get(f"https://huggingface.co/api/spaces/{space}/jwt?expiration={encoded_dt}&include_pro_status=true", cookies=cookies) as response:
172 response_data = (await response.json())
173 if "token" in response_data:
174 zerogpu_token = response_data["token"]
175
148 176 return zerogpu_uuid, zerogpu_token
Modified g4f/Provider/hf_space/__init__.py +3 -1
@@ -15,6 +15,7 @@ from .Qwen_QVQ_72B import Qwen_QVQ_72B
15 15 from .Qwen_Qwen_2_5M_Demo import Qwen_Qwen_2_5M_Demo
16 16 from .Qwen_Qwen_2_72B_Instruct import Qwen_Qwen_2_72B_Instruct
17 17 from .StableDiffusion35Large import StableDiffusion35Large
18 from .G4F import G4F
18 19
19 20 class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
20 21 url = "https://huggingface.co/spaces"
@@ -30,7 +31,8 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
30 31 VoodoohopFlux1Schnell,
31 32 CohereForAI, Janus_Pro_7B,
32 33 Qwen_QVQ_72B, Qwen_Qwen_2_5M_Demo, Qwen_Qwen_2_72B_Instruct,
33 StableDiffusion35Large
34 StableDiffusion35Large,
35 G4F
34 36 ]
35 37
36 38 @classmethod
Modified g4f/Provider/template/BackendApi.py +8 -1
@@ -2,8 +2,9 @@ from __future__ import annotations
2 2
3 3 import json
4 4
5 from ...typing import Messages, AsyncResult
5 from ...typing import Messages, AsyncResult, ImagesType
6 6 from ...requests import StreamSession
7 from ...image import to_data_uri
7 8 from ...providers.base_provider import AsyncGeneratorProvider, ProviderModelMixin
8 9 from ...providers.response import RawResponse
9 10 from ... import debug
@@ -17,16 +18,22 @@ class BackendApi(AsyncGeneratorProvider, ProviderModelMixin):
17 18 cls,
18 19 model: str,
19 20 messages: Messages,
21 images: ImagesType = None,
20 22 api_key: str = None,
21 23 **kwargs
22 24 ) -> AsyncResult:
23 25 debug.log(f"{cls.__name__}: {api_key}")
26 if images is not None:
27 for i in range(len(images)):
28 images[i] = (to_data_uri(images[i][0]), images[i][1])
24 29 async with StreamSession(
25 30 headers={"Accept": "text/event-stream", **cls.headers},
26 31 ) as session:
27 32 async with session.post(f"{cls.url}/backend-api/v2/conversation", json={
28 33 "model": model,
29 34 "messages": messages,
35 "images": images,
36 "api_key": api_key,
30 37 **kwargs
31 38 }, ssl=cls.ssl) as response:
32 39 async for line in response.iter_lines():
Modified g4f/Provider/template/OpenaiTemplate.py +0 -1
@@ -1,7 +1,6 @@
1 1 from __future__ import annotations
2 2
3 3 import json
4 import time
5 4 import requests
6 5
7 6 from ..helper import filter_none, format_image_prompt
Modified g4f/gui/client/static/js/chat.v1.js +1 -0
@@ -2425,6 +2425,7 @@ async function api(ressource, args=null, files=null, message_id=null, scroll=tru
2425 2425 const message = body.match(/<p>([^<]+?)<\/p>/)[1];
2426 2426 error_storage[message_id] = `**${title}**\n${message}`;
2427 2427 await finish_message();
2428 return;
2428 2429 } else {
2429 2430 await read_response(response, message_id, args.provider || null, scroll, finish_message);
2430 2431 await finish_message();
Modified g4f/models.py +4 -3
@@ -741,10 +741,11 @@ class ModelUtils:
741 741
742 742 demo_models = {
743 743 gpt_4o.name: [gpt_4o, [PollinationsAI, Blackbox]],
744 gpt_4o_mini.name: [gpt_4o_mini, [PollinationsAI, CablyAI, DDG]],
745 deepseek_r1.name: [deepseek_r1, [PollinationsAI, HuggingFace]],
744 746 "default": [llama_3_2_11b, [HuggingFace]],
745 747 qwen_2_vl_7b.name: [qwen_2_vl_7b, [HuggingFaceAPI]],
746 748 qvq_72b.name: [qvq_72b, [HuggingSpace]],
747 deepseek_r1.name: [deepseek_r1, [HuggingFace]],
748 749 command_r.name: [command_r, [HuggingSpace]],
749 750 command_r_plus.name: [command_r_plus, [HuggingSpace]],
750 751 command_r7b.name: [command_r7b, [HuggingSpace]],
@@ -753,8 +754,8 @@ demo_models = {
753 754 qwq_32b.name: [qwq_32b, [HuggingFace]],
754 755 llama_3_3_70b.name: [llama_3_3_70b, [HuggingFace]],
755 756 sd_3_5.name: [sd_3_5, [HuggingSpace, HuggingFace]],
756 flux_dev.name: [flux_dev, [HuggingSpace, HuggingFace]],
757 flux_schnell.name: [flux_schnell, [HuggingFace, HuggingSpace, PollinationsAI]],
757 flux_dev.name: [flux_dev, [PollinationsAI, HuggingSpace, HuggingFace]],
758 flux_schnell.name: [flux_schnell, [PollinationsAI, HuggingFace, HuggingSpace, PollinationsAI]],
758 759 }
759 760
760 761 # Create a list of all models and his providers
Added projects/deepseek4free/setup.sh +31 -0
@@ -0,0 +1,31 @@
1 git clone https://github.com/xtekky/deepseek4free.git
2
3 echo "recursive-include dsk/wasm *" >> ./deepseek4free/MANIFEST.in
4
5 echo "from setuptools import find_packages, setup
6
7 INSTALL_REQUIRE = [
8 'curl-cffi',
9 'wasmtime',
10 'numpy',
11 ]
12
13 DESCRIPTION = (
14 'The official deepseek4free repository | various collection of powerful language models'
15 )
16
17 # Setting up
18 setup(
19 name='dsk',
20 version='0.0.1.0',
21 author='Tekky',
22 author_email='<support@g4f.ai>',
23 description=DESCRIPTION,
24 long_description_content_type='text/markdown',
25 long_description='',
26 packages=find_packages(),
27 include_package_data=True,
28 install_requires=INSTALL_REQUIRE
29 )" >> ./deepseek4free/setup.py
30
31 pip install ./deepseek4free --break-system-packages