From 465a4deb5cff0418200492fe49ad4b36ab669ae1 Mon Sep 17 00:00:00 2001 From: liji <532311301@qq.com> Date: Tue, 28 Oct 2025 17:45:12 +0800 Subject: [PATCH 1/2] feat: fix sources --- src/memos/memories/textual/item.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/memos/memories/textual/item.py b/src/memos/memories/textual/item.py index f6254efbb..eae6b5ce8 100644 --- a/src/memos/memories/textual/item.py +++ b/src/memos/memories/textual/item.py @@ -1,6 +1,7 @@ """Defines memory item types for textual memory.""" import json +import logging import uuid from datetime import datetime @@ -123,6 +124,25 @@ class TreeNodeTextualMemoryMetadata(TextualMemoryMetadata): def coerce_sources(cls, v): if v is None: return v + # Handle string representation of sources (e.g., from PostgreSQL array or malformed data) + if isinstance(v, str): + logging.info(f"[coerce_sources] v: {v} type: {type(v)}") + # If it's a string that looks like a list representation, try to parse it + # This handles cases like: "[uuid1, uuid2, uuid3]" or "[item1, item2]" + v_stripped = v.strip() + if v_stripped.startswith("[") and v_stripped.endswith("]"): + # Remove brackets and split by comma + content = v_stripped[1:-1].strip() + if content: + # Split by comma and clean up each item + items = [item.strip() for item in content.split(",")] + # Convert to list of strings + v = items + else: + v = [] + else: + # Single string, wrap in list + v = [v] if not isinstance(v, list): raise TypeError("sources must be a list") out = [] From 3f29bcaa10fc1c72e198414e20e66107dfd51c18 Mon Sep 17 00:00:00 2001 From: liji <532311301@qq.com> Date: Tue, 28 Oct 2025 18:46:33 +0800 Subject: [PATCH 2/2] feat: fix sources --- src/memos/memories/textual/item.py | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/memos/memories/textual/item.py b/src/memos/memories/textual/item.py index eae6b5ce8..48f42fa4c 100644 --- a/src/memos/memories/textual/item.py +++ b/src/memos/memories/textual/item.py @@ -125,24 +125,24 @@ def coerce_sources(cls, v): if v is None: return v # Handle string representation of sources (e.g., from PostgreSQL array or malformed data) - if isinstance(v, str): - logging.info(f"[coerce_sources] v: {v} type: {type(v)}") - # If it's a string that looks like a list representation, try to parse it - # This handles cases like: "[uuid1, uuid2, uuid3]" or "[item1, item2]" - v_stripped = v.strip() - if v_stripped.startswith("[") and v_stripped.endswith("]"): - # Remove brackets and split by comma - content = v_stripped[1:-1].strip() - if content: - # Split by comma and clean up each item - items = [item.strip() for item in content.split(",")] - # Convert to list of strings - v = items - else: - v = [] + if isinstance(v, str): + logging.info(f"[coerce_sources] v: {v} type: {type(v)}") + # If it's a string that looks like a list representation, try to parse it + # This handles cases like: "[uuid1, uuid2, uuid3]" or "[item1, item2]" + v_stripped = v.strip() + if v_stripped.startswith("[") and v_stripped.endswith("]"): + # Remove brackets and split by comma + content = v_stripped[1:-1].strip() + if content: + # Split by comma and clean up each item + items = [item.strip() for item in content.split(",")] + # Convert to list of strings + v = items else: - # Single string, wrap in list - v = [v] + v = [] + else: + # Single string, wrap in list + v = [v] if not isinstance(v, list): raise TypeError("sources must be a list") out = []