Lumi/plugins/lumi_ai_web_search/public/settings-modal.js
2026-06-14 05:01:13 +02:00

104 lines
3.9 KiB
JavaScript

(() => {
if (window.LumiWebSearchSettingsLoaded) return;
window.LumiWebSearchSettingsLoaded = true;
window.addEventListener("lumi-ai-tool-settings-open", (event) => {
if (event.detail?.toolId !== "lumi_ai_web_search") return;
const root = event.detail.root?.querySelector("[data-web-search-settings]");
if (!root) return;
const payload = event.detail.payload || {};
const values = payload.values || {};
const status = payload.status || {};
set(root, "provider", status.provider || values.provider || "lumi_search_broker");
set(root, "provider_health", status.provider_health || "not_tested");
set(root, "policy_mode", values.policy_mode || "blacklist");
set(root, "last_success_at", status.last_success_at ? new Date(status.last_success_at).toLocaleString() : "Never");
set(root, "last_error", status.last_error || "None");
set(root, "cache", `${status.cache?.entries || 0} entries, ${formatBytes(status.cache?.bytes || 0)}`);
renderCapabilities(root, values);
renderRecent(root, status.recent || []);
bindTest(root);
});
function set(root, key, value) {
const target = root.querySelector(`[data-web-status="${key}"]`);
if (target) target.textContent = String(value);
}
function renderCapabilities(root, values) {
const target = root.querySelector("[data-web-capabilities]");
target.replaceChildren();
for (const [id, enabled] of [
["web_search.search", values.enable_search],
["web_search.fetch_url", values.enable_fetch_url],
["web_search.summarize_url", values.enable_summarize_url]
]) {
const badge = document.createElement("span");
badge.className = `ai-tag ${enabled ? "installed" : ""}`.trim();
badge.textContent = `${id}: ${enabled ? "enabled" : "disabled"}`;
target.append(badge);
}
}
function renderRecent(root, rows) {
const target = root.querySelector("[data-web-recent]");
target.replaceChildren();
if (!rows.length) {
target.textContent = "No calls recorded.";
return;
}
for (const row of rows.slice(0, 10)) {
const item = document.createElement("div");
item.textContent = [
row.timestamp ? new Date(row.timestamp).toLocaleString() : "",
row.capability,
row.origin,
row.status,
row.blocked_reason,
`${row.timing_ms || 0} ms`,
row.query_summary
].filter(Boolean).join(" | ");
target.append(item);
}
}
function bindTest(root) {
const form = root.querySelector("[data-web-search-test]");
const output = root.querySelector("[data-web-search-test-output]");
if (!form || form.dataset.bound === "1") return;
form.dataset.bound = "1";
form.addEventListener("submit", async (event) => {
event.preventDefault();
const data = new FormData(form);
output.hidden = false;
output.textContent = "Running through discovery, prompt exposure, and the normal tool pipeline...";
try {
const response = await fetch("/plugins/lumi_ai/assistant/test", {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
role: "admin",
origin: data.get("origin"),
message: data.get("query"),
allow_tools: true,
show_raw_prompt: true,
show_raw_output: false
})
});
const payload = await response.json();
if (!response.ok) throw new Error(payload.error || "Web-search test failed.");
output.textContent = JSON.stringify(payload, null, 2);
} catch (error) {
output.textContent = error.message;
}
});
}
function formatBytes(value) {
const bytes = Number(value) || 0;
if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${bytes} B`;
}
})();