From 77febc65d63ccbb69aa82c2cab8d644e5aa8ccae Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:05:34 +0200 Subject: [PATCH] fix: external knowledge citations show the domain instead of the page title (#31982) The inline citation markers in answers from external knowledge bases (Qdrant, Milvus, pgvector) showed the site's domain, for example docs.example.test, instead of the page title saved with each document. They now show that title, the same way a regular knowledge base shows the file name, and still fall back to the domain when a document has no title. Two different pages can share a title, so each marker now looks up its title by the page it points to; before, a repeated title made every later marker show the next page's title and the last one show nothing. Fixes https://github.com/open-webui/open-webui/issues/31929 --- backend/open_webui/retrieval/external.py | 2 +- src/lib/components/chat/Messages/ContentRenderer.svelte | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/retrieval/external.py b/backend/open_webui/retrieval/external.py index 269b6db8cd..efb0e1a60b 100644 --- a/backend/open_webui/retrieval/external.py +++ b/backend/open_webui/retrieval/external.py @@ -47,7 +47,7 @@ def _normalize_result(result: dict, mapping: dict, knowledge: KnowledgeModel, di source_name = source or title or metadata.get('source') or metadata.get('name') or knowledge.name metadata.update( { - 'name': title or source_name, + 'name': title or metadata.get('name') or source_name, 'source': source_name, 'url': url, 'file_id': document_id or f'external-{knowledge.id}', diff --git a/src/lib/components/chat/Messages/ContentRenderer.svelte b/src/lib/components/chat/Messages/ContentRenderer.svelte index bcd233b130..05bc83822f 100644 --- a/src/lib/components/chat/Messages/ContentRenderer.svelte +++ b/src/lib/components/chat/Messages/ContentRenderer.svelte @@ -105,6 +105,7 @@ const getSourceIds = (sources) => { const result = []; + const seenIds = new Set(); for (const source of sources ?? []) { for (let index = 0; index < (source.document ?? []).length; index++) { if (model?.info?.meta?.capabilities?.citations == false) { @@ -112,7 +113,11 @@ continue; } const metadata = source.metadata?.[index]; - const id = metadata?.source ?? 'N/A'; + const id = metadata?.source ?? source?.source?.id ?? 'N/A'; + if (seenIds.has(id)) { + continue; + } + seenIds.add(id); if (metadata?.name) { result.push(metadata.name); } else if (id.startsWith('http://') || id.startsWith('https://')) { @@ -122,7 +127,7 @@ } } } - sourceIds = [...new Set(result)]; + sourceIds = result; }; /** @param {string} messageContent */