Spaces:
Running
Running
| """Patch backend llm_params.py: force OpenRouter as the LiteLLM provider. | |
| Root cause: the openai/-prefixed (and deepseek/) model routing returns only | |
| ``api_base`` + ``api_key``. LiteLLM resolves the provider from the model | |
| string's org prefix, so for models whose org is NOT a recognized LiteLLM | |
| provider (upstage/, nvidia/, liquid/, meta-llama/, google/, poolside/, | |
| inclusionai/, ...) it raises "LLM Provider NOT provided" even though | |
| ``api_base`` points at OpenRouter. Only orgs that happen to match a real | |
| LiteLLM provider (e.g. tencent/) worked by luck. | |
| Fix: add ``custom_llm_provider: "openrouter"`` to both OpenRouter routing | |
| branches so LiteLLM always uses the OpenRouter OpenAI-compatible client. | |
| This runs AFTER patch_models.py (which may already have inserted the routing | |
| blocks); it is idempotent. | |
| """ | |
| import ast | |
| import os | |
| FILE = "/app/agent/core/llm_params.py" | |
| with open(FILE) as f: | |
| c = f.read() | |
| before = c | |
| # --- 1. openai/ branch (unique via or_model line) --- | |
| openai_old = ( | |
| ' or_model = normalized_model[len("openai/"):]\n' | |
| ' return {\n' | |
| ' "model": or_model,\n' | |
| ' "api_base": "https://openrouter.ai/api/v1",\n' | |
| ' "api_key": os.environ.get("OPENROUTER_API_KEY") or api_key or "",\n' | |
| ' }\n' | |
| ) | |
| openai_new = ( | |
| ' or_model = normalized_model[len("openai/"):]\n' | |
| ' return {\n' | |
| ' "model": or_model,\n' | |
| ' "api_base": "https://openrouter.ai/api/v1",\n' | |
| ' "api_key": os.environ.get("OPENROUTER_API_KEY") or api_key or "",\n' | |
| ' "custom_llm_provider": "openrouter",\n' | |
| ' }\n' | |
| ) | |
| # --- 2. deepseek/ branch (unique via normalized_model on its own line) --- | |
| deepseek_old = ( | |
| ' if normalized_model.startswith("deepseek/"):\n' | |
| ' return {\n' | |
| ' "model": normalized_model,\n' | |
| ' "api_base": "https://openrouter.ai/api/v1",\n' | |
| ' "api_key": os.environ.get("OPENROUTER_API_KEY") or api_key or "",\n' | |
| ' }\n' | |
| ) | |
| deepseek_new = ( | |
| ' if normalized_model.startswith("deepseek/"):\n' | |
| ' return {\n' | |
| ' "model": normalized_model,\n' | |
| ' "api_base": "https://openrouter.ai/api/v1",\n' | |
| ' "api_key": os.environ.get("OPENROUTER_API_KEY") or api_key or "",\n' | |
| ' "custom_llm_provider": "openrouter",\n' | |
| ' }\n' | |
| ) | |
| if 'custom_llm_provider' in c: | |
| print("OK: llm_params.py already contains custom_llm_provider (idempotent)") | |
| else: | |
| n1 = c.count(openai_old) | |
| n2 = c.count(deepseek_old) | |
| if n1 == 1: | |
| c = c.replace(openai_old, openai_new) | |
| print("OK: openai/ branch -> custom_llm_provider='openrouter'") | |
| else: | |
| print(f"WARN: openai/ branch match count = {n1} (expected 1)") | |
| if n2 == 1: | |
| c = c.replace(deepseek_old, deepseek_new) | |
| print("OK: deepseek/ branch -> custom_llm_provider='openrouter'") | |
| else: | |
| print(f"WARN: deepseek/ branch match count = {n2} (expected 1)") | |
| if c != before: | |
| with open(FILE, "w") as f: | |
| f.write(c) | |
| try: | |
| ast.parse(c) | |
| print("OK: llm_params.py written & syntax valid") | |
| except SyntaxError as e: | |
| print(f"FAIL: llm_params.py syntax error: {e}") | |
| raise | |
| else: | |
| print("WARN: no changes applied") | |