返回提交历史
Modified
g4f/Provider/PollinationsAI.py
+2
-1
Added
g4f/Provider/hf_space/G4F.py
+74
-0
Modified
g4f/Provider/hf_space/Janus_Pro_7B.py
+62
-34
Modified
g4f/Provider/hf_space/__init__.py
+3
-1
Modified
g4f/Provider/template/BackendApi.py
+8
-1
Modified
g4f/Provider/template/OpenaiTemplate.py
+0
-1
Modified
g4f/gui/client/static/js/chat.v1.js
+1
-0
Modified
g4f/models.py
+4
-3
Added
projects/deepseek4free/setup.sh
+31
-0
XFEstudio/gpt4free
Add mew G4F provider
03d0c305
代码差异
9 个文件
+185
-41
@@ -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
@@ -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)
@@ -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""token":"([^&]+?)"", 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
@@ -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
@@ -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():
@@ -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
@@ -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();
@@ -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
@@ -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