feat: Web-Search Sources anzeigen (Streaming + History + Archive + Shared)
Backend: - web_search_tool_result Sources extrahieren (url, title) - Als 'web_search_result' Message-Typ in DB persistieren - Sources im web_search_end SSE-Event mitsenden - Alle 3 Chat-Pfade: StreamChat, RunAgentChat, ChatNonStreaming Frontend: - renderToolBoxContent: Sources-Sektion mit klickbaren Domain-Links - finishToolBox/addToolBoxStatic: sources-Parameter durchgereicht - History: web_search_result Message-Typ in allen 3 Render-Pfaden - web_search immer sichtbar (auch bei 'modifications' Filter) CSS: - .web-search-sources: Flex-Wrap Container - .web-search-source: Domain-Pill mit Hover-Effekt, Title-Ellipsis
This commit is contained in:
1 parent
116f21105c
commit
f64052caf4
5 files changed
+221
-7
No files matched your search
+25
-5
@@ -823,7 +823,8 @@ function isToolVisible(toolName) {
|
||||
const mode = loadSettings().toolCallDisplay;
|
||||
if (mode === 'all') return true;
|
||||
if (mode === 'hidden') return false;
|
||||
// 'modifications' – nur modifizierende Tools anzeigen
|
||||
// 'modifications' – nur modifizierende Tools + web_search anzeigen
|
||||
if (toolName === 'web_search') return true;
|
||||
return MODIFICATION_TOOLS.includes(toolName);
|
||||
}
|
||||
|
||||
@@ -855,7 +856,7 @@ function addToolBoxLoading(name) {
|
||||
return div;
|
||||
}
|
||||
|
||||
function renderToolBoxContent(div, name, inputJson, result, isError) {
|
||||
function renderToolBoxContent(div, name, inputJson, result, isError, sources) {
|
||||
let parsedInput = null;
|
||||
try { parsedInput = JSON.parse(inputJson); } catch {}
|
||||
|
||||
@@ -879,6 +880,25 @@ function renderToolBoxContent(div, name, inputJson, result, isError) {
|
||||
|
||||
let foldTarget = null;
|
||||
|
||||
// Web-Search Sources – immer sichtbar, kein Toggle
|
||||
if (name === 'web_search' && sources && sources.length > 0) {
|
||||
const sourcesList = document.createElement('div');
|
||||
sourcesList.className = 'web-search-sources';
|
||||
sources.forEach(function(s) {
|
||||
const link = document.createElement('a');
|
||||
link.href = s.url;
|
||||
link.target = '_blank';
|
||||
link.rel = 'noopener noreferrer';
|
||||
link.className = 'web-search-source';
|
||||
var domain = '';
|
||||
try { domain = new URL(s.url).hostname.replace('www.', ''); } catch(e) { domain = s.url; }
|
||||
link.innerHTML = '<i class="fa fa-external-link"></i> <span class="source-domain">' + esc(domain) + '</span>' +
|
||||
(s.title ? '<span class="source-title">' + esc(s.title) + '</span>' : '');
|
||||
sourcesList.appendChild(link);
|
||||
});
|
||||
div.appendChild(sourcesList);
|
||||
}
|
||||
|
||||
if (name === 'edit_file' && parsedInput && parsedInput.path) {
|
||||
const pathSpan = document.createElement('span');
|
||||
pathSpan.className = 'tool-input';
|
||||
@@ -1072,15 +1092,15 @@ function buildTodoList(result, isError) {
|
||||
|
||||
function finishToolBox(div, data) {
|
||||
if (!div) return;
|
||||
renderToolBoxContent(div, data.name, data.input, data.result, data.isError);
|
||||
renderToolBoxContent(div, data.name, data.input, data.result, data.isError, data.sources);
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
function addToolBoxStatic(name, input, result, isError) {
|
||||
function addToolBoxStatic(name, input, result, isError, sources) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'tool-box';
|
||||
div.dataset.toolName = name;
|
||||
renderToolBoxContent(div, name, input, result, isError);
|
||||
renderToolBoxContent(div, name, input, result, isError, sources);
|
||||
chatEl().appendChild(div);
|
||||
scrollDown();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user