From 7d3038510c40e55f09c67b24e4c2cdcf6e904d9c Mon Sep 17 00:00:00 2001 From: simpleqt <89645338+simpleqt@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:58:52 +0800 Subject: [PATCH] Only split bracketed lists whose items are reference tags split_continuous_references treated any [a, b] block as a reference list, corrupting plain prose like 'the set is [apple, banana]'. The items must now match int:id reference-tag shapes. Fixes #2446 --- src/memos/mem_os/utils/reference_utils.py | 8 ++++++ tests/mem_os/test_reference_split_shape.py | 29 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/mem_os/test_reference_split_shape.py diff --git a/src/memos/mem_os/utils/reference_utils.py b/src/memos/mem_os/utils/reference_utils.py index 09b812207..de2d744e4 100644 --- a/src/memos/mem_os/utils/reference_utils.py +++ b/src/memos/mem_os/utils/reference_utils.py @@ -41,6 +41,14 @@ def split_continuous_references(text: str) -> str: # Check if there's a comma between brackets if "," not in content_between_brackets: return text + # Every item must look like a reference tag "int:id"; plain bracketed + # prose such as "[apple, banana]" must pass through untouched + import re + + if not re.fullmatch( + r"\s*\d+:[^,\s]+(?:,\s*\d+:[^,\s]+)*\s*", content_between_brackets + ): + return text text = text.replace(content_between_brackets, content_between_brackets.replace(", ", "][")) text = text.replace(content_between_brackets, content_between_brackets.replace(",", "][")) diff --git a/tests/mem_os/test_reference_split_shape.py b/tests/mem_os/test_reference_split_shape.py new file mode 100644 index 000000000..56edb89eb --- /dev/null +++ b/tests/mem_os/test_reference_split_shape.py @@ -0,0 +1,29 @@ +import pytest + +from memos.mem_os.utils.reference_utils import split_continuous_references + + +@pytest.mark.parametrize( + ("text", "expected"), + [ + ("[1:92ff35fb, 4:bfe6f044]", "[1:92ff35fb][4:bfe6f044]"), + ("[1:92ff35fb,4:bfe6f044]", "[1:92ff35fb][4:bfe6f044]"), + ("See [1:aa, 2:bb] now", "See [1:aa][2:bb] now"), + ], +) +def test_reference_lists_are_split(text, expected): + assert split_continuous_references(text) == expected + + +@pytest.mark.parametrize( + "text", + [ + "The set is [apple, banana] here", + "[1, 2, 3]", + "[some note, another note]", + "no brackets at all", + ], +) +def test_non_reference_text_passes_through(text): + # plain bracketed prose used to be corrupted into [apple][banana] + assert split_continuous_references(text) == text