Niansuh commited on
Commit
b251981
·
verified ·
1 Parent(s): a2672b1

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +45 -221
main.py CHANGED
@@ -21,7 +21,7 @@ from pydantic import BaseModel
21
 
22
  # Configure logging
23
  logging.basicConfig(
24
- level=logging.INFO, # Set to DEBUG for more detailed logs
25
  format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
26
  handlers=[logging.StreamHandler()]
27
  )
@@ -237,6 +237,12 @@ class Blackbox:
237
  websearch: bool = False,
238
  **kwargs
239
  ) -> Union[str, ImageResponseModel]:
 
 
 
 
 
 
240
  model = cls.get_model(model)
241
  chat_id = cls.generate_random_string()
242
  next_action = cls.generate_next_action()
@@ -328,6 +334,7 @@ class Blackbox:
328
 
329
  async with ClientSession(headers=common_headers) as session:
330
  try:
 
331
  async with session.post(
332
  cls.api_endpoint,
333
  headers=headers_api_chat_combined,
@@ -336,12 +343,26 @@ class Blackbox:
336
  ) as response_api_chat:
337
  response_api_chat.raise_for_status()
338
  text = await response_api_chat.text()
339
- logger.debug(f"Raw response from Blackbox API: {text}") # Added logging
340
  cleaned_response = cls.clean_response(text)
341
- logger.debug(f"Cleaned response: {cleaned_response}") # Added logging
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
  if model in cls.image_models:
344
- match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', cleaned_response)
345
  if match:
346
  image_url = match.group(1)
347
  image_response = ImageResponseModel(images=image_url, alt="Generated Image")
@@ -349,13 +370,13 @@ class Blackbox:
349
  return image_response
350
  else:
351
  logger.debug("No image URL found in the response.") # Added logging
352
- return cleaned_response
353
  else:
354
  if websearch:
355
- match = re.search(r'\$~~~\$(.*?)\$~~~\$', cleaned_response, re.DOTALL)
356
  if match:
357
  source_part = match.group(1).strip()
358
- answer_part = cleaned_response[match.end():].strip()
359
  try:
360
  sources = json.loads(source_part)
361
  source_formatted = "**Source:**\n"
@@ -368,12 +389,12 @@ class Blackbox:
368
  except json.JSONDecodeError:
369
  final_response = f"{answer_part}\n\nSource information is unavailable."
370
  else:
371
- final_response = cleaned_response
372
  else:
373
- if '$~~~$' in cleaned_response:
374
- final_response = cleaned_response.split('$~~~$')[0].strip()
375
  else:
376
- final_response = cleaned_response
377
 
378
  logger.debug(f"Final response to return: {final_response}") # Added logging
379
  return final_response
@@ -391,31 +412,6 @@ class Blackbox:
391
  logger.exception(f"Unexpected error during /api/chat request: {str(e)}") # Added logging
392
  return f"Unexpected error during /api/chat request: {str(e)}"
393
 
394
- # The following block is unreachable due to the return statements above
395
- # It can be removed unless it's intended for future use
396
- chat_url = f'{cls.url}/chat/{chat_id}?model={model}'
397
-
398
- try:
399
- async with session.post(
400
- chat_url,
401
- headers=headers_chat_combined,
402
- data=data_chat,
403
- proxy=proxy
404
- ) as response_chat:
405
- response_chat.raise_for_status()
406
- pass
407
- except ClientResponseError as e:
408
- error_text = f"Error {e.status}: {e.message}"
409
- try:
410
- error_response = await e.response.text()
411
- cleaned_error = cls.clean_response(error_response)
412
- error_text += f" - {cleaned_error}"
413
- except Exception:
414
- pass
415
- return error_text
416
- except Exception as e:
417
- return f"Unexpected error during /chat/{chat_id} request: {str(e)}"
418
-
419
  @classmethod
420
  async def create_async_generator(
421
  cls,
@@ -427,194 +423,22 @@ class Blackbox:
427
  ) -> AsyncGenerator[Union[str, ImageResponseModel], None]:
