Files
X-Agents/core/agents/main.py
DESKTOP-72TV0V4\caoxiaozhu 249e7e577a feat: 新增 core/agents 模块和 nanobot
- 新增 agents 模块,包含 agent、api、skills 等子模块
- 新增 nanobot 项目,支持多渠道集成
- 添加启动脚本 start-all.bat 和 start-all.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 21:29:12 +08:00

166 lines
4.5 KiB
Python

"""Main entry point for X-Agents agent service."""
import logging
import asyncio
import sys
from pathlib import Path
# Add project root to path (parent of core directory)
project_root = Path(__file__).parent.parent.parent
core_dir = project_root / "core"
sys.path.insert(0, str(project_root)) # for X-Agents root
sys.path.insert(0, str(core_dir)) # for core
sys.path.insert(0, str(core_dir / "nanobot")) # for nanobot
from fastapi import FastAPI
import uvicorn
from agents.config import Config
from agents.api.routes import router, set_agent, set_team_agent, add_cors
from agents.agent.loop import AgentLoop
from agents.agent.team_agent import TeamAgent
from agents.llm import ProviderFactory
from agents.tools import create_default_registry
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
class SimpleProvider:
"""Simple LLM provider placeholder for testing without API keys."""
def __init__(self, api_key: str = "", base_url: str | None = None):
self.api_key = api_key
self.base_url = base_url
async def chat(self, messages: list[dict], model: str, **kwargs) -> dict:
"""Simulate LLM chat response.
Args:
messages: Message list
model: Model name
Returns:
Simulated response
"""
from agents.llm import LLMResponse
user_msg = ""
for msg in reversed(messages):
if msg.get("role") == "user":
user_msg = msg.get("content", "")
break
return LLMResponse(
content=f"I received your message: {user_msg[:50]}... (LLM integration pending)",
tool_calls=[],
finish_reason="stop",
)
async def chat_with_retry(self, *args, **kwargs):
return await self.chat(*args, **kwargs)
def get_default_model(self) -> str:
return "simple"
def create_app(config: Config | None = None) -> FastAPI:
"""Create and configure the FastAPI application.
Args:
config: Configuration instance
Returns:
Configured FastAPI app
"""
config = config or Config()
app = FastAPI(
title="X-Agents API",
description="Agent API for X-Agents platform",
version="0.1.0",
)
# Include routers with /api/v1 prefix (aligned with Go backend paths: /api/agent/chat, /api/agent/chat/stream)
app.include_router(router, prefix="/api/v1")
# Add CORS middleware to allow Go backend cross-origin requests
add_cors(app)
# Initialize LLM provider
if config.LLM_API_KEY:
try:
provider = ProviderFactory.create(
provider=config.LLM_PROVIDER,
api_key=config.LLM_API_KEY,
api_base=config.LLM_BASE_URL,
)
logger.info(f"Using {config.LLM_PROVIDER} provider with model {config.LLM_MODEL}")
except ImportError as e:
logger.warning(f"Failed to import provider package: {e}, using placeholder")
provider = SimpleProvider(api_key=config.LLM_API_KEY)
else:
logger.warning("No LLM_API_KEY provided, using placeholder provider")
provider = SimpleProvider()
# Create tool registry
tools = create_default_registry()
# Initialize agent
agent = AgentLoop(
provider=provider,
model=config.LLM_MODEL,
workspace=config.WORKSPACE,
max_iterations=config.MAX_ITERATIONS,
tools=tools,
)
set_agent(agent)
# Initialize team agent for multi-agent collaboration
team_agent = TeamAgent(
provider=provider,
model=config.LLM_MODEL,
workspace=config.WORKSPACE,
)
set_team_agent(team_agent)
@app.on_event("startup")
async def startup_event():
logger.info("X-Agents starting up...")
logger.info(f"Model: {config.LLM_MODEL}")
logger.info(f"Provider: {config.LLM_PROVIDER}")
logger.info(f"Workspace: {config.WORKSPACE}")
logger.info(f"Tools: {tools.tool_names}")
@app.on_event("shutdown")
async def shutdown_event():
logger.info("X-Agents shutting down...")
return app
def main():
"""Run the agent service."""
config = Config()
# Ensure workspace exists
config.WORKSPACE.mkdir(exist_ok=True)
app = create_app(config)
uvicorn.run(
app,
host=config.API_HOST,
port=config.API_PORT,
log_level="info",
)
if __name__ == "__main__":
main()