justadri23 commited on
Commit
aa74f29
·
verified ·
1 Parent(s): 64386ad

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -51
app.py CHANGED
@@ -15,25 +15,12 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(level
15
  logger = logging.getLogger(__name__)
16
 
17
  # Constants
18
- PORT = 7860
19
  REVE_API_URL = "https://preview.reve.art/api/misc/chat"
20
  RATE_LIMIT = 4
21
  RATE_LIMIT_WINDOW = 60
22
  HASH_SALT = os.urandom(16).hex()
23
 
24
- LATEST_VERSION_MAPPING = {
25
- "claude-3-7-sonnet-latest": "claude-3-7-sonnet-20250219",
26
- "claude-3-5-sonnet-latest": "claude-3-5-sonnet-20241022",
27
- "claude-3-5-haiku-latest": "claude-3-5-haiku-20241022"
28
- }
29
-
30
- MODEL_MAPPING = {
31
- "claude-3-7-sonnet-20250219": "llm_claude_sonnet_3_7",
32
- "claude-3-5-sonnet-20241022": "llm_claude_sonnet_3_5_v2",
33
- "claude-3-5-sonnet-20240620": "llm_claude_sonnet_3_5",
34
- "claude-3-5-haiku-20241022": "llm_claude_haiku_3_5_v2"
35
- }
36
-
37
  # Rate limiting store
38
  rate_limit_store = defaultdict(lambda: deque(maxlen=RATE_LIMIT))
39
 
@@ -151,15 +138,19 @@ def get_next_token():
151
  return token
152
 
153
  def convert_anthropic_to_reve_request(anthropic_req):
154
- model = anthropic_req.get("model", "claude-3-7-sonnet-latest")
155
 
156
- # Resolve latest version to specific version if needed
157
- if model in LATEST_VERSION_MAPPING:
158
- model = LATEST_VERSION_MAPPING[model]
159
-
160
- reve_model = MODEL_MAPPING.get(model, "llm_claude_sonnet_3_7")
161
-
162
- system_prompt = anthropic_req.get("system", "")
 
 
 
 
163
 
164
  if isinstance(system_prompt, list):
165
  system_text_chunks = []
@@ -170,58 +161,74 @@ def convert_anthropic_to_reve_request(anthropic_req):
170
  system_text_chunks.append(item)
171
  system_prompt = "\n".join(system_text_chunks)
172
 
173
- max_tokens = anthropic_req.get("max_tokens", 8192)
174
-
175
- temperature = anthropic_req.get("temperature", 1.0)
176
  temperature_percent = int(temperature * 100)
177
 
 
 
178
  conversation = []
 
179
  for msg in anthropic_req.get("messages", []):
180
  role = msg.get("role", "user")
181
-
182
  content = msg.get("content", "")
 
 
 
183
  multi_content = []
184
 
185
  if isinstance(content, str):
186
- multi_content = [{"text": content}]
 
187
  elif isinstance(content, list):
 
188
  for item in content:
189
  if isinstance(item, str):
 
190
  multi_content.append({"text": item})
191
  elif isinstance(item, dict):
192
  if item.get("type") == "text":
 
193
  multi_content.append({"text": item.get("text", "")})
194
  elif item.get("type") == "image":
195
- src = item["source"]
196
  multi_content.append({
197
  "image": {
198
- "type": src["type"],
199
- "media_type": src["type"],
200
- "data": src["data"]
201
  }
202
  })
 
 
 
203
 
204
- conversation.append({
205
- "role": role,
206
- "multi_content": multi_content
207
- })
208
 
209
  reve_req = {
210
- "model": reve_model,
211
- "max_length": max_tokens,
212
  "system_prompt": system_prompt,
 
 
213
  "temperature_percent": temperature_percent,
214
- "conversation": conversation
215
  }
216
 
217
- return reve_req
218
 
219
  def convert_reve_to_anthropic_response(reve_resp, reve_model):
220
- content = reve_resp.get("response", "")
 
 
 
 
 
221
 
222
- # Find the corresponding Anthropic model
223
- anthropic_model = next((anthr_model for anthr_model, rev_model in MODEL_MAPPING.items()
224
- if rev_model == reve_model), "claude-3-7-sonnet-20250219")
 
 
 
225
 
226
  anthropic_resp = {
227
  "id": "msg_" + os.urandom(8).hex(),
@@ -230,15 +237,15 @@ def convert_reve_to_anthropic_response(reve_resp, reve_model):
230
  "content": [
231
  {
232
  "type": "text",
233
- "text": content
234
  }
235
  ],
236
  "model": anthropic_model,
237
- "stop_reason": reve_resp.get("stop_reason", "end_turn"),
238
  "stop_sequence": None,
239
  "usage": {
240
- "input_tokens": reve_resp.get("prompt_tokens", 0),
241
- "output_tokens": reve_resp.get("completion_tokens", 0)
242
  }
243
  }
244
 
@@ -275,8 +282,7 @@ async def handle_anthropic_request(request):
275
  }
276
  }, status=400)
277
 
278
- reve_req = convert_anthropic_to_reve_request(anthropic_req)
279
- reve_model = reve_req['model']
280
  logger.info(f"Doing request with model {reve_model}")
281
 
282
  tried_tokens = set()
@@ -294,7 +300,8 @@ async def handle_anthropic_request(request):
294
 
295
  headers = {
296
  "Authorization": current_token,
297
- "Content-Type": "application/json; charset=utf-8"
 
298
  }
299
 
300
  try:
@@ -341,7 +348,7 @@ async def main():
341
  app = web.Application()
342
  app.router.add_post('/v1/messages', handle_anthropic_request)
343
 
