code format

This commit is contained in:
jinli.yl 2024-07-29 21:20:44 +08:00
parent 4d8e0e3da7
commit ff5df06f3f
58 changed files with 598 additions and 909 deletions

View file

@ -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

View file

@ -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",
]

View file

@ -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

View file

@ -12,7 +12,7 @@
- worker: 框架中的基本工作模块
# 💡 代码贡献
欢迎社区的代码贡献。

View file

@ -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()

View file

@ -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

View file

@ -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"

View file

@ -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)

View file

@ -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)

View file

@ -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"

View file

@ -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 = {

View file

@ -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)

View file

@ -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".

View file

@ -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()

View file

@ -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: |

View file

@ -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()

View file

@ -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

View file

@ -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]

View file

@ -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:

View file

@ -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.

View file

@ -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:

View file

@ -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

View file

@ -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]

View file

@ -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.
"""

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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.

View file

@ -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}

View file

@ -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.

View file

@ -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:

View file

@ -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}

View file

@ -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.

View file

@ -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.

View file

@ -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?

View file

@ -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.
"""

View file

@ -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 = {

View file

@ -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.

View file

@ -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:

View file

@ -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.

View file

@ -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))

View file

@ -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()

View file

@ -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)

View file

@ -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时。

View file

@ -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,

View file

@ -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}

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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"

View file

@ -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

View file

@ -1,6 +1,6 @@
import sys
sys.path.append(".") # noqa: E402
sys.path.append(".") # pylint: disable=E402
import unittest
import time