Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/boxiaolanya2008_ds-cache-server.json
T
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
6.5 KiB
JSON

{"repo": "boxiaolanya2008/ds-cache-server", "files": {"src/config.py": {"d2f3a3375a98e3ae9139711027787e397ef42e6b": {"t": 1786068481.9153407, "n": 5866, "h": "db53f703c2009f43", "c": "\"\"\"配置管理: 合并 YAML 文件配置与 .env 环境变量\"\"\"\nfrom __future__ import annotations\n\nimport os\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional\n\nimport yaml\nfrom dotenv import load_dotenv\nfrom pydantic import BaseModel, Field\n\n\nclass ServerConfig(BaseModel):\n host: str = \"0.0.0.0\"\n port: int = 8000\n title: str = \"DeepSeek Proxy\"\n description: str = \"\"\n\n\nclass DeepSeekConfig(BaseModel):\n base_url: str = \"https://api.deepseek.com\"\n api_keys: List[str] = Field(default_factory=list)\n model_aliases: Dict[str, str] = Field(default_factory=dict)\n\n\nclass CacheConfig(BaseModel):\n enabled: bool = True\n db_path: str = \"./data/cache.db\"\n ttl_hours: int = 24\n max_entries: int = 10000\n cache_stream: bool = False\n\n\nclass RoutingContentRule(BaseModel):\n \"\"\"基于内容关键词的模型路由规则\"\"\"\n keywords: List[str] = Field(default_factory=list)\n model: str = \"\"\n\n\nclass RoutingConfig(BaseModel):\n default_model: str = \"deepseek-v4-flash\"\n force_model: str = \"\"\n content_rules: Dict[str, str] = Field(default_factory=dict)\n\n\nclass KeyPoolConfig(BaseModel):\n strategy: str = \"round_robin\"\n backoff_seconds: int = 60\n health_check_interval: int = 300\n\n\nclass ModelPricing(BaseModel):\n input_per_million: float = 0.14\n cache_hit_input_per_million: float = 0.0028\n output_per_million: float = 0.28\n\n\nclass PricingConfig(BaseModel):\n model_pricing: Dict[str, ModelPricing] = Field(default_factory=dict)\n\n\nclass StatsConfig(BaseModel):\n db_path: str = \"./data/stats.db\"\n\n\nclass AppConfig(BaseModel):\n server: ServerConfig = Field(default_factory=ServerConfig)\n deepseek: DeepSeekConfig = Field(default_factory=DeepSeekConfig)\n cache: CacheConfig = Field(default_factory=CacheConfig)\n routing: RoutingConfig = Field(default_factory=RoutingConfig)\n key_pool: KeyPoolConfig = Field(default_factory=KeyPoolConfig)\n pricing: PricingConfig = Field(default_factory=PricingConfig)\n stats: StatsConfig = Field(default_factory=StatsConfig)\n\n\ndef _flatten_yaml(data: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"将嵌套 YAML 结构展平以便于 .env 覆盖\"\"\"\n result = {}\n\n def walk(obj: Any, prefix: str = \"\"):\n if isinstance(obj, dict):\n for k, v in obj.items():\n new_key = f\"{prefix}_{k}\" if prefix else k\n if isinstance(v, dict):\n walk(v, new_key)\n else:\n result[new_key] = v\n elif isinstance(obj, list):\n result[prefix] = \",\".join(str(x) for x in obj)\n\n walk(data)\n return result\n\n\ndef _build_pricing(raw: Dict[str, Any]) -> Dict[str, ModelPricing]:\n \"\"\"从原始配置字典构建 model_pricing 映射\"\"\"\n pricing = {}\n for model_name, vals in raw.get(\"model_pricing\", {}).items():\n if isinstance(vals, dict):\n pricing[model_name] = ModelPricing(**vals)\n return pricing\n\n\ndef load_config(config_path: str = \"config.yaml\") -> AppConfig:\n \"\"\"加载 YAML 配置, 并用 .env 变量覆盖\"\"\"\n load_dotenv()\n\n # 解析 YAML\n yaml_path = Path(config_path)\n if yaml_path.exists():\n with open(yaml_path, \"r\", encoding=\"utf-8\") as f:\n raw = yaml.safe_load(f) or {}\n else:\n raw = {}\n\n # 收集所有 YAML 字段到扁平字典\n flat = _flatten_yaml(raw)\n\n # 构建最终数据\n deepseek_keys: List[str] = []\n if \"DEEPSEEK_API_KEYS\" in os.environ:\n deepseek_keys = [k.strip() for k in os.environ[\"DEEPSEEK_API_KEYS\"].split(\",\") if k.strip()]\n elif flat.get(\"deepseek_api_keys\"):\n keys_str = flat[\"deepseek_api_keys\"]\n deepseek_keys = [k.strip() for k in keys_str.split(\",\") if k.strip()]\n\n deepseek_base_url = os.environ.get(\"DEEPSEEK_BASE_URL\") or flat.get(\"deepseek_base_url\", \"https://api.deepseek.com\")\n\n # 构建配置\n data = {\n \"server\": {\n \"host\": os.environ.get(\"SERVER_HOST\", flat.get(\"server_host\", \"0.0.0.0\")),\n \"port\": int(os.environ.get(\"SERVER_PORT\", flat.get(\"server_port\", 8000))),\n \"title\": flat.get(\"server_title\", \"DeepSeek Proxy\"),\n \"description\": flat.get(\"server_description\", \"\"),\n },\n \"deepseek\": {\n \"base_url\": deepseek_base_url,\n \"api_keys\": deepseek_keys,\n \"model_aliases\": flat.get(\"deepseek_model_aliases\", {}),\n },\n \"cache\": {\n \"enabled\": flat.get(\"cache_enabled\", True),\n \"db_path\": os.environ.get(\"CACHE_DB_PATH\", flat.get(\"cache_db_path\", \"./data/cache.db\")),\n \"ttl_hours\": int(os.environ.get(\"CACHE_TTL_HOURS\", flat.get(\"cache_ttl_hours\", 24))),\n \"max_entries\": int(os.environ.get(\"CACHE_MAX_ENTRIES\", flat.get(\"cache_max_entries\", 10000))),\n \"cache_stream\": flat.get(\"cache_cache_stream\", False),\n },\n \"routing\": {\n \"default_model\": flat.get(\"routing_default_model\", \"deepseek-v4-flash\"),\n \"force_model\": flat.get(\"routing_force_model\", \"\"),\n \"content_rules\": flat.get(\"routing_content_rules\") or {},\n },\n \"key_pool\": {\n \"strategy\": flat.get(\"key_pool_strategy\", \"round_robin\"),\n \"backoff_seconds\": int(flat.get(\"key_pool_backoff_seconds\", 60)),\n \"health_check_interval\": int(flat.get(\"key_pool_health_check_interval\", 300)),\n },\n \"stats\": {\n \"db_path\": os.environ.get(\"STATS_DB_PATH\", flat.get(\"stats_db_path\", \"./data/stats.db\")),\n },\n }\n\n # pricing 需要特殊处理\n pricing_raw = raw.get(\"pricing\", {})\n data[\"pricing\"] = {\n \"model_pricing\": _build_pricing(pricing_raw),\n }\n\n return AppConfig(**data)\n\n\n# 全局单例\n_config: Optional[AppConfig] = None\n\n\ndef get_config() -> AppConfig:\n global _config\n if _config is None:\n _config = load_config()\n return _config\n\n\ndef reload_config(config_path: str = \"config.yaml\") -> AppConfig:\n global _config\n _config = load_config(config_path)\n return _config"}}}}