feat: Agent 批量测试、作业助手与上传预览;Windows 启动脚本与文档- 新增 run_agent_test_cases 与示例 JSON、(红头)agent测试用例文档

- 扩展 test_agent_execution(--homework、UTF-8 控制台)
- 后端:uploads 预览、file_read、工作流与对话落盘等
- 前端:AgentChatPreview 与设计器相关调整
- 忽略 redis二进制、agent_workspaces、uploads、tessdata 等本机产物

Made-with: Cursor
This commit is contained in:
renjianbo
2026-04-13 20:17:18 +08:00
parent 0608161c82
commit df4fab1e6e
31 changed files with 3784 additions and 251 deletions

View File

@@ -13,6 +13,7 @@ from app.api.auth import get_current_user
from app.models.user import User
from app.core.exceptions import NotFoundError, ValidationError, ConflictError
from app.services.permission_service import check_agent_permission
from app.services.agent_workspace_chat_log import fetch_agent_preview_chat_turns
from app.services.workflow_validator import validate_workflow
import uuid
@@ -68,6 +69,18 @@ class AgentFromSceneTemplateCreate(BaseModel):
budget_config: Optional[Dict[str, Any]] = None
class PreviewChatTurnResponse(BaseModel):
"""设计器预览侧单轮对话(来自已完成执行)"""
execution_id: str
created_at: datetime
user_text: str
agent_text: str
class Config:
from_attributes = True
class AgentResponse(BaseModel):
"""Agent响应模型"""
id: str
@@ -208,6 +221,40 @@ async def create_agent(
return agent
@router.get(
"/{agent_id}/preview-chat-history",
response_model=List[PreviewChatTurnResponse],
)
async def get_agent_preview_chat_history(
agent_id: str,
preview_user_id: Optional[str] = Query(
None,
description="预览会话 user_id与创建执行时 input_data.user_id 一致),只返回本会话记录",
),
limit: int = Query(50, ge=1, le=200),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
"""
获取设计器预览区的对话历史(按已完成执行还原)。
与前端 localStorage 中的 preview user_id 对齐,避免多人混在同一 Agent 下串会话。
须注册在 GET /{agent_id} 之前,避免路径被误匹配。
"""
agent = db.query(Agent).filter(Agent.id == agent_id).first()
if not agent:
raise NotFoundError(f"Agent不存在: {agent_id}")
if not check_agent_permission(db, current_user, agent, "read"):
raise HTTPException(status_code=403, detail="无权访问此Agent")
rows = fetch_agent_preview_chat_turns(
db,
agent_id,
preview_user_id=preview_user_id,
limit=limit,
)
return rows
@router.get("/{agent_id}", response_model=AgentResponse)
async def get_agent(
agent_id: str,