Space-Mutiverse-Control / patch_frontend.py
bep40's picture
Upload patch_frontend.py
9fca8b2 verified
Raw
History Blame
6.09 kB
"""Patch frontend ChatInput.tsx: Replace entire DEFAULT_MODEL_OPTIONS array.
OpenRouter model routing on backend:
- Models with openai/google/, openai/deepseek/, openai/nvidia/, openai/poolside/ → OpenRouter
- Models starting with openai/openrouter/ → OpenRouter
- All others → HF Inference Router
Owl Alpha removed (provider Stealth broken on OpenRouter).
Replaced with Gemma 4 9B (free, reliable on OpenRouter).
"""
FILE = "/source/frontend/src/components/Chat/ChatInput.tsx"
with open(FILE) as f:
content = f.read()
# === Step 1: Fix imports - remove unused constants, keep isClaudePath ===
old_import = """import {
CLAUDE_OPUS_48_MODEL_PATH,
GPT_55_MODEL_PATH,
KIMI_K26_MODEL_PATH,
isClaudePath,
} from '@/utils/model';"""
new_import = """import { isClaudePath } from '@/utils/model';"""
if old_import in content:
content = content.replace(old_import, new_import)
print("✅ Fixed imports")
else:
# Try single-line format
alt_import = "import { CLAUDE_OPUS_48_MODEL_PATH, GPT_55_MODEL_PATH, KIMI_K26_MODEL_PATH, isClaudePath } from '@/utils/model';"
if alt_import in content:
content = content.replace(alt_import, "import { isClaudePath } from '@/utils/model';")
print("✅ Fixed imports (single-line)")
else:
print("⚠ Could not find import line, checking if already patched...")
if "import { isClaudePath } from '@/utils/model'" in content:
print(" Already patched, skipping")
else:
print("❌ Import line not found!")
raise SystemExit(1)
# === Step 2: Replace DEFAULT_MODEL_OPTIONS array ===
marker = "const DEFAULT_MODEL_OPTIONS: ModelOption[] = ["
start = content.find(marker)
if start < 0:
print("❌ DEFAULT_MODEL_OPTIONS not found!")
# Debug: find the actual position
alt = content.find("DEFAULT_MODEL_OPTIONS")
if alt >= 0:
print(f" Found 'DEFAULT_MODEL_OPTIONS' at pos {alt}")
print(f" Context: {repr(content[alt:alt+150])}")
raise SystemExit(1)
# Find the end of the array by counting brackets
end = content.find("];", start)
if end < 0:
print("❌ Array closing ] not found!")
raise SystemExit(1)
# Validate we found the right ] by looking for the pattern
check_segment = content[start:end]
if "];" in check_segment:
# There might be nested arrays - find the outermost ]
depth = 0
for i, ch in enumerate(content[start:], start):
if ch == '[':
depth += 1
elif ch == ']':
depth -= 1
if depth == 0:
end = i + 1 # include the ;
# look for ; after ]
if end < len(content) and content[end] == ';':
end += 1
break
else:
end = end + 2
new_array = """const DEFAULT_MODEL_OPTIONS: ModelOption[] = [
{
id: 'deepseek-v4-pro',
name: 'DeepSeek V4 Pro',
modelPath: 'deepseek-ai/DeepSeek-V4-Pro',
avatarUrl: 'https://huggingface.co/api/avatars/deepseek-ai',
recommended: true,
},
{
id: 'deepseek-v4-flash',
name: 'DeepSeek V4 Flash',
modelPath: 'deepseek-ai/DeepSeek-V4-Flash',
avatarUrl: 'https://huggingface.co/api/avatars/deepseek-ai',
},
{
id: 'gpt-5.5',
name: 'GPT-5.5',
modelPath: 'openai/gpt-5.5:fal-ai',
avatarUrl: 'https://huggingface.co/api/avatars/openai',
},
{
id: 'qwen3-coder-next',
name: 'Qwen3 Coder Next',
modelPath: 'Qwen/Qwen3-Coder-Next',
avatarUrl: 'https://huggingface.co/api/avatars/Qwen',
recommended: true,
},
{
id: 'gemma-3-1b',
name: 'Gemma 3 1B',
modelPath: 'google/gemma-3-1b-it',
avatarUrl: 'https://huggingface.co/api/avatars/google',
recommended: true,
},
{
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',
},
{
id: 'deepseek-v4-flash-or',
name: 'DeepSeek V4 Flash (OR)',
modelPath: 'openai/deepseek/deepseek-v4-flash:free',
avatarUrl: 'https://huggingface.co/api/avatars/deepseek-ai',
},
{
id: 'gemma-4-9b',
name: 'Gemma 4 9B',
modelPath: 'openai/google/gemma-4-9b-it:free',
avatarUrl: 'https://huggingface.co/api/avatars/google',
recommended: true,
},
{
id: 'gemma-4-31b',
name: 'Gemma 4 31B',
modelPath: 'openai/google/gemma-4-31b-it:free',
avatarUrl: 'https://huggingface.co/api/avatars/google',
recommended: true,
},
{
id: 'nemotron-120b',
name: 'Nemotron 3 Super 120B',
modelPath: 'openai/nvidia/nemotron-3-super-120b-a12b:free',
avatarUrl: 'https://huggingface.co/api/avatars/nvidia',
},
{
id: 'nemotron-3-ultra',
name: 'Nemotron 3 Ultra 550B',
modelPath: 'openai/nvidia/nemotron-3-ultra-550b-a55b:free',
avatarUrl: 'https://huggingface.co/api/avatars/nvidia',
recommended: true,
},
{
id: 'laguna-m',
name: 'Laguna M.1',
modelPath: 'openai/poolside/laguna-m.1:free',
avatarUrl: 'https://huggingface.co/api/avatars/poolside',
recommended: true,
},
{
id: 'laguna-xs',
name: 'Laguna XS.2',
modelPath: 'openai/poolside/laguna-xs.2:free',
avatarUrl: 'https://huggingface.co/api/avatars/poolside',
},
];"""
content = content[:start] + new_array + content[end:]
# === Step 3: DEFAULT_FREE_MODEL_OPTION_ID ===
old_free = "DEFAULT_FREE_MODEL_OPTION_ID = 'kimi-k2.6'"
new_free = "DEFAULT_FREE_MODEL_OPTION_ID = 'deepseek-v4-pro'"
if old_free in content:
content = content.replace(old_free, new_free)
print("✅ Set default free model to DeepSeek V4 Pro")
elif "DEFAULT_FREE_MODEL_OPTION_ID" in content:
print("⚠ DEFAULT_FREE_MODEL_OPTION_ID found, checking value...")
idx = content.find("DEFAULT_FREE_MODEL_OPTION_ID")
print(f" Context: {repr(content[idx:idx+80])}")
with open(FILE, "w") as f:
f.write(content)
print("✅ Frontend patched — 13 models")
print(" Owl Alpha REMOVED (Stealth provider broken)")
print(" Replaced with: Gemma 4 9B (OpenRouter free)")
print(" Default: DeepSeek V4 Pro")