mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-11-05 20:30:03 +08:00
129 lines
4.3 KiB
Python
129 lines
4.3 KiB
Python
from collections.abc import Sequence
|
|||
|
|
from typing import TYPE_CHECKING, Literal
|
||
|
|
|
||
|
|
from zhenxun.services.ai.context.memory.types import (
|
||
|
|
MemorySlot,
|
||
|
|
SessionMetadata,
|
||
|
|
)
|
||
|
|
from zhenxun.services.ai.core.messages import AgentMessage, LLMMessage
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from zhenxun.services.ai.context.memory.manager import GlobalMemoryManager
|
||
|
|
from zhenxun.services.ai.context.memory.storage.interfaces import (
|
||
|
|
BaseChatContext,
|
||
|
|
BaseSlotContext,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class ChatHistoryFacade:
|
||
|
|
"""短期对话历史门面"""
|
||
|
|
|
||
|
|
def __init__(self, manager: "GlobalMemoryManager", session_meta: SessionMetadata):
|
||
|
|
self.manager = manager
|
||
|
|
self.session_meta = session_meta
|
||
|
|
|
||
|
|
@property
|
||
|
|
def _backend(self) -> "BaseChatContext | None":
|
||
|
|
return self.manager.get_chat_context(
|
||
|
|
None, self.session_meta.namespace or "global"
|
||
|
|
)
|
||
|
|
|
||
|
|
async def get(self, limit: int | None = None) -> list[LLMMessage]:
|
||
|
|
"""获取当前会话的历史消息"""
|
||
|
|
if not self._backend:
|
||
|
|
return []
|
||
|
|
msgs = await self._backend.get_messages(self.session_meta)
|
||
|
|
return msgs[-limit:] if limit else msgs
|
||
|
|
|
||
|
|
async def add(self, messages: Sequence[AgentMessage] | AgentMessage) -> None:
|
||
|
|
"""向当前会话追加一条或多条历史消息"""
|
||
|
|
if not self._backend:
|
||
|
|
return
|
||
|
|
from zhenxun.services.ai.core.engine.context_renderer import ContextConverter
|
||
|
|
|
||
|
|
msgs = messages if isinstance(messages, Sequence) else [messages]
|
||
|
|
flattened = ContextConverter.flatten_to_llm_messages(msgs)
|
||
|
|
if flattened:
|
||
|
|
await self._backend.add_messages(self.session_meta, flattened)
|
||
|
|
|
||
|
|
async def clear(self) -> None:
|
||
|
|
"""清空当前会话的短期对话历史"""
|
||
|
|
if not self._backend:
|
||
|
|
return
|
||
|
|
await self._backend.clear(self.session_meta)
|
||
|
|
|
||
|
|
|
||
|
|
class SlotFacade:
|
||
|
|
"""中期记忆槽门面"""
|
||
|
|
|
||
|
|
def __init__(self, manager: "GlobalMemoryManager", session_meta: SessionMetadata):
|
||
|
|
self.manager = manager
|
||
|
|
self.session_meta = session_meta
|
||
|
|
|
||
|
|
@property
|
||
|
|
def _backend(self) -> "BaseSlotContext | None":
|
||
|
|
"""获取底层槽位存储后端"""
|
||
|
|
return self.manager.get_slot_context(
|
||
|
|
None, self.session_meta.namespace or "global"
|
||
|
|
)
|
||
|
|
|
||
|
|
async def get(self, label: str) -> str | None:
|
||
|
|
"""获取指定标识的槽位记忆内容"""
|
||
|
|
if not self._backend:
|
||
|
|
return None
|
||
|
|
slot = await self._backend.get_slot(self.session_meta, label)
|
||
|
|
return slot.content if slot else None
|
||
|
|
|
||
|
|
async def set(
|
||
|
|
self,
|
||
|
|
label: str,
|
||
|
|
content: str,
|
||
|
|
scope: Literal["session", "global"] = "session",
|
||
|
|
size_limit: int = 2000,
|
||
|
|
pinned: bool = True,
|
||
|
|
) -> None:
|
||
|
|
"""设置或更新指定的槽位记忆"""
|
||
|
|
if not self._backend:
|
||
|
|
return
|
||
|
|
slot = MemorySlot(
|
||
|
|
label=label,
|
||
|
|
content=content,
|
||
|
|
scope=scope,
|
||
|
|
size_limit=size_limit,
|
||
|
|
pinned=pinned,
|
||
|
|
)
|
||
|
|
await self._backend.set_slot(self.session_meta, slot)
|
||
|
|
|
||
|
|
async def delete(
|
||
|
|
self, label: str, scope: Literal["session", "global"] = "session"
|
||
|
|
) -> None:
|
||
|
|
"""删除指定的槽位记忆"""
|
||
|
|
if not self._backend:
|
||
|
|
return
|
||
|
|
await self._backend.delete_slot(self.session_meta, label, scope)
|
||
|
|
|
||
|
|
async def list_all(self) -> dict[str, str]:
|
||
|
|
"""获取当前会话所有被置顶的槽位记忆"""
|
||
|
|
if not self._backend:
|
||
|
|
return {}
|
||
|
|
slots = await self._backend.list_pinned_slots(self.session_meta)
|
||
|
|
return {s.label: s.content for s in slots}
|
||
|
|
|
||
|
|
|
||
|
|
class AgentSessionFacade:
|
||
|
|
"""
|
||
|
|
提供给第三方开发者的会话记忆访问聚合门面 (Facade)。
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(self, manager: "GlobalMemoryManager", session_meta: SessionMetadata):
|
||
|
|
self.manager = manager
|
||
|
|
self.session_meta = session_meta
|
||
|
|
self.history = ChatHistoryFacade(manager, session_meta)
|
||
|
|
self.slots = SlotFacade(manager, session_meta)
|
||
|
|
|
||
|
|
async def clear_all(self) -> None:
|
||
|
|
"""一键清空当前会话下的短期对话历史与记忆槽"""
|
||
|
|
cleaner = self.manager.cleaner().session(self.session_meta.session_id)
|
||
|
|
await cleaner.clear_short_term()
|
||
|
|
await cleaner.clear_slots()
|