File size: 5,023 Bytes
4ef1c2f
 
 
 
 
 
 
2991256
4ef1c2f
6b00697
 
fd42a59
 
4ef1c2f
2991256
6b00697
 
e38233f
 
e792964
e38233f
9a844a3
0ef7b61
5e92e89
 
90073ea
4150671
4ef1c2f
2e719ba
5e92e89
 
 
 
e38233f
2e719ba
e38233f
 
 
 
 
4150671
f7281b8
2991256
6b00697
f7281b8
 
fd42a59
f7281b8
fd42a59
f7281b8
6b00697
 
 
fd42a59
 
 
 
 
96eedae
 
 
 
 
 
 
 
 
 
fd42a59
2157e93
 
4ef1c2f
 
97e80a4
 
2157e93
 
fd42a59
2157e93
fd42a59
6e59528
fd42a59
 
 
96eedae
 
 
 
 
fd42a59
96eedae
 
2157e93
fd42a59
96eedae
4ef1c2f
 
 
 
 
fd42a59
 
 
 
 
 
 
 
 
 
 
2157e93
4ef1c2f
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""Patch backend: add new model IDs to AVAILABLE_MODELS + fix OpenRouter routing.

OpenRouter models:
- openai/openrouter/owl-alpha β€” FREE by default, no :free suffix
- openai/google/gemini-2.0-flash-001 β€” PAID, no :free
- openai/*/...:free β€” free tier models, need :free suffix
"""
import ast
import os

AGENT_FILE = "/app/backend/routes/agent.py"
LLM_PARAMS_FILE = "/app/agent/core/llm_params.py"

# ── Step 1: Patch AVAILABLE_MODELS in agent.py ──
with open(AGENT_FILE) as f:
    content = f.read()

target = "AVAILABLE_MODELS = _available_models()\n"
patch = '''
# === PATCH: Add HF Inference + OpenRouter models ===
AVAILABLE_MODELS.extend([
    {"id": "deepseek-ai/DeepSeek-V4-Pro", "label": "DeepSeek V4 Pro", "provider": "huggingface", "tier": "free", "recommended": True},
    {"id": "deepseek-ai/DeepSeek-V4-Flash", "label": "DeepSeek V4 Flash", "provider": "huggingface", "tier": "free"},
    {"id": "openai/deepseek/deepseek-v4-flash:free", "label": "DeepSeek V4 Flash (OR)", "provider": "openrouter", "tier": "free"},
    {"id": "openai/nvidia/nemotron-3-super-120b-a12b:free", "label": "Nemotron 3 Super 120B", "provider": "openrouter", "tier": "free"},
    {"id": "google/gemma-3-1b-it", "label": "Gemma 3 1B", "provider": "huggingface", "tier": "free", "recommended": True},
    {"id": "Qwen/Qwen3-Coder-Next", "label": "Qwen3 Coder Next", "provider": "huggingface", "tier": "free", "recommended": True},
    {"id": "openai/openrouter/owl-alpha", "label": "Owl Alpha", "provider": "openrouter", "tier": "free", "recommended": True},
    {"id": "openai/google/gemini-2.0-flash-001", "label": "Gemini 2.0 Flash", "provider": "openrouter", "tier": "free"},
    {"id": "openai/google/gemma-4-31b-it:free", "label": "Gemma 4 31B", "provider": "openrouter", "tier": "free", "recommended": True},
    {"id": "openai/nvidia/nemotron-3-ultra-550b-a55b:free", "label": "Nemotron 3 Ultra 550B", "provider": "openrouter", "tier": "free", "recommended": True},
    {"id": "openai/poolside/laguna-m.1:free", "label": "Laguna M.1", "provider": "openrouter", "tier": "free", "recommended": True},
    {"id": "openai/poolside/laguna-xs.2:free", "label": "Laguna XS.2", "provider": "openrouter", "tier": "free"},
])
DEFAULT_FREE_MODEL_ID = "deepseek-ai/DeepSeek-V4-Pro"
# === END PATCH ===
'''

if target in content:
    content = content.replace(target, target + patch)
    print("βœ… Added models to AVAILABLE_MODELS")
else:
    print("⚠ Could not find target line")

try:
    ast.parse(content)
    print("βœ… agent.py syntax OK")
except SyntaxError as e:
    print(f"❌ Syntax error in agent.py: {e}")
    raise

with open(AGENT_FILE, "w") as f:
    f.write(content)

# ── Step 2: Patch _resolve_llm_params to route OpenRouter models ──
with open(LLM_PARAMS_FILE) as f:
    llm_content = f.read()

old_block = """    hf_model = normalized_model
    api_key = _resolve_hf_router_token(session_hf_token)
    params = {
        "model": f"openai/{hf_model}",
        "api_base": HF_ROUTER_BASE_URL,
        "api_key": api_key,
    }"""

new_block = """    hf_model = normalized_model
    api_key = _resolve_hf_router_token(session_hf_token)

    # === PATCH: Route OpenRouter models to openrouter.ai ===
    # OpenRouter expects the model name WITHOUT the openai/ prefix.
    # E.g. "openai/openrouter/owl-alpha" -> send "openrouter/owl-alpha"
    # No :free suffix for Owl Alpha (free by default).
    _or_prefixes = ("openai/google/", "openai/deepseek/", "openai/nvidia/", "openai/poolside/", "openai/openrouter/")
    if normalized_model.startswith(_or_prefixes):
        # Strip the "openai/" prefix so OpenRouter gets the correct model ID
        or_model = normalized_model[len("openai/"):]
        return {
            "model": or_model,
            "api_base": "https://openrouter.ai/api/v1",
            "api_key": os.environ.get("OPENROUTER_API_KEY") or api_key or "",
        }
    # === END PATCH ===

    params = {
        "model": f"openai/{hf_model}",
        "api_base": HF_ROUTER_BASE_URL,
        "api_key": api_key,
    }"""

if old_block in llm_content:
    llm_content = llm_content.replace(old_block, new_block)
    print("βœ… Patched _resolve_llm_params: OpenRouter routing with stripped prefix")
else:
    print("⚠ Could not find target block in llm_params.py")
    # Debug: find the actual block
    idx = llm_content.find("hf_model = normalized_model")
    if idx >= 0:
        print(f"Found 'hf_model = normalized_model' at pos {idx}")
        print(repr(llm_content[idx:idx+300]))

try:
    ast.parse(llm_content)
    print("βœ… llm_params.py syntax OK")
except SyntaxError as e:
    print(f"❌ Syntax error in llm_params.py: {e}")
    raise

with open(LLM_PARAMS_FILE, "w") as f:
    f.write(llm_content)

print("βœ… Backend patched")
print("  - Owl Alpha: sends 'openrouter/owl-alpha' to openrouter.ai (NO :free)")
print("  - Gemini 2.0 Flash: sends 'google/gemini-2.0-flash-001' to openrouter.ai (NO :free)")
print("  - Other OR free models: include :free suffix")