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:
parent
5508374669
commit
a06741397d
@ -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),
|
||||
|
||||
@ -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`;
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user