Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
192 commits
Select commit Hold shift + click to select a range
65d5649
update reader and search strategy
Oct 28, 2025
6cad866
set strategy reader and search config
Oct 29, 2025
f040110
fix all reader conflicts
Oct 29, 2025
c389367
fix install problem
Oct 29, 2025
499502d
fix
Oct 29, 2025
e1bb223
fix test
Oct 29, 2025
72b7466
Merge branch 'dev' into dev_test
CaralHsi Oct 29, 2025
74585e8
Merge branch 'dev' into dev_test
fridayL Oct 30, 2025
790e99f
turn off graph recall
Oct 30, 2025
15b63a7
Merge branch 'dev' into dev_test
Oct 30, 2025
390ba29
turn off graph recall
Oct 30, 2025
9615282
turn off graph recall
Oct 30, 2025
2fb8ce0
Merge branch 'dev' into dev_test
fridayL Oct 30, 2025
6035522
Merge branch 'dev' into dev_test
Oct 30, 2025
04f412b
fix Searcher input bug
Oct 30, 2025
9716274
fix Searcher
Oct 30, 2025
c455a4e
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Oct 30, 2025
f8b9b4a
fix Search
Oct 30, 2025
c840ad4
Merge branch 'dev' into dev_test
Oct 30, 2025
b9dbecd
fix bug
Nov 4, 2025
1798f60
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 4, 2025
6db95e7
Merge branch 'dev' into dev_test
Nov 4, 2025
1173c07
adjust strategy reader
Nov 4, 2025
7ab465b
Merge branch 'dev' into dev_test
Nov 4, 2025
744d227
adjust strategy reader
Nov 4, 2025
a9a98fa
adjust search config input
Nov 4, 2025
900f5e6
reformat code
Nov 4, 2025
ac7aff5
Merge branch 'dev' into dev_test
CaralHsi Nov 4, 2025
144c446
re pr
Nov 5, 2025
a2b55c7
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 5, 2025
441c52b
Merge branch 'dev' into dev_test
Nov 5, 2025
6f272db
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Nov 5, 2025
f506d3e
format repair
Nov 5, 2025
db9041c
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 5, 2025
d921284
Merge branch 'dev' into dev_test
CaralHsi Nov 5, 2025
d036c53
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 11, 2025
5a3f0db
Merge branch 'dev' into dev_test
Nov 11, 2025
dc67413
fix time issue
Nov 11, 2025
7699b9a
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Nov 11, 2025
8bfbf94
develop feedback process
Nov 19, 2025
875c551
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 19, 2025
7f20f8b
Resolve merge conflicts
Nov 19, 2025
4d712eb
feedback handler configuration
Nov 20, 2025
36b93eb
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 25, 2025
adec73e
merged
Nov 25, 2025
aef3aad
upgrade feedback using
Nov 26, 2025
81ec520
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 26, 2025
55c9d89
fix
Nov 26, 2025
b4fbfde
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 27, 2025
ee64719
Merge branch 'dev' into dev_test
Nov 27, 2025
0fa9be7
add threshold
Nov 27, 2025
4a4746e
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Nov 27, 2025
16de8da
Merge branch 'dev' into dev_test
Nov 27, 2025
facb7b3
update prompt
Nov 27, 2025
eab5fe6
update prompt
Nov 27, 2025
7577aac
fix handler
Nov 27, 2025
cc4069d
add feedback scheduler
Nov 29, 2025
2529db2
add handler change node update
Dec 1, 2025
898ccac
add handler change node update
Dec 1, 2025
faec340
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 1, 2025
913c24d
add handler change node update
Dec 1, 2025
91d063d
add handler change node update
Dec 1, 2025
2a47880
add handler change node update
Dec 1, 2025
c5618c6
Merge branch 'dev' into dev_test
whipser030 Dec 2, 2025
b9737f1
Merge branch 'dev' into dev_test
CaralHsi Dec 2, 2025
ad9c2e7
fix interface input
Dec 2, 2025
c0c32b1
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 2, 2025
d906f0d
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 2, 2025
696708e
fix interface input
Dec 2, 2025
6ad8dae
add chunk and ratio filter
Dec 3, 2025
6298c64
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 3, 2025
47acd7a
Merge branch 'dev' into dev_test
Dec 3, 2025
0727c25
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 3, 2025
0b0342d
Merge branch 'dev' into dev_test
Dec 3, 2025
294c1e6
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 3, 2025
d9158e4
Merge branch 'dev' into dev_test
Dec 3, 2025
699cdf7
update stopwords
Dec 3, 2025
8ca03c0
Merge branch 'dev' into dev_test
fridayL Dec 3, 2025
6076935
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 4, 2025
b2b0f6e
Merge branch 'dev' into dev_test
Dec 4, 2025
343eeb3
fix messages queue
Dec 4, 2025
1bb9396
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 4, 2025
045196c
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 4, 2025
7131c35
Merge branch 'dev' into dev_test
Dec 4, 2025
d66e8ce
add seach_by_keywords_LIKE
Dec 7, 2025
d081aaa
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 7, 2025
405658f
Merge branch 'dev' into dev_test
Dec 7, 2025
ae60994
add doc filter
Dec 9, 2025
70efbf3
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 9, 2025
a613c7e
merge dev
Dec 9, 2025
7b0f2f4
add retrieve query
Dec 9, 2025
c6768b6
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 9, 2025
005a5bb
add retrieve queies
Dec 10, 2025
d69e7f4
patch info filter
Dec 10, 2025
d4f18e8
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 10, 2025
3c5199a
add strict info filter
Dec 11, 2025
365e0b6
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 12, 2025
9bc942d
Merge branch 'dev' into dev_test
Dec 12, 2025
eab3d80
add log and make embedding safety net
Dec 12, 2025
9519f5e
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 12, 2025
f21a885
Merge branch 'dev' into dev_test
Dec 12, 2025
7f146e1
add log and make embedding safety net
Dec 12, 2025
4cc4677
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 15, 2025
c01c900
Merge branch 'dev' into dev_test
Dec 15, 2025
4da6d31
deduplicate add objects
Dec 16, 2025
28934c8
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 16, 2025
d3f0a77
Merge branch 'dev' into dev_test
Dec 16, 2025
13e8d16
Merge branch 'dev' into dev_test
CaralHsi Dec 16, 2025
fd2816c
use _add_memories_parallel
Dec 17, 2025
dfe62dc
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 17, 2025
192d150
Merge branch 'dev' into dev_test
Dec 17, 2025
e6ce0ee
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 17, 2025
02585f2
Merge branch 'dev' into dev_test
fridayL Dec 17, 2025
39b0b20
delete Special characters
Dec 17, 2025
81fa434
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 17, 2025
0a10a52
Merge branch 'dev' into dev_test
Dec 17, 2025
991092e
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 17, 2025
b7b5003
delete Special characters
Dec 17, 2025
95bb061
delete Special characters
Dec 17, 2025
14d6732
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 17, 2025
c8ea8ae
Merge branch 'dev' into dev_test
Dec 17, 2025
a2fe6ed
delete Special characters
Dec 17, 2025
6274864
add source_doc_id
Dec 17, 2025
5f19846
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 17, 2025
a06e5f7
Merge branch 'dev' into dev_test
Dec 17, 2025
f2aec38
add source_doc_id
Dec 17, 2025
45f4957
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 18, 2025
bd612b9
Merge branch 'dev' into dev_test
Dec 18, 2025
d34812b
add reranker in init com..
Dec 18, 2025
5b681be
Merge branch 'dev' into dev_test
fridayL Dec 18, 2025
3919dcf
fix circle import
Dec 18, 2025
56df680
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 18, 2025
dd1aef9
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 18, 2025
777d6e0
Merge branch 'dev' into dev_test
Dec 18, 2025
353e417
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 22, 2025
bd8651c
Merge branch 'dev' into dev_test
Dec 22, 2025
73106ed
add feedback judgement
Dec 23, 2025
b7ffa5a
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 23, 2025
f37b15b
Merge branch 'dev' into dev_test
Dec 23, 2025
1b0e3af
add feedback judgement
Dec 23, 2025
f6d8f77
add pref feedback
Dec 24, 2025
9137781
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 24, 2025
ef36b5b
add pref feedback
Dec 24, 2025
ed34f0c
add pref feedback
Dec 24, 2025
fd50e90
Merge branch 'dev' into dev_test
fridayL Dec 25, 2025
653d900
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 29, 2025
827a503
patch: get_memory func filter user id and make page chunk
Dec 29, 2025
82ea9ee
Merge branch 'dev' into dev_test
Dec 29, 2025
8e28619
Merge branch 'dev_test' of github.com:whipser030/MemOS into dev_test
Dec 29, 2025
3dd09d5
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 29, 2025
a779823
Merge branch 'dev' into dev_test
Dec 29, 2025
4fab261
add total num
Dec 30, 2025
29f63c0
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 30, 2025
6aacaa7
Merge branch 'dev' into dev_test
Dec 30, 2025
b5f71a5
add total num
Dec 30, 2025
098a830
add milvus pagination
Dec 30, 2025
dd8cd80
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 30, 2025
9eca446
Merge branch 'dev' into dev_test
Dec 30, 2025
3fd1743
fix merge implicit explicit pref
Dec 30, 2025
963aa91
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Dec 30, 2025
031876c
fix merge implicit explicit pref
Dec 30, 2025
af610fe
fix merge implicit explicit pref
Dec 30, 2025
eab2303
fix merge implicit explicit pref
Dec 30, 2025
83061d1
fix json load bug
Jan 7, 2026
6707cc2
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Jan 7, 2026
a0989fd
Merge branch 'dev' into dev_test
Jan 7, 2026
48d4ff1
knowledge raw_text replace memory
Jan 8, 2026
f5b7547
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Jan 8, 2026
10d8b93
Merge branch 'dev' into dev_test
Jan 8, 2026
21c12cd
knowledge raw_text replace memory
Jan 8, 2026
7164b71
knowledge raw_text replace memory
Jan 8, 2026
d6e5bfa
Merge branch 'dev' of github.com:MemTensor/MemOS into dev
Jan 12, 2026
4a195dc
Merge branch 'dev' into dev_test
Jan 12, 2026
47f2100
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 12, 2026
adff60a
unuse rerank
Jan 12, 2026
a1179da
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 12, 2026
33aab5e
Merge branch 'dev_release' into dev_test
Jan 12, 2026
1f795ab
backtrack knowledge retrieval
Jan 13, 2026
7b9941b
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 13, 2026
e2ee965
Merge branch 'dev_release' into dev_test
Jan 13, 2026
a5e423f
norerank knowledge data
Jan 14, 2026
cdfea53
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 14, 2026
4ff53e7
norerank knowledge data
Jan 14, 2026
a2e8781
use embedding rerank knowledge
Jan 14, 2026
4d9a86d
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 14, 2026
f3e1b92
Merge branch 'dev_release' into dev_test
Jan 14, 2026
456f830
add chunk memories
Jan 15, 2026
cb34aaf
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 15, 2026
f856060
feat: mix search upload file raw content
Jan 18, 2026
0883f22
Merge branch 'dev-20260112-v2.0.2' of github.com:MemTensor/MemOS into…
Jan 18, 2026
2e1edf2
feat: search upload raw file
Jan 18, 2026
444eba3
feedback soures set empty
Jan 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/memos/api/handlers/formatters_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ def separate_knowledge_and_conversation_mem(memories: list[dict[str, Any]]):
for item in memories:
sources = item["metadata"]["sources"]
if (
len(sources) > 0
item["metadata"]["memory_type"] != "RawFileMemory"
and len(sources) > 0
and "type" in sources[0]
and sources[0]["type"] == "file"
and "content" in sources[0]
Expand Down Expand Up @@ -192,8 +193,7 @@ def rerank_knowledge_mem(
key=lambda item: item.get("metadata", {}).get("relativity", 0.0),
reverse=True,
)

# TODO revoke sources replace memory value
# replace memory value with source.content for LongTermMemory, WorkingMemory or UserMemory
for item in reranked_knowledge_mem:
item["memory"] = item["metadata"]["sources"][0]["content"]
item["metadata"]["sources"] = []
Expand Down
4 changes: 2 additions & 2 deletions src/memos/api/product_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ class APISearchRequest(BaseRequest):
)
# Internal field for search memory type
search_memory_type: str = Field(
"All",
description="Type of memory to search: All, WorkingMemory, LongTermMemory, UserMemory, OuterMemory, ToolSchemaMemory, ToolTrajectoryMemory",
"AllSummaryMemory",
description="Type of memory to search: All, WorkingMemory, LongTermMemory, UserMemory, OuterMemory, ToolSchemaMemory, ToolTrajectoryMemory, RawFileMemory, AllSummaryMemory",
)

