返回提交历史
Modified
g4f/Provider/Nexra.py
+100
-30
Modified
g4f/Provider/__init__.py
+1
-1
Modified
g4f/models.py
+27
-0
XFEstudio/gpt4free
feat(Nexra): add image generation support
35b96f32
代码差异
3 个文件
+128
-31
@@ -1,16 +1,19 @@
1
1
from __future__ import annotations
2
2
3
3
import json
4
import base64
4
5
from aiohttp import ClientSession
6
from typing import AsyncGenerator
5
7
6
8
from ..typing import AsyncResult, Messages
7
9
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
10
from ..image import ImageResponse
8
11
from .helper import format_prompt
9
12
10
11
13
class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
12
14
url = "https://nexra.aryahcr.cc"
13
api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt"
15
api_endpoint_text = "https://nexra.aryahcr.cc/api/chat/gpt"
16
api_endpoint_image = "https://nexra.aryahcr.cc/api/image/complements"
14
17
working = True
15
18
supports_gpt_35_turbo = True
16
19
supports_gpt_4 = True
@@ -20,34 +23,19 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
20
23
21
24
default_model = 'gpt-3.5-turbo'
22
25
models = [
23
# Working with text
24
'gpt-4',
25
'gpt-4-0613',
26
'gpt-4-32k',
27
'gpt-4-0314',
28
'gpt-4-32k-0314',
29
30
'gpt-3.5-turbo',
31
'gpt-3.5-turbo-16k',
32
'gpt-3.5-turbo-0613',
33
'gpt-3.5-turbo-16k-0613',
34
'gpt-3.5-turbo-0301',
35
36
'gpt-3',
37
'text-davinci-003',
38
'text-davinci-002',
39
'code-davinci-002',
40
'text-curie-001',
41
'text-babbage-001',
42
'text-ada-001',
43
'davinci',
44
'curie',
45
'babbage',
46
'ada',
47
'babbage-002',
48
'davinci-002',
26
# Text models
27
'gpt-4', 'gpt-4-0613', 'gpt-4-32k', 'gpt-4-0314', 'gpt-4-32k-0314',
28
'gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301',
29
'gpt-3', 'text-davinci-003', 'text-davinci-002', 'code-davinci-002',
30
'text-curie-001', 'text-babbage-001', 'text-ada-001',
31
'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002',
32
# Image models
33
'dalle', 'dalle-mini', 'emi'
49
34
]
50
35
36
image_models = {"dalle", "dalle-mini", "emi"}
37
text_models = set(models) - image_models
38
51
39
model_aliases = {
52
40
"gpt-4": "gpt-4-0613",
53
41
"gpt-4": "gpt-4-32k",
@@ -90,9 +78,24 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
90
78
messages: Messages,
91
79
proxy: str = None,
92
80
**kwargs
93
) -> AsyncResult:
81
) -> AsyncGenerator[str | ImageResponse, None]:
94
82
model = cls.get_model(model)
95
83
84
if model in cls.image_models:
85
async for result in cls.create_image_async_generator(model, messages, proxy, **kwargs):
86
yield result
87
else:
88
async for result in cls.create_text_async_generator(model, messages, proxy, **kwargs):
89
yield result
90
91
@classmethod
92
async def create_text_async_generator(
93
cls,
94
model: str,
95
messages: Messages,
96
proxy: str = None,
97
**kwargs
98
) -> AsyncGenerator[str, None]:
96
99
headers = {
97
100
"Content-Type": "application/json",
98
101
}
@@ -104,8 +107,75 @@ class Nexra(AsyncGeneratorProvider, ProviderModelMixin):
104
107
"markdown": False,
105
108
"stream": False,
106
109
}
107
async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
110
async with session.post(cls.api_endpoint_text, json=data, proxy=proxy) as response:
108
111
response.raise_for_status()
109
112
result = await response.text()
110
113
json_result = json.loads(result)
111
114
yield json_result["gpt"]
115
116
@classmethod
117
async def create_image_async_generator(
118
cls,
119
model: str,
120
messages: Messages,
121
proxy: str = None,
122
**kwargs
123
) -> AsyncGenerator[ImageResponse | str, None]:
124
headers = {
125
"Content-Type": "application/json"
126
}
127
128
prompt = messages[-1]['content'] if messages else ""
129
130
data = {
131
"prompt": prompt,
132
"model": model
133
}
134
135
async def process_response(response_text: str) -> ImageResponse | None:
136
json_start = response_text.find('{')
137
if json_start != -1:
138
json_data = response_text[json_start:]
139
try:
140
response_data = json.loads(json_data)
141
image_data = response_data.get('images', [])[0]
142
143
if image_data.startswith('data:image/'):
144
return ImageResponse([image_data], "Generated image")
145
146
try:
147
base64.b64decode(image_data)
148
data_uri = f"data:image/jpeg;base64,{image_data}"
149
return ImageResponse([data_uri], "Generated image")
150
except:
151
print("Invalid base64 data")
152
return None
153
except json.JSONDecodeError:
154
print("Failed to parse JSON.")
155
else:
156
print("No JSON data found in the response.")
157
return None
158
159
async with ClientSession(headers=headers) as session:
160
async with session.post(cls.api_endpoint_image, json=data, proxy=proxy) as response:
161
response.raise_for_status()
162
response_text = await response.text()
163
164
image_response = await process_response(response_text)
165
if image_response:
166
yield image_response
167
else:
168
yield "Failed to process image data."
169
170
@classmethod
171
async def create_async(
172
cls,
173
model: str,
174
messages: Messages,
175
proxy: str = None,
176
**kwargs
177
) -> str:
178
async for response in cls.create_async_generator(model, messages, proxy, **kwargs):
179
if isinstance(response, ImageResponse):
180
return response.images[0]
181
return response
@@ -12,7 +12,7 @@ from .needs_auth import *
12
12
from .AI365VIP import AI365VIP
13
13
from .Allyfy import Allyfy
14
14
from .AiChatOnline import AiChatOnline
15
from .AiChats import AiChats
15
from .AiChats import AiChats
16
16
from .Aura import Aura
17
17
from .Bing import Bing
18
18
from .BingCreateImages import BingCreateImages
@@ -461,6 +461,28 @@ flux_disney = Model(
461
461
462
462
)
463
463
464
### ###
465
dalle = Model(
466
name = 'dalle',
467
base_provider = '',
468
best_provider = IterListProvider([Nexra])
469
470
)
471
472
dalle_mini = Model(
473
name = 'dalle-mini',
474
base_provider = '',
475
best_provider = IterListProvider([Nexra])
476
477
)
478
479
emi = Model(
480
name = 'emi',
481
base_provider = '',
482
best_provider = IterListProvider([Nexra])
483
484
)
485
464
486
class ModelUtils:
465
487
"""
466
488
Utility class for mapping string identifiers to Model instances.
@@ -617,6 +639,11 @@ class ModelUtils:
617
639
'flux-3d': flux_3d,
618
640
'flux-disney': flux_disney,
619
641
642
643
### ###
644
'dalle': dalle,
645
'dalle-mini': dalle_mini,
646
'emi': emi,
620
647
}
621
648
622
649
_all_models = list(ModelUtils.convert.keys())