From 0243c26de63032ffa9f655cc248e7c02e65d0bd1 Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Fri, 16 Jan 2026 14:17:27 +0800 Subject: feat: enhance settings view with AI assistant configuration options Expanded the SettingsView component to include new features for managing the AI assistant, such as selecting language models, configuring response settings, and applying preset personas. Added a button to open the configuration editor for JSON settings. This update improves user interaction with the assistant and provides more control over its behavior and settings. --- ui/src/components/SettingsView.svelte | 386 ++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) diff --git a/ui/src/components/SettingsView.svelte b/ui/src/components/SettingsView.svelte index 76d441b..4de18b3 100644 --- a/ui/src/components/SettingsView.svelte +++ b/ui/src/components/SettingsView.svelte @@ -2,6 +2,9 @@ import { open } from "@tauri-apps/plugin-dialog"; import { settingsState } from "../stores/settings.svelte"; import CustomSelect from "./CustomSelect.svelte"; + import ConfigEditorModal from "./ConfigEditorModal.svelte"; + import { onMount } from "svelte"; + import { RefreshCw, FileJson } from "lucide-svelte"; // Use convertFileSrc directly from settingsState.backgroundUrl for cleaner approach // or use the imported one if passing raw path. @@ -17,6 +20,84 @@ { value: "pastebin.com", label: "pastebin.com (Requires API Key)" } ]; + const llmProviderOptions = [ + { value: "ollama", label: "Ollama (Local)" }, + { value: "openai", label: "OpenAI (Remote)" } + ]; + + const languageOptions = [ + { value: "auto", label: "Auto (Match User)" }, + { value: "English", label: "English" }, + { value: "Chinese", label: "中文" }, + { value: "Japanese", label: "日本語" }, + { value: "Korean", label: "한국어" }, + { value: "Spanish", label: "Español" }, + { value: "French", label: "Français" }, + { value: "German", label: "Deutsch" }, + { value: "Russian", label: "Русский" }, + ]; + + const ttsProviderOptions = [ + { value: "disabled", label: "Disabled" }, + { value: "piper", label: "Piper TTS (Local)" }, + { value: "edge", label: "Edge TTS (Online)" }, + ]; + + const personas = [ + { + value: "default", + label: "Minecraft Expert (Default)", + prompt: "You are a helpful Minecraft expert assistant. You help players with game issues, mod installation, performance optimization, and gameplay tips. Analyze any game logs provided and give concise, actionable advice." + }, + { + value: "technical", + label: "Technical Debugger", + prompt: "You are a technical support specialist for Minecraft. Focus strictly on analyzing logs, identifying crash causes, and providing technical solutions. Be precise and avoid conversational filler." + }, + { + value: "concise", + label: "Concise Helper", + prompt: "You are a direct and concise assistant. Provide answers in as few words as possible while remaining accurate. Use bullet points for lists." + }, + { + value: "explain", + label: "Teacher / Explainer", + prompt: "You are a patient teacher. Explain Minecraft concepts, redstone mechanics, and mod features in simple, easy-to-understand terms suitable for beginners." + }, + { + value: "pirate", + label: "Pirate Captain", + prompt: "You are a salty Minecraft Pirate Captain! Yarr! Speak like a pirate while helping the crew (the user) with their blocky adventures. Use terms like 'matey', 'landlubber', and 'treasure'." + } + ]; + + let selectedPersona = $state(""); + + function applyPersona(value: string) { + const persona = personas.find(p => p.value === value); + if (persona) { + settingsState.settings.assistant.system_prompt = persona.prompt; + selectedPersona = value; // Keep selected to show what's active + } + } + + function resetSystemPrompt() { + const defaultPersona = personas.find(p => p.value === "default"); + if (defaultPersona) { + settingsState.settings.assistant.system_prompt = defaultPersona.prompt; + selectedPersona = "default"; + } + } + + // Load models when assistant settings are shown + function loadModelsForProvider() { + if (settingsState.settings.assistant.llm_provider === "ollama") { + settingsState.loadOllamaModels(); + } else if (settingsState.settings.assistant.llm_provider === "openai") { + settingsState.loadOpenaiModels(); + } + } + async function selectBackground() { try { const selected = await open({ @@ -47,6 +128,15 @@

Settings

+ +
@@ -341,6 +431,298 @@
+ +
+

+ + + + + + + + AI Assistant +

+
+ +
+
+

Enable Assistant

+

Toggle the AI assistant feature on or off.

+
+ +
+ + {#if settingsState.settings.assistant.enabled} + +
+

Language Model

+ +
+
+ + settingsState.saveSettings()} + class="w-full" + /> +
+ + {#if settingsState.settings.assistant.llm_provider === 'ollama'} + +
+
+ +
+ + +
+

+ Default: http://localhost:11434. Make sure Ollama is running. +

+
+ +
+
+ + {#if settingsState.ollamaModels.length > 0} + + {settingsState.ollamaModels.length} installed + + {/if} +
+ + {#if settingsState.isLoadingOllamaModels} +
+ + Loading models... +
+ {:else if settingsState.ollamaModelsError} +
+ {settingsState.ollamaModelsError} +
+ settingsState.saveSettings()} + class="w-full mt-2" + allowCustom={true} + /> + {:else if settingsState.ollamaModels.length === 0} +
+ No models found. Click Refresh to load installed models. +
+ settingsState.saveSettings()} + class="w-full mt-2" + allowCustom={true} + /> + {:else} + settingsState.saveSettings()} + class="w-full" + allowCustom={true} + /> + {/if} + +

+ Run ollama pull {''} to download new models. Or type a custom model name above. +

+
+
+ {:else if settingsState.settings.assistant.llm_provider === 'openai'} + +
+
+ +
+ + +
+

+ Get your API key from OpenAI Dashboard. +

+
+ +
+ + +

+ Use custom endpoint for Azure OpenAI or other compatible APIs. +

+
+ +
+
+ + {#if settingsState.openaiModels.length > 0} + + {settingsState.openaiModels.length} available + + {/if} +
+ + {#if settingsState.isLoadingOpenaiModels} +
+ + Loading models... +
+ {:else if settingsState.openaiModelsError} +
+ {settingsState.openaiModelsError} +
+ settingsState.saveSettings()} + class="w-full" + allowCustom={true} + /> + {:else} + settingsState.saveSettings()} + class="w-full" + allowCustom={true} + /> + {/if} +
+
+ {/if} +
+
+ + +
+

Response Settings

+ +
+
+ + settingsState.saveSettings()} + class="w-full" + /> +
+ +
+
+ + +
+ +
+ ({ value: p.value, label: p.label }))} + bind:value={selectedPersona} + placeholder="Load a preset persona..." + onchange={applyPersona} + class="w-full" + /> +
+ + +

+ Customize how the assistant behaves and responds. +

+
+
+
+ + +
+

Text-to-Speech (Coming Soon)

+ +
+
+
+

Enable TTS

+

Read assistant responses aloud.

+
+ +
+ +
+ + +
+
+
+ {/if} +
+
+
+{#if settingsState.showConfigEditor} + +{/if} + {#if settingsState.showJavaDownloadModal}
-- cgit v1.2.3-70-g09d2