428
  """
429
  Creates an asynchronous generator for streaming responses from Blackbox AI.
430
-
431
- Parameters:
432
- model (str): Model to use for generating responses.
433
- messages (List[Dict[str, str]]): Message history.
434
- proxy (Optional[str]): Proxy URL, if needed.
435
- websearch (bool): Enables or disables web search mode.
436
- **kwargs: Additional keyword arguments.
437
-
438
- Yields:
439
- Union[str, ImageResponseModel]: Segments of the generated response or ImageResponse objects.
440
  """
441
- model = cls.get_model(model)
442
- chat_id = cls.generate_random_string()
443
- next_action = cls.generate_next_action()
444
- next_router_state_tree = cls.generate_next_router_state_tree()
445
-
446
- agent_mode = cls.agentMode.get(model, {})
447
- trending_agent_mode = cls.trendingAgentMode.get(model, {})
448
-
449
- prefix = cls.model_prefixes.get(model, "")
450
-
451
- formatted_prompt = ""
452
- for message in messages:
453
- role = message.get('role', '').capitalize()
454
- content = message.get('content', '')
455
- if role and content:
456
- formatted_prompt += f"{role}: {content}\n"
457
-
458
- if prefix:
459
- formatted_prompt = f"{prefix} {formatted_prompt}".strip()
460
-
461
- referer_path = cls.model_referers.get(model, f"/?model={model}")
462
- referer_url = f"{cls.url}{referer_path}"
463
-
464
- common_headers = {
465
- 'accept': '*/*',
466
- 'accept-language': 'en-US,en;q=0.9',
467
- 'cache-control': 'no-cache',
468
- 'origin': cls.url,
469
- 'pragma': 'no-cache',
470
- 'priority': 'u=1, i',
471
- 'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
472
- 'sec-ch-ua-mobile': '?0',
473
- 'sec-ch-ua-platform': '"Linux"',
474
- 'sec-fetch-dest': 'empty',
475
- 'sec-fetch-mode': 'cors',
476
- 'sec-fetch-site': 'same-origin',
477
- 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) '
478
- 'AppleWebKit/537.36 (KHTML, like Gecko) '
479
- 'Chrome/129.0.0.0 Safari/537.36'
480
- }
481
-
482
- headers_api_chat = {
483
- 'Content-Type': 'application/json',
484
- 'Referer': referer_url
485
- }
486
- headers_api_chat_combined = {**common_headers, **headers_api_chat}
487
-
488
- payload_api_chat = {
489
- "messages": [
490
- {
491
- "id": chat_id,
492
- "content": formatted_prompt,
493
- "role": "user"
494
- }
495
- ],
496
- "id": chat_id,
497
- "previewToken": None,
498
- "userId": None,
499
- "codeModelMode": True,
500
- "agentMode": agent_mode,
501
- "trendingAgentMode": trending_agent_mode,
502
- "isMicMode": False,
503
- "userSystemPrompt": None,
504
- "maxTokens": 1024,
505
- "playgroundTopP": 0.9,
506
- "playgroundTemperature": 0.5,
507
- "isChromeExt": False,
508
- "githubToken": None,
509
- "clickedAnswer2": False,
510
- "clickedAnswer3": False,
511
- "clickedForceWebSearch": False,
512
- "visitFromDelta": False,
513
- "mobileClient": False,
514
- "webSearchMode": websearch,
515
- "userSelectedModel": cls.userSelectedModel.get(model, model)
516
- }
517
-
518
- headers_chat = {
519
- 'Accept': 'text/x-component',
520
- 'Content-Type': 'text/plain;charset=UTF-8',
521
- 'Referer': f'{cls.url}/chat/{chat_id}?model={model}',
522
- 'next-action': next_action,
523
- 'next-router-state-tree': next_router_state_tree,
524
- 'next-url': '/'
525
- }
526
- headers_chat_combined = {**common_headers, **headers_chat}
527
-
528
- data_chat = '[]'
529
-
530
- async with ClientSession(headers=common_headers) as session:
531
- try:
532
- async with session.post(
533
- cls.api_endpoint,
534
- headers=headers_api_chat_combined,
535
- json=payload_api_chat,
536
- proxy=proxy
537
- ) as response_api_chat:
538
- response_api_chat.raise_for_status()
539
- text = await response_api_chat.text()
540
- logger.debug(f"Raw response from Blackbox API: {text}") # Added logging
541
- cleaned_response = cls.clean_response(text)
542
- logger.debug(f"Cleaned response: {cleaned_response}") # Added logging
543
-
544
- if model in cls.image_models:
545
- match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', cleaned_response)
546
- if match:
547
- image_url = match.group(1)
548
- image_response = ImageResponseModel(images=image_url, alt="Generated Image")
549
- logger.debug(f"Image URL extracted: {image_url}") # Added logging
550
- yield image_response
551
- else:
552
- logger.debug("No image URL found in the response.") # Added logging
553
- yield cleaned_response
554
- else:
555
- if websearch:
556
- match = re.search(r'\$~~~\$(.*?)\$~~~\$', cleaned_response, re.DOTALL)
557
- if match:
558
- source_part = match.group(1).strip()
559
- answer_part = cleaned_response[match.end():].strip()
560
- try:
561
- sources = json.loads(source_part)
562
- source_formatted = "**Source:**\n"
563
- for item in sources:
564
- title = item.get('title', 'No Title')
565
- link = item.get('link', '#')
566
- position = item.get('position', '')
567
- source_formatted += f"{position}. [{title}]({link})\n"
568
- final_response = f"{answer_part}\n\n{source_formatted}"
569
- except json.JSONDecodeError:
570
- final_response = f"{answer_part}\n\nSource information is unavailable."
571
- else:
572
- final_response = cleaned_response
573
- else:
574
- if '$~~~$' in cleaned_response:
575
- final_response = cleaned_response.split('$~~~$')[0].strip()
576
- else:
577
- final_response = cleaned_response
578
-
579
- logger.debug(f"Final response to yield: {final_response}") # Added logging
580
- yield final_response
581
- except ClientResponseError as e:
582
- error_text = f"Error {e.status}: {e.message}"
583
- try:
584
- error_response = await e.response.text()
585
- cleaned_error = cls.clean_response(error_response)
586
- error_text += f" - {cleaned_error}"
587
- logger.error(f"ClientResponseError: {error_text}") # Added logging
588
- except Exception:
589
- pass
590
- yield error_text
591
- except Exception as e:
592
- yield f"Unexpected error during /api/chat request: {str(e)}"
593
-
594
- # The following block is unreachable due to the yield statements above
595
- # It can be removed unless it's intended for future use
596
- chat_url = f'{cls.url}/chat/{chat_id}?model={model}'
597
-
598
  try:
