|
|
from flask import Flask, request, jsonify |
|
|
import json |
|
|
import logging |
|
|
import time |
|
|
from gradio_client import Client |
|
|
from json.decoder import JSONDecodeError |
|
|
import httpx |
|
|
|
|
|
app = Flask(__name__) |
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO, |
|
|
format='%(asctime)s - %(levelname)s - %(message)s') |
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
jarvis = None |
|
|
JARVIS_INIT_LOCK = False |
|
|
|
|
|
|
|
|
models = [ |
|
|
"JARVIS: 2.1.2", |
|
|
"DeepSeek: V3-0324", |
|
|
|
|
|
"Agentica: Deepcoder 14B Preview" |
|
|
] |
|
|
|
|
|
|
|
|
API_KEY = "ez8j795dR3zChxvIG9VgcuCTyV9iJRFL" |
|
|
|
|
|
def authenticate_request(request): |
|
|
auth_header = request.headers.get('Authorization') |
|
|
if auth_header is None or not auth_header.startswith('Bearer '): |
|
|
return False |
|
|
provided_api_key = auth_header.split(' ')[1] |
|
|
return provided_api_key == API_KEY |
|
|
|
|
|
|
|
|
def get_jarvis_client(): |
|
|
global jarvis, JARVIS_INIT_LOCK |
|
|
if jarvis is None and not JARVIS_INIT_LOCK: |
|
|
JARVIS_INIT_LOCK = True |
|
|
max_retries = 5 |
|
|
retry_delay = 5 |
|
|
for attempt in range(max_retries): |
|
|
try: |
|
|
logger.info(f"Attempting to initialize JARVIS client (attempt {attempt+1}/{max_retries})...") |
|
|
jarvis = Client("hadadrjt/ai", client_kwargs={"timeout": httpx.Timeout(60.0)}) |
|
|
logger.info("JARVIS client initialized successfully.") |
|
|
JARVIS_INIT_LOCK = False |
|
|
return jarvis |
|
|
except JSONDecodeError as e: |
|
|
logger.warning(f"Attempt {attempt + 1}/{max_retries}: JSONDecodeError during JARVIS client initialization: {e}") |
|
|
try: |
|
|
response = e.doc |
|
|
logger.warning(f"Problematic response content: {response[:200]}...") |
|
|
except: |
|
|
logger.warning("Could not retrieve problematic response content.") |
|
|
|
|
|
if attempt < max_retries - 1: |
|
|
time.sleep(retry_delay) |
|
|
else: |
|
|
logger.error("Max retries reached. JARVIS client initialization failed due to JSONDecodeError.") |
|
|
JARVIS_INIT_LOCK = False |
|
|
return None |
|
|
except Exception as e: |
|
|
logger.error(f"Attempt {attempt + 1}/{max_retries}: Error during JARVIS client initialization: {e}") |
|
|
if attempt < max_retries - 1: |
|
|
time.sleep(retry_delay) |
|
|
else: |
|
|
logger.error("Max retries reached. JARVIS client initialization failed due to general exception.") |
|
|
JARVIS_INIT_LOCK = False |
|
|
return None |
|
|
JARVIS_INIT_LOCK = False |
|
|
|
|
|
elif JARVIS_INIT_LOCK: |
|
|
logger.info("JARVIS client initialization is already in progress, waiting...") |
|
|
while JARVIS_INIT_LOCK: |
|
|
time.sleep(1) |
|
|
|
|
|
return jarvis |
|
|
|
|
|
@app.route("/v1/chat/completions", methods=["POST"]) |
|
|
def chat_completions(): |
|
|
if not authenticate_request(request): |
|
|
return jsonify({"error": {"message": "Invalid API key", "code": "invalid_api_key"}}), 401 |
|
|
|
|
|
current_jarvis = get_jarvis_client() |
|
|
if current_jarvis is None: |
|
|
return jsonify({"error": {"message": "JARVIS client failed to initialize. API not available.", "code": "jarvis_not_initialized"}}), 500 |
|
|
|
|
|
|
|
|
data = request.json |
|
|
messages = data.get("messages", []) |
|
|
model = data.get("model", "JARVIS: 2.1.2") |
|
|
stream = data.get("stream", False) |
|
|
|
|
|
|
|
|
if not isinstance(messages, list): |
|
|
return jsonify({"error": ..., "code": ...}), 400 |
|
|
for message in messages: |
|
|
if not isinstance(message, dict) or 'role' not in message or 'content' not in message: |
|
|
return jsonify({"error": ..., "code": ...}), 400 |
|
|
|
|
|
last_message = messages[-1]["content"] |
|
|
|
|
|
try: |
|
|
current_jarvis.predict(new=model, api_name="/change_model") |
|
|
result = current_jarvis.predict(multi={"text": last_message}, api_name="/api") |
|
|
response_text = result[0][0][1] |
|
|
|
|
|
response_data = { |
|
|
"id": ..., "object": ..., "created": ..., |
|
|
"choices": [{ "index": 0, "message": { "role": "assistant", "content": response_text }, "finish_reason": "stop" }], |
|
|
"usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 } |
|
|
} |
|
|
return jsonify(response_data) |
|
|
|
|
|
except Exception as e: |
|
|
logger.error(f"Error processing request: {str(e)}") |
|
|
return jsonify({"error": {"message": str(e), "code": "jarvis_error"}}), 500 |
|
|
|
|
|
@app.route("/v1/models", methods=["GET"]) |
|
|
def list_models(): |
|
|
if not authenticate_request(request): |
|
|
return jsonify({"error": {"message": "Invalid API key", "code": "invalid_api_key"}}), 401 |
|
|
|
|
|
current_jarvis = get_jarvis_client() |
|
|
if current_jarvis is None: |
|
|
return jsonify({"error": {"message": "JARVIS client failed to initialize. API not available.", "code": "jarvis_not_initialized"}}), 500 |
|
|
|
|
|
return jsonify({"data": [{"id": model} for model in models], "object": "list"}) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
app.run(host='0.0.0.0', port=7860) |