# ==== Context ====
Expand Down
15 changes: 6 additions & 9 deletions src/memos/mem_feedback/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,15 @@ def _single_add_operation(
to_add_memory.metadata.tags = new_memory_item.metadata.tags
to_add_memory.memory = new_memory_item.memory
to_add_memory.metadata.embedding = new_memory_item.metadata.embedding

to_add_memory.metadata.user_id = new_memory_item.metadata.user_id
to_add_memory.metadata.created_at = to_add_memory.metadata.updated_at = (
datetime.now().isoformat()
)
to_add_memory.metadata.background = new_memory_item.metadata.background
else:
to_add_memory = new_memory_item.model_copy(deep=True)
to_add_memory.metadata.created_at = to_add_memory.metadata.updated_at = (
datetime.now().isoformat()
)
to_add_memory.metadata.background = new_memory_item.metadata.background

to_add_memory.metadata.created_at = to_add_memory.metadata.updated_at = (
datetime.now().isoformat()
)
to_add_memory.metadata.background = new_memory_item.metadata.background
to_add_memory.metadata.sources = []

to_add_memory.id = ""
added_ids = self._retry_db_operation(
Expand Down
1 change: 1 addition & 0 deletions src/memos/mem_reader/multi_modal_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ def _process_string_fine(
) -> list[TextualMemoryItem]:
"""
Process fast mode memory items through LLM to generate fine mode memories.
Where fast_memory_items are raw chunk memory items, not the final memory items.
"""
if not fast_memory_items:
return []
Expand Down
89 changes: 51 additions & 38 deletions src/memos/mem_reader/read_multi_modal/file_content_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,6 @@ def parse_fast(
if filename:
content_parts.append(f"[Filename: {filename}]")

# If no content can be extracted, create a placeholder
if not content_parts:
content_parts.append("[File: unknown]")

# Combine content parts
content = " ".join(content_parts)

Expand Down Expand Up @@ -513,38 +509,6 @@ def parse_fast(
)
memory_items.append(memory_item)

# If no chunks were created, create a placeholder
if not memory_items:
# Create source for placeholder (no chunk index since there are no chunks)
placeholder_source = self.create_source(
message,
info,
chunk_index=None,
chunk_total=0,
chunk_content=content,
file_url_flag=file_url_flag,
)
memory_item = TextualMemoryItem(
memory=content,
metadata=TreeNodeTextualMemoryMetadata(
user_id=user_id,
session_id=session_id,
memory_type=memory_type,
status="activated",
tags=["mode:fast", "multimodal:file"],
key=_derive_key(content),
embedding=self.embedder.embed([content])[0],
usage=[],
sources=[placeholder_source],
background="",
confidence=0.99,
type="fact",
info=info_,
file_ids=file_ids,
),
)
memory_items.append(memory_item)

return memory_items

def parse_fine(
Expand Down Expand Up @@ -781,6 +745,31 @@ def _process_chunk(chunk_idx: int, chunk_text: str) -> TextualMemoryItem:
logger.warning(f"[FileContentParser] Fallback to raw for chunk {chunk_idx}")
return _make_fallback(chunk_idx, chunk_text)

def _relate_chunks(items: list[TextualMemoryItem]) -> None:
"""
Relate chunks to each other.
"""
if len(items) <= 1:
return

def get_chunk_idx(item: TextualMemoryItem) -> int:
"""Extract chunk_idx from item's source metadata."""
if item.metadata.sources and len(item.metadata.sources) > 0:
source = item.metadata.sources[0]
if source.file_info and isinstance(source.file_info, dict):
chunk_idx = source.file_info.get("chunk_index")
if chunk_idx is not None:
return chunk_idx
return float("inf")

sorted_items = sorted(items, key=get_chunk_idx)

# Relate adjacent items
for i in range(len(sorted_items) - 1):
sorted_items[i].metadata.following_id = sorted_items[i + 1].id
sorted_items[i + 1].metadata.preceding_id = sorted_items[i].id
return sorted_items

# Process chunks concurrently with progress bar
memory_items = []
chunk_map = dict(valid_chunks)
Expand All @@ -802,8 +791,24 @@ def _process_chunk(chunk_idx: int, chunk_text: str) -> TextualMemoryItem:
chunk_idx = futures[future]
try:
node = future.result()
if node:
memory_items.append(node)
memory_items.append(node)
# save raw file
node_id = node.id
if node.memory != node.metadata.sources[0].content:
chunk_node = _make_memory_item(
value=node.metadata.sources[0].content,
mem_type="RawFileMemory",
tags=[
"mode:fine",
"multimodal:file",
f"chunk:{chunk_idx + 1}/{total_chunks}",
],
chunk_idx=chunk_idx,
chunk_content="",
)
chunk_node.metadata.summary_id = node_id
memory_items.append(chunk_node)

except Exception as e:
tqdm.write(f"[ERROR] Chunk {chunk_idx} failed: {e}")
logger.error(f"[FileContentParser] Future failed for chunk {chunk_idx}: {e}")
Expand All @@ -816,6 +821,14 @@ def _process_chunk(chunk_idx: int, chunk_text: str) -> TextualMemoryItem:
logger.info(
f"[FileContentParser] Completed processing {len(memory_items)}/{total_chunks} chunks"
)
rawfile_items = [
memory for memory in memory_items if memory.metadata.memory_type == "RawFileMemory"
]
mem_items = [
memory for memory in memory_items if memory.metadata.memory_type != "RawFileMemory"
]
related_rawfile_items = _relate_chunks(rawfile_items)
memory_items = mem_items + related_rawfile_items

return memory_items or [
_make_memory_item(
Expand Down
4 changes: 4 additions & 0 deletions src/memos/mem_reader/read_multi_modal/user_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def create_source(
part_type = part.get("type", "")
if part_type == "text":
text_contents.append(part.get("text", ""))
if part_type == "file":
file_info = part.get("file", {})
file_data = file_info.get("file_data", "")
text_contents.append(file_data)

# Detect overall language from all text content
overall_lang = "en"
Expand Down
33 changes: 29 additions & 4 deletions src/memos/mem_scheduler/general_scheduler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import concurrent.futures
import contextlib
import json
import os
import traceback

from memos.configs.mem_scheduler import GeneralSchedulerConfig
Expand Down Expand Up @@ -840,7 +841,7 @@ def _process_memories_with_reader(
)
return

# Get the original memory items
# Get the original fast memory (raw chunk) items
memory_items = []
for mem_id in mem_ids:
try:
Expand Down Expand Up @@ -893,14 +894,38 @@ def _process_memories_with_reader(

# Add the enhanced memories back to the memory system
if flattened_memories:
enhanced_mem_ids = text_mem.add(flattened_memories, user_name=user_name)
mem_group = [
memory
for memory in flattened_memories
if memory.metadata.memory_type != "RawFileMemory"
]
enhanced_mem_ids = text_mem.add(mem_group, user_name=user_name)
logger.info(
f"Added {len(enhanced_mem_ids)} enhanced memories: {enhanced_mem_ids}"
)

# add raw file nodes and edges
if os.getenv("SAVE_RAWFILE_NODE", "false").lower() == "true":
raw_file_mem_group = [
memory
for memory in flattened_memories
if memory.metadata.memory_type == "RawFileMemory"
]
text_mem.add_rawfile_nodes_n_edges(
raw_file_mem_group,
enhanced_mem_ids,
user_id=user_id,
user_name=user_name,
)

# Mark merged_from memories as archived when provided in memory metadata
summary_memories = [
memory
for memory in flattened_memories
if memory.metadata.memory_type != "RawFileMemory"
]
if self.mem_reader.graph_db:
for memory in flattened_memories:
for memory in summary_memories:
merged_from = (memory.metadata.info or {}).get("merged_from")
if merged_from:
old_ids = (
Expand All @@ -923,7 +948,7 @@ def _process_memories_with_reader(
else:
# Check if any memory has merged_from but graph_db is unavailable
has_merged_from = any(
(m.metadata.info or {}).get("merged_from") for m in flattened_memories
(m.metadata.info or {}).get("merged_from") for m in summary_memories
)
if has_merged_from:
logger.warning(
Expand Down
1 change: 1 addition & 0 deletions src/memos/memories/textual/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class TreeNodeTextualMemoryMetadata(TextualMemoryMetadata):
"OuterMemory",
"ToolSchemaMemory",
"ToolTrajectoryMemory",
"RawFileMemory",
] = Field(default="WorkingMemory", description="Memory lifecycle type.")
sources: list[SourceMessage] | None = Field(
default=None, description="Multiple origins of the memory (e.g., URLs, notes)."
Expand Down
99 changes: 99 additions & 0 deletions src/memos/memories/textual/tree.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import concurrent.futures
import json
import os
import shutil
import tempfile
import time

from datetime import datetime
from pathlib import Path
from typing import Any

from memos.configs.memory import TreeTextMemoryConfig
from memos.configs.reranker import RerankerConfigFactory
from memos.context.context import ContextThreadPoolExecutor
from memos.embedders.factory import EmbedderFactory, OllamaEmbedder
from memos.graph_dbs.factory import GraphStoreFactory, Neo4jGraphDB
from memos.llms.factory import AzureLLM, LLMFactory, OllamaLLM, OpenAILLM
Expand Down Expand Up @@ -457,3 +460,99 @@ def _cleanup_old_backups(root_dir: Path, keep_last_n: int) -> None:
logger.info(f"Deleted old backup directory: {old_dir}")
except Exception as e:
logger.warning(f"Failed to delete backup {old_dir}: {e}")

def add_rawfile_nodes_n_edges(
self,
raw_file_mem_group: list[TextualMemoryItem],
mem_ids: list[str],
user_id: str | None = None,
user_name: str | None = None,
) -> None:
"""
Add raw file nodes and edges to the graph. Edges are between raw file ids and mem_ids.
Args:
raw_file_mem_group: List of raw file memory items.
mem_ids: List of memory IDs.
user_name: cube id.
"""
rawfile_ids_local: list[str] = self.add(
raw_file_mem_group,
user_name=user_name,
)

from_ids = []
to_ids = []
types = []

for raw_file_mem in raw_file_mem_group:
# Add SUMMARY edge: memory -> raw file; raw file -> memory
if hasattr(raw_file_mem.metadata, "summary_id") and raw_file_mem.metadata.summary_id:
summary_id = raw_file_mem.metadata.summary_id
if summary_id in mem_ids:
from_ids.append(summary_id)
to_ids.append(raw_file_mem.id)
types.append("MATERIAL")

from_ids.append(raw_file_mem.id)
to_ids.append(summary_id)
types.append("SUMMARY")

# Add FOLLOWING edge: current chunk -> next chunk
if (
hasattr(raw_file_mem.metadata, "following_id")
and raw_file_mem.metadata.following_id
):
following_id = raw_file_mem.metadata.following_id
if following_id in rawfile_ids_local:
from_ids.append(raw_file_mem.id)
to_ids.append(following_id)
types.append("FOLLOWING")

# Add PRECEDING edge: previous chunk -> current chunk
if (
hasattr(raw_file_mem.metadata, "preceding_id")
and raw_file_mem.metadata.preceding_id
):
preceding_id = raw_file_mem.metadata.preceding_id
if preceding_id in rawfile_ids_local:
from_ids.append(raw_file_mem.id)
to_ids.append(preceding_id)
types.append("PRECEDING")

start_time = time.time()
self.add_graph_edges(
from_ids,
to_ids,
types,
user_name=user_name,
)
end_time = time.time()
logger.info(f"[RawFile]Added {len(rawfile_ids_local)} chunks for user {user_id}")
logger.info(
f"[RawFile]Time taken to add edges: {end_time - start_time} seconds for {len(from_ids)} edges"
)

def add_graph_edges(
self, from_ids: list[str], to_ids: list[str], types: list[str], user_name: str | None = None
) -> None:
"""
Add edges to the graph.
Args:
from_ids: List of source node IDs.
to_ids: List of target node IDs.
types: List of edge types.
user_name: Optional user name.
"""
with ContextThreadPoolExecutor(max_workers=20) as executor:
futures = {
executor.submit(
self.graph_store.add_edge, from_id, to_id, edge_type, user_name=user_name
)
for from_id, to_id, edge_type in zip(from_ids, to_ids, types, strict=False)
}

for future in concurrent.futures.as_completed(futures):
try:
future.result()
except Exception as e:
logger.exception("Add edge error: ", exc_info=e)
Loading
Loading