Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- main.py +25 -8
- node3-ui/src/App.jsx +6 -5
main.py
CHANGED
|
@@ -68,14 +68,22 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 68 |
|
| 69 |
base_url = PROVIDER_BASES.get(request.provider, PROVIDER_BASES["Groq"])
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
try:
|
| 72 |
async with httpx.AsyncClient(timeout=60) as client:
|
| 73 |
resp = await client.post(
|
| 74 |
f"{base_url}/chat/completions",
|
| 75 |
-
headers=
|
| 76 |
-
"Authorization": f"Bearer {api_key}",
|
| 77 |
-
"Content-Type": "application/json",
|
| 78 |
-
},
|
| 79 |
json={
|
| 80 |
"model": request.model,
|
| 81 |
"messages": [
|
|
@@ -88,7 +96,7 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 88 |
resp.raise_for_status()
|
| 89 |
data = resp.json()
|
| 90 |
|
| 91 |
-
# Robust response extraction
|
| 92 |
reply = None
|
| 93 |
try:
|
| 94 |
choices = data.get("choices", [])
|
|
@@ -99,7 +107,7 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 99 |
except (KeyError, IndexError, TypeError):
|
| 100 |
pass
|
| 101 |
|
| 102 |
-
# Fallback
|
| 103 |
if not reply:
|
| 104 |
reply = (
|
| 105 |
data.get("text")
|
|
@@ -110,9 +118,16 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 110 |
or ""
|
| 111 |
)
|
| 112 |
|
| 113 |
-
#
|
| 114 |
if not reply:
|
| 115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
# Cache to Redis if available
|
| 118 |
if REDIS_OK:
|
|
@@ -124,6 +139,8 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 124 |
|
| 125 |
return {"response": reply, "doc": True}
|
| 126 |
|
|
|
|
|
|
|
| 127 |
except httpx.HTTPStatusError as e:
|
| 128 |
status = e.response.status_code
|
| 129 |
try:
|
|
|
|
| 68 |
|
| 69 |
base_url = PROVIDER_BASES.get(request.provider, PROVIDER_BASES["Groq"])
|
| 70 |
|
| 71 |
+
# Build headers
|
| 72 |
+
headers = {
|
| 73 |
+
"Authorization": f"Bearer {api_key}",
|
| 74 |
+
"Content-Type": "application/json",
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# OpenRouter needs extra headers for some models
|
| 78 |
+
if request.provider == "OpenRouter":
|
| 79 |
+
headers["HTTP-Referer"] = "https://augment17-logic-engine.hf.space"
|
| 80 |
+
headers["X-Title"] = "Manus Clone"
|
| 81 |
+
|
| 82 |
try:
|
| 83 |
async with httpx.AsyncClient(timeout=60) as client:
|
| 84 |
resp = await client.post(
|
| 85 |
f"{base_url}/chat/completions",
|
| 86 |
+
headers=headers,
|
|
|
|
|
|
|
|
|
|
| 87 |
json={
|
| 88 |
"model": request.model,
|
| 89 |
"messages": [
|
|
|
|
| 96 |
resp.raise_for_status()
|
| 97 |
data = resp.json()
|
| 98 |
|
| 99 |
+
# Robust response extraction
|
| 100 |
reply = None
|
| 101 |
try:
|
| 102 |
choices = data.get("choices", [])
|
|
|
|
| 107 |
except (KeyError, IndexError, TypeError):
|
| 108 |
pass
|
| 109 |
|
| 110 |
+
# Fallback keys
|
| 111 |
if not reply:
|
| 112 |
reply = (
|
| 113 |
data.get("text")
|
|
|
|
| 118 |
or ""
|
| 119 |
)
|
| 120 |
|
| 121 |
+
# Empty choices = model not found / not available
|
| 122 |
if not reply:
|
| 123 |
+
raise HTTPException(
|
| 124 |
+
status_code=404,
|
| 125 |
+
detail=(
|
| 126 |
+
f"Model '{request.model}' returned an empty response from {request.provider}. "
|
| 127 |
+
f"This usually means the model does not exist on {request.provider}'s API. "
|
| 128 |
+
f"Try a different model or switch to OpenRouter which supports more models."
|
| 129 |
+
)
|
| 130 |
+
)
|
| 131 |
|
| 132 |
# Cache to Redis if available
|
| 133 |
if REDIS_OK:
|
|
|
|
| 139 |
|
| 140 |
return {"response": reply, "doc": True}
|
| 141 |
|
| 142 |
+
except HTTPException:
|
| 143 |
+
raise
|
| 144 |
except httpx.HTTPStatusError as e:
|
| 145 |
status = e.response.status_code
|
| 146 |
try:
|
node3-ui/src/App.jsx
CHANGED
|
@@ -55,17 +55,18 @@ const MODELS = {
|
|
| 55 |
'deepseek/deepseek-chat', 'deepseek/deepseek-coder', 'deepseek/deepseek-r1',
|
| 56 |
'meta-llama/llama-3.3-70b-instruct', 'meta-llama/llama-3.1-405b-instruct',
|
| 57 |
'x-ai/grok-2-1212', 'x-ai/grok-2-vision-1212',
|
| 58 |
-
'mistralai/mistral-large', 'mistralai/mixtral-8x22b-instruct'
|
|
|
|
| 59 |
],
|
| 60 |
Nvidia: [
|
| 61 |
'minimaxai/minimax-m3', 'moonshotai/kimi-k2.6',
|
| 62 |
'deepseek-ai/deepseek-v4-pro', 'z-ai/glm-5.1',
|
| 63 |
'minimaxai/minimax-m1-40k', 'moonshotai/kimi-k2',
|
| 64 |
'deepseek-ai/deepseek-r1-0528', 'z-ai/glm-4.5',
|
| 65 |
-
'nvidia/llama-3.1-nemotron-70b-instruct', '
|
| 66 |
-
'meta/llama-3.1-
|
| 67 |
-
'mistralai/
|
| 68 |
-
'
|
| 69 |
],
|
| 70 |
Mistral: [
|
| 71 |
'mistral-large-latest', 'mistral-large-2411', 'mistral-large-2407',
|
|
|
|
| 55 |
'deepseek/deepseek-chat', 'deepseek/deepseek-coder', 'deepseek/deepseek-r1',
|
| 56 |
'meta-llama/llama-3.3-70b-instruct', 'meta-llama/llama-3.1-405b-instruct',
|
| 57 |
'x-ai/grok-2-1212', 'x-ai/grok-2-vision-1212',
|
| 58 |
+
'mistralai/mistral-large', 'mistralai/mixtral-8x22b-instruct',
|
| 59 |
+
'qwen/qwq-32b'
|
| 60 |
],
|
| 61 |
Nvidia: [
|
| 62 |
'minimaxai/minimax-m3', 'moonshotai/kimi-k2.6',
|
| 63 |
'deepseek-ai/deepseek-v4-pro', 'z-ai/glm-5.1',
|
| 64 |
'minimaxai/minimax-m1-40k', 'moonshotai/kimi-k2',
|
| 65 |
'deepseek-ai/deepseek-r1-0528', 'z-ai/glm-4.5',
|
| 66 |
+
'nvidia/llama-3.1-nemotron-70b-instruct', 'nvidia/nemotron-4-340b-instruct',
|
| 67 |
+
'meta/llama-3.1-405b-instruct', 'meta/llama-3.1-70b-instruct',
|
| 68 |
+
'mistralai/mistral-large-2-instruct', 'mistralai/mixtral-8x22b-instruct',
|
| 69 |
+
'google/gemma-2-27b-it', 'microsoft/phi-3-medium-128k-instruct'
|
| 70 |
],
|
| 71 |
Mistral: [
|
| 72 |
'mistral-large-latest', 'mistral-large-2411', 'mistral-large-2407',
|