130 lines
4.0 KiB
Python
130 lines
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Base class for memory
|
|
|
|
TODO: a abstract class for a piece of memory
|
|
TODO: data structure to organize multiple memory pieces in memory class
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Iterable, Sequence
|
|
from typing import Optional
|
|
from typing import Union
|
|
from typing import Callable
|
|
|
|
from ..message import Msg
|
|
|
|
|
|
class MemoryBase(ABC):
|
|
"""Base class for memory."""
|
|
|
|
_version: int = 1
|
|
|
|
def __init__(
|
|
self,
|
|
config: Optional[dict] = None,
|
|
) -> None:
|
|
"""MemoryBase is a base class for memory of agents.
|
|
|
|
Args:
|
|
config (`Optional[dict]`, defaults to `None`):
|
|
Configuration of this memory.
|
|
"""
|
|
self.config = {} if config is None else config
|
|
|
|
def update_config(self, config: dict) -> None:
|
|
"""
|
|
Configure memory as specified in config
|
|
Args:
|
|
config (`dict`): Configuration of resetting this memory
|
|
"""
|
|
self.config = config
|
|
|
|
@abstractmethod
|
|
def get_memory(
|
|
self,
|
|
recent_n: Optional[int] = None,
|
|
filter_func: Optional[Callable[[int, dict], bool]] = None,
|
|
) -> list:
|
|
"""
|
|
Return a certain range (`recent_n` or all) of memory,
|
|
filtered by `filter_func`
|
|
Args:
|
|
recent_n (int, optional):
|
|
indicate the most recent N memory pieces to be returned.
|
|
filter_func (Optional[Callable[[int, dict], bool]]):
|
|
filter function to decide which pieces of memory should
|
|
be returned, taking the index and a piece of memory as
|
|
input and return True (return this memory) or False
|
|
(does not return)
|
|
"""
|
|
|
|
@abstractmethod
|
|
def add(
|
|
self,
|
|
memories: Union[Sequence[Msg], Msg, None],
|
|
) -> None:
|
|
"""
|
|
Adding new memory fragment, depending on how the memory are stored
|
|
Args:
|
|
memories (Union[Sequence[Msg], Msg, None]):
|
|
Memories to be added.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def delete(self, index: Union[Iterable, int]) -> None:
|
|
"""
|
|
Delete memory fragment, depending on how the memory are stored
|
|
and matched
|
|
Args:
|
|
index (Union[Iterable, int]):
|
|
indices of the memory fragments to delete
|
|
"""
|
|
|
|
@abstractmethod
|
|
def load(
|
|
self,
|
|
memories: Union[str, list[Msg], Msg],
|
|
overwrite: bool = False,
|
|
) -> None:
|
|
"""
|
|
Load memory, depending on how the memory are passed, design to load
|
|
from both file or dict
|
|
Args:
|
|
memories (Union[str, list[Msg], Msg]):
|
|
memories to be loaded.
|
|
If it is in str type, it will be first checked if it is a
|
|
file; otherwise it will be deserialized as messages.
|
|
Otherwise, memories must be either in message type or list
|
|
of messages.
|
|
overwrite (bool):
|
|
if True, clear the current memory before loading the new ones;
|
|
if False, memories will be appended to the old one at the end.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def export(
|
|
self,
|
|
file_path: Optional[str] = None,
|
|
to_mem: bool = False,
|
|
) -> Optional[list]:
|
|
"""
|
|
Export memory, depending on how the memory are stored
|
|
Args:
|
|
file_path (Optional[str]):
|
|
file path to save the memory to.
|
|
to_mem (Optional[str]):
|
|
if True, just return the list of messages in memory
|
|
Notice: this method prevents file_path is None when to_mem
|
|
is False.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def clear(self) -> None:
|
|
"""Clean memory, depending on how the memory are stored"""
|
|
|
|
@abstractmethod
|
|
def size(self) -> int:
|
|
"""Returns the number of memory segments in memory."""
|
|
raise NotImplementedError
|