fischer-agentkit/configs/geo_server.py

112 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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