Spaces:
Paused
Paused
Add 3 new OpenRouter models: UPSTAGE Solar Pro 4, NVIDIA Nemotron 3.5 Lightning:free, Liquid LFM 2.5 2.6B:free
Browse files- BUILD_TRIGGER +1 -1
- Dockerfile +6 -0
- README.md +1 -0
- patch_frontend_new_models.py +71 -0
- patch_new_models.py +88 -0
BUILD_TRIGGER
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
|
|
|
|
| 1 |
+
rebuild_new_models_1786504823
|
Dockerfile
CHANGED
|
@@ -13,6 +13,9 @@ RUN python3 /tmp/patch_frontend_uploads.py
|
|
| 13 |
# Patch frontend: multi-file uploads (many images/files at once)
|
| 14 |
COPY patch_frontend_multi.py /tmp/patch_frontend_multi.py
|
| 15 |
RUN python3 /tmp/patch_frontend_multi.py
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
# Patch auto-continue V17
|
| 18 |
COPY patch_auto_continue_v17.py /tmp/patch_auto_continue_v17.py
|
|
@@ -65,6 +68,9 @@ COPY backend/document_parser.py /app/backend/document_parser.py
|
|
| 65 |
# Patch backend: accept new model IDs
|
| 66 |
COPY patch_models.py /tmp/patch_models.py
|
| 67 |
RUN python /tmp/patch_models.py
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
# Patch backend: auto-continue detection + auto-approve
|
| 70 |
COPY patch_agent_backend.py /tmp/patch_agent_backend.py
|
|
|
|
| 13 |
# Patch frontend: multi-file uploads (many images/files at once)
|
| 14 |
COPY patch_frontend_multi.py /tmp/patch_frontend_multi.py
|
| 15 |
RUN python3 /tmp/patch_frontend_multi.py
|
| 16 |
+
# Patch frontend: add 3 new OpenRouter models
|
| 17 |
+
COPY patch_frontend_new_models.py /tmp/patch_frontend_new_models.py
|
| 18 |
+
RUN python3 /tmp/patch_frontend_new_models.py
|
| 19 |
|
| 20 |
# Patch auto-continue V17
|
| 21 |
COPY patch_auto_continue_v17.py /tmp/patch_auto_continue_v17.py
|
|
|
|
| 68 |
# Patch backend: accept new model IDs
|
| 69 |
COPY patch_models.py /tmp/patch_models.py
|
| 70 |
RUN python /tmp/patch_models.py
|
| 71 |
+
# Patch backend: add 3 new OpenRouter models
|
| 72 |
+
COPY patch_new_models.py /tmp/patch_new_models.py
|
| 73 |
+
RUN python /tmp/patch_new_models.py
|
| 74 |
|
| 75 |
# Patch backend: auto-continue detection + auto-approve
|
| 76 |
COPY patch_agent_backend.py /tmp/patch_agent_backend.py
|
README.md
CHANGED
|
@@ -30,6 +30,7 @@ tags:
|
|
| 30 |
- Added OpenRouter routing (catch-all `openai/` prefix → OpenRouter API)
|
| 31 |
- Default: `openai/tencent/hy3:free`
|
| 32 |
- Models: Tencent HY3:free, Gemma 4 31B:free, Llama 3.3 70B:free, **Laguna M.1:free**, **Laguna S 2.1:free**, Llama 3.1 8B, DeepSeek V4 Flash latest
|
|
|
|
| 33 |
- Ollama: không thể dùng cho HF Space (local inference, không có cloud API free cho use case này)
|
| 34 |
|
| 35 |
## 📎 Upload tài liệu để AI hiểu ngữ cảnh (PDF, ảnh, Excel, Word, ...)
|
|
|
|
| 30 |
- Added OpenRouter routing (catch-all `openai/` prefix → OpenRouter API)
|
| 31 |
- Default: `openai/tencent/hy3:free`
|
| 32 |
- Models: Tencent HY3:free, Gemma 4 31B:free, Llama 3.3 70B:free, **Laguna M.1:free**, **Laguna S 2.1:free**, Llama 3.1 8B, DeepSeek V4 Flash latest
|
| 33 |
+
- New: **UPSTAGE Solar Pro 4**, **NVIDIA Nemotron 3.5 Lightning:free**, **Liquid LFM 2.5 2.6B:free**
|
| 34 |
- Ollama: không thể dùng cho HF Space (local inference, không có cloud API free cho use case này)
|
| 35 |
|
| 36 |
## 📎 Upload tài liệu để AI hiểu ngữ cảnh (PDF, ảnh, Excel, Word, ...)
|
patch_frontend_new_models.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Patch frontend ChatInput.tsx: add 3 new OpenRouter models to the model picker.
|
| 2 |
+
|
| 3 |
+
New models (openai/ prefix routes to OpenRouter):
|
| 4 |
+
- UPSTAGE Solar Pro 4 (openai/upstage/solar-pro4)
|
| 5 |
+
- NVIDIA Nemotron 3.5 Lightning:free (openai/nvidia/nemotron-3.5-lightning:free)
|
| 6 |
+
- Liquid LFM 2.5 2.6B:free (openai/liquid/lfm-2.5-2.6b:free)
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
import os
|
| 10 |
+
|
| 11 |
+
FILE = "/source/frontend/src/components/Chat/ChatInput.tsx"
|
| 12 |
+
|
| 13 |
+
def patch():
|
| 14 |
+
if not os.path.exists(FILE):
|
| 15 |
+
print(f"SKIP: {FILE} not found")
|
| 16 |
+
return
|
| 17 |
+
|
| 18 |
+
with open(FILE, "r", encoding="utf-8") as f:
|
| 19 |
+
content = f.read()
|
| 20 |
+
|
| 21 |
+
if "upstage-solar-pro4" in content:
|
| 22 |
+
print("OK: models already present")
|
| 23 |
+
return
|
| 24 |
+
|
| 25 |
+
# Unique anchor: the deepseek-v4-flash-latest entry inside DEFAULT_MODEL_OPTIONS.
|
| 26 |
+
# Insert the 3 new model objects immediately BEFORE that entry.
|
| 27 |
+
anchor = " {\n id: 'deepseek-v4-flash-latest',\n"
|
| 28 |
+
new_entries = (
|
| 29 |
+
" {\n"
|
| 30 |
+
" id: 'upstage-solar-pro4',\n"
|
| 31 |
+
" name: 'UPSTAGE Solar Pro 4',\n"
|
| 32 |
+
" modelPath: 'openai/upstage/solar-pro4',\n"
|
| 33 |
+
" avatarUrl: 'https://huggingface.co/api/avatars/upstage',\n"
|
| 34 |
+
" recommended: true,\n"
|
| 35 |
+
" },\n"
|
| 36 |
+
" {\n"
|
| 37 |
+
" id: 'nemotron-3.5-lightning',\n"
|
| 38 |
+
" name: 'NVIDIA Nemotron 3.5 Lightning:free',\n"
|
| 39 |
+
" modelPath: 'openai/nvidia/nemotron-3.5-lightning:free',\n"
|
| 40 |
+
" avatarUrl: 'https://huggingface.co/api/avatars/nvidia',\n"
|
| 41 |
+
" recommended: true,\n"
|
| 42 |
+
" },\n"
|
| 43 |
+
" {\n"
|
| 44 |
+
" id: 'liquid-lfm-2.5-2.6b',\n"
|
| 45 |
+
" name: 'Liquid LFM 2.5 2.6B:free',\n"
|
| 46 |
+
" modelPath: 'openai/liquid/lfm-2.5-2.6b:free',\n"
|
| 47 |
+
" avatarUrl: 'https://huggingface.co/api/avatars/liquid',\n"
|
| 48 |
+
" recommended: true,\n"
|
| 49 |
+
" },\n"
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
if anchor in content:
|
| 53 |
+
content = content.replace(anchor, new_entries + anchor, 1)
|
| 54 |
+
print("OK: added 3 new models before deepseek-v4-flash-latest entry")
|
| 55 |
+
else:
|
| 56 |
+
# Fallback: find the deepseek id line by itself.
|
| 57 |
+
alt = " id: 'deepseek-v4-flash-latest',\n"
|
| 58 |
+
if alt in content:
|
| 59 |
+
content = content.replace(alt, new_entries + " {\n" + alt, 1)
|
| 60 |
+
print("OK: added 3 new models (fallback anchor)")
|
| 61 |
+
else:
|
| 62 |
+
print("FAIL: could not find insertion anchor in DEFAULT_MODEL_OPTIONS")
|
| 63 |
+
return
|
| 64 |
+
|
| 65 |
+
with open(FILE, "w", encoding="utf-8") as f:
|
| 66 |
+
f.write(content)
|
| 67 |
+
print("OK: ChatInput.tsx new models patched")
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
if __name__ == "__main__":
|
| 71 |
+
patch()
|
patch_new_models.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Patch backend: add 3 new OpenRouter models (openai/ prefix routes to OpenRouter).
|
| 2 |
+
|
| 3 |
+
New models:
|
| 4 |
+
- openai/upstage/solar-pro4
|
| 5 |
+
- openai/nvidia/nemotron-3.5-lightning:free
|
| 6 |
+
- openai/liquid/lfm-2.5-2.6b:free
|
| 7 |
+
|
| 8 |
+
The `openai/` prefix is already stripped in _resolve_llm_params and routed to
|
| 9 |
+
OpenRouter, so we only need to register the model IDs, imports, and the
|
| 10 |
+
available-models list.
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
import ast
|
| 14 |
+
import os
|
| 15 |
+
|
| 16 |
+
IDS_FILE = "/app/agent/core/model_ids.py"
|
| 17 |
+
AGENT_FILE = "/app/backend/routes/agent.py"
|
| 18 |
+
|
| 19 |
+
# ---------- 1. model_ids.py ----------
|
| 20 |
+
with open(IDS_FILE) as f:
|
| 21 |
+
c = f.read()
|
| 22 |
+
|
| 23 |
+
new_constants = '''UPSTAGE_SOLAR_PRO4_MODEL_ID = "openai/upstage/solar-pro4"
|
| 24 |
+
NEMOTRON_3_5_LIGHTNING_FREE_MODEL_ID = "openai/nvidia/nemotron-3.5-lightning:free"
|
| 25 |
+
LIQUID_LFM_2_5_2_6B_FREE_MODEL_ID = "openai/liquid/lfm-2.5-2.6b:free"
|
| 26 |
+
'''
|
| 27 |
+
|
| 28 |
+
if "UPSTAGE_SOLAR_PRO4_MODEL_ID" not in c:
|
| 29 |
+
# Insert before DEEPSEEK_V4_PRO_MODEL_ID definition
|
| 30 |
+
target = 'DEEPSEEK_V4_PRO_MODEL_ID = "nvidia/nemotron-3-super-120b-a12b:free"'
|
| 31 |
+
if target in c:
|
| 32 |
+
c = c.replace(target, new_constants + target)
|
| 33 |
+
print("OK: added 3 new model constants to model_ids.py")
|
| 34 |
+
else:
|
| 35 |
+
# fallback: append at end of constants near TENCENT/HY3 block
|
| 36 |
+
anchor = 'LING_3_0_FLASH_FREE_MODEL_ID = "openai/inclusionai/ling-3.0-flash:free"'
|
| 37 |
+
if anchor in c:
|
| 38 |
+
c = c.replace(anchor, anchor + "\n" + new_constants)
|
| 39 |
+
print("OK: added constants after LING block")
|
| 40 |
+
else:
|
| 41 |
+
print("FAIL: could not find insertion anchor in model_ids.py")
|
| 42 |
+
else:
|
| 43 |
+
print("OK: constants already present")
|
| 44 |
+
|
| 45 |
+
with open(IDS_FILE, "w") as f:
|
| 46 |
+
f.write(c)
|
| 47 |
+
ast.parse(c)
|
| 48 |
+
print("OK: model_ids.py syntax OK")
|
| 49 |
+
|
| 50 |
+
# ---------- 2. agent.py : imports + _available_models ----------
|
| 51 |
+
with open(AGENT_FILE) as f:
|
| 52 |
+
ac = f.read()
|
| 53 |
+
|
| 54 |
+
# Add imports
|
| 55 |
+
if "UPSTAGE_SOLAR_PRO4_MODEL_ID" not in ac:
|
| 56 |
+
old_imp = " NEX_N2_MINI_MODEL_ID,\n LING_3_0_FLASH_FREE_MODEL_ID,\n"
|
| 57 |
+
new_imp = (
|
| 58 |
+
" NEX_N2_MINI_MODEL_ID,\n"
|
| 59 |
+
" LING_3_0_FLASH_FREE_MODEL_ID,\n"
|
| 60 |
+
" UPSTAGE_SOLAR_PRO4_MODEL_ID,\n"
|
| 61 |
+
" NEMOTRON_3_5_LIGHTNING_FREE_MODEL_ID,\n"
|
| 62 |
+
" LIQUID_LFM_2_5_2_6B_FREE_MODEL_ID,\n"
|
| 63 |
+
)
|
| 64 |
+
if old_imp in ac:
|
| 65 |
+
ac = ac.replace(old_imp, new_imp)
|
| 66 |
+
print("OK: added new model imports")
|
| 67 |
+
else:
|
| 68 |
+
print("WARN: import anchor not matched")
|
| 69 |
+
|
| 70 |
+
# Add to _available_models list - insert after LING_3_0_FLASH line
|
| 71 |
+
old_line = ' {"id": LING_3_0_FLASH_FREE_MODEL_ID, "label": "inclusionai/ling-3.0-flash:free", "recommended": True},\n'
|
| 72 |
+
new_line = old_line + (
|
| 73 |
+
' {"id": UPSTAGE_SOLAR_PRO4_MODEL_ID, "label": "UPSTAGE Solar Pro 4", "recommended": True},\n'
|
| 74 |
+
' {"id": NEMOTRON_3_5_LIGHTNING_FREE_MODEL_ID, "label": "NVIDIA Nemotron 3.5 Lightning:free", "recommended": True},\n'
|
| 75 |
+
' {"id": LIQUID_LFM_2_5_2_6B_FREE_MODEL_ID, "label": "Liquid LFM 2.5 2.6B:free", "recommended": True},\n'
|
| 76 |
+
)
|
| 77 |
+
if old_line in ac:
|
| 78 |
+
ac = ac.replace(old_line, new_line)
|
| 79 |
+
print("OK: added 3 new models to _available_models")
|
| 80 |
+
else:
|
| 81 |
+
print("WARN: _available_models LING line not matched (check exact text)")
|
| 82 |
+
|
| 83 |
+
with open(AGENT_FILE, "w") as f:
|
| 84 |
+
f.write(ac)
|
| 85 |
+
ast.parse(ac)
|
| 86 |
+
print("OK: agent.py syntax OK")
|
| 87 |
+
|
| 88 |
+
print("DONE: 3 new OpenRouter models added (backend)")
|