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

XFEstudio/gpt4free

feat(Nexra): add image generation support

35b96f32
kqlio67 <kqlio67@users.noreply.github.com>
提交于

代码差异

3 个文件 +128 -31
Modified g4f/Provider/Nexra.py +100 -30
@@ -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
Modified g4f/Provider/__init__.py +1 -1
@@ -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
Modified g4f/models.py +27 -0
@@ -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())