[dev] modify path to absolute class path

This commit is contained in:
jinli.yl 2024-06-27 14:28:19 +08:00
parent 879dcf866c
commit 28624de878
45 changed files with 30 additions and 389 deletions

View file

@ -7,7 +7,7 @@
},
"memory_chat": {
"cli_memory_chat": {
"class": "chat_v2.cli_memory_chat",
"class": "chat.cli_memory_chat",
"memory_service": "memory_chat_service",
"generation_model": "dashscope_generation"
}

View file

@ -5,7 +5,7 @@ global_config:
open_ai_apikey:
memory_chat:
cli_memory_chat:
class: chat_v2.cli_memory_chat
class: chat.cli_memory_chat
memory_service: memory_chat_service
generation_model: dashscope_generation
memory_service:

View file

@ -2,8 +2,6 @@ from abc import ABCMeta, abstractmethod
class BaseMemoryChat(metaclass=ABCMeta):
def __init__(self, **kwargs):
self.kwargs = kwargs
@abstractmethod
def chat_with_memory(self, query: str):

View file

@ -1,54 +0,0 @@
import threading
from abc import ABCMeta, abstractmethod
from typing import List, Dict
from memory_scope.memory.operation.base_operation import BaseOperation
from memory_scope.scheme.message import Message
from memory_scope.utils.logger import Logger
class BaseMemoryService(metaclass=ABCMeta):
def __init__(self,
memory_operations: Dict[str, dict],
read_memory_key: str = "read_memory",
**kwargs):
self.memory_operations: Dict[str, dict] = memory_operations
self.read_memory_key: str = read_memory_key
self._operation_dict: Dict[str, BaseOperation] = {}
self._op_description_dict: Dict[str, str] = {}
self.chat_messages: List[Message] = []
self.message_lock = threading.Lock
self.logger = Logger.get_logger()
self.kwargs = kwargs
self._init_operation(memory_operations)
@abstractmethod
def _init_operation(self, memory_operations: Dict[str, dict]):
raise NotImplementedError
@abstractmethod
def add_messages(self, messages: List[Message] | Message):
raise NotImplementedError
def prepare_service(self):
pass
@abstractmethod
def do_operation(self, op_name: str):
raise NotImplementedError
@property
def op_description_dict(self) -> Dict[str, str]:
if not self._op_description_dict:
self._op_description_dict = {k: v.description for k, v in self._operation_dict.items()}
return self._op_description_dict
def read_memory(self):
assert self.read_memory_key in self._operation_dict, f"op={self.read_memory_key} is not inited!"
return self.operate(self.read_memory_key)
# def __getattr__(self, key):
# return self.kwargs[key]

View file

@ -1,50 +0,0 @@
from typing import List, Dict
from memory_scope.memory.service.base_memory_service import BaseMemoryService
from memory_scope.scheme.message import Message
from memory_scope.utils.tool_functions import init_instance_by_config
class ChatMemoryService(BaseMemoryService):
def __init__(self,
history_msg_count: int = 32,
contextual_msg_count: int = 6,
**kwargs):
super().__init__(**kwargs)
self.history_msg_count: int = history_msg_count
self.contextual_msg_count: int = contextual_msg_count
assert self.history_msg_count >= self.contextual_msg_count
def _init_operation(self, memory_operations: Dict[str, dict]):
for name, operation_config in memory_operations.items():
if name in self._operation_dict:
self.logger.warning(f"memory operation={name} is repeated!")
continue
self._operation_dict[name] = init_instance_by_config(config=operation_config,
name=name,
chat_messages=self.chat_messages,
message_lock=self.message_lock,
contextual_msg_count=self.contextual_msg_count)
def add_messages(self, messages: List[Message] | Message):
if isinstance(messages, Message):
messages = [messages]
messages = sorted(messages, key=lambda x: x.time_created)
self.chat_messages.extend(messages)
if len(self.chat_messages) > self.history_msg_count:
gap_size = len(self.chat_messages) - self.history_msg_count
for _ in range(gap_size):
self.chat_messages.pop(0)
def prepare_service(self):
for _, operation in self._operation_dict.items():
operation.init_workflow()
if operation.operation_type == "backend":
operation.run_operation_backend()
def do_operation(self, op_name: str):
if op_name not in self._operation_dict:
self.logger.warning(f"op_name={op_name} is not inited!")
return
return self._operation_dict[op_name].run_operation()

View file

@ -1,10 +1,11 @@
import datetime
import time
from typing import Dict, List
from typing import List
import questionary
from memory_scope.chat.base_memory_chat import BaseMemoryChat
from memory_scope.chat.global_context import GlobalContext
from memory_scope.chat.global_context import G_CONTEXT
from memory_scope.enumeration.message_role_enum import MessageRoleEnum
from memory_scope.memory.service.base_memory_service import BaseMemoryService
from memory_scope.models.base_model import BaseModel
@ -20,30 +21,30 @@ class CliMemoryChat(BaseMemoryChat):
"stream": "get stream response"
}
def __init__(self, memory_service: str, generation_model: str, **kwargs):
super().__init__(**kwargs)
def __init__(self, memory_service: str, generation_model: str, stream: bool = True, **kwargs):
self._memory_service: BaseMemoryService | str = memory_service
self._generation_model: BaseModel | str = generation_model
self.stream: bool = True
self.stream: bool = stream
self.kwargs: dict = kwargs
@property
def memory_service(self) -> BaseMemoryService:
if isinstance(self._memory_service, str):
self._memory_service = GlobalContext.memory_service_dict[self._memory_service]
self._memory_service = G_CONTEXT.memory_service_dict[self._memory_service]
self._memory_service.prepare_service()
return self._memory_service
@property
def generation_model(self) -> BaseModel:
if isinstance(self._generation_model, str):
self._generation_model = GlobalContext.model_dict[self._generation_model]
self._generation_model = G_CONTEXT.model_dict[self._generation_model]
return self._generation_model
@staticmethod
def get_system_prompt(related_memories: List[str], time_created: int) -> Message:
system_prompt = SYSTEM_PROMPT[GlobalContext.language]
system_prompt = SYSTEM_PROMPT[G_CONTEXT.language]
if related_memories:
memory_prompt = MEMORY_PROMPT[GlobalContext.language]
memory_prompt = MEMORY_PROMPT[G_CONTEXT.language]
all_prompt_list = [system_prompt, memory_prompt]
all_prompt_list.extend(related_memories)
system_prompt = "\n".join([x.strip() for x in all_prompt_list])
@ -56,18 +57,17 @@ class CliMemoryChat(BaseMemoryChat):
time_created = int(datetime.datetime.now().timestamp())
new_message: Message = Message(role=MessageRoleEnum.USER, content=query, time_created=time_created)
self.submit_messages(new_message)
self.memory_service.add_messages(new_message)
related_memories: List[str] = self.memory_service.read_memory()
system_message: Message = self.get_system_prompt(related_memories, time_created)
if self.stream:
for result in self.generation_model.call(messages=[system_message, new_message], stream=self.stream):
yield result
self.submit_messages(result.text)
self.memory_service.add_messages(result.text)
def run(self):
op_description_dict: Dict[str, str] = self.memory_service.get_op_description_dict()
self.USER_COMMANDS.update({f"/{k}": v for k, v in op_description_dict.items()})
self.USER_COMMANDS.update({f"/{k}": v for k, v in self.memory_service.op_description_dict.items()})
while True:
query = questionary.text(
@ -97,7 +97,7 @@ class CliMemoryChat(BaseMemoryChat):
elif query == "stream":
questionary.print(f"stream: {self.stream}")
self.stream = ~self.stream
elif query in op_description_dict:
elif query in self.memory_service.op_description_dict:
if not args:
result = self.memory_service.do_operation(op_name=query)
print(result)

View file

@ -1,31 +1,27 @@
from concurrent.futures import ThreadPoolExecutor
from typing import Dict, Any
from .base_memory_chat import BaseMemoryChat
from ..enumeration.language_enum import LanguageEnum
from ..models.base_model import BaseModel
from ..storage.base_monitor import BaseMonitor
from ..storage.base_vector_store import BaseVectorStore
from ..worker.base_worker import BaseWorker
from memory_scope.chat.base_memory_chat import BaseMemoryChat
from memory_scope.enumeration.language_enum import LanguageEnum
from memory_scope.memory.service.base_memory_service import BaseMemoryService
from memory_scope.models.base_model import BaseModel
from memory_scope.storage.base_monitor import BaseMonitor
from memory_scope.storage.base_vector_store import BaseVectorStore
class GlobalContext(object):
def __init__(self):
self.global_configs: Dict[str, Any] = {}
self.worker_config: Dict[str, Dict[str, BaseWorker]] = {}
self.global_config: Dict[str, Any] = {}
self.worker_config: Dict[str, Dict[str, Any]] = {}
self.memory_service_dict: Dict[str, BaseMemoryService] = {}
self.model_dict: Dict[str, BaseModel] = {}
self.memory_chat_dict: Dict[str, BaseMemoryChat] = {}
self.vector_store: BaseVectorStore | None = None
self.monitor: BaseMonitor | None = None
self.thread_pool: ThreadPoolExecutor | None = None
self.language: LanguageEnum = LanguageEnum.EN
GLOBAL_CONTEXT = GlobalContext()
G_CONTEXT = GlobalContext()

View file

@ -1,57 +0,0 @@
import datetime
from typing import List
from .base_memory_chat import BaseMemoryChat
from .global_context import GLOBAL_CONTEXT
from enumeration.message_role_enum import MessageRoleEnum
from models.base_model import BaseModel
from prompts.memory_chat_prompt import SYSTEM_PROMPT, MEMORY_PROMPT
from scheme.message import Message
from .memory_service import MemoryService
class MemoryChat(BaseMemoryChat):
def __init__(self, generation_model: str, history_msg_count: int, chat_name: str, **kwargs):
super().__init__(**kwargs)
self.memory_service = MemoryService(chat_name=chat_name, **kwargs)
self.generation_model_name: str = generation_model
self.history_msg_count: int = history_msg_count
self._generation_model: BaseModel | None = None
self.history_message_list: List[Message] = []
@property
def generation_model(self):
if self._generation_model is None:
self._generation_model = GLOBAL_CONTEXT.model_dict[
self.generation_model_name
]
return self._generation_model
def chat_with_memory(self, query: str):
query = query.strip()
if not query:
return
time_created = int(datetime.datetime.now().timestamp())
new_message: Message = Message(
role=MessageRoleEnum.USER, content=query, time_created=time_created
)
related_memories: List[str] = self.memory_service.retrieve(message=new_message)
system_message = self.get_system_prompt(related_memories, time_created)
self.history_message_list.append(new_message)
self.history_message_list = self.history_message_list[-self.history_msg_count:]
all_messages = [system_message] + self.history_message_list
# TODO at xian zhe
return self.generation_model.call(messages=all_messages, stream=True)
def run(self):
self.memory_service.start_memory_backend()
while True:
query = input("wait for input:")
if query in ["stop", "停止"]:
break
self.chat_with_memory(query=query)

View file

@ -1,14 +0,0 @@
from abc import ABCMeta, abstractmethod
class BaseMemoryChat(metaclass=ABCMeta):
@abstractmethod
def chat_with_memory(self, query: str):
"""
:param query:
:return:
"""
def run(self):
pass

View file

@ -1,139 +0,0 @@
import datetime
import time
from typing import List
import questionary
from memory_scope.chat_v2.base_memory_chat import BaseMemoryChat
from memory_scope.chat_v2.global_context import G_CONTEXT
from memory_scope.enumeration.message_role_enum import MessageRoleEnum
from memory_scope.memory.service.base_memory_service import BaseMemoryService
from memory_scope.models.base_model import BaseModel
from memory_scope.prompts.memory_chat_prompt import MEMORY_PROMPT, SYSTEM_PROMPT
from memory_scope.scheme.message import Message
from ..models.model_response import ModelResponse, ModelResponseGen
class CliMemoryChat(BaseMemoryChat):
USER_COMMANDS = {
"exit": "exit the CLI",
"help": "get cli commands help",
"stream": "get stream response"
}
def __init__(self, memory_service: str, generation_model: str, stream: bool = True, **kwargs):
self._memory_service: BaseMemoryService | str = memory_service
self._generation_model: BaseModel | str = generation_model
self.stream: bool = stream
self.kwargs: dict = kwargs
@property
def memory_service(self) -> BaseMemoryService:
if isinstance(self._memory_service, str):
self._memory_service = G_CONTEXT.memory_service_dict[self._memory_service]
self._memory_service.prepare_service()
return self._memory_service
@property
def generation_model(self) -> BaseModel:
if isinstance(self._generation_model, str):
self._generation_model = G_CONTEXT.model_dict[self._generation_model]
return self._generation_model
@staticmethod
def get_system_prompt(related_memories: List[str], time_created: int) -> Message:
system_prompt = SYSTEM_PROMPT[G_CONTEXT.language]
if related_memories:
memory_prompt = MEMORY_PROMPT[G_CONTEXT.language]
all_prompt_list = [system_prompt, memory_prompt]
all_prompt_list.extend(related_memories)
system_prompt = "\n".join([x.strip() for x in all_prompt_list])
return Message(role=MessageRoleEnum.SYSTEM, content=system_prompt, time_created=time_created)
def chat_with_memory(self, query: str) -> ModelResponse | ModelResponseGen:
query = query.strip()
if not query:
return
time_created = int(datetime.datetime.now().timestamp())
new_message: Message = Message(role=MessageRoleEnum.USER, content=query, time_created=time_created)
self.memory_service.add_messages(new_message)
related_memories: List[str] = self.memory_service.read_memory()
system_message: Message = self.get_system_prompt(related_memories, time_created)
if self.stream:
for result in self.generation_model.call(messages=[system_message, new_message], stream=self.stream):
yield result
self.memory_service.add_messages(result.text)
def run(self):
self.USER_COMMANDS.update({f"/{k}": v for k, v in self.memory_service.op_description_dict.items()})
while True:
query = questionary.text(
"Please enter your message or command:",
multiline=False,
qmark=">",
).ask()
query: str = query.rstrip()
if query == "":
print("Empty input received. Please try again!")
continue
# handle cli / commands with memory ops
if query.startswith("/"):
query_split = query.lstrip("/").lower().split(" ")
query = query_split[0]
args = query_split[1:]
if query == "exit":
break
elif query == "help":
questionary.print("CLI commands", "bold")
for cmd, desc in self.USER_COMMANDS.items():
questionary.print(cmd, "bold")
print(f" {desc}")
elif query == "stream":
questionary.print(f"stream: {self.stream}")
self.stream = ~self.stream
elif query in self.memory_service.op_description_dict:
if not args:
result = self.memory_service.do_operation(op_name=query)
print(result)
elif args[0].isdigit():
refresh_time = int(args[0])
try:
while True:
time.sleep(refresh_time)
result = self.memory_service.do_operation(op_name=query)
print(result, flush=True)
except KeyboardInterrupt:
print("stop refresh!")
else:
print("unknown command received. Please try again!")
else:
print("unknown command received. Please try again!")
continue
while True:
try:
if self.stream:
for msg in self.chat_with_memory(query=query):
print(msg.text, flush=True)
print()
else:
msg = self.chat_with_memory(query=query)
print(msg.text)
break
except KeyboardInterrupt:
questionary.print("User interrupt occurred.")
retry = questionary.confirm("Retry chat_with_memory()?").ask()
if not retry:
break
except Exception as e:
questionary.print(f"An exception occurred when running chat_with_memory(): {e}")
retry = questionary.confirm("Retry chat_with_memory()?").ask()
if not retry:
break

View file

@ -1,27 +0,0 @@
from concurrent.futures import ThreadPoolExecutor
from typing import Dict, Any
from memory_scope.chat_v2.base_memory_chat import BaseMemoryChat
from memory_scope.enumeration.language_enum import LanguageEnum
from memory_scope.memory.service.base_memory_service import BaseMemoryService
from memory_scope.models.base_model import BaseModel
from memory_scope.storage.base_monitor import BaseMonitor
from memory_scope.storage.base_vector_store import BaseVectorStore
class GlobalContext(object):
def __init__(self):
self.global_config: Dict[str, Any] = {}
self.worker_config: Dict[str, Dict[str, Any]] = {}
self.memory_service_dict: Dict[str, BaseMemoryService] = {}
self.model_dict: Dict[str, BaseModel] = {}
self.memory_chat_dict: Dict[str, BaseMemoryChat] = {}
self.vector_store: BaseVectorStore | None = None
self.monitor: BaseMonitor | None = None
self.thread_pool: ThreadPoolExecutor | None = None
self.language: LanguageEnum = LanguageEnum.EN
G_CONTEXT = GlobalContext()

View file

@ -9,7 +9,7 @@ from typing import Dict, Any
import fire
import yaml
from memory_scope.chat_v2.global_context import G_CONTEXT
from memory_scope.chat.global_context import G_CONTEXT
from memory_scope.enumeration.language_enum import LanguageEnum
from memory_scope.utils.logger import Logger
from memory_scope.utils.tool_functions import init_instance_by_config

View file

@ -4,7 +4,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
from itertools import zip_longest
from typing import Dict, Any, List
from memory_scope.chat_v2.global_context import G_CONTEXT
from memory_scope.chat.global_context import G_CONTEXT
from memory_scope.constants.common_constants import WORKFLOW_NAME
from memory_scope.memory.worker.base_worker import BaseWorker
from memory_scope.utils.logger import Logger

View file

@ -1,6 +1,6 @@
import time
from memory_scope.chat_v2.global_context import G_CONTEXT
from memory_scope.chat.global_context import G_CONTEXT
from memory_scope.constants.common_constants import RESULT
from memory_scope.memory.operation.base_operation import BaseOperation, OPERATION_TYPE
from memory_scope.memory.operation.base_workflow import BaseWorkflow

View file

@ -1,7 +1,7 @@
import time
from typing import List
from memory_scope.chat_v2.global_context import G_CONTEXT
from memory_scope.chat.global_context import G_CONTEXT
from memory_scope.constants.common_constants import CHAT_MESSAGES, RESULT
from memory_scope.memory.operation.base_operation import BaseOperation, OPERATION_TYPE
from memory_scope.memory.operation.base_workflow import BaseWorkflow

View file

@ -19,22 +19,10 @@ class BaseVectorStore(metaclass=ABCMeta):
@abstractmethod
def retrieve(self, query: str, top_k: int, filter_dict: Dict[str, List[str]]):
"""
:param text:
:param limit_size:
:param filter_dict:
:return:
"""
pass
@abstractmethod
async def async_retrieve(self, query: str, top_k: int, filter_dict: Dict[str, List[str]]):
"""
:param text:
:param limit_size:
:param filter_dict:
:return:
"""
pass
@abstractmethod