Spaces:
Running
Running
| """Patch frontend: Replace DEFAULT_MODEL_OPTIONS with OpenRouter models.""" | |
| import re | |
| import sys | |
| FILE = "/source/frontend/src/components/Chat/ChatInput.tsx" | |
| MODEL_FILE = "/source/frontend/src/utils/model.ts" | |
| # === Step 1: Patch model.ts === | |
| with open(MODEL_FILE, "r") as f: | |
| model_content = f.read() | |
| model_content = model_content.replace( | |
| "export const KIMI_K27_CODE_MODEL_PATH = 'moonshotai/Kimi-K2.7-Code:novita';", | |
| "export const KIMI_K27_CODE_MODEL_PATH = 'deepseek-ai/DeepSeek-V4-Pro';" | |
| ) | |
| model_content = model_content.replace( | |
| "export const MINIMAX_M3_MODEL_PATH = 'MiniMaxAI/MiniMax-M3:novita';", | |
| "export const MINIMAX_M3_MODEL_PATH = 'deepseek-ai/DeepSeek-V4-Flash';" | |
| ) | |
| model_content = model_content.replace( | |
| "export const GLM_52_MODEL_PATH = 'zai-org/GLM-5.2:novita';", | |
| "export const GLM_52_MODEL_PATH = 'openai/deepseek/deepseek-v4-flash';" | |
| ) | |
| model_content = model_content.replace( | |
| "export const DEEPSEEK_V4_PRO_MODEL_PATH = 'deepseek-ai/DeepSeek-V4-Pro:novita';", | |
| "export const DEEPSEEK_V4_PRO_MODEL_PATH = 'nvidia/nemotron-3-super-120b-a12b:free';" | |
| ) | |
| # === PATCH: Add Laguna S 2.1 model path === | |
| if "LAGUNA_S21_MODEL_PATH" not in model_content: | |
| model_content = model_content.replace( | |
| "export const LAGUNA_M1_MODEL_PATH", | |
| "export const LAGUNA_S21_MODEL_PATH = 'openai/poolside/laguna-s-2.1:free';\n\nexport const LAGUNA_M1_MODEL_PATH" | |
| ) | |
| print("OK: Added LAGUNA_S21_MODEL_PATH") | |
| with open(MODEL_FILE, "w") as f: | |
| f.write(model_content) | |
| print("OK: model.ts constants updated") | |
| # === Step 2: Patch ChatInput.tsx === | |
| with open(FILE, "r", encoding="utf-8") as f: | |
| content = f.read() | |
| # Fix imports | |
| import_pattern = re.compile( | |
| r'import\s*\{[^}]+\}\s*from\s*[\'"]@/utils/model[\'"];' | |
| ) | |
| match = import_pattern.search(content) | |
| if match: | |
| content = content.replace(match.group(0), "import { isClaudePath } from '@/utils/model';") | |
| print("OK: Replaced imports") | |
| # Remove Owl Alpha references | |
| content = content.replace("'Owl Alpha'", "'Claude Opus 4.8'") | |
| content = content.replace('"Owl Alpha"', '"Claude Opus 4.8"') | |
| # Row 3: Kimi → DeepSeek V4 Pro | |
| content = content.replace("'Kimi K2.7 Code'", "'DeepSeek V4 Pro'") | |
| content = content.replace('"Kimi K2.7 Code"', '"DeepSeek V4 Pro"') | |
| # Row 4: MiniMax → DeepSeek V4 Flash | |
| content = content.replace("'MiniMax M3'", "'DeepSeek V4 Flash'") | |
| content = content.replace('"MiniMax M3"', '"DeepSeek V4 Flash"') | |
| # Row 5: GLM → DeepSeek V4 Flash | |
| content = content.replace("'GLM 5.2'", "'DeepSeek V4 Flash'") | |
| content = content.replace('"GLM 5.2"', '"DeepSeek V4 Flash"') | |
| # Row 6: DeepSeek V4 Pro → Nemotron | |
| content = content.replace( | |
| " {\n id: 'deepseek-v4-pro',\n name: 'DeepSeek V4 Pro',\n modelPath: DEEPSEEK_V4_PRO_MODEL_PATH,\n avatarUrl: getHfAvatarUrl('deepseek-ai/DeepSeek-V4-Pro'),\n },", | |
| " {\n id: 'nemotron-120b',\n name: 'nvidia/nemotron-3-super-120b-a12b:free',\n modelPath: DEEPSEEK_V4_PRO_MODEL_PATH,\n avatarUrl: 'https://huggingface.co/api/avatars/nvidia',\n }," | |
| ) | |
| # Replace entire DEFAULT_MODEL_OPTIONS array | |
| pattern = r'const DEFAULT_MODEL_OPTIONS: ModelOption\[\] = \[.*?\];' | |
| match = re.search(pattern, content, re.DOTALL) | |
| if not match: | |
| print("FAIL: Could not find DEFAULT_MODEL_OPTIONS array!") | |
| sys.exit(1) | |
| NEW_MODELS = """const DEFAULT_MODEL_OPTIONS: ModelOption[] = [ | |
| { | |
| id: 'tencent-hy3', | |
| name: 'Tencent HY3:free', | |
| modelPath: 'openai/tencent/hy3:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/tencent', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'gemma-4-31b', | |
| name: 'Gemma 4 31B:free', | |
| modelPath: 'openai/google/gemma-4-31b-it:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/google', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'llama-3.3-70b', | |
| name: 'Llama 3.3 70B:free', | |
| modelPath: 'openai/meta-llama/llama-3.3-70b-instruct:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/meta-llama', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'laguna-m1', | |
| name: 'Laguna M.1:free', | |
| modelPath: 'openai/poolside/laguna-m.1:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/poolside', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'laguna-s21', | |
| name: 'Laguna S 2.1:free', | |
| modelPath: 'openai/poolside/laguna-s-2.1:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/poolside', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'nex-n2-mini', | |
| name: 'nex-agi/nex-n2-mini', | |
| modelPath: 'openai/nex-agi/nex-n2-mini', | |
| avatarUrl: 'https://huggingface.co/api/avatars/nex-agi', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'ling-3.0-flash', | |
| name: 'inclusionai/ling-3.0-flash:free', | |
| modelPath: 'openai/inclusionai/ling-3.0-flash:free', | |
| avatarUrl: 'https://huggingface.co/api/avatars/inclusionai', | |
| recommended: true, | |
| }, | |
| { | |
| id: 'llama-3.1-8b', | |
| name: 'Llama 3.1 8B', | |
| modelPath: 'openai/meta-llama/llama-3.1-8b-instruct', | |
| avatarUrl: 'https://huggingface.co/api/avatars/meta-llama', | |
| }, | |
| { | |
| id: 'qwen3-coder-next', | |
| name: 'Qwen3 Coder Next', | |
| modelPath: 'Qwen/Qwen3-Coder-Next', | |
| avatarUrl: 'https://huggingface.co/api/avatars/Qwen', | |
| }, | |
| { | |
| id: 'gemini-2.0-flash', | |
| name: 'Gemini 2.0 Flash', | |
| modelPath: 'openai/google/gemini-2.0-flash-001', | |
| avatarUrl: 'https://huggingface.co/api/avatars/google', | |
| }, | |
| ];""" | |
| content = content[:match.start()] + NEW_MODELS + content[match.end():] | |
| # Update DEFAULT_MODEL_PATH | |
| dm_path = re.search(r'const DEFAULT_MODEL_PATH\s*=.*?;', content) | |
| if dm_path: | |
| content = content.replace(dm_path.group(0), "const DEFAULT_MODEL_PATH = 'openai/tencent/hy3:free';") | |
| print("OK: Replaced DEFAULT_MODEL_PATH") | |
| else: | |
| print("OK: DEFAULT_MODEL_PATH not found") | |
| with open(FILE, "w", encoding="utf-8") as f: | |
| f.write(content) | |
| print("OK: Frontend patched - Tencent HY3:free DEFAULT") | |
| print(" Models: HY3:free, Gemma 4 31B:free, Llama 3.3 70B:free, Laguna M.1:free, Laguna S 2.1:free, Nex N2 Mini, Ling 3.0 Flash:free, Llama 3.1 8B") |