344
- logger.info(f"Async proxy server running on port {PORT}")
345
  logger.info(f"Rate limit set to {RATE_LIMIT} requests per {RATE_LIMIT_WINDOW} seconds per IP")
346
 
347
  runner = web.AppRunner(app)
 
15
  logger = logging.getLogger(__name__)
16
 
17
  # Constants
18
+ PORT = 7860
19
  REVE_API_URL = "https://preview.reve.art/api/misc/chat"
20
  RATE_LIMIT = 4
21
  RATE_LIMIT_WINDOW = 60
22
  HASH_SALT = os.urandom(16).hex()
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  # Rate limiting store
25
  rate_limit_store = defaultdict(lambda: deque(maxlen=RATE_LIMIT))
26
 
 
138
  return token
139
 
140
  def convert_anthropic_to_reve_request(anthropic_req):
141
+ model_name = anthropic_req.get("model", "claude-3-7-sonnet-20250219")
142
 
143
+ reve_model = "llm_claude_sonnet_3_7"
144
+
145
+ if "claude-3-5-sonnet" in model_name:
146
+ if "20241022" in model_name:
147
+ reve_model = "llm_claude_sonnet_3_5_v2"
148
+ else:
149
+ reve_model = "llm_claude_sonnet_3_5"
150
+ elif "claude-3-5-haiku" in model_name:
151
+ reve_model = "llm_claude_haiku_3_5_v2"
152
+
153
+ system_prompt = anthropic_req.get("system", "You are a helpful assistant.")
154
 
155
  if isinstance(system_prompt, list):
156
  system_text_chunks = []
 
161
  system_text_chunks.append(item)
162
  system_prompt = "\n".join(system_text_chunks)
163
 
164
+ temperature = anthropic_req.get("temperature", 0.5)
 
 
165
  temperature_percent = int(temperature * 100)
166
 
167
+ max_tokens = anthropic_req.get("max_tokens", 4000)
168
+
169
  conversation = []
170
+
171
  for msg in anthropic_req.get("messages", []):
172
  role = msg.get("role", "user")
 
173
  content = msg.get("content", "")
174
+
175
+ reve_message = {"role": role}
176
+
177
  multi_content = []
178
 
179
  if isinstance(content, str):
180
+ multi_content.append({"text": content})
181
+ reve_message["content"] = content
182
  elif isinstance(content, list):
183
+ text_parts = []
184
  for item in content:
185
  if isinstance(item, str):
186
+ text_parts.append(item)
187
  multi_content.append({"text": item})
188
  elif isinstance(item, dict):
189
  if item.get("type") == "text":
190
+ text_parts.append(item.get("text", ""))
191
  multi_content.append({"text": item.get("text", "")})
192
  elif item.get("type") == "image":
193
+ src = item.get("source", {})
194
  multi_content.append({
195
  "image": {
196
+ "type": src.get("type", ""),
197
+ "media_type": src.get("media_type", src.get("type", "")),
198
+ "data": src.get("data", "")
199
  }
200
  })
201
+
202
+ if text_parts:
203
+ reve_message["content"] = " ".join(text_parts)
204
 
205
+ reve_message["multi_content"] = multi_content
206
+ conversation.append(reve_message)
 
 
207
 
208
  reve_req = {
 
 
209
  "system_prompt": system_prompt,
210
+ "conversation": conversation,
211
+ "model": reve_model,
212
  "temperature_percent": temperature_percent,
213
+ "max_length": max_tokens
214
  }
215
 
216
+ return reve_req, reve_model
217
 
218
  def convert_reve_to_anthropic_response(reve_resp, reve_model):
219
+ response_text = reve_resp.get("response", "")
220
+ stop_reason = reve_resp.get("stop_reason", "end_turn")
221
+ prompt_tokens = reve_resp.get("prompt_tokens", 0)
222
+ completion_tokens = reve_resp.get("completion_tokens", 0)
223
+
224
+ anthropic_model = "claude-3-7-sonnet-20250219" # default
225
 
226
+ if reve_model == "llm_claude_sonnet_3_5_v2":
227
+ anthropic_model = "claude-3-5-sonnet-20241022"
228
+ elif reve_model == "llm_claude_sonnet_3_5":
229
+ anthropic_model = "claude-3-5-sonnet-20240620"
230
+ elif reve_model == "llm_claude_haiku_3_5_v2":
231
+ anthropic_model = "claude-3-5-haiku-20241022"
232
 
233
  anthropic_resp = {
234
  "id": "msg_" + os.urandom(8).hex(),
 
237
  "content": [
238
  {
239
  "type": "text",
240
+ "text": response_text
241
  }
242
  ],
243
  "model": anthropic_model,
244
+ "stop_reason": stop_reason,
245
  "stop_sequence": None,
246
  "usage": {
247
+ "input_tokens": prompt_tokens,
248
+ "output_tokens": completion_tokens
249
  }
250
  }
251
 
 
282
  }
283
  }, status=400)
284
 
285
+ reve_req, reve_model = convert_anthropic_to_reve_request(anthropic_req)
 
286
  logger.info(f"Doing request with model {reve_model}")
287
 
288
  tried_tokens = set()
 
300
 
301
  headers = {
302
  "Authorization": current_token,
303
+ "Content-Type": "application/json",
304
+ "Accept": "application/json"
305
  }
306
 
307
  try:
 
348
  app = web.Application()
349
  app.router.add_post('/v1/messages', handle_anthropic_request)
350
 
351
+ logger.info(f"Reve.art API proxy running on port {PORT}")
352
  logger.info(f"Rate limit set to {RATE_LIMIT} requests per {RATE_LIMIT_WINDOW} seconds per IP")
353
 
354
  runner = web.AppRunner(app)