add optional web search functionality with UI updates and backend integration
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/** @typedef {{title: string, url: string, snippet: string}} WebSource */
|
||||
/** @typedef {{message: string, model: string, chatId: number, webSearch?: boolean}} ChatRequest */
|
||||
/** @typedef {{role: string, content: string, sources?: WebSource[]}} ChatMessage */
|
||||
|
||||
export function createWebSearchToggle(button) {
|
||||
let enabled = false;
|
||||
const reset = () => {
|
||||
enabled = false;
|
||||
render();
|
||||
};
|
||||
const render = () => {
|
||||
button.setAttribute("aria-pressed", String(enabled));
|
||||
button.title = enabled ? "Web search enabled" : "Search the web";
|
||||
button.setAttribute("aria-label", button.title);
|
||||
};
|
||||
button.addEventListener("click", () => {
|
||||
enabled = !enabled;
|
||||
render();
|
||||
});
|
||||
render();
|
||||
return {get enabled() { return enabled; }, reset};
|
||||
}
|
||||
|
||||
/** @param {HTMLElement} container @param {WebSource[] | undefined} sources */
|
||||
export function appendSources(container, sources) {
|
||||
if (!Array.isArray(sources) || !sources.length) return;
|
||||
const section = document.createElement("section");
|
||||
section.className = "msg-sources";
|
||||
section.setAttribute("aria-label", "Sources");
|
||||
const heading = document.createElement("div");
|
||||
heading.className = "msg-sources-heading";
|
||||
heading.textContent = "Sources";
|
||||
section.appendChild(heading);
|
||||
sources.slice(0, 5).forEach((source, index) => {
|
||||
let url;
|
||||
try { url = new URL(source.url); } catch { return; }
|
||||
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password) return;
|
||||
const link = document.createElement("a");
|
||||
link.href = url.href;
|
||||
link.target = "_blank";
|
||||
link.rel = "noopener noreferrer";
|
||||
link.className = "msg-source";
|
||||
const title = document.createElement("span");
|
||||
title.textContent = `[${index + 1}] ${source.title}`;
|
||||
title.title = source.title;
|
||||
const domain = document.createElement("small");
|
||||
domain.textContent = url.hostname;
|
||||
link.append(title, domain);
|
||||
section.appendChild(link);
|
||||
});
|
||||
if (section.childElementCount > 1) container.appendChild(section);
|
||||
}
|
||||
Reference in New Issue
Block a user