fix: add clear separator between metadata and user message

Problem: When a user message is passed to the LLM, metadata blocks
(sender info, conversation info, etc.) are joined with the actual user
content using only double newlines. This causes the LLM to sometimes
misinterpret the structure, treating metadata as the entire message.

Solution: Insert a visible "---\n**User Message:**" separator between
metadata and user content. Both sanitizer functions strip it after
removing metadata blocks so it never appears in user-facing surfaces.

Changes:
- get-reply-run.ts: inject separator when metadata is present
- strip-inbound-meta.ts: strip separator after metadata removal in
  both stripInboundMetadata and stripLeadingInboundMetadata
- strip-inbound-meta.test.ts: add separator stripping tests
This commit is contained in:
Cursor Agent 2026-03-19 13:41:50 +00:00
parent 5508374669
commit a06741397d
No known key found for this signature in database
3 changed files with 36 additions and 3 deletions

View File

@ -307,7 +307,9 @@ export async function runPreparedReply(
);
const baseBodyForPrompt = isBareSessionReset
? baseBodyFinal
: [inboundUserContext, baseBodyFinal].filter(Boolean).join("\n\n");
: inboundUserContext
? `${inboundUserContext}\n\n---\n**User Message:**\n${baseBodyFinal}`
: baseBodyFinal;
const baseBodyTrimmed = baseBodyForPrompt.trim();
const hasMediaAttachment = Boolean(
sessionCtx.MediaPath || (sessionCtx.MediaPaths && sessionCtx.MediaPaths.length > 0),

View File

@ -146,6 +146,28 @@ Hello`;
});
});
describe("user-message separator stripping", () => {
it("strips separator after metadata removal", () => {
const input = `${CONV_BLOCK}\n\n---\n**User Message:**\nHello world`;
expect(stripInboundMetadata(input)).toBe("Hello world");
});
it("strips separator with multiple metadata blocks", () => {
const input = `${CONV_BLOCK}\n\n${SENDER_BLOCK}\n\n---\n**User Message:**\nHello world`;
expect(stripInboundMetadata(input)).toBe("Hello world");
});
it("preserves separator when no metadata blocks are present", () => {
const input = `---\n**User Message:**\nHello world`;
expect(stripInboundMetadata(input)).toBe(input);
});
it("preserves user content starting with --- when it is not the separator", () => {
const input = `${CONV_BLOCK}\n\n---\nSome regular content`;
expect(stripInboundMetadata(input)).toBe("---\nSome regular content");
});
});
describe("extractInboundSenderLabel", () => {
it("returns the sender label block when present", () => {
const input = `${CONV_BLOCK}\n\n${SENDER_BLOCK}\n\nHello from user`;

View File

@ -184,7 +184,16 @@ export function stripInboundMetadata(text: string): string {
result.push(line);
}
return result.join("\n").replace(/^\n+/, "").replace(/\n+$/, "");
return stripUserMessageSeparator(result.join("\n").replace(/^\n+/, "").replace(/\n+$/, ""));
}
/**
* Removes the `---\n**User Message:**` separator injected between metadata and
* user content. Called after metadata blocks have already been stripped so the
* separator (if any) is now a leading artefact in the remaining text.
*/
function stripUserMessageSeparator(text: string): string {
return text.replace(/^[\t ]*---[\t ]*\n[\t ]*\*\*User Message:\*\*[\t ]*\n?/, "");
}
export function stripLeadingInboundMetadata(text: string): string {
@ -232,7 +241,7 @@ export function stripLeadingInboundMetadata(text: string): string {
}
const strippedRemainder = stripTrailingUntrustedContextSuffix(lines.slice(index));
return strippedRemainder.join("\n");
return stripUserMessageSeparator(strippedRemainder.join("\n"));
}
export function extractInboundSenderLabel(text: string): string | null {