/**
* The shared `ā¦` injection marker.
*
* Both the v2 graph-memory producers (`conversation-graph-memory.ts`) and the
* v3 live renderer (`v3/render-injection.ts`) emit memory blocks with this
* exact wrapper, and the strip/recognition machinery in
* `conversation-graph-memory.ts` (`countMemoryPrefixBlocks`) matches the same
* `"\n"` / `"\n"` delimiters. Keeping the producer wrapper in
* one leaf module guarantees the byte-for-byte marker contract across v2 and
* v3 ā a change here updates every producer at once.
*
* This is a tiny dependency-free leaf so the pure v3 renderer can import it
* without pulling in the heavyweight graph-memory module.
*/
export function wrapMemoryBlock(text: string): string {
return `\n${text}\n`;
}
/**
* Inverse of {@link wrapMemoryBlock}: recover the inner text from a wrapped
* block. Only unwraps when the full `\nā¦\n` pair is present,
* so payloads that merely start with the opening tag pass through unchanged ā
* the same defensive guard the metadata rehydration in
* `daemon/conversation.ts` applies.
*/
export function unwrapMemoryBlock(block: string): string {
return block.startsWith("\n") && block.endsWith("\n")
? block.slice("\n".length, -"\n".length)
: block;
}
/**
* The memory-v3 ephemeral spotlight wrapper. Unlike `` card blocks
* (frozen into history), the spotlight block is re-rendered onto the current
* user tail every turn: the per-turn scoped strip in
* `context/strip-injections.ts` (`stripSpotlightInjections`) and the
* compaction matcher in `RUNTIME_INJECTION_PREFIXES` both key off this exact
* prefix/suffix pair, so the producer wrapper lives here beside the ``
* marker it parallels.
*/
export const MEMORY_SPOTLIGHT_PREFIX = "\n";
export const MEMORY_SPOTLIGHT_SUFFIX = "\n";
export function wrapMemorySpotlightBlock(text: string): string {
return `${MEMORY_SPOTLIGHT_PREFIX}${text}${MEMORY_SPOTLIGHT_SUFFIX}`;
}