Upload 12 files
Browse files- api/config.py +4 -32
- api/models.py +0 -3
- api/routes.py +1 -12
- api/utils.py +17 -51
api/config.py
CHANGED
@@ -3,7 +3,7 @@ from dotenv import load_dotenv
|
|
3 |
|
4 |
load_dotenv()
|
5 |
|
6 |
-
BASE_URL = "https://
|
7 |
common_headers = {
|
8 |
'accept': '*/*',
|
9 |
'accept-language': 'en-US,en;q=0.9',
|
@@ -231,6 +231,7 @@ ALLOWED_MODELS = [
|
|
231 |
{"id": "mistralai/mistral-nemo", "name": "mistralai/mistral-nemo" },
|
232 |
{"id": "mistralai/codestral-mamba", "name": "mistralai/codestral-mamba" },
|
233 |
{"id": "x-ai/grok-vision-beta", "name": "x-ai/grok-vision-beta" },
|
|
|
234 |
]
|
235 |
|
236 |
MODEL_MAPPING = {
|
@@ -402,12 +403,14 @@ MODEL_MAPPING = {
|
|
402 |
"mistralai/mistral-nemo": "mistralai/mistral-nemo",
|
403 |
"mistralai/codestral-mamba": "mistralai/codestral-mamba",
|
404 |
"x-ai/grok-vision-beta": "x-ai/grok-vision-beta",
|
|
|
405 |
|
406 |
}
|
407 |
|
408 |
# Agent modes
|
409 |
AGENT_MODE = {
|
410 |
'claude-sonnet-3.5': {'mode': True, 'id': "claude-sonnet-3.5", 'name': "claude-sonnet-3.5"},
|
|
|
411 |
'flux': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "flux"},
|
412 |
'gpt-4o': {'mode': True, 'id': "GPT-4o", 'name': "GPT-4o"},
|
413 |
'Llama-4-Maverick-17B-128E': {'mode': True, 'id': "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", 'name': "Llama-4-Maverick-17B-128E"},
|
@@ -523,37 +526,6 @@ TRENDING_AGENT_MODE = {
|
|
523 |
|
524 |
# Model prefixes
|
525 |
MODEL_PREFIXES = {
|
526 |
-
'PythonAgent': '@python',
|
527 |
-
'JavaAgent': '@java',
|
528 |
-
'JavaScriptAgent': '@javascript',
|
529 |
-
'HTMLAgent': '@html',
|
530 |
-
'GoogleCloudAgent': '@googlecloud',
|
531 |
-
'AndroidDeveloper': '@android',
|
532 |
-
'SwiftDeveloper': '@swift',
|
533 |
-
'Next.jsAgent': '@next.js',
|
534 |
-
'MongoDBAgent': '@mongodb',
|
535 |
-
'PyTorchAgent': '@pytorch',
|
536 |
-
'ReactAgent': '@react',
|
537 |
-
'XcodeAgent': '@xcode',
|
538 |
-
'AngularJSAgent': '@angularjs',
|
539 |
-
'HerokuAgent': '@heroku',
|
540 |
-
'GodotAgent': '@godot',
|
541 |
-
'GoAgent': '@go',
|
542 |
-
'GitlabAgent': '@gitlab',
|
543 |
-
'GitAgent': '@git',
|
544 |
-
'blackboxai-pro': '@blackboxai-pro',
|
545 |
-
'FlaskAgent': '@flask',
|
546 |
-
'FirebaseAgent': '@firebase',
|
547 |
-
'FastAPIAgent': '@fastapi',
|
548 |
-
'ErlangAgent': '@erlang',
|
549 |
-
'ElectronAgent': '@electron',
|
550 |
-
'DockerAgent': '@docker',
|
551 |
-
'DigitalOceanAgent': '@digitalocean',
|
552 |
-
'BitbucketAgent': '@bitbucket',
|
553 |
-
'AzureAgent': '@azure',
|
554 |
-
'FlutterAgent': '@flutter',
|
555 |
-
'YoutubeAgent': '@youtube',
|
556 |
-
'builderAgent': '@builder',
|
557 |
}
|
558 |
|
559 |
# Model referers
|
|
|
3 |
|
4 |
load_dotenv()
|
5 |
|
6 |
+
BASE_URL = "https://www.blackbox.ai"
|
7 |
common_headers = {
|
8 |
'accept': '*/*',
|
9 |
'accept-language': 'en-US,en;q=0.9',
|
|
|
231 |
{"id": "mistralai/mistral-nemo", "name": "mistralai/mistral-nemo" },
|
232 |
{"id": "mistralai/codestral-mamba", "name": "mistralai/codestral-mamba" },
|
233 |
{"id": "x-ai/grok-vision-beta", "name": "x-ai/grok-vision-beta" },
|
234 |
+
{"id": "Claude-3.7", "name": "Claude-3.7" },
|
235 |
]
|
236 |
|
237 |
MODEL_MAPPING = {
|
|
|
403 |
"mistralai/mistral-nemo": "mistralai/mistral-nemo",
|
404 |
"mistralai/codestral-mamba": "mistralai/codestral-mamba",
|
405 |
"x-ai/grok-vision-beta": "x-ai/grok-vision-beta",
|
406 |
+
"Claude-3.7": "Claude-3.7",
|
407 |
|
408 |
}
|
409 |
|
410 |
# Agent modes
|
411 |
AGENT_MODE = {
|
412 |
'claude-sonnet-3.5': {'mode': True, 'id': "claude-sonnet-3.5", 'name': "claude-sonnet-3.5"},
|
413 |
+
'Claude-3.7': {'mode': True, 'id': "Claude-3.7mzvq9k0", 'name': "Claude-3.7"},
|
414 |
'flux': {'mode': True, 'id': "ImageGenerationLV45LJp", 'name': "flux"},
|
415 |
'gpt-4o': {'mode': True, 'id': "GPT-4o", 'name': "GPT-4o"},
|
416 |
'Llama-4-Maverick-17B-128E': {'mode': True, 'id': "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", 'name': "Llama-4-Maverick-17B-128E"},
|
|
|
526 |
|
527 |
# Model prefixes
|
528 |
MODEL_PREFIXES = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
529 |
}
|
530 |
|
531 |
# Model referers
|
api/models.py
CHANGED
@@ -12,6 +12,3 @@ class ChatRequest(BaseModel):
|
|
12 |
temperature: Optional[float] = 0.5
|
13 |
top_p: Optional[float] = 0.9
|
14 |
max_tokens: Optional[int] = 1024
|
15 |
-
function_call: Optional[bool] = False
|
16 |
-
function_call_details: Optional[dict] = None
|
17 |
-
tools: Optional[List[Dict]] = None
|
|
|
12 |
temperature: Optional[float] = 0.5
|
13 |
top_p: Optional[float] = 0.9
|
14 |
max_tokens: Optional[int] = 1024
|
|
|
|
|
|
api/routes.py
CHANGED
@@ -49,11 +49,6 @@ async def chat_completions(
|
|
49 |
logger.info("Non-streaming response")
|
50 |
return await process_non_streaming_response(request)
|
51 |
|
52 |
-
# New function calling logic
|
53 |
-
if request.function_call:
|
54 |
-
logger.info("Handling function call")
|
55 |
-
return await handle_function_call(request)
|
56 |
-
|
57 |
@router.route('/us/')
|
58 |
@router.route('/us/healthz')
|
59 |
@router.route('/us/ready')
|
@@ -68,10 +63,4 @@ def health_check(request: Request):
|
|
68 |
}),
|
69 |
media_type="application/json",
|
70 |
status_code=421 # Changing the status code to 421
|
71 |
-
)
|
72 |
-
|
73 |
-
async def handle_function_call(request: ChatRequest):
|
74 |
-
# Placeholder for function calling logic
|
75 |
-
logger.info("Handling function call for model: {}".format(request.model))
|
76 |
-
logger.info("Function call details: {}".format(request.function_call_details))
|
77 |
-
return {"message": "Function call handled successfully", "details": request.function_call_details}
|
|
|
49 |
logger.info("Non-streaming response")
|
50 |
return await process_non_streaming_response(request)
|
51 |
|
|
|
|
|
|
|
|
|
|
|
52 |
@router.route('/us/')
|
53 |
@router.route('/us/healthz')
|
54 |
@router.route('/us/ready')
|
|
|
63 |
}),
|
64 |
media_type="application/json",
|
65 |
status_code=421 # Changing the status code to 421
|
66 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
api/utils.py
CHANGED
@@ -62,8 +62,8 @@ def get_random_name_email_customer():
|
|
62 |
Generate a random name, email, and customer ID.
|
63 |
The customer ID keeps the same length format as 'cus_Rldf7IKdNhdhiw'.
|
64 |
"""
|
65 |
-
first_names = ["
|
66 |
-
last_names = ["
|
67 |
|
68 |
random_name = f"{random.choice(first_names)} {random.choice(last_names)}"
|
69 |
email_username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
@@ -147,7 +147,6 @@ def create_chat_completion_data(
|
|
147 |
prompt_tokens: int = 0,
|
148 |
completion_tokens: int = 0,
|
149 |
finish_reason: Optional[str] = None,
|
150 |
-
function_call: Optional[Dict] = None,
|
151 |
) -> Dict[str, Any]:
|
152 |
usage = None
|
153 |
if finish_reason == "stop":
|
@@ -162,28 +161,15 @@ def create_chat_completion_data(
|
|
162 |
"created": timestamp,
|
163 |
"model": model,
|
164 |
"system_fingerprint": system_fingerprint,
|
165 |
-
"choices": [{
|
166 |
-
"index": 0,
|
167 |
-
"delta": {
|
168 |
-
"content": content if not function_call else None,
|
169 |
-
"role": "assistant",
|
170 |
-
"function_call": function_call
|
171 |
-
},
|
172 |
-
"finish_reason": finish_reason
|
173 |
-
}],
|
174 |
"usage": usage,
|
175 |
}
|
176 |
|
177 |
-
|
178 |
-
# Placeholder for function calling logic
|
179 |
-
logger.info(f"Handling function call for model: {request.model}")
|
180 |
-
logger.info(f"Function call details: {function_call_details}")
|
181 |
-
return {"message": "Function call handled successfully", "details": function_call_details}
|
182 |
-
|
183 |
-
def message_to_dict(message, model_prefix: Optional[str] = None, tools: Optional[List[Dict]] = None) -> Dict[str, Any]:
|
184 |
"""
|
185 |
Convert a ChatRequest message to a dict for the request payload.
|
186 |
-
Supports
|
|
|
187 |
"""
|
188 |
content = ""
|
189 |
images_data = []
|
@@ -256,12 +242,13 @@ async def process_streaming_response(request: ChatRequest):
|
|
256 |
logger.error("No h-value for validation.")
|
257 |
raise HTTPException(status_code=500, detail="Missing h-value.")
|
258 |
|
259 |
-
messages = [message_to_dict(msg, model_prefix=model_prefix
|
260 |
|
261 |
json_data = {
|
262 |
"agentMode": agent_mode,
|
263 |
"clickedAnswer2": False,
|
264 |
"clickedAnswer3": False,
|
|
|
265 |
"clickedForceWebSearch": False,
|
266 |
"codeInterpreterMode": False,
|
267 |
"codeModelMode": True,
|
@@ -288,16 +275,15 @@ async def process_streaming_response(request: ChatRequest):
|
|
288 |
"visitFromDelta": False,
|
289 |
"webSearchModePrompt": False,
|
290 |
"vscodeClient": False,
|
|
|
|
|
|
|
291 |
"customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
|
292 |
"webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
|
293 |
"session": {
|
294 |
"user": {"name": random_name, "email": random_email, "image": "https://lh3.googleusercontent.com/a/...=s96-c", "subscriptionStatus": "PREMIUM"},
|
295 |
"expires": datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'),
|
296 |
"subscriptionCache": {"customerId": random_customer_id, "status": "PREMIUM", "isTrialSubscription": "False", "expiryTimestamp": 1744652408, "lastChecked": int(time.time() * 1000)},
|
297 |
-
"beastMode": False,
|
298 |
-
"reasoningMode": False,
|
299 |
-
"designerMode": False,
|
300 |
-
"workspaceId": "",
|
301 |
},
|
302 |
}
|
303 |
|
@@ -334,27 +320,7 @@ async def process_streaming_response(request: ChatRequest):
|
|
334 |
final_snapzion_links.extend(snapzion_urls)
|
335 |
cleaned_content = strip_model_prefix(chunk, model_prefix)
|
336 |
completion_tokens += calculate_tokens(cleaned_content, request.model)
|
337 |
-
|
338 |
-
# Handle function call responses
|
339 |
-
function_call = None
|
340 |
-
if cleaned_content and cleaned_content.startswith("{"):
|
341 |
-
try:
|
342 |
-
function_call = json.loads(cleaned_content)
|
343 |
-
cleaned_content = None # Content must be null for function calls
|
344 |
-
except json.JSONDecodeError:
|
345 |
-
pass
|
346 |
-
|
347 |
-
yield "data: " + json.dumps(create_chat_completion_data(
|
348 |
-
cleaned_content,
|
349 |
-
request.model,
|
350 |
-
timestamp,
|
351 |
-
request_id,
|
352 |
-
system_fingerprint,
|
353 |
-
prompt_tokens,
|
354 |
-
completion_tokens,
|
355 |
-
finish_reason=None,
|
356 |
-
function_call=function_call
|
357 |
-
)) + "\n\n"
|
358 |
yield "data: " + json.dumps(create_chat_completion_data("", request.model, timestamp, request_id, system_fingerprint, prompt_tokens, completion_tokens, "stop")) + "\n\n"
|
359 |
yield "data: [DONE]\n\n"
|
360 |
except httpx.HTTPStatusError as e:
|
@@ -408,12 +374,13 @@ async def process_non_streaming_response(request: ChatRequest):
|
|
408 |
logger.error("Failed to retrieve h-value.")
|
409 |
raise HTTPException(status_code=500, detail="Missing h-value.")
|
410 |
|
411 |
-
messages = [message_to_dict(msg, model_prefix=model_prefix
|
412 |
|
413 |
json_data = {
|
414 |
"agentMode": agent_mode,
|
415 |
"clickedAnswer2": False,
|
416 |
"clickedAnswer3": False,
|
|
|
417 |
"clickedForceWebSearch": False,
|
418 |
"codeInterpreterMode": False,
|
419 |
"codeModelMode": True,
|
@@ -440,16 +407,15 @@ async def process_non_streaming_response(request: ChatRequest):
|
|
440 |
"visitFromDelta": False,
|
441 |
"webSearchModePrompt": False,
|
442 |
"vscodeClient": False,
|
|
|
|
|
|
|
443 |
"customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
|
444 |
"webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
|
445 |
"session": {
|
446 |
"user": {"name": random_name, "email": random_email, "image": "https://lh3.googleusercontent.com/a/...=s96-c", "subscriptionStatus": "PREMIUM"},
|
447 |
"expires": datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'),
|
448 |
"subscriptionCache": {"customerId": random_customer_id, "status": "PREMIUM", "isTrialSubscription": "False", "expiryTimestamp": 1744652408, "lastChecked": int(time.time() * 1000)},
|
449 |
-
"beastMode": False,
|
450 |
-
"reasoningMode": False,
|
451 |
-
"designerMode": False,
|
452 |
-
"workspaceId": "",
|
453 |
},
|
454 |
}
|
455 |
|
|
|
62 |
Generate a random name, email, and customer ID.
|
63 |
The customer ID keeps the same length format as 'cus_Rldf7IKdNhdhiw'.
|
64 |
"""
|
65 |
+
first_names = ["Aliace", "B21ob", "Car232ol", "Daavid", "Evewwlyn", "Fraank", "Grssace", "Hefctor", "Ivgy", "Jackdie"]
|
66 |
+
last_names = ["Smilth", "Johnkson", "Dajvis", "Mihller", "Thomgpson", "Garwcia", "Broawn", "Wilfson", "Maartin", "Clarak"]
|
67 |
|
68 |
random_name = f"{random.choice(first_names)} {random.choice(last_names)}"
|
69 |
email_username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
|
|
147 |
prompt_tokens: int = 0,
|
148 |
completion_tokens: int = 0,
|
149 |
finish_reason: Optional[str] = None,
|
|
|
150 |
) -> Dict[str, Any]:
|
151 |
usage = None
|
152 |
if finish_reason == "stop":
|
|
|
161 |
"created": timestamp,
|
162 |
"model": model,
|
163 |
"system_fingerprint": system_fingerprint,
|
164 |
+
"choices": [{"index": 0, "delta": {"content": content, "role": "assistant"}, "finish_reason": finish_reason}],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
"usage": usage,
|
166 |
}
|
167 |
|
168 |
+
def message_to_dict(message, model_prefix: Optional[str] = None):
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
"""
|
170 |
Convert a ChatRequest message to a dict for the request payload.
|
171 |
+
Supports up to three images with type-based structure and sends multiple formats.
|
172 |
+
Prepends model_prefix to text content if specified.
|
173 |
"""
|
174 |
content = ""
|
175 |
images_data = []
|
|
|
242 |
logger.error("No h-value for validation.")
|
243 |
raise HTTPException(status_code=500, detail="Missing h-value.")
|
244 |
|
245 |
+
messages = [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages]
|
246 |
|
247 |
json_data = {
|
248 |
"agentMode": agent_mode,
|
249 |
"clickedAnswer2": False,
|
250 |
"clickedAnswer3": False,
|
251 |
+
"reasoningMode": False,
|
252 |
"clickedForceWebSearch": False,
|
253 |
"codeInterpreterMode": False,
|
254 |
"codeModelMode": True,
|
|
|
275 |
"visitFromDelta": False,
|
276 |
"webSearchModePrompt": False,
|
277 |
"vscodeClient": False,
|
278 |
+
"designerMode": False,
|
279 |
+
"workspaceId": "",
|
280 |
+
"beastMode": False,
|
281 |
"customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
|
282 |
"webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
|
283 |
"session": {
|
284 |
"user": {"name": random_name, "email": random_email, "image": "https://lh3.googleusercontent.com/a/...=s96-c", "subscriptionStatus": "PREMIUM"},
|
285 |
"expires": datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'),
|
286 |
"subscriptionCache": {"customerId": random_customer_id, "status": "PREMIUM", "isTrialSubscription": "False", "expiryTimestamp": 1744652408, "lastChecked": int(time.time() * 1000)},
|
|
|
|
|
|
|
|
|
287 |
},
|
288 |
}
|
289 |
|
|
|
320 |
final_snapzion_links.extend(snapzion_urls)
|
321 |
cleaned_content = strip_model_prefix(chunk, model_prefix)
|
322 |
completion_tokens += calculate_tokens(cleaned_content, request.model)
|
323 |
+
yield "data: " + json.dumps(create_chat_completion_data(cleaned_content, request.model, timestamp, request_id, system_fingerprint, prompt_tokens, completion_tokens)) + "\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
yield "data: " + json.dumps(create_chat_completion_data("", request.model, timestamp, request_id, system_fingerprint, prompt_tokens, completion_tokens, "stop")) + "\n\n"
|
325 |
yield "data: [DONE]\n\n"
|
326 |
except httpx.HTTPStatusError as e:
|
|
|
374 |
logger.error("Failed to retrieve h-value.")
|
375 |
raise HTTPException(status_code=500, detail="Missing h-value.")
|
376 |
|
377 |
+
messages = [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages]
|
378 |
|
379 |
json_data = {
|
380 |
"agentMode": agent_mode,
|
381 |
"clickedAnswer2": False,
|
382 |
"clickedAnswer3": False,
|
383 |
+
"reasoningMode": False,
|
384 |
"clickedForceWebSearch": False,
|
385 |
"codeInterpreterMode": False,
|
386 |
"codeModelMode": True,
|
|
|
407 |
"visitFromDelta": False,
|
408 |
"webSearchModePrompt": False,
|
409 |
"vscodeClient": False,
|
410 |
+
"designerMode": False,
|
411 |
+
"workspaceId": "",
|
412 |
+
"beastMode": False,
|
413 |
"customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
|
414 |
"webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
|
415 |
"session": {
|
416 |
"user": {"name": random_name, "email": random_email, "image": "https://lh3.googleusercontent.com/a/...=s96-c", "subscriptionStatus": "PREMIUM"},
|
417 |
"expires": datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'),
|
418 |
"subscriptionCache": {"customerId": random_customer_id, "status": "PREMIUM", "isTrialSubscription": "False", "expiryTimestamp": 1744652408, "lastChecked": int(time.time() * 1000)},
|
|
|
|
|
|
|
|
|
419 |
},
|
420 |
}
|
421 |
|