"""Namespace construction and access checks for Memory Gateway.""" from __future__ import annotations from datetime import datetime, timezone from .schemas import AccessContext, MemoryRecord, NamespaceInfo, Visibility def user_profile_namespace(user_id: str) -> str: return f"user/{user_id}/profile" def user_preferences_namespace(user_id: str) -> str: return f"user/{user_id}/preferences" def user_long_term_namespace(user_id: str) -> str: return f"user/{user_id}/long_term" def agent_memory_namespace(agent_id: str) -> str: return f"agent/{agent_id}/memory" def workspace_shared_namespace(workspace_id: str) -> str: return f"workspace/{workspace_id}/shared" def session_episodic_namespace(session_id: str) -> str: return f"session/{session_id}/episodic" def global_public_namespace() -> str: return "global/public" def default_namespace_for_context(ctx: AccessContext, visibility: Visibility) -> str: if visibility == Visibility.AGENT_ONLY and ctx.agent_id: return agent_memory_namespace(ctx.agent_id) if visibility == Visibility.WORKSPACE_SHARED and ctx.workspace_id: return workspace_shared_namespace(ctx.workspace_id) if ctx.session_id: return session_episodic_namespace(ctx.session_id) return user_long_term_namespace(ctx.user_id) def can_access_memory(ctx: AccessContext, memory: MemoryRecord) -> bool: if memory.expires_at and memory.expires_at <= datetime.now(timezone.utc): return False if memory.visibility == Visibility.GLOBAL: return True if memory.visibility == Visibility.PRIVATE: return memory.user_id == ctx.user_id if memory.visibility == Visibility.AGENT_ONLY: return memory.user_id == ctx.user_id and memory.agent_id == ctx.agent_id if memory.visibility == Visibility.WORKSPACE_SHARED: return memory.workspace_id is not None and memory.workspace_id == ctx.workspace_id return False def visible_namespaces(ctx: AccessContext) -> list[NamespaceInfo]: namespaces = [ NamespaceInfo( namespace=user_profile_namespace(ctx.user_id), owner_user_id=ctx.user_id, visibility=Visibility.PRIVATE, description="用户 profile 与稳定偏好", ), NamespaceInfo( namespace=user_preferences_namespace(ctx.user_id), owner_user_id=ctx.user_id, visibility=Visibility.PRIVATE, description="用户显式偏好", ), NamespaceInfo( namespace=user_long_term_namespace(ctx.user_id), owner_user_id=ctx.user_id, visibility=Visibility.PRIVATE, description="用户长期记忆", ), NamespaceInfo( namespace=global_public_namespace(), visibility=Visibility.GLOBAL, description="全局公开知识", ), ] if ctx.agent_id: namespaces.append( NamespaceInfo( namespace=agent_memory_namespace(ctx.agent_id), owner_user_id=ctx.user_id, visibility=Visibility.AGENT_ONLY, description="指定 agent 私有经验", ) ) if ctx.workspace_id: namespaces.append( NamespaceInfo( namespace=workspace_shared_namespace(ctx.workspace_id), owner_user_id=ctx.user_id, visibility=Visibility.WORKSPACE_SHARED, description="workspace / project 共享记忆", ) ) if ctx.session_id: namespaces.append( NamespaceInfo( namespace=session_episodic_namespace(ctx.session_id), owner_user_id=ctx.user_id, visibility=Visibility.PRIVATE, description="session 临时 episodic memory", ) ) return namespaces