refactor: Architecture improvements

This commit is contained in:
Aleksander Grygier 2026-01-12 14:45:24 +01:00
parent a63a421952
commit 60ef752d0f
6 changed files with 23 additions and 110 deletions

View File

@ -10,11 +10,7 @@
import { conversationsStore } from '$lib/stores/conversations.svelte';
import { parseMcpServerSettings, getServerDisplayName, getFaviconUrl } from '$lib/utils/mcp';
import type { MCPServerSettingsEntry } from '$lib/types/mcp';
import {
mcpGetHealthCheckState,
mcpHasHealthCheck,
mcpGetUsageStats
} from '$lib/stores/mcp.svelte';
import { mcpStore } from '$lib/stores/mcp.svelte';
import { mcpClient } from '$lib/clients/mcp.client';
interface Props {
@ -33,7 +29,7 @@
let hasMcpServers = $derived(mcpServers.length > 0);
let mcpUsageStats = $derived(mcpGetUsageStats());
let mcpUsageStats = $derived(mcpStore.getUsageStats());
function getServerUsageCount(serverId: string): number {
return mcpUsageStats[serverId] || 0;
@ -53,7 +49,7 @@
let healthyEnabledMcpServers = $derived(
enabledMcpServersForChat.filter((s) => {
const healthState = mcpGetHealthCheckState(s.id);
const healthState = mcpStore.getHealthCheckState(s.id);
return healthState.status !== 'error';
})
);
@ -105,7 +101,7 @@
onMount(() => {
for (const server of serversWithUrls) {
if (!mcpHasHealthCheck(server.id)) {
if (!mcpStore.hasHealthCheck(server.id)) {
mcpClient.runHealthCheck(server);
}
}
@ -159,7 +155,7 @@
{/snippet}
{#each filteredMcpServers() as server (server.id)}
{@const healthState = mcpGetHealthCheckState(server.id)}
{@const healthState = mcpStore.getHealthCheckState(server.id)}
{@const hasError = healthState.status === 'error'}
{@const isEnabledForChat = isServerEnabledForChat(server)}
{@const hasOverride = hasPerChatOverride(server.id)}

View File

@ -2,11 +2,7 @@
import { onMount } from 'svelte';
import * as Card from '$lib/components/ui/card';
import type { MCPServerSettingsEntry } from '$lib/types/mcp';
import {
mcpGetHealthCheckState,
mcpHasHealthCheck,
type HealthCheckState
} from '$lib/stores/mcp.svelte';
import { mcpStore, type HealthCheckState } from '$lib/stores/mcp.svelte';
import { mcpClient } from '$lib/clients/mcp.client';
import McpServerCardHeader from './McpServerCardHeader.svelte';
import McpServerCardActions from './McpServerCardActions.svelte';
@ -25,7 +21,7 @@
let { server, displayName, faviconUrl, onToggle, onUpdate, onDelete }: Props = $props();
let healthState = $derived<HealthCheckState>(mcpGetHealthCheckState(server.id));
let healthState = $derived<HealthCheckState>(mcpStore.getHealthCheckState(server.id));
let isHealthChecking = $derived(healthState.status === 'loading');
let isConnected = $derived(healthState.status === 'success');
let isError = $derived(healthState.status === 'error');
@ -37,7 +33,7 @@
let editFormRef: McpServerCardEditForm | null = $state(null);
onMount(() => {
if (!mcpHasHealthCheck(server.id) && server.enabled && server.url.trim()) {
if (!mcpStore.hasHealthCheck(server.id) && server.enabled && server.url.trim()) {
mcpClient.runHealthCheck(server);
}
});

View File

@ -4,12 +4,12 @@
import * as Card from '$lib/components/ui/card';
import { getServerDisplayName, getFaviconUrl } from '$lib/utils/mcp';
import type { MCPServerSettingsEntry } from '$lib/types/mcp';
import { mcpStore, mcpGetServers } from '$lib/stores/mcp.svelte';
import { mcpStore } from '$lib/stores/mcp.svelte';
import { McpServerCard } from '$lib/components/app/mcp/McpServerCard';
import McpServerForm from './McpServerForm.svelte';
// Get servers from store
let servers = $derived<MCPServerSettingsEntry[]>(mcpGetServers());
let servers = $derived<MCPServerSettingsEntry[]>(mcpStore.getServers());
// New server form state
let isAddingServer = $state(false);

View File

@ -217,19 +217,6 @@ class MCPStore {
this.clearHealthCheck(id);
}
/**
* Check if a server is enabled considering per-chat overrides
*/
isServerEnabled(server: MCPServerSettingsEntry, perChatOverrides?: McpServerOverride[]): boolean {
if (perChatOverrides) {
const override = perChatOverrides.find((o) => o.serverId === server.id);
if (override !== undefined) {
return override.enabled;
}
}
return server.enabled;
}
/**
* Check if there are any enabled MCP servers
*/
@ -270,66 +257,11 @@ class MCPStore {
export const mcpStore = new MCPStore();
export function mcpIsInitializing() {
return mcpStore.isInitializing;
}
export function mcpIsInitialized() {
return mcpStore.isInitialized;
}
export function mcpError() {
return mcpStore.error;
}
export function mcpIsEnabled() {
return mcpStore.isEnabled;
}
export function mcpAvailableTools() {
return mcpStore.availableTools;
}
export function mcpConnectedServerCount() {
return mcpStore.connectedServerCount;
}
export function mcpConnectedServerNames() {
return mcpStore.connectedServerNames;
}
export function mcpToolCount() {
return mcpStore.toolCount;
}
// State access functions (getters only - use mcpStore.method() for actions)
export function mcpGetHealthCheckState(serverId: string) {
return mcpStore.getHealthCheckState(serverId);
}
export function mcpHasHealthCheck(serverId: string) {
return mcpStore.hasHealthCheck(serverId);
}
export function mcpGetServers() {
return mcpStore.getServers();
}
export function mcpIsServerEnabled(
server: MCPServerSettingsEntry,
perChatOverrides?: McpServerOverride[]
) {
return mcpStore.isServerEnabled(server, perChatOverrides);
}
export function mcpHasEnabledServers(perChatOverrides?: McpServerOverride[]) {
return mcpStore.hasEnabledServers(perChatOverrides);
}
export function mcpGetUsageStats() {
return mcpStore.getUsageStats();
}
export function mcpGetServerUsageCount(serverId: string) {
return mcpStore.getServerUsageCount(serverId);
}
export const mcpIsInitializing = () => mcpStore.isInitializing;
export const mcpIsInitialized = () => mcpStore.isInitialized;
export const mcpError = () => mcpStore.error;
export const mcpIsEnabled = () => mcpStore.isEnabled;
export const mcpAvailableTools = () => mcpStore.availableTools;
export const mcpConnectedServerCount = () => mcpStore.connectedServerCount;
export const mcpConnectedServerNames = () => mcpStore.connectedServerNames;
export const mcpToolCount = () => mcpStore.toolCount;

View File

@ -4,7 +4,7 @@ import type { SettingsConfigType } from '$lib/types/settings';
import type { McpServerOverride } from '$lib/types/database';
import { DEFAULT_AGENTIC_CONFIG } from '$lib/constants/agentic';
import { normalizePositiveNumber } from '$lib/utils/number';
import { hasEnabledMcpServers } from '$lib/utils/mcp';
import { mcpStore } from '$lib/stores/mcp.svelte';
/**
* Gets the current agentic configuration.
@ -30,7 +30,7 @@ export function getAgenticConfig(
: DEFAULT_AGENTIC_CONFIG.filterReasoningAfterFirstTurn;
return {
enabled: hasEnabledMcpServers(settings, perChatOverrides) && DEFAULT_AGENTIC_CONFIG.enabled,
enabled: mcpStore.hasEnabledServers(perChatOverrides) && DEFAULT_AGENTIC_CONFIG.enabled,
maxTurns,
maxToolPreviewLines,
filterReasoningAfterFirstTurn

View File

@ -206,8 +206,9 @@ function buildServerConfig(
/**
* Checks if a server is enabled considering per-chat overrides.
* Per-chat override takes precedence over global setting.
* Pure helper function - no side effects.
*/
function isServerEnabled(
export function checkServerEnabled(
server: MCPServerSettingsEntry,
perChatOverrides?: McpServerOverride[]
): boolean {
@ -239,7 +240,7 @@ export function buildMcpClientConfig(
const servers: Record<string, MCPServerConfig> = {};
for (const [index, entry] of rawServers.entries()) {
if (!isServerEnabled(entry, perChatOverrides)) continue;
if (!checkServerEnabled(entry, perChatOverrides)) continue;
const normalized = buildServerConfig(entry);
if (normalized) {
@ -259,15 +260,3 @@ export function buildMcpClientConfig(
servers
};
}
/**
* Checks if there are any enabled MCP servers in the configuration.
* @param config - Global settings configuration
* @param perChatOverrides - Optional per-chat server overrides
*/
export function hasEnabledMcpServers(
config: SettingsConfigType,
perChatOverrides?: McpServerOverride[]
): boolean {
return Boolean(buildMcpClientConfig(config, perChatOverrides));
}