初始化提交

This commit is contained in:
chenxin committed 2026-08-21 16:00:13 +08:00
commit 887c1f449e
963 files changed
+166869

No files matched your search

+180
View File
@@ -0,0 +1,180 @@
"""司命台治理对象数据访问(api-spec §19.4)。
目标 / 感知通道 / 世界实体 / 计划 / 天工阁角色的 CRUD 数据访问;
均为本地单用户全局对象,不挂 character_id。
"""
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.time import utc_now
from app.models.governance import (
AgentRosterEntry,
Goal,
PerceptionChannel,
Plan,
ToolPolicy,
WorldEntity,
)
# —— 太一枢 · 目标 ——
async def list_goals(session: AsyncSession) -> list[Goal]:
result = await session.execute(
select(Goal).order_by(Goal.priority.desc(), Goal.updated_at.desc())
)
return list(result.scalars().all())
async def get_goal(session: AsyncSession, goal_id: str) -> Goal | None:
return await session.get(Goal, goal_id)
async def add_goal(session: AsyncSession, goal: Goal) -> Goal:
session.add(goal)
await session.flush()
return goal
async def list_goals_by_character(
session: AsyncSession,
character_id: str,
status_filter: str | None = None,
) -> list[Goal]:
"""按 character_id 获取目标列表;可选的 status 过滤。"""
stmt = select(Goal).where(Goal.character_id == character_id)
if status_filter:
stmt = stmt.where(Goal.status == status_filter)
stmt = stmt.order_by(Goal.priority.desc(), Goal.updated_at.desc())
result = await session.execute(stmt)
return list(result.scalars().all())
async def update_goal_progress(
session: AsyncSession,
goal_id: str,
progress: float,
) -> Goal | None:
"""更新目标的 progress 与 updated_at 字段。"""
goal = await session.get(Goal, goal_id)
if goal is None:
return None
goal.progress = progress
goal.updated_at = utc_now()
await session.flush()
return goal
async def list_active_session_goal(session: AsyncSession, character_id: str) -> Goal | None:
"""查找指定人物活跃的 session 级目标(各人物至多一个活跃 session 目标)。"""
result = await session.execute(
select(Goal)
.where(
Goal.character_id == character_id,
Goal.level == "session",
Goal.status == "active",
)
.limit(1)
)
return result.scalar_one_or_none()
# —— 烛照枢 · 感知通道 ——
async def list_perception_channels(session: AsyncSession) -> list[PerceptionChannel]:
result = await session.execute(select(PerceptionChannel).order_by(PerceptionChannel.channel))
return list(result.scalars().all())
async def get_perception_channel(session: AsyncSession, channel: str) -> PerceptionChannel | None:
return await session.get(PerceptionChannel, channel)
async def add_perception_channel(
session: AsyncSession, channel: PerceptionChannel
) -> PerceptionChannel:
session.add(channel)
await session.flush()
return channel
# —— 河图枢 · 世界实体 ——
async def list_world_entities(session: AsyncSession) -> list[WorldEntity]:
result = await session.execute(select(WorldEntity).order_by(WorldEntity.updated_at.desc()))
return list(result.scalars().all())
async def get_world_entity(session: AsyncSession, entity_id: str) -> WorldEntity | None:
return await session.get(WorldEntity, entity_id)
async def add_world_entity(session: AsyncSession, entity: WorldEntity) -> WorldEntity:
session.add(entity)
await session.flush()
return entity
# —— 洛书枢 · 计划 ——
async def list_plans(session: AsyncSession) -> list[Plan]:
result = await session.execute(select(Plan).order_by(Plan.updated_at.desc()))
return list(result.scalars().all())
async def get_plan(session: AsyncSession, plan_id: str) -> Plan | None:
return await session.get(Plan, plan_id)
async def add_plan(session: AsyncSession, plan: Plan) -> Plan:
session.add(plan)
await session.flush()
return plan
# —— 天工阁枢 · 角色在岗 ——
async def list_agent_roster(session: AsyncSession) -> list[AgentRosterEntry]:
result = await session.execute(select(AgentRosterEntry).order_by(AgentRosterEntry.role))
return list(result.scalars().all())
async def get_agent(session: AsyncSession, role: str) -> AgentRosterEntry | None:
return await session.get(AgentRosterEntry, role)
async def add_agent(session: AsyncSession, agent: AgentRosterEntry) -> AgentRosterEntry:
session.add(agent)
await session.flush()
return agent
# —— 百工枢 · 工具策略(§15/§16 共享)——
async def list_tool_policies(session: AsyncSession) -> list[ToolPolicy]:
result = await session.execute(select(ToolPolicy).order_by(ToolPolicy.name))
return list(result.scalars().all())
async def get_tool_policy(session: AsyncSession, name: str) -> ToolPolicy | None:
return await session.get(ToolPolicy, name)
async def add_tool_policy(session: AsyncSession, policy: ToolPolicy) -> ToolPolicy:
session.add(policy)
await session.flush()
return policy
# —— 计数(供九枢健康度聚合)——
async def count(session: AsyncSession, model: type) -> int:
result = await session.execute(select(func.count()).select_from(model))
return int(result.scalar_one())