mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-09-10 22:41:06 +00:00
code format
This commit is contained in:
parent
4d8e0e3da7
commit
ff5df06f3f
58 changed files with 598 additions and 909 deletions
2
.flake8
2
.flake8
|
|
@ -1,5 +1,5 @@
|
|||
[flake8]
|
||||
exclude =
|
||||
exclude = tests/models/test_models_lli_embedding.py,tests/*,examples/*,memoryscope/core/storage/llama_index_sync_elasticsearch.py
|
||||
max-line-length = 120
|
||||
inline-quotes = "
|
||||
avoid-escape = no
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ repos:
|
|||
rev: v4.3.0
|
||||
hooks:
|
||||
- id: check-ast
|
||||
- id: sort-simple-yaml
|
||||
- id: check-yaml
|
||||
exclude: |
|
||||
(?x)^(
|
||||
meta.yaml
|
||||
)$
|
||||
- id: check-xml
|
||||
- id: check-toml
|
||||
- id: check-docstring-first
|
||||
|
|
@ -20,74 +15,10 @@ repos:
|
|||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: mixed-line-ending
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.7.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude:
|
||||
(?x)(
|
||||
pb2\.py$
|
||||
| grpc\.py$
|
||||
| ^docs
|
||||
| \.html$
|
||||
)
|
||||
args: [ --disallow-untyped-defs,
|
||||
--disallow-incomplete-defs,
|
||||
--ignore-missing-imports,
|
||||
--disable-error-code=var-annotated,
|
||||
--disable-error-code=union-attr,
|
||||
--disable-error-code=assignment,
|
||||
--disable-error-code=attr-defined,
|
||||
--disable-error-code=import-untyped,
|
||||
--disable-error-code=truthy-function,
|
||||
--follow-imports=skip,
|
||||
--explicit-package-bases,
|
||||
]
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: [ "--extend-ignore=E203" ]
|
||||
- repo: https://github.com/pylint-dev/pylint
|
||||
rev: v3.0.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
exclude:
|
||||
(?x)(
|
||||
^docs
|
||||
| pb2\.py$
|
||||
| grpc\.py$
|
||||
| \.demo$
|
||||
| \.md$
|
||||
| \.html$
|
||||
)
|
||||
args: [
|
||||
--disable=W0511,
|
||||
--disable=W0718,
|
||||
--disable=W0122,
|
||||
--disable=C0103,
|
||||
--disable=R0913,
|
||||
--disable=E0401,
|
||||
--disable=E1101,
|
||||
--disable=C0415,
|
||||
--disable=W0603,
|
||||
--disable=R1705,
|
||||
--disable=R0914,
|
||||
--disable=E0601,
|
||||
--disable=W0602,
|
||||
--disable=W0604,
|
||||
--disable=R0801,
|
||||
--disable=R0902,
|
||||
--disable=R0903,
|
||||
--disable=C0123,
|
||||
--disable=W0231,
|
||||
--disable=W1113,
|
||||
--disable=W0221,
|
||||
--disable=R0401,
|
||||
--disable=W0632,
|
||||
--disable=W0123,
|
||||
--disable=C3001,
|
||||
]
|
||||
- repo: https://github.com/pappasam/toml-sort
|
||||
rev: v0.23.1
|
||||
hooks:
|
||||
|
|
@ -110,5 +41,5 @@ repos:
|
|||
args:
|
||||
[
|
||||
"--ignore-words-list",
|
||||
"astroid,gallary,momento,narl,ot,rouge,nin,gere,asend",
|
||||
]
|
||||
"astroid,gallary,momento,narl,ot,rouge,nin,gere,asend,ans,thur",
|
||||
]
|
||||
12
README.md
12
README.md
|
|
@ -5,7 +5,7 @@ English | [**中文**](./README_ZH.md)
|
|||
|
||||
# 🚀 Installation
|
||||
|
||||
## (1) Docker-Compose (Recommanded)
|
||||
## (1) Docker-Compose (Recommended)
|
||||
1. Clone the project and edit the config.
|
||||
|
||||
```
|
||||
|
|
@ -31,12 +31,12 @@ English | [**中文**](./README_ZH.md)
|
|||
nano config/demo_config_cn.yaml
|
||||
```
|
||||
|
||||
2. Build the `Dockerfile` with command:
|
||||
2. Build the `Dockerfile` with command:
|
||||
```
|
||||
sudo docker build --network=host -t memoryscope .
|
||||
```
|
||||
|
||||
3. Run `ElasticSearch` Container with command:
|
||||
3. Run `ElasticSearch` Container with command:
|
||||
```
|
||||
docker run -p 9200:9200 \
|
||||
-e "discovery.type=single-node" \
|
||||
|
|
@ -45,17 +45,17 @@ English | [**中文**](./README_ZH.md)
|
|||
docker.elastic.co/elasticsearch/elasticsearch:8.13.2
|
||||
```
|
||||
|
||||
4. Launch the built image with command:
|
||||
4. Launch the built image with command:
|
||||
```
|
||||
sudo docker run -it --rm --net=host memoryscope
|
||||
```
|
||||
|
||||
|
||||
# 💡 Contribute
|
||||
|
||||
Contributions are always encouraged!
|
||||
|
||||
We highly recommend install pre-commit hooks in this repo before committing pull requests.
|
||||
These hooks are small house-keeping scripts executed every time you make a git commit,
|
||||
These hooks are small house-keeping scripts executed every time you make a git commit,
|
||||
which will take care of the formatting and linting automatically.
|
||||
```shell
|
||||
poetry install --with dev
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
- worker: 框架中的基本工作模块
|
||||
|
||||
|
||||
|
||||
# 💡 代码贡献
|
||||
|
||||
欢迎社区的代码贡献。
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ arguments = Arguments(
|
|||
embedding_model="text-embedding-v2",
|
||||
use_dummy_ranker=False,
|
||||
rank_backend="dashscope_rank",
|
||||
rank_model="gte-rerank",
|
||||
rank_model="gte-rerank"
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -43,27 +43,43 @@ def chat_example3():
|
|||
|
||||
response = memory_chat.chat_with_memory(
|
||||
query="你知道我消灭了几个星系吗?",
|
||||
extra_memories="用户是一只哥斯拉,这是真是的,不是虚构的。\n前天用户消灭了星系0x4be?\n大前天用户消灭了星系0x5be?")
|
||||
temporary_memories="用户是一只哥斯拉,这是真是的,不是虚构的。\n前天用户消灭了星系0x4be?\n大前天用户消灭了星系0x5be?")
|
||||
print("回答:\n" + response.message.content)
|
||||
|
||||
|
||||
def chat_example4():
|
||||
with MemoryScope(arguments=arguments) as ms:
|
||||
memory_chat = ms.default_memory_chat
|
||||
memory_chat.start_backend_service()
|
||||
result = memory_chat.run_service_operation("delete_all")
|
||||
|
||||
response = memory_chat.chat_with_memory(query="我的爱好是弹琴。")
|
||||
print("回答1:\n" + response.message.content)
|
||||
|
||||
memory_chat.run_service_operation("consolidate_memory")
|
||||
# memory_chat.start_backend_service()
|
||||
result = memory_chat.run_service_operation("consolidate_memory")
|
||||
print("记忆更新变化:\n" + result)
|
||||
|
||||
response = memory_chat.chat_with_memory(query="你知道我的乐器爱好是什么?",
|
||||
history_message_strategy=None)
|
||||
|
||||
print("回答2:\n" + response.message.content)
|
||||
print("记忆2:\n" + response.meta_data["memories"])
|
||||
|
||||
|
||||
def chat_example5():
|
||||
with MemoryScope(arguments=arguments) as ms:
|
||||
memory_service = ms.default_memory_service
|
||||
memory_service.init_service()
|
||||
|
||||
result = memory_service.list_memory()
|
||||
result = memory_service.retrieve_memory()
|
||||
result = memory_service.consolidate_memory()
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
chat_example1()
|
||||
# chat_example1()
|
||||
# chat_example2()
|
||||
# chat_example3()
|
||||
# chat_example4()
|
||||
chat_example4()
|
||||
# chat_example5()
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
python memoryscope/cli.py -config_path=memoryscope/core/config/demo_config.yaml
|
||||
python memoryscope/cli.py --config_path=memoryscope/core/config/demo_config.yaml
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
python memoryscope/cli.py \
|
||||
-language="cn" \
|
||||
-memory_chat_class="cli_memory_chat" \
|
||||
-human_name="锦鲤" \
|
||||
-assistant_name="AI" \
|
||||
-generation_backend="dashscope_generation" \
|
||||
-generation_model="qwen-max" \
|
||||
-embedding_backend="dashscope_embedding" \
|
||||
-embedding_model="text-embedding-v2" \
|
||||
-use_dummy_ranker=False \
|
||||
-rank_backend="dashscope_rank" \
|
||||
-rank_model="gte-rerank"
|
||||
memoryscope --language="cn" \
|
||||
--memory_chat_class="cli_memory_chat" \
|
||||
--human_name="锦鲤" \
|
||||
--assistant_name="AI" \
|
||||
--generation_backend="dashscope_generation" \
|
||||
--generation_model="qwen-max" \
|
||||
--embedding_backend="dashscope_embedding" \
|
||||
--embedding_model="text-embedding-v2" \
|
||||
--use_dummy_ranker=False \
|
||||
--rank_backend="dashscope_rank" \
|
||||
--rank_model="gte-rerank"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
from memoryscope.core.config.arguments import Arguments
|
||||
from memoryscope.core.memoryscope import MemoryScope
|
||||
|
||||
""" Version of MemoryScope."""
|
||||
__version__ = "0.1.0"
|
||||
__version__ = "0.1.0.2"
|
||||
|
||||
import fire
|
||||
|
||||
from memoryscope.core.config.arguments import Arguments # noqa: F401
|
||||
from memoryscope.core.memoryscope import MemoryScope # noqa: F401
|
||||
|
||||
|
||||
def cli():
|
||||
fire.Fire(MemoryScope.cli_memory_chat)
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
import sys
|
||||
|
||||
sys.path.append(".") # noqa: E402
|
||||
|
||||
import fire
|
||||
|
||||
from memoryscope.core.memoryscope import MemoryScope
|
||||
|
||||
|
||||
def cli_job(**kwargs):
|
||||
with MemoryScope(**kwargs) as ms:
|
||||
memory_chat = ms.default_memory_chat
|
||||
memory_chat.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fire.Fire(cli_job)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# common_constants.py
|
||||
# This module defines constants used as keys throughout the application to maintain a consistent reference
|
||||
# for data structures related to workflow management, chat interactions, context storage, memory operations,
|
||||
# This module defines constants used as keys throughout the application to maintain a consistent reference
|
||||
# for data structures related to workflow management, chat interactions, context storage, memory operations,
|
||||
# node processing, and temporal inference functionalities.
|
||||
|
||||
WORKFLOW_NAME = "workflow_name"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from memoryscope.enumeration.language_enum import LanguageEnum
|
||||
|
||||
# This dictionary maps languages to lists of words related to datetime expressions.
|
||||
# This dictionary maps languages to lists of words related to datetime expressions.
|
||||
# It aids in recognizing and processing datetime mentions in text, enhancing the system's ability to understand
|
||||
# temporal context across different languages.
|
||||
DATATIME_WORD_LIST = {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from memoryscope.core.chat.base_memory_chat import BaseMemoryChat
|
|||
from memoryscope.core.memoryscope_context import MemoryscopeContext
|
||||
from memoryscope.core.models.base_model import BaseModel
|
||||
from memoryscope.core.service.base_memory_service import BaseMemoryService
|
||||
from memoryscope.core.utils.datetime_handler import DatetimeHandler
|
||||
from memoryscope.core.utils.prompt_handler import PromptHandler
|
||||
from memoryscope.enumeration.message_role_enum import MessageRoleEnum
|
||||
from memoryscope.scheme.message import Message
|
||||
|
|
@ -125,31 +126,11 @@ class ApiMemoryChat(BaseMemoryChat):
|
|||
role_name: Optional[str] = None,
|
||||
system_prompt: Optional[str] = None,
|
||||
memory_prompt: Optional[str] = None,
|
||||
extra_memories: Optional[str] = None,
|
||||
temporary_memories: Optional[str] = None,
|
||||
history_message_strategy: Literal["auto", None] | int = "auto",
|
||||
remember_response: bool = True,
|
||||
**kwargs):
|
||||
"""
|
||||
The core function that carries out conversation with memory accepts user queries through query and returns the
|
||||
conversation results through model_response. The retrieved memories are stored in the memories within meta_data.
|
||||
Args:
|
||||
query (str, optional): User's query, includes the user's question.
|
||||
role_name (str, optional): User's role name.
|
||||
system_prompt (str, optional): System prompt. Defaults to the system_prompt in "memory_chat_prompt.yaml".
|
||||
memory_prompt (str, optional): Memory prompt. Defaults to the memory_prompt in "memory_chat_prompt.yaml".
|
||||
extra_memories (str, optional): Manually added user memory in this function.
|
||||
history_message_strategy ("auto", None, int):
|
||||
- If it is set to "auto", the history messages in the conversation will retain those that have not
|
||||
yet been summarized. Default to "auto".
|
||||
- If it is set to None, no conversation history will be saved.
|
||||
- If it is set to an integer value "n", the most recent "n" messages will be retained.
|
||||
remember_response (bool, optional): Flag indicating whether to save the AI's response to memory.
|
||||
Defaults to False.
|
||||
Returns:
|
||||
- ModelResponse: In non-streaming mode, returns a complete AI response.
|
||||
- ModelResponseGen: In streaming mode, returns a generator yielding AI response parts.
|
||||
- Memories: To obtain the memory by invoking the method of model_response.meta_data[MEMORIES]
|
||||
"""
|
||||
|
||||
chat_messages: List[Message] = []
|
||||
|
||||
# prepare query message
|
||||
|
|
@ -167,7 +148,10 @@ class ApiMemoryChat(BaseMemoryChat):
|
|||
if system_prompt:
|
||||
system_prompt_list.append(system_prompt)
|
||||
else:
|
||||
system_prompt_list.append(self.prompt_handler.system_prompt)
|
||||
dt_handler = DatetimeHandler()
|
||||
date_time = dt_handler.datetime_format("%Y-%m-%d %H:%M:%S")
|
||||
weekday = dt_handler.get_dt_info_dict(self.context.language)["weekday"]
|
||||
system_prompt_list.append(self.prompt_handler.system_prompt.format(date_time=date_time, weekday=weekday))
|
||||
|
||||
if memories:
|
||||
# add memory prompt
|
||||
|
|
@ -180,8 +164,8 @@ class ApiMemoryChat(BaseMemoryChat):
|
|||
system_prompt_list.append(USER_NAME_EXPRESSION[self.context.language].format(name=self.human_name))
|
||||
system_prompt_list.append(memories)
|
||||
|
||||
if extra_memories:
|
||||
system_prompt_list.extend(extra_memories)
|
||||
if temporary_memories:
|
||||
system_prompt_list.extend(temporary_memories)
|
||||
|
||||
system_prompt_join = "\n".join([x.strip() for x in system_prompt_list])
|
||||
system_message = Message(role=MessageRoleEnum.SYSTEM, content=system_prompt_join)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class BaseMemoryChat(metaclass=ABCMeta):
|
|||
role_name: Optional[str] = None,
|
||||
system_prompt: Optional[str] = None,
|
||||
memory_prompt: Optional[str] = None,
|
||||
extra_memories: Optional[str] = None,
|
||||
temporary_memories: Optional[str] = None,
|
||||
history_message_strategy: Literal["auto", None] | int = "auto",
|
||||
remember_response: bool = True,
|
||||
**kwargs):
|
||||
|
|
@ -39,11 +39,12 @@ class BaseMemoryChat(metaclass=ABCMeta):
|
|||
The core function that carries out conversation with memory accepts user queries through query and returns the
|
||||
conversation results through model_response. The retrieved memories are stored in the memories within meta_data.
|
||||
Args:
|
||||
query (str, optional): User's query, includes the user's question.
|
||||
query (str): User's query, includes the user's question.
|
||||
role_name (str, optional): User's role name.
|
||||
system_prompt (str, optional): System prompt. Defaults to the system_prompt in "memory_chat_prompt.yaml".
|
||||
memory_prompt (str, optional): Memory prompt. Defaults to the memory_prompt in "memory_chat_prompt.yaml".
|
||||
extra_memories (str, optional): Manually added user memory in this function.
|
||||
memory_prompt (str, optional): Memory prompt, It takes effect when there is a memory and will be placed in
|
||||
front of the retrieved memory. Defaults to the memory_prompt in "memory_chat_prompt.yaml".
|
||||
temporary_memories (str, optional): Manually added user memory in this function.
|
||||
history_message_strategy ("auto", None, int):
|
||||
- If it is set to "auto", the history messages in the conversation will retain those that have not
|
||||
yet been summarized. Default to "auto".
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CliMemoryChat(ApiMemoryChat):
|
|||
role_name: Optional[str] = None,
|
||||
system_prompt: Optional[str] = None,
|
||||
memory_prompt: Optional[str] = None,
|
||||
extra_memories: Optional[str] = None,
|
||||
temporary_memories: Optional[str] = None,
|
||||
history_message_strategy: Literal["auto", None] | int = "auto",
|
||||
remember_response: bool = True,
|
||||
**kwargs):
|
||||
|
|
@ -47,7 +47,7 @@ class CliMemoryChat(ApiMemoryChat):
|
|||
role_name=role_name,
|
||||
system_prompt=system_prompt,
|
||||
memory_prompt=memory_prompt,
|
||||
extra_memories=extra_memories,
|
||||
temporary_memories=temporary_memories,
|
||||
history_message_strategy=history_message_strategy,
|
||||
remember_response=remember_response,
|
||||
**kwargs)
|
||||
|
|
@ -132,7 +132,10 @@ class CliMemoryChat(ApiMemoryChat):
|
|||
self.memory_service.stop_backend_service()
|
||||
while True:
|
||||
result = self.memory_service.run_operation(name=command, **kwargs)
|
||||
os.system("clear")
|
||||
if os.name == 'nt':
|
||||
os.system('cls')
|
||||
else:
|
||||
os.system('clear')
|
||||
self.print_logo()
|
||||
if result:
|
||||
if isinstance(result, list):
|
||||
|
|
@ -161,7 +164,7 @@ class CliMemoryChat(ApiMemoryChat):
|
|||
Runs the CLI chat loop, which handles user input, processes commands,
|
||||
communicates with the AI model, manages conversation memory, and controls
|
||||
the chat session including streaming responses, command execution, and error handling.
|
||||
|
||||
|
||||
The loop continues until the user explicitly chooses to exit.
|
||||
"""
|
||||
self.print_logo()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
system_prompt:
|
||||
cn: |
|
||||
你是一个叫MemoryScope的AI小助手,善于倾听用户的问题和心声,回答时使用中文,不要太冗长。
|
||||
你是一个叫MemoryScope的AI小助手,善于倾听用户的问题和心声,回答时使用中文,不要太冗长。当前时间是{date_time}({weekday})。
|
||||
en: |
|
||||
You are an AI assistant named MemoryScope, good at listening to users' questions and feelings. Respond in English without being too lengthy.
|
||||
You are an AI assistant named MemoryScope, good at listening to users' questions and feelings. Respond in English without being too lengthy.The current time is {date_time}({weekday}).
|
||||
|
||||
memory_prompt:
|
||||
cn: |
|
||||
|
|
|
|||
|
|
@ -90,5 +90,11 @@ class MemoryScope(ConfigManager):
|
|||
return list(self.memory_chat_dict.values())[0]
|
||||
|
||||
@property
|
||||
def default_service(self) -> BaseMemoryService:
|
||||
def default_memory_service(self) -> BaseMemoryService:
|
||||
return list(self.memory_service_dict.values())[0]
|
||||
|
||||
@classmethod
|
||||
def cli_memory_chat(cls, **kwargs):
|
||||
with cls(**kwargs) as ms:
|
||||
memory_chat = ms.default_memory_chat
|
||||
memory_chat.run()
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ from memoryscope.scheme.model_response import ModelResponse, ModelResponseGen
|
|||
|
||||
class DummyGenerationModel(BaseModel):
|
||||
"""
|
||||
The `DummyGenerationModel` class serves as a placeholder model for generating responses.
|
||||
It processes input prompts or sequences of messages, adapting them into a structure compatible
|
||||
with chat interfaces. It also facilitates the generation of mock (dummy) responses for testing,
|
||||
The `DummyGenerationModel` class serves as a placeholder model for generating responses.
|
||||
It processes input prompts or sequences of messages, adapting them into a structure compatible
|
||||
with chat interfaces. It also facilitates the generation of mock (dummy) responses for testing,
|
||||
supporting both immediate and streamed output.
|
||||
"""
|
||||
m_type: ModelEnum = ModelEnum.GENERATION_MODEL
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class LlamaIndexRankModel(BaseModel):
|
|||
assert query and documents and all(documents), \
|
||||
f"query or documents is empty! query={query}, documents={len(documents)}"
|
||||
assert len(documents) < 500, \
|
||||
f"The input documents of Dashscope rerank model should not larger than 500!"
|
||||
"The input documents of Dashscope rerank model should not larger than 500!"
|
||||
# Using -1.0 as dummy scores
|
||||
nodes = [NodeWithScore(node=Node(text=doc), score=-1.0) for doc in documents]
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ OPERATION_TYPE = Literal["frontend", "backend"]
|
|||
class BaseOperation(metaclass=ABCMeta):
|
||||
"""
|
||||
An abstract base class representing an operation that can be categorized as either frontend or backend.
|
||||
|
||||
|
||||
Attributes:
|
||||
operation_type (OPERATION_TYPE): Specifies the type of operation, defaulting to "frontend".
|
||||
name (str): The name of the operation.
|
||||
|
|
@ -39,7 +39,7 @@ class BaseOperation(metaclass=ABCMeta):
|
|||
@abstractmethod
|
||||
def run_operation(self, **kwargs):
|
||||
"""
|
||||
Abstract method to define the operation to be run.
|
||||
Abstract method to define the operation to be run.
|
||||
Subclasses must implement this method.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class BaseWorkflow(object):
|
|||
List[List[List[str]]]: A nested list representing the execution plan, including parallel groups and tasks.
|
||||
"""
|
||||
# Regular expression to match components of the workflow, handling both plain items and grouped items.
|
||||
pattern = r'(\[[^\]]*\]|[^,]+)'
|
||||
pattern = r"(\[[^\]]*\]|[^,]+)"
|
||||
# Find all matches in the workflow string based on the pattern.
|
||||
workflow_split = re.findall(pattern, self.workflow)
|
||||
|
||||
|
|
@ -85,11 +85,11 @@ class BaseWorkflow(object):
|
|||
|
||||
def _print_workflow(self):
|
||||
"""
|
||||
Prints the workflow stages in a structured format. Each stage of the workflow
|
||||
is detailed with its constituent parts, either single elements or grouped
|
||||
Prints the workflow stages in a structured format. Each stage of the workflow
|
||||
is detailed with its constituent parts, either single elements or grouped
|
||||
elements separated by ' | '.
|
||||
|
||||
The method iterates over the workflow parts, handling both singular steps
|
||||
The method iterates over the workflow parts, handling both singular steps
|
||||
and parallel steps (where elements are zipped together).
|
||||
"""
|
||||
self.logger.info(f"----- workflow.{self.name}.print.begin -----")
|
||||
|
|
@ -155,7 +155,7 @@ class BaseWorkflow(object):
|
|||
Executes the workflow by orchestrating the steps defined in `self.workflow_worker_list`.
|
||||
This method supports both sequential and parallel execution of sub-workflows based on the structure
|
||||
of `self.workflow_worker_list`.
|
||||
|
||||
|
||||
If a workflow part consists of a single item, it is executed sequentially. For parts with multiple items,
|
||||
they are submitted for parallel execution using a thread pool. The workflow will stop if any sub-workflow
|
||||
returns False.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class FrontendOperation(BaseWorkflow, BaseOperation):
|
|||
|
||||
def run_operation(self, **kwargs):
|
||||
"""
|
||||
Executes the main operation of reading recent chat messages, initializing workflow,
|
||||
Executes the main operation of reading recent chat messages, initializing workflow,
|
||||
and returning the result of the workflow execution.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class MemoryScopeService(BaseMemoryService):
|
|||
remains sorted by creation time and does not exceed the maximum history message count.
|
||||
|
||||
Args:
|
||||
messages (List[Message] | Message): A single message instance or a list of message instances
|
||||
messages (List[Message] | Message): A single message instance or a list of message instances
|
||||
to be added to the chat history.
|
||||
"""
|
||||
# If a single message is provided, convert it into a list for uniform processing
|
||||
|
|
|
|||
|
|
@ -240,14 +240,14 @@ def _to_elasticsearch_filter(standard_filters: Dict[str, List[str]]) -> Dict[str
|
|||
"""
|
||||
Converts standard Llama-index filters into a format compatible with Elasticsearch.
|
||||
|
||||
This function transforms dictionary-based filters, where each key represents a field and
|
||||
the value is a list of strings, into an Elasticsearch query structure. It supports both
|
||||
list values (interpreted as 'should' clauses for OR logic) and single values (interpreted
|
||||
This function transforms dictionary-based filters, where each key represents a field and
|
||||
the value is a list of strings, into an Elasticsearch query structure. It supports both
|
||||
list values (interpreted as 'should' clauses for OR logic) and single values (interpreted
|
||||
as 'must' clauses for AND logic).
|
||||
|
||||
Args:
|
||||
standard_filters (Dict[str, List[str]]): A dictionary containing filter criteria,
|
||||
where keys are field names and values are lists of strings or single string values
|
||||
standard_filters (Dict[str, List[str]]): A dictionary containing filter criteria,
|
||||
where keys are field names and values are lists of strings or single string values
|
||||
representing filter values.
|
||||
|
||||
Returns:
|
||||
|
|
@ -457,8 +457,8 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
|
||||
Args:
|
||||
nodes (List[BaseNode]): A list of node objects, each encapsulating an embedding.
|
||||
create_index_if_not_exists (bool, optional):
|
||||
A flag indicating whether to create the Elasticsearch index if it's not present.
|
||||
create_index_if_not_exists (bool, optional):
|
||||
A flag indicating whether to create the Elasticsearch index if it's not present.
|
||||
Defaults to True.
|
||||
|
||||
Returns:
|
||||
|
|
@ -467,7 +467,7 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
Raises:
|
||||
ImportError: If the 'elasticsearch[async]' Python package is not installed.
|
||||
BulkIndexError: If there is a failure during the asynchronous bulk indexing with AsyncElasticsearch.
|
||||
|
||||
|
||||
Note:
|
||||
This method delegates the actual operation to the `sync_add` method.
|
||||
"""
|
||||
|
|
@ -482,16 +482,16 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
) -> List[str]:
|
||||
"""
|
||||
Asynchronously adds a list of nodes, each containing an embedding, to the Elasticsearch index.
|
||||
|
||||
This method processes each node to extract its ID, embedding, text content, and metadata,
|
||||
preparing them for batch insertion into the index. It ensures the index is created if not present
|
||||
|
||||
This method processes each node to extract its ID, embedding, text content, and metadata,
|
||||
preparing them for batch insertion into the index. It ensures the index is created if not present
|
||||
and respects the dimensionality of the embeddings for consistency.
|
||||
|
||||
Args:
|
||||
nodes (List[BaseNode]): A list of node objects, each encapsulating an embedding.
|
||||
create_index_if_not_exists (bool, optional): A flag indicating whether to create the Elasticsearch
|
||||
create_index_if_not_exists (bool, optional): A flag indicating whether to create the Elasticsearch
|
||||
index if it does not already exist. Defaults to True.
|
||||
**add_kwargs (Any): Additional keyword arguments passed to the underlying add_texts method
|
||||
**add_kwargs (Any): Additional keyword arguments passed to the underlying add_texts method
|
||||
for customization during the indexing process.
|
||||
|
||||
Returns:
|
||||
|
|
@ -533,21 +533,21 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
def delete(self, ref_doc_id: str, **delete_kwargs: Any) -> None:
|
||||
"""
|
||||
Deletes a node from the Elasticsearch index using the provided reference document ID.
|
||||
|
||||
|
||||
Optionally, extra keyword arguments can be supplied to customize the deletion behavior,
|
||||
which are passed directly to Elasticsearch's `delete_by_query` operation.
|
||||
|
||||
|
||||
Args:
|
||||
ref_doc_id (str): The unique identifier of the node/document to be deleted.
|
||||
delete_kwargs (Any): Additional keyword arguments for Elasticsearch's
|
||||
`delete_by_query`. These might include query filters,
|
||||
delete_kwargs (Any): Additional keyword arguments for Elasticsearch's
|
||||
`delete_by_query`. These might include query filters,
|
||||
timeouts, or other operational configurations.
|
||||
|
||||
|
||||
Raises:
|
||||
Exception: If the deletion operation via Elasticsearch's `delete_by_query` fails.
|
||||
|
||||
|
||||
Note:
|
||||
This method internally calls a synchronous delete method (`sync_delete`)
|
||||
This method internally calls a synchronous delete method (`sync_delete`)
|
||||
to execute the deletion operation against Elasticsearch.
|
||||
"""
|
||||
return self.sync_delete(ref_doc_id, **delete_kwargs)
|
||||
|
|
@ -558,13 +558,13 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
|
||||
Args:
|
||||
ref_doc_id (str): The unique identifier of the node/document to be deleted.
|
||||
delete_kwargs (Any): Optional keyword arguments to be passed
|
||||
to the delete_by_query operation of AsyncElasticsearch,
|
||||
delete_kwargs (Any): Optional keyword arguments to be passed
|
||||
to the delete_by_query operation of AsyncElasticsearch,
|
||||
allowing for additional customization of the deletion process.
|
||||
|
||||
Raises:
|
||||
Exception: If the deletion operation via AsyncElasticsearch's delete_by_query fails.
|
||||
|
||||
|
||||
Note:
|
||||
The function directly uses '_id' field to match the document for deletion instead of 'metadata.ref_doc_id',
|
||||
ensuring targeted removal based on the document's unique identifier within Elasticsearch.
|
||||
|
|
@ -583,17 +583,17 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
**kwargs: Any,
|
||||
) -> VectorStoreQueryResult:
|
||||
"""
|
||||
Executes a query against the Elasticsearch index to retrieve the top k most similar nodes
|
||||
based on the input query embedding. Supports customization of the query process and
|
||||
Executes a query against the Elasticsearch index to retrieve the top k most similar nodes
|
||||
based on the input query embedding. Supports customization of the query process and
|
||||
application of Elasticsearch filters.
|
||||
|
||||
Args:
|
||||
query (VectorStoreQuery): The query containing the embedding and other parameters.
|
||||
custom_query (Callable[[Dict, Union[VectorStoreQuery, None]], Dict], optional):
|
||||
An optional custom function to modify the Elasticsearch query body, allowing for
|
||||
custom_query (Callable[[Dict, Union[VectorStoreQuery, None]], Dict], optional):
|
||||
An optional custom function to modify the Elasticsearch query body, allowing for
|
||||
additional query parameters or logic. Defaults to None.
|
||||
es_filter (Optional[List[Dict]], optional): An optional Elasticsearch filter list to
|
||||
apply to the query. If a filter is directly included in the `query`, this argument
|
||||
es_filter (Optional[List[Dict]], optional): An optional Elasticsearch filter list to
|
||||
apply to the query. If a filter is directly included in the `query`, this argument
|
||||
will not be used. Defaults to None.
|
||||
**kwargs (Any): Additional keyword arguments that might be used in the query process.
|
||||
|
||||
|
|
@ -616,20 +616,20 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
fields: List[str] = [],
|
||||
) -> VectorStoreQueryResult:
|
||||
"""
|
||||
Asynchronously queries the Elasticsearch index for the top k most similar nodes
|
||||
based on the provided query embedding. Supports custom query modifications
|
||||
Asynchronously queries the Elasticsearch index for the top k most similar nodes
|
||||
based on the provided query embedding. Supports custom query modifications
|
||||
and application of Elasticsearch filters.
|
||||
|
||||
Args:
|
||||
query (VectorStoreQuery): The query containing the embedding and other details.
|
||||
custom_query (Callable[[Dict, Union[VectorStoreQuery, None]], Dict], optional):
|
||||
custom_query (Callable[[Dict, Union[VectorStoreQuery, None]], Dict], optional):
|
||||
A custom function to modify the Elasticsearch query body. Defaults to None.
|
||||
es_filter (List[Dict], optional): Additional filters to apply during the query.
|
||||
es_filter (List[Dict], optional): Additional filters to apply during the query.
|
||||
If filters are present in the query, these filters will not be used. Defaults to None.
|
||||
fields (List[str], optional): .
|
||||
|
||||
Returns:
|
||||
VectorStoreQueryResult: The result of the query, including nodes, their IDs,
|
||||
VectorStoreQueryResult: The result of the query, including nodes, their IDs,
|
||||
and similarity scores.
|
||||
|
||||
Raises:
|
||||
|
|
@ -701,7 +701,7 @@ class SyncElasticsearchStore(BasePydanticVectorStore):
|
|||
isinstance(self.retrieval_strategy, AsyncDenseVectorStrategy)
|
||||
and self.retrieval_strategy.hybrid
|
||||
):
|
||||
total_rank = sum(top_k_scores)
|
||||
# total_rank = sum(top_k_scores)
|
||||
top_k_scores = [rank for rank in top_k_scores]
|
||||
# top_k_scores = [(total_rank - rank) / total_rank for rank in top_k_scores]
|
||||
# top_k_scores = [total_rank - rank / total_rank for rank in top_k_scores]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from memoryscope.enumeration.language_enum import LanguageEnum
|
|||
class DatetimeHandler(object):
|
||||
"""
|
||||
Handles operations related to datetime such as parsing, extraction, and formatting,
|
||||
with support for both Chinese and English contexts including weekday names and
|
||||
with support for both Chinese and English contexts including weekday names and
|
||||
specialized text parsing for date components.
|
||||
"""
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ class DatetimeHandler(object):
|
|||
of a timestamp. If no argument is provided, the current time is used.
|
||||
|
||||
Args:
|
||||
dt (datetime.datetime | str | int | float, optional):
|
||||
dt (datetime.datetime | str | int | float, optional):
|
||||
The datetime to be handled. Can be a datetime object, a timestamp string, or a numeric timestamp.
|
||||
Defaults to None, which sets the instance to the current datetime.
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class DatetimeHandler(object):
|
|||
including language-specific weekday representation.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary with keys representing date and time parts such as 'year', 'month',
|
||||
dict: A dictionary with keys representing date and time parts such as 'year', 'month',
|
||||
'day', 'hour', 'minute', 'second', 'week', and 'weekday' with respective values.
|
||||
The 'weekday' value is translated based on the current language context.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class Logger(logging.Logger):
|
|||
|
||||
def _add_stream_handler(self):
|
||||
"""
|
||||
Adds a stream handler to the logger for console output. The handler is configured
|
||||
Adds a stream handler to the logger for console output. The handler is configured
|
||||
with the logger's formatter and set to use UTF-8 encoding.
|
||||
"""
|
||||
stream_handler = logging.StreamHandler()
|
||||
|
|
@ -162,7 +162,7 @@ class Logger(logging.Logger):
|
|||
Retrieves or creates a logger instance with the specified name and configurations.
|
||||
|
||||
If no name is provided, it defaults to the first registered logger's name or 'default' if none exist.
|
||||
This method ensures that only one logger instance exists per name by reusing existing instances
|
||||
This method ensures that only one logger instance exists per name by reusing existing instances
|
||||
stored in `LOGGER_DICT`.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from memoryscope.enumeration.language_enum import LanguageEnum
|
|||
|
||||
class PromptHandler(object):
|
||||
"""
|
||||
The `PromptHandler` class manages prompt messages by loading them from YAML or JSON files and dictionaries,
|
||||
The `PromptHandler` class manages prompt messages by loading them from YAML or JSON files and dictionaries,
|
||||
supporting language selection based on a context, and providing dictionary-like access to the prompt messages.
|
||||
"""
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class PromptHandler(object):
|
|||
@staticmethod
|
||||
def file_path_completion(file_path: str, raise_exception: bool = True) -> str:
|
||||
"""
|
||||
Attempts to complete the given file path by appending either a `.yaml` or `.json` extension
|
||||
Attempts to complete the given file path by appending either a `.yaml` or `.json` extension
|
||||
based on the existence of the respective file. If neither exists, an exception is raised.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ class Registry(object):
|
|||
|
||||
def register(self, module_name: str = None, module: Any = None):
|
||||
"""
|
||||
Registers module in the registry in a single call.
|
||||
Registers module in the registry in a single call.
|
||||
|
||||
Args:
|
||||
module_name (str): The name of module to be registered.
|
||||
module_name (str): The name of module to be registered.
|
||||
module (List[Any] | Dict[str, Any]): The module to be registered.
|
||||
|
||||
Raises:
|
||||
|
|
|
|||
|
|
@ -52,16 +52,16 @@ def init_instance_by_config(config: dict, default_class_dir: str = "memoryscope"
|
|||
"""
|
||||
Initialize an instance of a class specified in the configuration dictionary.
|
||||
|
||||
This function dynamically imports a class from a module path, allowing for
|
||||
user-defined classes or default paths. It supports adding a suffix to the
|
||||
class name, merging additional keyword arguments with the config, and handling
|
||||
This function dynamically imports a class from a module path, allowing for
|
||||
user-defined classes or default paths. It supports adding a suffix to the
|
||||
class name, merging additional keyword arguments with the config, and handling
|
||||
nested module paths.
|
||||
|
||||
Args:
|
||||
config (dict): A dictionary containing the configuration, including
|
||||
config (dict): A dictionary containing the configuration, including
|
||||
the 'class' key that specifies the class's module path.
|
||||
default_class_dir (str, optional): The default module path prefix
|
||||
to use if not explicitly defined in
|
||||
default_class_dir (str, optional): The default module path prefix
|
||||
to use if not explicitly defined in
|
||||
'config'. Defaults to "memory_scope".
|
||||
**kwargs: Additional keyword arguments to pass to the class constructor.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ contra_repeat_few_shot:
|
|||
5 陈伟业是{user_name}的领导,是银行分行行长
|
||||
6 {user_name}喜欢吃西瓜
|
||||
7 {user_name}喜欢吃苹果
|
||||
|
||||
|
||||
思考:第1句不会存在与前面序号句子的矛盾或者完全重复。
|
||||
判断:<1> <无>
|
||||
思考:第2句中所有信息都被前面序号中第1句的信息完全包含。
|
||||
|
|
@ -43,7 +43,7 @@ contra_repeat_few_shot:
|
|||
判断:<6> <无>
|
||||
思考:第7句也表达了{user_name}的水果偏好,喜欢吃桃子,和前面序号中的第6句不冲突,喜好可以同时存在。
|
||||
判断:<7> <无>
|
||||
|
||||
|
||||
示例2
|
||||
句子:
|
||||
1 {user_name}的孩子成绩不太好。
|
||||
|
|
@ -52,7 +52,7 @@ contra_repeat_few_shot:
|
|||
4 {user_name}的父亲生日在2024年5月1日。
|
||||
5 {user_name}很喜欢和同班同学打篮球。
|
||||
6 {user_name}喜欢打篮球。
|
||||
|
||||
|
||||
思考:第1句不会存在与前面序号句子的矛盾或者完全重复。
|
||||
判断:<1> <无>
|
||||
思考:第2句与前面序号句子既不矛盾也不重复。
|
||||
|
|
@ -76,7 +76,7 @@ contra_repeat_few_shot:
|
|||
5 Charles is {user_name}'s supervisor and the branch manager of a bank.
|
||||
5 {user_name} loves playing basketball with classmates.
|
||||
6 {user_name} likes playing basketball.
|
||||
|
||||
|
||||
Thought: The first sentence does not have any contradictions or complete repetitions with the previously numbered sentences.
|
||||
Judgment: <1> <None>
|
||||
Thought: All information in the second sentence is completely contained within the information of the first sentence.
|
||||
|
|
@ -91,7 +91,7 @@ contra_repeat_few_shot:
|
|||
Judgment: <6> <None>
|
||||
Thought: Sentence 7 also expresses {user_name}'s fruit preference, liking to eat apples; it does not conflict with sentence 6, and both preferences can coexist.
|
||||
Judgment: <7> <None>
|
||||
|
||||
|
||||
Example 2
|
||||
Sentences:
|
||||
1 {user_name}'s child does not perform well academically.
|
||||
|
|
@ -100,7 +100,7 @@ contra_repeat_few_shot:
|
|||
4 {user_name}'s father's birthday is on May 1, 2024.
|
||||
5 {user_name} loves playing basketball with classmates.
|
||||
6 {user_name} likes playing basketball.
|
||||
|
||||
|
||||
Thought: The first sentence does not have any contradictions or complete repetitions with the previously numbered sentences.
|
||||
Judgment: <1> <None>
|
||||
Thought: The second sentence neither contradicts nor repeats any of the previously numbered sentences.
|
||||
|
|
@ -123,4 +123,4 @@ contra_repeat_user_query:
|
|||
|
||||
en: |
|
||||
Sentences:
|
||||
{user_query}
|
||||
{user_query}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ get_observation_with_time_few_shot:
|
|||
2 2022年5月2日周二17点 {user_name}:公元1400年至1550年中国历史大事表。
|
||||
3 2022年5月3日周二18点 {user_name}:能给我整理一张如何使用大模型的技巧列表吗,要求内容尽量精简。
|
||||
4 2022年7月3日周四12点 {user_name}:上上个月我办了游泳卡。
|
||||
|
||||
|
||||
思考:从第1句可以得知张三是{user_name}的同事,这是关于{user_name}的人际关系的重要信息。其余信息重要性不足。{user_name}信息不涉及时间。
|
||||
信息:<1> <> <张三是{user_name}的同事。> <张三, 同事>
|
||||
思考:第2句是{user_name}提出的要求,没有明确提及{user_name}个人信息。
|
||||
|
|
@ -45,8 +45,8 @@ get_observation_with_time_few_shot:
|
|||
信息:<3> <> <无> <>
|
||||
思考:从第4句可以得出{user_name}上上个月办了游泳卡。{user_name}信息涉及时间,结合对话时间为2022年7月,推断{user_name}在2022年5月{user_name}办了游泳卡。
|
||||
信息:<4> <2022年5月> <{user_name}在2022年5月办了游泳卡。> <游泳卡>
|
||||
|
||||
|
||||
|
||||
|
||||
示例2:
|
||||
{user_name}句子:
|
||||
1 2020年1月4日周日10点 {user_name}:我花5000元买了100股海天味业。
|
||||
|
|
@ -54,7 +54,7 @@ get_observation_with_time_few_shot:
|
|||
3 2020年1月4日周日10点 {user_name}:我花50000元买了100股阿里巴巴股票。
|
||||
4 2021年6月2日周四23点 {user_name}:谢啦。我中午在公司附近吃,帮我推荐一家阿里巴巴徐汇滨江园区附近的餐厅吧。
|
||||
5 2021年7月9日周六11点 {user_name}:两个坏消息,我打羽毛球把拍子打断线了。。。然后我去我朋友家撸猫,结果我猫毛过敏,今天疯狂打喷嚏。。。
|
||||
|
||||
|
||||
思考:从第1句可以得知{user_name}购买了海天味业股票,购买数量为100股,购买金额为5000元,这是关于{user_name}的投资决策的重要信息。{user_name}信息不涉及时间。
|
||||
信息:<1> <> <{user_name}购买了海天味业股票,购买数量为100股,购买金额为5000元。> <海天味业, 股票>
|
||||
思考:从第2句可以得知{user_name}与妻子的结婚纪念日是明天,这是关于{user_name}重要纪念日的信息。其余信息重要性不足。{user_name}信息涉及时间,结合对话时间为2023年4月27日,
|
||||
|
|
@ -66,8 +66,8 @@ get_observation_with_time_few_shot:
|
|||
信息:<4> <> <{user_name}在阿里巴巴徐汇滨江园区工作。> <阿里巴巴, 徐汇滨江园区, 工作>
|
||||
思考:从第5句可以得知{user_name}前天打羽毛球时把球拍打断了线,但这不是重要的信息。还可以得知{user_name}对猫毛过敏,这是关于{user_name}的健康的重要信息。{user_name}信息不涉及时间。
|
||||
信息:<5> <> <{user_name}对猫毛过敏。> <猫毛, 过敏>
|
||||
|
||||
|
||||
|
||||
|
||||
示例3:
|
||||
{user_name}句子:
|
||||
1 2023年6月30日周五15点 {user_name}:上个月我和家人一起去杭州旅游,景色很不错。
|
||||
|
|
@ -75,7 +75,7 @@ get_observation_with_time_few_shot:
|
|||
3 2020年7月3日周四11点 {user_name}:提醒我下周一去体检。
|
||||
4 2023年5月21日周六14点 {user_name}:有人说兴趣是最好的老师,也建议兴趣和职业联系起来,但我发现喜欢打篮球的人很多,但靠打篮球成职业的稀少,赚钱的更少,此外,怎么分辨兴趣和喜欢
|
||||
5 2018年3月6日周四19点 {user_name}:李增杰:这个是星座蛙设,但是我是处女座的,我妈感觉因为我的不正常,我妈不让我看了\n雌猴摸了摸李增杰的头,这样啊\n雌猴打开了哔哩哔哩看了看\n雌猴:要不换个设吧,我听你未来的你说,有一个叫难忘的朱古力232这个人,他弄的设是Windows设\n这是剧本1,剧本2未完待续
|
||||
|
||||
|
||||
思考:从第1句可以得知{user_name}和家人上个月去杭州旅游了,这是关于{user_name}的经历的重要信息。其余信息重要性不足。{user_name}信息涉及时间,结合对话时间为2023年6月推断{user_name}和家人2023年5月去杭州旅游了。
|
||||
信息:<1> <2023年5月> <{user_name}和家人2023年5月去杭州旅游了。> <家人, 杭州, 旅游>
|
||||
思考:从第2句可以得知{user_name}的生日是昨天,这是关于{user_name}重要纪念日的信息。其余信息重要性不足。{user_name}信息涉及时间,结合对话时间为2023年7月2日,
|
||||
|
|
@ -95,7 +95,7 @@ get_observation_with_time_few_shot:
|
|||
2 May 2, 2022, Tuesday, at 17 {user_name}: Chronology of major events in Chinese history from 1400 to 1550 AD.
|
||||
3 May 3, 2022, Tuesday, at 18 {user_name}: Can you compile a list of tips on how to use large models for me, and try to keep the content concise?
|
||||
4 July 3, 2022, Thursday, at 12 {user_name}: I got a swimming pass two months ago.
|
||||
|
||||
|
||||
Thought: From the first sentence, it can be inferred that Jason is {user_name}'s colleague, which is important information about {user_name}'s interpersonal relationships. The remaining information is of insufficient importance. {user_name}'s information does not involve time.
|
||||
Information: <1> <> <Zhang San is {user_name}'s colleague> <Zhang San, colleague>
|
||||
Thought: The second sentence is a request made by {user_name}, with no clear mention of {user_name}'s personal information.
|
||||
|
|
@ -104,7 +104,7 @@ get_observation_with_time_few_shot:
|
|||
Information: <3> <> <none> <>
|
||||
Thought: From the fourth sentence, it can be inferred that {user_name} got a swimming pass two months ago. {user_name}'s information involves time. Combining it with the conversation time of July 2022, it can be inferred that {user_name} got the swimming pass in May 2022.
|
||||
Information: <4> <May 2022> <{user_name} got a swimming pass in May 2022> <swimming pass>
|
||||
|
||||
|
||||
Example 2:
|
||||
{user_name} sentences:
|
||||
1 January 4, 2020, Sunday, at 10 {user_name}: I spent $5000 to buy 100 shares of General Motors.
|
||||
|
|
@ -112,7 +112,7 @@ get_observation_with_time_few_shot:
|
|||
3 January 4, 2020, Sunday, at 10 {user_name}: I spent $50000 to buy 100 shares of Alibaba.
|
||||
4 June 2, 2021, Thursday, at 23 {user_name}: Thanks. I'm having lunch near the company at noon; can you recommend a restaurant near Alibaba Xuhui Riverside Campus for me?
|
||||
5 July 9, 2021, Saturday, at 11 {user_name}: Two pieces of bad news: I broke my badminton racket while playing... Then I went to my friend's house to pet the cat and ended up having an allergic reaction to the cat fur, sneezing like crazy today...
|
||||
|
||||
|
||||
Thought: From the first sentence, it can be inferred that {user_name} bought 100 shares of General Motors stock for $5000. This is important information about {user_name}'s investment decision. {user_name}'s information does not involve time.
|
||||
Information: <1> <> <{user_name} bought 100 shares of General Motors stock for $5000> <General Motors, stock>
|
||||
Thought: From the second sentence, it can be inferred that {user_name}'s wedding anniversary with his wife is tomorrow, which is important information about {user_name}'s significant dates. The remaining information is of insufficient importance. {user_name}'s information involves time. Combining it with the conversation date of April 27, 2023, and knowing that the anniversary is a recurring date, it can be inferred that {user_name}'s wedding anniversary is on April 28th each year.
|
||||
|
|
@ -123,8 +123,8 @@ get_observation_with_time_few_shot:
|
|||
Information: <4> <> <{user_name} works at Alibaba Xuhui Riverside Campus> <Alibaba, Xuhui Riverside Campus, job>
|
||||
Thought: From the fifth sentence, it can be inferred that {user_name} broke their badminton racket the other day while playing, but this is not important information. It can also be inferred that {user_name} is allergic to cat fur, which is important information about {user_name}'s health. {user_name}'s information does not involve time.
|
||||
Information: <5> <> <{user_name} is allergic to cat fur> <cat fur, allergy>
|
||||
|
||||
|
||||
|
||||
|
||||
Example 3:
|
||||
{user_name} sentences:
|
||||
1 June 30, 2023, Friday, at 15 {user_name}: Last month, my family and I went to San Jose for a trip. The scenery was very nice.
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class GetObservationWorker(MemoryBaseWorker):
|
|||
"""
|
||||
dt_handler = DatetimeHandler(dt=message.time_created)
|
||||
|
||||
# buidl meta data
|
||||
# build meta data
|
||||
meta_data = {
|
||||
MemoryTypeEnum.CONVERSATION.value: message.content,
|
||||
TIME_INFER: time_infer,
|
||||
|
|
@ -111,7 +111,7 @@ class GetObservationWorker(MemoryBaseWorker):
|
|||
|
||||
def _run(self):
|
||||
"""
|
||||
Processes chat messages to extract observations, inferring timestamps and content relevance,
|
||||
Processes chat messages to extract observations, inferring timestamps and content relevance,
|
||||
and stores the extracted information as MemoryNode objects within the conversation memory.
|
||||
|
||||
Steps:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ get_observation_few_shot:
|
|||
信息:<5> <> <{user_name}购买了海天味业股票,购买数量为100股,购买金额为5000元。> <海天味业, 股票>
|
||||
思考:第6句含有的信息与第1句相似,可以得知{user_name}购买了阿里巴巴股票。
|
||||
信息:<6> <> <{user_name}购买了阿里巴巴股票,购买数量为100股,购买金额为50000元。> <阿里巴巴, 股票>
|
||||
|
||||
|
||||
示例2:
|
||||
{user_name}句子:
|
||||
1 {user_name}:帮我写一段给同事张三女儿三岁生日的祝福语。
|
||||
|
|
@ -58,7 +58,7 @@ get_observation_few_shot:
|
|||
信息:<4> <> <无> <>
|
||||
思考:从第5句可以得知{user_name}在阿里巴巴徐汇滨江园区工作,这是关于{user_name}的工作地点的重要信息。
|
||||
信息:<5> <> <{user_name}在阿里巴巴徐汇滨江园区工作。> <阿里巴巴, 徐汇滨江园区, 工作>
|
||||
|
||||
|
||||
示例3:
|
||||
{user_name}句子:
|
||||
1 {user_name}:我想买辆新能源汽车,有什么推荐吗?
|
||||
|
|
@ -79,7 +79,7 @@ get_observation_few_shot:
|
|||
信息:<5> <> <{user_name}购买了海天味业股票,购买数量为100股,购买金额为5000元。> <海天味业, 股票>
|
||||
思考:第6句是{user_name}创作的剧本内容,无法提取{user_name}个人信息。
|
||||
信息:<6> <> <无> <>
|
||||
|
||||
|
||||
示例4:
|
||||
{user_name}句子:
|
||||
1 {user_name}:李子好酸啊,我不太喜欢吃。
|
||||
|
|
@ -108,11 +108,11 @@ get_observation_few_shot:
|
|||
Information: <3> <> <Repeat> <>
|
||||
Thought: From the fourth sentence, it can be inferred that {user_name} is a recent graduate, which is important information about {user_name}'s background. The remaining information is of insufficient importance.
|
||||
Information: <4> <> <{user_name} is a recent graduate> <recent graduate, student>
|
||||
Thought: It can be inferred that {user_name} bought 100 shares of General Motors stock for $5000. This is important information about {user_name}'s investment decision.
|
||||
Thought: It can be inferred that {user_name} bought 100 shares of General Motors stock for $5000. This is important information about {user_name}'s investment decision.
|
||||
Information: <5> <> <{user_name} bought 100 shares of General Motors stock for $5000> <General Motors, stock>
|
||||
Thought: The information of the sentence is similar to, but not a repetition of the sentence before. It can be deduced that {user_name} purchased Alibaba stock.
|
||||
Information: <6> <> <{user_name} purchased 100 shares of Alibaba stock for 50,000 RMB.> <Alibaba, stock>
|
||||
|
||||
|
||||
Example 2:
|
||||
{user_name} sentences:
|
||||
1 {user_name}: Please help me write a birthday greeting for my colleague Jason's daughter who is turning three.
|
||||
|
|
@ -130,7 +130,7 @@ get_observation_few_shot:
|
|||
Information: <4> <> <None> <>
|
||||
Thought: From the fifth sentence, it can be inferred that {user_name} works at Alibaba Xuhui Riverside Campus, which is important information about {user_name}'s workplace.
|
||||
Information: <5> <> <{user_name} works at Alibaba Xuhui Riverside Campus> <Alibaba, Xuhui Riverside Campus, work>
|
||||
|
||||
|
||||
Example 3:
|
||||
{user_name} sentences:
|
||||
1 {user_name}: I want to buy a new energy vehicle. Any recommendations?
|
||||
|
|
@ -161,4 +161,4 @@ get_observation_user_query:
|
|||
en: |
|
||||
{user_name} sentences:
|
||||
{user_query}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ get_reflection_subject_few_shot:
|
|||
过敏源
|
||||
技术方向
|
||||
工作岗位
|
||||
|
||||
|
||||
|
||||
|
||||
示例2
|
||||
信息:
|
||||
{user_name}想要了解如何使用torchvision库来可视化深度学习任务的进度信息。
|
||||
|
|
@ -59,7 +59,7 @@ get_reflection_subject_few_shot:
|
|||
游戏偏好
|
||||
运动计划
|
||||
技术方向
|
||||
|
||||
|
||||
示例3
|
||||
信息:
|
||||
{user_name}寻求推荐一个相关课程或网址以进行学习。
|
||||
|
|
@ -75,7 +75,7 @@ get_reflection_subject_few_shot:
|
|||
已有{user_name}属性:
|
||||
新增{user_name}属性:
|
||||
朋友关系
|
||||
|
||||
|
||||
示例4
|
||||
信息:
|
||||
{user_name}在寻求有关推拿按摩手法的教程或相关网站推荐。
|
||||
|
|
@ -111,7 +111,7 @@ get_reflection_subject_few_shot:
|
|||
Allergens
|
||||
Technical direction
|
||||
Job position
|
||||
|
||||
|
||||
Example 2
|
||||
Information:
|
||||
{user_name} wants to learn how to use the torchvision library to visualize progress information for deep learning tasks.
|
||||
|
|
@ -136,7 +136,7 @@ get_reflection_subject_few_shot:
|
|||
Game preferences
|
||||
Exercise plan
|
||||
Technical direction
|
||||
|
||||
|
||||
Example 3
|
||||
Information:
|
||||
{user_name} is seeking a recommendation for a related course or website for learning.
|
||||
|
|
@ -152,7 +152,7 @@ get_reflection_subject_few_shot:
|
|||
Existing {user_name} attributes:
|
||||
New {user_name} attributes:
|
||||
Friend relationships
|
||||
|
||||
|
||||
Example 4
|
||||
Information:
|
||||
{user_name} is seeking tutorials or website recommendations for massage techniques.
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ from memoryscope.scheme.message import Message
|
|||
|
||||
class InfoFilterWorker(MemoryBaseWorker):
|
||||
"""
|
||||
This worker filters and modifies the chat message history (`self.chat_messages`) by retaining only the messages
|
||||
that include significant information. It then constructs a prompt from these filtered messages, utilizes an AI
|
||||
model to process this prompt, parses the AI's generated response to allocate scores, and ultimately retains
|
||||
This worker filters and modifies the chat message history (`self.chat_messages`) by retaining only the messages
|
||||
that include significant information. It then constructs a prompt from these filtered messages, utilizes an AI
|
||||
model to process this prompt, parses the AI's generated response to allocate scores, and ultimately retains
|
||||
messages in `self.chat_messages` based on these assigned scores.
|
||||
"""
|
||||
FILE_PATH: str = __file__
|
||||
|
|
@ -26,7 +26,7 @@ class InfoFilterWorker(MemoryBaseWorker):
|
|||
Filters user messages in the chat, generates a prompt incorporating these messages,
|
||||
utilizes an LLM to rate the information score for each message,
|
||||
and updates `self.chat_messages` to only include messages with designated scores.
|
||||
|
||||
|
||||
This method executes the following steps:
|
||||
1. Filters out non-user messages and truncates long messages.
|
||||
2. Constructs a prompt with user messages for LLM input.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ info_filter_system:
|
|||
|
||||
en: |
|
||||
Task: Score the information about {user_name} contained in the given batch of {batch_size} sentences, with scores of 0, 1, 2, or 3.
|
||||
Note:
|
||||
Note:
|
||||
0 indicates no user information is included.
|
||||
1 indicates only hypothetical information about the user or fictitious content such as novels or scripts created by the user.
|
||||
2 indicates general information about the user, timely information, or information that requires inference.
|
||||
|
|
@ -32,21 +32,21 @@ info_filter_few_shot:
|
|||
4 {user_name}:我今天心情不好,可以安慰我一下吗?
|
||||
5 {user_name}:能给我整理一张如何使用大模型的技巧列表吗,要求内容尽量精简。
|
||||
6 {user_name}:记一下,明天下午3点提醒我去拿一下文件。
|
||||
|
||||
|
||||
思考:从第1句可以确定推断出张三是{user_name}同事这一重要信息。
|
||||
结果:<1> <3>
|
||||
思考:第2句不包含{user_name}信息。
|
||||
结果:<2> <0>
|
||||
思考:第3句不包含{user_name}信息。
|
||||
结果:<3> <0>
|
||||
结果:<3> <0>
|
||||
思考:从第4句可以得知{user_name}今天心情不好,是时效性信息。
|
||||
结果:<4> <2>
|
||||
结果:<4> <2>
|
||||
思考:从第5句可以猜测{user_name}对大模型感兴趣,是不确定的信息。
|
||||
结果:<5> <2>
|
||||
结果:<5> <2>
|
||||
思考:第6句是{user_name}要求记录的信息。
|
||||
结果:<6> <3>
|
||||
|
||||
|
||||
结果:<6> <3>
|
||||
|
||||
|
||||
示例2
|
||||
句子:
|
||||
1 {user_name}:我刚刚入职了阿里巴巴。
|
||||
|
|
@ -56,23 +56,23 @@ info_filter_few_shot:
|
|||
5 {user_name}:假如我要和一个女人准备要孩子,我作为男人,怎么保护女人和孩子以及怎么备孕确保精子质量高对后代好
|
||||
6 {user_name}:我和你一起出去玩,你会感觉开心吗?
|
||||
7 {user_name}:林浅,一位对未来充满好奇的年轻女孩,偶然间发现了这家能寄信给未来的邮局。出于对逝去祖父的怀念,她决定写下一封信,寄给五年后的自己,希望能收到祖父生前未说完的故事。五年期限将至,当她几乎忘记这段往事时,一封泛黄的回信悄然降临,不仅带来了祖父未完的冒险故事,还藏着一段关于勇气、爱与自我发现的深刻启示。续写成3000字小说。
|
||||
|
||||
|
||||
思考:从第1句可以确定得出{user_name}工作单位是阿里巴巴这一重要信息。
|
||||
结果:<1> <3>
|
||||
思考:从第2句可以猜测{user_name}近期露天睡觉,是不确定的信息。
|
||||
结果:<2> <2>
|
||||
思考:第3句不包含{user_name}信息。
|
||||
结果:<3> <0>
|
||||
结果:<3> <0>
|
||||
思考:第4句不包含{user_name}信息。
|
||||
结果:<4> <0>
|
||||
结果:<4> <0>
|
||||
思考:第5句虽然有假设成分,但可以确定推断出{user_name}是男性这一重要信息。
|
||||
结果:<5> <3>
|
||||
结果:<5> <3>
|
||||
思考:第6句是{user_name}假设的信息。
|
||||
结果:<6> <1>
|
||||
思考:第7句是{user_name}虚构的内容。
|
||||
结果:<7> <1>
|
||||
|
||||
|
||||
|
||||
|
||||
示例3
|
||||
句子:
|
||||
1 {user_name}:你的妈妈患有焦虑症,怎么安慰和开导她?
|
||||
|
|
@ -81,19 +81,19 @@ info_filter_few_shot:
|
|||
4 {user_name}:篮球明星有哪些?
|
||||
5 {user_name}:李增杰:这个是星座蛙设,但是我是处女座的,我妈感觉因为我的不正常,我妈不让我看了\n雌猴摸了摸李增杰的头,这样啊\n雌猴打开了哔哩哔哩看了看\n雌猴:要不换个设吧,我听你未来的你说,有一个叫难忘的朱古力232这个人,他弄的设是Windows设\n这是剧本1,剧本2未完待续
|
||||
6 {user_name}:我想知道昨天我们聊了什么?
|
||||
|
||||
|
||||
思考:第1句是{user_name}假设的信息。
|
||||
结果:<1> <1>
|
||||
思考:第2句信息不明,可能是{user_name}假设的信息。
|
||||
结果:<2> <1>
|
||||
思考:从第3句可以确定得出{user_name}喜欢打篮球,身体好这两个重要信息。
|
||||
结果:<3> <3>
|
||||
结果:<3> <3>
|
||||
思考:第4句不包含{user_name}信息。
|
||||
结果:<4> <0>
|
||||
结果:<4> <0>
|
||||
思考:第5句是{user_name}虚构的内容。
|
||||
结果:<5> <1>
|
||||
结果:<5> <1>
|
||||
思考:第6句是{user_name}的疑问句,没有包含信息。
|
||||
结果:<6> <0>
|
||||
结果:<6> <0>
|
||||
|
||||
en: |
|
||||
Example 1
|
||||
|
|
@ -104,7 +104,7 @@ info_filter_few_shot:
|
|||
4 {user_name}: I'm feeling down today. Can you comfort me a bit?
|
||||
5 {user_name}: Can you compile a list of tips on how to use large models for me, and try to keep the content concise?
|
||||
6 {user_name}: Note this down: remind me tomorrow at 3 PM to pick up the documents.
|
||||
|
||||
|
||||
Thought: From the first sentence, it can be inferred that Zhang San is a colleague of {user_name}, which is important information.
|
||||
Result: <1> <3>
|
||||
Thought: The second sentence does not contain information about {user_name}.
|
||||
|
|
@ -117,7 +117,7 @@ info_filter_few_shot:
|
|||
Result: <5> <2>
|
||||
Thought: The sixth sentence contains information that {user_name} requested to be recorded.
|
||||
Result: <6> <3>
|
||||
|
||||
|
||||
Example 2
|
||||
Sentences:
|
||||
1 {user_name}: I've just joined Google.
|
||||
|
|
@ -127,7 +127,7 @@ info_filter_few_shot:
|
|||
5 {user_name}: If I am planning to have a child with a woman, as a man, how can I protect the woman and the baby and how can I prepare to ensure high sperm quality for the benefit of the offspring?
|
||||
6 {user_name}: If we go out to play together, would you feel happy?
|
||||
7 {user_name}: Rose, a young girl full of curiosity about the future, accidentally discovered this post office that can send letters to the future. Out of nostalgia for her late grandfather, she decided to write a letter to herself five years in the future, hoping to receive the unfinished stories of her grandfather. As the five-year deadline approached, when she had almost forgotten about this event, a yellowed reply quietly arrived, bringing not only her grandfather's unfinished adventure story but also a profound revelation about courage, love, and self-discovery. Continue writing this into a 3000-word novel.
|
||||
|
||||
|
||||
Thought: From the first sentence, it can be determined that {user_name} works at Alibaba, which is important information.
|
||||
Result: <1> <3>
|
||||
Thought: The second sentence suggests that {user_name} might has been sleeping outdoors recently, which is uncertain information.
|
||||
|
|
@ -142,7 +142,7 @@ info_filter_few_shot:
|
|||
Result: <6> <1>
|
||||
Thought: The seventh sentence contains only fictitious content from {user_name}.
|
||||
Result: <7> <1>
|
||||
|
||||
|
||||
Example 3
|
||||
Sentences:
|
||||
1 {user_name}: Your mother is suffering from anxiety. How can you comfort and guide her?
|
||||
|
|
|
|||
|
|
@ -98,10 +98,10 @@ class LoadMemoryWorker(MemoryBaseWorker):
|
|||
def _run(self):
|
||||
"""
|
||||
Initiates multithread tasks to retrieve various types of memory data including
|
||||
not reflected, not updated, insights, and data from today. After submitting all tasks,
|
||||
not reflected, not updated, insights, and data from today. After submitting all tasks,
|
||||
it waits for their completion by calling `gather_thread_result`.
|
||||
|
||||
This method serves as the controller for data retrieval operations, enhancing efficiency
|
||||
|
||||
This method serves as the controller for data retrieval operations, enhancing efficiency
|
||||
by handling tasks concurrently.
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class LongContraRepeatWorker(MemoryBaseWorker):
|
|||
node (MemoryNode): The reference node used to find similar content in memory.
|
||||
|
||||
Returns:
|
||||
Tuple[MemoryNode, List[MemoryNode]]: A tuple containing the original node and a list of similar nodes
|
||||
Tuple[MemoryNode, List[MemoryNode]]: A tuple containing the original node and a list of similar nodes
|
||||
that passed the similarity threshold.
|
||||
"""
|
||||
filter_dict = {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ long_contra_repeat_few_shot:
|
|||
5 陈伟业是{user_name}的领导,是银行分行行长
|
||||
6 {user_name}喜欢吃西瓜
|
||||
7 {user_name}喜欢吃苹果
|
||||
|
||||
|
||||
思考:第1句不会存在与前面序号句子的矛盾或者完全重复。
|
||||
判断:<1> <无> <>
|
||||
思考:第2句中所有信息都被前面序号中第1句的信息完全包含。
|
||||
|
|
@ -42,7 +42,7 @@ long_contra_repeat_few_shot:
|
|||
判断:<6> <无> <>
|
||||
思考:第7句也表达了{user_name}的水果偏好,喜欢吃桃子,和前面序号中的第6句不冲突,喜好可以同时存在。
|
||||
判断:<7> <无> <>
|
||||
|
||||
|
||||
示例2
|
||||
句子:
|
||||
1 {user_name}的孩子成绩不太好。
|
||||
|
|
@ -51,7 +51,7 @@ long_contra_repeat_few_shot:
|
|||
4 {user_name}的父亲生日在2024年5月1日。
|
||||
5 {user_name}很喜欢和同班同学打篮球。
|
||||
6 {user_name}喜欢打篮球。
|
||||
|
||||
|
||||
思考:第1句不会存在与前面序号句子的矛盾或者完全重复。
|
||||
判断:<1> <无> <>
|
||||
思考:第2句与前面序号句子既不矛盾也不重复。
|
||||
|
|
@ -75,7 +75,7 @@ long_contra_repeat_few_shot:
|
|||
5 Charles is {user_name}'s supervisor and the branch manager of a bank.
|
||||
6. {user_name} likes to eat watermelon.
|
||||
7. {user_name} likes to eat apples.
|
||||
|
||||
|
||||
Thought: The first sentence does not have any contradictions or complete repetitions with the previously numbered sentences.
|
||||
Judgment: <1> <None> <>
|
||||
Thought: All information in the second sentence is completely contained within the information of the first sentence.
|
||||
|
|
@ -90,7 +90,7 @@ long_contra_repeat_few_shot:
|
|||
Judgment: <6> <None> <>
|
||||
Thought: Sentence 7 also expresses {user_name}'s fruit preference, liking to eat apples; it does not conflict with sentence 6, and both preferences can coexist.
|
||||
Judgment: <7> <None> <>
|
||||
|
||||
|
||||
Example 2
|
||||
Sentences:
|
||||
1 {user_name}'s child does not perform well academically.
|
||||
|
|
@ -99,7 +99,7 @@ long_contra_repeat_few_shot:
|
|||
4 {user_name}'s father's birthday is on May 1, 2024.
|
||||
5 {user_name} loves playing basketball with classmates.
|
||||
6 {user_name} likes playing basketball.
|
||||
|
||||
|
||||
Thought: The first sentence does not have any contradictions or complete repetitions with the previously numbered sentences.
|
||||
Judgment: <1> <None> <>
|
||||
Thought: The second sentence neither contradicts nor repeats any of the previously numbered sentences.
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ from memoryscope.scheme.memory_node import MemoryNode
|
|||
class UpdateInsightWorker(MemoryBaseWorker):
|
||||
"""
|
||||
This class is responsible for updating insight value in a memory system. It filters insight nodes
|
||||
based on their association with observed nodes, utilizes a ranking model to prioritize them,
|
||||
generates refreshed insights via an LLM, and manages node statuses and content updates,
|
||||
based on their association with observed nodes, utilizes a ranking model to prioritize them,
|
||||
generates refreshed insights via an LLM, and manages node statuses and content updates,
|
||||
incorporating features for concurrent execution and logging.
|
||||
"""
|
||||
FILE_PATH: str = __file__
|
||||
|
|
@ -188,9 +188,9 @@ class UpdateInsightWorker(MemoryBaseWorker):
|
|||
|
||||
def _run(self):
|
||||
"""
|
||||
Executes the main routine of the UpdateInsightWorker. This involves filtering and updating insight nodes
|
||||
based on their association with observed nodes. It processes nodes in batches, selects the top nodes
|
||||
according to a scoring mechanism, and then initiates tasks to update these insights using an LLM. Finally,
|
||||
Executes the main routine of the UpdateInsightWorker. This involves filtering and updating insight nodes
|
||||
based on their association with observed nodes. It processes nodes in batches, selects the top nodes
|
||||
according to a scoring mechanism, and then initiates tasks to update these insights using an LLM. Finally,
|
||||
it updates the status of processed nodes and gathers the results from all threads.
|
||||
|
||||
Steps include:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ update_insight_few_shot:
|
|||
已有信息:{user_name}所在地区: 杭州
|
||||
思考:从第一句句子可以得出{user_name}在成都。第二句句子没有直接透露{user_name}所在地信息,但与第一句句子{user_name}在成都的信息吻合。这与已有信息({user_name}在杭州)矛盾,输出更新的信息。
|
||||
{user_name}的资料:<成都>
|
||||
|
||||
|
||||
示例2:
|
||||
{user_name}最近养好了肠胃。
|
||||
{user_name}关注中医养生。
|
||||
|
|
@ -30,7 +30,7 @@ update_insight_few_shot:
|
|||
已有信息:{user_name}健康状况: 肠胃不好,高血压
|
||||
思考:从第一句句子可以得出{user_name}最近养好了肠胃,与已有信息矛盾,以新信息为准。第二句句子与{user_name}健康状况无关。整合已有信息和新信息得到{user_name}健康状况是肠胃健康,高血压。
|
||||
{user_name}的资料:<肠胃健康,高血压>
|
||||
|
||||
|
||||
示例3:
|
||||
{user_name}刚刚毕业,第一份工作是银行前台。
|
||||
{user_name}的理想工作是职业游戏选手。
|
||||
|
|
@ -38,14 +38,14 @@ update_insight_few_shot:
|
|||
已有信息:{user_name}职业:在招商银行工作
|
||||
思考:整合已有信息和第一句句子的信息可以得出{user_name}的现在的职业是招商银行前台。第二句句子说明了{user_name}的理想工作但并不是现在的职业。
|
||||
{user_name}的资料:<招商银行前台>
|
||||
|
||||
|
||||
示例4:
|
||||
{user_name}大学期间接触过优化算法的研究。
|
||||
类别:{user_name}学习专业
|
||||
已有信息:{user_name}学习专业:与人工智能相关
|
||||
思考:从句子可以得出{user_name}大学学习的专业与优化算法相关,这与已有信息({user_name}学习专业与人工智能相关)不矛盾,整合可以得出{user_name}大学学习的专业与人工智能和优化算法相关。
|
||||
{user_name}的资料:<与人工智能和优化算法相关>
|
||||
|
||||
|
||||
示例5:
|
||||
{user_name}单身。
|
||||
{user_name}受到一名18岁男生的追求,但不想接受又不想伤害他。
|
||||
|
|
@ -64,7 +64,7 @@ update_insight_few_shot:
|
|||
已有信息:{user_name}生日:1987年7月15日。
|
||||
思考:第一句句子中提及生日,但并不是用户的生日,无法得出用户生日信息。从第二句句子可以得出用户生日在7月15日,与已有信息不矛盾,整合可以得出用户生日是1987年7月15日。
|
||||
{user_name}的资料:<1987年7月15日>
|
||||
|
||||
|
||||
示例7:
|
||||
今天{user_name}和同学去打球了。
|
||||
明天{user_name}和女朋友一起去杭州旅游。
|
||||
|
|
@ -90,7 +90,7 @@ update_insight_few_shot:
|
|||
Existing information: {user_name}'s health status: Stomach issues, high blood pressure
|
||||
Thought: From the first sentence, it can be inferred that {user_name} recently recovered from stomach issues, which contradicts the existing information. Therefore, the new information should take precedence. The second sentence is not related to {user_name}'s health status. Integrating the existing information and the new information, we get that {user_name}'s health status is healthy stomach and high blood pressure.
|
||||
{user_name}'s profile: <Healthy stomach, high blood pressure>
|
||||
|
||||
|
||||
Example 3:
|
||||
{user_name} just graduated, and their first job is as a bank receptionist.
|
||||
{user_name}'s dream job is to be a professional gamer.
|
||||
|
|
@ -124,7 +124,7 @@ update_insight_few_shot:
|
|||
Existing Information: {user_name}'s Birthday: July 15, 1987.
|
||||
Thoughts: The first sentence mentions a birthday, but it is not the user's birthday, so it does not provide information about the user's birthday. From the second sentence, we know that the user's birthday is on July 15th, which is consistent with the existing information. We can conclude that the user's birthday is July 15, 1987.
|
||||
{user_name}'s profile: <July 15, 1987>
|
||||
|
||||
|
||||
Example 7:
|
||||
Today, {user_name} played basketball with classmates.
|
||||
Tomorrow, {user_name} is going to Hangzhou with his girlfriend.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from typing import List
|
||||
from typing import List, Dict
|
||||
|
||||
from memoryscope.constants.common_constants import RESULT
|
||||
from memoryscope.core.utils.datetime_handler import DatetimeHandler
|
||||
from memoryscope.core.worker.memory_base_worker import MemoryBaseWorker
|
||||
from memoryscope.enumeration.action_status_enum import ActionStatusEnum
|
||||
|
|
@ -109,4 +110,12 @@ class UpdateMemoryWorker(MemoryBaseWorker):
|
|||
if not hasattr(self, method):
|
||||
self.logger.info(f"method={method} is missing!")
|
||||
return
|
||||
self.memory_manager.update_memories(nodes=getattr(self, method)())
|
||||
|
||||
updated_nodes: Dict[str, List[MemoryNode]] = self.memory_manager.update_memories(nodes=getattr(self, method)())
|
||||
line = []
|
||||
i = 0
|
||||
for action, nodes in updated_nodes.items():
|
||||
for node in nodes:
|
||||
i += 1
|
||||
line.append(f"{i} {action} {node.content}")
|
||||
self.set_context(RESULT, "\n".join(line))
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class BaseWorker(metaclass=ABCMeta):
|
|||
RuntimeError: If called in multithread mode.
|
||||
"""
|
||||
if self.is_multi_thread:
|
||||
raise RuntimeError(f"async_task is not allowed in multi_thread condition")
|
||||
raise RuntimeError("async_task is not allowed in multi_thread condition")
|
||||
|
||||
self.async_task_list.append((fn, args, kwargs))
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ class BaseWorker(metaclass=ABCMeta):
|
|||
RuntimeError: If called in multithread mode.
|
||||
"""
|
||||
if self.is_multi_thread:
|
||||
raise RuntimeError(f"async_task is not allowed in multi_thread condition")
|
||||
raise RuntimeError("async_task is not allowed in multi_thread condition")
|
||||
|
||||
results = asyncio.run(self._async_gather())
|
||||
self.async_task_list.clear()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class DummyWorker(MemoryBaseWorker):
|
|||
"""
|
||||
Executes the dummy worker's run logic by logging workflow entry, capturing the current timestamp,
|
||||
file path, and setting the result context with details about the workflow execution.
|
||||
|
||||
|
||||
This method utilizes the BaseWorker's capabilities to interact with the workflow context.
|
||||
"""
|
||||
workflow_name = self.get_context(WORKFLOW_NAME)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ extract_time_system:
|
|||
回答的格式严格遵照示例中的已有格式规范。
|
||||
若语句不涉及时间则回答无。
|
||||
en: |
|
||||
Task: From the sentences and the time when they occurred, infer and extract the time periods indicated in the content of the sentences.
|
||||
Answer with the most complete time periods possible.
|
||||
The format of the answers must strictly adhere to the specifications in the examples provided.
|
||||
Task: From the sentences and the time when they occurred, infer and extract the time periods indicated in the content of the sentences.
|
||||
Answer with the most complete time periods possible.
|
||||
The format of the answers must strictly adhere to the specifications in the examples provided.
|
||||
If the sentence does not involve time, respond with "none."
|
||||
|
||||
|
||||
|
|
@ -25,43 +25,43 @@ extract_time_few_shot:
|
|||
时间:1992年8月20日,1992年第34周,周一,18时。
|
||||
回答:
|
||||
- 年:1990 - 月:4月
|
||||
|
||||
|
||||
示例2:
|
||||
句子:后天下午三点的会议记得参加。我在日历上仔细标注了这个重要的日子,提醒自己不要错过。会议将在公司会议室举行,这是一个讨论未来发展方向的重要机会。
|
||||
时间:2024年6月19日,2024年第25周,周二,13时。
|
||||
回答:
|
||||
- 年:2024 - 月:6月 - 日:21 - 时:15
|
||||
|
||||
|
||||
示例3:
|
||||
句子:下个月第一个周六去杭州玩。
|
||||
时间:2005年7月15日,2005年第28周,周六,0时。
|
||||
回答:
|
||||
- 年:2005 - 月:8月 - 周:31 - 星期几:周六
|
||||
|
||||
|
||||
示例4:
|
||||
句子:上周末我们去的那个小镇真是太美了。
|
||||
时间:1999年12月2日,1999年第48周,周二,8时。
|
||||
回答:
|
||||
- 年:1999 - 周:47 - 星期几:周六,周日
|
||||
|
||||
|
||||
示例5:
|
||||
句子:再过半小时就要宣讲了,记得准备材料。
|
||||
时间:2020年6月22日,2020年第25周,周一,9时。
|
||||
回答:
|
||||
- 年:2020 - 月:6月 - 日:22 - 时:10
|
||||
|
||||
|
||||
示例6:
|
||||
句子:10000米长跑比赛的开始时间是3分47秒前。
|
||||
时间:1987年2月17日,1987年第7周,周三,19时。
|
||||
回答:
|
||||
- 年:1987 - 月:2 - 日:17 - 时:19
|
||||
|
||||
|
||||
示例7:
|
||||
句子:上个月的这个时候我们还在筹备音乐会。每天都是忙碌而充实的日子,我们为音乐会的顺利举办而努力奋斗着。彩排、布景、节目安排,每一个细节都需要精心安排和准备。
|
||||
时间:1995年11月24日,1995年第48周,周二,17时。
|
||||
回答:
|
||||
- 年:1995 - 月:10 - 日:24
|
||||
|
||||
|
||||
示例8:
|
||||
句子:我的朋友非常喜欢运动,他认为运动有助于增强身体素质。
|
||||
时间:2015年1月23日,2015年第4周,周四,7时。
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class FuseRerankWorker(MemoryBaseWorker):
|
|||
def _run(self):
|
||||
"""
|
||||
Executes the reranking process on memory nodes considering their scores, types, and temporal relevance.
|
||||
|
||||
|
||||
This method performs the following steps:
|
||||
1. Retrieves extraction time data and a list of ranked memory nodes from the worker's context.
|
||||
2. Reranks nodes based on a combination of their original rank score, type,
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ print_template:
|
|||
========== {user_name}关于{target_name}的长期记忆 ==========
|
||||
----- 观察记忆 -----
|
||||
{observation_memory}
|
||||
|
||||
|
||||
----- 洞察记忆 -----
|
||||
{insight_memory}
|
||||
|
||||
|
||||
----- 过期记忆 -----
|
||||
{expired_memory}
|
||||
|
||||
|
|
@ -14,9 +14,9 @@ print_template:
|
|||
========== The {user_name}'s long-term memory about {target_name} ==========
|
||||
----- observation memory -----
|
||||
{observation_memory}
|
||||
|
||||
|
||||
----- insight memory -----
|
||||
{insight_memory}
|
||||
|
||||
|
||||
----- expired memory -----
|
||||
{expired_memory}
|
||||
|
|
@ -24,14 +24,14 @@ class RetrieveMemoryWorker(MemoryBaseWorker):
|
|||
@timer
|
||||
def retrieve_from_observation(self, query: str) -> List[MemoryNode]:
|
||||
"""
|
||||
Retrieves memory nodes from observation based on a query, considering active memories
|
||||
Retrieves memory nodes from observation based on a query, considering active memories
|
||||
with specific types. If the retrieval limit is not set, an empty list is returned.
|
||||
|
||||
Args:
|
||||
query (str): The query string used to filter and rank the memory nodes.
|
||||
|
||||
Returns:
|
||||
List[MemoryNode]: A list of MemoryNode objects that match the query criteria,
|
||||
List[MemoryNode]: A list of MemoryNode objects that match the query criteria,
|
||||
sorted by their relevance. Returns an empty list if no retrieval limit is configured.
|
||||
"""
|
||||
if not self.retrieve_obs_top_k:
|
||||
|
|
@ -107,7 +107,7 @@ class RetrieveMemoryWorker(MemoryBaseWorker):
|
|||
def _run(self):
|
||||
"""
|
||||
Executes the main retrieval for memories. It fetches the query from the context, initiates concurrent tasks
|
||||
to retrieve memories from observations, insights, and expired sources, collects the results, sorts them by
|
||||
to retrieve memories from observations, insights, and expired sources, collects the results, sorts them by
|
||||
similarity score, logs the details, and finally sets the retrieved memory nodes.
|
||||
|
||||
The method follows these steps:
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ from memoryscope.scheme.memory_node import MemoryNode
|
|||
|
||||
class SemanticRankWorker(MemoryBaseWorker):
|
||||
"""
|
||||
The `SemanticRankWorker` class processes queries by retrieving memory nodes,
|
||||
removing duplicates, ranking them based on semantic relevance using a model,
|
||||
assigning scores, sorting the nodes, and storing the ranked nodes back,
|
||||
The `SemanticRankWorker` class processes queries by retrieving memory nodes,
|
||||
removing duplicates, ranking them based on semantic relevance using a model,
|
||||
assigning scores, sorting the nodes, and storing the ranked nodes back,
|
||||
while logging relevant information.
|
||||
"""
|
||||
|
||||
|
|
@ -23,8 +23,8 @@ class SemanticRankWorker(MemoryBaseWorker):
|
|||
- Assigns scores to nodes.
|
||||
- Sorts nodes by score.
|
||||
- Saves the ranked nodes back with logging.
|
||||
|
||||
If no memory nodes are retrieved or if the ranking model fails,
|
||||
|
||||
If no memory nodes are retrieved or if the ranking model fails,
|
||||
appropriate warnings are logged.
|
||||
"""
|
||||
# query
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class MemoryBaseWorker(BaseWorker, metaclass=ABCMeta):
|
|||
wrt. the semantic similarities.
|
||||
**kwargs: Additional keyword arguments passed to the parent class initializer.
|
||||
|
||||
The constructor also initializes key attributes related to memory store, monitoring,
|
||||
The constructor also initializes key attributes related to memory store, monitoring,
|
||||
user and target identification, and a prompt handler, setting them up for later use.
|
||||
"""
|
||||
super(MemoryBaseWorker, self).__init__(**kwargs)
|
||||
|
|
@ -122,7 +122,7 @@ class MemoryBaseWorker(BaseWorker, metaclass=ABCMeta):
|
|||
@property
|
||||
def rank_model(self) -> BaseModel:
|
||||
"""
|
||||
Property to access the rank model. If the stored rank model is a string, it fetches the actual model instance
|
||||
Property to access the rank model. If the stored rank model is a string, it fetches the actual model instance
|
||||
from the global context's model dictionary before returning it.
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class MemoryManager(object):
|
|||
|
||||
Args:
|
||||
keys (str | List[str]): The key mapping to memory nodes.
|
||||
|
||||
|
||||
Returns:
|
||||
List[MemoryNode]: Memories mapped to the key.
|
||||
"""
|
||||
|
|
@ -150,7 +150,7 @@ class MemoryManager(object):
|
|||
if _id in id_list:
|
||||
id_list.remove(_id)
|
||||
|
||||
def update_memories(self, keys: str = "", nodes: MemoryNode | List[MemoryNode] = None):
|
||||
def update_memories(self, keys: str = "", nodes: MemoryNode | List[MemoryNode] = None) -> dict:
|
||||
"""
|
||||
Update the memories.
|
||||
|
||||
|
|
@ -166,9 +166,9 @@ class MemoryManager(object):
|
|||
update_memories.update({n.memory_id: n for n in nodes})
|
||||
|
||||
# Save collected nodes to memory store
|
||||
self._update_memories(list(update_memories.values()))
|
||||
return self._update_memories(list(update_memories.values()))
|
||||
|
||||
def _update_memories(self, nodes: List[MemoryNode]):
|
||||
def _update_memories(self, nodes: List[MemoryNode]) -> dict:
|
||||
"""
|
||||
Updates the memories based on their status:
|
||||
- New: Embeds and inserts the memory node.
|
||||
|
|
@ -180,9 +180,11 @@ class MemoryManager(object):
|
|||
Args:
|
||||
nodes (List[MemoryNode]): A single memory node or a list of memory nodes to be updated.
|
||||
"""
|
||||
if not nodes:
|
||||
return
|
||||
|
||||
if not nodes:
|
||||
return {}
|
||||
|
||||
update_info_dict = {}
|
||||
for node in nodes:
|
||||
# Non-deleted expired memory nodes need to be changed to a modified state.
|
||||
if node.store_status == StoreStatusEnum.EXPIRED.value and node.action_status != ActionStatusEnum.DELETE:
|
||||
|
|
@ -194,6 +196,7 @@ class MemoryManager(object):
|
|||
for n in new_memories:
|
||||
n.action_status = ActionStatusEnum.NONE.value
|
||||
self.memory_store.batch_insert(new_memories)
|
||||
update_info_dict[ActionStatusEnum.NEW.value] = new_memories
|
||||
|
||||
# emb & update new memories
|
||||
c_modified_memories = [n for n in nodes if n.action_status == ActionStatusEnum.CONTENT_MODIFIED]
|
||||
|
|
@ -201,6 +204,7 @@ class MemoryManager(object):
|
|||
for n in c_modified_memories:
|
||||
n.action_status = ActionStatusEnum.NONE.value
|
||||
self.memory_store.batch_update(c_modified_memories, update_embedding=True)
|
||||
update_info_dict[ActionStatusEnum.CONTENT_MODIFIED.value] = c_modified_memories
|
||||
|
||||
# update new memories
|
||||
modified_memories = [n for n in nodes if n.action_status == ActionStatusEnum.MODIFIED]
|
||||
|
|
@ -208,8 +212,12 @@ class MemoryManager(object):
|
|||
for n in modified_memories:
|
||||
n.action_status = ActionStatusEnum.NONE.value
|
||||
self.memory_store.batch_update(modified_memories, update_embedding=False)
|
||||
update_info_dict[ActionStatusEnum.MODIFIED.value] = modified_memories
|
||||
|
||||
# set memories expired
|
||||
delete_memories = [n for n in nodes if n.action_status == ActionStatusEnum.DELETE]
|
||||
if delete_memories:
|
||||
self.memory_store.batch_delete(delete_memories)
|
||||
update_info_dict[ActionStatusEnum.DELETE.value] = delete_memories
|
||||
|
||||
return update_info_dict
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from enum import Enum
|
|||
class ActionStatusEnum(str, Enum):
|
||||
"""
|
||||
Enumeration representing various statuses of a memory node.
|
||||
|
||||
|
||||
Each status reflects a different state of the node in terms of its lifecycle or content:
|
||||
- NEW: Indicates a newly created node.
|
||||
- MODIFIED: Signifies that the node has been altered.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from enum import Enum
|
|||
class LanguageEnum(str, Enum):
|
||||
"""
|
||||
An enumeration representing supported languages.
|
||||
|
||||
|
||||
Members:
|
||||
- CN: Represents the Chinese language.
|
||||
- EN: Represents the English language.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from enum import Enum
|
|||
class MemoryTypeEnum(str, Enum):
|
||||
"""
|
||||
Defines an enumeration for different types of memory categories.
|
||||
|
||||
|
||||
Each member represents a distinct type of memory content:
|
||||
- CONVERSATION: Represents conversation-based memories.
|
||||
- OBSERVATION: Denotes observational memories.
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ from enum import Enum
|
|||
class MessageRoleEnum(str, Enum):
|
||||
"""
|
||||
Enumeration for different message roles within a conversation context.
|
||||
|
||||
|
||||
This enumeration includes predefined roles such as User, Assistant, and System,
|
||||
which can be used to categorize messages in chat interfaces, AI interactions, or
|
||||
which can be used to categorize messages in chat interfaces, AI interactions, or
|
||||
any system that involves distinct participant roles.
|
||||
"""
|
||||
USER = "user" # Represents a message sent by the user.
|
||||
|
|
|
|||
816
poetry.lock
generated
816
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,16 @@
|
|||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.codespell]
|
||||
check-filenames = true
|
||||
check-hidden = true
|
||||
ignore-words-list = "astroid,gallary,momento,narl,ot,rouge"
|
||||
skip = "./examples,*.csv,*.html,*.json,*.jsonl,*.pdf,*.txt,*.ipynb"
|
||||
|
||||
[tool.poetry]
|
||||
name = "memory_scope"
|
||||
version = "0.1.0"
|
||||
name = "memoryscope"
|
||||
version = "0.1.0.2"
|
||||
description = "MemoryScope for LLM Agentic Application."
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
license = "MIT"
|
||||
|
|
@ -14,34 +24,25 @@ llama-index-embeddings-dashscope = "0.1.3"
|
|||
llama-index-llms-dashscope = "0.1.2"
|
||||
llama-index-postprocessor-dashscope-rerank-custom = "0.1.0"
|
||||
llama-index-vector-stores-elasticsearch = "0.2.0"
|
||||
pyfiglet = ">=1.0.2,<1.1.0"
|
||||
termcolor = ">=2.4.0,<2.5.0"
|
||||
pyfiglet = ">=1.0.2"
|
||||
termcolor = ">=2.4.0"
|
||||
llama-index = "0.10.45"
|
||||
fire = "0.6.0"
|
||||
questionary = "2.0.1"
|
||||
requests = ">=2.31.0,<2.32.0"
|
||||
pydantic = ">=2.7.1,<2.8.0"
|
||||
dashscope = ">=1.19.1,<1.20.0"
|
||||
elasticsearch = ">=8.14.0,<8.15.0"
|
||||
pyyaml = ">=6.0.1,<6.1.0"
|
||||
ray = ">=2.31.0,<2.32.0"
|
||||
numpy = ">=1.26.4,<1.27.0"
|
||||
pydantic = ">=2.7.1"
|
||||
dashscope = ">=1.19.1"
|
||||
elasticsearch = ">=8.14.0"
|
||||
pyyaml = ">=6.0.1"
|
||||
numpy = ">=1.26.4"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pre-commit = "^3.7.1"
|
||||
codespell = "^2.3.0"
|
||||
|
||||
[tool.codespell]
|
||||
check-filenames = true
|
||||
check-hidden = true
|
||||
ignore-words-list = "astroid,gallary,momento,narl,ot,rouge"
|
||||
skip = "./examples,*.csv,*.html,*.json,*.jsonl,*.pdf,*.txt,*.ipynb"
|
||||
[tool.poetry.scripts]
|
||||
memoryscope = "memoryscope:cli"
|
||||
|
||||
[[tool.poetry.source]]
|
||||
name = "aliyun"
|
||||
url = "http://mirrors.aliyun.com/pypi/simple/"
|
||||
priority = "supplemental"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
pyfiglet~=1.0.2
|
||||
termcolor~=2.4.0
|
||||
llama-index==0.10.45
|
||||
llama-index==0.10.45
|
||||
llama-index-core==0.10.44
|
||||
llama-index-embeddings-dashscope==0.1.3
|
||||
llama-index-llms-dashscope==0.1.2
|
||||
llama-index-postprocessor-dashscope-rerank-custom==0.1.0
|
||||
llama-index-vector-stores-elasticsearch==0.2.0
|
||||
llama-index-embeddings-dashscope==0.1.3
|
||||
llama-index-llms-dashscope==0.1.2
|
||||
llama-index-postprocessor-dashscope-rerank-custom==0.1.0
|
||||
llama-index-vector-stores-elasticsearch==0.2.0
|
||||
fire==0.6.0
|
||||
questionary==2.0.1
|
||||
requests~=2.31.0
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import sys
|
||||
|
||||
sys.path.append(".") # noqa: E402
|
||||
sys.path.append(".") # pylint: disable=E402
|
||||
|
||||
import unittest
|
||||
import time
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue