"""从 Hermes 配置文件中读取各搜索源所需密钥""" import os import re import yaml HERMES_CONFIG = '/root/.hermes/config.yaml' HERMES_ENV = '/root/.hermes/.env' SEARCH_HUB_CONFIG = '/root/agentspace/projects/search-hub/config.yaml' def load_config(): """加载所有搜索源配置,返回 dict""" # 从 hermes config 读取 with open(HERMES_CONFIG, 'r') as f: config = yaml.safe_load(f) # 读取 .env env_vars = {} if os.path.exists(HERMES_ENV): with open(HERMES_ENV, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#'): if '=' in line: k, v = line.split('=', 1) env_vars[k.strip()] = v.strip() def resolve_api_key(raw_key): if not raw_key: return None m = re.match(r'\$\{(\w+)\}', str(raw_key)) if m: var_name = m.group(1) return env_vars.get(var_name) or os.environ.get(var_name) return raw_key # === Tavily === tavily_cfg = config.get('search', {}).get('tavily', {}) tavily_api_key = resolve_api_key(tavily_cfg.get('api_key')) tavily_base_url = tavily_cfg.get('base_url', 'https://api.tavily.com') tavily_max_results = tavily_cfg.get('default_max_results', 10) tavily_depth = tavily_cfg.get('default_search_depth', 'basic') # === OpenCodeZen === opencodezen_key = None opencodezen_base_url = 'https://opencode.ai/zen/go/v1' opencodezen_model = 'deepseek-v4-flash' for provider in config.get('custom_providers', []): if provider.get('name') == 'OpenCodeZen': opencodezen_key = resolve_api_key(provider.get('api_key')) opencodezen_base_url = provider.get('base_url', opencodezen_base_url) opencodezen_model = provider.get('model', opencodezen_model) break if not opencodezen_key: opencodezen_key = env_vars.get('OPENCODE_ZEN_API_KEY') # === Search Hub 自身配置(可选,可覆盖 Hermes 配置)=== hub_config = {} if os.path.exists(SEARCH_HUB_CONFIG): with open(SEARCH_HUB_CONFIG, 'r') as f: hub_config = yaml.safe_load(f) or {} # 应用本地配置覆盖 local_sources = hub_config.get('sources', {}) # Tavily 覆盖 if 'tavily' in local_sources: tavily_local = local_sources['tavily'] if tavily_local.get('api_key'): tavily_api_key = tavily_local['api_key'] if tavily_local.get('base_url'): tavily_base_url = tavily_local['base_url'] # OpenCodeZen/AI 覆盖 if 'ai' in local_sources: ai_local = local_sources['ai'] if ai_local.get('api_key'): opencodezen_key = ai_local['api_key'] if ai_local.get('base_url'): opencodezen_base_url = ai_local['base_url'] if ai_local.get('model'): opencodezen_model = ai_local['model'] # 百度配置(来自本地 config.yaml) baidu_api_key = '' baidu_intelligent_url = 'https://qianfan.baidubce.com/v2/ai_search/chat/completions' baidu_web_search_url = 'https://qianfan.baidubce.com/v2/ai_search/web_search' if 'baidu' in local_sources: baidu_local = local_sources['baidu'] if baidu_local.get('api_key'): baidu_api_key = baidu_local['api_key'] if baidu_local.get('intelligent_url'): baidu_intelligent_url = baidu_local['intelligent_url'] if baidu_local.get('web_search_url'): baidu_web_search_url = baidu_local['web_search_url'] # === SearXNG === searxng_base_url = 'http://localhost:8888' if 'searxng' in local_sources: searxng_local = local_sources['searxng'] if searxng_local.get('base_url'): searxng_base_url = searxng_local['base_url'] return { 'tavily': { 'api_key': tavily_api_key, 'base_url': tavily_base_url, 'max_results': tavily_max_results, 'depth': tavily_depth, }, 'opencodezen': { 'api_key': opencodezen_key, 'base_url': opencodezen_base_url, 'model': opencodezen_model, }, 'hub': hub_config, 'baidu': { 'api_key': baidu_api_key, 'intelligent_url': baidu_intelligent_url, 'web_search_url': baidu_web_search_url, }, 'searxng': { 'base_url': searxng_base_url, }, }