"""会话业务状态 repository(作业 6-1/6-2)。 抽象出 repository 接口,使应用服务不依赖具体存储; 作业 6 用内存实现跑通四接口,作业 7 再替换为 PostgreSQL 实现 (对话 checkpoint 已由 LangGraph checkpointer 承担,本层只管 业务字段——单一事实来源,图每轮读取最新值)。 语义约定: - 业务状态按外部业务键(hphm1、ywrysw...)扁平存储,值为内部强类型; - 不存在的会话视为空状态(读取返回 {}),与首轮 checkpoint 无字段一致; - delete 幂等:重复删除固定成功,不抛异常(行为进测试)。 """ from typing import Protocol class SessionRepository(Protocol): """业务字段存储接口(作业 7 由 PostgreSQL 实现替换)。""" def load(self, session_id: str) -> dict: """读取会话业务字段;无记录时返回空 dict。""" ... def apply_update(self, session_id: str, patch: dict) -> dict: """合并差量并返回合并后的完整业务字段。""" ... def delete(self, session_id: str) -> None: """删除会话业务状态;幂等,重复删除不抛异常。""" ... class InMemorySessionRepository: """内存实现:字典存储,仅用于单进程开发与测试。""" def __init__(self) -> None: self._store: dict[str, dict] = {} def load(self, session_id: str) -> dict: return dict(self._store.get(session_id) or {}) def apply_update(self, session_id: str, patch: dict) -> dict: state = self._store.setdefault(session_id, {}) state.update(patch) return dict(state) def delete(self, session_id: str) -> None: # 幂等:pop 的缺省值吞掉不存在的情况,重复删除行为固定为成功 self._store.pop(session_id, None) __all__ = ["SessionRepository", "InMemorySessionRepository"]