diff --git a/src/memos/mem_reader/read_multi_modal/file_content_parser.py b/src/memos/mem_reader/read_multi_modal/file_content_parser.py index cce99e76a..ad862d559 100644 --- a/src/memos/mem_reader/read_multi_modal/file_content_parser.py +++ b/src/memos/mem_reader/read_multi_modal/file_content_parser.py @@ -170,6 +170,7 @@ def create_source( chunk_index: int | None = None, chunk_total: int | None = None, chunk_content: str | None = None, + file_url_flag: bool = False, ) -> SourceMessage: """Create SourceMessage from file content part.""" if isinstance(message, dict): @@ -178,6 +179,7 @@ def create_source( "type": "file", "doc_path": file_info.get("filename") or file_info.get("file_id", ""), "content": chunk_content if chunk_content else file_info.get("file_data", ""), + "file_info": file_info if file_url_flag else {}, } # Add chunk ordering information if provided if chunk_index is not None: @@ -202,10 +204,7 @@ def rebuild_from_source( # Rebuild from source fields return { "type": "file", - "file": { - "filename": source.doc_path or "", - "file_data": source.content or "", - }, + "file": source.file_info, } def _parse_file(self, file_info: dict[str, Any]) -> str: @@ -278,7 +277,7 @@ def parse_fast( file_data = file_info.get("file_data", "") file_id = file_info.get("file_id", "") filename = file_info.get("filename", "") - + file_url_flag = False # Build content string based on available information content_parts = [] @@ -297,6 +296,7 @@ def parse_fast( content_parts.append(f"[File Data (base64/encoded): {len(file_data)} chars]") # Check if it looks like a URL elif file_data.startswith(("http://", "https://", "file://")): + file_url_flag = True content_parts.append(f"[File URL: {file_data}]") else: # TODO: split into multiple memory items @@ -348,6 +348,7 @@ def parse_fast( chunk_index=chunk_idx, chunk_total=total_chunks, chunk_content=chunk_text, + file_url_flag=file_url_flag, ) memory_item = TextualMemoryItem( @@ -384,6 +385,7 @@ def parse_fast( chunk_index=None, chunk_total=0, chunk_content=content, + file_url_flag=file_url_flag, ) memory_item = TextualMemoryItem( memory=content, diff --git a/src/memos/mem_reader/read_multi_modal/user_parser.py b/src/memos/mem_reader/read_multi_modal/user_parser.py index 359506e13..e62d9369d 100644 --- a/src/memos/mem_reader/read_multi_modal/user_parser.py +++ b/src/memos/mem_reader/read_multi_modal/user_parser.py @@ -80,6 +80,7 @@ def create_source( message_id=message_id, doc_path=file_info.get("filename") or file_info.get("file_id", ""), content=file_info.get("file_data", ""), + file_info=file_info, ) ) elif part_type == "image_url": diff --git a/src/memos/memories/textual/item.py b/src/memos/memories/textual/item.py index 1e7d579ee..a1c85033b 100644 --- a/src/memos/memories/textual/item.py +++ b/src/memos/memories/textual/item.py @@ -28,6 +28,7 @@ class SourceMessage(BaseModel): source is a chat turn. - content: Minimal reproducible snippet from the source. If omitted, upstream may fall back to `doc_path` / `url` / `message_id`. + - file_info: File information for file source. - chat_time / message_id / doc_path: Locators for precisely pointing back to the original record (timestamp, message id, document path). - Extra fields: Allowed (`model_config.extra="allow"`) to carry arbitrary @@ -40,7 +41,7 @@ class SourceMessage(BaseModel): message_id: str | None = None content: str | None = None doc_path: str | None = None - + file_info: dict | None = None model_config = ConfigDict(extra="allow")