rkihacker commited on
Commit
e8c8604
·
verified ·
1 Parent(s): e0ff141

Update api/utils.py

Browse files
Files changed (1) hide show
  1. api/utils.py +116 -115
api/utils.py CHANGED
@@ -37,8 +37,6 @@ R2_ACCESS_KEY_ID = "df9c9eb87e850a8eb27afd3968077b42"
37
  R2_SECRET_ACCESS_KEY = "14b08b0855263bb63d2618da3a6537e1b0446d89d51da03a568620b1e5342ea8"
38
  R2_ENDPOINT_URL = "https://f2f92ac53fae792c4155f6e93a514989.r2.cloudflarestorage.com"
39
  R2_BUCKET_NAME = "snapzion"
40
-
41
- # We always store replaced URLs in one file named snapzion.txt
42
  R2_REPLACED_URLS_KEY = "snapzion.txt"
43
 
44
  s3 = boto3.client(
@@ -48,7 +46,6 @@ s3 = boto3.client(
48
  aws_secret_access_key=R2_SECRET_ACCESS_KEY,
49
  )
50
 
51
- # Example blocked message
52
  BLOCKED_MESSAGE = (
53
  "Generated by BLACKBOX.AI, try unlimited chat https://www.blackbox.ai "
54
  "and for API requests replace https://www.blackbox.ai with https://api.blackbox.ai"
@@ -58,15 +55,12 @@ BLOCKED_MESSAGE = (
58
  # RANDOM USER-DATA & SESSION GENERATION
59
  # ---------------------------------------------
60
  def get_random_name_email_customer():
61
- """
62
- Generate a random name, email, and customer ID.
63
- """
64
  first_names = ["Aliace", "B21ob", "Car232ol", "Daavid", "Evewwlyn", "Fraank", "Grssace", "Hefctor", "Ivgy", "Jackdie"]
65
  last_names = ["Smilth", "Johnkson", "Dajvis", "Mihller", "Thomgpson", "Garwcia", "Broawn", "Wilfson", "Maartin", "Clarak"]
66
 
67
  random_name = f"{random.choice(first_names)} {random.choice(last_names)}"
68
  email_username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
69
- random_email = f"{email_username}@blackbox.ai"
70
  suffix_length = len("Rldf7IKdNhdhiw")
71
  suffix_chars = string.ascii_letters + string.digits
72
  random_suffix = ''.join(random.choice(suffix_chars) for _ in range(suffix_length))
@@ -75,9 +69,6 @@ def get_random_name_email_customer():
75
  return random_name, random_email, random_customer_id
76
 
77
  def generate_session(email: str, id_length: int = 21, days_ahead: int = 365) -> dict:
78
- """
79
- Mirror the normal provider logic to generate session IDs and expiry.
80
- """
81
  numeric_id = ''.join(random.choice('0123456789') for _ in range(id_length))
82
  future_date = datetime.now(timezone.utc) + timedelta(days=days_ahead)
83
  expiry = future_date.isoformat(timespec='milliseconds').replace('+00:00', 'Z')
@@ -88,7 +79,7 @@ def generate_session(email: str, id_length: int = 21, days_ahead: int = 365) ->
88
 
89
  return {
90
  "user": {
91
- "name": "BLACKBOX.AI",
92
  "email": email,
93
  "image": image_url,
94
  "id": numeric_id
@@ -98,9 +89,6 @@ def generate_session(email: str, id_length: int = 21, days_ahead: int = 365) ->
98
  }
99
 
100
  def generate_session_data() -> dict:
101
- """
102
- Generate a complete session data object with random email.
103
- """
104
  _, email, _ = get_random_name_email_customer()
105
  session_data = generate_session(email)
106
  logger.info(f"Using generated session with email {email}")
@@ -110,8 +98,8 @@ def generate_session_data() -> dict:
110
  # HELPER FUNCTIONS
111
  # ---------------------------------------------
112
  def generate_system_fingerprint() -> str:
113
- raw_data = f"{platform.node()}-{time.time()}-{uuid.uuid4()}"
114
- short_hash = hashlib.md5(raw_data.encode()).hexdigest()[:12]
115
  return f"fp_{short_hash}"
116
 
117
  def get_last_user_prompt(messages: List[Any]) -> str:
@@ -127,37 +115,36 @@ def get_last_user_prompt(messages: List[Any]) -> str:
127
 
128
  def upload_replaced_urls_to_r2(urls: List[str], alt_text: str = "") -> None:
129
  if not urls:
130
- logger.info("No replaced or final Snapzion URLs to store. Skipping snapzion.txt update.")
131
  return
132
- existing_data = ""
133
  try:
134
- response = s3.get_object(Bucket=R2_BUCKET_NAME, Key=R2_REPLACED_URLS_KEY)
135
- existing_data = response['Body'].read().decode('utf-8')
136
- logger.info("Successfully read existing snapzion.txt from R2.")
137
  except s3.exceptions.NoSuchKey:
138
- logger.info("snapzion.txt does not exist yet. Will create a new one.")
139
  except Exception as e:
140
- logger.error(f"Error reading snapzion.txt from R2: {e}")
141
- markdown_lines = [f"![{alt_text}]({url})" for url in urls]
142
- to_append = "\n".join(markdown_lines)
143
- updated_content = (existing_data + "\n" + to_append) if existing_data.strip() else to_append
 
144
  try:
145
  s3.put_object(
146
  Bucket=R2_BUCKET_NAME,
147
  Key=R2_REPLACED_URLS_KEY,
148
- Body=updated_content.encode("utf-8"),
149
  ContentType="text/plain",
150
  )
151
- logger.info(f"Appended {len(urls)} new URLs to snapzion.txt in R2 (in Markdown format).")
152
  except Exception as e:
153
- logger.error(f"Failed to upload replaced URLs to R2: {e}")
154
 
155
  def calculate_tokens(text: str, model: str) -> int:
156
  try:
157
- encoding = tiktoken.encoding_for_model(model)
158
- return len(encoding.encode(text))
159
- except KeyError:
160
- logger.warning(f"Model '{model}' not supported by tiktoken for token counting. Using a generic method.")
161
  return len(text.split())
162
 
163
  def create_chat_completion_data(
@@ -188,13 +175,47 @@ def create_chat_completion_data(
188
  }
189
 
190
  def message_to_dict(message, model_prefix: Optional[str] = None):
191
- # ... existing implementation ...
192
- # unchanged from your original code for handling content/images ...
193
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
  def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
196
  if model_prefix and content.startswith(model_prefix):
197
- logger.debug(f"Stripping prefix '{model_prefix}' from content.")
198
  return content[len(model_prefix):].strip()
199
  return content
200
 
@@ -202,27 +223,23 @@ def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
202
  # STREAMING RESPONSE HANDLER
203
  # ---------------------------------------------
204
  async def process_streaming_response(request: ChatRequest):
205
- system_fingerprint = generate_system_fingerprint()
206
  request_id = f"chatcmpl-{uuid.uuid4()}"
207
- logger.info(f"Processing request (stream) {request_id} - Model: {request.model}")
208
 
209
  agent_mode = AGENT_MODE.get(request.model, {})
210
- trending_agent_mode = TRENDING_AGENT_MODE.get(request.model, {})
211
- model_prefix = MODEL_PREFIXES.get(request.model, "")
212
-
213
- headers_api_chat = get_headers_api_chat(BASE_URL)
214
 
 
215
  if request.model == "o1-preview":
216
- delay_seconds = random.randint(1, 60)
217
- logger.info(f"Delay {delay_seconds}s for model 'o1-preview' (Request: {request_id})")
218
- await asyncio.sleep(delay_seconds)
219
 
220
- h_value = await getHid()
221
- if not h_value:
222
- logger.error("No h-value for validation.")
223
  raise HTTPException(status_code=500, detail="Missing h-value.")
224
 
225
- messages = [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages]
226
 
227
  json_data = {
228
  "agentMode": agent_mode,
@@ -242,16 +259,16 @@ async def process_streaming_response(request: ChatRequest):
242
  "isPremium": True,
243
  "isMemoryEnabled": False,
244
  "maxTokens": request.max_tokens,
245
- "messages": messages,
246
  "mobileClient": False,
247
  "playgroundTemperature": request.temperature,
248
  "playgroundTopP": request.top_p,
249
  "previewToken": None,
250
- "trendingAgentMode": trending_agent_mode,
251
  "userId": None,
252
  "userSelectedModel": MODEL_MAPPING.get(request.model, request.model),
253
  "userSystemPrompt": None,
254
- "validated": h_value,
255
  "visitFromDelta": False,
256
  "webSearchModePrompt": False,
257
  "vscodeClient": False,
@@ -264,19 +281,19 @@ async def process_streaming_response(request: ChatRequest):
264
  }
265
 
266
  prompt_tokens = sum(
267
- calculate_tokens(msg.get("content", ""), request.model) +
268
- sum(calculate_tokens(img["contents"], request.model) for img in msg.get("data", {}).get("imagesData", []))
269
- for msg in messages
270
  )
271
 
272
  completion_tokens = 0
273
- final_snapzion_links: List[str] = []
274
 
275
  async with httpx.AsyncClient() as client:
276
  try:
277
- async with client.stream("POST", f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data, timeout=100) as response:
278
- response.raise_for_status()
279
- async for chunk in response.aiter_text():
280
  if not chunk:
281
  continue
282
  if chunk.startswith("$@$v=undefined-rv1$@$"):
@@ -285,59 +302,48 @@ async def process_streaming_response(request: ChatRequest):
285
  chunk = chunk.replace(BLOCKED_MESSAGE, "").strip()
286
  if not chunk:
287
  continue
288
- if "https://storage.googleapis.com" in chunk:
289
- chunk = chunk.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
290
- snapzion_urls = re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", chunk)
291
- final_snapzion_links.extend(snapzion_urls)
292
- cleaned = strip_model_prefix(chunk, model_prefix)
293
- completion_tokens += calculate_tokens(cleaned, request.model)
294
- timestamp = int(datetime.now().timestamp())
295
  yield "data: " + json.dumps(
296
- create_chat_completion_data(cleaned, request.model, timestamp, request_id, system_fingerprint, prompt_tokens, completion_tokens)
297
  ) + "\n\n"
298
 
299
- # send final stop
300
- timestamp = int(datetime.now().timestamp())
301
  yield "data: " + json.dumps(
302
- create_chat_completion_data("", request.model, timestamp, request_id, system_fingerprint, prompt_tokens, completion_tokens, "stop")
303
  ) + "\n\n"
304
  yield "data: [DONE]\n\n"
305
 
306
- except httpx.HTTPStatusError as e:
307
- # handle HTTP error...
308
- pass
309
  except Exception as e:
310
- # handle other errors...
311
- pass
312
-
313
- upload_replaced_urls_to_r2(final_snapzion_links, alt_text=get_last_user_prompt(request.messages))
314
 
 
315
 
316
  # ---------------------------------------------
317
  # NON-STREAMING RESPONSE HANDLER
318
  # ---------------------------------------------
319
  async def process_non_streaming_response(request: ChatRequest):
320
- system_fingerprint = generate_system_fingerprint()
321
  request_id = f"chatcmpl-{uuid.uuid4()}"
322
- logger.info(f"Processing request (non-stream) {request_id} - Model: {request.model}")
323
 
324
  agent_mode = AGENT_MODE.get(request.model, {})
325
- trending_agent_mode = TRENDING_AGENT_MODE.get(request.model, {})
326
- model_prefix = MODEL_PREFIXES.get(request.model, "")
327
-
328
- headers_api_chat = get_headers_api_chat(BASE_URL)
329
 
 
330
  if request.model == "o1-preview":
331
- delay_seconds = random.randint(20, 60)
332
- logger.info(f"Delay {delay_seconds}s for 'o1-preview' (Request: {request_id})")
333
- await asyncio.sleep(delay_seconds)
334
 
335
- h_value = await getHid()
336
- if not h_value:
337
- logger.error("Failed to retrieve h-value.")
338
  raise HTTPException(status_code=500, detail="Missing h-value.")
339
 
340
- messages = [message_to_dict(msg, model_prefix=model_prefix) for msg in request.messages]
341
 
342
  json_data = {
343
  "agentMode": agent_mode,
@@ -357,16 +363,16 @@ async def process_non_streaming_response(request: ChatRequest):
357
  "isPremium": True,
358
  "isMemoryEnabled": False,
359
  "maxTokens": request.max_tokens,
360
- "messages": messages,
361
  "mobileClient": False,
362
  "playgroundTemperature": request.temperature,
363
  "playgroundTopP": request.top_p,
364
  "previewToken": None,
365
- "trendingAgentMode": trending_agent_mode,
366
  "userId": None,
367
  "userSelectedModel": MODEL_MAPPING.get(request.model, request.model),
368
  "userSystemPrompt": None,
369
- "validated": h_value,
370
  "visitFromDelta": False,
371
  "webSearchModePrompt": False,
372
  "vscodeClient": False,
@@ -379,49 +385,44 @@ async def process_non_streaming_response(request: ChatRequest):
379
  }
380
 
381
  prompt_tokens = sum(
382
- calculate_tokens(msg.get("content", ""), request.model) +
383
- sum(calculate_tokens(img["contents"], request.model) for img in msg.get("data", {}).get("imagesData", []))
384
- for msg in messages
385
  )
386
 
387
- full_response = ""
388
- final_snapzion_links: List[str] = []
389
 
390
  async with httpx.AsyncClient() as client:
391
  try:
392
- resp = await client.post(f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data)
393
  resp.raise_for_status()
394
- full_response = resp.text
395
  except Exception as e:
396
- # error handling...
397
  return {
398
  "id": request_id,
399
  "object": "chat.completion",
400
  "created": int(datetime.now().timestamp()),
401
  "model": request.model,
402
- "system_fingerprint": system_fingerprint,
403
  "choices": [{"index": 0, "message": {"role": "assistant", "content": str(e)}, "finish_reason": "error"}],
404
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": 0, "total_tokens": prompt_tokens},
405
  }
406
 
407
- if BLOCKED_MESSAGE in full_response:
408
- full_response = full_response.replace(BLOCKED_MESSAGE, "").strip()
409
-
410
- if "https://storage.googleapis.com" in full_response:
411
- full_response = full_response.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
412
 
413
- final_snapzion_links.extend(re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", full_response))
414
- cleaned = strip_model_prefix(full_response, model_prefix)
415
- completion_tokens = calculate_tokens(cleaned, request.model)
416
-
417
- upload_replaced_urls_to_r2(final_snapzion_links, alt_text=get_last_user_prompt(request.messages))
418
 
419
  return {
420
  "id": request_id,
421
  "object": "chat.completion",
422
  "created": int(datetime.now().timestamp()),
423
  "model": request.model,
424
- "system_fingerprint": system_fingerprint,
425
- "choices": [{"index": 0, "message": {"role": "assistant", "content": cleaned}, "finish_reason": "stop"}],
426
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": prompt_tokens + completion_tokens},
427
  }
 
37
  R2_SECRET_ACCESS_KEY = "14b08b0855263bb63d2618da3a6537e1b0446d89d51da03a568620b1e5342ea8"
38
  R2_ENDPOINT_URL = "https://f2f92ac53fae792c4155f6e93a514989.r2.cloudflarestorage.com"
39
  R2_BUCKET_NAME = "snapzion"
 
 
40
  R2_REPLACED_URLS_KEY = "snapzion.txt"
41
 
42
  s3 = boto3.client(
 
46
  aws_secret_access_key=R2_SECRET_ACCESS_KEY,
47
  )
48
 
 
49
  BLOCKED_MESSAGE = (
50
  "Generated by BLACKBOX.AI, try unlimited chat https://www.blackbox.ai "
51
  "and for API requests replace https://www.blackbox.ai with https://api.blackbox.ai"
 
55
  # RANDOM USER-DATA & SESSION GENERATION
56
  # ---------------------------------------------
57
  def get_random_name_email_customer():
 
 
 
58
  first_names = ["Aliace", "B21ob", "Car232ol", "Daavid", "Evewwlyn", "Fraank", "Grssace", "Hefctor", "Ivgy", "Jackdie"]
59
  last_names = ["Smilth", "Johnkson", "Dajvis", "Mihller", "Thomgpson", "Garwcia", "Broawn", "Wilfson", "Maartin", "Clarak"]
60
 
61
  random_name = f"{random.choice(first_names)} {random.choice(last_names)}"
62
  email_username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
63
+ random_email = f"{email_username}@gmail.com"
64
  suffix_length = len("Rldf7IKdNhdhiw")
65
  suffix_chars = string.ascii_letters + string.digits
66
  random_suffix = ''.join(random.choice(suffix_chars) for _ in range(suffix_length))
 
69
  return random_name, random_email, random_customer_id
70
 
71
  def generate_session(email: str, id_length: int = 21, days_ahead: int = 365) -> dict:
 
 
 
72
  numeric_id = ''.join(random.choice('0123456789') for _ in range(id_length))
73
  future_date = datetime.now(timezone.utc) + timedelta(days=days_ahead)
74
  expiry = future_date.isoformat(timespec='milliseconds').replace('+00:00', 'Z')
 
79
 
80
  return {
81
  "user": {
82
+ "name": "SNAPZION",
83
  "email": email,
84
  "image": image_url,
85
  "id": numeric_id
 
89
  }
90
 
91
  def generate_session_data() -> dict:
 
 
 
92
  _, email, _ = get_random_name_email_customer()
93
  session_data = generate_session(email)
94
  logger.info(f"Using generated session with email {email}")
 
98
  # HELPER FUNCTIONS
99
  # ---------------------------------------------
100
  def generate_system_fingerprint() -> str:
101
+ raw = f"{platform.node()}-{time.time()}-{uuid.uuid4()}"
102
+ short_hash = hashlib.md5(raw.encode()).hexdigest()[:12]
103
  return f"fp_{short_hash}"
104
 
105
  def get_last_user_prompt(messages: List[Any]) -> str:
 
115
 
116
  def upload_replaced_urls_to_r2(urls: List[str], alt_text: str = "") -> None:
117
  if not urls:
118
+ logger.info("No replaced or final URLs to store.")
119
  return
120
+ existing = ""
121
  try:
122
+ resp = s3.get_object(Bucket=R2_BUCKET_NAME, Key=R2_REPLACED_URLS_KEY)
123
+ existing = resp["Body"].read().decode()
 
124
  except s3.exceptions.NoSuchKey:
125
+ pass
126
  except Exception as e:
127
+ logger.error(f"Error reading {R2_REPLACED_URLS_KEY}: {e}")
128
+
129
+ markdown = "\n".join(f"![{alt_text}]({u})" for u in urls)
130
+ content = f"{existing}\n{markdown}" if existing.strip() else markdown
131
+
132
  try:
133
  s3.put_object(
134
  Bucket=R2_BUCKET_NAME,
135
  Key=R2_REPLACED_URLS_KEY,
136
+ Body=content.encode(),
137
  ContentType="text/plain",
138
  )
139
+ logger.info(f"Appended {len(urls)} URLs to {R2_REPLACED_URLS_KEY}.")
140
  except Exception as e:
141
+ logger.error(f"Error writing {R2_REPLACED_URLS_KEY}: {e}")
142
 
143
  def calculate_tokens(text: str, model: str) -> int:
144
  try:
145
+ enc = tiktoken.encoding_for_model(model)
146
+ return len(enc.encode(text))
147
+ except Exception:
 
148
  return len(text.split())
149
 
150
  def create_chat_completion_data(
 
175
  }
176
 
177
  def message_to_dict(message, model_prefix: Optional[str] = None):
178
+ """
179
+ Convert a ChatRequest message to a dict for the request payload.
180
+ Supports up to three images with type-based structure and sends multiple formats.
181
+ Prepends model_prefix to text content if specified.
182
+ """
183
+ content = ""
184
+ images_data = []
185
+ image_urls = []
186
+
187
+ if isinstance(message.content, list):
188
+ for item in message.content:
189
+ if item.get("type") == "text":
190
+ content = item.get("text", "").strip()
191
+ elif item.get("type") == "image_url" and len(images_data) < 3:
192
+ url = item["image_url"].get("url", "")
193
+ if url:
194
+ path = f"MultipleFiles/{uuid.uuid4().hex}.jpg"
195
+ images_data.append({"filePath": path, "contents": url})
196
+ image_urls.append({"image_url": {"url": url}})
197
+ elif isinstance(message.content, str):
198
+ content = message.content.strip()
199
+
200
+ if model_prefix and content:
201
+ content = f"{model_prefix} {content}"
202
+
203
+ base = {"role": message.role, "content": content}
204
+ if images_data:
205
+ base["data"] = {
206
+ "imageBase64": images_data[0]["contents"],
207
+ "fileText": "",
208
+ "title": "snapshot",
209
+ "imagesData": images_data
210
+ }
211
+ # embed any extra URLs in content list
212
+ for extra in image_urls[1:]:
213
+ base.setdefault("content", []).append(extra)
214
+
215
+ return base
216
 
217
  def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
218
  if model_prefix and content.startswith(model_prefix):
 
219
  return content[len(model_prefix):].strip()
220
  return content
221
 
 
223
  # STREAMING RESPONSE HANDLER
224
  # ---------------------------------------------
225
  async def process_streaming_response(request: ChatRequest):
226
+ system_fp = generate_system_fingerprint()
227
  request_id = f"chatcmpl-{uuid.uuid4()}"
228
+ logger.info(f"Processing (stream) {request_id} - Model: {request.model}")
229
 
230
  agent_mode = AGENT_MODE.get(request.model, {})
231
+ trending_mode = TRENDING_AGENT_MODE.get(request.model, {})
232
+ prefix = MODEL_PREFIXES.get(request.model, "")
 
 
233
 
234
+ headers_api = get_headers_api_chat(BASE_URL)
235
  if request.model == "o1-preview":
236
+ await asyncio.sleep(random.randint(1, 60))
 
 
237
 
238
+ h = await getHid()
239
+ if not h:
 
240
  raise HTTPException(status_code=500, detail="Missing h-value.")
241
 
242
+ msgs = [message_to_dict(m, prefix) for m in request.messages]
243
 
244
  json_data = {
245
  "agentMode": agent_mode,
 
259
  "isPremium": True,
260
  "isMemoryEnabled": False,
261
  "maxTokens": request.max_tokens,
262
+ "messages": msgs,
263
  "mobileClient": False,
264
  "playgroundTemperature": request.temperature,
265
  "playgroundTopP": request.top_p,
266
  "previewToken": None,
267
+ "trendingAgentMode": trending_mode,
268
  "userId": None,
269
  "userSelectedModel": MODEL_MAPPING.get(request.model, request.model),
270
  "userSystemPrompt": None,
271
+ "validated": h,
272
  "visitFromDelta": False,
273
  "webSearchModePrompt": False,
274
  "vscodeClient": False,
 
281
  }
282
 
283
  prompt_tokens = sum(
284
+ calculate_tokens(m.get("content", ""), request.model) +
285
+ sum(calculate_tokens(img["contents"], request.model) for img in m.get("data", {}).get("imagesData", []))
286
+ for m in msgs
287
  )
288
 
289
  completion_tokens = 0
290
+ final_links: List[str] = []
291
 
292
  async with httpx.AsyncClient() as client:
293
  try:
294
+ async with client.stream("POST", f"{BASE_URL}/api/chat", headers=headers_api, json=json_data, timeout=100) as resp:
295
+ resp.raise_for_status()
296
+ async for chunk in resp.aiter_text():
297
  if not chunk:
298
  continue
299
  if chunk.startswith("$@$v=undefined-rv1$@$"):
 
302
  chunk = chunk.replace(BLOCKED_MESSAGE, "").strip()
303
  if not chunk:
304
  continue
305
+ chunk = chunk.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
306
+ links = re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", chunk)
307
+ final_links.extend(links)
308
+ clean = strip_model_prefix(chunk, prefix)
309
+ completion_tokens += calculate_tokens(clean, request.model)
310
+ ts = int(datetime.now().timestamp())
 
311
  yield "data: " + json.dumps(
312
+ create_chat_completion_data(clean, request.model, ts, request_id, system_fp, prompt_tokens, completion_tokens)
313
  ) + "\n\n"
314
 
315
+ ts = int(datetime.now().timestamp())
 
316
  yield "data: " + json.dumps(
317
+ create_chat_completion_data("", request.model, ts, request_id, system_fp, prompt_tokens, completion_tokens, "stop")
318
  ) + "\n\n"
319
  yield "data: [DONE]\n\n"
320
 
 
 
 
321
  except Exception as e:
322
+ logger.error(f"Stream error {request_id}: {e}")
 
 
 
323
 
324
+ upload_replaced_urls_to_r2(final_links, alt_text=get_last_user_prompt(request.messages))
325
 
326
  # ---------------------------------------------
327
  # NON-STREAMING RESPONSE HANDLER
328
  # ---------------------------------------------
329
  async def process_non_streaming_response(request: ChatRequest):
330
+ system_fp = generate_system_fingerprint()
331
  request_id = f"chatcmpl-{uuid.uuid4()}"
332
+ logger.info(f"Processing (non-stream) {request_id} - Model: {request.model}")
333
 
334
  agent_mode = AGENT_MODE.get(request.model, {})
335
+ trending_mode = TRENDING_AGENT_MODE.get(request.model, {})
336
+ prefix = MODEL_PREFIXES.get(request.model, "")
 
 
337
 
338
+ headers_api = get_headers_api_chat(BASE_URL)
339
  if request.model == "o1-preview":
340
+ await asyncio.sleep(random.randint(20, 60))
 
 
341
 
342
+ h = await getHid()
343
+ if not h:
 
344
  raise HTTPException(status_code=500, detail="Missing h-value.")
345
 
346
+ msgs = [message_to_dict(m, prefix) for m in request.messages]
347
 
348
  json_data = {
349
  "agentMode": agent_mode,
 
363
  "isPremium": True,
364
  "isMemoryEnabled": False,
365
  "maxTokens": request.max_tokens,
366
+ "messages": msgs,
367
  "mobileClient": False,
368
  "playgroundTemperature": request.temperature,
369
  "playgroundTopP": request.top_p,
370
  "previewToken": None,
371
+ "trendingAgentMode": trending_mode,
372
  "userId": None,
373
  "userSelectedModel": MODEL_MAPPING.get(request.model, request.model),
374
  "userSystemPrompt": None,
375
+ "validated": h,
376
  "visitFromDelta": False,
377
  "webSearchModePrompt": False,
378
  "vscodeClient": False,
 
385
  }
386
 
387
  prompt_tokens = sum(
388
+ calculate_tokens(m.get("content", ""), request.model) +
389
+ sum(calculate_tokens(img["contents"], request.model) for img in m.get("data", {}).get("imagesData", []))
390
+ for m in msgs
391
  )
392
 
393
+ full_resp = ""
394
+ final_links: List[str] = []
395
 
396
  async with httpx.AsyncClient() as client:
397
  try:
398
+ resp = await client.post(f"{BASE_URL}/api/chat", headers=headers_api, json=json_data)
399
  resp.raise_for_status()
400
+ full_resp = resp.text
401
  except Exception as e:
 
402
  return {
403
  "id": request_id,
404
  "object": "chat.completion",
405
  "created": int(datetime.now().timestamp()),
406
  "model": request.model,
407
+ "system_fingerprint": system_fp,
408
  "choices": [{"index": 0, "message": {"role": "assistant", "content": str(e)}, "finish_reason": "error"}],
409
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": 0, "total_tokens": prompt_tokens},
410
  }
411
 
412
+ full_resp = full_resp.replace(BLOCKED_MESSAGE, "").strip()
413
+ full_resp = full_resp.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
414
+ final_links.extend(re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", full_resp))
415
+ clean = strip_model_prefix(full_resp, prefix)
416
+ completion_tokens = calculate_tokens(clean, request.model)
417
 
418
+ upload_replaced_urls_to_r2(final_links, alt_text=get_last_user_prompt(request.messages))
 
 
 
 
419
 
420
  return {
421
  "id": request_id,
422
  "object": "chat.completion",
423
  "created": int(datetime.now().timestamp()),
424
  "model": request.model,
425
+ "system_fingerprint": system_fp,
426
+ "choices": [{"index": 0, "message": {"role": "assistant", "content": clean}, "finish_reason": "stop"}],
427
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": prompt_tokens + completion_tokens},
428
  }