599
- async with session.post(
600
- chat_url,
601
- headers=headers_chat_combined,
602
- data=data_chat,
603
- proxy=proxy
604
- ) as response_chat:
605
- response_chat.raise_for_status()
606
- pass
607
- except ClientResponseError as e:
608
- error_text = f"Error {e.status}: {e.message}"
609
- try:
610
- error_response = await e.response.text()
611
- cleaned_error = cls.clean_response(error_response)
612
- error_text += f" - {cleaned_error}"
613
- except Exception:
614
- pass
615
- yield error_text
616
  except Exception as e:
617
- yield f"Unexpected error during /chat/{chat_id} request: {str(e)}"
 
618
 
619
  # ----------------------------- FastAPI App Setup -----------------------------
620
 
 
21
 
22
  # Configure logging
23
  logging.basicConfig(
24
+ level=logging.DEBUG, # Set to DEBUG for detailed logs; change to INFO in production
25
  format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
26
  handlers=[logging.StreamHandler()]
27
  )
 
237
  websearch: bool = False,
238
  **kwargs
239
  ) -> Union[str, ImageResponseModel]:
240
+ """
241
+ Generates a response by interacting with the Blackbox API.
242
+ Performs two POST requests:
243
+ 1. Initiates the chat and obtains a chat_id.
244
+ 2. Retrieves the chat response using the chat_id.
245
+ """
246
  model = cls.get_model(model)
