rkihacker commited on
Commit
e601239
·
verified ·
1 Parent(s): 98dd7e6

Update api/utils.py

Browse files
Files changed (1) hide show
  1. api/utils.py +87 -165
api/utils.py CHANGED
@@ -5,7 +5,7 @@ import re
5
  import string
6
  import time
7
  import uuid
8
- from datetime import datetime, timezone
9
  from typing import Any, Dict, List, Optional
10
 
11
  import boto3
@@ -55,12 +55,11 @@ BLOCKED_MESSAGE = (
55
  )
56
 
57
  # ---------------------------------------------
58
- # RANDOM USER-DATA GENERATION
59
  # ---------------------------------------------
60
  def get_random_name_email_customer():
61
  """
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"]
@@ -75,6 +74,38 @@ def get_random_name_email_customer():
75
 
76
  return random_name, random_email, random_customer_id
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  # ---------------------------------------------
79
  # HELPER FUNCTIONS
80
  # ---------------------------------------------
@@ -98,7 +129,6 @@ def upload_replaced_urls_to_r2(urls: List[str], alt_text: str = "") -> None:
98
  if not urls:
99
  logger.info("No replaced or final Snapzion URLs to store. Skipping snapzion.txt update.")
100
  return
101
-
102
  existing_data = ""
103
  try:
104
  response = s3.get_object(Bucket=R2_BUCKET_NAME, Key=R2_REPLACED_URLS_KEY)
@@ -108,16 +138,9 @@ def upload_replaced_urls_to_r2(urls: List[str], alt_text: str = "") -> None:
108
  logger.info("snapzion.txt does not exist yet. Will create a new one.")
109
  except Exception as e:
110
  logger.error(f"Error reading snapzion.txt from R2: {e}")
111
-
112
- alt_text = alt_text.strip()
113
  markdown_lines = [f"![{alt_text}]({url})" for url in urls]
114
  to_append = "\n".join(markdown_lines)
115
-
116
- if existing_data.strip():
117
- updated_content = existing_data + "\n" + to_append
118
- else:
119
- updated_content = to_append
120
-
121
  try:
122
  s3.put_object(
123
  Bucket=R2_BUCKET_NAME,
@@ -132,8 +155,7 @@ def upload_replaced_urls_to_r2(urls: List[str], alt_text: str = "") -> None:
132
  def calculate_tokens(text: str, model: str) -> int:
133
  try:
134
  encoding = tiktoken.encoding_for_model(model)
135
- tokens = encoding.encode(text)
136
- return len(tokens)
137
  except KeyError:
138
  logger.warning(f"Model '{model}' not supported by tiktoken for token counting. Using a generic method.")
139
  return len(text.split())
@@ -166,49 +188,9 @@ def create_chat_completion_data(
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 = []
176
- image_urls = []
177
-
178
- # Handle content based on type
179
- if isinstance(message.content, list):
180
- for item in message.content:
181
- if item.get("type") == "text":
182
- content = item.get("text", "").strip()
183
- elif item.get("type") == "image_url" and len(images_data) < 3:
184
- image_url = item.get("image_url", {}).get("url", "")
185
- if image_url:
186
- # Generate unique file path (assuming .jpg, adjust if needed)
187
- file_path = f"MultipleFiles/{uuid.uuid4().hex}.jpg"
188
- images_data.append({"filePath": file_path, "contents": image_url})
189
- image_urls.append({"image_url": {"url": image_url}})
190
- elif isinstance(message.content, str):
191
- content = message.content.strip()
192
-
193
- # Apply model prefix to text content
194
- if model_prefix and content:
195
- content = f"{model_prefix} {content}"
196
-
197
- # Create payload with both formats
198
- base_message = {"role": message.role, "content": content}
199
- if images_data:
200
- base_message["data"] = {
201
- "imageBase64": images_data[0]["contents"] if images_data else "",
202
- "fileText": "",
203
- "title": "snapshot",
204
- "imagesData": images_data
205
- }
206
- # Add additional image_url entries for testing
207
- for img in image_urls[1:]: # Skip the first image (already in imageBase64)
208
- base_message["content"] = base_message.get("content", "") # Preserve text
209
- base_message.setdefault("content", []).append(img)
210
-
211
- return base_message if images_data else {"role": message.role, "content": content}
212
 
213
  def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
214
  if model_prefix and content.startswith(model_prefix):
@@ -221,8 +203,6 @@ def strip_model_prefix(content: str, model_prefix: Optional[str] = None) -> str:
221
  # ---------------------------------------------
222
  async def process_streaming_response(request: ChatRequest):
223
  system_fingerprint = generate_system_fingerprint()
224
- random_name, random_email, random_customer_id = get_random_name_email_customer()
225
-
226
  request_id = f"chatcmpl-{uuid.uuid4()}"
227
  logger.info(f"Processing request (stream) {request_id} - Model: {request.model}")
228
 
@@ -280,80 +260,64 @@ async def process_streaming_response(request: ChatRequest):
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
 
290
- prompt_tokens = 0
291
- for msg in messages:
292
- if "content" in msg:
293
- prompt_tokens += calculate_tokens(msg["content"], request.model)
294
- if "data" in msg and "imagesData" in msg["data"]:
295
- for image_data in msg["data"]["imagesData"]:
296
- prompt_tokens += calculate_tokens(image_data["contents"], request.model)
297
 
298
  completion_tokens = 0
299
- final_snapzion_links = []
300
 
301
  async with httpx.AsyncClient() as client:
302
  try:
303
  async with client.stream("POST", f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data, timeout=100) as response:
304
  response.raise_for_status()
305
  async for chunk in response.aiter_text():
306
- timestamp = int(datetime.now().timestamp())
307
  if not chunk:
308
  continue
309
  if chunk.startswith("$@$v=undefined-rv1$@$"):
310
  chunk = chunk[21:]
311
  if BLOCKED_MESSAGE in chunk:
312
- logger.info(f"Blocked message found in chunk (Request: {request_id}).")
313
  chunk = chunk.replace(BLOCKED_MESSAGE, "").strip()
314
  if not chunk:
315
  continue
316
  if "https://storage.googleapis.com" in chunk:
317
  chunk = chunk.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
318
  snapzion_urls = re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", chunk)
319
- if snapzion_urls:
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:
327
- logger.error(f"HTTP error (stream) {request_id}: {e}")
328
- error_message = f"HTTP error occurred: {e}"
329
- try:
330
- error_details = e.response.json()
331
- error_message += f" Details: {error_details}"
332
- except ValueError:
333
- error_message += f" Response body: {e.response.text}"
334
- yield "data: " + json.dumps(create_chat_completion_data(error_message, request.model, int(datetime.now().timestamp()), request_id, system_fingerprint, prompt_tokens, completion_tokens, "error")) + "\n\n"
335
- yield "data: [DONE]\n\n"
336
- except httpx.RequestError as e:
337
- logger.error(f"Request error (stream) {request_id}: {e}")
338
- error_message = f"Request error occurred: {e}"
339
- yield "data: " + json.dumps(create_chat_completion_data(error_message, request.model, int(datetime.now().timestamp()), request_id, system_fingerprint, prompt_tokens, completion_tokens, "error")) + "\n\n"
340
- yield "data: [DONE]\n\n"
341
  except Exception as e:
342
- logger.error(f"Unhandled error (stream) {request_id}: {e}")
343
- error_message = f"An unexpected error occurred: {e}"
344
- yield "data: " + json.dumps(create_chat_completion_data(error_message, request.model, int(datetime.now().timestamp()), request_id, system_fingerprint, prompt_tokens, completion_tokens, "error")) + "\n\n"
345
- yield "data: [DONE]\n\n"
346
 
347
- last_user_prompt = get_last_user_prompt(request.messages)
348
- upload_replaced_urls_to_r2(final_snapzion_links, alt_text=last_user_prompt)
349
 
350
  # ---------------------------------------------
351
  # NON-STREAMING RESPONSE HANDLER
352
  # ---------------------------------------------
353
  async def process_non_streaming_response(request: ChatRequest):
354
  system_fingerprint = generate_system_fingerprint()
355
- random_name, random_email, random_customer_id = get_random_name_email_customer()
356
-
357
  request_id = f"chatcmpl-{uuid.uuid4()}"
358
  logger.info(f"Processing request (non-stream) {request_id} - Model: {request.model}")
359
 
@@ -362,14 +326,13 @@ async def process_non_streaming_response(request: ChatRequest):
362
  model_prefix = MODEL_PREFIXES.get(request.model, "")
363
 
364
  headers_api_chat = get_headers_api_chat(BASE_URL)
365
- headers_chat = get_headers_chat(BASE_URL, next_action=str(uuid.uuid4()), next_router_state_tree=json.dumps([""]))
366
 
367
  if request.model == "o1-preview":
368
  delay_seconds = random.randint(20, 60)
369
  logger.info(f"Delay {delay_seconds}s for 'o1-preview' (Request: {request_id})")
370
  await asyncio.sleep(delay_seconds)
371
 
372
- h_value = "00f37b34-a166-4efb-bce5-1312d87f2f94"
373
  if not h_value:
374
  logger.error("Failed to retrieve h-value.")
375
  raise HTTPException(status_code=500, detail="Missing h-value.")
@@ -412,87 +375,46 @@ async def process_non_streaming_response(request: ChatRequest):
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
 
422
- prompt_tokens = 0
423
- for msg in messages:
424
- if "content" in msg:
425
- prompt_tokens += calculate_tokens(msg["content"], request.model)
426
- if "data" in msg and "imagesData" in msg["data"]:
427
- for image_data in msg["data"]["imagesData"]:
428
- prompt_tokens += calculate_tokens(image_data["contents"], request.model)
429
 
430
  full_response = ""
431
- final_snapzion_links = []
432
 
433
  async with httpx.AsyncClient() as client:
434
  try:
435
- async with client.stream("POST", f"{BASE_URL}/api/chat", headers=headers_api_chat, json=json_data) as response:
436
- response.raise_for_status()
437
- async for chunk in response.aiter_text():
438
- full_response += chunk
439
- except httpx.HTTPStatusError as e:
440
- logger.error(f"HTTP error (non-stream) {request_id}: {e}")
441
- error_message = f"HTTP error occurred: {e}"
442
- try:
443
- error_details = e.response.json()
444
- error_message += f" Details: {error_details}"
445
- except ValueError:
446
- error_message += f" Response body: {e.response.text}"
447
- return {
448
- "id": request_id,
449
- "object": "chat.completion",
450
- "created": int(datetime.now().timestamp()),
451
- "model": request.model,
452
- "system_fingerprint": system_fingerprint,
453
- "choices": [{"index": 0, "message": {"role": "assistant", "content": error_message}, "finish_reason": "error"}],
454
- "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": 0, "total_tokens": prompt_tokens},
455
- }
456
- except httpx.RequestError as e:
457
- logger.error(f"Request error (non-stream) {request_id}: {e}")
458
- error_message = f"Request error occurred: {e}"
459
- return {
460
- "id": request_id,
461
- "object": "chat.completion",
462
- "created": int(datetime.now().timestamp()),
463
- "model": request.model,
464
- "system_fingerprint": system_fingerprint,
465
- "choices": [{"index": 0, "message": {"role": "assistant", "content": error_message}, "finish_reason": "error"}],
466
- "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": 0, "total_tokens": prompt_tokens},
467
- }
468
  except Exception as e:
469
- logger.error(f"Unexpected error (non-stream) {request_id}: {e}")
470
- error_message = f"An unexpected error occurred: {e}"
471
  return {
472
  "id": request_id,
473
  "object": "chat.completion",
474
  "created": int(datetime.now().timestamp()),
475
  "model": request.model,
476
  "system_fingerprint": system_fingerprint,
477
- "choices": [{"index": 0, "message": {"role": "assistant", "content": error_message}, "finish_reason": "error"}],
478
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": 0, "total_tokens": prompt_tokens},
479
  }
480
 
481
- if full_response.startswith("$@$v=undefined-rv1$@$"):
482
- full_response = full_response[21:]
483
  if BLOCKED_MESSAGE in full_response:
484
  full_response = full_response.replace(BLOCKED_MESSAGE, "").strip()
485
- if not full_response:
486
- raise HTTPException(status_code=500, detail="Blocked message in response.")
487
  if "https://storage.googleapis.com" in full_response:
488
  full_response = full_response.replace("https://storage.googleapis.com", "https://cdn.snapzion.com")
489
- snapzion_urls = re.findall(r"(https://cdn\.snapzion\.com[^\s\)]+)", full_response)
490
- for link in snapzion_urls:
491
- final_snapzion_links.append(link)
492
- cleaned_full_response = strip_model_prefix(full_response, model_prefix)
493
- completion_tokens = calculate_tokens(cleaned_full_response, request.model)
494
- last_user_prompt = get_last_user_prompt(request.messages)
495
- upload_replaced_urls_to_r2(final_snapzion_links, alt_text=last_user_prompt)
496
 
497
  return {
498
  "id": request_id,
@@ -500,6 +422,6 @@ async def process_non_streaming_response(request: ChatRequest):
500
  "created": int(datetime.now().timestamp()),
501
  "model": request.model,
502
  "system_fingerprint": system_fingerprint,
503
- "choices": [{"index": 0, "message": {"role": "assistant", "content": cleaned_full_response}, "finish_reason": "stop"}],
504
  "usage": {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": prompt_tokens + completion_tokens},
505
  }
 
5
  import string
6
  import time
7
  import uuid
8
+ from datetime import datetime, timezone, timedelta
9
  from typing import Any, Dict, List, Optional
10
 
11
  import boto3
 
55
  )
56
 
57
  # ---------------------------------------------
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"]
 
74
 
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')
84
+
85
+ chars = string.ascii_letters + string.digits + "-"
86
+ random_img_id = ''.join(random.choice(chars) for _ in range(48))
87
+ image_url = f"https://lh3.googleusercontent.com/a/ACg8oc{random_img_id}=s96-c"
88
+
89
+ return {
90
+ "user": {
91
+ "name": "SNAPZION",
92
+ "email": email,
93
+ "image": image_url,
94
+ "id": numeric_id
95
+ },
96
+ "expires": expiry,
97
+ "isNewUser": False
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}")
107
+ return session_data
108
+
109
  # ---------------------------------------------
110
  # HELPER FUNCTIONS
111
  # ---------------------------------------------
 
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)
 
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,
 
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())
 
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):
 
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
 
 
260
  "beastMode": False,
261
  "customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
262
  "webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
263
+ "session": generate_session_data(),
 
 
 
 
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$@$"):
283
  chunk = chunk[21:]
284
  if BLOCKED_MESSAGE in chunk:
 
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
 
 
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.")
 
375
  "beastMode": False,
376
  "customProfile": {"name": "", "occupation": "", "traits": [], "additionalInfo": "", "enableNewChats": False},
377
  "webSearchModeOption": {"autoMode": False, "webMode": False, "offlineMode": True},
378
+ "session": generate_session_data(),
 
 
 
 
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,
 
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
  }