From 2bc1111f8d789622713473e8b00f25a4f073459b Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Wed, 11 Feb 2026 09:14:22 +0100 Subject: [PATCH] refactor: Cleanup --- .../ChatMessages/ChatMessageStatistics.svelte | 13 +- .../app/chat/ChatSettings/ChatSettings.svelte | 177 +++++++++--------- .../ChatSettings/ChatSettingsFields.svelte | 14 +- .../app/content/MarkdownContent.svelte | 5 + .../dialogs/DialogMcpResourcePreview.svelte | 2 +- .../mcp-resource-browser.ts | 2 +- .../server/webui/src/lib/constants/agentic.ts | 5 + tools/server/webui/src/lib/constants/cache.ts | 12 ++ .../webui/src/lib/constants/formatters.ts | 3 + .../webui/src/lib/constants/mcp-resource.ts | 15 ++ .../webui/src/lib/constants/settings-keys.ts | 57 ++++++ tools/server/webui/src/lib/enums/index.ts | 2 +- tools/server/webui/src/lib/enums/settings.ts | 10 + .../webui/src/lib/stores/agentic.svelte.ts | 36 ++-- .../src/lib/stores/mcp-resources.svelte.ts | 13 +- .../server/webui/src/lib/stores/mcp.svelte.ts | 38 +++- .../server/webui/src/lib/types/settings.d.ts | 4 +- tools/server/webui/src/lib/utils/mcp.ts | 5 +- 18 files changed, 283 insertions(+), 130 deletions(-) create mode 100644 tools/server/webui/src/lib/constants/settings-keys.ts diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics.svelte index 9a2a42289d..bca1dfea4f 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics.svelte @@ -5,6 +5,7 @@ import { ChatMessageStatsView } from '$lib/enums'; import type { ChatMessageAgenticTimings } from '$lib/types/chat'; import { formatPerformanceTime } from '$lib/utils'; + import { MS_PER_SECOND, DEFAULT_PERFORMANCE_TIME } from '$lib/constants/formatters'; interface Props { predictedTokens?: number; @@ -65,14 +66,16 @@ predictedMs > 0 ); - let tokensPerSecond = $derived(hasGenerationStats ? (predictedTokens! / predictedMs!) * 1000 : 0); + let tokensPerSecond = $derived( + hasGenerationStats ? (predictedTokens! / predictedMs!) * MS_PER_SECOND : 0 + ); let formattedTime = $derived( - predictedMs !== undefined ? formatPerformanceTime(predictedMs) : '0s' + predictedMs !== undefined ? formatPerformanceTime(predictedMs) : DEFAULT_PERFORMANCE_TIME ); let promptTokensPerSecond = $derived( promptTokens !== undefined && promptMs !== undefined && promptMs > 0 - ? (promptTokens / promptMs) * 1000 + ? (promptTokens / promptMs) * MS_PER_SECOND : undefined ); @@ -94,12 +97,12 @@ let agenticToolsPerSecond = $derived( hasAgenticStats && agenticTimings!.toolsMs > 0 - ? (agenticTimings!.toolCallsCount / agenticTimings!.toolsMs) * 1000 + ? (agenticTimings!.toolCallsCount / agenticTimings!.toolsMs) * MS_PER_SECOND : 0 ); let formattedAgenticToolsTime = $derived( - hasAgenticStats ? formatPerformanceTime(agenticTimings!.toolsMs) : '0s' + hasAgenticStats ? formatPerformanceTime(agenticTimings!.toolsMs) : DEFAULT_PERFORMANCE_TIME ); let agenticTotalTimeMs = $derived( diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte index 6c8ef1516e..37ef2e7717 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte @@ -20,10 +20,12 @@ import { config, settingsStore } from '$lib/stores/settings.svelte'; import { setMode } from 'mode-watcher'; import { ColorMode } from '$lib/enums/ui'; + import { SettingsFieldType } from '$lib/enums/settings'; import type { Component } from 'svelte'; import { NUMERIC_FIELDS, POSITIVE_INTEGER_FIELDS } from '$lib/constants/settings-fields'; import { SETTINGS_COLOR_MODES_CONFIG } from '$lib/constants/settings-config'; import { SETTINGS_SECTION_TITLES } from '$lib/constants/settings-sections'; + import { SETTINGS_KEYS } from '$lib/constants/settings-keys'; import type { SettingsSectionTitle } from '$lib/constants/settings-sections'; interface Props { @@ -43,42 +45,42 @@ icon: Settings, fields: [ { - key: 'theme', + key: SETTINGS_KEYS.THEME, label: 'Theme', - type: 'select', + type: SettingsFieldType.SELECT, options: SETTINGS_COLOR_MODES_CONFIG }, - { key: 'apiKey', label: 'API Key', type: 'input' }, + { key: SETTINGS_KEYS.API_KEY, label: 'API Key', type: SettingsFieldType.INPUT }, { - key: 'systemMessage', + key: SETTINGS_KEYS.SYSTEM_MESSAGE, label: 'System Message', - type: 'textarea' + type: SettingsFieldType.TEXTAREA }, { - key: 'pasteLongTextToFileLen', + key: SETTINGS_KEYS.PASTE_LONG_TEXT_TO_FILE_LEN, label: 'Paste long text to file length', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'copyTextAttachmentsAsPlainText', + key: SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT, label: 'Copy text attachments as plain text', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'enableContinueGeneration', + key: SETTINGS_KEYS.ENABLE_CONTINUE_GENERATION, label: 'Enable "Continue" button', - type: 'checkbox', + type: SettingsFieldType.CHECKBOX, isExperimental: true }, { - key: 'pdfAsImage', + key: SETTINGS_KEYS.PDF_AS_IMAGE, label: 'Parse PDF as image', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'askForTitleConfirmation', + key: SETTINGS_KEYS.ASK_FOR_TITLE_CONFIRMATION, label: 'Ask for confirmation before changing conversation title', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX } ] }, @@ -87,45 +89,45 @@ icon: Monitor, fields: [ { - key: 'showMessageStats', + key: SETTINGS_KEYS.SHOW_MESSAGE_STATS, label: 'Show message generation statistics', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'showThoughtInProgress', + key: SETTINGS_KEYS.SHOW_THOUGHT_IN_PROGRESS, label: 'Show thought in progress', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'keepStatsVisible', + key: SETTINGS_KEYS.KEEP_STATS_VISIBLE, label: 'Keep stats visible after generation', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'autoMicOnEmpty', + key: SETTINGS_KEYS.AUTO_MIC_ON_EMPTY, label: 'Show microphone on empty input', - type: 'checkbox', + type: SettingsFieldType.CHECKBOX, isExperimental: true }, { - key: 'renderUserContentAsMarkdown', + key: SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN, label: 'Render user content as Markdown', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'disableAutoScroll', + key: SETTINGS_KEYS.DISABLE_AUTO_SCROLL, label: 'Disable automatic scroll', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'alwaysShowSidebarOnDesktop', + key: SETTINGS_KEYS.ALWAYS_SHOW_SIDEBAR_ON_DESKTOP, label: 'Always show sidebar on desktop', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'autoShowSidebarOnNewChat', + key: SETTINGS_KEYS.AUTO_SHOW_SIDEBAR_ON_NEW_CHAT, label: 'Auto-show sidebar on new chat', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX } ] }, @@ -134,64 +136,64 @@ icon: Funnel, fields: [ { - key: 'temperature', + key: SETTINGS_KEYS.TEMPERATURE, label: 'Temperature', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dynatemp_range', + key: SETTINGS_KEYS.DYNATEMP_RANGE, label: 'Dynamic temperature range', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dynatemp_exponent', + key: SETTINGS_KEYS.DYNATEMP_EXPONENT, label: 'Dynamic temperature exponent', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'top_k', + key: SETTINGS_KEYS.TOP_K, label: 'Top K', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'top_p', + key: SETTINGS_KEYS.TOP_P, label: 'Top P', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'min_p', + key: SETTINGS_KEYS.MIN_P, label: 'Min P', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'xtc_probability', + key: SETTINGS_KEYS.XTC_PROBABILITY, label: 'XTC probability', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'xtc_threshold', + key: SETTINGS_KEYS.XTC_THRESHOLD, label: 'XTC threshold', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'typ_p', + key: SETTINGS_KEYS.TYP_P, label: 'Typical P', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'max_tokens', + key: SETTINGS_KEYS.MAX_TOKENS, label: 'Max tokens', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'samplers', + key: SETTINGS_KEYS.SAMPLERS, label: 'Samplers', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'backend_sampling', + key: SETTINGS_KEYS.BACKEND_SAMPLING, label: 'Backend sampling', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX } ] }, @@ -200,44 +202,44 @@ icon: AlertTriangle, fields: [ { - key: 'repeat_last_n', + key: SETTINGS_KEYS.REPEAT_LAST_N, label: 'Repeat last N', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'repeat_penalty', + key: SETTINGS_KEYS.REPEAT_PENALTY, label: 'Repeat penalty', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'presence_penalty', + key: SETTINGS_KEYS.PRESENCE_PENALTY, label: 'Presence penalty', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'frequency_penalty', + key: SETTINGS_KEYS.FREQUENCY_PENALTY, label: 'Frequency penalty', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dry_multiplier', + key: SETTINGS_KEYS.DRY_MULTIPLIER, label: 'DRY multiplier', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dry_base', + key: SETTINGS_KEYS.DRY_BASE, label: 'DRY base', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dry_allowed_length', + key: SETTINGS_KEYS.DRY_ALLOWED_LENGTH, label: 'DRY allowed length', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'dry_penalty_last_n', + key: SETTINGS_KEYS.DRY_PENALTY_LAST_N, label: 'DRY penalty last N', - type: 'input' + type: SettingsFieldType.INPUT } ] }, @@ -251,24 +253,24 @@ icon: McpLogo, fields: [ { - key: 'agenticMaxTurns', + key: SETTINGS_KEYS.AGENTIC_MAX_TURNS, label: 'Agentic loop max turns', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'alwaysShowAgenticTurns', + key: SETTINGS_KEYS.ALWAYS_SHOW_AGENTIC_TURNS, label: 'Always show agentic turns in conversation', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'agenticMaxToolPreviewLines', + key: SETTINGS_KEYS.AGENTIC_MAX_TOOL_PREVIEW_LINES, label: 'Max lines per tool preview', - type: 'input' + type: SettingsFieldType.INPUT }, { - key: 'showToolCallInProgress', + key: SETTINGS_KEYS.SHOW_TOOL_CALL_IN_PROGRESS, label: 'Show tool call in progress', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX } ] }, @@ -277,24 +279,19 @@ icon: Code, fields: [ { - key: 'disableReasoningParsing', + key: SETTINGS_KEYS.DISABLE_REASONING_PARSING, label: 'Disable reasoning content parsing', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'showRawOutputSwitch', + key: SETTINGS_KEYS.SHOW_RAW_OUTPUT_SWITCH, label: 'Enable raw output toggle', - type: 'checkbox' + type: SettingsFieldType.CHECKBOX }, { - key: 'showRawOutputSwitch', - label: 'Enable raw output toggle', - type: 'checkbox' - }, - { - key: 'custom', + key: SETTINGS_KEYS.CUSTOM, label: 'Custom JSON', - type: 'textarea' + type: SettingsFieldType.TEXTAREA } ] } diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsFields.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsFields.svelte index a6f51f47d6..0774994411 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsFields.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsFields.svelte @@ -6,6 +6,8 @@ import * as Select from '$lib/components/ui/select'; import { Textarea } from '$lib/components/ui/textarea'; import { SETTING_CONFIG_DEFAULT, SETTING_CONFIG_INFO } from '$lib/constants/settings-config'; + import { SETTINGS_KEYS } from '$lib/constants/settings-keys'; + import { SettingsFieldType } from '$lib/enums/settings'; import { settingsStore } from '$lib/stores/settings.svelte'; import { ChatSettingsParameterSourceIndicator } from '$lib/components/app'; import type { Component } from 'svelte'; @@ -31,7 +33,7 @@ {#each fields as field (field.key)}
- {#if field.type === 'input'} + {#if field.type === SettingsFieldType.INPUT} {@const paramInfo = getParameterSourceInfo(field.key)} {@const currentValue = String(localConfig[field.key] ?? '')} {@const propsDefault = paramInfo?.serverDefault} @@ -98,7 +100,7 @@ {@html field.help || SETTING_CONFIG_INFO[field.key]}

{/if} - {:else if field.type === 'textarea'} + {:else if field.type === SettingsFieldType.TEXTAREA}