From 653d6d6ed6d4fb401b2c77072ddc39ea7f1d0c1b Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 9 Sep 2026 04:22:15 +0200 Subject: [PATCH] fix: strip [src]/[source] placeholder tokens from rendered answers instead of showing src --- public/js/assistant/citations.js | 6 +++++- test/assistant-citations.test.js | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/public/js/assistant/citations.js b/public/js/assistant/citations.js index 6ca822b..c33db86 100644 --- a/public/js/assistant/citations.js +++ b/public/js/assistant/citations.js @@ -22,7 +22,11 @@ export function safeImageUrl(src) { export function renderAssistantMarkdown(md, sources, options) { var opts = options || {}; - var text = String(md || ''); + var text = String(md || '') + // The model occasionally writes [src]/[source] placeholders instead of + // real citation numbers. Never invent numbers — drop the tokens; the + // sources panel still lists the actual sources. + .replace(/\[(?:src|source)\]/gi, ''); var embedded = textProtection(text, 'html'); // Literal/embedded content bypasses prose, math and citation rewriting, then // rejoins the parsed HTML before the single sanitization boundary. diff --git a/test/assistant-citations.test.js b/test/assistant-citations.test.js index 7214aac..88e2b22 100644 --- a/test/assistant-citations.test.js +++ b/test/assistant-citations.test.js @@ -45,6 +45,15 @@ test('can render citation labels as numbers for PDF export', async () => { assert.match(html, /]*>1<\/a> ]*>2<\/a>/); }); +test('strips [src]/[source] placeholder tokens instead of inventing numbers', async () => { + const { renderAssistantMarkdown } = await loadCitationModule(); + const html = renderAssistantMarkdown('Give fluids [src] and review in 24h [source].', []); + assert.doesNotMatch(html, /\[src\]|\[source\]/i); + assert.match(html, /Give fluids/); + const kept = renderAssistantMarkdown('Give fluids [1] and review.', [{ number: 1, title: 'S', page: 2 }]); + assert.match(kept, /data-source-number="1"/, 'real citation numbers still render'); +}); + test('leaves unknown citation clusters untouched rather than guessing', async () => { const { renderAssistantMarkdown } = await loadCitationModule(); const html = renderAssistantMarkdown('Dose statement [4].', sources);