feat: 增强 core/agents 工具和 API
- 新增 loop.py Agent 运行循环 - 优化 memory.py 记忆模块 - 扩展 api/routes.py 接口 - 更新 tools 模块:builtin.py, manager.py, __init__.py - 新增 .env.example 配置示例 - 更新 requirements.txt 依赖 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ class ChatRequest(BaseModel):
|
||||
|
||||
Fields aligned with server/internal/service/agent_service.go::AgentChatRequest
|
||||
"""
|
||||
agent_id: int
|
||||
agent_id: str # 支持 UUID 字符串
|
||||
message: str
|
||||
user_id: int = 0
|
||||
session_id: str | None = None
|
||||
@@ -37,7 +37,7 @@ class ChatResponse(BaseModel):
|
||||
|
||||
Fields aligned with server/internal/service/agent_service.go::AgentChatResponse
|
||||
"""
|
||||
agent_id: int
|
||||
agent_id: str # 支持 UUID 字符串
|
||||
response: str
|
||||
tool_calls: list = []
|
||||
tokens_used: int = 0
|
||||
@@ -209,7 +209,10 @@ async def chat_stream(request: ChatRequest):
|
||||
Yields:
|
||||
Streaming response chunks in SSE format
|
||||
"""
|
||||
logger.info(f"[chat_stream] Received request: agent_id={request.agent_id}, message={request.message[:50]}...")
|
||||
|
||||
if _agent is None:
|
||||
logger.error("[chat_stream] Agent not initialized!")
|
||||
raise HTTPException(status_code=500, detail="Agent not initialized")
|
||||
|
||||
session_id = request.session_id or f"session_{request.agent_id}_{int(time.time())}"
|
||||
@@ -217,6 +220,8 @@ async def chat_stream(request: ChatRequest):
|
||||
async def generate() -> AsyncGenerator[str, None]:
|
||||
"""Generate streaming response."""
|
||||
try:
|
||||
logger.info(f"[chat_stream] Starting stream for session: {session_id}")
|
||||
|
||||
# Prepare kwargs for agent.chat()
|
||||
kwargs = {
|
||||
"message": request.message,
|
||||
@@ -225,28 +230,38 @@ async def chat_stream(request: ChatRequest):
|
||||
|
||||
if request.model_id:
|
||||
kwargs["model_id"] = request.model_id
|
||||
logger.info(f"[chat_stream] Using model_id: {request.model_id}")
|
||||
if request.model_name:
|
||||
kwargs["model_name"] = request.model_name
|
||||
logger.info(f"[chat_stream] Using model_name: {request.model_name}")
|
||||
if request.model_provider:
|
||||
kwargs["model_provider"] = request.model_provider
|
||||
logger.info(f"[chat_stream] Using model_provider: {request.model_provider}")
|
||||
if request.api_key:
|
||||
kwargs["api_key"] = request.api_key
|
||||
logger.info(f"[chat_stream] Using api_key: {request.api_key[:10]}...")
|
||||
if request.base_url:
|
||||
kwargs["base_url"] = request.base_url
|
||||
logger.info(f"[chat_stream] Using base_url: {request.base_url}")
|
||||
if request.use_xbot:
|
||||
kwargs["use_xbot"] = request.use_xbot
|
||||
logger.info(f"[chat_stream] Using use_xbot: {request.use_xbot}")
|
||||
|
||||
# Process with streaming
|
||||
chunk_count = 0
|
||||
async for chunk in _agent.chat_stream(**kwargs):
|
||||
# SSE format: "data: <json>\n\n"
|
||||
yield f"data: {json.dumps(chunk)}\n\n"
|
||||
chunk_count += 1
|
||||
logger.info(f"[chat_stream] Yielding chunk {chunk_count}: {chunk}")
|
||||
# SSE format: "data: <json>\n\n" - ensure_ascii=False to output UTF-8 characters directly
|
||||
yield f"data: {json.dumps(chunk, ensure_ascii=False)}\n\n"
|
||||
|
||||
logger.info(f"[chat_stream] Stream complete, yielded {chunk_count} chunks")
|
||||
# Send final message
|
||||
yield f"data: {json.dumps({'done': True, 'session_id': session_id})}\n\n"
|
||||
yield f"data: {json.dumps({'done': True, 'session_id': session_id}, ensure_ascii=False)}\n\n"
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Error in streaming chat: {e}")
|
||||
yield f"data: {json.dumps({'error': str(e)})}\n\n"
|
||||
yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n"
|
||||
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
||||
|
||||
Reference in New Issue
Block a user