Repository navigation
Python: fix(core): stop losing multiline consolidated memories on reload #9240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c2cd4d3
51fe190
aea2062
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -368,7 +368,10 @@ def __init__( | |
| normalized_topic = _normalize_topic(topic) | ||
| self.topic = normalized_topic | ||
| self.slug = _slugify_topic(slug or normalized_topic) | ||
| self.memories = _dedupe_strings(memories) | ||
| # Collapse line breaks up front: the markdown format stores one bullet per line, | ||
| # and the consolidation path hands LLM-supplied strings in raw, so a memory kept | ||
| # multiline here would write fine but lose its continuation on the next read. | ||
| self.memories = _dedupe_strings([_normalize_memory_text(memory) for memory in memories if memory.strip()]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yufeng He (@he-yufeng) Reloading can change valid single-line memory text — |
||
| self.summary = _coerce_summary(summary, self.memories) | ||
| self.updated_at = updated_at | ||
| self.session_ids = _dedupe_strings(session_ids or []) | ||
|
|
@@ -513,10 +516,16 @@ def from_markdown(cls, markdown: str, *, fallback_topic: str | None = None) -> M | |
| if stripped: | ||
| summary_lines.append(_unescape_markdown_line(stripped)) | ||
| continue | ||
| if current_section == "memories" and stripped.startswith("- "): | ||
| memory_text = _unescape_markdown_line(stripped[2:].strip()) | ||
| if memory_text and memory_text != DEFAULT_MEMORY_NO_TOPICS_TEXT[2:]: | ||
| memories.append(memory_text) | ||
| if current_section == "memories": | ||
| if stripped.startswith("- "): | ||
| memory_text = _unescape_markdown_line(stripped[2:].strip()) | ||
| if memory_text and memory_text != DEFAULT_MEMORY_NO_TOPICS_TEXT[2:]: | ||
| memories.append(memory_text) | ||
| elif stripped and memories and not stripped.startswith("#"): | ||
| # Files written before multiline normalization carry a | ||
| # continuation line as bare text; fold it back into the | ||
| # bullet it continues instead of dropping it. | ||
| memories[-1] = f"{memories[-1]} {_unescape_markdown_line(stripped)}" | ||
|
|
||
| if topic is None: | ||
| raise ValueError("Memory topic markdown is missing a '# <topic>' heading.") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yufeng He (@he-yufeng) This only normalizes memories as they are newly constructed. Existing pre-fix files with a continuation line (for example,
- Deploy staging.followed byThen deploy production.) still lose the continuation becausefrom_markdownignores non-bullet lines beforeMemoryTopicRecordnormalization runs. Please makefrom_markdownfold non-empty continuation lines into the preceding memory and add a regression loading raw legacy Markdown from disk.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 51fe190.
from_markdownnow folds a non-empty bare line in the memories section back into the bullet it continues, so a pre-normalization file like- Deploy staging.followed byThen deploy production.loads as one memory instead of dropping the tail beforeMemoryTopicRecordnormalization ever runs. Heading-looking lines still cannot be swallowed into a memory. Addedtest_memory_topic_record_folds_legacy_continuation_lines(raw legacy markdown in, folded memory out, plus a write-read round-trip); it fails against the previous parser and passes now. Fulltest_harness_memory.pygreen (36 passed), ruff check and format clean.