From a558d5e8e1322daca4e6a2c05e4d9b3c2270b617 Mon Sep 17 00:00:00 2001 From: Edgecaser Date: Wed, 25 Mar 2026 18:47:33 -0700 Subject: [PATCH] fix: use assistant prefill to prevent harvest/refresh returning narrative instead of memory file The model sometimes ignores the "return only the memory file" instruction and outputs a session summary, which the malformed-response check correctly rejects. Adding an assistant prefill that starts with the first line of the current memory file forces the model to continue in the expected format. Also prints the raw malformed response on failure for easier debugging. Co-Authored-By: Claude Opus 4.6 --- memsync/cli.py | 4 +++- memsync/sync.py | 53 ++++++++++++++++++++++++++++++++++++------- tests/test_harvest.py | 14 +++++++++++- tests/test_sync.py | 14 +++++++++++- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/memsync/cli.py b/memsync/cli.py index 1956f96..65acda5 100644 --- a/memsync/cli.py +++ b/memsync/cli.py @@ -577,9 +577,11 @@ def cmd_harvest(args: argparse.Namespace, config: Config) -> int: if result.get("malformed"): print( "\nError: API response does not look like a memory file (missing leading # or " + + +def _strip_model_wrapper(content: str) -> str: + """ + Strip wrapper artifacts the model sometimes adds around the memory file: + - Code fences (```markdown, ```md, plain ```) + - Preamble lines before the first heading ("Here's the updated...", etc.) """ stripped = content.strip() + + # Strip code fences first if stripped.startswith("```"): lines = stripped.splitlines() # Remove opening fence line (e.g. ```markdown) @@ -111,7 +132,19 @@ def _strip_code_fences(content: str) -> str: # Remove closing fence if present if lines and lines[-1].strip() == "```": lines = lines[:-1] - return "\n".join(lines).strip() + stripped = "\n".join(lines).strip() + + # Strip preamble lines before the first heading or comment marker. + # The model sometimes leads with "Here's the updated memory file:" or similar. + lines = stripped.splitlines() + while lines: + first = lines[0].strip() + if first.startswith("#") or first.startswith("