Update agent orchestration and knowledge flow
Add sub-commander orchestration updates, align frontend integrations, and refine knowledge view behavior without including local data artifacts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,13 +9,17 @@ from app.schemas.agent import AgentCreate, AgentOut, AgentStats, AgentConfigUpda
|
||||
|
||||
router = APIRouter(prefix="/api/agents", tags=["Agent"])
|
||||
|
||||
# 运行时调用统计(内存中,非持久化)
|
||||
_agent_call_counts: dict[str, int] = {}
|
||||
_agent_current_tasks: dict[str, str | None] = {}
|
||||
_agent_statuses: dict[str, str] = {}
|
||||
|
||||
# 默认 Agent 角色列表
|
||||
DEFAULT_AGENT_ROLES = ["master", "planner", "executor", "librarian", "analyst"]
|
||||
SUB_COMMANDERS_BY_ROLE = {
|
||||
"planner": ["planner_scope", "planner_steps"],
|
||||
"executor": ["executor_tasks", "executor_forum"],
|
||||
"librarian": ["librarian_retrieval", "librarian_graph"],
|
||||
"analyst": ["analyst_progress", "analyst_insights"],
|
||||
}
|
||||
|
||||
|
||||
def record_agent_call(agent_id: str):
|
||||
@@ -31,6 +35,15 @@ def set_agent_status(agent_id: str, status: str):
|
||||
_agent_statuses[agent_id] = status
|
||||
|
||||
|
||||
def _build_agent_stats(agent_id: str) -> AgentStats:
|
||||
return AgentStats(
|
||||
agent_id=agent_id,
|
||||
call_count=_agent_call_counts.get(agent_id, 0),
|
||||
current_task=_agent_current_tasks.get(agent_id),
|
||||
status=_agent_statuses.get(agent_id, "idle"),
|
||||
)
|
||||
|
||||
|
||||
@router.get("", response_model=list[AgentOut])
|
||||
async def list_agents(
|
||||
current_user: User = Depends(get_current_user),
|
||||
@@ -42,32 +55,35 @@ async def list_agents(
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
# ———— 运行时统计(必须在 /{agent_id} 之前)————
|
||||
@router.get("/stats", response_model=list[AgentStats])
|
||||
async def get_agent_stats(
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""
|
||||
获取各 Agent 的运行时统计(调用次数、当前任务、状态)
|
||||
"""
|
||||
stats = []
|
||||
return [_build_agent_stats(role) for role in DEFAULT_AGENT_ROLES]
|
||||
|
||||
|
||||
@router.get("/stats/hierarchy")
|
||||
async def get_agent_hierarchy_stats(
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
main_agents = []
|
||||
for role in DEFAULT_AGENT_ROLES:
|
||||
stats.append(AgentStats(
|
||||
agent_id=role,
|
||||
call_count=_agent_call_counts.get(role, 0),
|
||||
current_task=_agent_current_tasks.get(role),
|
||||
status=_agent_statuses.get(role, "idle"),
|
||||
))
|
||||
return stats
|
||||
if role == "master":
|
||||
continue
|
||||
node = _build_agent_stats(role).model_dump()
|
||||
node["sub_commanders"] = [
|
||||
_build_agent_stats(sub_id).model_dump()
|
||||
for sub_id in SUB_COMMANDERS_BY_ROLE.get(role, [])
|
||||
]
|
||||
main_agents.append(node)
|
||||
return {"main_agents": main_agents}
|
||||
|
||||
|
||||
# ———— 配置管理(必须在 /{agent_id} 之前)————
|
||||
@router.get("/config/{agent_id}", response_model=AgentConfigOut)
|
||||
async def get_agent_config(
|
||||
agent_id: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取单个 Agent 完整配置"""
|
||||
result = await db.execute(select(Agent).where(Agent.role == agent_id))
|
||||
agent = result.scalar_one_or_none()
|
||||
|
||||
@@ -84,8 +100,13 @@ async def get_agent_config(
|
||||
raise HTTPException(status_code=404, detail="Agent 不存在")
|
||||
name, desc, prompt = defaults[agent_id]
|
||||
return AgentConfigOut(
|
||||
id=agent_id, name=name, role=agent_id,
|
||||
description=desc, system_prompt=prompt, enabled=True, is_active=True,
|
||||
id=agent_id,
|
||||
name=name,
|
||||
role=agent_id,
|
||||
description=desc,
|
||||
system_prompt=prompt,
|
||||
enabled=True,
|
||||
is_active=True,
|
||||
)
|
||||
return AgentConfigOut(
|
||||
id=agent.role,
|
||||
@@ -105,7 +126,6 @@ async def update_agent_config(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""更新 Agent 配置(名称、描述、提示词、启用状态)"""
|
||||
result = await db.execute(select(Agent).where(Agent.role == agent_id))
|
||||
agent = result.scalar_one_or_none()
|
||||
|
||||
@@ -163,78 +183,3 @@ async def get_agent(
|
||||
if not agent:
|
||||
raise HTTPException(status_code=404, detail="Agent 不存在")
|
||||
return agent
|
||||
|
||||
|
||||
|
||||
# ———— 配置管理 ————
|
||||
@router.get("/config/{agent_id}", response_model=AgentConfigOut)
|
||||
async def get_agent_config(
|
||||
agent_id: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取单个 Agent 完整配置"""
|
||||
result = await db.execute(select(Agent).where(Agent.role == agent_id))
|
||||
agent = result.scalar_one_or_none()
|
||||
if not agent:
|
||||
# 如果数据库中没有,返回默认配置
|
||||
from app.agents.prompts import MASTER_SYSTEM_PROMPT, PLANNER_SYSTEM_PROMPT, EXECUTOR_SYSTEM_PROMPT, LIBRARIAN_SYSTEM_PROMPT, ANALYST_SYSTEM_PROMPT
|
||||
defaults = {
|
||||
"master": ("JARVIS", "主控制核心", MASTER_SYSTEM_PROMPT),
|
||||
"planner": ("PLANNER", "规划专家", PLANNER_SYSTEM_PROMPT),
|
||||
"executor": ("EXECUTOR", "执行专家", EXECUTOR_SYSTEM_PROMPT),
|
||||
"librarian": ("LIBRARIAN", "知识管理员", LIBRARIAN_SYSTEM_PROMPT),
|
||||
"analyst": ("ANALYST", "数据分析师", ANALYST_SYSTEM_PROMPT),
|
||||
}
|
||||
if agent_id not in defaults:
|
||||
raise HTTPException(status_code=404, detail="Agent 不存在")
|
||||
name, desc, prompt = defaults[agent_id]
|
||||
return AgentConfigOut(
|
||||
id=agent_id, name=name, role=agent_id,
|
||||
description=desc, system_prompt=prompt, enabled=True, is_active=True,
|
||||
)
|
||||
return AgentConfigOut(
|
||||
id=agent.role,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
description=agent.description,
|
||||
system_prompt=agent.system_prompt,
|
||||
enabled=agent.is_active,
|
||||
is_active=agent.is_active,
|
||||
)
|
||||
|
||||
|
||||
@router.put("/config/{agent_id}", response_model=AgentConfigOut)
|
||||
async def update_agent_config(
|
||||
agent_id: str,
|
||||
data: AgentConfigUpdate,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""更新 Agent 配置(名称、描述、提示词、启用状态)"""
|
||||
result = await db.execute(select(Agent).where(Agent.role == agent_id))
|
||||
agent = result.scalar_one_or_none()
|
||||
|
||||
if not agent:
|
||||
raise HTTPException(status_code=404, detail="Agent 不存在")
|
||||
|
||||
if data.name is not None:
|
||||
agent.name = data.name
|
||||
if data.description is not None:
|
||||
agent.description = data.description
|
||||
if data.system_prompt is not None:
|
||||
agent.system_prompt = data.system_prompt
|
||||
if data.enabled is not None:
|
||||
agent.is_active = data.enabled
|
||||
_agent_statuses[agent_id] = "disabled" if not data.enabled else "idle"
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(agent)
|
||||
return AgentConfigOut(
|
||||
id=agent.role,
|
||||
name=agent.name,
|
||||
role=agent.role,
|
||||
description=agent.description,
|
||||
system_prompt=agent.system_prompt,
|
||||
enabled=agent.is_active,
|
||||
is_active=agent.is_active,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user