Improve dashboard LLM validation UX and report flow

This commit is contained in:
2026-02-26 17:53:41 +03:00
parent a8ccf6cb79
commit e97778448d
10 changed files with 1199 additions and 30 deletions

View File

@@ -21,6 +21,8 @@
* @UX_TEST: LoadingHistory -> {openPanel: true, expected: loading block visible}
* @UX_TEST: Sending -> {sendMessage: "branch", expected: send button disabled}
* @UX_TEST: NeedsConfirmation -> {click: confirm action, expected: started response with task_id}
* @TEST_DATA: assistant_llm_ready -> {"llmStatus":{"configured":true,"reason":"ok"},"messages":[{"role":"assistant","text":"Ready","state":"success"}]}
* @TEST_DATA: assistant_llm_not_configured -> {"llmStatus":{"configured":false,"reason":"invalid_api_key"}}
*/
import { onMount } from "svelte";
@@ -40,6 +42,7 @@
getAssistantHistory,
getAssistantConversations,
} from "$lib/api/assistant.js";
import { api } from "$lib/api.js";
import { gitService } from "../../../services/gitService.js";
const HISTORY_PAGE_SIZE = 30;
@@ -62,6 +65,8 @@
let conversationsHasNext = false;
let historyViewport = null;
let initialized = false;
let llmReady = true;
let llmStatusReason = "";
$: isOpen = $assistantChatStore?.isOpen || false;
$: conversationId = $assistantChatStore?.conversationId || null;
@@ -202,6 +207,7 @@
$: if (isOpen && !initialized) {
loadConversations(true);
loadHistory();
loadLlmStatus();
}
$: if (isOpen && initialized && conversationId) {
@@ -502,6 +508,17 @@
onMount(() => {
initialized = false;
});
async function loadLlmStatus() {
try {
const status = await api.getLlmStatus();
llmReady = Boolean(status?.configured);
llmStatusReason = status?.reason || "";
} catch (_err) {
llmReady = false;
llmStatusReason = "status_unavailable";
}
}
</script>
{#if isOpen}
@@ -533,6 +550,21 @@
</div>
<div class="flex h-[calc(100%-56px)] flex-col">
{#if !llmReady}
<div class="mx-3 mt-3 rounded-lg border border-rose-300 bg-rose-50 px-3 py-2 text-xs text-rose-800">
<div class="font-semibold">{$t.dashboard?.llm_not_configured || "LLM is not configured"}</div>
<div class="mt-1 text-rose-700">
{#if llmStatusReason === "no_active_provider"}
{$t.dashboard?.llm_configure_provider || "No active LLM provider. Configure it in Admin -> LLM Settings."}
{:else if llmStatusReason === "invalid_api_key"}
{$t.dashboard?.llm_configure_key || "Invalid LLM API key. Update and save a real key in Admin -> LLM Settings."}
{:else}
{$t.dashboard?.llm_status_unavailable || "LLM status is unavailable. Check settings and backend logs."}
{/if}
</div>
</div>
{/if}
<div class="border-b border-slate-200 px-3 py-2">
<div class="mb-2 flex items-center justify-between">
<span
@@ -726,7 +758,7 @@
bind:value={input}
rows="2"
placeholder={$t.assistant?.input_placeholder}
class="min-h-[52px] w-full resize-y rounded-lg border border-slate-300 px-3 py-2 text-sm outline-none transition focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
class="min-h-[52px] w-full resize-y rounded-lg border px-3 py-2 text-sm outline-none transition {llmReady ? 'border-slate-300 focus:border-sky-400 focus:ring-2 focus:ring-sky-100' : 'border-rose-300 bg-rose-50 focus:border-rose-400 focus:ring-2 focus:ring-rose-100'}"
on:keydown={handleKeydown}
></textarea>
<button