From 1e13f79899622dd8a5c268b5b8e854b14f82d87f Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Thu, 21 May 2026 20:59:24 +0900 Subject: feat: system prompt editor, tool permissions save-on-send, responsive sidebar, UI polish - System Prompt sidebar view: editable textarea, save-on-send, reset button - Tool permissions: save-on-send pattern (not immediate), reset button - Dynamic system prompt: buildSystemPrompt reads from DB, tool list auto-generated - Responsive sidebar: overlay on small screens with backdrop - Chat bubbles: user=fit-width, assistant=full-width - Fix infinite loops (use onMount for data fetching) - Fix sendMessage race condition (await settings saves before chat POST) - Model selector: auto-open model modal after key selection - Rename views: Permissions->Tools, Tab Settings->Model Choice - Shared appSettings store for cross-component reactive state - Delete old chat.svelte.ts --- .../frontend/src/lib/components/ChatMessage.svelte | 4 +- .../src/lib/components/ModelSelector.svelte | 17 +++--- .../src/lib/components/PermissionLog.svelte | 43 ++++++++------- .../src/lib/components/SidebarPanel.svelte | 9 ++-- .../src/lib/components/SystemPromptPanel.svelte | 61 ++++++++++++++++++++++ 5 files changed, 103 insertions(+), 31 deletions(-) create mode 100644 packages/frontend/src/lib/components/SystemPromptPanel.svelte (limited to 'packages/frontend/src/lib/components') diff --git a/packages/frontend/src/lib/components/ChatMessage.svelte b/packages/frontend/src/lib/components/ChatMessage.svelte index 4db57c3..398bee8 100644 --- a/packages/frontend/src/lib/components/ChatMessage.svelte +++ b/packages/frontend/src/lib/components/ChatMessage.svelte @@ -21,8 +21,8 @@ const isSystem = $derived(message.role === "system"); {:else} -
-
+
+
{#if message.thinking}
diff --git a/packages/frontend/src/lib/components/ModelSelector.svelte b/packages/frontend/src/lib/components/ModelSelector.svelte index b88b2e3..0af5ae6 100644 --- a/packages/frontend/src/lib/components/ModelSelector.svelte +++ b/packages/frontend/src/lib/components/ModelSelector.svelte @@ -44,16 +44,19 @@ function selectKey(keyId: string) { showKeyModal = false; onKeyChange(keyId); + // Immediately open model selection for the new key + openModelModal(keyId); } - async function openModelModal() { - if (!activeKeyId) return; + async function openModelModal(keyIdOverride?: string) { + const keyId = keyIdOverride ?? activeKeyId; + if (!keyId) return; showModelModal = true; modelError = null; // Check session cache - if (modelCache.has(activeKeyId)) { - availableModels = modelCache.get(activeKeyId)!; + if (modelCache.has(keyId)) { + availableModels = modelCache.get(keyId)!; loadingModels = false; return; } @@ -63,7 +66,7 @@ try { const res = await fetch( - `${config.apiBase}/models/available?keyId=${encodeURIComponent(activeKeyId)}`, + `${config.apiBase}/models/available?keyId=${encodeURIComponent(keyId)}`, ); if (!res.ok) { const data = await res.json().catch(() => ({})); @@ -73,7 +76,7 @@ const data = await res.json(); availableModels = data.models ?? []; // Cache for session - modelCache.set(activeKeyId, availableModels); + modelCache.set(keyId, availableModels); } catch (err) { modelError = err instanceof Error ? err.message : "Failed to fetch models"; } finally { @@ -99,7 +102,7 @@
Model -
diff --git a/packages/frontend/src/lib/components/PermissionLog.svelte b/packages/frontend/src/lib/components/PermissionLog.svelte index 06607de..7733dcf 100644 --- a/packages/frontend/src/lib/components/PermissionLog.svelte +++ b/packages/frontend/src/lib/components/PermissionLog.svelte @@ -1,5 +1,7 @@
Tool Permissions
+

Changes are applied when you send your next message.

{#each toolPermissions as perm (perm.id)} @@ -63,7 +60,7 @@ $effect(() => { togglePermission(perm.id)} />
@@ -74,6 +71,14 @@ $effect(() => { {/each}
+ +

Warning: changing tool access will reset the AI's prompt cache for active conversations, which may increase usage costs.

diff --git a/packages/frontend/src/lib/components/SidebarPanel.svelte b/packages/frontend/src/lib/components/SidebarPanel.svelte index 9aca408..93d528e 100644 --- a/packages/frontend/src/lib/components/SidebarPanel.svelte +++ b/packages/frontend/src/lib/components/SidebarPanel.svelte @@ -8,6 +8,7 @@ import KeyUsage from "./KeyUsage.svelte"; import ClaudeReset from "./ClaudeReset.svelte"; import SettingsPanel from "./SettingsPanel.svelte"; + import SystemPromptPanel from "./SystemPromptPanel.svelte"; import type { TaskItem, LogEntry, KeyInfo } from "../types.js"; const { @@ -42,7 +43,7 @@ let nextId = 0; let panels = $state([{ id: nextId++, selected: "Model Choice" }]); - const viewOptions = ["Select a view", "Model Choice", "Key Usage", "Claude Reset", "Model Status", "Tasks", "Config", "Skills", "Permissions", "Settings"]; + const viewOptions = ["Select a view", "Model Choice", "Key Usage", "Claude Reset", "Model Status", "Tasks", "Config", "Skills", "Tools", "System Prompt", "Settings"]; function addPanel() { panels = [...panels, { id: nextId++, selected: "Select a view" }]; @@ -113,9 +114,11 @@ {:else if panel.selected === "Skills"} - {:else if panel.selected === "Permissions"} + {:else if panel.selected === "Tools"} - {:else if panel.selected === "Settings"} + {:else if panel.selected === "System Prompt"} + + {:else if panel.selected === "Settings"} {/if}
diff --git a/packages/frontend/src/lib/components/SystemPromptPanel.svelte b/packages/frontend/src/lib/components/SystemPromptPanel.svelte new file mode 100644 index 0000000..6b91ebe --- /dev/null +++ b/packages/frontend/src/lib/components/SystemPromptPanel.svelte @@ -0,0 +1,61 @@ + + +
+
System Prompt
+

The base instructions sent to the AI at the start of every conversation. Tool descriptions are appended automatically. Changes are applied when you send your next message.

+ + + + + +

Warning: changing the system prompt will reset the AI's prompt cache for active conversations, which may increase usage costs.

+
-- cgit v1.2.3