"""Exploration session settlement on campaign finalize (活动终态结算). 活动窗口结束或被取消进入终态时,仍 running 的探索会话转 expired—— 不留悬挂会话。结算后消息端点按既有状态机拒收(409)。 """ from sqlmodel import Session from agenteval.exploration.models import ExplorationSessionStatus from agenteval.storage.db import utc_now from agenteval.storage.repository import ExplorationSessionRepository def settle_campaign_sessions(campaign_id: str, session: Session) -> int: """Expire every still-running exploration session of a finalized campaign. Returns the number of sessions expired. Completed/failed sessions keep their evidence untouched. """ repo = ExplorationSessionRepository(session) expired = 0 for session_obj in repo.list_by_campaign(campaign_id): if session_obj.status != ExplorationSessionStatus.RUNNING: continue session_obj.status = ExplorationSessionStatus.EXPIRED session_obj.closed_at = utc_now() repo.update(session_obj) expired += 1 return expired