diff --git a/python/extensions/banners/_20_missing_api_key.py b/python/extensions/banners/_20_missing_api_key.py index 9d31a5b50..672f8d3bb 100644 --- a/python/extensions/banners/_20_missing_api_key.py +++ b/python/extensions/banners/_20_missing_api_key.py @@ -54,9 +54,9 @@ class MissingApiKeyCheck(Extension): "id": "missing-api-key", "type": "error", "priority": 100, - "title": "Missing API Key", - "html": f"""No API key configured for: {model_list}. - Agent Zero will not be able to function properly. + "title": "Missing LLM API Key for current settings", + "html": f"""No API key configured for: {model_list}.
+ Agent Zero will not be able to function properly unless you provide an API key or change your settings.
Add your API key in Settings → External Services → API Keys.""", "dismissible": False, diff --git a/webui/components/sidebar/chats/chats-store.js b/webui/components/sidebar/chats/chats-store.js index a2f1cdcfa..ab72e791d 100644 --- a/webui/components/sidebar/chats/chats-store.js +++ b/webui/components/sidebar/chats/chats-store.js @@ -27,11 +27,10 @@ const model = { }, init() { - // Initialize from localStorage - const lastSelectedChat = localStorage.getItem("lastSelectedChat"); + // Initialize from sessionStorage + const lastSelectedChat = sessionStorage.getItem("lastSelectedChat"); if (lastSelectedChat) { this.selectChat(lastSelectedChat); - // this.selected = lastSelectedChat; } }, @@ -260,11 +259,15 @@ const model = { // Set selected context setSelected(contextId) { - this.selected = contextId; - this.selectedContext = this.contexts.find((ctx) => ctx.id === contextId); + this.selected = contextId || ""; + this.selectedContext = this.contexts.find((ctx) => ctx.id === this.selected); // if not found in contexts, try to find in tasks < not nice, will need refactor later - if(!this.selectedContext) this.selectedContext = tasksStore.tasks.find((ctx) => ctx.id === contextId); - localStorage.setItem("lastSelectedChat", contextId); + if(!this.selectedContext) this.selectedContext = tasksStore.tasks.find((ctx) => ctx.id === this.selected); + if (this.selected) { + sessionStorage.setItem("lastSelectedChat", this.selected); + } else { + sessionStorage.removeItem("lastSelectedChat"); + } }, // Restart the backend diff --git a/webui/components/welcome/welcome-screen.html b/webui/components/welcome/welcome-screen.html index a5252eb9e..de3d5d84a 100644 --- a/webui/components/welcome/welcome-screen.html +++ b/webui/components/welcome/welcome-screen.html @@ -10,88 +10,71 @@
@@ -109,6 +92,39 @@ background: var(--color-background); color: var(--color-text); min-height: 100vh; + position: relative; + overflow: hidden; + } + + .welcome-container::before { + content: ""; + position: absolute; + inset: 0; + background-image: url("./public/darkSymbol.svg"); + background-repeat: no-repeat; + background-position: center; + background-size: 80% auto; + opacity: 0.07; + pointer-events: none; + } + + .light-mode .welcome-container::before { + filter: invert(0.55); + opacity: 0.06; + } + + .dark-mode .welcome-container::before { + filter: invert(0.85); + opacity: 0.08; + } + + .welcome-content { + position: relative; + z-index: 1; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; } /* Welcome container styles */ @@ -153,9 +169,9 @@ .welcome-actions { display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 1.2rem; - max-width: 520px; + grid-template-columns: repeat(4, 1fr); + gap: 1rem; + max-width: 640px; width: 100%; margin: 1.5rem 0; } @@ -164,7 +180,7 @@ background: var(--color-panel); border: 1px solid var(--color-border); border-radius: 12px; - padding: 1.5rem; + padding: 0.6rem; transition: all 0.3s ease; cursor: pointer; text-decoration: none; @@ -173,8 +189,8 @@ flex-direction: column; align-items: center; text-align: center; - min-height: 10rem; justify-content: center; + aspect-ratio: 1 / 1; } .welcome-action-card:hover { @@ -183,15 +199,13 @@ } .welcome-action-icon { - font-size: 2rem; - margin-bottom: 0; + font-size: 2.1rem; + margin-bottom: 0.25rem; color: var(--color-highlight-dark); } - .welcome-action-description { - font-size: 0.8rem; - color: var(--color-secondary); - line-height: 1.3; + .welcome-action-title { + font-size: 0.9rem; } /* Banner Styles */ @@ -199,7 +213,7 @@ display: flex; flex-direction: column; gap: 0.75rem; - max-width: 520px; + max-width: 680px; width: 100%; margin-top: 1.5rem; } @@ -383,14 +397,14 @@ } .welcome-actions { - grid-template-columns: 1fr; + grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-bottom: 2rem; } .welcome-action-card { - padding: 1.5rem; - min-height: 120px; + padding: 1rem; + aspect-ratio: 1 / 1; } .welcome-action-icon { diff --git a/webui/components/welcome/welcome-store.js b/webui/components/welcome/welcome-store.js index 4da18c9ed..9c6981303 100644 --- a/webui/components/welcome/welcome-store.js +++ b/webui/components/welcome/welcome-store.js @@ -3,6 +3,7 @@ import { getContext } from "/index.js"; import { store as chatsStore } from "/components/sidebar/chats/chats-store.js"; import { store as memoryStore } from "/components/modals/memory/memory-dashboard-store.js"; import { store as projectsStore } from "/components/projects/projects-store.js"; +import { store as chatInputStore } from "/components/chat/input/input-store.js"; import * as API from "/js/api.js"; const model = { @@ -176,6 +177,9 @@ const model = { case "new-chat": chatsStore.newChat(); break; + case "scheduler": + window.openModal("modals/scheduler/scheduler-modal.html"); + break; case "settings": // Open settings modal const settingsButton = document.getElementById("settings"); @@ -189,6 +193,9 @@ const model = { case "memory": memoryStore.openModal(); break; + case "files": + chatInputStore.browseFiles(); + break; case "website": window.open("https://agent-zero.ai", "_blank"); break; diff --git a/webui/index.js b/webui/index.js index a9c70362e..2cd28e367 100644 --- a/webui/index.js +++ b/webui/index.js @@ -387,20 +387,7 @@ export async function poll() { } } } else { - const welcomeStore = - globalThis.Alpine && typeof globalThis.Alpine.store === "function" - ? globalThis.Alpine.store("welcomeStore") - : null; - const welcomeVisible = Boolean(welcomeStore && welcomeStore.isVisible); - - // No context selected, try to select the first available item unless welcome screen is active - if (!welcomeVisible && contexts.length > 0) { - const firstChatId = chatsStore.firstId(); - if (firstChatId) { - setContext(firstChatId); - chatsStore.setSelected(firstChatId); - } - } + // No context selected: keep it that way so the welcome screen stays visible. } lastLogVersion = response.log_version; @@ -528,7 +515,9 @@ export const deselectChat = function () { // Clear current context to show welcome screen setContext(null); - // Clear localStorage selections so we don't auto-restore + // Clear selections so we don't auto-restore + sessionStorage.removeItem("lastSelectedChat"); + sessionStorage.removeItem("lastSelectedTask"); localStorage.removeItem("lastSelectedChat"); localStorage.removeItem("lastSelectedTask");