mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 17:24:57 +02:00
ui : open MCP servers in a dialog from the chat form
Replace the MCP servers submenu with a single "MCP Servers" item that opens a new DialogMcpServers dialog instead of navigating to the /mcp-servers route. Assisted-by: pi
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
ChatFormInputFileInputInvisible,
|
||||
ChatFormMcpResourcesList,
|
||||
ChatFormPickers,
|
||||
DialogMcpResourcesBrowser
|
||||
DialogMcpResourcesBrowser,
|
||||
DialogMcpServers
|
||||
} from '$lib/components/app';
|
||||
import {
|
||||
CLIPBOARD_CONTENT_QUOTE_PREFIX,
|
||||
@@ -183,6 +184,9 @@
|
||||
let isResourceDialogOpen = $state(false);
|
||||
let preSelectedResourceUri = $state<string | undefined>(undefined);
|
||||
|
||||
// MCP Servers Dialog State
|
||||
let isMcpServersDialogOpen = $state(false);
|
||||
|
||||
let currentConfig = $derived(settingsStore.config);
|
||||
|
||||
let pasteLongTextToFileLength = $derived.by(() => {
|
||||
@@ -618,6 +622,7 @@
|
||||
onFileUpload={handleFileUpload}
|
||||
onMcpPromptClick={showMcpPromptButton ? () => pickers.openPromptPicker() : undefined}
|
||||
onMcpResourcesClick={() => (isResourceDialogOpen = true)}
|
||||
onMcpSettingsClick={() => (isMcpServersDialogOpen = true)}
|
||||
onMicClick={handleMicClick}
|
||||
{onStop}
|
||||
onSystemPromptClick={() => onSystemPromptClick?.({ files: uploadedFiles, message: value })}
|
||||
@@ -656,3 +661,5 @@
|
||||
}}
|
||||
preSelectedUri={preSelectedResourceUri}
|
||||
/>
|
||||
|
||||
<DialogMcpServers bind:open={isMcpServersDialogOpen} />
|
||||
|
||||
+9
-39
@@ -1,10 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { File, FolderOpen, MessageSquare, Plus, Zap } from '@lucide/svelte';
|
||||
import {
|
||||
ChatFormActionAddMcpServersSubmenu,
|
||||
ChatFormActionAddReasoningSubmenu,
|
||||
ChatFormActionAddToolsSubmenu
|
||||
} from '$lib/components/app';
|
||||
import { File, MessageSquare, Plus } from '@lucide/svelte';
|
||||
import { ChatFormActionAddToolsSubmenu, McpLogo } from '$lib/components/app';
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||
@@ -31,11 +27,6 @@
|
||||
// must not restore focus to the trigger on close
|
||||
let suppressCloseAutoFocus = false;
|
||||
|
||||
function handleMcpSettingsClick() {
|
||||
dropdownOpen = false;
|
||||
chatFormActions.onMcpSettingsClick?.();
|
||||
}
|
||||
|
||||
const attachmentMenu = useAttachmentMenu(
|
||||
() => ({
|
||||
hasAudioModality: chatFormActions.hasAudioModality,
|
||||
@@ -93,10 +84,6 @@
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChatFormActionAddReasoningSubmenu />
|
||||
|
||||
<DropdownMenu.Separator />
|
||||
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2">
|
||||
<File class={ICON_CLASS_DEFAULT} />
|
||||
@@ -156,31 +143,14 @@
|
||||
|
||||
<ChatFormActionAddToolsSubmenu />
|
||||
|
||||
<ChatFormActionAddMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={chatFormActions.onMcpSettingsClick}
|
||||
>
|
||||
<McpLogo class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
{#if chatFormActions.hasMcpPromptsSupport}
|
||||
<DropdownMenu.Separator />
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={chatFormActions.onMcpPromptClick}
|
||||
>
|
||||
<Zap class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>MCP Prompt</span>
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
|
||||
{#if chatFormActions.hasMcpResourcesSupport}
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={chatFormActions.onMcpResourcesClick}
|
||||
>
|
||||
<FolderOpen class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>MCP Resources</span>
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
<span>MCP Servers</span>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
||||
</div>
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { FolderOpen, Server, Zap } from '@lucide/svelte';
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import { McpLogo } from '$lib/components/app';
|
||||
import { ICON_CLASS_DEFAULT } from '$lib/constants';
|
||||
import { getChatFormActionsContext } from '$lib/contexts';
|
||||
|
||||
const chatFormActions = getChatFormActionsContext();
|
||||
|
||||
function handleServersClick() {
|
||||
chatFormActions.onMcpSettingsClick?.();
|
||||
}
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Sub>
|
||||
<DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2">
|
||||
<McpLogo class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>MCP</span>
|
||||
</DropdownMenu.SubTrigger>
|
||||
|
||||
<DropdownMenu.SubContent class="w-48">
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={handleServersClick}
|
||||
>
|
||||
<Server class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>Servers</span>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
{#if chatFormActions.hasMcpPromptsSupport}
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={chatFormActions.onMcpPromptClick}
|
||||
>
|
||||
<Zap class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>Prompts</span>
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
|
||||
{#if chatFormActions.hasMcpResourcesSupport}
|
||||
<DropdownMenu.Item
|
||||
class="flex cursor-pointer items-center gap-2"
|
||||
onclick={chatFormActions.onMcpResourcesClick}
|
||||
>
|
||||
<FolderOpen class={ICON_CLASS_DEFAULT} />
|
||||
|
||||
<span>Resources</span>
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
</DropdownMenu.SubContent>
|
||||
</DropdownMenu.Sub>
|
||||
+4
-3
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { SkipForward, Square } from '@lucide/svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import {
|
||||
ChatFormActionModels,
|
||||
@@ -10,7 +9,7 @@
|
||||
ChatFormContextGauge
|
||||
} from '$lib/components/app';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { ICON_CLASS_DEFAULT, ROUTES } from '$lib/constants';
|
||||
import { ICON_CLASS_DEFAULT } from '$lib/constants';
|
||||
import { setChatFormActionsContext } from '$lib/contexts';
|
||||
import { FileTypeCategory, MessageRole } from '$lib/enums';
|
||||
import { ChatService } from '$lib/services';
|
||||
@@ -34,6 +33,7 @@
|
||||
onSystemPromptClick?: () => void;
|
||||
onMcpPromptClick?: () => void;
|
||||
onMcpResourcesClick?: () => void;
|
||||
onMcpSettingsClick?: () => void;
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -47,6 +47,7 @@
|
||||
onFileUpload,
|
||||
onMcpPromptClick,
|
||||
onMcpResourcesClick,
|
||||
onMcpSettingsClick,
|
||||
onMicClick,
|
||||
onStop,
|
||||
onSystemPromptClick,
|
||||
@@ -163,7 +164,7 @@
|
||||
return onMcpResourcesClick;
|
||||
},
|
||||
get onMcpSettingsClick() {
|
||||
return () => goto(ROUTES.MCP_SERVERS);
|
||||
return onMcpSettingsClick;
|
||||
},
|
||||
get onSystemPromptClick() {
|
||||
return onSystemPromptClick;
|
||||
|
||||
@@ -221,25 +221,17 @@ export { default as ChatFormActionModels } from './ChatForm/ChatFormActions/Chat
|
||||
export { default as ChatFormActionAddToolsSubmenu } from './ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddToolsSubmenu.svelte';
|
||||
|
||||
/**
|
||||
* Dropdown submenu for managing MCP servers in the chat form.
|
||||
* Dropdown submenu for MCP prompts and resources in the chat form.
|
||||
*
|
||||
* Displays a searchable list of enabled MCP servers with toggle switches
|
||||
* to enable/disable each server for chat. Shows server favicon, health status,
|
||||
* and a "Manage MCP Servers" settings link.
|
||||
*
|
||||
* Features:
|
||||
* - Search/filter servers by name or URL
|
||||
* - Per-server toggle to enable/disable for chat
|
||||
* - Health check indicator (shows "Error" badge for failed servers)
|
||||
* - Server favicon display
|
||||
* - Settings link to manage MCP server configuration
|
||||
* Shows an "MCP" sub-menu item with entries for MCP Prompts and MCP
|
||||
* Resources. Only visible when the server supports them.
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatFormActionAddMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />
|
||||
* <ChatFormActionAddMcpSubmenu />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatFormActionAddMcpServersSubmenu } from './ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddMcpServersSubmenu.svelte';
|
||||
export { default as ChatFormActionAddMcpSubmenu } from './ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddMcpSubmenu.svelte';
|
||||
|
||||
/**
|
||||
* Dropdown submenu for selecting reasoning effort level.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { SettingsMcpServers } from '$lib/components/app/settings';
|
||||
import { McpLogo } from '$lib/components/app';
|
||||
import * as Dialog from '$lib/components/ui/dialog';
|
||||
|
||||
interface Props {
|
||||
open?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
let { onOpenChange, open = $bindable(false) }: Props = $props();
|
||||
|
||||
function handleOpenChange(value: boolean) {
|
||||
open = value;
|
||||
onOpenChange?.(value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog.Root {open} onOpenChange={handleOpenChange}>
|
||||
<Dialog.Content class="h-[calc(100vh-4rem)]! max-h-240! w-[calc(100vw-4rem)]! max-w-360! flex flex-col">
|
||||
<Dialog.Header >
|
||||
<Dialog.Title class="flex items-center gap-2">
|
||||
<McpLogo class="h-5 w-5" />
|
||||
|
||||
<span>MCP Servers</span>
|
||||
</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
|
||||
<SettingsMcpServers class="mt-4" />
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
@@ -18,6 +18,14 @@
|
||||
*/
|
||||
export { default as DialogMcpServerAddNew } from './DialogMcpServerAddNew.svelte';
|
||||
|
||||
/**
|
||||
* **DialogMcpServers** - MCP servers dialog shown from the chat form
|
||||
*
|
||||
* Shows the same MCP server list as the `/mcp-servers` route inside a modal
|
||||
* dialog.
|
||||
*/
|
||||
export { default as DialogMcpServers } from './DialogMcpServers.svelte';
|
||||
|
||||
/**
|
||||
* **DialogExportSettings** - Settings export dialog with sensitive data warning
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user