247
  chat_id = cls.generate_random_string()
248
  next_action = cls.generate_next_action()
 
334
 
335
  async with ClientSession(headers=common_headers) as session:
336
  try:
337
+ # First POST request to initiate the chat and get chat_id
338
  async with session.post(
339
  cls.api_endpoint,
340
  headers=headers_api_chat_combined,
 
343
  ) as response_api_chat:
344
  response_api_chat.raise_for_status()
345
  text = await response_api_chat.text()
346
+ logger.debug(f"Raw response from Blackbox API (initiate chat): {text}") # Added logging
347
  cleaned_response = cls.clean_response(text)
348
+ logger.debug(f"Cleaned response (initiate chat): {cleaned_response}") # Added logging
349
+
350
+ # Second POST request to retrieve the chat response using chat_id
351
+ chat_url = f'{cls.url}/chat/{chat_id}?model={model}'
352
+ async with session.post(
353
+ chat_url,
354
+ headers=headers_chat_combined,
355
+ data=data_chat,
356
+ proxy=proxy
357
+ ) as response_chat:
358
+ response_chat.raise_for_status()
359
+ chat_response_text = await response_chat.text()
360
+ logger.debug(f"Raw response from Blackbox API (retrieve chat): {chat_response_text}") # Added logging
361
+ cleaned_chat_response = cls.clean_response(chat_response_text)
362
+ logger.debug(f"Cleaned response (retrieve chat): {cleaned_chat_response}") # Added logging
363
 
364
  if model in cls.image_models:
365
+ match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', cleaned_chat_response)
366
  if match:
367
  image_url = match.group(1)
368
  image_response = ImageResponseModel(images=image_url, alt="Generated Image")
 
370
  return image_response
371
  else:
372
  logger.debug("No image URL found in the response.") # Added logging
373
+ return cleaned_chat_response
374
  else:
375
  if websearch:
376
+ match = re.search(r'\$~~~\$(.*?)\$~~~\$', cleaned_chat_response, re.DOTALL)
377
  if match:
378
  source_part = match.group(1).strip()
379
+ answer_part = cleaned_chat_response[match.end():].strip()
380
  try:
381
  sources = json.loads(source_part)
382
  source_formatted = "**Source:**\n"
 
389
  except json.JSONDecodeError:
390
  final_response = f"{answer_part}\n\nSource information is unavailable."
391
  else:
392
+ final_response = cleaned_chat_response
393
  else:
394
+ if '$~~~$' in cleaned_chat_response:
395
+ final_response = cleaned_chat_response.split('$~~~$')[0].strip()
396
  else:
397
+ final_response = cleaned_chat_response
398
 
399
  logger.debug(f"Final response to return: {final_response}") # Added logging
400
  return final_response
 
412
  logger.exception(f"Unexpected error during /api/chat request: {str(e)}") # Added logging
413
  return f"Unexpected error during /api/chat request: {str(e)}"
414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  @classmethod
416
  async def create_async_generator(
417
  cls,
 
423
  ) -> AsyncGenerator[Union[str, ImageResponseModel], None]:
424
  """
425
  Creates an asynchronous generator for streaming responses from Blackbox AI.
 
 
 
 
 
 
 
 
 
 
426
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  try:
428
+ response = await cls.generate_response(
429
+ model=model,
430
+ messages=messages,
431
+ proxy=proxy,
432
+ websearch=websearch,
433
+ **kwargs
434
+ )
435
+ if isinstance(response, ImageResponseModel):
436
+ yield response
437
+ else:
438
+ yield response
 
 
 
 
 
 
439
  except Exception as e:
440
+ logger.exception(f"Error in create_async_generator: {str(e)}")
441
+ yield f"Unexpected error: {str(e)}"
442
 
443
  # ----------------------------- FastAPI App Setup -----------------------------
444