sonygod commited on
Commit
9e6ffec
·
1 Parent(s): fd50883
Files changed (2) hide show
  1. app.py +155 -0
  2. requirements.txt +1 -0
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import socket
 
2
  from fastapi import FastAPI, HTTPException, UploadFile, File, Form
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from fastapi.responses import HTMLResponse
@@ -486,5 +487,159 @@ async def proxy_request(url: str, request: Request):
486
  logger.error(f"Proxy error: {str(e)}")
487
  raise HTTPException(status_code=500, detail=str(e))
488
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  if __name__ == "__main__":
490
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import socket
2
+ from uuid import uuid4
3
  from fastapi import FastAPI, HTTPException, UploadFile, File, Form
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import HTMLResponse
 
487
  logger.error(f"Proxy error: {str(e)}")
488
  raise HTTPException(status_code=500, detail=str(e))
489
 
490
+
491
+ MODEL_MAPPING = {
492
+ "deepseek": "deepseek/deepseek-chat",
493
+ "gpt-4o-mini": "openai/gpt-4o-mini",
494
+ "gemini-flash-1.5": "google/gemini-flash-1.5",
495
+ "deepseek-reasoner": "deepseek-reasoner",
496
+ "minimax-01": "minimax/minimax-01"
497
+ }
498
+
499
+ def make_heck_request(question, session_id, messages, actual_model):
500
+ previous_question = previous_answer = None
501
+ if len(messages) >= 2:
502
+ for i in range(len(messages)-2, -1, -1):
503
+ if messages[i]["role"] == "user":
504
+ previous_question = messages[i]["content"]
505
+ if i+1 < len(messages) and messages[i+1]["role"] == "assistant":
506
+ previous_answer = messages[i+1]["content"]
507
+ break
508
+
509
+ payload = {
510
+ "model": actual_model,
511
+ "question": question,
512
+ "language": "Chinese",
513
+ "sessionId": session_id,
514
+ "previousQuestion": previous_question,
515
+ "previousAnswer": previous_answer
516
+ }
517
+
518
+ headers = {
519
+ "Content-Type": "application/json",
520
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
521
+ }
522
+
523
+ return requests.post(
524
+ "https://gateway.aiapilab.com/api/ha/v1/chat",
525
+ json=payload,
526
+ headers=headers,
527
+ stream=True
528
+ )
529
+
530
+ def stream_response(question, session_id, messages, request_model, actual_model):
531
+ resp = make_heck_request(question, session_id, messages, actual_model)
532
+ is_answering = False
533
+
534
+ for line in resp.iter_lines():
535
+ if line:
536
+ line = line.decode('utf-8')
537
+ if not line.startswith('data: '):
538
+ continue
539
+
540
+ content = line[6:].strip()
541
+
542
+ if content == "[ANSWER_START]":
543
+ is_answering = True
544
+ chunk = {
545
+ "id": session_id,
546
+ "object": "chat.completion.chunk",
547
+ "created": int(time.time()),
548
+ "model": request_model,
549
+ "choices": [{
550
+ "index": 0,
551
+ "delta": {"role": "assistant"},
552
+ }]
553
+ }
554
+ yield f"data: {json.dumps(chunk, ensure_ascii=False)}\n\n"
555
+ continue
556
+
557
+ if content == "[ANSWER_DONE]":
558
+ chunk = {
559
+ "id": session_id,
560
+ "object": "chat.completion.chunk",
561
+ "created": int(time.time()),
562
+ "model": request_model,
563
+ "choices": [{
564
+ "index": 0,
565
+ "delta": {},
566
+ "finish_reason": "stop"
567
+ }]
568
+ }
569
+ yield f"data: {json.dumps(chunk, ensure_ascii=False)}\n\n"
570
+ break
571
+
572
+ if is_answering and content and not content.startswith("[RELATE_Q"):
573
+ chunk = {
574
+ "id": session_id,
575
+ "object": "chat.completion.chunk",
576
+ "created": int(time.time()),
577
+ "model": request_model,
578
+ "choices": [{
579
+ "index": 0,
580
+ "delta": {"content": content},
581
+ }]
582
+ }
583
+ yield f"data: {json.dumps(chunk, ensure_ascii=False)}\n\n"
584
+
585
+ def normal_response(question, session_id, messages, request_model, actual_model):
586
+ resp = make_heck_request(question, session_id, messages, actual_model)
587
+ full_content = []
588
+ is_answering = False
589
+
590
+ for line in resp.iter_lines():
591
+ if line:
592
+ line = line.decode('utf-8')
593
+ if line.startswith('data: '):
594
+ content = line[6:].strip()
595
+ if content == "[ANSWER_START]":
596
+ is_answering = True
597
+ elif content == "[ANSWER_DONE]":
598
+ break
599
+ elif is_answering:
600
+ full_content.append(content)
601
+
602
+ response = {
603
+ "id": session_id,
604
+ "object": "chat.completion",
605
+ "created": int(time.time()),
606
+ "model": request_model,
607
+ "choices": [{
608
+ "index": 0,
609
+ "message": {
610
+ "role": "assistant",
611
+ "content": "".join(full_content)
612
+ },
613
+ "finish_reason": "stop"
614
+ }]
615
+ }
616
+ return response
617
+
618
+
619
+
620
+
621
+
622
+
623
+ @app.route("/v1/chat/completions", methods=["POST"])
624
+ def chat_completions():
625
+ data = requests.request.json
626
+ model = MODEL_MAPPING.get(data["model"])
627
+ if not model:
628
+ return {"error": "Unsupported Model"}, 400
629
+
630
+ question = next((msg["content"] for msg in reversed(data["messages"])
631
+ if msg["role"] == "user"), None)
632
+ session_id = str(uuid4())
633
+
634
+ if data.get("stream"):
635
+ return requests.Response(
636
+ stream_response(question, session_id, data["messages"],
637
+ data["model"], model),
638
+ mimetype="text/event-stream"
639
+ )
640
+ else:
641
+ return normal_response(question, session_id, data["messages"],
642
+ data["model"], model)
643
+
644
  if __name__ == "__main__":
645
  uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt CHANGED
@@ -5,3 +5,4 @@ python-multipart
5
  pydantic
6
  psutil
7
  aiohttp>=3.8.0
 
 
5
  pydantic
6
  psutil
7
  aiohttp>=3.8.0
8
+ uuid