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

XFEstudio/gpt4free

Update (g4f/Provider/Blackbox.py)

36aecbd6
kqlio67 <kqlio67@users.noreply.github.com>
提交于

代码差异

1 个文件 +113 -337
Modified g4f/Provider/Blackbox.py +113 -337
@@ -1,21 +1,15 @@
1 1 from __future__ import annotations
2 2
3 import asyncio
4 import aiohttp
3 from aiohttp import ClientSession
5 4 import random
6 5 import string
7 6 import json
8 import uuid
9 7 import re
10 from typing import Optional, AsyncGenerator, Union
11
12 from aiohttp import ClientSession, ClientResponseError
13 8
14 9 from ..typing import AsyncResult, Messages, ImageType
15 10 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
16 11 from ..image import ImageResponse, to_data_uri
17 12
18
19 13 class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
20 14 label = "Blackbox AI"
21 15 url = "https://www.blackbox.ai"
@@ -24,154 +18,89 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
24 18 supports_stream = True
25 19 supports_system_message = True
26 20 supports_message_history = True
27
21
28 22 default_model = 'blackboxai'
29 image_models = ['ImageGeneration']
30 models = [
31 default_model,
32 'blackboxai-pro',
33 *image_models,
34 "llama-3.1-8b",
35 'llama-3.1-70b',
36 'llama-3.1-405b',
37 'gpt-4o',
38 'gemini-pro',
39 'gemini-1.5-flash',
40 'claude-sonnet-3.5',
41 'PythonAgent',
42 'JavaAgent',
43 'JavaScriptAgent',
44 'HTMLAgent',
45 'GoogleCloudAgent',
46 'AndroidDeveloper',
47 'SwiftDeveloper',
48 'Next.jsAgent',
49 'MongoDBAgent',
50 'PyTorchAgent',
51 'ReactAgent',
52 'XcodeAgent',
53 'AngularJSAgent',
54 'HerokuAgent',
55 'GodotAgent',
56 'GoAgent',
57 'GitlabAgent',
58 'GitAgent',
59 'RepoMap',
60 'FlaskAgent',
61 'FirebaseAgent',
62 'FastAPIAgent',
63 'ErlangAgent',
64 'ElectronAgent',
65 'DockerAgent',
66 'DigitalOceanAgent',
67 'BitbucketAgent',
68 'AzureAgent',
69 'FlutterAgent',
70 'YoutubeAgent',
71 'builderAgent',
72 ]
73
23
24 image_models = ['Image Generation', 'repomap']
25
26 userSelectedModel = ['gpt-4o', 'gemini-pro', 'claude-sonnet-3.5', 'blackboxai-pro']
27
74 28 agentMode = {
75 'ImageGeneration': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"},
29 'Image Generation': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "Image Generation"},
76 30 }
77
31
78 32 trendingAgentMode = {
79 "blackboxai": {},
80 "blackboxai": {},
81 33 "gemini-1.5-flash": {'mode': True, 'id': 'Gemini'},
82 34 "llama-3.1-8b": {'mode': True, 'id': "llama-3.1-8b"},
83 35 'llama-3.1-70b': {'mode': True, 'id': "llama-3.1-70b"},
84 'llama-3.1-405b': {'mode': True, 'id': "llama-3.1-405b"},
36 #
37 'Python Agent': {'mode': True, 'id': "Python Agent"},
38 'Java Agent': {'mode': True, 'id': "Java Agent"},
39 'JavaScript Agent': {'mode': True, 'id': "JavaScript Agent"},
40 'HTML Agent': {'mode': True, 'id': "HTML Agent"},
41 'Google Cloud Agent': {'mode': True, 'id': "Google Cloud Agent"},
42 'Android Developer': {'mode': True, 'id': "Android Developer"},
43 'Swift Developer': {'mode': True, 'id': "Swift Developer"},
44 'Next.js Agent': {'mode': True, 'id': "Next.js Agent"},
45 'MongoDB Agent': {'mode': True, 'id': "MongoDB Agent"},
46 'PyTorch Agent': {'mode': True, 'id': "PyTorch Agent"},
47 'React Agent': {'mode': True, 'id': "React Agent"},
48 'Xcode Agent': {'mode': True, 'id': "Xcode Agent"},
49 'AngularJS Agent': {'mode': True, 'id': "AngularJS Agent"},
85 50 'blackboxai-pro': {'mode': True, 'id': "BLACKBOXAI-PRO"},
86 'PythonAgent': {'mode': True, 'id': "Python Agent"},
87 'JavaAgent': {'mode': True, 'id': "Java Agent"},
88 'JavaScriptAgent': {'mode': True, 'id': "JavaScript Agent"},
89 'HTMLAgent': {'mode': True, 'id': "HTML Agent"},
90 'GoogleCloudAgent': {'mode': True, 'id': "Google Cloud Agent"},
91 'AndroidDeveloper': {'mode': True, 'id': "Android Developer"},
92 'SwiftDeveloper': {'mode': True, 'id': "Swift Developer"},
93 'Next.jsAgent': {'mode': True, 'id': "Next.js Agent"},
94 'MongoDBAgent': {'mode': True, 'id': "MongoDB Agent"},
95 'PyTorchAgent': {'mode': True, 'id': "PyTorch Agent"},
96 'ReactAgent': {'mode': True, 'id': "React Agent"},
97 'XcodeAgent': {'mode': True, 'id': "Xcode Agent"},
98 'AngularJSAgent': {'mode': True, 'id': "AngularJS Agent"},
99 'HerokuAgent': {'mode': True, 'id': "Heroku Agent"},
100 'GodotAgent': {'mode': True, 'id': "Godot Agent"},
101 'GoAgent': {'mode': True, 'id': "Go Agent"},
102 'GitlabAgent': {'mode': True, 'id': "Gitlab Agent"},
103 'GitAgent': {'mode': True, 'id': "Git Agent"},
104 'RepoMap': {'mode': True, 'id': "RepoMap"},
105 'FlaskAgent': {'mode': True, 'id': "Flask Agent"},
106 'FirebaseAgent': {'mode': True, 'id': "Firebase Agent"},
107 'FastAPIAgent': {'mode': True, 'id': "FastAPI Agent"},
108 'ErlangAgent': {'mode': True, 'id': "Erlang Agent"},
109 'ElectronAgent': {'mode': True, 'id': "Electron Agent"},
110 'DockerAgent': {'mode': True, 'id': "Docker Agent"},
111 'DigitalOceanAgent': {'mode': True, 'id': "DigitalOcean Agent"},
112 'BitbucketAgent': {'mode': True, 'id': "Bitbucket Agent"},
113 'AzureAgent': {'mode': True, 'id': "Azure Agent"},
114 'FlutterAgent': {'mode': True, 'id': "Flutter Agent"},
115 'YoutubeAgent': {'mode': True, 'id': "Youtube Agent"},
116 'builderAgent': {'mode': True, 'id': "builder Agent"},
117 }
118
119 userSelectedModel = {
120 "gpt-4o": "gpt-4o",
121 "gemini-pro": "gemini-pro",
122 'claude-sonnet-3.5': "claude-sonnet-3.5",
123 }
124
125 model_prefixes = {
126 'gpt-4o': '@GPT-4o',
127 'gemini-pro': '@Gemini-PRO',
128 'PythonAgent': '@Python Agent',
129 'JavaAgent': '@Java Agent',
130 'JavaScriptAgent': '@JavaScript Agent',
131 'HTMLAgent': '@HTML Agent',
132 'GoogleCloudAgent': '@Google Cloud Agent',
133 'AndroidDeveloper': '@Android Developer',
134 'SwiftDeveloper': '@Swift Developer',
135 'Next.jsAgent': '@Next.js Agent',
136 'MongoDBAgent': '@MongoDB Agent',
137 'PyTorchAgent': '@PyTorch Agent',
138 'ReactAgent': '@React Agent',
139 'XcodeAgent': '@Xcode Agent',
140 'AngularJSAgent': '@AngularJS Agent',
141 'HerokuAgent': '@Heroku Agent',
142 'GodotAgent': '@Godot Agent',
143 'GoAgent': '@Go Agent',
144 'GitlabAgent': '@Gitlab Agent',
145 'GitAgent': '@Git Agent',
146 'blackboxai-pro': '@BLACKBOXAI-PRO',
147 'ImageGeneration': '@Image Generation',
148 'FlaskAgent': '@Flask Agent',
149 'FirebaseAgent': '@Firebase Agent',
150 'FastAPIAgent': '@FastAPI Agent',
151 'ErlangAgent': '@Erlang Agent',
152 'ElectronAgent': '@Electron Agent',
153 'DockerAgent': '@Docker Agent',
154 'DigitalOceanAgent': '@DigitalOcean Agent',
155 'BitbucketAgent': '@Bitbucket Agent',
156 'AzureAgent': '@Azure Agent',
157 'FlutterAgent': '@Flutter Agent',
158 'YoutubeAgent': '@Youtube Agent',
159 'builderAgent': '@builder Agent',
160 }
161
162 model_referers = {
163 "blackboxai": "/?model=blackboxai",
164 "gpt-4o": "/?model=gpt-4o",
165 "gemini-pro": "/?model=gemini-pro",
166 "claude-sonnet-3.5": "/?model=claude-sonnet-3.5"
51 #
52 'repomap': {'mode': True, 'id': "repomap"},
53 #
54 'Heroku Agent': {'mode': True, 'id': "Heroku Agent"},
55 'Godot Agent': {'mode': True, 'id': "Godot Agent"},
56 'Go Agent': {'mode': True, 'id': "Go Agent"},
57 'Gitlab Agent': {'mode': True, 'id': "Gitlab Agent"},
58 'Git Agent': {'mode': True, 'id': "Git Agent"},
59 'Flask Agent': {'mode': True, 'id': "Flask Agent"},
60 'Firebase Agent': {'mode': True, 'id': "Firebase Agent"},
61 'FastAPI Agent': {'mode': True, 'id': "FastAPI Agent"},
62 'Erlang Agent': {'mode': True, 'id': "Erlang Agent"},
63 'Electron Agent': {'mode': True, 'id': "Electron Agent"},
64 'Docker Agent': {'mode': True, 'id': "Docker Agent"},
65 'DigitalOcean Agent': {'mode': True, 'id': "DigitalOcean Agent"},
66 'Bitbucket Agent': {'mode': True, 'id': "Bitbucket Agent"},
67 'Azure Agent': {'mode': True, 'id': "Azure Agent"},
68 'Flutter Agent': {'mode': True, 'id': "Flutter Agent"},
69 'Youtube Agent': {'mode': True, 'id': "Youtube Agent"},
70 'builder Agent': {'mode': True, 'id': "builder Agent"},
167 71 }
72
73 model_prefixes = {mode: f"@{value['id']}" for mode, value in trendingAgentMode.items() if mode not in ["gemini-1.5-flash", "llama-3.1-8b", "llama-3.1-70b", "repomap"]}
168 74
75
76 models = [default_model, *userSelectedModel, *list(agentMode.keys()), *list(trendingAgentMode.keys())]
77
169 78 model_aliases = {
170 79 "gemini-flash": "gemini-1.5-flash",
171 80 "claude-3.5-sonnet": "claude-sonnet-3.5",
172 "flux": "ImageGeneration",
81 "flux": "Image Generation",
173 82 }
174 83
84 @staticmethod
85 def generate_id(length=7):
86 characters = string.ascii_letters + string.digits
87 return ''.join(random.choice(characters) for _ in range(length))
88
89 @classmethod
90 def add_prefix_to_messages(cls, messages: Messages, model: str) -> Messages:
91 prefix = cls.model_prefixes.get(model, "")
92 if not prefix:
93 return messages
94
95 new_messages = []
96 for message in messages:
97 new_message = message.copy()
98 if message['role'] == 'user':
99 new_message['content'] = (prefix + " " + message['content']).strip()
100 new_messages.append(new_message)
101
102 return new_messages
103
175 104 @classmethod
176 105 def get_model(cls, model: str) -> str:
177 106 if model in cls.models:
@@ -181,140 +110,54 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
181 110 else:
182 111 return cls.default_model
183 112
184 @staticmethod
185 def generate_random_string(length: int = 7) -> str:
186 characters = string.ascii_letters + string.digits
187 return ''.join(random.choices(characters, k=length))
188
189 @staticmethod
190 def generate_next_action() -> str:
191 return uuid.uuid4().hex
192
193 @staticmethod
194 def generate_next_router_state_tree() -> str:
195 router_state = [
196 "",
197 {
198 "children": [
199 "(chat)",
200 {
201 "children": [
202 "__PAGE__",
203 {}
204 ]
205 }
206 ]
207 },
208 None,
209 None,
210 True
211 ]
212 return json.dumps(router_state)
213
214 @staticmethod
215 def clean_response(text: str) -> str:
216 pattern = r'^\$\@\$v=undefined-rv1\$\@\$'
217 cleaned_text = re.sub(pattern, '', text)
218 return cleaned_text
219
220 113 @classmethod
221 114 async def create_async_generator(
222 115 cls,
223 116 model: str,
224 117 messages: Messages,
225 proxy: Optional[str] = None,
118 proxy: str = None,
119 web_search: bool = False,
226 120 image: ImageType = None,
227 121 image_name: str = None,
228 web_search: bool = False,
229 122 **kwargs
230 ) -> AsyncGenerator[Union[str, ImageResponse], None]:
231 """
232 Creates an asynchronous generator for streaming responses from Blackbox AI.
233
234 Parameters:
235 model (str): Model to use for generating responses.
236 messages (Messages): Message history.
237 proxy (Optional[str]): Proxy URL, if needed.
238 image (ImageType): Image data to be processed, if any.
239 image_name (str): Name of the image file, if an image is provided.
240 web_search (bool): Enables or disables web search mode.
241 **kwargs: Additional keyword arguments.
123 ) -> AsyncResult:
124 model = cls.get_model(model)
125 message_id = cls.generate_id()
126 messages_with_prefix = cls.add_prefix_to_messages(messages, model)
242 127
243 Yields:
244 Union[str, ImageResponse]: Segments of the generated response or ImageResponse objects.
245 """
246
247 128 if image is not None:
248 messages[-1]['data'] = {
129 messages_with_prefix[-1]['data'] = {
249 130 'fileText': '',
250 131 'imageBase64': to_data_uri(image),
251 132 'title': image_name
252 133 }
253 messages[-1]['content'] = 'FILE:BB\n$#$\n\n$#$\n' + messages[-1]['content']
254
255 model = cls.get_model(model)
256
257 chat_id = cls.generate_random_string()
258 next_action = cls.generate_next_action()
259 next_router_state_tree = cls.generate_next_router_state_tree()
260 134
261 agent_mode = cls.agentMode.get(model, {})
262 trending_agent_mode = cls.trendingAgentMode.get(model, {})
263
264 prefix = cls.model_prefixes.get(model, "")
265
266 formatted_prompt = ""
267 for message in messages:
268 role = message.get('role', '').capitalize()
269 content = message.get('content', '')
270 if role and content:
271 formatted_prompt += f"{role}: {content}\n"
272
273 if prefix:
274 formatted_prompt = f"{prefix} {formatted_prompt}".strip()
275
276 referer_path = cls.model_referers.get(model, f"/?model={model}")
277 referer_url = f"{cls.url}{referer_path}"
278
279 common_headers = {
135 headers = {
280 136 'accept': '*/*',
281 137 'accept-language': 'en-US,en;q=0.9',
282 138 'cache-control': 'no-cache',
139 'content-type': 'application/json',
283 140 'origin': cls.url,
284 141 'pragma': 'no-cache',
285 142 'priority': 'u=1, i',
286 'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
143 'referer': f'{cls.url}/',
144 'sec-ch-ua': '"Not?A_Brand";v="99", "Chromium";v="130"',
287 145 'sec-ch-ua-mobile': '?0',
288 146 'sec-ch-ua-platform': '"Linux"',
289 147 'sec-fetch-dest': 'empty',
290 148 'sec-fetch-mode': 'cors',
291 149 'sec-fetch-site': 'same-origin',
292 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) '
293 'AppleWebKit/537.36 (KHTML, like Gecko) '
294 'Chrome/129.0.0.0 Safari/537.36'
295 }
296
297 headers_api_chat = {
298 'Content-Type': 'application/json',
299 'Referer': referer_url
150 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36'
300 151 }
301 headers_api_chat_combined = {**common_headers, **headers_api_chat}
302
303 payload_api_chat = {
304 "messages": [
305 {
306 "id": chat_id,
307 "content": formatted_prompt,
308 "role": "user",
309 "data": messages[-1].get('data')
310 }
311 ],
312 "id": chat_id,
152
153 data = {
154 "messages": messages_with_prefix,
155 "id": message_id,
313 156 "previewToken": None,
314 157 "userId": None,
315 158 "codeModelMode": True,
316 "agentMode": agent_mode,
317 "trendingAgentMode": trending_agent_mode,
159 "agentMode": cls.agentMode.get(model, {}) if model in cls.agentMode else {},
160 "trendingAgentMode": cls.trendingAgentMode.get(model, {}) if model in cls.trendingAgentMode else {},
318 161 "isMicMode": False,
319 162 "userSystemPrompt": None,
320 163 "maxTokens": 1024,
@@ -327,100 +170,33 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
327 170 "clickedForceWebSearch": False,
328 171 "visitFromDelta": False,
329 172 "mobileClient": False,
173 "userSelectedModel": model if model in cls.userSelectedModel else None,
330 174 "webSearchMode": web_search,
331 "userSelectedModel": cls.userSelectedModel.get(model, model),
332 175 "validated": "69783381-2ce4-4dbd-ac78-35e9063feabc"
333 176 }
334 177
335 headers_chat = {
336 'Accept': 'text/x-component',
337 'Content-Type': 'text/plain;charset=UTF-8',
338 'Referer': f'{cls.url}/chat/{chat_id}?model={model}',
339 'next-action': next_action,
340 'next-router-state-tree': next_router_state_tree,
341 'next-url': '/'
342 }
343 headers_chat_combined = {**common_headers, **headers_chat}
344
345 data_chat = '[]'
346
347 async with ClientSession(headers=common_headers) as session:
348 try:
349 async with session.post(
350 cls.api_endpoint,
351 headers=headers_api_chat_combined,
352 json=payload_api_chat,
353 proxy=proxy
354 ) as response_api_chat:
355 response_api_chat.raise_for_status()
356 text = await response_api_chat.text()
357 cleaned_response = cls.clean_response(text)
358
359 if model in cls.image_models:
360 match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', cleaned_response)
361 if match:
362 image_url = match.group(1)
363 image_response = ImageResponse(images=image_url, alt="Generated Image")
364 yield image_response
365 else:
366 yield cleaned_response
367 else:
368 if web_search:
369 match = re.search(r'\$~~~\$(.*?)\$~~~\$', cleaned_response, re.DOTALL)
370 if match:
371 source_part = match.group(1).strip()
372 answer_part = cleaned_response[match.end():].strip()
373 try:
374 sources = json.loads(source_part)
375 source_formatted = "**Source:**\n"
376 for item in sources:
377 title = item.get('title', 'No Title')
378 link = item.get('link', '#')
379 position = item.get('position', '')
380 source_formatted += f"{position}. [{title}]({link})\n"
381 final_response = f"{answer_part}\n\n{source_formatted}"
382 except json.JSONDecodeError:
383 final_response = f"{answer_part}\n\nSource information is unavailable."
384 else:
385 final_response = cleaned_response
386 else:
387 if '$~~~$' in cleaned_response:
388 final_response = cleaned_response.split('$~~~$')[0].strip()
389 else:
390 final_response = cleaned_response
391
392 yield final_response
393 except ClientResponseError as e:
394 error_text = f"Error {e.status}: {e.message}"
395 try:
396 error_response = await e.response.text()
397 cleaned_error = cls.clean_response(error_response)
398 error_text += f" - {cleaned_error}"
399 except Exception:
400 pass
401 yield error_text
402 except Exception as e:
403 yield f"Unexpected error during /api/chat request: {str(e)}"
404
405 chat_url = f'{cls.url}/chat/{chat_id}?model={model}'
406
407 try:
408 async with session.post(
409 chat_url,
410 headers=headers_chat_combined,
411 data=data_chat,
412 proxy=proxy
413 ) as response_chat:
414 response_chat.raise_for_status()
415 pass
416 except ClientResponseError as e:
417 error_text = f"Error {e.status}: {e.message}"
418 try:
419 error_response = await e.response.text()
420 cleaned_error = cls.clean_response(error_response)
421 error_text += f" - {cleaned_error}"
422 except Exception:
423 pass
424 yield error_text
425 except Exception as e:
426 yield f"Unexpected error during /chat/{chat_id} request: {str(e)}"
178 async with ClientSession(headers=headers) as session:
179 async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
180 response.raise_for_status()
181 response_text = await response.text()
182
183 if model in cls.image_models:
184 image_matches = re.findall(r'!\[.*?\]\((https?://[^\)]+)\)', response_text)
185 if image_matches:
186 image_url = image_matches[0]
187 image_response = ImageResponse(images=[image_url], alt="Generated Image")
188 yield image_response
189 return
190
191 json_match = re.search(r'\$~~~\$(.*?)\$~~~\$', response_text, re.DOTALL)
192 if json_match:
193 search_results = json.loads(json_match.group(1))
194 answer = response_text.split('$~~~$')[-1].strip()
195
196 formatted_response = f"{answer}\n\n**Source:**"
197 for i, result in enumerate(search_results, 1):
198 formatted_response += f"\n{i}. {result['title']}: {result['link']}"
199
200 yield formatted_response
201 else:
202 yield response_text.strip()