From 8024ae540f257fbec215e10057ea6e7f8c897de1 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Mon, 29 Dec 2025 10:35:46 +0100 Subject: [PATCH] refactor: Update Agentic and MCP config parsing to use new utils and constants --- .../ChatSettings/McpSettingsSection.svelte | 24 +++--- tools/server/webui/src/lib/config/agentic.ts | 42 +++------- tools/server/webui/src/lib/config/mcp.ts | 84 ++++--------------- 3 files changed, 35 insertions(+), 115 deletions(-) diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSettings/McpSettingsSection.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSettings/McpSettingsSection.svelte index dbef67dd49..101dff27d4 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatSettings/McpSettingsSection.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatSettings/McpSettingsSection.svelte @@ -4,14 +4,12 @@ import { Input } from '$lib/components/ui/input'; import Label from '$lib/components/ui/label/label.svelte'; import { Button } from '$lib/components/ui/button'; - import { - detectMcpTransportFromUrl, - parseMcpServerSettings, - getDefaultMcpConfig, - type MCPServerSettingsEntry - } from '$lib/config/mcp'; + import { parseMcpServerSettings } from '$lib/config/mcp'; + import { detectMcpTransportFromUrl } from '$lib/utils/mcp'; + import type { MCPServerSettingsEntry } from '$lib/types/mcp'; import { MCPClient } from '$lib/mcp'; import type { SettingsConfigType } from '$lib/types/settings'; + import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp'; interface Props { localConfig: SettingsConfigType; @@ -20,8 +18,6 @@ let { localConfig, onConfigChange }: Props = $props(); - const defaultMcpConfig = getDefaultMcpConfig(); - type HealthCheckState = | { status: 'idle' } | { status: 'loading' } @@ -44,7 +40,7 @@ id: crypto.randomUUID ? crypto.randomUUID() : `server-${Date.now()}`, enabled: true, url: '', - requestTimeoutSeconds: defaultMcpConfig.requestTimeoutSeconds + requestTimeoutSeconds: DEFAULT_MCP_CONFIG.requestTimeoutSeconds }; serializeServers([...servers, newServer]); @@ -103,15 +99,15 @@ const timeoutMs = Math.round(server.requestTimeoutSeconds * 1000); const mcpClient = new MCPClient({ - protocolVersion: defaultMcpConfig.protocolVersion, - capabilities: defaultMcpConfig.capabilities, - clientInfo: defaultMcpConfig.clientInfo, + protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion, + capabilities: DEFAULT_MCP_CONFIG.capabilities, + clientInfo: DEFAULT_MCP_CONFIG.clientInfo, requestTimeoutMs: timeoutMs, servers: { [server.id]: { url: trimmedUrl, transport: detectMcpTransportFromUrl(trimmedUrl), - handshakeTimeoutMs: defaultMcpConfig.connectionTimeoutMs, + handshakeTimeoutMs: DEFAULT_MCP_CONFIG.connectionTimeoutMs, requestTimeoutMs: timeoutMs } } @@ -228,7 +224,7 @@ requestTimeoutSeconds: Number.isFinite(parsed) && parsed > 0 ? parsed - : defaultMcpConfig.requestTimeoutSeconds + : DEFAULT_MCP_CONFIG.requestTimeoutSeconds }); }} /> diff --git a/tools/server/webui/src/lib/config/agentic.ts b/tools/server/webui/src/lib/config/agentic.ts index 61f3aa9621..6aed7a3728 100644 --- a/tools/server/webui/src/lib/config/agentic.ts +++ b/tools/server/webui/src/lib/config/agentic.ts @@ -1,49 +1,29 @@ import { hasEnabledMcpServers } from './mcp'; import type { SettingsConfigType } from '$lib/types/settings'; - -/** - * Agentic orchestration configuration. - */ -export interface AgenticConfig { - enabled: boolean; - maxTurns: number; - maxToolPreviewLines: number; - filterReasoningAfterFirstTurn: boolean; -} - -const defaultAgenticConfig: AgenticConfig = { - enabled: true, - maxTurns: 100, - maxToolPreviewLines: 25, - filterReasoningAfterFirstTurn: true -}; - -function normalizeNumber(value: unknown, fallback: number): number { - const parsed = typeof value === 'string' ? Number.parseFloat(value) : Number(value); - if (!Number.isFinite(parsed) || parsed <= 0) { - return fallback; - } - - return parsed; -} +import type { AgenticConfig } from '$lib/types/agentic'; +import { DEFAULT_AGENTIC_CONFIG } from '$lib/constants/agentic'; +import { normalizePositiveNumber } from '$lib/utils/number'; /** * Gets the current agentic configuration. * Automatically disables agentic mode if no MCP servers are configured. */ export function getAgenticConfig(settings: SettingsConfigType): AgenticConfig { - const maxTurns = normalizeNumber(settings.agenticMaxTurns, defaultAgenticConfig.maxTurns); - const maxToolPreviewLines = normalizeNumber( + const maxTurns = normalizePositiveNumber( + settings.agenticMaxTurns, + DEFAULT_AGENTIC_CONFIG.maxTurns + ); + const maxToolPreviewLines = normalizePositiveNumber( settings.agenticMaxToolPreviewLines, - defaultAgenticConfig.maxToolPreviewLines + DEFAULT_AGENTIC_CONFIG.maxToolPreviewLines ); const filterReasoningAfterFirstTurn = typeof settings.agenticFilterReasoningAfterFirstTurn === 'boolean' ? settings.agenticFilterReasoningAfterFirstTurn - : defaultAgenticConfig.filterReasoningAfterFirstTurn; + : DEFAULT_AGENTIC_CONFIG.filterReasoningAfterFirstTurn; return { - enabled: hasEnabledMcpServers(settings) && defaultAgenticConfig.enabled, + enabled: hasEnabledMcpServers(settings) && DEFAULT_AGENTIC_CONFIG.enabled, maxTurns, maxToolPreviewLines, filterReasoningAfterFirstTurn diff --git a/tools/server/webui/src/lib/config/mcp.ts b/tools/server/webui/src/lib/config/mcp.ts index 01e4ede3c5..83e08ae557 100644 --- a/tools/server/webui/src/lib/config/mcp.ts +++ b/tools/server/webui/src/lib/config/mcp.ts @@ -1,68 +1,12 @@ -import type { - MCPClientCapabilities, - MCPClientConfig, - MCPClientInfo, - MCPServerConfig -} from '../mcp/types'; +import type { MCPClientConfig, MCPServerConfig, MCPServerSettingsEntry } from '$lib/types/mcp'; import type { SettingsConfigType } from '$lib/types/settings'; - -/** - * Raw MCP server configuration entry stored in settings. - */ -export type MCPServerSettingsEntry = { - id: string; - enabled: boolean; - url: string; - requestTimeoutSeconds: number; -}; - -const defaultMcpConfig = { - protocolVersion: '2025-06-18', - capabilities: { tools: { listChanged: true } } as MCPClientCapabilities, - clientInfo: { name: 'llama-webui-mcp', version: 'dev' } as MCPClientInfo, - requestTimeoutSeconds: 300, // 5 minutes for long-running tools - connectionTimeoutMs: 10_000 // 10 seconds for connection establishment -}; - -export function getDefaultMcpConfig() { - return defaultMcpConfig; -} - -export function detectMcpTransportFromUrl(url: string): 'websocket' | 'streamable_http' { - const normalized = url.trim().toLowerCase(); - return normalized.startsWith('ws://') || normalized.startsWith('wss://') - ? 'websocket' - : 'streamable_http'; -} - -function normalizeRequestTimeoutSeconds(value: unknown, fallback: number): number { - const parsed = typeof value === 'string' ? Number.parseFloat(value) : Number(value); - if (!Number.isFinite(parsed) || parsed <= 0) { - return fallback; - } - - return parsed; -} - -function sanitizeId(id: unknown, index: number): string { - if (typeof id === 'string' && id.trim()) { - return id.trim(); - } - - return `server-${index + 1}`; -} - -function sanitizeUrl(url: unknown): string { - if (typeof url === 'string') { - return url.trim(); - } - - return ''; -} +import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp'; +import { detectMcpTransportFromUrl, generateMcpServerId } from '$lib/utils/mcp'; +import { normalizePositiveNumber } from '$lib/utils/number'; export function parseMcpServerSettings( rawServers: unknown, - fallbackRequestTimeoutSeconds = defaultMcpConfig.requestTimeoutSeconds + fallbackRequestTimeoutSeconds = DEFAULT_MCP_CONFIG.requestTimeoutSeconds ): MCPServerSettingsEntry[] { if (!rawServers) return []; @@ -84,15 +28,15 @@ export function parseMcpServerSettings( if (!Array.isArray(parsed)) return []; return parsed.map((entry, index) => { - const requestTimeoutSeconds = normalizeRequestTimeoutSeconds( + const requestTimeoutSeconds = normalizePositiveNumber( (entry as { requestTimeoutSeconds?: unknown })?.requestTimeoutSeconds, fallbackRequestTimeoutSeconds ); - const url = sanitizeUrl((entry as { url?: unknown })?.url); + const url = typeof entry?.url === 'string' ? entry.url.trim() : ''; return { - id: sanitizeId((entry as { id?: unknown })?.id, index), + id: generateMcpServerId((entry as { id?: unknown })?.id, index), enabled: Boolean((entry as { enabled?: unknown })?.enabled), url, requestTimeoutSeconds @@ -102,7 +46,7 @@ export function parseMcpServerSettings( function buildServerConfig( entry: MCPServerSettingsEntry, - connectionTimeoutMs = defaultMcpConfig.connectionTimeoutMs + connectionTimeoutMs = DEFAULT_MCP_CONFIG.connectionTimeoutMs ): MCPServerConfig | undefined { if (!entry?.url) { return undefined; @@ -133,7 +77,7 @@ export function buildMcpClientConfig(config: SettingsConfigType): MCPClientConfi const normalized = buildServerConfig(entry); if (normalized) { - servers[sanitizeId(entry.id, index)] = normalized; + servers[generateMcpServerId(entry.id, index)] = normalized; } } @@ -142,10 +86,10 @@ export function buildMcpClientConfig(config: SettingsConfigType): MCPClientConfi } return { - protocolVersion: defaultMcpConfig.protocolVersion, - capabilities: defaultMcpConfig.capabilities, - clientInfo: defaultMcpConfig.clientInfo, - requestTimeoutMs: Math.round(defaultMcpConfig.requestTimeoutSeconds * 1000), + protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion, + capabilities: DEFAULT_MCP_CONFIG.capabilities, + clientInfo: DEFAULT_MCP_CONFIG.clientInfo, + requestTimeoutMs: Math.round(DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000), servers }; }