fix: stop pointing the agent at an empty episodic log under a memory backend#216
Open
AmirF194 wants to merge 1 commit into
Open
fix: stop pointing the agent at an empty episodic log under a memory backend#216AmirF194 wants to merge 1 commit into
AmirF194 wants to merge 1 commit into
Conversation
…backend
The Workspace section of the system prompt always advertises
{workspace}/user_memory/episodic/episodes.md as the episodic log to
grep, in both render.py's identity_text (the live per-turn prompt) and
builder.py's hand-duplicated copy (token-size estimation only). That
file is written only by the host's legacy MemoryConsolidator. When a
MemoryBackend plugin is wired (e.g. EverOS), episodes live in the
plugin's own store instead and are surfaced through per-turn recall
into the # Memory section (MemorySegmentBuilder), so the workspace
file stays empty and the guidance sends the agent to grep nothing.
Thread whether a backend is wired into identity_text via a new
has_memory_backend flag. IdentitySegmentBuilder and
build_context_engine already receive backend, so this is one added
parameter on each; ContextBuilder gains the same parameter, passed in
from AgentLoop.__init__ where backend is already available. With a
backend, the Episodic log line is replaced with guidance pointing at
the automatic # Memory recall instead of a file path that stays
empty. Without one (the default), the rendered text is unchanged.
Also fold ContextBuilder._get_identity into a call to the shared
render.identity_text instead of keeping a second hand-maintained copy
of the same prompt text: the two had already drifted once (builder.py
was missing the language directive render.py has), and a duplicated
literal is how this bug's own guidance line went stale in only one of
the two places to begin with.
Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Workspace section of the system prompt always advertises
{workspace}/user_memory/episodic/episodes.mdas the episodic log to grep, in bothrender.py'sidentity_text(the live per-turn prompt) andbuilder.py's hand-duplicated copy (token-size estimation only). That file is written only by the host's legacyMemoryConsolidator. When aMemoryBackendplugin is wired (e.g. EverOS), episodes live in the plugin's own store instead and are surfaced through per-turn recall into the# Memorysection (MemorySegmentBuilder), so the workspace file stays empty and the guidance sends the agent to grep nothing, exactly as the issue's own evidence shows (0-byteepisodes.mdnext to 8 populated EverOS episode files).identity_textnow takes ahas_memory_backendflag.IdentitySegmentBuilderandbuild_context_enginealready receivebackend, so wiring it through is one added parameter on each. With a backend, theEpisodic logline is replaced with guidance pointing at the automatic# Memoryrecall instead of a file path that stays empty; without one (the default), the rendered text is unchanged.ContextBuilder._get_identitynow delegates to the sharedrender.identity_textinstead of keeping its own copy of the same text, which is the "unify" half of the issue: the two had already drifted once (builder.pywas missing the language directiverender.pyhas).Type
Verification
Commands run (this container,
python:3.12-slim+uv sync --frozen --extra dev --dev):uv run --extra dev pytest tests/test_segments.py tests/test_context_invariants.py tests/test_default_context_engine.py tests/test_security_untrusted_context.py -v-> 42 passed.test_identity_with_backend_omits_stale_episodic_path,test_identity_with_backend_matches_legacy_builderintests/test_segments.py) fail onmainwithTypeError: IdentitySegmentBuilder.__init__() takes 2 positional arguments but 3 were given(confirmed by reverting only the source files and re-running against the new tests) and pass on this branch.ContextBuilder/AgentLoop/build_context_engine(29 files,git greplist), minustests/integration/and the messaging-channel adapter tests that fail to import for missing optional deps unrelated to this change (dingtalk_stream,lark_oapi,nh3,botpy,slackify_markdown,python-telegram-bot,wecom_aibot_sdk, none installed by--extra dev) -> 402 passed, 22 failed. All 22 failures are intests/test_runtime_checkpoint_bug2*.pyand are pre-existing environment gaps (FileNotFoundError: [Errno 2] No such file or directory: 'git', thepython:3.12-slimimage has nogitbinary), unrelated to this diff.uv run --extra dev ruff check/ruff format --checkon every changed file: clean.uv run --extra dev pre-commit run --files <changed files>: all hooks pass (ruff, ruff-format, trailing-whitespace, end-of-file-fixer, large-files, merge-conflict, private-key).Not verified: an end-to-end run against a live EverOS instance (the issue's own repro environment). The fix is scoped to the prompt-text guidance the issue describes and is covered by the unit tests above; I did not stand up EverOS to confirm the rendered prompt reaches a running agent unchanged elsewhere.
Risk
has_memory_backenddefaults toFalseand the newbackendparameters default toNone, so every existing call site (all of which construct without a backend) renders byte-identical text to before.Related Issues
Fixes #122