Skip to content

refactor(memory): use XML markers for injected context#178

Open
GCS-ZHN wants to merge 1 commit into
tickernelz:mainfrom
GCS-ZHN:feat/memory-xml-markers
Open

refactor(memory): use XML markers for injected context#178
GCS-ZHN wants to merge 1 commit into
tickernelz:mainfrom
GCS-ZHN:feat/memory-xml-markers

Conversation

@GCS-ZHN

@GCS-ZHN GCS-ZHN commented Jul 18, 2026

Copy link
Copy Markdown

Summary

Replace the plain-text [MEMORY] header in injected context with explicit XML tags so the model can clearly distinguish reference material from the user's message.

Changes

  • src/services/context.ts — wrap the injected block in <memory_context>...</memory_context> with a header reminding the model the contents are background context. Nest <user_profile> and <project_knowledge> sections; each memory item becomes <memory relevance="N%">...</memory>.
  • src/services/user-profile/profile-context.ts — emit profile categories as <user_preferences>, <user_patterns>, <user_workflows>, and <learning_paths> with their items as nested elements carrying category / topic / frequency attributes. Add escapeXmlText / escapeXmlAttr helpers and apply them to all user-supplied strings so profile content cannot break out of the tags.

Behavior preserved

  • formatContextForPrompt still returns "" when there is nothing to inject, so the if (memoryContext) guard in src/index.ts:279 behaves identically.
  • getUserProfileContext still returns string | null; null is returned when no profile or no injectable items exist.
  • The parts array name, forEach + parts.push calling style, and the workflow steps formatting expression are kept as-is. Only the pushed string contents change.

Motivation

Models that consume injected context benefit from explicit structural markers: tags make it trivial to identify the start/end of the injected region, attributes carry similarity / category / frequency without parsing prose, and escaping prevents profile content (some of which is written by AI cleanup passes) from breaking out of the wrapper.

Test plan

  • No automated tests target formatContextForPrompt output today. Suggested follow-up: a unit test asserting the XML structure (see PR comment).
  • Manual: trigger chat.message with a user that has a profile and project memories; confirm the injected part begins with <memory_context> and closes with </memory_context>.

Wrap the memory block returned to the model in explicit
<memory_context>...</memory_context> tags so the agent can clearly
distinguish injected reference material from the user's message.
A short header inside the wrapper reminds the model that the contents
are background context, not instructions.

- src/services/context.ts: replace the [MEMORY] header with a
  <memory_context> wrapper; nest <user_profile> and
  <project_knowledge> sections, with each memory item as
  <memory relevance=N%>...</memory>.
- src/services/user-profile/profile-context.ts: emit the four profile
  categories as <user_preferences>, <user_patterns>,
  <user_workflows>, and <learning_paths> with their items as nested
  elements carrying category / topic / frequency attributes. Add
  escapeXmlText / escapeXmlAttr helpers and apply them to all
  user-supplied strings so profile content cannot break out of the
  tags.

Calling logic (forEach + parts.push, the parts array name, return
contract, and the workflow steps formatting expression) is preserved;
only the pushed string contents change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant