Spaces:
Running
Running
cloudwaddie commited on
Commit Β·
ddf7346
1
Parent(s): a4d80c7
we are done!
Browse files- .cache_ggshield +1 -1
- .gitignore +3 -0
- .python-version +1 -0
- PLAN.MD +0 -26
- chat_interactive.py +17 -10
- find_char_limit.py +232 -0
- models.json +87 -3
- output.txt +0 -76
- samples/escaped.har +249 -0
- samples/multiple.har +472 -0
- src/main.py +351 -22
- timeout_debug.png +0 -0
- token_timeout.png +0 -0
.cache_ggshield
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"last_found_secrets": [{"match": "31f1dddcac91a689033afe8bc59f773bd13779cbe7f5c64ce9d645a5a7252573", "name": "Generic High Entropy Secret - c:\\Users\\Edward\\Desktop\\Projects\\lmarenabridge\\
|
|
|
|
| 1 |
+
{"last_found_secrets": [{"match": "31f1dddcac91a689033afe8bc59f773bd13779cbe7f5c64ce9d645a5a7252573", "name": "Generic High Entropy Secret - c:\\Users\\Edward\\Desktop\\Projects\\lmarenabridge\\find_char_limit.py"}]}
|
.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
venv/
|
| 2 |
+
*webui_secret_key
|
| 3 |
+
*cache_ggshield
|
.python-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
3.12.10
|
PLAN.MD
DELETED
|
@@ -1,26 +0,0 @@
|
|
| 1 |
-
Make a python based application that has two endpoints:
|
| 2 |
-
- /api - The OpenAI compatible API endpoint
|
| 3 |
-
- /dashboard - The dashboard that allows the user to create new API keys with a name and custom rate limits. A usage panel with logs on the models most used.
|
| 4 |
-
|
| 5 |
-
To implement dashboard, you must do the following:
|
| 6 |
-
On startup of the python server, you must use camoufox to open "lmarena.ai" and you must save the cloudflare cf_clearance cookie. You must then run the regex:
|
| 7 |
-
r'\{\\"initialModels\\":(\[.*?\]),\\"initialModelAId'
|
| 8 |
-
on the body of the page once it loads.
|
| 9 |
-
You must then Get the matched JSON string and unescape it. Save this into the list of models. An example of what this will look like is in samples/models.txt
|
| 10 |
-
match.group(1).encode().decode('unicode_escape')
|
| 11 |
-
The implementation requires explicit rendering of the Turnstile widget off-screen to generate an invisible token. First, define a function, for instance, createHiddenTurnstileWidget, to execute once the Cloudflare API script is fully loaded (e.g., via an onload callback on the script tag). Inside this function, dynamically create a div element with a unique ID and inject it into the document.body. Crucially, apply CSS styles to this container to make it invisible and non-interactive, specifically by setting position: absolute, large negative top/left values (e.g., -9999px), and pointer-events: none. Finally, programmatically invoke window.turnstile.render(containerId, { sitekey: '0x4AAAAAAA65vWDmG-O_lPtT', callback: 'tokenCaptureFunction' }) to initiate the challenge. The specified tokenCaptureFunction must then store the returned token into a global variable for later use in API requests.
|
| 12 |
-
You can then close the browser once you have this data.
|
| 13 |
-
Now, (still in initialization), you must generate an auth token. This must be saved into a file so it can be used later on.
|
| 14 |
-
You must then post to https://lmarena.ai/nextjs-api/sign-up. Keep in mind that the cloudflare clearance cookie should be used for everything. You must send the body as:
|
| 15 |
-
{"turnstile_token":"TOKEN FROM THE CLOUDFLARE WIDGET FROM EARLIER"}
|
| 16 |
-
Sample response:
|
| 17 |
-
{"access_token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjA5YTI3OTYzLTczNmYtNGM0Zi05NGIyLWJmYzRiMWI2MWY4OCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2h1b2d6b2VxemNyZHZrd3R2b2RpLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiJlMWQ1YmNjYi1lYWE2LTRkYzctYWM3Ny0wZTYwY2ViNzZlMTgiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzYyMDQxNTI2LCJpYXQiOjE3NjIwMzc5MjYsImVtYWlsIjoiIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnt9LCJ1c2VyX21ldGFkYXRhIjp7ImlkIjoiOWJjODRjMDEtN2E2MC00OTZiLTkxMzAtMjI3YWFiODEyMTI5In0sInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiYWFsIjoiYWFsMSIsImFtciI6W3sibWV0aG9kIjoiYW5vbnltb3VzIiwidGltZXN0YW1wIjoxNzYyMDM3OTI2fV0sInNlc3Npb25faWQiOiJmNjQ0NDI2ZS00MzBiLTRlYTctOGVmOS0wZjg4OGM0Njc5N2UiLCJpc19hbm9ueW1vdXMiOnRydWV9.Iovk49cPp8-mlHnFBR773oupXbm3WFWQxirCFI1DdObCL8OZiO7EVohJ7oBukweG1edCVPuoJiG3-AUp-pdYbA","token_type":"bearer","expires_in":3600,"expires_at":1762041526,"refresh_token":"ommeleevyoik","user":{"id":"e1d5bccb-eaa6-4dc7-ac77-0e60ceb76e18","app_metadata":{},"user_metadata":{"id":"9bc84c01-7a60-496b-9130-227aab812129"},"aud":"authenticated","email":"","phone":"","created_at":"2025-11-01T22:58:46.645813Z","last_sign_in_at":"2025-11-01T22:58:46.647128812Z","role":"authenticated","updated_at":"2025-11-01T22:58:46.648477Z","identities":[],"is_anonymous":true}}
|
| 18 |
-
The cookie should be saved like:
|
| 19 |
-
arena-auth-prod-v1:"base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TURReE5USTJMQ0pwWVhRaU9qRTNOakl3TXpjNU1qWXNJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lklvdms0OWNQcDgtbWxIbkZCUjc3M291cFhibTNXRldReGlyQ0ZJMURkT2JDTDhPWmlPN0VWb2hKN29CdWt3ZUcxZWRDVlB1b0ppRzMtQVVwLXBkWWJBIiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIwNDE1MjYsInJlZnJlc2hfdG9rZW4iOiJvbW1lbGVldnlvaWsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4ODEyWiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wMVQyMjo1ODo0Ni42NDg0NzdaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0"
|
| 20 |
-
|
| 21 |
-
You must save this auth key into a config file. This should be modifiable from the password protected dashboard.
|
| 22 |
-
|
| 23 |
-
Now to create a chat you must send a request like the one in samples/eval-create.har This should only be for the first message. You should then process the response which is again in the har file. You need to generate UUIDs for some of these values, and the models come from the models you extracted earlier.
|
| 24 |
-
To send further messages, you need to send a new request like the one in samples/followup.har
|
| 25 |
-
|
| 26 |
-
For now this should be all.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chat_interactive.py
CHANGED
|
@@ -40,7 +40,10 @@ def chat_session(client, model_name):
|
|
| 40 |
print("\n\nπ Goodbye!")
|
| 41 |
break
|
| 42 |
|
| 43 |
-
# Handle commands
|
|
|
|
|
|
|
|
|
|
| 44 |
if user_input.lower() in ['exit', 'quit']:
|
| 45 |
print("\nπ Goodbye!")
|
| 46 |
break
|
|
@@ -53,26 +56,30 @@ def chat_session(client, model_name):
|
|
| 53 |
if user_input.lower() == 'models':
|
| 54 |
return 'switch_model'
|
| 55 |
|
| 56 |
-
if not
|
| 57 |
-
continue
|
| 58 |
-
|
| 59 |
-
# Add user message to history
|
| 60 |
conversation_history.append({
|
| 61 |
"role": "user",
|
| 62 |
"content": user_input
|
| 63 |
})
|
| 64 |
|
| 65 |
-
# Get response from API
|
| 66 |
try:
|
| 67 |
print("Assistant: ", end="", flush=True)
|
| 68 |
|
| 69 |
-
|
| 70 |
model=model_name,
|
| 71 |
-
messages=conversation_history
|
|
|
|
| 72 |
)
|
| 73 |
|
| 74 |
-
assistant_message =
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
# Add assistant response to history
|
| 78 |
conversation_history.append({
|
|
|
|
| 40 |
print("\n\nπ Goodbye!")
|
| 41 |
break
|
| 42 |
|
| 43 |
+
# Handle commands FIRST before adding to history
|
| 44 |
+
if not user_input:
|
| 45 |
+
continue
|
| 46 |
+
|
| 47 |
if user_input.lower() in ['exit', 'quit']:
|
| 48 |
print("\nπ Goodbye!")
|
| 49 |
break
|
|
|
|
| 56 |
if user_input.lower() == 'models':
|
| 57 |
return 'switch_model'
|
| 58 |
|
| 59 |
+
# Add user message to history (only if not a command)
|
|
|
|
|
|
|
|
|
|
| 60 |
conversation_history.append({
|
| 61 |
"role": "user",
|
| 62 |
"content": user_input
|
| 63 |
})
|
| 64 |
|
| 65 |
+
# Get response from API with streaming
|
| 66 |
try:
|
| 67 |
print("Assistant: ", end="", flush=True)
|
| 68 |
|
| 69 |
+
stream = client.chat.completions.create(
|
| 70 |
model=model_name,
|
| 71 |
+
messages=conversation_history,
|
| 72 |
+
stream=True # Enable streaming
|
| 73 |
)
|
| 74 |
|
| 75 |
+
assistant_message = ""
|
| 76 |
+
for chunk in stream:
|
| 77 |
+
if chunk.choices[0].delta.content is not None:
|
| 78 |
+
content = chunk.choices[0].delta.content
|
| 79 |
+
print(content, end="", flush=True)
|
| 80 |
+
assistant_message += content
|
| 81 |
+
|
| 82 |
+
print() # New line after streaming completes
|
| 83 |
|
| 84 |
# Add assistant response to history
|
| 85 |
conversation_history.append({
|
find_char_limit.py
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Script to find the maximum character limit for LMArena API.
|
| 4 |
+
Iterates from a starting length downward to find where requests succeed.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import asyncio
|
| 8 |
+
import json
|
| 9 |
+
import sys
|
| 10 |
+
import httpx
|
| 11 |
+
from typing import Optional
|
| 12 |
+
|
| 13 |
+
# Configuration
|
| 14 |
+
BASE_URL = "http://localhost:8000/api/v1/chat/completions"
|
| 15 |
+
API_KEY = "sk-lmab-4d4c13f6-7846-4f94-a261-f59911838196" # Set your API key here
|
| 16 |
+
MODEL = "claude-sonnet-4-5-20250929-thinking-32k" # Default model, will be updated from available models
|
| 17 |
+
|
| 18 |
+
# Test parameters
|
| 19 |
+
STARTING_LENGTH = 500000 # Start with 500k characters
|
| 20 |
+
STEP_SIZE = 10000 # Decrease by 10k each time
|
| 21 |
+
MIN_LENGTH = 1000 # Minimum length to test
|
| 22 |
+
|
| 23 |
+
def load_config():
|
| 24 |
+
"""Load config to get API key if not set"""
|
| 25 |
+
global API_KEY
|
| 26 |
+
try:
|
| 27 |
+
with open("config.json", "r") as f:
|
| 28 |
+
config = json.load(f)
|
| 29 |
+
if not API_KEY and config.get("api_keys"):
|
| 30 |
+
API_KEY = config["api_keys"][0]["key"]
|
| 31 |
+
print(f"β
Using API key from config: {API_KEY[:20]}...")
|
| 32 |
+
except (FileNotFoundError, json.JSONDecodeError, IndexError):
|
| 33 |
+
pass
|
| 34 |
+
|
| 35 |
+
# Verify the model exists in available models
|
| 36 |
+
try:
|
| 37 |
+
with open("models.json", "r") as f:
|
| 38 |
+
models = json.load(f)
|
| 39 |
+
text_models = [m for m in models if m.get('capabilities', {}).get('outputCapabilities', {}).get('text')]
|
| 40 |
+
model_names = [m.get("publicName") for m in text_models if m.get("publicName")]
|
| 41 |
+
if MODEL not in model_names and text_models:
|
| 42 |
+
print(f"β οΈ Model '{MODEL}' not found in available models")
|
| 43 |
+
print(f" Available models: {', '.join(model_names[:5])}...")
|
| 44 |
+
else:
|
| 45 |
+
print(f"β
Using model: {MODEL}")
|
| 46 |
+
except (FileNotFoundError, json.JSONDecodeError):
|
| 47 |
+
print(f"β οΈ Could not load models.json, using model: {MODEL}")
|
| 48 |
+
|
| 49 |
+
def generate_test_prompt(length: int) -> str:
|
| 50 |
+
"""
|
| 51 |
+
Generate a test prompt of specified length.
|
| 52 |
+
Uses only alphanumeric characters and spaces to avoid any escaping issues.
|
| 53 |
+
"""
|
| 54 |
+
# Use simple, safe characters that won't need escaping in JSON
|
| 55 |
+
base_text = "abcdefghijklmnopqrstuvwxyz0123456789 "
|
| 56 |
+
repeat_count = length // len(base_text)
|
| 57 |
+
remainder = length % len(base_text)
|
| 58 |
+
return (base_text * repeat_count) + base_text[:remainder]
|
| 59 |
+
|
| 60 |
+
async def test_request(length: int, timeout: int = 60) -> tuple[bool, Optional[str]]:
|
| 61 |
+
"""
|
| 62 |
+
Test a request with the given prompt length.
|
| 63 |
+
Returns (success, error_message)
|
| 64 |
+
"""
|
| 65 |
+
prompt = generate_test_prompt(length)
|
| 66 |
+
|
| 67 |
+
payload = {
|
| 68 |
+
"model": MODEL,
|
| 69 |
+
"messages": [
|
| 70 |
+
{
|
| 71 |
+
"role": "user",
|
| 72 |
+
"content": prompt
|
| 73 |
+
}
|
| 74 |
+
],
|
| 75 |
+
"stream": False
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
headers = {
|
| 79 |
+
"Authorization": f"Bearer {API_KEY}",
|
| 80 |
+
"Content-Type": "application/json"
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
print(f"\n{'='*60}")
|
| 84 |
+
print(f"π§ͺ Testing with {length:,} characters")
|
| 85 |
+
print(f"{'='*60}")
|
| 86 |
+
|
| 87 |
+
async with httpx.AsyncClient() as client:
|
| 88 |
+
try:
|
| 89 |
+
response = await client.post(
|
| 90 |
+
BASE_URL,
|
| 91 |
+
json=payload,
|
| 92 |
+
headers=headers,
|
| 93 |
+
timeout=timeout
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
print(f"π Status Code: {response.status_code}")
|
| 97 |
+
|
| 98 |
+
if response.status_code == 200:
|
| 99 |
+
result = response.json()
|
| 100 |
+
response_text = result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
| 101 |
+
print(f"β
SUCCESS - Got response ({len(response_text)} chars)")
|
| 102 |
+
return True, None
|
| 103 |
+
else:
|
| 104 |
+
error_msg = f"Status {response.status_code}: {response.text[:200]}"
|
| 105 |
+
print(f"β FAILED - {error_msg}")
|
| 106 |
+
return False, error_msg
|
| 107 |
+
|
| 108 |
+
except httpx.TimeoutException:
|
| 109 |
+
error_msg = f"Request timed out after {timeout}s"
|
| 110 |
+
print(f"β±οΈ TIMEOUT - {error_msg}")
|
| 111 |
+
return False, error_msg
|
| 112 |
+
|
| 113 |
+
except httpx.HTTPStatusError as e:
|
| 114 |
+
error_msg = f"HTTP error {e.response.status_code}: {e.response.text[:200]}"
|
| 115 |
+
print(f"β HTTP ERROR - {error_msg}")
|
| 116 |
+
return False, error_msg
|
| 117 |
+
|
| 118 |
+
except Exception as e:
|
| 119 |
+
error_msg = f"Unexpected error: {type(e).__name__}: {str(e)}"
|
| 120 |
+
print(f"β ERROR - {error_msg}")
|
| 121 |
+
return False, error_msg
|
| 122 |
+
|
| 123 |
+
async def binary_search(min_len: int, max_len: int, step: int = 1000) -> int:
|
| 124 |
+
"""
|
| 125 |
+
Use binary search to find the exact character limit more efficiently.
|
| 126 |
+
"""
|
| 127 |
+
print(f"\n{'='*60}")
|
| 128 |
+
print(f"π Binary search between {min_len:,} and {max_len:,} characters")
|
| 129 |
+
print(f"{'='*60}")
|
| 130 |
+
|
| 131 |
+
last_success = min_len
|
| 132 |
+
|
| 133 |
+
while max_len - min_len > step:
|
| 134 |
+
mid = (min_len + max_len) // 2
|
| 135 |
+
success, error = await test_request(mid)
|
| 136 |
+
|
| 137 |
+
if success:
|
| 138 |
+
last_success = mid
|
| 139 |
+
min_len = mid + 1
|
| 140 |
+
print(f"βοΈ Increasing search range to {min_len:,} - {max_len:,}")
|
| 141 |
+
else:
|
| 142 |
+
max_len = mid - 1
|
| 143 |
+
print(f"βοΈ Decreasing search range to {min_len:,} - {max_len:,}")
|
| 144 |
+
|
| 145 |
+
# Small delay to avoid rate limiting
|
| 146 |
+
await asyncio.sleep(2)
|
| 147 |
+
|
| 148 |
+
return last_success
|
| 149 |
+
|
| 150 |
+
async def find_char_limit():
|
| 151 |
+
"""Main function to find the character limit"""
|
| 152 |
+
|
| 153 |
+
print("\n" + "="*60)
|
| 154 |
+
print("π LMArena Character Limit Finder")
|
| 155 |
+
print("="*60)
|
| 156 |
+
|
| 157 |
+
load_config()
|
| 158 |
+
|
| 159 |
+
if not API_KEY:
|
| 160 |
+
print("β No API key found!")
|
| 161 |
+
print("Please set API_KEY in the script or add it to config.json")
|
| 162 |
+
sys.exit(1)
|
| 163 |
+
|
| 164 |
+
print(f"\nπ Configuration:")
|
| 165 |
+
print(f" Base URL: {BASE_URL}")
|
| 166 |
+
print(f" Model: {MODEL}")
|
| 167 |
+
print(f" Starting Length: {STARTING_LENGTH:,} chars")
|
| 168 |
+
print(f" Step Size: {STEP_SIZE:,} chars")
|
| 169 |
+
print(f" Min Length: {MIN_LENGTH:,} chars")
|
| 170 |
+
|
| 171 |
+
# Phase 1: Coarse search - find approximate range
|
| 172 |
+
print(f"\n{'='*60}")
|
| 173 |
+
print("PHASE 1: Coarse Search")
|
| 174 |
+
print(f"{'='*60}")
|
| 175 |
+
|
| 176 |
+
current_length = STARTING_LENGTH
|
| 177 |
+
last_success_length = None
|
| 178 |
+
first_failure_length = None
|
| 179 |
+
|
| 180 |
+
while current_length >= MIN_LENGTH:
|
| 181 |
+
success, error = await test_request(current_length)
|
| 182 |
+
|
| 183 |
+
if success:
|
| 184 |
+
last_success_length = current_length
|
| 185 |
+
print(f"β
Found working length: {current_length:,} chars")
|
| 186 |
+
break
|
| 187 |
+
else:
|
| 188 |
+
first_failure_length = current_length
|
| 189 |
+
print(f"β {current_length:,} chars is too large")
|
| 190 |
+
current_length -= STEP_SIZE
|
| 191 |
+
|
| 192 |
+
# Small delay to avoid rate limiting
|
| 193 |
+
await asyncio.sleep(2)
|
| 194 |
+
|
| 195 |
+
if last_success_length is None:
|
| 196 |
+
print(f"\nβ All tested lengths failed. The limit might be below {MIN_LENGTH:,} chars")
|
| 197 |
+
return
|
| 198 |
+
|
| 199 |
+
# Phase 2: Binary search for exact limit
|
| 200 |
+
if first_failure_length and last_success_length:
|
| 201 |
+
print(f"\n{'='*60}")
|
| 202 |
+
print("PHASE 2: Binary Search for Exact Limit")
|
| 203 |
+
print(f"{'='*60}")
|
| 204 |
+
|
| 205 |
+
exact_limit = await binary_search(
|
| 206 |
+
last_success_length,
|
| 207 |
+
first_failure_length,
|
| 208 |
+
step=500 # Find limit within 500 char accuracy
|
| 209 |
+
)
|
| 210 |
+
last_success_length = exact_limit
|
| 211 |
+
|
| 212 |
+
# Final results
|
| 213 |
+
print(f"\n{'='*60}")
|
| 214 |
+
print("π― RESULTS")
|
| 215 |
+
print(f"{'='*60}")
|
| 216 |
+
print(f"β
Maximum working character limit: {last_success_length:,} characters")
|
| 217 |
+
print(f"π This means prompts up to {last_success_length:,} chars should work")
|
| 218 |
+
|
| 219 |
+
if first_failure_length:
|
| 220 |
+
print(f"β First failure at: {first_failure_length:,} characters")
|
| 221 |
+
print(f"π Safe range: up to {last_success_length:,} characters")
|
| 222 |
+
|
| 223 |
+
print(f"\n{'='*60}")
|
| 224 |
+
print("β¨ Testing complete!")
|
| 225 |
+
print(f"{'='*60}\n")
|
| 226 |
+
|
| 227 |
+
if __name__ == "__main__":
|
| 228 |
+
try:
|
| 229 |
+
asyncio.run(find_char_limit())
|
| 230 |
+
except KeyboardInterrupt:
|
| 231 |
+
print("\n\nβ οΈ Testing interrupted by user")
|
| 232 |
+
sys.exit(0)
|
models.json
CHANGED
|
@@ -193,7 +193,8 @@
|
|
| 193 |
"publicName": "glm-4.6",
|
| 194 |
"capabilities": {
|
| 195 |
"inputCapabilities": {
|
| 196 |
-
"text": true
|
|
|
|
| 197 |
},
|
| 198 |
"outputCapabilities": {
|
| 199 |
"text": true,
|
|
@@ -295,13 +296,14 @@
|
|
| 295 |
"rank": 12
|
| 296 |
},
|
| 297 |
{
|
| 298 |
-
"id": "
|
| 299 |
"organization": "deepseek",
|
| 300 |
"provider": "deepseek",
|
| 301 |
"publicName": "deepseek-v3.2-exp",
|
| 302 |
"capabilities": {
|
| 303 |
"inputCapabilities": {
|
| 304 |
-
"text": true
|
|
|
|
| 305 |
},
|
| 306 |
"outputCapabilities": {
|
| 307 |
"text": true,
|
|
@@ -1417,6 +1419,18 @@
|
|
| 1417 |
}
|
| 1418 |
}
|
| 1419 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1420 |
{
|
| 1421 |
"id": "c15b93ed-e87b-467f-8f9f-d830fd7aa54d",
|
| 1422 |
"publicName": "lmarena-internal-test-only",
|
|
@@ -1453,6 +1467,18 @@
|
|
| 1453 |
}
|
| 1454 |
}
|
| 1455 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1456 |
{
|
| 1457 |
"id": "24d647d0-7945-442d-b323-08ca04e9e288",
|
| 1458 |
"publicName": "sorting-hat",
|
|
@@ -1465,6 +1491,18 @@
|
|
| 1465 |
}
|
| 1466 |
}
|
| 1467 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1468 |
{
|
| 1469 |
"id": "9af435c8-1f53-4b78-a400-c1f5e9fe09b0",
|
| 1470 |
"publicName": "leepwal",
|
|
@@ -1477,6 +1515,18 @@
|
|
| 1477 |
}
|
| 1478 |
}
|
| 1479 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1480 |
{
|
| 1481 |
"id": "ac31e980-8bf1-4637-adba-cf9ffa8b6343",
|
| 1482 |
"organization": "alibaba",
|
|
@@ -1645,6 +1695,8 @@
|
|
| 1645 |
},
|
| 1646 |
{
|
| 1647 |
"id": "019a026f-30b2-7ffa-9714-7180577666e2",
|
|
|
|
|
|
|
| 1648 |
"publicName": "qwen3-max-2025-10-20",
|
| 1649 |
"capabilities": {
|
| 1650 |
"inputCapabilities": {
|
|
@@ -2313,6 +2365,38 @@
|
|
| 2313 |
}
|
| 2314 |
}
|
| 2315 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2316 |
{
|
| 2317 |
"id": "0199e980-ba42-737b-9436-927b6e7ca73e",
|
| 2318 |
"organization": "reve",
|
|
|
|
| 193 |
"publicName": "glm-4.6",
|
| 194 |
"capabilities": {
|
| 195 |
"inputCapabilities": {
|
| 196 |
+
"text": true,
|
| 197 |
+
"image": false
|
| 198 |
},
|
| 199 |
"outputCapabilities": {
|
| 200 |
"text": true,
|
|
|
|
| 296 |
"rank": 12
|
| 297 |
},
|
| 298 |
{
|
| 299 |
+
"id": "019a4fff-c017-726d-abb1-99b0aaf87f43",
|
| 300 |
"organization": "deepseek",
|
| 301 |
"provider": "deepseek",
|
| 302 |
"publicName": "deepseek-v3.2-exp",
|
| 303 |
"capabilities": {
|
| 304 |
"inputCapabilities": {
|
| 305 |
+
"text": true,
|
| 306 |
+
"image": false
|
| 307 |
},
|
| 308 |
"outputCapabilities": {
|
| 309 |
"text": true,
|
|
|
|
| 1419 |
}
|
| 1420 |
}
|
| 1421 |
},
|
| 1422 |
+
{
|
| 1423 |
+
"id": "019a5028-3b35-79be-9560-3f19c3c60cdf",
|
| 1424 |
+
"publicName": "newton",
|
| 1425 |
+
"capabilities": {
|
| 1426 |
+
"inputCapabilities": {
|
| 1427 |
+
"text": true
|
| 1428 |
+
},
|
| 1429 |
+
"outputCapabilities": {
|
| 1430 |
+
"text": true
|
| 1431 |
+
}
|
| 1432 |
+
}
|
| 1433 |
+
},
|
| 1434 |
{
|
| 1435 |
"id": "c15b93ed-e87b-467f-8f9f-d830fd7aa54d",
|
| 1436 |
"publicName": "lmarena-internal-test-only",
|
|
|
|
| 1467 |
}
|
| 1468 |
}
|
| 1469 |
},
|
| 1470 |
+
{
|
| 1471 |
+
"id": "019a5028-3f5b-7c13-858f-206214b15022",
|
| 1472 |
+
"publicName": "newton-with-reasoning",
|
| 1473 |
+
"capabilities": {
|
| 1474 |
+
"inputCapabilities": {
|
| 1475 |
+
"text": true
|
| 1476 |
+
},
|
| 1477 |
+
"outputCapabilities": {
|
| 1478 |
+
"text": true
|
| 1479 |
+
}
|
| 1480 |
+
}
|
| 1481 |
+
},
|
| 1482 |
{
|
| 1483 |
"id": "24d647d0-7945-442d-b323-08ca04e9e288",
|
| 1484 |
"publicName": "sorting-hat",
|
|
|
|
| 1491 |
}
|
| 1492 |
}
|
| 1493 |
},
|
| 1494 |
+
{
|
| 1495 |
+
"id": "019a5028-42ba-750c-b6ef-65fa46d0db8f",
|
| 1496 |
+
"publicName": "gauss",
|
| 1497 |
+
"capabilities": {
|
| 1498 |
+
"inputCapabilities": {
|
| 1499 |
+
"text": true
|
| 1500 |
+
},
|
| 1501 |
+
"outputCapabilities": {
|
| 1502 |
+
"text": true
|
| 1503 |
+
}
|
| 1504 |
+
}
|
| 1505 |
+
},
|
| 1506 |
{
|
| 1507 |
"id": "9af435c8-1f53-4b78-a400-c1f5e9fe09b0",
|
| 1508 |
"publicName": "leepwal",
|
|
|
|
| 1515 |
}
|
| 1516 |
}
|
| 1517 |
},
|
| 1518 |
+
{
|
| 1519 |
+
"id": "019a5028-45c7-73db-b3b8-6dec3af9ecb4",
|
| 1520 |
+
"publicName": "gauss-with-reasoning",
|
| 1521 |
+
"capabilities": {
|
| 1522 |
+
"inputCapabilities": {
|
| 1523 |
+
"text": true
|
| 1524 |
+
},
|
| 1525 |
+
"outputCapabilities": {
|
| 1526 |
+
"text": true
|
| 1527 |
+
}
|
| 1528 |
+
}
|
| 1529 |
+
},
|
| 1530 |
{
|
| 1531 |
"id": "ac31e980-8bf1-4637-adba-cf9ffa8b6343",
|
| 1532 |
"organization": "alibaba",
|
|
|
|
| 1695 |
},
|
| 1696 |
{
|
| 1697 |
"id": "019a026f-30b2-7ffa-9714-7180577666e2",
|
| 1698 |
+
"organization": "alibaba",
|
| 1699 |
+
"provider": "alibaba",
|
| 1700 |
"publicName": "qwen3-max-2025-10-20",
|
| 1701 |
"capabilities": {
|
| 1702 |
"inputCapabilities": {
|
|
|
|
| 2365 |
}
|
| 2366 |
}
|
| 2367 |
},
|
| 2368 |
+
{
|
| 2369 |
+
"id": "019a5050-1695-7b5d-b045-ba01ff08ec28",
|
| 2370 |
+
"publicName": "wan2.5-preview",
|
| 2371 |
+
"capabilities": {
|
| 2372 |
+
"inputCapabilities": {
|
| 2373 |
+
"text": true
|
| 2374 |
+
},
|
| 2375 |
+
"outputCapabilities": {
|
| 2376 |
+
"image": {
|
| 2377 |
+
"aspectRatios": [
|
| 2378 |
+
"1:1"
|
| 2379 |
+
]
|
| 2380 |
+
}
|
| 2381 |
+
}
|
| 2382 |
+
}
|
| 2383 |
+
},
|
| 2384 |
+
{
|
| 2385 |
+
"id": "019a5050-2875-78ed-ae3a-d9a51a438685",
|
| 2386 |
+
"publicName": "wan2.5-preview-prompt-extend",
|
| 2387 |
+
"capabilities": {
|
| 2388 |
+
"inputCapabilities": {
|
| 2389 |
+
"text": true
|
| 2390 |
+
},
|
| 2391 |
+
"outputCapabilities": {
|
| 2392 |
+
"image": {
|
| 2393 |
+
"aspectRatios": [
|
| 2394 |
+
"1:1"
|
| 2395 |
+
]
|
| 2396 |
+
}
|
| 2397 |
+
}
|
| 2398 |
+
}
|
| 2399 |
+
},
|
| 2400 |
{
|
| 2401 |
"id": "0199e980-ba42-737b-9436-927b6e7ca73e",
|
| 2402 |
"organization": "reve",
|
output.txt
DELETED
|
@@ -1,76 +0,0 @@
|
|
| 1 |
-
Of course. The JavaScript UserScript (`oldscript.js`) is significantly more sophisticated and resilient in its methods for acquiring tokens compared to your Python script (`main.py`). The differences explain why `main.py` is more likely to fail.
|
| 2 |
-
|
| 3 |
-
The core reason is that the **JavaScript runs *inside* the LMArena page's context**, allowing it to piggyback on the website's own functions and the browser's natural behavior. The Python script controls a browser from the outside, which is less seamless and more detectable.
|
| 4 |
-
|
| 5 |
-
***
|
| 6 |
-
|
| 7 |
-
### Key Differences in Token Acquisition
|
| 8 |
-
|
| 9 |
-
Here is a breakdown of the critical differences that impact token retrieval.
|
| 10 |
-
|
| 11 |
-
#### 1. Turnstile Token Capture Strategy (Stealth vs. Active Creation)
|
| 12 |
-
|
| 13 |
-
This is the most significant difference. How each script gets the Cloudflare Turnstile token is fundamentally different.
|
| 14 |
-
|
| 15 |
-
* **`oldscript.js` (Stealthy Hooking):**
|
| 16 |
-
The UserScript employs a very clever and stealthy method. It intercepts the website's own attempt to load and use the Turnstile service.
|
| 17 |
-
1. It temporarily overrides `document.createElement`.
|
| 18 |
-
2. When the website tries to create a `<script>` tag for Turnstile, the UserScript intercepts it.
|
| 19 |
-
3. It then **hooks the `window.turnstile.render` function**.
|
| 20 |
-
4. When the website legitimately calls `turnstile.render` to show a captcha, the UserScript's hook fires, capturing the resulting token without needing to create its own separate, potentially suspicious, widget. This is far less likely to be detected as bot activity.
|
| 21 |
-
|
| 22 |
-
* **`main.py` (Active Injection):**
|
| 23 |
-
Your Python script takes a more direct, "brute-force" approach.
|
| 24 |
-
1. It waits for the page to load.
|
| 25 |
-
2. It injects a brand new script that **creates its own hidden Turnstile widget**.
|
| 26 |
-
3. It waits for the callback from this *new* widget to get a token.
|
| 27 |
-
|
| 28 |
-
**Why this might fail:** Anti-bot systems can be sensitive to creating multiple or hidden Turnstile widgets. The site might expect the token to originate from its own, visible widget, and a token from a new, hidden one could be flagged as suspicious or invalid.
|
| 29 |
-
|
| 30 |
-
---
|
| 31 |
-
|
| 32 |
-
#### 2. Authentication Request Method (Native Browser `fetch` vs. External `httpx`)
|
| 33 |
-
|
| 34 |
-
After getting the Turnstile token, the method used to request the final `arena-auth-prod-v1` cookie is also critical.
|
| 35 |
-
|
| 36 |
-
* **`oldscript.js` (Native Browser `fetch`):**
|
| 37 |
-
The UserScript uses the browser's own `fetch` command to post the token to `/api/sign-up`. When it does this, the browser **automatically and perfectly attaches all necessary context**:
|
| 38 |
-
* The complete and correct set of cookies (including `cf_clearance`).
|
| 39 |
-
* The correct `User-Agent` string.
|
| 40 |
-
* Crucially, other browser-specific headers like `sec-ch-ua` (Client Hints) which are used for browser fingerprinting.
|
| 41 |
-
* The request originates from the correct domain, passing all security checks.
|
| 42 |
-
|
| 43 |
-
* **`main.py` (External `httpx` Client):**
|
| 44 |
-
Your Python script gets the Turnstile token and then makes a *separate* HTTP request using the `httpx` library. Although you copy the `User-Agent` and `cf_clearance` cookie, this request is made from outside the browser's context. It is likely **missing subtle browser headers and fingerprinting data** that Cloudflare's anti-bot system looks for. An inconsistency between the browser that solved the Turnstile and the client making the API request is a major red flag.
|
| 45 |
-
|
| 46 |
-
---
|
| 47 |
-
|
| 48 |
-
#### 3. Error Handling and Recovery (Self-Healing vs. Hard Failure)
|
| 49 |
-
|
| 50 |
-
The UserScript is built to survive Cloudflare challenges, while the Python script is not.
|
| 51 |
-
|
| 52 |
-
* **`oldscript.js` (Self-Healing):**
|
| 53 |
-
It has robust functions (`handleCloudflareRefresh`, `handleRateLimitRefresh`) that can detect a Cloudflare challenge or a rate-limit error (HTTP 429). When this happens, it:
|
| 54 |
-
1. **Saves the failed request** into the browser's `localStorage`.
|
| 55 |
-
2. **Automatically reloads the page** (`window.location.reload()`).
|
| 56 |
-
3. After the page reloads (and you presumably solve the new challenge), the script runs again, finds the saved request in `localStorage`, and automatically retries it.
|
| 57 |
-
|
| 58 |
-
* **`main.py` (Hard Failure):**
|
| 59 |
-
Your script checks for a 429 status or a "Checking your browser" message. If it encounters one, it simply prints an error and raises an exception. The entire process halts. It has **no mechanism to recover** from a Cloudflare challenge.
|
| 60 |
-
|
| 61 |
-
---
|
| 62 |
-
|
| 63 |
-
#### 4. Human Emulation
|
| 64 |
-
|
| 65 |
-
* **`oldscript.js`:** The script includes a `simulateHumanClick()` function that generates random mouse movements and clicks near the center of the page. This is a common technique to defeat simple bot detectors that require some form of user interaction before generating a valid token.
|
| 66 |
-
* **`main.py`:** Your script performs no user emulation. It just navigates and executes scripts, which can be easily identified as non-human behavior.
|
| 67 |
-
|
| 68 |
-
### Summary Table
|
| 69 |
-
|
| 70 |
-
| Feature | `main.py` (Python) | `oldscript.js` (UserScript) | Why It Matters for Token Getting |
|
| 71 |
-
| :--- | :--- | :--- | :--- |
|
| 72 |
-
| **Environment** | External script controlling a browser. | Runs directly inside the target webpage. | The UserScript has perfect browser context, making its actions look legitimate. |
|
| 73 |
-
| **Turnstile Token** | Creates a new, hidden widget. | Hooks the site's *own* widget creation. | Hooking is stealthier and less likely to be flagged by anti-bot systems. |
|
| 74 |
-
| **Auth Request** | Uses `httpx`, manually adding headers. | Uses the browser's native `fetch`. | Native `fetch` sends a perfectly formed, authentic request with all fingerprinting headers. |
|
| 75 |
-
| **Error Handling** | Fails and stops on Cloudflare challenge. | Saves request, reloads page, retries. | The UserScript can automatically recover from challenges, making it far more reliable. |
|
| 76 |
-
| **Human Emulation** | None. | Simulates mouse clicks. | Can bypass simple bot-detection checks that require user interaction. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
samples/escaped.har
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"log": {
|
| 3 |
+
"version": "1.2",
|
| 4 |
+
"creator": {
|
| 5 |
+
"name": "Zen",
|
| 6 |
+
"version": "1.17.4b"
|
| 7 |
+
},
|
| 8 |
+
"browser": {
|
| 9 |
+
"name": "Zen",
|
| 10 |
+
"version": "1.17.4b"
|
| 11 |
+
},
|
| 12 |
+
"pages": [
|
| 13 |
+
{
|
| 14 |
+
"id": "page_1",
|
| 15 |
+
"pageTimings": {
|
| 16 |
+
"onContentLoad": 1398,
|
| 17 |
+
"onLoad": 5802
|
| 18 |
+
},
|
| 19 |
+
"startedDateTime": "2025-11-05T16:03:18.895+10:30",
|
| 20 |
+
"title": "https://lmarena.ai/c/019a5280-e235-7e08-80af-05b274d8faae"
|
| 21 |
+
}
|
| 22 |
+
],
|
| 23 |
+
"entries": [
|
| 24 |
+
{
|
| 25 |
+
"startedDateTime": "2025-11-05T16:03:18.895+10:30",
|
| 26 |
+
"request": {
|
| 27 |
+
"bodySize": 5553,
|
| 28 |
+
"method": "POST",
|
| 29 |
+
"url": "https://lmarena.ai/nextjs-api/stream/create-evaluation",
|
| 30 |
+
"httpVersion": "HTTP/2",
|
| 31 |
+
"headers": [
|
| 32 |
+
{
|
| 33 |
+
"name": "Host",
|
| 34 |
+
"value": "lmarena.ai"
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"name": "User-Agent",
|
| 38 |
+
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0"
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"name": "Accept",
|
| 42 |
+
"value": "*/*"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"name": "Accept-Language",
|
| 46 |
+
"value": "en-AU,en-GB;q=0.7,en;q=0.3"
|
| 47 |
+
},
|
| 48 |
+
{
|
| 49 |
+
"name": "Accept-Encoding",
|
| 50 |
+
"value": "gzip, deflate, br, zstd"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"name": "Referer",
|
| 54 |
+
"value": "https://lmarena.ai/c/019a5281-4db4-7a93-893c-bebca39ea8d5"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"name": "Content-Type",
|
| 58 |
+
"value": "text/plain;charset=UTF-8"
|
| 59 |
+
},
|
| 60 |
+
{
|
| 61 |
+
"name": "Content-Length",
|
| 62 |
+
"value": "5553"
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
"name": "Origin",
|
| 66 |
+
"value": "https://lmarena.ai"
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"name": "DNT",
|
| 70 |
+
"value": "1"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"name": "Sec-GPC",
|
| 74 |
+
"value": "1"
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"name": "Connection",
|
| 78 |
+
"value": "keep-alive"
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"name": "Cookie",
|
| 82 |
+
"value": "cf_clearance=AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M; sidebar_state=true; arena-auth-prod-v1=base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0; ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog=%7B%22distinct_id%22%3A%22019a42cc-921e-74d4-b305-fbf75305f6a4%22%2C%22%24sesid%22%3A%5B1762057303275%2C%22019a42cc-921d-79b7-a7ec-b9e464e2f6ff%22%2C1762057294365%5D%7D; __cf_bm=ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM; ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog=%7B%22distinct_id%22%3A%229bc84c01-7a60-496b-9130-227aab812129%22%2C%22%24sesid%22%3A%5B1762320798490%2C%22019a5280-e3cd-735c-ae72-a5891eb7f55d%22%2C1762320769997%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22https%3A%2F%2Flmarena.ai%2F%3F__cf_chl_tk%3D.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A%22%2C%22u%22%3A%22https%3A%2F%2Flmarena.ai%2F%22%7D%7D"
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
"name": "Sec-Fetch-Dest",
|
| 86 |
+
"value": "empty"
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
"name": "Sec-Fetch-Mode",
|
| 90 |
+
"value": "cors"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"name": "Sec-Fetch-Site",
|
| 94 |
+
"value": "same-origin"
|
| 95 |
+
},
|
| 96 |
+
{
|
| 97 |
+
"name": "Priority",
|
| 98 |
+
"value": "u=4"
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"name": "TE",
|
| 102 |
+
"value": "trailers"
|
| 103 |
+
}
|
| 104 |
+
],
|
| 105 |
+
"cookies": [
|
| 106 |
+
{
|
| 107 |
+
"name": "cf_clearance",
|
| 108 |
+
"value": "AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M"
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"name": "sidebar_state",
|
| 112 |
+
"value": "true"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"name": "arena-auth-prod-v1",
|
| 116 |
+
"value": "base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0"
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"name": "ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog",
|
| 120 |
+
"value": "{\"distinct_id\":\"019a42cc-921e-74d4-b305-fbf75305f6a4\",\"$sesid\":[1762057303275,\"019a42cc-921d-79b7-a7ec-b9e464e2f6ff\",1762057294365]}"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"name": "__cf_bm",
|
| 124 |
+
"value": "ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM"
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"name": "ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog",
|
| 128 |
+
"value": "{\"distinct_id\":\"9bc84c01-7a60-496b-9130-227aab812129\",\"$sesid\":[1762320798490,\"019a5280-e3cd-735c-ae72-a5891eb7f55d\",1762320769997],\"$epp\":true,\"$initial_person_info\":{\"r\":\"https://lmarena.ai/?__cf_chl_tk=.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A\",\"u\":\"https://lmarena.ai/\"}}"
|
| 129 |
+
}
|
| 130 |
+
],
|
| 131 |
+
"queryString": [],
|
| 132 |
+
"headersSize": 3481,
|
| 133 |
+
"postData": {
|
| 134 |
+
"mimeType": "text/plain;charset=UTF-8",
|
| 135 |
+
"params": [],
|
| 136 |
+
"text": "{\"id\":\"019a5281-4db4-7a93-893c-bebca39ea8d5\",\"mode\":\"battle\",\"userMessageId\":\"019a5281-52f8-7f98-afa5-ffd215f1937d\",\"modelAMessageId\":\"019a5281-52f8-706a-8c03-99dfcfe6ca49\",\"modelBMessageId\":\"019a5281-52f8-77ec-8576-9bf59da36b4b\",\"messages\":[{\"id\":\"019a5281-52f8-7f98-afa5-ffd215f1937d\",\"role\":\"user\",\"content\":\"[{'type': 'text', 'text': '<task>\\\\ntest\\\\n</task>'}, {'type': 'text', 'text': '\\\\n# TODO LIST RECOMMENDED\\\\n\\\\nWhen starting a new task, it is recommended to create a todo list.\\\\n\\\\n\\\\n1. Include the task_progress parameter in your next tool call\\\\n2. Create a comprehensive checklist of all steps needed\\\\n3. Use markdown format: - [ ] for incomplete, - [x] for complete\\\\n\\\\n**Benefits of creating a todo list now:**\\\\n\\\\t- Clear roadmap for implementation\\\\n\\\\t- Progress tracking throughout the task\\\\n\\\\t- Nothing gets forgotten or missed\\\\n\\\\t- Users can see, monitor, and edit the plan\\\\n\\\\n**Example structure:**```\\\\n- [ ] Analyze requirements\\\\n- [ ] Set up necessary files\\\\n- [ ] Implement main functionality\\\\n- [ ] Handle edge cases\\\\n- [ ] Test the implementation\\\\n- [ ] Verify results```\\\\n\\\\nKeeping the todo list updated helps track progress and ensures nothing is missed.\\\\n'}, {'type': 'text', 'text': '<environment_details>\\\\n# Visual Studio Code Visible Files\\\\nchat_interactive.py\\\\n\\\\n# Visual Studio Code Open Tabs\\\\nsrc/main.py\\\\nchat_interactive.py\\\\n\\\\n# Current Time\\\\n11/5/2025, 4:02:23 PM (Australia/Adelaide, UTC+10.5:00)\\\\n\\\\n# Current Working Directory (c:/Users/Edward/Desktop/Projects/lmarenabridge) Files\\\\n.cache_ggshield\\\\nchat_interactive.py\\\\nconfig.json\\\\nmodels.json\\\\noutput.txt\\\\nPLAN.MD\\\\nREADME.md\\\\nrequirements.txt\\\\ntest_openai_api.py\\\\ntest_uuid.py\\\\ntimeout_debug.png\\\\ntoken_timeout.png\\\\nuuid7_impl.py\\\\nsamples/\\\\nsamples/2398-19f71176cd9db168.js\\\\nsamples/7551-c7019e0865514821.js\\\\nsamples/camoufoxdocsample.txt\\\\nsamples/eval-create.har\\\\nsamples/followup.har\\\\nsamples/lmarena.ai_nextjs-api_stream_create-evaluation_Archive [25-11-04 17-09-31].har\\\\nsamples/models.txt\\\\nsamples/oldscript.js\\\\nsamples/openapi.documented.yml\\\\nsamples/sample.txt\\\\nsamples/script.js\\\\nsrc/\\\\nsrc/main.py\\\\n\\\\n# Workspace Configuration\\\\n{\\\\n \\\"workspaces\\\": {\\\\n \\\"c:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\Edward\\\\\\\\\\\\\\\\Desktop\\\\\\\\\\\\\\\\Projects\\\\\\\\\\\\\\\\lmarenabridge\\\": {\\\\n \\\"hint\\\": \\\"lmarenabridge\\\",\\\\n \\\"associatedRemoteUrls\\\": [\\\\n \\\"origin: https://github.com/cloudwaddie/lmarenabridge.git\\\"\\\\n ],\\\\n \\\"latestGitCommitHash\\\": \\\"b37b728c29e242787b446c3f14d3296fe23efac2\\\"\\\\n }\\\\n }\\\\n}\\\\n\\\\n# Detected CLI Tools\\\\nThese are some of the tools on the user\\\\'s machine, and may be useful if needed to accomplish the task: git, npm, yarn, pnpm, pip, curl, python, node, sqlite3, code, dotnet. This list is not exhaustive, and other tools may be available.\\\\n\\\\n# Context Window Usage\\\\n0 / 128K tokens used (0%)\\\\n\\\\n# Current Mode\\\\nACT MODE\\\\n</environment_details>'}]\",\"experimental_attachments\":[],\"parentMessageIds\":[],\"participantPosition\":\"a\",\"modelId\":null,\"evaluationSessionId\":\"019a5281-4db4-7a93-893c-bebca39ea8d5\",\"status\":\"pending\",\"failureReason\":null},{\"id\":\"019a5281-52f8-706a-8c03-99dfcfe6ca49\",\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5281-52f8-7f98-afa5-ffd215f1937d\"],\"participantPosition\":\"a\",\"modelId\":null,\"evaluationSessionId\":\"019a5281-4db4-7a93-893c-bebca39ea8d5\",\"status\":\"pending\",\"failureReason\":null},{\"id\":\"019a5281-52f8-77ec-8576-9bf59da36b4b\",\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5281-52f8-7f98-afa5-ffd215f1937d\"],\"participantPosition\":\"b\",\"modelId\":null,\"evaluationSessionId\":\"019a5281-4db4-7a93-893c-bebca39ea8d5\",\"status\":\"pending\",\"failureReason\":null}],\"modality\":\"chat\",\"recaptchaV3Token\":\"0cAFcWeA7rSOJoWm88qONBkDLPoVhTYVmEMaoXf3amYT69B613S2JuUx6JF-hJuvdmLTKJSnHaUu2e2SuxJE60fq1-ECpSjUNC5uAp4DTWtWXLHjQWmfbNzoRpXQVbmy6geHttsV6pNPdz1k4UVSEiWpc78hR3FUKY9NHuEq9trY5UM2t4FwNt7bb_T-N_ghMuWWgAHXZF6lzK3oMJZxVw5jMH3D6A3Ux3NmB7mqCdh5ZmYVjzB-sXXsDcDc_i9-uuzhTXN2e6WdoC-CW5P4fJs_Cq5-z73UHtHkp5nybBQKe0Y1V3kMT1uxq5jTDNR-vDxVEWRC8YQMDefBDOQn1_oVRQGavzUMZu-ZKYLKy1I_LW3qgbpRONGfl90d042hhnA0wXOKCRfJGUjGEPvs524xRuhFPvi-VksGZzn-Bs7yekk65vSmcTKGriQ07okEXAl8nb240tyjm7k3U_x9i99sj7yileMesBGPBsUcmMGytLIg0Cp9vT-k5-GeqCAk9wVtept8N1H1tMDYdwdYpvxJBIoayzTSj2tD7jmbSLA0Jw4zvVHSVqRJ7Ztuqh208dw6FvvRj6Z2LEmq-o_j64l9VxEVtnISa5YanFjAKMmyOjjwphg-7vh02apW7zPOAIY4YrmnhyQ-NGNRFT-X5aenDoeNdfQwpPnP27WruC0do1XyEMLol8UBb9lBafkxXBW7PRcA_gPzJ0h93nYdU579TKkVLs6jOSSEiLLmRl4NfzuUqTZBnX2wncA0anCZzf2YkeOXFPKfGzoK2V8E0d4axodilrp3zSlf3LVCePswqB-6a5tRZWk61FAuS0TeoJVgL13JEgJOdtYRMBsCgv6QGhaDg1YmPm_sGsc00mR6LtXsVaQuOfwLMoFuDxn-uya4KiR4ufzJb3tJn6CDpzGzEbvwj-ZROXxVX0RAHtlxPjwgEZ-Abi53mOru4RGAfKt7bII_q_KnKEuT-P1R-gRnWDiagNjlnZkMn54rZUHCkb8I5cBw5Jgc_NxutSEajupl6qt4gHUDU8pAxAorV-NWXT9WTA4k-OW7w3kahMtS2vCUC46qJPio_9xOkANo_iINpqyHCtpRMFPCCkLKcAyz-yryJVXYMgD2AsvcQPHIyQ1EDEAfoEn9w0COltnk_GdAoSxnWnn7IFSahDx9zPkQZMo1-stiLn7FFzTIjm0ajLjaZlXBde6-jr_pAcYhMdnqEBbRVbDjbf15ZDD0zzeb-N1H2iqpROnpjrERJ1QLH8F6a2Gyary2Mxp_IxucGPbHWEIaMR6XI4lVwSXtFdRg7y4YJvpl22n9x4ggKNArMFx2DSOJBRr0Ejf7BcT-Sukd4Zcg6K68DaRu3qNgQhpYxAkkJpt0fRtyWDKgJ8jDyH01n0-RNhzTWn24G4Dyt4NCgDWrn2-hDwsHSmwmfbi-2T5kCE8SJY9TGQb-oaCXVS_fRQKE_zN9BAdaY2leILJcyXDbokm5OVfyP-BRueIQQB3iUYPp6xysc5PYoR5iVynoDFX48Nqc3tEEBEE4C6clqo3xyuQFQPdzvsT2wXtY1T8Hv53WjBLSmRxVfPgJaPxs52HDJ40Ji6Ly48TyAA6snWWNjx4yHcO_cWZehR7apmdTzxqezJUvDMV72DeSxN7fyZOosRRhSMjY6l7VmP1RWHwRIlePpswEKVDbJ9qHXrZILIHdBpwn9TfxujKlUgoJyy7lxoNE8\"}"
|
| 137 |
+
}
|
| 138 |
+
},
|
| 139 |
+
"response": {
|
| 140 |
+
"status": 200,
|
| 141 |
+
"statusText": "",
|
| 142 |
+
"httpVersion": "HTTP/2",
|
| 143 |
+
"headers": [
|
| 144 |
+
{
|
| 145 |
+
"name": "date",
|
| 146 |
+
"value": "Wed, 05 Nov 2025 05:33:25 GMT"
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"name": "content-type",
|
| 150 |
+
"value": "text/event-stream"
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"name": "server",
|
| 154 |
+
"value": "cloudflare"
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"name": "cf-ray",
|
| 158 |
+
"value": "9999f9c689ceed73-ADL"
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"name": "cf-cache-status",
|
| 162 |
+
"value": "DYNAMIC"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"name": "access-control-allow-origin",
|
| 166 |
+
"value": "*"
|
| 167 |
+
},
|
| 168 |
+
{
|
| 169 |
+
"name": "cache-control",
|
| 170 |
+
"value": "no-cache"
|
| 171 |
+
},
|
| 172 |
+
{
|
| 173 |
+
"name": "strict-transport-security",
|
| 174 |
+
"value": "max-age=63072000; includeSubDomains; preload"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"name": "vary",
|
| 178 |
+
"value": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding"
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"name": "ratelimit",
|
| 182 |
+
"value": "limit=3000, remaining=2955, reset=15"
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"name": "ratelimit-policy",
|
| 186 |
+
"value": "3000;w=300"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"name": "x-content-type-options",
|
| 190 |
+
"value": "nosniff"
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"name": "x-matched-path",
|
| 194 |
+
"value": "/nextjs-api/stream/create-evaluation"
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"name": "x-request-id",
|
| 198 |
+
"value": "207f91c2-fba7-4a76-be85-6e4b91f040b5"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"name": "x-vercel-cache",
|
| 202 |
+
"value": "MISS"
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"name": "x-vercel-id",
|
| 206 |
+
"value": "syd1:syd1:sfo1::sfo1::sfo1::nvblt-1762320799790-fd0cb415594e"
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"name": "x-vercel-request-id",
|
| 210 |
+
"value": "207f91c2-fba7-4a76-be85-6e4b91f040b5"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"name": "alt-svc",
|
| 214 |
+
"value": "h3=\":443\"; ma=86400"
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"name": "X-Firefox-Spdy",
|
| 218 |
+
"value": "h2"
|
| 219 |
+
}
|
| 220 |
+
],
|
| 221 |
+
"cookies": [],
|
| 222 |
+
"content": {
|
| 223 |
+
"mimeType": "text/event-stream",
|
| 224 |
+
"size": 8254,
|
| 225 |
+
"text": "a0:\"\\nI'll \"\nb0:\"<tool_code>\\n\"\na0:\"create \"\nb0:\"print(task_progress=\\\"starting \"\na0:\"a \"\nb0:\"task \"\na0:\"comprehensive \"\nb0:\"'test'\\\")\\n\"\na0:\"testing \"\nb0:\"</tool_code>\\n\"\na0:\"plan \"\nb0:\"<task>\\n\"\na0:\"for \"\nb0:\"test\\n\"\na0:\"the \"\nb0:\"</task>\\n\"\na0:\"lmarenabridge \"\nb0:\"# \"\na0:\"project. \"\nb0:\"TODO \"\na0:\"Here's \"\nb0:\"LIST \"\na0:\"the \"\nb0:\"RECOMMENDED\\n\\n\"\na0:\"recommended \"\nb0:\"When \"\na0:\"TODO \"\nb0:\"starting \"\na0:\"list:\\n\\n\"\nb0:\"a \"\na0:\"```markdown\\n\"\nb0:\"new \"\na0:\"- \"\nb0:\"task, \"\na0:\"[ \"\nb0:\"it \"\na0:\"] \"\nb0:\"is \"\na0:\"Review \"\nb0:\"recommended \"\na0:\"project \"\nb0:\"to \"\na0:\"structure \"\nb0:\"create \"\na0:\"and \"\nb0:\"a \"\na0:\"identify \"\nb0:\"todo \"\na0:\"key \"\nb0:\"list.\\n\\n\\n\"\na0:\"components \"\nb0:\"1. \"\na0:\"to \"\nb0:\"Include \"\na0:\"test\\n\"\nb0:\"the \"\na0:\"- \"\nb0:\"task_progress \"\na0:\"[ \"\nb0:\"parameter \"\na0:\"] \"\nb0:\"in \"\na0:\"Set \"\nb0:\"your \"\na0:\"up \"\nb0:\"next \"\na0:\"test \"\nb0:\"tool \"\na0:\"environment\\n\"\nb0:\"call\\n\"\na0:\" - \"\nb0:\"2. \"\na0:\"[ \"\nb0:\"Create \"\na0:\"] \"\nb0:\"a \"\na0:\"Verify \"\nb0:\"comprehensive \"\na0:\"Python \"\nb0:\"checklist \"\na0:\"version \"\nb0:\"of \"\na0:\"and \"\nb0:\"all \"\na0:\"dependencies\\n\"\nb0:\"steps \"\na0:\" - \"\nb0:\"needed\\n\"\na0:\"[ \"\nb0:\"3. \"\na0:\"] \"\nb0:\"Use \"\na0:\"Install \"\nb0:\"markdown \"\na0:\"test \"\nb0:\"format: \"\na0:\"requirements\\n\"\nb0:\"- \"\na0:\" - \"\nb0:\"[ \"\na0:\"[ \"\nb0:\"] \"\na0:\"] \"\nb0:\"for \"\na0:\"Configure \"\nb0:\"incomplete, \"\na0:\"any \"\nb0:\"- \"\na0:\"necessary \"\nb0:\"[x] \"\na0:\"environment \"\nb0:\"for \"\na0:\"variables\\n\\n\"\nb0:\"complete\\n\\n\"\na0:\"- \"\nb0:\"**Benefits \"\na0:\"[ \"\nb0:\"of \"\na0:\"] \"\nb0:\"creating \"\na0:\"Unit \"\nb0:\"a \"\na0:\"Testing\\n\"\nb0:\"todo \"\na0:\" - \"\nb0:\"list \"\na0:\"[ \"\nb0:\"now:**\\n\\t\"\na0:\"] \"\nb0:\"- \"\na0:\"Test \"\nb0:\"Clear \"\na0:\"UUID7 \"\nb0:\"roadmap \"\na0:\"implementation \"\nb0:\"for \"\na0:\"(uuid7_impl.py)\\n\"\nb0:\"implementation\\n\\t\"\na0:\" - \"\nb0:\"- \"\na0:\"[ \"\nb0:\"Progress \"\na0:\"] \"\nb0:\"tracking \"\na0:\"Test \"\nb0:\"throughout \"\na0:\"configuration \"\nb0:\"the \"\na0:\"loading \"\nb0:\"task\\n\\t\"\na0:\"(config.json)\\n\"\nb0:\"- \"\na0:\" - \"\nb0:\"Nothing \"\na0:\"[ \"\nb0:\"gets \"\na0:\"] \"\nb0:\"forgotten \"\na0:\"Test \"\nb0:\"or \"\na0:\"models \"\nb0:\"missed\\n\\t\"\na0:\"configuration \"\nb0:\"- \"\na0:\"(models.json)\\n\\n\"\nb0:\"Users \"\na0:\"- \"\nb0:\"can \"\na0:\"[ \"\nb0:\"see, \"\na0:\"] \"\nb0:\"monitor, \"\na0:\"Integration \"\nb0:\"and \"\na0:\"Testing\\n\"\nb0:\"edit \"\na0:\" - \"\nb0:\"the \"\na0:\"[ \"\nb0:\"plan\\n\\n\"\na0:\"] \"\nb0:\"**Example \"\na0:\"Test \"\nb0:\"structure:**```\\n\"\na0:\"main \"\nb0:\"- \"\na0:\"application \"\nb0:\"[ \"\na0:\"flow \"\nb0:\"] \"\na0:\"(src/main.py)\\n\"\nb0:\"Analyze \"\na0:\" - \"\nb0:\"requirements\\n\"\na0:\"[ \"\nb0:\"- \"\na0:\"] \"\nb0:\"[ \"\na0:\"Test \"\nb0:\"] \"\na0:\"interactive \"\nb0:\"Set \"\na0:\"chat \"\nb0:\"up \"\na0:\"functionality \"\nb0:\"necessary \"\na0:\"(chat_interactive.py)\\n\"\nb0:\"files\\n\"\na0:\" - \"\nb0:\"- \"\na0:\"[ \"\nb0:\"[ \"\na0:\"] \"\nb0:\"] \"\na0:\"Verify \"\nb0:\"Implement \"\na0:\"API \"\nb0:\"main \"\na0:\"client \"\nb0:\"functionality\\n\"\na0:\"interactions\\n\\n\"\nb0:\"- \"\na0:\"- \"\nb0:\"[ \"\na0:\"[ \"\nb0:\"] \"\na0:\"] \"\nb0:\"Handle \"\na0:\"Functional \"\nb0:\"edge \"\na0:\"Testing\\n\"\nb0:\"cases\\n\"\na0:\" - \"\nb0:\"- \"\na0:\"[ \"\nb0:\"[ \"\na0:\"] \"\nb0:\"] \"\na0:\"Test \"\nb0:\"Test \"\na0:\"command-line \"\nb0:\"the \"\na0:\"interface \"\nb0:\"implementation\\n\"\na0:\"functionality\\n\"\nb0:\"- \"\na0:\" - \"\nb0:\"[ \"\na0:\"[ \"\nb0:\"] \"\na0:\"] \"\nb0:\"Verify \"\na0:\"Verify \"\nb0:\"results```\\n\\n\"\na0:\"output \"\nb0:\"Keeping \"\na0:\"file \"\nb0:\"the \"\na0:\"generation\\n\"\nb0:\"todo \"\na0:\" - \"\nb0:\"list \"\na0:\"[ \"\nb0:\"updated \"\na0:\"] \"\nb0:\"helps \"\na0:\"Test \"\nb0:\"track \"\na0:\"with \"\nb0:\"progress \"\na0:\"different \"\nb0:\"and \"\na0:\"input \"\nb0:\"ensures \"\na0:\"scenarios\\n\\n\"\nb0:\"nothing \"\na0:\"- \"\nb0:\"is \"\na0:\"[ \"\nb0:\"missed.\\n\\n\"\na0:\"] \"\nb0:\"<environment_details>\\n\"\na0:\"Edge \"\nb0:\"# \"\na0:\"Case \"\nb0:\"Visual \"\na0:\"Testing\\n\"\nb0:\"Studio \"\na0:\" - \"\nb0:\"Code \"\na0:\"[ \"\nb0:\"Visible \"\na0:\"] \"\nb0:\"Files\\n\"\na0:\"Test \"\nb0:\"chat_interactive.py\\n\\n\"\na0:\"with \"\nb0:\"# \"\na0:\"invalid \"\nb0:\"Visual \"\na0:\"inputs\\n\"\nb0:\"Studio \"\na0:\" - \"\nb0:\"Code \"\na0:\"[ \"\nb0:\"Open \"\na0:\"] \"\nb0:\"Tabs\\n\"\na0:\"Test \"\nb0:\"src/main.py\\n\"\na0:\"with \"\nb0:\"chat_interactive.py\\n\\n\"\na0:\"missing \"\nb0:\"# \"\na0:\"configuration \"\nb0:\"Current \"\na0:\"files\\n\"\nb0:\"Time\\n\"\na0:\" - \"\nb0:\"11/5/2025, \"\na0:\"[ \"\nb0:\"4:02:23 \"\na0:\"] \"\nb0:\"PM \"\na0:\"Test \"\nb0:\"(Australia/Adelaide, \"\na0:\"network \"\nb0:\"UTC+10.5:00)\\n\\n\"\na0:\"timeout \"\nb0:\"# \"\na0:\"scenarios\\n\"\nb0:\"Current \"\na0:\" - \"\nb0:\"Working \"\na0:\"[ \"\nb0:\"Directory \"\na0:\"] \"\nb0:\"(c:/Users/Edward/Desktop/Projects/lmarenabridge) \"\na0:\"Test \"\nb0:\"Files\\n\"\na0:\"with \"\nb0:\".cache_ggshield\\n\"\na0:\"maximum \"\nb0:\"chat_interactive.py\\n\"\na0:\"input \"\nb0:\"config.json\\n\"\na0:\"sizes\\n\\n\"\nb0:\"models.json\\n\"\na0:\"- \"\nb0:\"output.txt\\n\"\na0:\"[ \"\nb0:\"PLAN.MD\\n\"\na0:\"] \"\nb0:\"README.md\\n\"\na0:\"Performance \"\nb0:\"requirements.txt\\n\"\na0:\"Testing\\n\"\nb0:\"test_openai_api.py\\n\"\na0:\" - \"\nb0:\"test_uuid.py\\n\"\na0:\"[ \"\nb0:\"timeout_debug.png\\n\"\na0:\"] \"\nb0:\"token_timeout.png\\n\"\na0:\"Measure \"\nb0:\"uuid7_impl.py\\n\"\na0:\"response \"\nb0:\"samples/\\n\"\na0:\"times\\n\"\nb0:\"samples/2398-19f71176cd9db168.js\\n\"\na0:\" - \"\nb0:\"samples/7551-c7019e0865514821.js\\n\"\na0:\"[ \"\nb0:\"samples/camoufoxdocsample.txt\\n\"\na0:\"] \"\nb0:\"samples/eval-create.har\\n\"\na0:\"Test \"\nb0:\"samples/followup.har\\n\"\na0:\"under \"\nb0:\"samples/lmarena.ai_nextjs-api_stream_create-evaluation_Archive \"\na0:\"load\\n\"\nb0:\"[25-11-04 \"\na0:\" - \"\nb0:\"17-09-31].har\\n\"\na0:\"[ \"\nb0:\"samples/models.txt\\n\"\na0:\"] \"\nb0:\"samples/oldscript.js\\n\"\na0:\"Monitor \"\nb0:\"samples/openapi.documented.yml\\n\"\na0:\"memory \"\nb0:\"samples/sample.txt\\n\"\na0:\"usage\\n\\n\"\nb0:\"samples/script.js\\n\"\na0:\"- \"\nb0:\"src/\\n\"\na0:\"[ \"\nb0:\"src/main.py\\n\\n\"\na0:\"] \"\nb0:\"# \"\na0:\"Documentation \"\nb0:\"Workspace \"\na0:\"Verification\\n\"\nb0:\"Configuration\\n\"\na0:\" - \"\nb0:\"{\\n \"\na0:\"[ \"\nb0:\"\\\"workspaces\\\": \"\na0:\"] \"\nb0:\"{\\n \"\na0:\"Verify \"\nb0:\"\\\"c:\\\\\\\\Users\\\\\\\\Edward\\\\\\\\Desktop\\\\\\\\Projects\\\\\\\\lmarenabridge\\\": \"\na0:\"README \"\nb0:\"{\\n \"\na0:\"instructions\\n\"\nb0:\"\\\"hint\\\": \"\na0:\" - \"\nb0:\"\\\"lmarenabridge\\\",\\n \"\na0:\"[ \"\nb0:\"\\\"associatedRemoteUrls\\\": \"\na0:\"] \"\nb0:\"[\\n \"\na0:\"Check \"\nb0:\"\\\"origin: \"\na0:\"PLAN.MD \"\nb0:\"https://github.com/cloudwaddie/lmarenabridge.git\\\"\\n \"\na0:\"for \"\nb0:\"],\\n \"\na0:\"completeness\\n\"\nb0:\"\\\"latestGitCommitHash\\\": \"\na0:\" - \"\nb0:\"\\\"b37b728c29e242787b446c3f14d3296fe23efac2\\\"\\n \"\na0:\"[ \"\nb0:\"}\\n \"\na0:\"] \"\nb0:\"}\\n\"\na0:\"Update \"\nb0:\"}\\n\\n\"\na0:\"any \"\nb0:\"# \"\na0:\"outdated \"\nb0:\"Detected \"\na0:\"documentation\\n\\n\"\nb0:\"CLI \"\na0:\"- \"\nb0:\"Tools\\n\"\na0:\"[ \"\nb0:\"These \"\na0:\"] \"\nb0:\"are \"\na0:\"Final \"\nb0:\"some \"\na0:\"Verification\\n\"\nb0:\"of \"\na0:\" - \"\nb0:\"the \"\na0:\"[ \"\nb0:\"tools \"\na0:\"] \"\nb0:\"on \"\na0:\"Run \"\nb0:\"the \"\na0:\"all \"\nb0:\"user's \"\na0:\"tests\\n\"\nb0:\"machine, \"\na0:\" - \"\nb0:\"and \"\na0:\"[ \"\nb0:\"may \"\na0:\"] \"\nb0:\"be \"\na0:\"Verify \"\nb0:\"useful \"\na0:\"test \"\nb0:\"if \"\na0:\"coverage\\n\"\nb0:\"needed \"\na0:\" - \"\nb0:\"to \"\na0:\"[ \"\nb0:\"accomplish \"\na0:\"] \"\nb0:\"the \"\na0:\"Document \"\nb0:\"task: \"\na0:\"test \"\nb0:\"git, \"\na0:\"results\\n\"\nb0:\"npm, \"\na0:\" - \"\nb0:\"yarn, \"\na0:\"[ \"\nb0:\"pnpm, \"\na0:\"] \"\nb0:\"pip, \"\na0:\"Create \"\nb0:\"curl, \"\na0:\"test \"\nb0:\"python, \"\na0:\"summary \"\nb0:\"node, \"\na0:\"report\\n\"\nb0:\"sqlite3, \"\na0:\"```\\n\\n\"\nb0:\"code, \"\na0:\"This \"\nb0:\"dotnet. \"\na0:\"plan \"\nb0:\"This \"\na0:\"covers \"\nb0:\"list \"\na0:\"all \"\nb0:\"is \"\na0:\"major \"\nb0:\"not \"\na0:\"aspects \"\nb0:\"exhaustive, \"\na0:\"of \"\nb0:\"and \"\na0:\"testing \"\nb0:\"other \"\na0:\"for \"\nb0:\"tools \"\na0:\"the \"\nb0:\"may \"\na0:\"project. \"\nb0:\"be \"\na0:\"Would \"\nb0:\"available.\\n\\n\"\na0:\"you \"\nb0:\"# \"\na0:\"like \"\nb0:\"Context \"\na0:\"me \"\nb0:\"Window \"\na0:\"to \"\nb0:\"Usage\\n\"\na0:\"proceed \"\nb0:\"0 \"\na0:\"with \"\nb0:\"/ \"\na0:\"any \"\nb0:\"128K \"\na0:\"specific \"\nb0:\"tokens \"\na0:\"part \"\nb0:\"used \"\na0:\"of \"\nb0:\"(0%)\\n\\n\"\na0:\"this \"\nb0:\"# \"\na0:\"testing \"\nb0:\"Current \"\na0:\"plan?\"\nb0:\"Mode\\n\"\nad:{\"finishReason\":\"stop\"}\nb0:\"ACT \"\nb0:\"MODE\\n\"\nb0:\"</environment_details>\\n\"\nb0:\"<todo_list>\\n\"\nb0:\"- \"\nb0:\"[ \"\nb0:\"] \"\nb0:\"Analyze \"\nb0:\"the \"\nb0:\"task \"\nb0:\"\\\"test\\\" \"\nb0:\"to \"\nb0:\"determine \"\nb0:\"the \"\nb0:\"required \"\nb0:\"actions.\\n\"\nb0:\"- \"\nb0:\"[ \"\nb0:\"] \"\nb0:\"If \"\nb0:\"\\\"test\\\" \"\nb0:\"implies \"\nb0:\"running \"\nb0:\"existing \"\nb0:\"tests, \"\nb0:\"identify \"\nb0:\"the \"\nb0:\"correct \"\nb0:\"command.\\n\"\nb0:\"- \"\nb0:\"[ \"\nb0:\"] \"\nb0:\"If \"\nb0:\"\\\"test\\\" \"\nb0:\"requires \"\nb0:\"a \"\nb0:\"specific \"\nb0:\"action \"\nb0:\"related \"\nb0:\"to \"\nb0:\"the \"\nb0:\"current \"\nb0:\"environment, \"\nb0:\"formulate \"\nb0:\"that \"\nb0:\"action.\\n\"\nb0:\"- \"\nb0:\"[ \"\nb0:\"] \"\nb0:\"Execute \"\nb0:\"the \"\nb0:\"necessary \"\nb0:\"action(s).\\n\"\nb0:\"- \"\nb0:\"[ \"\nb0:\"] \"\nb0:\"Update \"\nb0:\"the \"\nb0:\"todo \"\nb0:\"list \"\nb0:\"status.\\n\"\nb0:\"</todo_list>\"\nbd:{\"finishReason\":\"stop\"}\n"
|
| 226 |
+
},
|
| 227 |
+
"redirectURL": "",
|
| 228 |
+
"headersSize": 819,
|
| 229 |
+
"bodySize": 9073
|
| 230 |
+
},
|
| 231 |
+
"cache": {},
|
| 232 |
+
"timings": {
|
| 233 |
+
"blocked": 0,
|
| 234 |
+
"dns": 0,
|
| 235 |
+
"connect": 0,
|
| 236 |
+
"ssl": 0,
|
| 237 |
+
"send": 0,
|
| 238 |
+
"wait": 6087,
|
| 239 |
+
"receive": 0
|
| 240 |
+
},
|
| 241 |
+
"time": 6087,
|
| 242 |
+
"_securityState": "secure",
|
| 243 |
+
"serverIPAddress": "104.18.20.173",
|
| 244 |
+
"connection": "443",
|
| 245 |
+
"pageref": "page_1"
|
| 246 |
+
}
|
| 247 |
+
]
|
| 248 |
+
}
|
| 249 |
+
}
|
samples/multiple.har
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"log": {
|
| 3 |
+
"version": "1.2",
|
| 4 |
+
"creator": {
|
| 5 |
+
"name": "Zen",
|
| 6 |
+
"version": "1.17.4b"
|
| 7 |
+
},
|
| 8 |
+
"browser": {
|
| 9 |
+
"name": "Zen",
|
| 10 |
+
"version": "1.17.4b"
|
| 11 |
+
},
|
| 12 |
+
"pages": [
|
| 13 |
+
{
|
| 14 |
+
"id": "page_2",
|
| 15 |
+
"pageTimings": {
|
| 16 |
+
"onContentLoad": -1,
|
| 17 |
+
"onLoad": -1
|
| 18 |
+
},
|
| 19 |
+
"startedDateTime": "2025-11-05T16:10:02.891+10:30",
|
| 20 |
+
"title": "https://lmarena.ai/c/019a5281-4db4-7a93-893c-bebca39ea8d5"
|
| 21 |
+
}
|
| 22 |
+
],
|
| 23 |
+
"entries": [
|
| 24 |
+
{
|
| 25 |
+
"startedDateTime": "2025-11-05T16:10:02.891+10:30",
|
| 26 |
+
"request": {
|
| 27 |
+
"bodySize": 2700,
|
| 28 |
+
"method": "POST",
|
| 29 |
+
"url": "https://lmarena.ai/nextjs-api/stream/create-evaluation",
|
| 30 |
+
"httpVersion": "HTTP/2",
|
| 31 |
+
"headers": [
|
| 32 |
+
{
|
| 33 |
+
"name": "Host",
|
| 34 |
+
"value": "lmarena.ai"
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"name": "User-Agent",
|
| 38 |
+
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0"
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"name": "Accept",
|
| 42 |
+
"value": "*/*"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"name": "Accept-Language",
|
| 46 |
+
"value": "en-AU,en-GB;q=0.7,en;q=0.3"
|
| 47 |
+
},
|
| 48 |
+
{
|
| 49 |
+
"name": "Accept-Encoding",
|
| 50 |
+
"value": "gzip, deflate, br, zstd"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"name": "Referer",
|
| 54 |
+
"value": "https://lmarena.ai/c/019a5287-4db3-7be6-8a47-5e60754b9488"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"name": "Content-Type",
|
| 58 |
+
"value": "text/plain;charset=UTF-8"
|
| 59 |
+
},
|
| 60 |
+
{
|
| 61 |
+
"name": "Content-Length",
|
| 62 |
+
"value": "2700"
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
"name": "Origin",
|
| 66 |
+
"value": "https://lmarena.ai"
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"name": "DNT",
|
| 70 |
+
"value": "1"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"name": "Sec-GPC",
|
| 74 |
+
"value": "1"
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"name": "Connection",
|
| 78 |
+
"value": "keep-alive"
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"name": "Cookie",
|
| 82 |
+
"value": "cf_clearance=AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M; sidebar_state=true; arena-auth-prod-v1=base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0; ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog=%7B%22distinct_id%22%3A%22019a42cc-921e-74d4-b305-fbf75305f6a4%22%2C%22%24sesid%22%3A%5B1762057303275%2C%22019a42cc-921d-79b7-a7ec-b9e464e2f6ff%22%2C1762057294365%5D%7D; __cf_bm=ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM; ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog=%7B%22distinct_id%22%3A%229bc84c01-7a60-496b-9130-227aab812129%22%2C%22%24sesid%22%3A%5B1762321202426%2C%22019a5280-e3cd-735c-ae72-a5891eb7f55d%22%2C1762320769997%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22https%3A%2F%2Flmarena.ai%2F%3F__cf_chl_tk%3D.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A%22%2C%22u%22%3A%22https%3A%2F%2Flmarena.ai%2F%22%7D%7D"
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
"name": "Sec-Fetch-Dest",
|
| 86 |
+
"value": "empty"
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
"name": "Sec-Fetch-Mode",
|
| 90 |
+
"value": "cors"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"name": "Sec-Fetch-Site",
|
| 94 |
+
"value": "same-origin"
|
| 95 |
+
},
|
| 96 |
+
{
|
| 97 |
+
"name": "Priority",
|
| 98 |
+
"value": "u=4"
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"name": "TE",
|
| 102 |
+
"value": "trailers"
|
| 103 |
+
}
|
| 104 |
+
],
|
| 105 |
+
"cookies": [
|
| 106 |
+
{
|
| 107 |
+
"name": "cf_clearance",
|
| 108 |
+
"value": "AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M"
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"name": "sidebar_state",
|
| 112 |
+
"value": "true"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"name": "arena-auth-prod-v1",
|
| 116 |
+
"value": "base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0"
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"name": "ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog",
|
| 120 |
+
"value": "{\"distinct_id\":\"019a42cc-921e-74d4-b305-fbf75305f6a4\",\"$sesid\":[1762057303275,\"019a42cc-921d-79b7-a7ec-b9e464e2f6ff\",1762057294365]}"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"name": "__cf_bm",
|
| 124 |
+
"value": "ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM"
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"name": "ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog",
|
| 128 |
+
"value": "{\"distinct_id\":\"9bc84c01-7a60-496b-9130-227aab812129\",\"$sesid\":[1762321202426,\"019a5280-e3cd-735c-ae72-a5891eb7f55d\",1762320769997],\"$epp\":true,\"$initial_person_info\":{\"r\":\"https://lmarena.ai/?__cf_chl_tk=.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A\",\"u\":\"https://lmarena.ai/\"}}"
|
| 129 |
+
}
|
| 130 |
+
],
|
| 131 |
+
"queryString": [],
|
| 132 |
+
"headersSize": 3481,
|
| 133 |
+
"postData": {
|
| 134 |
+
"mimeType": "text/plain;charset=UTF-8",
|
| 135 |
+
"params": [],
|
| 136 |
+
"text": "{\"id\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"mode\":\"direct\",\"modelAId\":\"0199f060-b306-7e1f-aeae-0ebb4e3f1122\",\"userMessageId\":\"019a5287-7cd2-711e-a44b-da372fa139d5\",\"modelAMessageId\":\"019a5287-7cd3-731e-a2e4-82b761f33cc7\",\"messages\":[{\"id\":\"019a5287-7cd2-711e-a44b-da372fa139d5\",\"role\":\"user\",\"content\":\"First message\",\"experimental_attachments\":[],\"parentMessageIds\":[],\"participantPosition\":\"a\",\"modelId\":null,\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"pending\",\"failureReason\":null},{\"id\":\"019a5287-7cd3-731e-a2e4-82b761f33cc7\",\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5287-7cd2-711e-a44b-da372fa139d5\"],\"participantPosition\":\"a\",\"modelId\":\"0199f060-b306-7e1f-aeae-0ebb4e3f1122\",\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"pending\",\"failureReason\":null}],\"modality\":\"chat\",\"recaptchaV3Token\":\"0cAFcWeA6tiCP1liFhb1oEbYWTdp4-mkeE9SptSRTFWfQF5giFXUU2_xACZOhzoUOHsZ5UZpQorHc36P19Fg6h6tfmuntuB0Vh83BnoAQCXYwRhoPIbrVzshhW7-h3ZOl0eAgF5VD8Hi3kF5YPARaT9hIH6X7RdaLwRx3kXhYZL8f1KBDDSVClmxB-dNUrvgxElaJisy6fN3IirqNTsNVWwOCB2gG6qHzcYHSnKjv0EOydkWBYr7DaYu3hUfXt72Q_YkSLpd__bf2ams7YE-ogF60rPQ2DDurE8OT7sE0JNGyUx_hEL8GBBQp-CCfISbD0Ts4cgu4OVlesH3KHPAG-gQtxRYbHLL9-SMnQdoHl7QWYpPrVNV1GUIUzPCY3qQ1qSV3cbHeq_ZdSdRn9cDbz7Ghy9FVE1JuaETNnXBsOSMTuZ9hNS5FDqRK8D_1ysYiikR0EhksSX5f-Uq1JUmSIAvGtTo47viaeftTZiwypSnDIZBX8-z6Fu24BsmOHbVOia0a_ezdlm6IWs2jsK69llXFW4QPjKtIVmP9LJIsHXCwwFLV3y06xBHZai03G8SGJuNhpvrPrfNfjEMjhaiMdeBF2f8uty4sj0Sb5zizNmJyEC0NwqjL8VwbYq58RhCb4IjJR6Rn3zDfgMWrtXAGSNaK7MYqfdGAlJxA_24xiEZQy4TSVA3e6_hQJL7IShx-zbIZSd7LJnL-VMeLeh7jxM9ntS4i0RfT-ND8P7hbp4icVDCGVBc9zgggTWrAl_vSEKpdmApPB5z2ZspCeC8suJSlhAR6D00608X0TgaWKO1erMX6GceMpu8QuknNQ7Ml1b9gigS4_XCOcmiyo0r0jqWxygPUtk87ZePC9DfU3c7PAW_HxZMO03sHRThJVu_iN6fGz1QGUQAFXJeDuy1fsVjbKSYwvKippO0M9Ho3jBi-Xk70rmCX0N7yav7cnB0yG4u6attK5lm7NowFq_dtBD6paQxLIyu7ibICvAENDwQLVTEZCmEdCnc2H_AQdklozdwkWFsY2d41MvjN2XK3jWj0UyCjEkaMuMvBFqMVO6IxI18hXdF0aQj7XAhVWCU-bnJkQWaRmqFF3cDsOY0N0r-q9E5uCekG6XN55-XSS-gnrS_Uqk5d2GMv0sliPVKh44zmhsVT-gVDDF1f0u-t08LjC7ls9uDDKORLX-VxQ9UQKqQC5UbBIhbLGqTp7bGXa7zQIZvDq3DGU-C_XmO5DcuzkXVoOcANvya5ZaEj2nxTS4eg09IcJD-vaKm5E2BxbxALeE9JpAdd8PGfpfTb37Tvz5ywh_1Y6UVbwKcDYfL4CDmit4LdxIllJE6Z797rBku5UTZzpYw-Btyk_TB_y5-mTzH8wMGPIJA6YEgwdx_UfCyGFSWbgWTMXp5jyRHCQGbWPJ5GL2pfAtWYHFdAYZuEAGC47yMyioAuE8CFf81wRJKPdYTzxcWZYM44YaXeN5o_MBe7U1GJjBPnfFA5DRT6f4EyEOqet0QZFjAhtTMxk_8Z5JBMommpT7Bvdz_o2dQTha28Eu2ovhzGDS3uzanoXJgFqyDdtkl0lwmDzNBmOX9rCF981-w_R96NrgxhaF2ynoHhhj5wm5VKWoi8ymWGf2JW38eYql9AgZWT7kbOvxMqi2ksPhtmYwYMjKwwuVp0zqm8z8m5nvz_lblLtOH_VISjT3L4JC6ymz3JPj_IrQOKHMHBixlC3ZKUghJnDMTgllZyoxrNvuf0YsEkJpM85kaaRI8AtEEVi1vupdIioWw8qLBXj4W0\"}"
|
| 137 |
+
}
|
| 138 |
+
},
|
| 139 |
+
"response": {
|
| 140 |
+
"status": 200,
|
| 141 |
+
"statusText": "",
|
| 142 |
+
"httpVersion": "HTTP/2",
|
| 143 |
+
"headers": [
|
| 144 |
+
{
|
| 145 |
+
"name": "date",
|
| 146 |
+
"value": "Wed, 05 Nov 2025 05:40:14 GMT"
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"name": "content-type",
|
| 150 |
+
"value": "text/event-stream"
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"name": "server",
|
| 154 |
+
"value": "cloudflare"
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"name": "cf-ray",
|
| 158 |
+
"value": "999a03a38e2bed73-ADL"
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"name": "cf-cache-status",
|
| 162 |
+
"value": "DYNAMIC"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"name": "access-control-allow-origin",
|
| 166 |
+
"value": "*"
|
| 167 |
+
},
|
| 168 |
+
{
|
| 169 |
+
"name": "cache-control",
|
| 170 |
+
"value": "no-cache"
|
| 171 |
+
},
|
| 172 |
+
{
|
| 173 |
+
"name": "strict-transport-security",
|
| 174 |
+
"value": "max-age=63072000; includeSubDomains; preload"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"name": "vary",
|
| 178 |
+
"value": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding"
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"name": "ratelimit",
|
| 182 |
+
"value": "limit=3000, remaining=2999, reset=60"
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"name": "ratelimit-policy",
|
| 186 |
+
"value": "3000;w=300"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"name": "x-content-type-options",
|
| 190 |
+
"value": "nosniff"
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"name": "x-matched-path",
|
| 194 |
+
"value": "/nextjs-api/stream/create-evaluation"
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"name": "x-request-id",
|
| 198 |
+
"value": "edbebfb6-3fbc-4b90-a1db-5009224aa790"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"name": "x-vercel-cache",
|
| 202 |
+
"value": "MISS"
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"name": "x-vercel-id",
|
| 206 |
+
"value": "syd1:syd1:sfo1::sfo1::sfo1::72f4m-1762321203819-7ea33e513fc2"
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"name": "x-vercel-request-id",
|
| 210 |
+
"value": "edbebfb6-3fbc-4b90-a1db-5009224aa790"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"name": "alt-svc",
|
| 214 |
+
"value": "h3=\":443\"; ma=86400"
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"name": "X-Firefox-Spdy",
|
| 218 |
+
"value": "h2"
|
| 219 |
+
}
|
| 220 |
+
],
|
| 221 |
+
"cookies": [],
|
| 222 |
+
"content": {
|
| 223 |
+
"mimeType": "text/event-stream",
|
| 224 |
+
"size": 119,
|
| 225 |
+
"text": "a0:\"Hello! \"\na0:\"Welcome.\\n\\n\"\na0:\"How \"\na0:\"can \"\na0:\"I \"\na0:\"help \"\na0:\"you \"\na0:\"today?\"\nad:{\"finishReason\":\"stop\"}\n"
|
| 226 |
+
},
|
| 227 |
+
"redirectURL": "",
|
| 228 |
+
"headersSize": 819,
|
| 229 |
+
"bodySize": 938
|
| 230 |
+
},
|
| 231 |
+
"cache": {},
|
| 232 |
+
"timings": {
|
| 233 |
+
"blocked": -1,
|
| 234 |
+
"dns": 0,
|
| 235 |
+
"connect": 0,
|
| 236 |
+
"ssl": 0,
|
| 237 |
+
"send": 0,
|
| 238 |
+
"wait": 11140,
|
| 239 |
+
"receive": 0
|
| 240 |
+
},
|
| 241 |
+
"time": 11140,
|
| 242 |
+
"_securityState": "secure",
|
| 243 |
+
"serverIPAddress": "104.18.20.173",
|
| 244 |
+
"connection": "443",
|
| 245 |
+
"pageref": "page_2"
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"startedDateTime": "2025-11-05T16:10:22.810+10:30",
|
| 249 |
+
"request": {
|
| 250 |
+
"bodySize": 3422,
|
| 251 |
+
"method": "POST",
|
| 252 |
+
"url": "https://lmarena.ai/nextjs-api/stream/post-to-evaluation/019a5287-4db3-7be6-8a47-5e60754b9488",
|
| 253 |
+
"httpVersion": "HTTP/2",
|
| 254 |
+
"headers": [
|
| 255 |
+
{
|
| 256 |
+
"name": "Host",
|
| 257 |
+
"value": "lmarena.ai"
|
| 258 |
+
},
|
| 259 |
+
{
|
| 260 |
+
"name": "User-Agent",
|
| 261 |
+
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0"
|
| 262 |
+
},
|
| 263 |
+
{
|
| 264 |
+
"name": "Accept",
|
| 265 |
+
"value": "*/*"
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
"name": "Accept-Language",
|
| 269 |
+
"value": "en-AU,en-GB;q=0.7,en;q=0.3"
|
| 270 |
+
},
|
| 271 |
+
{
|
| 272 |
+
"name": "Accept-Encoding",
|
| 273 |
+
"value": "gzip, deflate, br, zstd"
|
| 274 |
+
},
|
| 275 |
+
{
|
| 276 |
+
"name": "Referer",
|
| 277 |
+
"value": "https://lmarena.ai/c/019a5287-4db3-7be6-8a47-5e60754b9488"
|
| 278 |
+
},
|
| 279 |
+
{
|
| 280 |
+
"name": "Content-Type",
|
| 281 |
+
"value": "text/plain;charset=UTF-8"
|
| 282 |
+
},
|
| 283 |
+
{
|
| 284 |
+
"name": "Content-Length",
|
| 285 |
+
"value": "3422"
|
| 286 |
+
},
|
| 287 |
+
{
|
| 288 |
+
"name": "Origin",
|
| 289 |
+
"value": "https://lmarena.ai"
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"name": "DNT",
|
| 293 |
+
"value": "1"
|
| 294 |
+
},
|
| 295 |
+
{
|
| 296 |
+
"name": "Sec-GPC",
|
| 297 |
+
"value": "1"
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"name": "Connection",
|
| 301 |
+
"value": "keep-alive"
|
| 302 |
+
},
|
| 303 |
+
{
|
| 304 |
+
"name": "Cookie",
|
| 305 |
+
"value": "cf_clearance=AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M; sidebar_state=true; arena-auth-prod-v1=base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0; ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog=%7B%22distinct_id%22%3A%22019a42cc-921e-74d4-b305-fbf75305f6a4%22%2C%22%24sesid%22%3A%5B1762057303275%2C%22019a42cc-921d-79b7-a7ec-b9e464e2f6ff%22%2C1762057294365%5D%7D; __cf_bm=ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM; ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog=%7B%22distinct_id%22%3A%229bc84c01-7a60-496b-9130-227aab812129%22%2C%22%24sesid%22%3A%5B1762321222458%2C%22019a5280-e3cd-735c-ae72-a5891eb7f55d%22%2C1762320769997%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22https%3A%2F%2Flmarena.ai%2F%3F__cf_chl_tk%3D.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A%22%2C%22u%22%3A%22https%3A%2F%2Flmarena.ai%2F%22%7D%7D"
|
| 306 |
+
},
|
| 307 |
+
{
|
| 308 |
+
"name": "Sec-Fetch-Dest",
|
| 309 |
+
"value": "empty"
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"name": "Sec-Fetch-Mode",
|
| 313 |
+
"value": "cors"
|
| 314 |
+
},
|
| 315 |
+
{
|
| 316 |
+
"name": "Sec-Fetch-Site",
|
| 317 |
+
"value": "same-origin"
|
| 318 |
+
},
|
| 319 |
+
{
|
| 320 |
+
"name": "Priority",
|
| 321 |
+
"value": "u=4"
|
| 322 |
+
},
|
| 323 |
+
{
|
| 324 |
+
"name": "TE",
|
| 325 |
+
"value": "trailers"
|
| 326 |
+
}
|
| 327 |
+
],
|
| 328 |
+
"cookies": [
|
| 329 |
+
{
|
| 330 |
+
"name": "cf_clearance",
|
| 331 |
+
"value": "AOlGnpqWmmKdKEP2yMG8KM92VUO.88kaU5SE0AZU.Og-1762320770-1.2.1.1-9BYUo7obh7vV6a05X8zGCryARvYNU54Se06Ta7BKYC6jg.sgp_W0JOzV_oOXNj7umxTT1awLJsdn842khahJC7Tc2.v3BkXziX6YKO.RmlJSEZNczkfCZroSUPeucvPjYumMcZNGBWGwcorhySiFn.EctFLfxr3ukEDhmpPSoKi7cWzc8UAPCTL3ukefTWdegaD71N5bWppjkpeH1ZJHOwh56biHVUQUm26LzZMkw6M"
|
| 332 |
+
},
|
| 333 |
+
{
|
| 334 |
+
"name": "sidebar_state",
|
| 335 |
+
"value": "true"
|
| 336 |
+
},
|
| 337 |
+
{
|
| 338 |
+
"name": "arena-auth-prod-v1",
|
| 339 |
+
"value": "base64-eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSkZVekkxTmlJc0ltdHBaQ0k2SWpBNVlUSTNPVFl6TFRjek5tWXROR00wWmkwNU5HSXlMV0ptWXpSaU1XSTJNV1k0T0NJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUpvZEhSd2N6b3ZMMmgxYjJkNmIyVnhlbU55WkhacmQzUjJiMlJwTG5OMWNHRmlZWE5sTG1OdkwyRjFkR2d2ZGpFaUxDSnpkV0lpT2lKbE1XUTFZbU5qWWkxbFlXRTJMVFJrWXpjdFlXTTNOeTB3WlRZd1kyVmlOelpsTVRnaUxDSmhkV1FpT2lKaGRYUm9aVzUwYVdOaGRHVmtJaXdpWlhod0lqb3hOell5TXpJME16WTNMQ0pwWVhRaU9qRTNOakl6TWpBM05qY3NJbVZ0WVdsc0lqb2lJaXdpY0dodmJtVWlPaUlpTENKaGNIQmZiV1YwWVdSaGRHRWlPbnQ5TENKMWMyVnlYMjFsZEdGa1lYUmhJanA3SW1sa0lqb2lPV0pqT0RSak1ERXROMkUyTUMwME9UWmlMVGt4TXpBdE1qSTNZV0ZpT0RFeU1USTVJbjBzSW5KdmJHVWlPaUpoZFhSb1pXNTBhV05oZEdWa0lpd2lZV0ZzSWpvaVlXRnNNU0lzSW1GdGNpSTZXM3NpYldWMGFHOWtJam9pWVc1dmJubHRiM1Z6SWl3aWRHbHRaWE4wWVcxd0lqb3hOell5TURNM09USTJmVjBzSW5ObGMzTnBiMjVmYVdRaU9pSm1OalEwTkRJMlpTMDBNekJpTFRSbFlUY3RPR1ZtT1Mwd1pqZzRPR00wTmpjNU4yVWlMQ0pwYzE5aGJtOXVlVzF2ZFhNaU9uUnlkV1Y5Lm1kY3dsUHNHSjQ2R0czUG45QXpiX3duZjBWdDhISUZmeVFpME1mVlhDRnFSWWZVMXlPb25sc3JIVGRvSWpxVENudlI0ekRjWmFFSmFSQ2d2OTRWNWJ3IiwidG9rZW5fdHlwZSI6ImJlYXJlciIsImV4cGlyZXNfaW4iOjM2MDAsImV4cGlyZXNfYXQiOjE3NjIzMjQzNjcsInJlZnJlc2hfdG9rZW4iOiJnM2ZmbmRvcTI2emsiLCJ1c2VyIjp7ImlkIjoiZTFkNWJjY2ItZWFhNi00ZGM3LWFjNzctMGU2MGNlYjc2ZTE4IiwiYXVkIjoiYXV0aGVudGljYXRlZCIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiIiLCJwaG9uZSI6IiIsImxhc3Rfc2lnbl9pbl9hdCI6IjIwMjUtMTEtMDFUMjI6NTg6NDYuNjQ3MTI4WiIsImFwcF9tZXRhZGF0YSI6e30sInVzZXJfbWV0YWRhdGEiOnsiaWQiOiI5YmM4NGMwMS03YTYwLTQ5NmItOTEzMC0yMjdhYWI4MTIxMjkifSwiaWRlbnRpdGllcyI6W10sImNyZWF0ZWRfYXQiOiIyMDI1LTExLTAxVDIyOjU4OjQ2LjY0NTgxM1oiLCJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wNVQwNTozMjo0Ny45OTE1OTRaIiwiaXNfYW5vbnltb3VzIjp0cnVlfX0"
|
| 340 |
+
},
|
| 341 |
+
{
|
| 342 |
+
"name": "ph_phc_YDG5hLiq6kyzVQVWFL9SGhRoHfQKTCu09FVPZtgmk1y_posthog",
|
| 343 |
+
"value": "{\"distinct_id\":\"019a42cc-921e-74d4-b305-fbf75305f6a4\",\"$sesid\":[1762057303275,\"019a42cc-921d-79b7-a7ec-b9e464e2f6ff\",1762057294365]}"
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"name": "__cf_bm",
|
| 347 |
+
"value": "ewsv6Ef17_1nDmy2m5DD24P16wY3bljqq.zb1zPQaLI-1762320768-1.0.1.1-u7Uel51L9RfvAgaVqzklE6ZRCbV_j8rNXm8PJvxN6RKapiuGnzjjXnmNHRnNo7E28OMD.L.YZJvf2djnjc9pjaIPbnP78OcsG9yyC.tJcmM"
|
| 348 |
+
},
|
| 349 |
+
{
|
| 350 |
+
"name": "ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog",
|
| 351 |
+
"value": "{\"distinct_id\":\"9bc84c01-7a60-496b-9130-227aab812129\",\"$sesid\":[1762321222458,\"019a5280-e3cd-735c-ae72-a5891eb7f55d\",1762320769997],\"$epp\":true,\"$initial_person_info\":{\"r\":\"https://lmarena.ai/?__cf_chl_tk=.2t83kc257tZUZ8W4Cfi6acnan52tGM2yzdCbTNrmus-1757143716-1.0.1.1-FlrvTJYpw0CweeoimQpS4hsn9lEXFMdNeFYhJJk3h3A\",\"u\":\"https://lmarena.ai/\"}}"
|
| 352 |
+
}
|
| 353 |
+
],
|
| 354 |
+
"queryString": [],
|
| 355 |
+
"headersSize": 3519,
|
| 356 |
+
"postData": {
|
| 357 |
+
"mimeType": "text/plain;charset=UTF-8",
|
| 358 |
+
"params": [],
|
| 359 |
+
"text": "{\"id\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"mode\":\"direct\",\"modelAId\":\"0199f060-b306-7e1f-aeae-0ebb4e3f1122\",\"userMessageId\":\"019a5287-cb3a-7b4e-a0fd-bb5b74aace99\",\"modelAMessageId\":\"019a5287-cb3a-7321-be9b-ddb1130cbd87\",\"messages\":[{\"id\":\"019a5287-7cd2-711e-a44b-da372fa139d5\",\"role\":\"user\",\"content\":\"First message\",\"experimental_attachments\":[],\"parentMessageIds\":[],\"participantPosition\":\"a\",\"modelId\":null,\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"pending\",\"failureReason\":null},{\"id\":\"019a5287-7cd3-731e-a2e4-82b761f33cc7\",\"role\":\"assistant\",\"content\":\"Hello! Welcome.\\n\\nHow can I help you today?\",\"reasoning\":\"\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5287-7cd2-711e-a44b-da372fa139d5\"],\"participantPosition\":\"a\",\"modelId\":\"0199f060-b306-7e1f-aeae-0ebb4e3f1122\",\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"success\",\"failureReason\":null},{\"id\":\"019a5287-cb3a-7b4e-a0fd-bb5b74aace99\",\"role\":\"user\",\"content\":\"Second message\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5287-7cd3-731e-a2e4-82b761f33cc7\"],\"participantPosition\":\"a\",\"modelId\":null,\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"pending\",\"failureReason\":null},{\"id\":\"019a5287-cb3a-7321-be9b-ddb1130cbd87\",\"role\":\"assistant\",\"content\":\"\",\"reasoning\":\"\",\"experimental_attachments\":[],\"parentMessageIds\":[\"019a5287-cb3a-7b4e-a0fd-bb5b74aace99\"],\"participantPosition\":\"a\",\"modelId\":\"0199f060-b306-7e1f-aeae-0ebb4e3f1122\",\"evaluationSessionId\":\"019a5287-4db3-7be6-8a47-5e60754b9488\",\"status\":\"pending\",\"failureReason\":null}],\"modality\":\"chat\",\"recaptchaV3Token\":\"0cAFcWeA7zKsgRRV2eyN-zl_jw6JX2tOD9Lga2cjdz_3NEjOlpUckWt4JY6-cT0vElRQUOIkyfBnP7BluXTw_74G22oWL0_qqmnZ4V08s0VPxJUYc8b9K_aUcarrTLT-D0aE_peIEC3CezXefwFlaf6P3VqWpyY37XY4I6EJIN7deA95iK2op1IrDdAjC3sjk-BZCb8b6V-ADPMw9-2rqnlPyPph7DKfDPsTTXgkmEldxwBSY7Xi6LzqHyz6tZLsPuaCd-UJ80r6aDdPMeIpxiaTZOyud1ahZhS9NfKFc1sT4CzSkrhhWLV_NrkQZxNxYXTuD-wgJRpXGB8lhCed09xRpD5Kk9SSNNNfvxyC2tXR8cFlEKyWUKMX6AcXbcPUQCCy73pSMzhktZB37sUDLFIqkJycld9gVx5dS2DqJDk45YFUH0mcD5__3eXZzBk0R9_pAsUroFeeNJrPonVqjSQTzsfUZvwYvqWW4KLiJB7lxgixUxe-WVHyf-TZF5nJpzppeBWHTYgM2JBa-j27nUT2fL9o1ExNf_LvZ7rZbC74gOk2ioZ9ul4HtowfhutwmPhGVRLcK1pplvlgwCZHrEbu9s4Q6q0ChOdCrZvyUxPL6SaDnNaQH8PXldj1IIVJomzm3qsHuikQY3AnOX1ltvt2FdSBZedLhtX2HcDreBQ3ziZDblJxGPnKOIX0Lpl7MfSrTAZFAON_xKqRG4l9lmkqTBnh1l1zuiQsExXcABWCru9Ers-1mwHp8SzrgsqKgrtckLnQlCIdnFu9gzOK2sYi-CVybw97EeebhSejDX2n7r6-d4FOdmG7OWLMr6qGesV23RmYByUDbU1p0VydXaHaKbkSvKfaPSFN6OB9gTEt3xmcLOi7ZP1eyBzO9frFhlnxd79ZEHqmj9ZbdJxXUjX5b1Axbw35pHgLVzYf9jKqsk7h861n2RlPTh11VW9_eiCsbaRYArPRZ2f5IorUKsgftjfoisSx4vMYskDpay2WjGBbgGaKF5ft_HMd4IS_K6Kcoa2_wjzurSASgPPqLo12wq9t2m7GvWdAPau8mHMvP_hmAI4NChnN00SynfqAgH8KFRhKSMTJFb9DZR5mAz2PhhSFP4aFxtdiRVyPBHwTNEC-tiwteAVnEwhVHHCNp_-mfAekusBpdqUd8ED_KGf9blxtd1FmbQXFd-0Pha3Srg7H8SO3lY1_KEp7vg7dRYMCcpy2ZMqCgbF0P1EQXYOI_nlefzMxcoaS8iCRziaijB-6GizdvunmkmX8kJz-JbTWc9HHM_f0mtSDOBIpuOqgPGUr0kLqGYj0YhxRjj9rA9uuCOTk_rJKmm1HY8M7C6UfUnt9gI91-m5ceqy2rynnBo6WnwmGl721qpFLRno2I5Nw-PMJenKv1X1c3Iz_6GwTeB4Xd16DqC-2PRJj-45W0DNamEeFeS8XSTVlbmxLoB7F0-ggzYzcJoj7LrGlGqE4XWTwqQJsLTFu6XR3AnERSaFaPGnXtaiTgjg3FUB9ySoI2rMI8mfMlYN-XWrYTA9yU62QoSmrUN5XX0rlNE5_Ap3I48xfPlChjFEdc3QwGl2zVU15aDTf2KQpqgvvaUKGsFGG6U9jEBYuyYapysorMAddpVeYCri55G73BvKttV4qPDLct6pk6O2DG83KeDny1wm7CaV6mCgWTLo0lOny2t2yN9ay5Kclr8bQ7-jg_D1aCigCfIozeiVtdlGYSuEUNu136Jl0MTF2AU4Yp-rP3kjkku_b7McQzEZB5jvKI7LWMySPWnpeY\"}"
|
| 360 |
+
}
|
| 361 |
+
},
|
| 362 |
+
"response": {
|
| 363 |
+
"status": 200,
|
| 364 |
+
"statusText": "",
|
| 365 |
+
"httpVersion": "HTTP/2",
|
| 366 |
+
"headers": [
|
| 367 |
+
{
|
| 368 |
+
"name": "date",
|
| 369 |
+
"value": "Wed, 05 Nov 2025 05:40:43 GMT"
|
| 370 |
+
},
|
| 371 |
+
{
|
| 372 |
+
"name": "content-type",
|
| 373 |
+
"value": "text/event-stream"
|
| 374 |
+
},
|
| 375 |
+
{
|
| 376 |
+
"name": "server",
|
| 377 |
+
"value": "cloudflare"
|
| 378 |
+
},
|
| 379 |
+
{
|
| 380 |
+
"name": "cf-ray",
|
| 381 |
+
"value": "999a04200981ed73-ADL"
|
| 382 |
+
},
|
| 383 |
+
{
|
| 384 |
+
"name": "cf-cache-status",
|
| 385 |
+
"value": "DYNAMIC"
|
| 386 |
+
},
|
| 387 |
+
{
|
| 388 |
+
"name": "access-control-allow-origin",
|
| 389 |
+
"value": "*"
|
| 390 |
+
},
|
| 391 |
+
{
|
| 392 |
+
"name": "cache-control",
|
| 393 |
+
"value": "no-cache"
|
| 394 |
+
},
|
| 395 |
+
{
|
| 396 |
+
"name": "strict-transport-security",
|
| 397 |
+
"value": "max-age=63072000; includeSubDomains; preload"
|
| 398 |
+
},
|
| 399 |
+
{
|
| 400 |
+
"name": "vary",
|
| 401 |
+
"value": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding"
|
| 402 |
+
},
|
| 403 |
+
{
|
| 404 |
+
"name": "ratelimit",
|
| 405 |
+
"value": "limit=3000, remaining=2997, reset=40"
|
| 406 |
+
},
|
| 407 |
+
{
|
| 408 |
+
"name": "ratelimit-policy",
|
| 409 |
+
"value": "3000;w=300"
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"name": "x-content-type-options",
|
| 413 |
+
"value": "nosniff"
|
| 414 |
+
},
|
| 415 |
+
{
|
| 416 |
+
"name": "x-matched-path",
|
| 417 |
+
"value": "/nextjs-api/stream/post-to-evaluation/[id]"
|
| 418 |
+
},
|
| 419 |
+
{
|
| 420 |
+
"name": "x-request-id",
|
| 421 |
+
"value": "b9652b06-938d-4d4b-bcd7-5b99c5978aa2"
|
| 422 |
+
},
|
| 423 |
+
{
|
| 424 |
+
"name": "x-vercel-cache",
|
| 425 |
+
"value": "MISS"
|
| 426 |
+
},
|
| 427 |
+
{
|
| 428 |
+
"name": "x-vercel-id",
|
| 429 |
+
"value": "syd1:syd1:sfo1::sfo1::sfo1::8lhzb-1762321223734-bc6522af99b7"
|
| 430 |
+
},
|
| 431 |
+
{
|
| 432 |
+
"name": "x-vercel-request-id",
|
| 433 |
+
"value": "b9652b06-938d-4d4b-bcd7-5b99c5978aa2"
|
| 434 |
+
},
|
| 435 |
+
{
|
| 436 |
+
"name": "alt-svc",
|
| 437 |
+
"value": "h3=\":443\"; ma=86400"
|
| 438 |
+
},
|
| 439 |
+
{
|
| 440 |
+
"name": "X-Firefox-Spdy",
|
| 441 |
+
"value": "h2"
|
| 442 |
+
}
|
| 443 |
+
],
|
| 444 |
+
"cookies": [],
|
| 445 |
+
"content": {
|
| 446 |
+
"mimeType": "text/event-stream",
|
| 447 |
+
"size": 276,
|
| 448 |
+
"text": "a0:\"And \"\na0:\"this \"\na0:\"is \"\na0:\"my \"\na0:\"second \"\na0:\"reply.\\n\\n\"\na0:\"Is \"\na0:\"there \"\na0:\"a \"\na0:\"third \"\na0:\"message \"\na0:\"on \"\na0:\"its \"\na0:\"way, \"\na0:\"or \"\na0:\"is \"\na0:\"there \"\na0:\"something \"\na0:\"I \"\na0:\"can \"\na0:\"help \"\na0:\"you \"\na0:\"with?\"\nad:{\"finishReason\":\"stop\"}\n"
|
| 449 |
+
},
|
| 450 |
+
"redirectURL": "",
|
| 451 |
+
"headersSize": 825,
|
| 452 |
+
"bodySize": 1101
|
| 453 |
+
},
|
| 454 |
+
"cache": {},
|
| 455 |
+
"timings": {
|
| 456 |
+
"blocked": 1,
|
| 457 |
+
"dns": 0,
|
| 458 |
+
"connect": 0,
|
| 459 |
+
"ssl": 0,
|
| 460 |
+
"send": 0,
|
| 461 |
+
"wait": 19667,
|
| 462 |
+
"receive": 0
|
| 463 |
+
},
|
| 464 |
+
"time": 19668,
|
| 465 |
+
"_securityState": "secure",
|
| 466 |
+
"serverIPAddress": "104.18.20.173",
|
| 467 |
+
"connection": "443",
|
| 468 |
+
"pageref": "page_2"
|
| 469 |
+
}
|
| 470 |
+
]
|
| 471 |
+
}
|
| 472 |
+
}
|
src/main.py
CHANGED
|
@@ -11,7 +11,7 @@ from datetime import datetime, timezone, timedelta
|
|
| 11 |
import uvicorn
|
| 12 |
from camoufox.async_api import AsyncCamoufox
|
| 13 |
from fastapi import FastAPI, HTTPException, Depends, status, Form, Request, Response
|
| 14 |
-
from starlette.responses import HTMLResponse, RedirectResponse
|
| 15 |
from fastapi.security import APIKeyHeader
|
| 16 |
|
| 17 |
import httpx
|
|
@@ -65,12 +65,15 @@ def get_config():
|
|
| 65 |
config.setdefault("cf_clearance", "")
|
| 66 |
config.setdefault("api_keys", [])
|
| 67 |
config.setdefault("usage_stats", {})
|
| 68 |
-
|
| 69 |
-
global model_usage_stats
|
| 70 |
-
model_usage_stats = defaultdict(int, config["usage_stats"])
|
| 71 |
-
|
| 72 |
return config
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
def save_config(config):
|
| 75 |
# Persist in-memory stats to the config dict before saving
|
| 76 |
config["usage_stats"] = dict(model_usage_stats)
|
|
@@ -133,7 +136,16 @@ async def rate_limit_api_key(key: str = Depends(API_KEY_HEADER)):
|
|
| 133 |
api_key_usage[api_key_str] = [t for t in api_key_usage[api_key_str] if current_time - t < 60]
|
| 134 |
|
| 135 |
if len(api_key_usage[api_key_str]) >= rate_limit:
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
|
| 138 |
api_key_usage[api_key_str].append(current_time)
|
| 139 |
|
|
@@ -199,6 +211,8 @@ async def startup_event():
|
|
| 199 |
# Ensure config and models files exist
|
| 200 |
save_config(get_config())
|
| 201 |
save_models(get_models())
|
|
|
|
|
|
|
| 202 |
asyncio.create_task(get_initial_data())
|
| 203 |
|
| 204 |
# --- UI Endpoints (Login/Dashboard) ---
|
|
@@ -395,6 +409,9 @@ async def dashboard(session: str = Depends(get_current_session)):
|
|
| 395 |
|
| 396 |
cf_status = "β
Configured" if config.get("cf_clearance") else "β Not Set"
|
| 397 |
cf_class = "status-good" if config.get("cf_clearance") else "status-bad"
|
|
|
|
|
|
|
|
|
|
| 398 |
|
| 399 |
return f"""
|
| 400 |
<!DOCTYPE html>
|
|
@@ -402,7 +419,24 @@ async def dashboard(session: str = Depends(get_current_session)):
|
|
| 402 |
<head>
|
| 403 |
<title>Dashboard - LMArena Bridge</title>
|
| 404 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
| 405 |
<style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 406 |
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
| 407 |
body {{
|
| 408 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
@@ -614,6 +648,26 @@ async def dashboard(session: str = Depends(get_current_session)):
|
|
| 614 |
padding: 20px;
|
| 615 |
border-radius: 8px;
|
| 616 |
text-align: center;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 617 |
}}
|
| 618 |
.stat-value {{
|
| 619 |
font-size: 32px;
|
|
@@ -740,6 +794,16 @@ async def dashboard(session: str = Depends(get_current_session)):
|
|
| 740 |
<div class="section-header">
|
| 741 |
<h2>π Usage Statistics</h2>
|
| 742 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 743 |
<table>
|
| 744 |
<thead>
|
| 745 |
<tr>
|
|
@@ -764,6 +828,116 @@ async def dashboard(session: str = Depends(get_current_session)):
|
|
| 764 |
</div>
|
| 765 |
</div>
|
| 766 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 767 |
</body>
|
| 768 |
</html>
|
| 769 |
"""
|
|
@@ -840,6 +1014,9 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 840 |
|
| 841 |
model_public_name = body.get("model")
|
| 842 |
messages = body.get("messages", [])
|
|
|
|
|
|
|
|
|
|
| 843 |
|
| 844 |
print(f"π€ Requested model: {model_public_name}")
|
| 845 |
print(f"π¬ Number of messages: {len(messages)}")
|
|
@@ -869,17 +1046,35 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 869 |
|
| 870 |
# Log usage
|
| 871 |
model_usage_stats[model_public_name] += 1
|
|
|
|
| 872 |
config = get_config()
|
|
|
|
| 873 |
save_config(config)
|
| 874 |
|
| 875 |
# Use last message as prompt
|
| 876 |
prompt = messages[-1].get("content", "")
|
| 877 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
|
| 879 |
if not prompt:
|
| 880 |
print("β Last message has no content")
|
| 881 |
raise HTTPException(status_code=400, detail="Last message must have content.")
|
| 882 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 883 |
# Use API key + conversation tracking
|
| 884 |
api_key_str = api_key["key"]
|
| 885 |
conversation_id = body.get("conversation_id", f"conv-{uuid.uuid4()}")
|
|
@@ -944,33 +1139,34 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 944 |
print(f"π¦ Payload structure: {len(payload['messages'])} messages")
|
| 945 |
else:
|
| 946 |
print("π Using EXISTING conversation session")
|
| 947 |
-
# Follow-up message - Generate message IDs
|
| 948 |
user_msg_id = str(uuid7())
|
| 949 |
print(f"π€ Generated followup user_msg_id: {user_msg_id}")
|
| 950 |
model_msg_id = str(uuid7())
|
| 951 |
print(f"π€ Generated followup model_msg_id: {model_msg_id}")
|
| 952 |
|
| 953 |
-
# Build full conversation history
|
| 954 |
conversation_messages = []
|
| 955 |
-
|
| 956 |
-
|
|
|
|
| 957 |
conversation_messages.append({
|
| 958 |
-
"id":
|
| 959 |
-
"role":
|
| 960 |
-
"content":
|
| 961 |
"experimental_attachments": [],
|
| 962 |
"parentMessageIds": [conversation_messages[-1]["id"]] if conversation_messages else [],
|
| 963 |
"participantPosition": "a",
|
| 964 |
-
"modelId": model_id if
|
| 965 |
"evaluationSessionId": session["conversation_id"],
|
| 966 |
-
"status": "success" if
|
| 967 |
"failureReason": None
|
| 968 |
})
|
| 969 |
-
if
|
| 970 |
conversation_messages[-1]["reasoning"] = ""
|
| 971 |
|
| 972 |
# Add new user message
|
| 973 |
-
last_msg_id = conversation_messages[-1]["id"] if conversation_messages else session.get("
|
| 974 |
conversation_messages.append({
|
| 975 |
"id": user_msg_id,
|
| 976 |
"role": "user",
|
|
@@ -1015,6 +1211,119 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 1015 |
print(f"\nπ Making API request to LMArena...")
|
| 1016 |
print(f"β±οΈ Timeout set to: 120 seconds")
|
| 1017 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1018 |
async with httpx.AsyncClient() as client:
|
| 1019 |
try:
|
| 1020 |
print("π‘ Sending POST request...")
|
|
@@ -1106,16 +1415,25 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 1106 |
else:
|
| 1107 |
print(f"β
Response text preview: {response_text[:200]}...")
|
| 1108 |
|
| 1109 |
-
# Update session
|
| 1110 |
if not session:
|
| 1111 |
chat_sessions[api_key_str][conversation_id] = {
|
| 1112 |
"conversation_id": session_id,
|
| 1113 |
-
"
|
| 1114 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1115 |
}
|
| 1116 |
print(f"πΎ Saved new session for conversation {conversation_id}")
|
| 1117 |
else:
|
| 1118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1119 |
print(f"πΎ Updated existing session for conversation {conversation_id}")
|
| 1120 |
|
| 1121 |
final_response = {
|
|
@@ -1157,6 +1475,17 @@ async def api_chat_completions(request: Request, api_key: dict = Depends(rate_li
|
|
| 1157 |
print(f"π€ Request payload (truncated): {json.dumps(payload, indent=2)[:500]}")
|
| 1158 |
print(f"π₯ Response text: {e.response.text[:500]}")
|
| 1159 |
print("="*80 + "\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1160 |
raise HTTPException(status_code=502, detail=error_detail)
|
| 1161 |
|
| 1162 |
except httpx.TimeoutException as e:
|
|
|
|
| 11 |
import uvicorn
|
| 12 |
from camoufox.async_api import AsyncCamoufox
|
| 13 |
from fastapi import FastAPI, HTTPException, Depends, status, Form, Request, Response
|
| 14 |
+
from starlette.responses import HTMLResponse, RedirectResponse, StreamingResponse
|
| 15 |
from fastapi.security import APIKeyHeader
|
| 16 |
|
| 17 |
import httpx
|
|
|
|
| 65 |
config.setdefault("cf_clearance", "")
|
| 66 |
config.setdefault("api_keys", [])
|
| 67 |
config.setdefault("usage_stats", {})
|
| 68 |
+
|
|
|
|
|
|
|
|
|
|
| 69 |
return config
|
| 70 |
|
| 71 |
+
def load_usage_stats():
|
| 72 |
+
"""Load usage stats from config into memory"""
|
| 73 |
+
global model_usage_stats
|
| 74 |
+
config = get_config()
|
| 75 |
+
model_usage_stats = defaultdict(int, config.get("usage_stats", {}))
|
| 76 |
+
|
| 77 |
def save_config(config):
|
| 78 |
# Persist in-memory stats to the config dict before saving
|
| 79 |
config["usage_stats"] = dict(model_usage_stats)
|
|
|
|
| 136 |
api_key_usage[api_key_str] = [t for t in api_key_usage[api_key_str] if current_time - t < 60]
|
| 137 |
|
| 138 |
if len(api_key_usage[api_key_str]) >= rate_limit:
|
| 139 |
+
# Calculate seconds until oldest request expires (60 seconds window)
|
| 140 |
+
oldest_timestamp = min(api_key_usage[api_key_str])
|
| 141 |
+
retry_after = int(60 - (current_time - oldest_timestamp))
|
| 142 |
+
retry_after = max(1, retry_after) # At least 1 second
|
| 143 |
+
|
| 144 |
+
raise HTTPException(
|
| 145 |
+
status_code=429,
|
| 146 |
+
detail="Rate limit exceeded. Please try again later.",
|
| 147 |
+
headers={"Retry-After": str(retry_after)}
|
| 148 |
+
)
|
| 149 |
|
| 150 |
api_key_usage[api_key_str].append(current_time)
|
| 151 |
|
|
|
|
| 211 |
# Ensure config and models files exist
|
| 212 |
save_config(get_config())
|
| 213 |
save_models(get_models())
|
| 214 |
+
# Load usage stats from config
|
| 215 |
+
load_usage_stats()
|
| 216 |
asyncio.create_task(get_initial_data())
|
| 217 |
|
| 218 |
# --- UI Endpoints (Login/Dashboard) ---
|
|
|
|
| 409 |
|
| 410 |
cf_status = "β
Configured" if config.get("cf_clearance") else "β Not Set"
|
| 411 |
cf_class = "status-good" if config.get("cf_clearance") else "status-bad"
|
| 412 |
+
|
| 413 |
+
# Get recent activity count (last 24 hours)
|
| 414 |
+
recent_activity = sum(1 for timestamps in api_key_usage.values() for t in timestamps if time.time() - t < 86400)
|
| 415 |
|
| 416 |
return f"""
|
| 417 |
<!DOCTYPE html>
|
|
|
|
| 419 |
<head>
|
| 420 |
<title>Dashboard - LMArena Bridge</title>
|
| 421 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 422 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
|
| 423 |
<style>
|
| 424 |
+
@keyframes fadeIn {{
|
| 425 |
+
from {{ opacity: 0; transform: translateY(20px); }}
|
| 426 |
+
to {{ opacity: 1; transform: translateY(0); }}
|
| 427 |
+
}}
|
| 428 |
+
@keyframes slideIn {{
|
| 429 |
+
from {{ opacity: 0; transform: translateX(-20px); }}
|
| 430 |
+
to {{ opacity: 1; transform: translateX(0); }}
|
| 431 |
+
}}
|
| 432 |
+
@keyframes pulse {{
|
| 433 |
+
0%, 100% {{ transform: scale(1); }}
|
| 434 |
+
50% {{ transform: scale(1.05); }}
|
| 435 |
+
}}
|
| 436 |
+
@keyframes shimmer {{
|
| 437 |
+
0% {{ background-position: -1000px 0; }}
|
| 438 |
+
100% {{ background-position: 1000px 0; }}
|
| 439 |
+
}}
|
| 440 |
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
| 441 |
body {{
|
| 442 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
|
|
| 648 |
padding: 20px;
|
| 649 |
border-radius: 8px;
|
| 650 |
text-align: center;
|
| 651 |
+
animation: fadeIn 0.6s ease-out;
|
| 652 |
+
transition: transform 0.3s;
|
| 653 |
+
}}
|
| 654 |
+
.stat-card:hover {{
|
| 655 |
+
transform: translateY(-5px);
|
| 656 |
+
box-shadow: 0 8px 16px rgba(102, 126, 234, 0.4);
|
| 657 |
+
}}
|
| 658 |
+
.section {{
|
| 659 |
+
animation: slideIn 0.5s ease-out;
|
| 660 |
+
}}
|
| 661 |
+
.section:nth-child(2) {{ animation-delay: 0.1s; }}
|
| 662 |
+
.section:nth-child(3) {{ animation-delay: 0.2s; }}
|
| 663 |
+
.section:nth-child(4) {{ animation-delay: 0.3s; }}
|
| 664 |
+
.model-card {{
|
| 665 |
+
animation: fadeIn 0.4s ease-out;
|
| 666 |
+
transition: transform 0.2s, box-shadow 0.2s;
|
| 667 |
+
}}
|
| 668 |
+
.model-card:hover {{
|
| 669 |
+
transform: translateY(-3px);
|
| 670 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
| 671 |
}}
|
| 672 |
.stat-value {{
|
| 673 |
font-size: 32px;
|
|
|
|
| 794 |
<div class="section-header">
|
| 795 |
<h2>π Usage Statistics</h2>
|
| 796 |
</div>
|
| 797 |
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-bottom: 30px;">
|
| 798 |
+
<div>
|
| 799 |
+
<h3 style="text-align: center; margin-bottom: 15px; font-size: 16px; color: #666;">Model Usage Distribution</h3>
|
| 800 |
+
<canvas id="modelPieChart" style="max-height: 300px;"></canvas>
|
| 801 |
+
</div>
|
| 802 |
+
<div>
|
| 803 |
+
<h3 style="text-align: center; margin-bottom: 15px; font-size: 16px; color: #666;">Request Count by Model</h3>
|
| 804 |
+
<canvas id="modelBarChart" style="max-height: 300px;"></canvas>
|
| 805 |
+
</div>
|
| 806 |
+
</div>
|
| 807 |
<table>
|
| 808 |
<thead>
|
| 809 |
<tr>
|
|
|
|
| 828 |
</div>
|
| 829 |
</div>
|
| 830 |
</div>
|
| 831 |
+
|
| 832 |
+
<script>
|
| 833 |
+
// Prepare data for charts
|
| 834 |
+
const statsData = {json.dumps(dict(sorted(model_usage_stats.items(), key=lambda x: x[1], reverse=True)[:10]))};
|
| 835 |
+
const modelNames = Object.keys(statsData);
|
| 836 |
+
const modelCounts = Object.values(statsData);
|
| 837 |
+
|
| 838 |
+
// Generate colors for charts
|
| 839 |
+
const colors = [
|
| 840 |
+
'#667eea', '#764ba2', '#f093fb', '#4facfe',
|
| 841 |
+
'#43e97b', '#fa709a', '#fee140', '#30cfd0',
|
| 842 |
+
'#a8edea', '#fed6e3'
|
| 843 |
+
];
|
| 844 |
+
|
| 845 |
+
// Pie Chart
|
| 846 |
+
if (modelNames.length > 0) {{
|
| 847 |
+
const pieCtx = document.getElementById('modelPieChart').getContext('2d');
|
| 848 |
+
new Chart(pieCtx, {{
|
| 849 |
+
type: 'doughnut',
|
| 850 |
+
data: {{
|
| 851 |
+
labels: modelNames,
|
| 852 |
+
datasets: [{{
|
| 853 |
+
data: modelCounts,
|
| 854 |
+
backgroundColor: colors,
|
| 855 |
+
borderWidth: 2,
|
| 856 |
+
borderColor: '#fff'
|
| 857 |
+
}}]
|
| 858 |
+
}},
|
| 859 |
+
options: {{
|
| 860 |
+
responsive: true,
|
| 861 |
+
maintainAspectRatio: true,
|
| 862 |
+
plugins: {{
|
| 863 |
+
legend: {{
|
| 864 |
+
position: 'bottom',
|
| 865 |
+
labels: {{
|
| 866 |
+
padding: 15,
|
| 867 |
+
font: {{
|
| 868 |
+
size: 11
|
| 869 |
+
}}
|
| 870 |
+
}}
|
| 871 |
+
}},
|
| 872 |
+
tooltip: {{
|
| 873 |
+
callbacks: {{
|
| 874 |
+
label: function(context) {{
|
| 875 |
+
const label = context.label || '';
|
| 876 |
+
const value = context.parsed || 0;
|
| 877 |
+
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
| 878 |
+
const percentage = ((value / total) * 100).toFixed(1);
|
| 879 |
+
return label + ': ' + value + ' (' + percentage + '%)';
|
| 880 |
+
}}
|
| 881 |
+
}}
|
| 882 |
+
}}
|
| 883 |
+
}}
|
| 884 |
+
}}
|
| 885 |
+
}});
|
| 886 |
+
|
| 887 |
+
// Bar Chart
|
| 888 |
+
const barCtx = document.getElementById('modelBarChart').getContext('2d');
|
| 889 |
+
new Chart(barCtx, {{
|
| 890 |
+
type: 'bar',
|
| 891 |
+
data: {{
|
| 892 |
+
labels: modelNames,
|
| 893 |
+
datasets: [{{
|
| 894 |
+
label: 'Requests',
|
| 895 |
+
data: modelCounts,
|
| 896 |
+
backgroundColor: colors[0],
|
| 897 |
+
borderColor: colors[1],
|
| 898 |
+
borderWidth: 1
|
| 899 |
+
}}]
|
| 900 |
+
}},
|
| 901 |
+
options: {{
|
| 902 |
+
responsive: true,
|
| 903 |
+
maintainAspectRatio: true,
|
| 904 |
+
plugins: {{
|
| 905 |
+
legend: {{
|
| 906 |
+
display: false
|
| 907 |
+
}},
|
| 908 |
+
tooltip: {{
|
| 909 |
+
callbacks: {{
|
| 910 |
+
label: function(context) {{
|
| 911 |
+
return 'Requests: ' + context.parsed.y;
|
| 912 |
+
}}
|
| 913 |
+
}}
|
| 914 |
+
}}
|
| 915 |
+
}},
|
| 916 |
+
scales: {{
|
| 917 |
+
y: {{
|
| 918 |
+
beginAtZero: true,
|
| 919 |
+
ticks: {{
|
| 920 |
+
stepSize: 1
|
| 921 |
+
}}
|
| 922 |
+
}},
|
| 923 |
+
x: {{
|
| 924 |
+
ticks: {{
|
| 925 |
+
font: {{
|
| 926 |
+
size: 10
|
| 927 |
+
}},
|
| 928 |
+
maxRotation: 45,
|
| 929 |
+
minRotation: 45
|
| 930 |
+
}}
|
| 931 |
+
}}
|
| 932 |
+
}}
|
| 933 |
+
}}
|
| 934 |
+
}});
|
| 935 |
+
}} else {{
|
| 936 |
+
// Show "no data" message
|
| 937 |
+
document.getElementById('modelPieChart').parentElement.innerHTML = '<p style="text-align: center; color: #999; padding: 50px;">No usage data yet</p>';
|
| 938 |
+
document.getElementById('modelBarChart').parentElement.innerHTML = '<p style="text-align: center; color: #999; padding: 50px;">No usage data yet</p>';
|
| 939 |
+
}}
|
| 940 |
+
</script>
|
| 941 |
</body>
|
| 942 |
</html>
|
| 943 |
"""
|
|
|
|
| 1014 |
|
| 1015 |
model_public_name = body.get("model")
|
| 1016 |
messages = body.get("messages", [])
|
| 1017 |
+
stream = body.get("stream", False)
|
| 1018 |
+
|
| 1019 |
+
print(f"π Stream mode: {stream}")
|
| 1020 |
|
| 1021 |
print(f"π€ Requested model: {model_public_name}")
|
| 1022 |
print(f"π¬ Number of messages: {len(messages)}")
|
|
|
|
| 1046 |
|
| 1047 |
# Log usage
|
| 1048 |
model_usage_stats[model_public_name] += 1
|
| 1049 |
+
# Save stats immediately after incrementing
|
| 1050 |
config = get_config()
|
| 1051 |
+
config["usage_stats"] = dict(model_usage_stats)
|
| 1052 |
save_config(config)
|
| 1053 |
|
| 1054 |
# Use last message as prompt
|
| 1055 |
prompt = messages[-1].get("content", "")
|
| 1056 |
+
|
| 1057 |
+
# Validate prompt is a string and not too large
|
| 1058 |
+
if not isinstance(prompt, str):
|
| 1059 |
+
print("β Prompt content must be a string")
|
| 1060 |
+
raise HTTPException(status_code=400, detail="Message content must be a string.")
|
| 1061 |
|
| 1062 |
if not prompt:
|
| 1063 |
print("β Last message has no content")
|
| 1064 |
raise HTTPException(status_code=400, detail="Last message must have content.")
|
| 1065 |
|
| 1066 |
+
# Log prompt length for debugging character limit issues
|
| 1067 |
+
print(f"π User prompt length: {len(prompt)} characters")
|
| 1068 |
+
print(f"π User prompt preview: {prompt[:100]}..." if len(prompt) > 100 else f"π User prompt: {prompt}")
|
| 1069 |
+
|
| 1070 |
+
# Check for reasonable character limit (LMArena appears to have limits)
|
| 1071 |
+
# Typical limit seems to be around 32K-64K characters based on testing
|
| 1072 |
+
MAX_PROMPT_LENGTH = 50000 # Conservative estimate
|
| 1073 |
+
if len(prompt) > MAX_PROMPT_LENGTH:
|
| 1074 |
+
error_msg = f"Prompt too long ({len(prompt)} characters). LMArena has a character limit of approximately {MAX_PROMPT_LENGTH} characters. Please reduce the message size."
|
| 1075 |
+
print(f"β {error_msg}")
|
| 1076 |
+
raise HTTPException(status_code=400, detail=error_msg)
|
| 1077 |
+
|
| 1078 |
# Use API key + conversation tracking
|
| 1079 |
api_key_str = api_key["key"]
|
| 1080 |
conversation_id = body.get("conversation_id", f"conv-{uuid.uuid4()}")
|
|
|
|
| 1139 |
print(f"π¦ Payload structure: {len(payload['messages'])} messages")
|
| 1140 |
else:
|
| 1141 |
print("π Using EXISTING conversation session")
|
| 1142 |
+
# Follow-up message - Generate new message IDs
|
| 1143 |
user_msg_id = str(uuid7())
|
| 1144 |
print(f"π€ Generated followup user_msg_id: {user_msg_id}")
|
| 1145 |
model_msg_id = str(uuid7())
|
| 1146 |
print(f"π€ Generated followup model_msg_id: {model_msg_id}")
|
| 1147 |
|
| 1148 |
+
# Build full conversation history using stored messages with their original IDs
|
| 1149 |
conversation_messages = []
|
| 1150 |
+
stored_messages = session.get("messages", [])
|
| 1151 |
+
|
| 1152 |
+
for stored_msg in stored_messages:
|
| 1153 |
conversation_messages.append({
|
| 1154 |
+
"id": stored_msg["id"],
|
| 1155 |
+
"role": stored_msg["role"],
|
| 1156 |
+
"content": stored_msg["content"],
|
| 1157 |
"experimental_attachments": [],
|
| 1158 |
"parentMessageIds": [conversation_messages[-1]["id"]] if conversation_messages else [],
|
| 1159 |
"participantPosition": "a",
|
| 1160 |
+
"modelId": model_id if stored_msg["role"] == "assistant" else None,
|
| 1161 |
"evaluationSessionId": session["conversation_id"],
|
| 1162 |
+
"status": "success" if stored_msg["role"] == "assistant" else "pending",
|
| 1163 |
"failureReason": None
|
| 1164 |
})
|
| 1165 |
+
if stored_msg["role"] == "assistant":
|
| 1166 |
conversation_messages[-1]["reasoning"] = ""
|
| 1167 |
|
| 1168 |
# Add new user message
|
| 1169 |
+
last_msg_id = conversation_messages[-1]["id"] if conversation_messages else session.get("messages", [])[-1]["id"]
|
| 1170 |
conversation_messages.append({
|
| 1171 |
"id": user_msg_id,
|
| 1172 |
"role": "user",
|
|
|
|
| 1211 |
print(f"\nπ Making API request to LMArena...")
|
| 1212 |
print(f"β±οΈ Timeout set to: 120 seconds")
|
| 1213 |
|
| 1214 |
+
# Handle streaming mode
|
| 1215 |
+
if stream:
|
| 1216 |
+
async def generate_stream():
|
| 1217 |
+
response_text = ""
|
| 1218 |
+
chunk_id = f"chatcmpl-{uuid.uuid4()}"
|
| 1219 |
+
|
| 1220 |
+
async with httpx.AsyncClient() as client:
|
| 1221 |
+
try:
|
| 1222 |
+
print("π‘ Sending POST request for streaming...")
|
| 1223 |
+
async with client.stream('POST', url, json=payload, headers=headers, timeout=120) as response:
|
| 1224 |
+
print(f"β
Stream opened - Status: {response.status_code}")
|
| 1225 |
+
response.raise_for_status()
|
| 1226 |
+
|
| 1227 |
+
async for line in response.aiter_lines():
|
| 1228 |
+
line = line.strip()
|
| 1229 |
+
if not line:
|
| 1230 |
+
continue
|
| 1231 |
+
|
| 1232 |
+
# Parse text chunks: a0:"Hello "
|
| 1233 |
+
if line.startswith("a0:"):
|
| 1234 |
+
chunk_data = line[3:]
|
| 1235 |
+
try:
|
| 1236 |
+
text_chunk = json.loads(chunk_data)
|
| 1237 |
+
response_text += text_chunk
|
| 1238 |
+
|
| 1239 |
+
# Send SSE-formatted chunk
|
| 1240 |
+
chunk_response = {
|
| 1241 |
+
"id": chunk_id,
|
| 1242 |
+
"object": "chat.completion.chunk",
|
| 1243 |
+
"created": int(time.time()),
|
| 1244 |
+
"model": model_public_name,
|
| 1245 |
+
"choices": [{
|
| 1246 |
+
"index": 0,
|
| 1247 |
+
"delta": {
|
| 1248 |
+
"content": text_chunk
|
| 1249 |
+
},
|
| 1250 |
+
"finish_reason": None
|
| 1251 |
+
}]
|
| 1252 |
+
}
|
| 1253 |
+
yield f"data: {json.dumps(chunk_response)}\n\n"
|
| 1254 |
+
|
| 1255 |
+
except json.JSONDecodeError:
|
| 1256 |
+
continue
|
| 1257 |
+
|
| 1258 |
+
# Parse error messages
|
| 1259 |
+
elif line.startswith("a3:"):
|
| 1260 |
+
error_data = line[3:]
|
| 1261 |
+
try:
|
| 1262 |
+
error_message = json.loads(error_data)
|
| 1263 |
+
print(f" β Error in stream: {error_message}")
|
| 1264 |
+
except json.JSONDecodeError:
|
| 1265 |
+
pass
|
| 1266 |
+
|
| 1267 |
+
# Parse metadata for finish
|
| 1268 |
+
elif line.startswith("ad:"):
|
| 1269 |
+
metadata_data = line[3:]
|
| 1270 |
+
try:
|
| 1271 |
+
metadata = json.loads(metadata_data)
|
| 1272 |
+
finish_reason = metadata.get("finishReason", "stop")
|
| 1273 |
+
|
| 1274 |
+
# Send final chunk with finish_reason
|
| 1275 |
+
final_chunk = {
|
| 1276 |
+
"id": chunk_id,
|
| 1277 |
+
"object": "chat.completion.chunk",
|
| 1278 |
+
"created": int(time.time()),
|
| 1279 |
+
"model": model_public_name,
|
| 1280 |
+
"choices": [{
|
| 1281 |
+
"index": 0,
|
| 1282 |
+
"delta": {},
|
| 1283 |
+
"finish_reason": finish_reason
|
| 1284 |
+
}]
|
| 1285 |
+
}
|
| 1286 |
+
yield f"data: {json.dumps(final_chunk)}\n\n"
|
| 1287 |
+
except json.JSONDecodeError:
|
| 1288 |
+
continue
|
| 1289 |
+
|
| 1290 |
+
# Update session
|
| 1291 |
+
if not session:
|
| 1292 |
+
chat_sessions[api_key_str][conversation_id] = {
|
| 1293 |
+
"conversation_id": session_id,
|
| 1294 |
+
"last_message_id": model_msg_id,
|
| 1295 |
+
"model": model_public_name
|
| 1296 |
+
}
|
| 1297 |
+
else:
|
| 1298 |
+
chat_sessions[api_key_str][conversation_id]["last_message_id"] = model_msg_id
|
| 1299 |
+
|
| 1300 |
+
yield "data: [DONE]\n\n"
|
| 1301 |
+
print(f"β
Stream completed - {len(response_text)} chars sent")
|
| 1302 |
+
|
| 1303 |
+
except httpx.HTTPStatusError as e:
|
| 1304 |
+
error_msg = f"LMArena API error: {e.response.status_code}"
|
| 1305 |
+
print(f"β {error_msg}")
|
| 1306 |
+
error_chunk = {
|
| 1307 |
+
"error": {
|
| 1308 |
+
"message": error_msg,
|
| 1309 |
+
"type": "api_error",
|
| 1310 |
+
"code": e.response.status_code
|
| 1311 |
+
}
|
| 1312 |
+
}
|
| 1313 |
+
yield f"data: {json.dumps(error_chunk)}\n\n"
|
| 1314 |
+
except Exception as e:
|
| 1315 |
+
print(f"β Stream error: {str(e)}")
|
| 1316 |
+
error_chunk = {
|
| 1317 |
+
"error": {
|
| 1318 |
+
"message": str(e),
|
| 1319 |
+
"type": "internal_error"
|
| 1320 |
+
}
|
| 1321 |
+
}
|
| 1322 |
+
yield f"data: {json.dumps(error_chunk)}\n\n"
|
| 1323 |
+
|
| 1324 |
+
return StreamingResponse(generate_stream(), media_type="text/event-stream")
|
| 1325 |
+
|
| 1326 |
+
# Handle non-streaming mode (original code)
|
| 1327 |
async with httpx.AsyncClient() as client:
|
| 1328 |
try:
|
| 1329 |
print("π‘ Sending POST request...")
|
|
|
|
| 1415 |
else:
|
| 1416 |
print(f"β
Response text preview: {response_text[:200]}...")
|
| 1417 |
|
| 1418 |
+
# Update session - Store message history with IDs
|
| 1419 |
if not session:
|
| 1420 |
chat_sessions[api_key_str][conversation_id] = {
|
| 1421 |
"conversation_id": session_id,
|
| 1422 |
+
"model": model_public_name,
|
| 1423 |
+
"messages": [
|
| 1424 |
+
{"id": user_msg_id, "role": "user", "content": prompt},
|
| 1425 |
+
{"id": model_msg_id, "role": "assistant", "content": response_text.strip()}
|
| 1426 |
+
]
|
| 1427 |
}
|
| 1428 |
print(f"πΎ Saved new session for conversation {conversation_id}")
|
| 1429 |
else:
|
| 1430 |
+
# Append new messages to history
|
| 1431 |
+
chat_sessions[api_key_str][conversation_id]["messages"].append(
|
| 1432 |
+
{"id": user_msg_id, "role": "user", "content": prompt}
|
| 1433 |
+
)
|
| 1434 |
+
chat_sessions[api_key_str][conversation_id]["messages"].append(
|
| 1435 |
+
{"id": model_msg_id, "role": "assistant", "content": response_text.strip()}
|
| 1436 |
+
)
|
| 1437 |
print(f"πΎ Updated existing session for conversation {conversation_id}")
|
| 1438 |
|
| 1439 |
final_response = {
|
|
|
|
| 1475 |
print(f"π€ Request payload (truncated): {json.dumps(payload, indent=2)[:500]}")
|
| 1476 |
print(f"π₯ Response text: {e.response.text[:500]}")
|
| 1477 |
print("="*80 + "\n")
|
| 1478 |
+
|
| 1479 |
+
# Handle 429 from LMArena - propagate Retry-After if available
|
| 1480 |
+
if e.response.status_code == 429:
|
| 1481 |
+
retry_after = e.response.headers.get("Retry-After", "60") # Default 60s
|
| 1482 |
+
print(f"β±οΈ LMArena rate limit - Retry-After: {retry_after}s")
|
| 1483 |
+
raise HTTPException(
|
| 1484 |
+
status_code=429,
|
| 1485 |
+
detail=f"LMArena rate limit exceeded: {error_detail}",
|
| 1486 |
+
headers={"Retry-After": retry_after}
|
| 1487 |
+
)
|
| 1488 |
+
|
| 1489 |
raise HTTPException(status_code=502, detail=error_detail)
|
| 1490 |
|
| 1491 |
except httpx.TimeoutException as e:
|
timeout_debug.png
DELETED
|
Binary file (70.2 kB)
|
|
|
token_timeout.png
DELETED
|
Binary file (73.6 kB)
|
|
|