refactor: Update Agentic and MCP config parsing to use new utils and constants
This commit is contained in:
parent
0c24db3178
commit
2325d2a50d
|
|
@ -4,14 +4,12 @@
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
import Label from '$lib/components/ui/label/label.svelte';
|
import Label from '$lib/components/ui/label/label.svelte';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import {
|
import { parseMcpServerSettings } from '$lib/config/mcp';
|
||||||
detectMcpTransportFromUrl,
|
import { detectMcpTransportFromUrl } from '$lib/utils/mcp';
|
||||||
parseMcpServerSettings,
|
import type { MCPServerSettingsEntry } from '$lib/types/mcp';
|
||||||
getDefaultMcpConfig,
|
|
||||||
type MCPServerSettingsEntry
|
|
||||||
} from '$lib/config/mcp';
|
|
||||||
import { MCPClient } from '$lib/mcp';
|
import { MCPClient } from '$lib/mcp';
|
||||||
import type { SettingsConfigType } from '$lib/types/settings';
|
import type { SettingsConfigType } from '$lib/types/settings';
|
||||||
|
import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
localConfig: SettingsConfigType;
|
localConfig: SettingsConfigType;
|
||||||
|
|
@ -20,8 +18,6 @@
|
||||||
|
|
||||||
let { localConfig, onConfigChange }: Props = $props();
|
let { localConfig, onConfigChange }: Props = $props();
|
||||||
|
|
||||||
const defaultMcpConfig = getDefaultMcpConfig();
|
|
||||||
|
|
||||||
type HealthCheckState =
|
type HealthCheckState =
|
||||||
| { status: 'idle' }
|
| { status: 'idle' }
|
||||||
| { status: 'loading' }
|
| { status: 'loading' }
|
||||||
|
|
@ -44,7 +40,7 @@
|
||||||
id: crypto.randomUUID ? crypto.randomUUID() : `server-${Date.now()}`,
|
id: crypto.randomUUID ? crypto.randomUUID() : `server-${Date.now()}`,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
url: '',
|
url: '',
|
||||||
requestTimeoutSeconds: defaultMcpConfig.requestTimeoutSeconds
|
requestTimeoutSeconds: DEFAULT_MCP_CONFIG.requestTimeoutSeconds
|
||||||
};
|
};
|
||||||
|
|
||||||
serializeServers([...servers, newServer]);
|
serializeServers([...servers, newServer]);
|
||||||
|
|
@ -103,15 +99,15 @@
|
||||||
const timeoutMs = Math.round(server.requestTimeoutSeconds * 1000);
|
const timeoutMs = Math.round(server.requestTimeoutSeconds * 1000);
|
||||||
|
|
||||||
const mcpClient = new MCPClient({
|
const mcpClient = new MCPClient({
|
||||||
protocolVersion: defaultMcpConfig.protocolVersion,
|
protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion,
|
||||||
capabilities: defaultMcpConfig.capabilities,
|
capabilities: DEFAULT_MCP_CONFIG.capabilities,
|
||||||
clientInfo: defaultMcpConfig.clientInfo,
|
clientInfo: DEFAULT_MCP_CONFIG.clientInfo,
|
||||||
requestTimeoutMs: timeoutMs,
|
requestTimeoutMs: timeoutMs,
|
||||||
servers: {
|
servers: {
|
||||||
[server.id]: {
|
[server.id]: {
|
||||||
url: trimmedUrl,
|
url: trimmedUrl,
|
||||||
transport: detectMcpTransportFromUrl(trimmedUrl),
|
transport: detectMcpTransportFromUrl(trimmedUrl),
|
||||||
handshakeTimeoutMs: defaultMcpConfig.connectionTimeoutMs,
|
handshakeTimeoutMs: DEFAULT_MCP_CONFIG.connectionTimeoutMs,
|
||||||
requestTimeoutMs: timeoutMs
|
requestTimeoutMs: timeoutMs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +224,7 @@
|
||||||
requestTimeoutSeconds:
|
requestTimeoutSeconds:
|
||||||
Number.isFinite(parsed) && parsed > 0
|
Number.isFinite(parsed) && parsed > 0
|
||||||
? parsed
|
? parsed
|
||||||
: defaultMcpConfig.requestTimeoutSeconds
|
: DEFAULT_MCP_CONFIG.requestTimeoutSeconds
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,29 @@
|
||||||
import { hasEnabledMcpServers } from './mcp';
|
import { hasEnabledMcpServers } from './mcp';
|
||||||
import type { SettingsConfigType } from '$lib/types/settings';
|
import type { SettingsConfigType } from '$lib/types/settings';
|
||||||
|
import type { AgenticConfig } from '$lib/types/agentic';
|
||||||
/**
|
import { DEFAULT_AGENTIC_CONFIG } from '$lib/constants/agentic';
|
||||||
* Agentic orchestration configuration.
|
import { normalizePositiveNumber } from '$lib/utils/number';
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current agentic configuration.
|
* Gets the current agentic configuration.
|
||||||
* Automatically disables agentic mode if no MCP servers are configured.
|
* Automatically disables agentic mode if no MCP servers are configured.
|
||||||
*/
|
*/
|
||||||
export function getAgenticConfig(settings: SettingsConfigType): AgenticConfig {
|
export function getAgenticConfig(settings: SettingsConfigType): AgenticConfig {
|
||||||
const maxTurns = normalizeNumber(settings.agenticMaxTurns, defaultAgenticConfig.maxTurns);
|
const maxTurns = normalizePositiveNumber(
|
||||||
const maxToolPreviewLines = normalizeNumber(
|
settings.agenticMaxTurns,
|
||||||
|
DEFAULT_AGENTIC_CONFIG.maxTurns
|
||||||
|
);
|
||||||
|
const maxToolPreviewLines = normalizePositiveNumber(
|
||||||
settings.agenticMaxToolPreviewLines,
|
settings.agenticMaxToolPreviewLines,
|
||||||
defaultAgenticConfig.maxToolPreviewLines
|
DEFAULT_AGENTIC_CONFIG.maxToolPreviewLines
|
||||||
);
|
);
|
||||||
const filterReasoningAfterFirstTurn =
|
const filterReasoningAfterFirstTurn =
|
||||||
typeof settings.agenticFilterReasoningAfterFirstTurn === 'boolean'
|
typeof settings.agenticFilterReasoningAfterFirstTurn === 'boolean'
|
||||||
? settings.agenticFilterReasoningAfterFirstTurn
|
? settings.agenticFilterReasoningAfterFirstTurn
|
||||||
: defaultAgenticConfig.filterReasoningAfterFirstTurn;
|
: DEFAULT_AGENTIC_CONFIG.filterReasoningAfterFirstTurn;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enabled: hasEnabledMcpServers(settings) && defaultAgenticConfig.enabled,
|
enabled: hasEnabledMcpServers(settings) && DEFAULT_AGENTIC_CONFIG.enabled,
|
||||||
maxTurns,
|
maxTurns,
|
||||||
maxToolPreviewLines,
|
maxToolPreviewLines,
|
||||||
filterReasoningAfterFirstTurn
|
filterReasoningAfterFirstTurn
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,12 @@
|
||||||
import type {
|
import type { MCPClientConfig, MCPServerConfig, MCPServerSettingsEntry } from '$lib/types/mcp';
|
||||||
MCPClientCapabilities,
|
|
||||||
MCPClientConfig,
|
|
||||||
MCPClientInfo,
|
|
||||||
MCPServerConfig
|
|
||||||
} from '../mcp/types';
|
|
||||||
import type { SettingsConfigType } from '$lib/types/settings';
|
import type { SettingsConfigType } from '$lib/types/settings';
|
||||||
|
import { DEFAULT_MCP_CONFIG } from '$lib/constants/mcp';
|
||||||
/**
|
import { detectMcpTransportFromUrl, generateMcpServerId } from '$lib/utils/mcp';
|
||||||
* Raw MCP server configuration entry stored in settings.
|
import { normalizePositiveNumber } from '$lib/utils/number';
|
||||||
*/
|
|
||||||
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 '';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function parseMcpServerSettings(
|
export function parseMcpServerSettings(
|
||||||
rawServers: unknown,
|
rawServers: unknown,
|
||||||
fallbackRequestTimeoutSeconds = defaultMcpConfig.requestTimeoutSeconds
|
fallbackRequestTimeoutSeconds = DEFAULT_MCP_CONFIG.requestTimeoutSeconds
|
||||||
): MCPServerSettingsEntry[] {
|
): MCPServerSettingsEntry[] {
|
||||||
if (!rawServers) return [];
|
if (!rawServers) return [];
|
||||||
|
|
||||||
|
|
@ -84,15 +28,15 @@ export function parseMcpServerSettings(
|
||||||
if (!Array.isArray(parsed)) return [];
|
if (!Array.isArray(parsed)) return [];
|
||||||
|
|
||||||
return parsed.map((entry, index) => {
|
return parsed.map((entry, index) => {
|
||||||
const requestTimeoutSeconds = normalizeRequestTimeoutSeconds(
|
const requestTimeoutSeconds = normalizePositiveNumber(
|
||||||
(entry as { requestTimeoutSeconds?: unknown })?.requestTimeoutSeconds,
|
(entry as { requestTimeoutSeconds?: unknown })?.requestTimeoutSeconds,
|
||||||
fallbackRequestTimeoutSeconds
|
fallbackRequestTimeoutSeconds
|
||||||
);
|
);
|
||||||
|
|
||||||
const url = sanitizeUrl((entry as { url?: unknown })?.url);
|
const url = typeof entry?.url === 'string' ? entry.url.trim() : '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: sanitizeId((entry as { id?: unknown })?.id, index),
|
id: generateMcpServerId((entry as { id?: unknown })?.id, index),
|
||||||
enabled: Boolean((entry as { enabled?: unknown })?.enabled),
|
enabled: Boolean((entry as { enabled?: unknown })?.enabled),
|
||||||
url,
|
url,
|
||||||
requestTimeoutSeconds
|
requestTimeoutSeconds
|
||||||
|
|
@ -102,7 +46,7 @@ export function parseMcpServerSettings(
|
||||||
|
|
||||||
function buildServerConfig(
|
function buildServerConfig(
|
||||||
entry: MCPServerSettingsEntry,
|
entry: MCPServerSettingsEntry,
|
||||||
connectionTimeoutMs = defaultMcpConfig.connectionTimeoutMs
|
connectionTimeoutMs = DEFAULT_MCP_CONFIG.connectionTimeoutMs
|
||||||
): MCPServerConfig | undefined {
|
): MCPServerConfig | undefined {
|
||||||
if (!entry?.url) {
|
if (!entry?.url) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -133,7 +77,7 @@ export function buildMcpClientConfig(config: SettingsConfigType): MCPClientConfi
|
||||||
|
|
||||||
const normalized = buildServerConfig(entry);
|
const normalized = buildServerConfig(entry);
|
||||||
if (normalized) {
|
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 {
|
return {
|
||||||
protocolVersion: defaultMcpConfig.protocolVersion,
|
protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion,
|
||||||
capabilities: defaultMcpConfig.capabilities,
|
capabilities: DEFAULT_MCP_CONFIG.capabilities,
|
||||||
clientInfo: defaultMcpConfig.clientInfo,
|
clientInfo: DEFAULT_MCP_CONFIG.clientInfo,
|
||||||
requestTimeoutMs: Math.round(defaultMcpConfig.requestTimeoutSeconds * 1000),
|
requestTimeoutMs: Math.round(DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000),
|
||||||
servers
|
servers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue