Lumi/plugins/lumi_ai/backend/assistant_visibility.js
2026-06-12 19:27:43 +02:00

94 lines
2.9 KiB
JavaScript

const fs = require("fs");
const { canUseAssistant } = require("./assistant_permissions");
const CONDITION_KEYS = Object.freeze([
"plugin_enabled",
"assistant_enabled",
"role_allowed",
"user_logged_in",
"model_installed",
"runtime_installed",
"runtime_running",
"runtime_healthy",
"assistant_slot_found",
"frontend_loader_loaded",
"panel_html_returned",
"mount_successful"
]);
function buildVisibilityDiagnostics({
user,
config,
model,
runtimeHealth = {},
providerAvailable = true,
frontend = {},
origin = "webui",
platform = origin,
requestedSurface = "webui_panel",
roleHint = null
}) {
const permission = canUseAssistant({
user,
config,
origin,
platform,
requestedSurface,
roleHint
});
const backend = {
plugin_enabled: Boolean(providerAvailable),
assistant_enabled: Boolean(config?.enabled && config?.assistant_enabled !== false),
role_allowed: permission.debug_details.role_allowed,
user_logged_in: Boolean(user?.id),
model_installed: Boolean(
model &&
runtimeHealth.model_downloaded &&
runtimeHealth.model_path &&
fs.existsSync(runtimeHealth.model_path)
),
runtime_installed: Boolean(runtimeHealth.runtime_installed),
runtime_running: runtimeHealth.state === "running",
runtime_healthy: Boolean(
runtimeHealth.healthy &&
runtimeHealth.runtime_usable !== false &&
runtimeHealth.last_self_test?.success !== false
)
};
const conditions = {
...backend,
assistant_slot_found: Boolean(frontend.assistant_slot_found),
frontend_loader_loaded: Boolean(frontend.frontend_loader_loaded),
panel_html_returned: Boolean(frontend.panel_html_returned),
mount_successful: Boolean(frontend.mount_successful)
};
const coldStartAvailable = Boolean(
backend.plugin_enabled &&
backend.assistant_enabled &&
backend.role_allowed &&
backend.user_logged_in &&
backend.model_installed &&
backend.runtime_installed &&
runtimeHealth.state === "stopped" &&
runtimeHealth.runtime_usable !== false &&
runtimeHealth.last_self_test?.success !== false
);
const backendAvailable = Object.values(backend).every(Boolean) || coldStartAvailable;
const reasonOrder = [
"user_logged_in", "plugin_enabled", "assistant_enabled", "role_allowed",
"model_installed", "runtime_installed", "runtime_running", "runtime_healthy"
];
const firstFailure = reasonOrder.find((key) => !backend[key]) || null;
return {
available: backendAvailable,
status: coldStartAvailable ? "cold_start" : backendAvailable ? "healthy" : "offline",
reason_code: coldStartAvailable ? null : firstFailure,
cold_start_available: coldStartAvailable,
conditions: CONDITION_KEYS.map((key) => ({ key, passed: conditions[key] })),
permission,
updated_at: new Date().toISOString()
};
}
module.exports = { CONDITION_KEYS, buildVisibilityDiagnostics };