ml-intern / patch_frontend.py
bep40's picture
Add Laguna S 2.1:free to frontend dropdown, replace GPT-5.5
f2a4625 verified
Raw
History Blame
5.52 kB
"""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_array = """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: '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_array + 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, Llama 3.1 8B")