Niansuh commited on
Commit
fec555d
·
verified ·
1 Parent(s): 6142314

Update api/utils.py

Browse files
Files changed (1) hide show
  1. api/utils.py +48 -74
api/utils.py CHANGED
@@ -1,11 +1,12 @@
1
- import re
2
  from datetime import datetime
3
  import json
4
  import uuid
5
  import asyncio
6
  import random
7
  import string
 
8
  from typing import Any, Dict, Optional
 
9
  import httpx
10
  from fastapi import HTTPException
11
  from api.config import (
@@ -24,6 +25,7 @@ from api.validate import getHid # Import the asynchronous getHid function
24
 
25
  logger = setup_logger(__name__)
26
 
 
27
  BLOCKED_MESSAGE = "Generated by BLACKBOX.AI, try unlimited chat https://www.blackbox.ai"
28
 
29
  # Helper function to create chat completion data
@@ -51,6 +53,7 @@ def message_to_dict(message, model_prefix: Optional[str] = None):
51
  if model_prefix:
52
  content = f"{model_prefix} {content}"
53
  if isinstance(message.content, list) and len(message.content) == 2 and "image_url" in message.content[1]:
 
54
  image_base64 = message.content[1]["image_url"]["url"]
55
  return {
56
  "role": message.role,
@@ -59,6 +62,7 @@ def message_to_dict(message, model_prefix: Optional[str] = None):
59
  "imageBase64": image_base64,
60
  "fileText": "",
61
  "title": "snapshot",
 
62
  "imagesData": [
63
  {
64
  "filePath": f"MultipleFiles/{uuid.uuid4().hex}.jpg",
@@ -77,25 +81,17 @@ def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
77
  return content[len(model_prefix):].strip()
78
  return content
79
 
80
- # Function to remove content between '$~~~$' tags
81
- def remove_message_between_special_tags(content: str) -> str:
82
- """Remove any content that starts with '$~~~$' and ends with '$~~~$', including the tags."""
83
- content = re.sub(r'\$~~~\$.*?\$~~~\$', '', content, flags=re.DOTALL)
84
- return content
85
-
86
- # Improved function to remove search results but keep the links intact
87
- def remove_search_results(content: str) -> str:
88
- """Remove search result sections, keeping the URLs intact."""
89
- # Regex pattern to match search result JSON structures (looking for "link" and capturing it)
90
- search_result_pattern = r'\$~~~\$.*?"link":\s*"(https?://[^\"]+).*?\$~~~\$'
91
-
92
- # Remove content inside `$~~~$` tags that contains search result data, keeping only the URLs
93
- cleaned_content = re.sub(search_result_pattern, '', content)
94
-
95
- # Remove unnecessary newlines or extra spaces left by the removal
96
- cleaned_content = cleaned_content.strip()
97
-
98
- return cleaned_content
99
 
100
  # Process streaming response with headers from config.py
101
  async def process_streaming_response(request: ChatRequest):
@@ -112,19 +108,14 @@ async def process_streaming_response(request: ChatRequest):
112
 
113
  if request.model == 'o1-preview':
114
  delay_seconds = random.randint(1, 60)
115
- logger.info(
116
- f"Introducing a delay of {delay_seconds} seconds for model 'o1-preview' "
117
- f"(Request ID: {request_id})"
118
- )
119
  await asyncio.sleep(delay_seconds)
120
 
121
  # Fetch the h-value for the 'validated' field
122
  h_value = await getHid()
123
  if not h_value:
124
  logger.error("Failed to retrieve h-value for validation.")
125
- raise HTTPException(
126
- status_code=500, detail="Validation failed due to missing h-value."
127
- )
128
 
129
  json_data = {
130
  "agentMode": agent_mode,
@@ -137,9 +128,7 @@ async def process_streaming_response(request: ChatRequest):
137
  "isChromeExt": False,
138
  "isMicMode": False,
139
  "maxTokens": request.max_tokens,
140
- "messages": [
141
- message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages
142
- ],
143
  "mobileClient": False,
144
  "playgroundTemperature": request.temperature,
145
  "playgroundTopP": request.top_p,
@@ -157,11 +146,7 @@ async def process_streaming_response(request: ChatRequest):
157
  async with httpx.AsyncClient() as client:
158
  try:
159
  async with client.stream(
160
- "POST",
161
- f"{BASE_URL}/api/chat",
162
- headers=headers_api_chat,
163
- json=json_data,
164
- timeout=100,
165
  ) as response:
166
  response.raise_for_status()
167
  async for chunk in response.aiter_text():
@@ -172,31 +157,22 @@ async def process_streaming_response(request: ChatRequest):
172
  content = content[21:]
173
  # Remove the blocked message if present
174
  if BLOCKED_MESSAGE in content:
175
- logger.info(
176
- f"Blocked message detected in response for Request ID {request_id}."
177
- )
178
  content = content.replace(BLOCKED_MESSAGE, '').strip()
179
  if not content:
180
  continue # Skip if content is empty after removal
181
-
182
- # Remove content between special tags
183
- content = remove_message_between_special_tags(content)
184
-
185
- # Remove search results but keep the links intact
186
- content = remove_search_results(content)
187
-
188
- cleaned_content = strip_model_prefix(content, model_prefix)
189
  yield f"data: {json.dumps(create_chat_completion_data(cleaned_content, request.model, timestamp))}\n\n"
190
 
191
- yield f"data: {json.dumps(create_chat_completion_data('', request.model, timestamp, 'stop'))}\n\n"
192
  yield "data: [DONE]\n\n"
193
  except httpx.HTTPStatusError as e:
194
  logger.error(f"HTTP error occurred for Request ID {request_id}: {e}")
195
  raise HTTPException(status_code=e.response.status_code, detail=str(e))
196
  except httpx.RequestError as e:
197
- logger.error(
198
- f"Error occurred during request for Request ID {request_id}: {e}"
199
- )
200
  raise HTTPException(status_code=500, detail=str(e))
201
 
202
  # Process non-streaming response with headers from config.py
@@ -209,23 +185,24 @@ async def process_non_streaming_response(request: ChatRequest):
209
  trending_agent_mode = TRENDING_AGENT_MODE.get(request.model, {})
210
  model_prefix = MODEL_PREFIXES.get(request.model, "")
211
 
 
212
  headers_api_chat = get_headers_api_chat(BASE_URL)
 
 
 
 
 
213
 
214
  if request.model == 'o1-preview':
215
- delay_seconds = random.randint(1, 60)
216
- logger.info(
217
- f"Introducing a delay of {delay_seconds} seconds for model 'o1-preview' "
218
- f"(Request ID: {request_id})"
219
- )
220
  await asyncio.sleep(delay_seconds)
221
 
222
  # Fetch the h-value for the 'validated' field
223
  h_value = await getHid()
224
  if not h_value:
225
  logger.error("Failed to retrieve h-value for validation.")
226
- raise HTTPException(
227
- status_code=500, detail="Validation failed due to missing h-value."
228
- )
229
 
230
  json_data = {
231
  "agentMode": agent_mode,
@@ -238,9 +215,7 @@ async def process_non_streaming_response(request: ChatRequest):
238
  "isChromeExt": False,
239
  "isMicMode": False,
240
  "maxTokens": request.max_tokens,
241
- "messages": [
242
- message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages
243
- ],
244
  "mobileClient": False,
245
  "playgroundTemperature": request.temperature,
246
  "playgroundTopP": request.top_p,
@@ -255,27 +230,26 @@ async def process_non_streaming_response(request: ChatRequest):
255
  "imageGenerationMode": False, # Added this line
256
  }
257
 
258
- full_response = ""
259
  async with httpx.AsyncClient() as client:
260
  try:
261
- async with client.stream(
262
- method="POST",
263
- url=f"{BASE_URL}/api/chat",
264
- headers=headers_api_chat,
265
- json=json_data,
266
- ) as response:
267
- response.raise_for_status()
268
- async for chunk in response.aiter_text():
269
- full_response += chunk
 
270
  except httpx.HTTPStatusError as e:
271
  logger.error(f"HTTP error occurred for Request ID {request_id}: {e}")
272
  raise HTTPException(status_code=e.response.status_code, detail=str(e))
273
  except httpx.RequestError as e:
274
- logger.error(
275
- f"Error occurred during request for Request ID {request_id}: {e}"
276
- )
277
  raise HTTPException(status_code=500, detail=str(e))
278
 
 
279
  if full_response.startswith("$@$v=undefined-rv1$@$"):
280
  full_response = full_response[21:]
281
 
 
 
1
  from datetime import datetime
2
  import json
3
  import uuid
4
  import asyncio
5
  import random
6
  import string
7
+ import re
8
  from typing import Any, Dict, Optional
9
+
10
  import httpx
11
  from fastapi import HTTPException
12
  from api.config import (
 
25
 
26
  logger = setup_logger(__name__)
27
 
28
+ # Define the blocked message
29
  BLOCKED_MESSAGE = "Generated by BLACKBOX.AI, try unlimited chat https://www.blackbox.ai"
30
 
31
  # Helper function to create chat completion data
 
53
  if model_prefix:
54
  content = f"{model_prefix} {content}"
55
  if isinstance(message.content, list) and len(message.content) == 2 and "image_url" in message.content[1]:
56
+ # Ensure base64 images are always included for all models
57
  image_base64 = message.content[1]["image_url"]["url"]
58
  return {
59
  "role": message.role,
 
62
  "imageBase64": image_base64,
63
  "fileText": "",
64
  "title": "snapshot",
65
+ # Added imagesData field here
66
  "imagesData": [
67
  {
68
  "filePath": f"MultipleFiles/{uuid.uuid4().hex}.jpg",
 
81
  return content[len(model_prefix):].strip()
82
  return content
83
 
84
+ # Helper function to remove content starting with N\n\n$~~~$ and ending with $~~~$
85
+ def remove_enclosed_content(message: str) -> str:
86
+ """
87
+ Remove content that starts with N\n\n$~~~$ and ends with $~~~$ from the message.
88
+ If no such content is found, return the original message.
89
+ """
90
+ pattern = r'N\n\n\$\~\~\~\$(.*?)\$\~\~\~\$'
91
+ match = re.search(pattern, message, re.DOTALL)
92
+ if match:
93
+ return message[:match.start()] + message[match.end():]
94
+ return message
 
 
 
 
 
 
 
 
95
 
96
  # Process streaming response with headers from config.py
97
  async def process_streaming_response(request: ChatRequest):
 
108
 
109
  if request.model == 'o1-preview':
110
  delay_seconds = random.randint(1, 60)
111
+ logger.info(f"Introducing a delay of {delay_seconds} seconds for model 'o1-preview' (Request ID: {request_id})")
 
 
 
112
  await asyncio.sleep(delay_seconds)
113
 
114
  # Fetch the h-value for the 'validated' field
115
  h_value = await getHid()
116
  if not h_value:
117
  logger.error("Failed to retrieve h-value for validation.")
118
+ raise HTTPException(status_code=500, detail="Validation failed due to missing h-value.")
 
 
119
 
120
  json_data = {
121
  "agentMode": agent_mode,
 
128
  "isChromeExt": False,
129
  "isMicMode": False,
130
  "maxTokens": request.max_tokens,
131
+ "messages": [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages],
 
 
132
  "mobileClient": False,
133
  "playgroundTemperature": request.temperature,
134
  "playgroundTopP": request.top_p,
 
146
  async with httpx.AsyncClient() as client:
147
  try:
148
  async with client.stream(
149
+ "POST", f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data, timeout=100
 
 
 
 
150
  ) as response:
151
  response.raise_for_status()
152
  async for chunk in response.aiter_text():
 
157
  content = content[21:]
158
  # Remove the blocked message if present
159
  if BLOCKED_MESSAGE in content:
160
+ logger.info(f"Blocked message detected in response for Request ID {request_id}.")
 
 
161
  content = content.replace(BLOCKED_MESSAGE, '').strip()
162
  if not content:
163
  continue # Skip if content is empty after removal
164
+ # Remove content starting with N\n\n$~~~$ and ending with $~~~$
165
+ cleaned_content = remove_enclosed_content(content)
166
+ cleaned_content = strip_model_prefix(cleaned_content, model_prefix)
 
 
 
 
 
167
  yield f"data: {json.dumps(create_chat_completion_data(cleaned_content, request.model, timestamp))}\n\n"
168
 
169
+ yield f"data: {json.dumps(create_chat_completion_data('ok', request.model, timestamp))}\n\n"
170
  yield "data: [DONE]\n\n"
171
  except httpx.HTTPStatusError as e:
172
  logger.error(f"HTTP error occurred for Request ID {request_id}: {e}")
173
  raise HTTPException(status_code=e.response.status_code, detail=str(e))
174
  except httpx.RequestError as e:
175
+ logger.error(f"Error occurred during request for Request ID {request_id}: {e}")
 
 
176
  raise HTTPException(status_code=500, detail=str(e))
177
 
178
  # Process non-streaming response with headers from config.py
 
185
  trending_agent_mode = TRENDING_AGENT_MODE.get(request.model, {})
186
  model_prefix = MODEL_PREFIXES.get(request.model, "")
187
 
188
+ # Adjust headers_api_chat and headers_chat since referer_url is removed
189
  headers_api_chat = get_headers_api_chat(BASE_URL)
190
+ headers_chat = get_headers_chat(
191
+ BASE_URL,
192
+ next_action=str(uuid.uuid4()),
193
+ next_router_state_tree=json.dumps([""]),
194
+ )
195
 
196
  if request.model == 'o1-preview':
197
+ delay_seconds = random.randint(20, 60)
198
+ logger.info(f"Introducing a delay of {delay_seconds} seconds for model 'o1-preview' (Request ID: {request_id})")
 
 
 
199
  await asyncio.sleep(delay_seconds)
200
 
201
  # Fetch the h-value for the 'validated' field
202
  h_value = await getHid()
203
  if not h_value:
204
  logger.error("Failed to retrieve h-value for validation.")
205
+ raise HTTPException(status_code=500, detail="Validation failed due to missing h-value.")
 
 
206
 
207
  json_data = {
208
  "agentMode": agent_mode,
 
215
  "isChromeExt": False,
216
  "isMicMode": False,
217
  "maxTokens": request.max_tokens,
218
+ "messages": [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages],
 
 
219
  "mobileClient": False,
220
  "playgroundTemperature": request.temperature,
221
  "playgroundTopP": request.top_p,
 
230
  "imageGenerationMode": False, # Added this line
231
  }
232
 
 
233
  async with httpx.AsyncClient() as client:
234
  try:
235
+ response = await client.post(
236
+ f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data, timeout=100
237
+ )
238
+ response.raise_for_status()
239
+
240
+ result = response.json()
241
+ content = result.get("choices", [{}])[0].get("text", "")
242
+ cleaned_content = remove_enclosed_content(content)
243
+ cleaned_content = strip_model_prefix(cleaned_content, model_prefix)
244
+ return {"choices": [{"text": cleaned_content}], "model": request.model}
245
  except httpx.HTTPStatusError as e:
246
  logger.error(f"HTTP error occurred for Request ID {request_id}: {e}")
247
  raise HTTPException(status_code=e.response.status_code, detail=str(e))
248
  except httpx.RequestError as e:
249
+ logger.error(f"Error occurred during request for Request ID {request_id}: {e}")
 
 
250
  raise HTTPException(status_code=500, detail=str(e))
251
 
252
+
253
  if full_response.startswith("$@$v=undefined-rv1$@$"):
254
  full_response = full_response[21:]
255