返回提交历史
Modified
g4f/Provider/Blackbox.py
+1
-0
Modified
g4f/Provider/Cloudflare.py
+6
-3
Modified
g4f/Provider/Copilot.py
+2
-11
Modified
g4f/Provider/PollinationsAI.py
+2
-2
Modified
g4f/Provider/needs_auth/Gemini.py
+4
-1
Modified
g4f/Provider/needs_auth/GithubCopilot.py
+18
-7
Modified
g4f/Provider/needs_auth/OpenaiChat.py
+8
-6
Modified
g4f/__init__.py
+14
-1
Modified
g4f/api/__init__.py
+16
-75
Added
g4f/api/stubs.py
+63
-0
Modified
g4f/client/__init__.py
+10
-8
Modified
g4f/cookies.py
+1
-0
Modified
g4f/gui/client/index.html
+7
-0
Modified
g4f/gui/client/static/css/style.css
+39
-66
Modified
g4f/gui/client/static/js/chat.v1.js
+15
-1
Modified
g4f/gui/server/api.py
+3
-2
Modified
g4f/models.py
+4
-3
Modified
g4f/providers/helper.py
+15
-0
Modified
g4f/providers/retry_provider.py
+4
-2
Modified
g4f/requests/raise_for_status.py
+22
-11
XFEstudio/gpt4free
Improve gradient in gui, show only models with enabled providers (#2492)
- **Cloudflare Provider**: Added error handling for missing requirements when fetching arguments. - **Copilot Provider**: Updated the prompt formatting to use a maximum length function, improving message handling. - **PollinationsAI Provider**: Adjusted the prompt length to a maximum of 5000 characters. - **GitHub Copilot Provider**: Updated to use `ClientSession` for better session management. - **CSS Updates**: Enhanced the gradient styling in the GUI for a more visually appealing interface. - **JavaScript Updates**: Added functionality to toggle search options in the chat interface.
bbb85824
代码差异
20 个文件
+254
-199
@@ -287,6 +287,7 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
287
287
return
288
288
289
289
response_text = re.sub(r'Generated by BLACKBOX.AI, try unlimited chat https://www.blackbox.ai', '', response_text, flags=re.DOTALL)
290
response_text = re.sub(r'and for API requests replace https://www.blackbox.ai with https://api.blackbox.ai', '', response_text, flags=re.DOTALL)
290
291
291
292
json_match = re.search(r'\$~~~\$(.*?)\$~~~\$', response_text, re.DOTALL)
292
293
if json_match:
@@ -5,8 +5,8 @@ import json
5
5
6
6
from ..typing import AsyncResult, Messages, Cookies
7
7
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin, get_running_loop
8
from ..requests import Session, StreamSession, get_args_from_nodriver, raise_for_status, merge_cookies
9
from ..errors import ResponseStatusError
8
from ..requests import Session, StreamSession, get_args_from_nodriver, raise_for_status, merge_cookies, DEFAULT_HEADERS
9
from ..errors import ResponseStatusError, MissingRequirementsError
10
10
11
11
class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
12
12
label = "Cloudflare AI"
@@ -62,7 +62,10 @@ class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
62
62
**kwargs
63
63
) -> AsyncResult:
64
64
if cls._args is None:
65
cls._args = await get_args_from_nodriver(cls.url, proxy, timeout, cookies)
65
try:
66
cls._args = await get_args_from_nodriver(cls.url, proxy, timeout, cookies)
67
except MissingRequirementsError:
68
cls._args = {"headers": DEFAULT_HEADERS, cookies: {}}
66
69
model = cls.get_model(model)
67
70
data = {
68
71
"messages": messages,
@@ -18,7 +18,7 @@ except ImportError:
18
18
has_nodriver = False
19
19
20
20
from .base_provider import AbstractProvider, ProviderModelMixin, BaseConversation
21
from .helper import format_prompt
21
from .helper import format_prompt_max_length
22
22
from ..typing import CreateResult, Messages, ImagesType
23
23
from ..errors import MissingRequirementsError, NoValidHarFileError
24
24
from ..requests.raise_for_status import raise_for_status
@@ -120,16 +120,7 @@ class Copilot(AbstractProvider, ProviderModelMixin):
120
120
conversation_id = response.json().get("id")
121
121
if return_conversation:
122
122
yield Conversation(conversation_id)
123
prompt = format_prompt(messages)
124
if len(prompt) > 10000:
125
if len(messages) > 6:
126
prompt = format_prompt(messages[:3] + messages[-3:])
127
if len(prompt) > 10000:
128
if len(messages) > 2:
129
prompt = format_prompt(messages[:2] + messages[-1:])
130
if len(prompt) > 10000:
131
prompt = messages[-1]["content"]
132
debug.log(f"Copilot: Trim messages to: {len(prompt)}")
123
prompt = format_prompt_max_length(messages, 10000)
133
124
debug.log(f"Copilot: Created conversation: {conversation_id}")
134
125
else:
135
126
conversation_id = conversation.conversation_id
@@ -10,7 +10,7 @@ from ..image import ImageResponse
10
10
from ..requests.raise_for_status import raise_for_status
11
11
from ..requests.aiohttp import get_connector
12
12
from .needs_auth.OpenaiAPI import OpenaiAPI
13
from .helper import format_prompt
13
from .helper import format_prompt_max_length
14
14
15
15
class PollinationsAI(OpenaiAPI):
16
16
label = "Pollinations AI"
@@ -97,7 +97,7 @@ class PollinationsAI(OpenaiAPI):
97
97
async def _generate_text(cls, model: str, messages: Messages, api_key: str = None, proxy: str = None, **kwargs):
98
98
if api_key is None:
99
99
async with ClientSession(connector=get_connector(proxy=proxy), headers=cls.headers) as session:
100
prompt = format_prompt(messages)
100
prompt = format_prompt_max_length(messages, 5000)
101
101
async with session.get(f"https://text.pollinations.ai/{quote(prompt)}?model={quote(model)}") as response:
102
102
await raise_for_status(response)
103
103
async for line in response.content.iter_any():
@@ -207,7 +207,7 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
207
207
) as session:
208
208
if not cls._snlm0e:
209
209
await cls.fetch_snlm0e(session, cls._cookies) if cls._cookies else None
210
inner_data = json.dumps([None, params["text"], "de-DE", None, 2])
210
inner_data = json.dumps([None, params["text"], "en-US", None, 2])
211
211
async with session.post(
212
212
"https://gemini.google.com/_/BardChatUi/data/batchexecute",
213
213
data={
@@ -334,8 +334,11 @@ async def iter_filter_base64(response_iter: AsyncIterator[bytes]) -> AsyncIterat
334
334
335
335
async def iter_base64_decode(response_iter: AsyncIterator[bytes]) -> AsyncIterator[bytes]:
336
336
buffer = b""
337
rest = 0
337
338
async for chunk in response_iter:
338
339
chunk = buffer + chunk
339
340
rest = len(chunk) % 4
340
341
buffer = chunk[-rest:]
341
342
yield base64.b64decode(chunk[:-rest])
343
if rest > 0:
344
yield base64.b64decode(buffer+rest*b"=")
@@ -1,11 +1,12 @@
1
1
from __future__ import annotations
2
2
3
3
import json
4
from aiohttp import ClientSession
4
5
5
6
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, BaseConversation
6
7
from ...typing import AsyncResult, Messages, Cookies
7
8
from ...requests.raise_for_status import raise_for_status
8
from ...requests import StreamSession
9
from ...requests.aiohttp import get_connector
9
10
from ...providers.helper import format_prompt
10
11
from ...cookies import get_cookies
11
12
@@ -16,6 +17,7 @@ class Conversation(BaseConversation):
16
17
self.conversation_id = conversation_id
17
18
18
19
class GithubCopilot(AsyncGeneratorProvider, ProviderModelMixin):
20
label = "GitHub Copilot"
19
21
url = "https://github.com/copilot"
20
22
21
23
working = True
@@ -42,13 +44,22 @@ class GithubCopilot(AsyncGeneratorProvider, ProviderModelMixin):
42
44
if not model:
43
45
model = cls.default_model
44
46
if cookies is None:
45
cookies = get_cookies(".github.com")
46
async with StreamSession(
47
proxy=proxy,
48
impersonate="chrome",
47
cookies = get_cookies("github.com")
48
async with ClientSession(
49
connector=get_connector(proxy=proxy),
49
50
cookies=cookies,
50
51
headers={
51
"GitHub-Verified-Fetch": "true",
52
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0',
53
'Accept-Language': 'en-US,en;q=0.5',
54
'Referer': 'https://github.com/copilot',
55
'Content-Type': 'application/json',
56
'GitHub-Verified-Fetch': 'true',
57
'X-Requested-With': 'XMLHttpRequest',
58
'Origin': 'https://github.com',
59
'Connection': 'keep-alive',
60
'Sec-Fetch-Dest': 'empty',
61
'Sec-Fetch-Mode': 'cors',
62
'Sec-Fetch-Site': 'same-origin',
52
63
}
53
64
) as session:
54
65
headers = {}
@@ -87,7 +98,7 @@ class GithubCopilot(AsyncGeneratorProvider, ProviderModelMixin):
87
98
json=json_data,
88
99
headers=headers
89
100
) as response:
90
async for line in response.iter_lines():
101
async for line in response.content:
91
102
if line.startswith(b"data: "):
92
103
data = json.loads(line[6:])
93
104
if data.get("type") == "content":
@@ -352,7 +352,10 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
352
352
json={"p": get_requirements_token(RequestConfig.proof_token) if RequestConfig.proof_token else None},
353
353
headers=cls._headers
354
354
) as response:
355
cls._update_request_args(session)
355
if response.status == 401:
356
cls._headers = cls._api_key = None
357
else:
358
cls._update_request_args(session)
356
359
await raise_for_status(response)
357
360
chat_requirements = await response.json()
358
361
need_turnstile = chat_requirements.get("turnstile", {}).get("required", False)
@@ -525,7 +528,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
525
528
cls._set_api_key(RequestConfig.access_token)
526
529
except NoValidHarFileError:
527
530
if has_nodriver:
528
if RequestConfig.access_token is None:
531
if cls._api_key is None:
529
532
await cls.nodriver_auth(proxy)
530
533
else:
531
534
raise
@@ -545,7 +548,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
545
548
if "OpenAI-Sentinel-Turnstile-Token" in event.request.headers:
546
549
RequestConfig.turnstile_token = event.request.headers["OpenAI-Sentinel-Turnstile-Token"]
547
550
if "Authorization" in event.request.headers:
548
RequestConfig.access_token = event.request.headers["Authorization"].split()[-1]
551
cls._set_api_key(event.request.headers["Authorization"].split()[-1])
549
552
elif event.request.url == arkose_url:
550
553
RequestConfig.arkose_request = arkReq(
551
554
arkURL=event.request.url,
@@ -560,13 +563,13 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
560
563
user_agent = await page.evaluate("window.navigator.userAgent")
561
564
await page.select("#prompt-textarea", 240)
562
565
while True:
563
if RequestConfig.access_token:
566
if cls._api_key is not None:
564
567
break
565
568
body = await page.evaluate("JSON.stringify(window.__remixContext)")
566
569
if body:
567
570
match = re.search(r'"accessToken":"(.*?)"', body)
568
571
if match:
569
RequestConfig.access_token = match.group(1)
572
cls._set_api_key(match.group(1))
570
573
break
571
574
await asyncio.sleep(1)
572
575
while True:
@@ -578,7 +581,6 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
578
581
RequestConfig.cookies[c.name] = c.value
579
582
await page.close()
580
583
cls._create_request_args(RequestConfig.cookies, RequestConfig.headers, user_agent=user_agent)
581
cls._set_api_key(RequestConfig.access_token)
582
584
583
585
@staticmethod
584
586
def get_default_headers() -> dict:
@@ -42,7 +42,9 @@ class ChatCompletion:
42
42
if "proxy" not in kwargs:
43
43
proxy = os.environ.get("G4F_PROXY")
44
44
if proxy:
45
kwargs['proxy'] = proxy
45
kwargs["proxy"] = proxy
46
if ignore_stream:
47
kwargs["ignore_stream"] = True
46
48
47
49
result = provider.create_completion(model, messages, stream=stream, **kwargs)
48
50
@@ -53,9 +55,20 @@ class ChatCompletion:
53
55
messages : Messages,
54
56
provider : Union[ProviderType, str, None] = None,
55
57
stream : bool = False,
58
image : ImageType = None,
59
image_name: Optional[str] = None,
60
ignore_stream: bool = False,
56
61
ignore_working: bool = False,
57
62
**kwargs) -> Union[AsyncResult, Coroutine[str]]:
58
63
model, provider = get_model_and_provider(model, provider, False, ignore_working)
64
if image is not None:
65
kwargs["images"] = [(image, image_name)]
66
if "proxy" not in kwargs:
67
proxy = os.environ.get("G4F_PROXY")
68
if proxy:
69
kwargs["proxy"] = proxy
70
if ignore_stream:
71
kwargs["ignore_stream"] = True
59
72
60
73
if stream:
61
74
if hasattr(provider, "create_async_generator"):
@@ -26,7 +26,6 @@ from fastapi.encoders import jsonable_encoder
26
26
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials, HTTPBasic
27
27
from fastapi.middleware.cors import CORSMiddleware
28
28
from starlette.responses import FileResponse
29
from pydantic import BaseModel, Field
30
29
from typing import Union, Optional, List
31
30
try:
32
31
from typing import Annotated
@@ -40,11 +39,16 @@ from g4f.client import AsyncClient, ChatCompletion, ImagesResponse, convert_to_p
40
39
from g4f.providers.response import BaseConversation
41
40
from g4f.client.helper import filter_none
42
41
from g4f.image import is_accepted_format, is_data_uri_an_image, images_dir
43
from g4f.typing import Messages
44
from g4f.errors import ProviderNotFoundError, ModelNotFoundError, MissingAuthError
42
from g4f.errors import ProviderNotFoundError, ModelNotFoundError, MissingAuthError, NoValidHarFileError
45
43
from g4f.cookies import read_cookie_files, get_cookies_dir
46
44
from g4f.Provider import ProviderType, ProviderUtils, __providers__
47
45
from g4f.gui import get_gui_app
46
from .stubs import (
47
ChatCompletionsConfig, ImageGenerationConfig,
48
ProviderResponseModel, ModelResponseModel,
49
ErrorResponseModel, ProviderResponseDetailModel,
50
FileResponseModel
51
)
48
52
49
53
logger = logging.getLogger(__name__)
50
54
@@ -64,18 +68,10 @@ def create_app():
64
68
65
69
api = Api(app)
66
70
67
if AppConfig.gui:
68
@app.get("/")
69
async def home():
70
return HTMLResponse(f'g4f v-{g4f.version.utils.current_version}:<br><br>'
71
'Start to chat: <a href="/chat/">/chat/</a><br>'
72
'Open Swagger UI at: '
73
'<a href="/docs">/docs</a>')
74
75
71
api.register_routes()
76
72
api.register_authorization()
77
73
api.register_validation_exception_handler()
78
74
79
75
if AppConfig.gui:
80
76
gui_app = WSGIMiddleware(get_gui_app())
81
77
app.mount("/", gui_app)
@@ -100,63 +96,6 @@ def create_app_with_gui_and_debug():
100
96
AppConfig.gui = True
101
97
return create_app()
102
98
103
class ChatCompletionsConfig(BaseModel):
104
messages: Messages = Field(examples=[[{"role": "system", "content": ""}, {"role": "user", "content": ""}]])
105
model: str = Field(default="")
106
provider: Optional[str] = None
107
stream: bool = False
108
image: Optional[str] = None
109
image_name: Optional[str] = None
110
images: Optional[list[tuple[str, str]]] = None
111
temperature: Optional[float] = None
112
max_tokens: Optional[int] = None
113
stop: Union[list[str], str, None] = None
114
api_key: Optional[str] = None
115
web_search: Optional[bool] = None
116
proxy: Optional[str] = None
117
conversation_id: Optional[str] = None
118
history_disabled: Optional[bool] = None
119
auto_continue: Optional[bool] = None
120
timeout: Optional[int] = None
121
122
class ImageGenerationConfig(BaseModel):
123
prompt: str
124
model: Optional[str] = None
125
provider: Optional[str] = None
126
response_format: Optional[str] = None
127
api_key: Optional[str] = None
128
proxy: Optional[str] = None
129
130
class ProviderResponseModel(BaseModel):
131
id: str
132
object: str = "provider"
133
created: int
134
url: Optional[str]
135
label: Optional[str]
136
137
class ProviderResponseDetailModel(ProviderResponseModel):
138
models: list[str]
139
image_models: list[str]
140
vision_models: list[str]
141
params: list[str]
142
143
class ModelResponseModel(BaseModel):
144
id: str
145
object: str = "model"
146
created: int
147
owned_by: Optional[str]
148
149
class ErrorResponseModel(BaseModel):
150
error: ErrorResponseMessageModel
151
model: Optional[str] = None
152
provider: Optional[str] = None
153
154
class ErrorResponseMessageModel(BaseModel):
155
message: str
156
157
class FileResponseModel(BaseModel):
158
filename: str
159
160
99
class ErrorResponse(Response):
161
100
media_type = "application/json"
162
101
@@ -198,7 +137,7 @@ class Api:
198
137
security = HTTPBearer(auto_error=False)
199
138
basic_security = HTTPBasic()
200
139
201
async def get_username(self, request: Request):
140
async def get_username(self, request: Request) -> str:
202
141
credentials = await self.basic_security(request)
203
142
current_password_bytes = credentials.password.encode()
204
143
is_correct_password = secrets.compare_digest(
@@ -222,13 +161,13 @@ class Api:
222
161
user_g4f_api_key = await self.get_g4f_api_key(request)
223
162
except HTTPException:
224
163
user_g4f_api_key = None
225
if request.url.path.startswith("/v1"):
164
path = request.url.path
165
if path.startswith("/v1"):
226
166
if user_g4f_api_key is None:
227
167
return ErrorResponse.from_message("G4F API key required", HTTP_401_UNAUTHORIZED)
228
168
if not secrets.compare_digest(AppConfig.g4f_api_key, user_g4f_api_key):
229
169
return ErrorResponse.from_message("Invalid G4F API key", HTTP_403_FORBIDDEN)
230
170
else:
231
path = request.url.path
232
171
if user_g4f_api_key is not None and path.startswith("/images/"):
233
172
if not secrets.compare_digest(AppConfig.g4f_api_key, user_g4f_api_key):
234
173
return ErrorResponse.from_message("Invalid G4F API key", HTTP_403_FORBIDDEN)
@@ -261,6 +200,8 @@ class Api:
261
200
def register_routes(self):
262
201
@self.app.get("/")
263
202
async def read_root():
203
if AppConfig.gui:
204
return RedirectResponse("/chat/", 302)
264
205
return RedirectResponse("/v1", 302)
265
206
266
207
@self.app.get("/v1")
@@ -336,6 +277,7 @@ class Api:
336
277
except ValueError as e:
337
278
example = json.dumps({"images": [["data:image/jpeg;base64,...", "filename"]]})
338
279
return ErrorResponse.from_message(f'The image you send must be a data URI. Example: {example}', status_code=HTTP_422_UNPROCESSABLE_ENTITY)
280
339
281
# Create the completion response
340
282
response = self.client.chat.completions.create(
341
283
**filter_none(
@@ -379,7 +321,7 @@ class Api:
379
321
except (ModelNotFoundError, ProviderNotFoundError) as e:
380
322
logger.exception(e)
381
323
return ErrorResponse.from_exception(e, config, HTTP_404_NOT_FOUND)
382
except MissingAuthError as e:
324
except (MissingAuthError, NoValidHarFileError) as e:
383
325
logger.exception(e)
384
326
return ErrorResponse.from_exception(e, config, HTTP_401_UNAUTHORIZED)
385
327
except Exception as e:
@@ -392,7 +334,6 @@ class Api:
392
334
HTTP_404_NOT_FOUND: {"model": ErrorResponseModel},
393
335
HTTP_500_INTERNAL_SERVER_ERROR: {"model": ErrorResponseModel},
394
336
}
395
396
337
@self.app.post("/v1/images/generate", responses=responses)
397
338
@self.app.post("/v1/images/generations", responses=responses)
398
339
async def generate_image(
@@ -564,4 +505,4 @@ def run_api(
564
505
use_colors=use_colors,
565
506
factory=True,
566
507
reload=reload
567
)
508
)
@@ -0,0 +1,63 @@
1
from __future__ import annotations
2
3
from pydantic import BaseModel, Field
4
from typing import Union, Optional
5
6
from g4f.typing import Messages
7
8
class ChatCompletionsConfig(BaseModel):
9
messages: Messages = Field(examples=[[{"role": "system", "content": ""}, {"role": "user", "content": ""}]])
10
model: str = Field(default="")
11
provider: Optional[str] = None
12
stream: bool = False
13
image: Optional[str] = None
14
image_name: Optional[str] = None
15
images: Optional[list[tuple[str, str]]] = None
16
temperature: Optional[float] = None
17
max_tokens: Optional[int] = None
18
stop: Union[list[str], str, None] = None
19
api_key: Optional[str] = None
20
web_search: Optional[bool] = None
21
proxy: Optional[str] = None
22
conversation_id: Optional[str] = None
23
history_disabled: Optional[bool] = None
24
auto_continue: Optional[bool] = None
25
timeout: Optional[int] = None
26
27
class ImageGenerationConfig(BaseModel):
28
prompt: str
29
model: Optional[str] = None
30
provider: Optional[str] = None
31
response_format: Optional[str] = None
32
api_key: Optional[str] = None
33
proxy: Optional[str] = None
34
35
class ProviderResponseModel(BaseModel):
36
id: str
37
object: str = "provider"
38
created: int
39
url: Optional[str]
40
label: Optional[str]
41
42
class ProviderResponseDetailModel(ProviderResponseModel):
43
models: list[str]
44
image_models: list[str]
45
vision_models: list[str]
46
params: list[str]
47
48
class ModelResponseModel(BaseModel):
49
id: str
50
object: str = "model"
51
created: int
52
owned_by: Optional[str]
53
54
class ErrorResponseModel(BaseModel):
55
error: ErrorResponseMessageModel
56
model: Optional[str] = None
57
provider: Optional[str] = None
58
59
class ErrorResponseMessageModel(BaseModel):
60
message: str
61
62
class FileResponseModel(BaseModel):
63
filename: str
@@ -16,7 +16,6 @@ from ..errors import NoImageResponseError
16
16
from ..providers.retry_provider import IterListProvider
17
17
from ..providers.asyncio import to_sync_generator, async_generator_to_list
18
18
from ..Provider.needs_auth import BingCreateImages, OpenaiAccount
19
from ..image import to_bytes
20
19
from .stubs import ChatCompletion, ChatCompletionChunk, Image, ImagesResponse
21
20
from .image_models import ImageModels
22
21
from .types import IterResponse, ImageProvider, Client as BaseClient
@@ -59,7 +58,7 @@ def iter_response(
59
58
elif isinstance(chunk, BaseConversation):
60
59
yield chunk
61
60
continue
62
elif isinstance(chunk, SynthesizeData) or chunk is None:
61
elif isinstance(chunk, SynthesizeData) or not chunk:
63
62
continue
64
63
65
64
chunk = str(chunk)
@@ -122,7 +121,7 @@ async def async_iter_response(
122
121
elif isinstance(chunk, BaseConversation):
123
122
yield chunk
124
123
continue
125
elif isinstance(chunk, SynthesizeData) or chunk is None:
124
elif isinstance(chunk, SynthesizeData) or not chunk:
126
125
continue
127
126
128
127
chunk = str(chunk)
@@ -214,6 +213,8 @@ class Completions:
214
213
stop = [stop] if isinstance(stop, str) else stop
215
214
if image is not None:
216
215
kwargs["images"] = [(image, image_name)]
216
if ignore_stream:
217
kwargs["ignore_stream"] = True
217
218
response = provider.create_completion(
218
219
model,
219
220
messages,
@@ -330,7 +331,6 @@ class Images:
330
331
model: str,
331
332
prompt: str,
332
333
prompt_prefix: str = "Generate a image: ",
333
image: ImageType = None,
334
334
**kwargs
335
335
) -> ImageResponse:
336
336
messages = [{"role": "user", "content": f"{prompt_prefix}{prompt}"}]
@@ -341,7 +341,6 @@ class Images:
341
341
messages,
342
342
stream=True,
343
343
prompt=prompt,
344
image=image,
345
344
**kwargs
346
345
):
347
346
if isinstance(item, ImageResponse):
@@ -353,7 +352,6 @@ class Images:
353
352
messages,
354
353
True,
355
354
prompt=prompt,
356
image=image,
357
355
**kwargs
358
356
):
359
357
if isinstance(item, ImageResponse):
@@ -389,20 +387,22 @@ class Images:
389
387
if proxy is None:
390
388
proxy = self.client.proxy
391
389
prompt = "create a variation of this image"
390
if image is not None:
391
kwargs["images"] = [(image, None)]
392
392
393
393
e = None
394
394
response = None
395
395
if isinstance(provider_handler, IterListProvider):
396
396
for provider in provider_handler.providers:
397
397
try:
398
response = await self._generate_image_response(provider, provider.__name__, model, prompt, image=image, **kwargs)
398
response = await self._generate_image_response(provider, provider.__name__, model, prompt, **kwargs)
399
399
if response is not None:
400
400
provider_name = provider.__name__
401
401
break
402
402
except Exception as e:
403
403
debug.log(f"Image provider {provider.__name__}: {e}")
404
404
else:
405
response = await self._generate_image_response(provider_handler, provider_name, model, prompt, image=image, **kwargs)
405
response = await self._generate_image_response(provider_handler, provider_name, model, prompt, **kwargs)
406
406
407
407
if isinstance(response, ImageResponse):
408
408
return await self._process_image_response(response, response_format, proxy, model, provider_name)
@@ -494,6 +494,8 @@ class AsyncCompletions:
494
494
stop = [stop] if isinstance(stop, str) else stop
495
495
if image is not None:
496
496
kwargs["images"] = [(image, image_name)]
497
if ignore_stream:
498
kwargs["ignore_stream"] = True
497
499
if hasattr(provider, "create_async_generator"):
498
500
create_handler = provider.create_async_generator
499
501
else:
@@ -59,6 +59,7 @@ DOMAINS = [
59
59
"chat.reka.ai",
60
60
"chatgpt.com",
61
61
".cerebras.ai",
62
"github.com",
62
63
]
63
64
64
65
if has_browser_cookie3 and os.environ.get('DBUS_SESSION_BUS_ADDRESS') == "/dev/null":