From d7cf6f3fc47f7b8bbcef6b49a475572234008ff6 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Mon, 15 Jun 2026 02:05:01 +0200 Subject: [PATCH] Feat(Library): Enhance metadata handling and display Improves search filtering to include summary, headline, keywords, and entities from item metadata. Adds comprehensive metadata display (summary, chips, entities) on content cards. Introduces deep enrichment status indicators and adds functionality to trigger metadata generation. --- src/LibraryManager.jsx | 59 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/LibraryManager.jsx b/src/LibraryManager.jsx index c1544c8..3abe083 100644 --- a/src/LibraryManager.jsx +++ b/src/LibraryManager.jsx @@ -19,7 +19,7 @@ function itemSyncMeta(item) { status, progress: 100, label: 'Available', - detail: detail || (enrichEnabled ? 'Ready in chat with enrichment enabled.' : 'Ready in chat with raw indexing only.') + detail: detail || (enrichEnabled ? 'Ready with standard metadata and deep enrichment.' : 'Ready with standard metadata.') } } if (status === 'failed') { @@ -287,7 +287,17 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) { body: JSON.stringify({ rel: item.rel, enabled }) }) return expectJson(response) - }) + }, enabled ? 'Deep enrichment enabled. Metadata is being updated.' : 'Using standard metadata only.') + } catch {} + } + + async function generateMetadata() { + if (!library) return + try { + await runAction(async () => { + const response = await fetch(`${apiBase}/libraries/${library.slug}/jobs/prepare`, { method: 'POST' }) + return expectJson(response) + }, 'Generating metadata for this database.') } catch {} } @@ -311,9 +321,20 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) { const filteredItems = useMemo(() => { const term = search.trim().toLowerCase() if (!term) return items - return items.filter(item => [item.title, item.name, item.path, item.url, item.kind] + return items.filter(item => [ + item.title, + item.name, + item.path, + item.url, + item.kind, + item.metadata?.headline, + item.metadata?.summary, + ...(item.metadata?.keywords || []), + ...(item.metadata?.entities || []).map(entity => entity?.name) + ] .some(value => String(value || '').toLowerCase().includes(term))) }, [items, search]) + const hasMissingMetadata = items.some(item => !['ready', 'fallback'].includes(item?.metadata?.status)) useEffect(() => { if (!library?.slug) { @@ -415,6 +436,9 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) { const itemId = item.item_id || item.sha256 || item.rel const isExpanded = expandedItemId === itemId const preview = contentPreviews[itemId] + const metadata = item.metadata || {} + const keywords = Array.isArray(metadata.keywords) ? metadata.keywords.slice(0, 6) : [] + const entities = Array.isArray(metadata.entities) ? metadata.entities.slice(0, 4) : [] return (
@@ -424,7 +448,29 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) {
{item.title || item.name || item.path}
{source}
- {item.enrich_enabled ? 'Enrichment on' : 'Raw only'} + {item.enrich_enabled ? 'Deep enrichment' : 'Standard'} +
+
+ {metadata.summary ? ( +

{metadata.summary}

+ ) : ( +

+ {metadata.status === 'pending' ? 'Metadata is being generated.' : 'No automatic metadata has been generated yet.'} +

+ )} + {keywords.length > 0 && ( +
+ {keywords.map(keyword => {keyword})} +
+ )} + {entities.length > 0 && ( +
+ {entities.map(entity => ( + {entity.name}{entity.type ? ` ยท ${entity.type}` : ''} + ))} +
+ )} + {metadata.status === 'fallback' &&
Local model metadata was unavailable; Heimgeist used a text fallback.
}
{sync.detail}
@@ -456,7 +502,7 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) { {item.kind === 'website' && } {(!item.kind || item.kind === 'file') && }
@@ -473,6 +519,9 @@ export default function LibraryManager({ apiBase, library, jobs, onRefresh }) { + {items.length > 0 && hasMissingMetadata && !isSyncing && isReadyForChat && ( + + )} {items.length > 0 && !isSyncing && !isReadyForChat && ( )}