Spaces:
Sleeping
Sleeping
| import os | |
| from functools import lru_cache | |
| from typing import Any | |
| import requests | |
| from crewai import LLM | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1" | |
| OPENCODE_GO_OPENAI_BASE_URL = "https://opencode.ai/zen/go/v1" | |
| OPENCODE_GO_ANTHROPIC_BASE_URL = "https://opencode.ai/zen/go" | |
| OPENCODE_GO_MODELS_URL = "https://opencode.ai/zen/go/v1/models" | |
| DEFAULT_OPENROUTER_MODEL = "moonshotai/kimi-k2:free" | |
| DEFAULT_OPENCODE_GO_MODEL = "deepseek-v4-flash" | |
| def _env_bool(name: str, default: bool = False) -> bool: | |
| value = os.getenv(name) | |
| if value is None: | |
| return default | |
| return value.strip().lower() in {"1", "true", "yes", "y", "on"} | |
| def _env_required(name: str) -> str: | |
| value = os.getenv(name) | |
| if not value: | |
| raise RuntimeError(f"Missing required environment variable: {name}") | |
| return value | |
| def _opencode_model_id(model: str) -> str: | |
| return model.removeprefix("opencode-go/").strip() | |
| def _openrouter_model_id(model: str) -> str: | |
| model = model.strip() | |
| if model.startswith("openrouter/"): | |
| return model | |
| return f"openrouter/{model}" | |
| def _strings_from(value: Any) -> list[str]: | |
| if isinstance(value, str): | |
| return [value.lower()] | |
| if isinstance(value, dict): | |
| strings: list[str] = [] | |
| for item in value.values(): | |
| strings.extend(_strings_from(item)) | |
| return strings | |
| if isinstance(value, list): | |
| strings = [] | |
| for item in value: | |
| strings.extend(_strings_from(item)) | |
| return strings | |
| return [] | |
| def _opencode_go_api_style(model: str, api_key: str) -> str: | |
| configured = os.getenv("OPENCODE_GO_API_STYLE", "auto").strip().lower() | |
| if configured in {"openai", "anthropic"}: | |
| return configured | |
| if configured != "auto": | |
| raise RuntimeError("OPENCODE_GO_API_STYLE must be auto, openai, or anthropic") | |
| model_id = _opencode_model_id(model) | |
| try: | |
| response = requests.get( | |
| OPENCODE_GO_MODELS_URL, | |
| headers={"Authorization": f"Bearer {api_key}"}, | |
| timeout=5, | |
| ) | |
| response.raise_for_status() | |
| payload = response.json() | |
| models = payload.get("data", payload) if isinstance(payload, dict) else payload | |
| if isinstance(models, list): | |
| for item in models: | |
| if not isinstance(item, dict): | |
| continue | |
| ids = { | |
| str(item.get("id", "")), | |
| str(item.get("model", "")), | |
| str(item.get("name", "")), | |
| } | |
| if model_id not in ids and f"opencode-go/{model_id}" not in ids: | |
| continue | |
| details = " ".join(_strings_from(item)) | |
| if "messages" in details or "anthropic" in details: | |
| return "anthropic" | |
| if ( | |
| "chat/completions" in details | |
| or "openai" in details | |
| or "alibaba" in details | |
| ): | |
| return "openai" | |
| except requests.RequestException: | |
| pass | |
| if model_id.startswith("minimax-"): | |
| return "anthropic" | |
| return "openai" | |
| def create_llm() -> LLM: | |
| temperature = float(os.getenv("LLM_TEMPERATURE", "0.2")) | |
| timeout = int(os.getenv("LLM_TIMEOUT", "300")) | |
| if _env_bool("USE_OPENROUTER", default=False): | |
| return LLM( | |
| model=_openrouter_model_id( | |
| os.getenv("OPENROUTER_MODEL", DEFAULT_OPENROUTER_MODEL) | |
| ), | |
| api_base=OPENROUTER_BASE_URL, | |
| api_key=_env_required("OPENROUTER_API_KEY"), | |
| temperature=temperature, | |
| timeout=timeout, | |
| ) | |
| api_key = _env_required("OPENCODE_GO_API_KEY") | |
| model = _opencode_model_id(os.getenv("OPENCODE_GO_MODEL", DEFAULT_OPENCODE_GO_MODEL)) | |
| api_style = _opencode_go_api_style(model, api_key) | |
| if api_style == "anthropic": | |
| return LLM( | |
| model=f"anthropic/{model}", | |
| api_base=OPENCODE_GO_ANTHROPIC_BASE_URL, | |
| api_key=api_key, | |
| temperature=temperature, | |
| timeout=timeout, | |
| ) | |
| return LLM( | |
| model=f"openai/{model}", | |
| api_base=OPENCODE_GO_OPENAI_BASE_URL, | |
| api_key=api_key, | |
| temperature=temperature, | |
| timeout=timeout, | |
| ) | |