"""GEO AgentKit Server 启动入口 工厂函数 create_geo_app() 初始化 LLM Gateway、Tool Registry、Skill Registry, 然后创建 FastAPI 应用。 使用方式: uvicorn configs.geo_server:create_geo_app --factory --host 0.0.0.0 --port 8001 """ import logging import os from agentkit.core.agent_pool import AgentPool from agentkit.llm.config import LLMConfig from agentkit.llm.gateway import LLMGateway from agentkit.llm.providers.openai import OpenAICompatibleProvider from agentkit.quality.gate import QualityGate from agentkit.quality.output import OutputStandardizer from agentkit.router.intent import IntentRouter from agentkit.server.app import create_app from agentkit.skills.loader import SkillLoader from agentkit.skills.registry import SkillRegistry from agentkit.tools.registry import ToolRegistry logger = logging.getLogger(__name__) # ─── 配置路径 ─── CONFIGS_DIR = os.path.dirname(os.path.abspath(__file__)) LLM_CONFIG_PATH = os.path.join(CONFIGS_DIR, "llm_config.yaml") SKILLS_DIR = os.path.join(CONFIGS_DIR, "skills") def _substitute_env_vars(config_path: str) -> dict: """加载 YAML 配置并替换 ${VAR} 环境变量""" import yaml with open(config_path, encoding="utf-8") as f: raw = f.read() # 递归替换 ${VAR_NAME} 和 ${VAR_NAME:-default} 格式 import re def _replace_env(match): var_expr = match.group(1) if ":-" in var_expr: var_name, default = var_expr.split(":-", 1) return os.getenv(var_name, default) return os.getenv(var_expr, match.group(0)) resolved = re.sub(r"\$\{([^}]+)\}", _replace_env, raw) return yaml.safe_load(resolved) def _init_llm_gateway() -> LLMGateway: """初始化 LLM Gateway 并注册 Provider""" config_data = _substitute_env_vars(LLM_CONFIG_PATH) config = LLMConfig.from_dict(config_data) gateway = LLMGateway(config) for provider_name, pconf in config.providers.items(): if not pconf.api_key: logger.warning(f"Skipping provider '{provider_name}': no API key") continue models = list(pconf.models.keys()) if pconf.models else [] default_model = models[0] if models else "gpt-4o-mini" provider = OpenAICompatibleProvider( api_key=pconf.api_key, base_url=pconf.base_url, default_model=default_model, ) gateway.register_provider(provider_name, provider) logger.info(f"Provider '{provider_name}' registered with model '{default_model}'") return gateway def _init_tool_registry() -> ToolRegistry: """初始化 Tool Registry 并注册 GEO Tools""" registry = ToolRegistry() from configs.geo_tools import register_geo_tools register_geo_tools(registry) return registry def _init_skill_registry(tool_registry: ToolRegistry) -> SkillRegistry: """初始化 Skill Registry 并从 configs/skills/ 目录加载""" registry = SkillRegistry() loader = SkillLoader(registry, tool_registry) skills = loader.load_from_directory(SKILLS_DIR) logger.info(f"Loaded {len(skills)} skills from {SKILLS_DIR}") return registry def create_geo_app() -> "FastAPI": """GEO AgentKit Server FastAPI 工厂函数""" llm_gateway = _init_llm_gateway() tool_registry = _init_tool_registry() skill_registry = _init_skill_registry(tool_registry) app = create_app( llm_gateway=llm_gateway, skill_registry=skill_registry, tool_registry=tool_registry, ) app.title = "GEO AgentKit Server" logger.info(f"GEO AgentKit Server initialized: {len(skill_registry.list_skills())} skills, " f"{len(tool_registry.list_tools())} tools") return app