2026-03-19 02:11:52 +08:00
|
|
|
|
"""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())
|
|
|
|
|
|
|
2026-03-29 13:47:41 +08:00
|
|
|
|
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())
|
|
|
|
|
|
|
2026-03-20 01:31:00 +08:00
|
|
|
|
async def list_all_specs(self) -> list[dict[str, Any]]:
|
2026-03-29 13:47:41 +08:00
|
|
|
|
"""获取已启用的 SubAgent 运行规格,按 updated_at 降序。"""
|
|
|
|
|
|
items = await self.list_enabled()
|
2026-03-20 01:31:00 +08:00
|
|
|
|
return [item.to_subagent_spec() for item in items]
|
|
|
|
|
|
|
2026-03-19 02:11:52 +08:00
|
|
|
|
async def get_by_name(self, name: str) -> SubAgent | None:
|
|
|
|
|
|
"""根据名称获取 SubAgent"""
|
|
|
|
|
|
result = await self.db.execute(select(SubAgent).where(SubAgent.name == name))
|
|
|
|
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
|
|
|
|
|
|
async def exists_name(self, name: str) -> bool:
|
2026-03-20 01:31:00 +08:00
|
|
|
|
"""检查名称是否存在(仅查询计数,不获取完整数据)"""
|
2026-03-20 03:21:52 +08:00
|
|
|
|
from sqlalchemy import func, select
|
|
|
|
|
|
|
|
|
|
|
|
result = await self.db.execute(select(func.count()).select_from(SubAgent).where(SubAgent.name == name))
|
2026-03-20 01:31:00 +08:00
|
|
|
|
return result.scalar() > 0
|
2026-03-19 02:11:52 +08:00
|
|
|
|
|
|
|
|
|
|
async def create(
|
|
|
|
|
|
self,
|
|
|
|
|
|
*,
|
|
|
|
|
|
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(
|
|
|
|
|
|
name=name,
|
|
|
|
|
|
description=description,
|
|
|
|
|
|
system_prompt=system_prompt,
|
|
|
|
|
|
tools=tools or [],
|
|
|
|
|
|
model=model,
|
2026-03-29 13:47:41 +08:00
|
|
|
|
enabled=True,
|
2026-03-19 02:11:52 +08:00
|
|
|
|
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,
|
|
|
|
|
|
*,
|
|
|
|
|
|
description: str | None,
|
|
|
|
|
|
system_prompt: str | None,
|
|
|
|
|
|
tools: list[str] | None,
|
|
|
|
|
|
model: str | None,
|
|
|
|
|
|
model_provided: bool = False,
|
|
|
|
|
|
updated_by: str | None,
|
|
|
|
|
|
) -> SubAgent:
|
2026-03-20 01:31:00 +08:00
|
|
|
|
# 批量更新非空字段
|
|
|
|
|
|
updates = {
|
|
|
|
|
|
"description": description,
|
|
|
|
|
|
"system_prompt": system_prompt,
|
|
|
|
|
|
"tools": tools,
|
|
|
|
|
|
}
|
|
|
|
|
|
for field, value in updates.items():
|
|
|
|
|
|
if value is not None:
|
|
|
|
|
|
setattr(item, field, value)
|
2026-03-21 00:03:33 +08:00
|
|
|
|
# model_provided=True 时显式设置 model 值(包括 None),用于清空字段
|
|
|
|
|
|
if model_provided:
|
|
|
|
|
|
item.model = model
|
2026-03-19 02:11:52 +08:00
|
|
|
|
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()
|