refactor: Update Agentic and MCP config parsing to use new utils and constants

This commit is contained in:
Aleksander Grygier 2025-12-29 10:35:46 +01:00
parent abc3764c9f
commit 8024ae540f
3 changed files with 35 additions and 115 deletions

View File

@ -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
});
}}
/>

View File

@ -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

View File

@ -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
};
}