refactor: Update Agentic and MCP config parsing to use new utils and constants
This commit is contained in:
parent
abc3764c9f
commit
8024ae540f
|
|
@ -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
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue