feat:1.历史记录重构UI重构2.置顶功能实现
This commit is contained in:
@@ -66,10 +66,10 @@ class MultiAgentTaskCRUD:
|
||||
def get_recent(
|
||||
db: Session, limit: int = 20, offset: int = 0
|
||||
) -> List[MultiAgentTask]:
|
||||
"""获取最近的任务记录"""
|
||||
"""获取最近的任务记录,置顶的排在最前面"""
|
||||
return (
|
||||
db.query(MultiAgentTask)
|
||||
.order_by(MultiAgentTask.created_at.desc())
|
||||
.order_by(MultiAgentTask.is_pinned.desc(), MultiAgentTask.created_at.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.all()
|
||||
@@ -184,6 +184,18 @@ class MultiAgentTaskCRUD:
|
||||
db.refresh(task)
|
||||
return task
|
||||
|
||||
@staticmethod
|
||||
def update_is_pinned(
|
||||
db: Session, task_id: str, is_pinned: bool
|
||||
) -> Optional[MultiAgentTask]:
|
||||
"""更新任务置顶状态"""
|
||||
task = db.query(MultiAgentTask).filter(MultiAgentTask.task_id == task_id).first()
|
||||
if task:
|
||||
task.is_pinned = is_pinned
|
||||
db.commit()
|
||||
db.refresh(task)
|
||||
return task
|
||||
|
||||
@staticmethod
|
||||
def append_rehearsal_log(
|
||||
db: Session, task_id: str, log_entry: dict
|
||||
|
||||
@@ -6,7 +6,7 @@ SQLAlchemy ORM 数据模型
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum as PyEnum
|
||||
from sqlalchemy import Column, String, Text, DateTime, Integer, Enum, Index, ForeignKey
|
||||
from sqlalchemy import Column, String, Text, DateTime, Integer, Enum, Index, ForeignKey, Boolean
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
@@ -48,6 +48,7 @@ class MultiAgentTask(Base):
|
||||
execution_id = Column(String(64))
|
||||
rehearsal_log = Column(JSONB)
|
||||
branches = Column(JSONB) # 任务大纲探索分支数据
|
||||
is_pinned = Column(Boolean, default=False, nullable=False) # 置顶标志
|
||||
created_at = Column(DateTime(timezone=True), default=utc_now)
|
||||
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
|
||||
|
||||
@@ -74,6 +75,7 @@ class MultiAgentTask(Base):
|
||||
"execution_id": self.execution_id,
|
||||
"rehearsal_log": self.rehearsal_log,
|
||||
"branches": self.branches,
|
||||
"is_pinned": self.is_pinned,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
@@ -331,10 +331,11 @@ def handle_execute_plan_optimized_ws(data):
|
||||
MultiAgentTaskCRUD.update_status(db, task_id, TaskStatus.STOPPED)
|
||||
print(f"[execute_plan_optimized] 用户停止执行,跳过保存执行数据,已完成 {completed_steps_count}/{plan_steps_count} 步骤,task_id={task_id}")
|
||||
|
||||
# 任务大纲(用户可能编辑了)仍然保存
|
||||
if plan:
|
||||
MultiAgentTaskCRUD.update_task_outline(db, task_id, plan)
|
||||
print(f"[execute_plan_optimized] 已保存 task_outline 到数据库,task_id={task_id}")
|
||||
# # 任务大纲(用户可能编辑了)仍然保存
|
||||
# # 注释原因:执行任务时不保存 task_outline,避免覆盖导致步骤 ID 变化与 agent_scores 不匹配
|
||||
# if plan:
|
||||
# MultiAgentTaskCRUD.update_task_outline(db, task_id, plan)
|
||||
# print(f"[execute_plan_optimized] 已保存 task_outline 到数据库,task_id={task_id}")
|
||||
|
||||
# # 保存 assigned_agents(每个步骤使用的 agent)
|
||||
# # 注释原因:assigned_agents 只在生成阶段由用户手动选择写入,执行时不覆盖
|
||||
@@ -1849,6 +1850,7 @@ def handle_get_plans(data):
|
||||
"status": task.status.value if task.status else 'unknown',
|
||||
"execution_count": task.execution_count or 0,
|
||||
"created_at": task.created_at.isoformat() if task.created_at else None,
|
||||
"is_pinned": task.is_pinned or False, # 置顶标志
|
||||
# 完整数据用于恢复
|
||||
"task_outline": task.task_outline,
|
||||
"assigned_agents": task.assigned_agents,
|
||||
@@ -2060,6 +2062,54 @@ def handle_delete_plan(data):
|
||||
})
|
||||
|
||||
|
||||
@socketio.on('pin_plan')
|
||||
def handle_pin_plan(data):
|
||||
"""
|
||||
WebSocket版本:置顶/取消置顶历史任务
|
||||
"""
|
||||
# socketio 包装: data = { id: 'pin_plan-xxx', action: 'pin_plan', data: { id: 'ws_req_xxx', data: {...} } }
|
||||
request_id = data.get('id') # socketio 包装的 id
|
||||
incoming_data = data.get('data', {}).get('data', {}) # 真正的请求数据
|
||||
plan_id = incoming_data.get('plan_id')
|
||||
is_pinned = incoming_data.get('is_pinned', True) # 默认为置顶
|
||||
|
||||
if not plan_id:
|
||||
emit('response', {
|
||||
'id': request_id,
|
||||
'status': 'error',
|
||||
'error': '缺少 plan_id(task_id)'
|
||||
})
|
||||
return
|
||||
|
||||
try:
|
||||
with get_db_context() as db:
|
||||
task = MultiAgentTaskCRUD.update_is_pinned(db, plan_id, is_pinned)
|
||||
|
||||
if not task:
|
||||
emit('response', {
|
||||
'id': request_id,
|
||||
'status': 'error',
|
||||
'error': f'任务不存在: {plan_id}'
|
||||
})
|
||||
return
|
||||
|
||||
# 通知所有客户端刷新历史列表
|
||||
socketio.emit('history_updated', {'task_id': plan_id})
|
||||
|
||||
emit('response', {
|
||||
'id': request_id,
|
||||
'status': 'success',
|
||||
'data': {"message": "置顶成功" if is_pinned else "取消置顶成功"}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
emit('response', {
|
||||
'id': request_id,
|
||||
'status': 'error',
|
||||
'error': str(e)
|
||||
})
|
||||
|
||||
|
||||
@socketio.on('save_branches')
|
||||
def handle_save_branches(data):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user