ForcePilot/backend/package/yuxi/repositories/subagent_repository.py
Wenjie Zhang c772e5ca3a refactor: Agent 运行时架构重构 - 移除 RuntimeConfigMiddleware,统一上下文准备与工具解析
- 删除 runtime_config_middleware.py,将功能合并到:
  - prepare_agent_runtime_context(): 统一上下文准备入口
  - resolve_configured_runtime_tools(): 运行时工具解析
- context.py: 规范化函数重命名 (_names → _keys),重构 config 加载流程
- chatbot/deep_agent graph: 集成新上下文准备流程,移除 RuntimeConfigMiddleware 引用
- skills_middleware: 抽取 normalize_string_list 为共享工具函数
- subagent_service: get_subagents_from_names → get_subagents_from_slugs,支持 slug 查询
- 对应更新 repositories/services/routers 适配新接口
2026-05-26 17:40:17 +08:00

112 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""SubAgent 数据访问层"""
from typing import Any
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from yuxi.storage.postgres.models_business import SubAgent
from yuxi.utils.datetime_utils import utc_now_naive
class SubAgentRepository:
def __init__(self, db_session: AsyncSession):
self.db = db_session
async def list_all(self) -> list[SubAgent]:
"""获取所有 SubAgent按 updated_at 降序"""
result = await self.db.execute(select(SubAgent).order_by(SubAgent.updated_at.desc()))
return list(result.scalars().all())
async def list_enabled(self) -> list[SubAgent]:
"""获取已启用的 SubAgent。"""
result = await self.db.execute(
select(SubAgent).where(SubAgent.enabled.is_(True)).order_by(SubAgent.updated_at.desc())
)
return list(result.scalars().all())
async def list_all_specs(self) -> list[dict[str, Any]]:
"""获取已启用的 SubAgent 运行规格,按 updated_at 降序。"""
items = await self.list_enabled()
return [item.to_subagent_spec() for item in items]
async def get_by_slug(self, slug: str) -> SubAgent | None:
"""根据 slug 获取 SubAgent"""
result = await self.db.execute(select(SubAgent).where(SubAgent.slug == slug))
return result.scalar_one_or_none()
async def exists_slug(self, slug: str) -> bool:
"""检查 slug 是否存在(仅查询计数,不获取完整数据)"""
from sqlalchemy import func, select
result = await self.db.execute(select(func.count()).select_from(SubAgent).where(SubAgent.slug == slug))
return result.scalar() > 0
async def create(
self,
*,
slug: str,
name: str,
description: str,
system_prompt: str,
tools: list[str] | None,
model: str | None,
is_builtin: bool,
created_by: str | None,
) -> SubAgent:
now = utc_now_naive()
item = SubAgent(
slug=slug,
name=name,
description=description,
system_prompt=system_prompt,
tools=tools or [],
model=model,
enabled=True,
is_builtin=is_builtin,
created_by=created_by,
updated_by=created_by,
created_at=now,
updated_at=now,
)
self.db.add(item)
await self.db.commit()
await self.db.refresh(item)
return item
async def update(
self,
item: SubAgent,
*,
name: str | None,
description: str | None,
system_prompt: str | None,
tools: list[str] | None,
model: str | None,
model_provided: bool = False,
updated_by: str | None,
) -> SubAgent:
# 批量更新非空字段
updates = {
"name": name,
"description": description,
"system_prompt": system_prompt,
"tools": tools,
}
for field, value in updates.items():
if value is not None:
setattr(item, field, value)
# model_provided=True 时显式设置 model 值(包括 None用于清空字段
if model_provided:
item.model = model
item.updated_by = updated_by
item.updated_at = utc_now_naive()
await self.db.commit()
await self.db.refresh(item)
return item
async def delete(self, item: SubAgent) -> None:
"""删除 SubAgent"""
await self.db.delete(item)
await self.db.commit()