Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7c8ece9
ui : strip trailing container-format segments from parsed model names
allozaur Aug 15, 2026
2190337
ui : show reasoning and modality icons on model options and search by…
allozaur Aug 15, 2026
3d0da6f
ui : keep reasoning submenu visible regardless of model state
allozaur Aug 15, 2026
4d6874b
ui : add show-org-name-in-trigger display setting
allozaur Aug 15, 2026
2fab2f4
ui : move model list into a submenu within the model selector
allozaur Aug 15, 2026
8961962
ui : make model option hover and focus highlight override the active …
allozaur Aug 15, 2026
7af64f3
ui : add raw model id tooltip to model selector options
allozaur Aug 15, 2026
dfd6ed8
feat: Enable microphone input as default for audio models
allozaur Aug 16, 2026
c684700
ui : fix eslint issues in chat form and model selector
allozaur Aug 17, 2026
20ec1c9
ui : open MCP servers in a dialog from the chat form
allozaur Aug 22, 2026
b9c3bb6
ui : browse MCP resources from the server card
allozaur Aug 22, 2026
c2ef793
ui : remove mcp-servers route and sidebar entry
allozaur Aug 22, 2026
a8aef5d
ui : remove unused MCP servers submenu component
allozaur Aug 22, 2026
45b0c17
chore: Format
allozaur Aug 22, 2026
553f3bc
ui: replace per-conversation MCP overrides with per-conversation tool…
allozaur Aug 22, 2026
dcbf990
feat(ui): make base dialog responsive and support sticky headers
allozaur Aug 22, 2026
d72e579
feat(ui): add DialogSettingsChat dialog
allozaur Aug 22, 2026
29776f6
refactor(ui): switch SettingsChat to in-app section navigation
allozaur Aug 22, 2026
8573111
feat(ui): open settings as dialog from sidebar
allozaur Aug 22, 2026
3d7ca1a
refactor(ui): remove settings route and URL-based settings navigation
allozaur Aug 22, 2026
c390ec8
fix(ui): adjust MCP dialogs for new base sizing and close add sheet b…
allozaur Aug 22, 2026
515b993
ui: show modality icons instead of file submenu in chat add menu
allozaur Aug 22, 2026
0b24f4a
ui: move dialog close button to the sticky header
allozaur Aug 22, 2026
4d2d1c2
chore: Format
allozaur Aug 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { Eye, Mic, Video } from '@lucide/svelte';
import { Image, Mic, Video } from '@lucide/svelte';
import { ModelModality } from '$lib/enums';

interface Props {
Expand All @@ -19,7 +19,7 @@
]}
>
{#if modality === ModelModality.VISION}
<Eye class="h-3 w-3" />
<Image class="h-3 w-3" />

Vision (Image)
{:else if modality === ModelModality.VIDEO}
Expand Down
16 changes: 11 additions & 5 deletions tools/ui/src/lib/components/app/chat/ChatForm/ChatForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
ChatFormInputFileInputInvisible,
ChatFormMcpResourcesList,
ChatFormPickers,
DialogMcpResourcesBrowser
DialogMcpResourcesBrowser,
DialogMcpServers
} from '$lib/components/app';
import {
CLIPBOARD_CONTENT_QUOTE_PREFIX,
Expand Down Expand Up @@ -151,9 +152,8 @@
getServerHome: () => toolsStore.serverHome ?? null,
getShowModelSelector: () => showModelSelector,
getValue: () => value,
hasCwdTools: () => toolsStore.hasEnabledCwdTools,
hasPrompts: () =>
mcpStore.hasPromptsCapability(conversationsStore.preferences.getAllMcpServerOverrides()),
hasCwdTools: () => conversationsStore.preferences.hasEnabledCwdTools(),
hasPrompts: () => mcpStore.hasPromptsCapability(),
openModelSelector: () => chatFormActionsRef?.openModelSelector(),
setCaretOffset: (offset) => inputRef?.setCaretOffset(offset),
setValue: (v) => {
Expand Down Expand Up @@ -183,6 +183,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(() => {
Expand Down Expand Up @@ -618,6 +621,7 @@
onFileUpload={handleFileUpload}
onMcpPromptClick={showMcpPromptButton ? () => pickers.openPromptPicker() : undefined}
onMcpResourcesClick={() => (isResourceDialogOpen = true)}
onMcpSettingsClick={() => (isMcpServersDialogOpen = true)}
onMicClick={handleMicClick}
{onStop}
onSystemPromptClick={() => onSystemPromptClick?.({ files: uploadedFiles, message: value })}
Expand All @@ -630,7 +634,7 @@

<ContextGaugePopup />

{#if toolsStore.hasEnabledCwdTools}
{#if conversationsStore.preferences.hasEnabledCwdTools()}
<ChatFormCurrentWorkingDirectory
bind:query={pickers.workingDirectoryQuery}
customAnchor={mentionAnchor}
Expand All @@ -656,3 +660,5 @@
}}
preSelectedUri={preSelectedResourceUri}
/>

<DialogMcpServers bind:open={isMcpServersDialogOpen} />
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
<script lang="ts">
import { File, FolderOpen, MessageSquare, Plus, Zap } from '@lucide/svelte';
import {
ChatFormActionAddMcpServersSubmenu,
ChatFormActionAddReasoningSubmenu,
ChatFormActionAddToolsSubmenu
} from '$lib/components/app';
import { File, Image, MessageSquare, Mic, Plus, Video } 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';
import { cn } from '$lib/components/ui/utils';
import {
ATTACHMENT_FILE_ITEMS,
ATTACHMENT_TOOLTIP_TEXT,
ICON_CLASS_DEFAULT,
TOOLTIP_DELAY_DURATION
ICON_CLASS_DEFAULT
} from '$lib/constants';
import { getChatFormActionsContext } from '$lib/contexts';
import { AttachmentAction, AttachmentItemEnabledWhen } from '$lib/enums';
import { useAttachmentMenu } from '$lib/hooks/use-attachment-menu.svelte';

interface Props {
Expand All @@ -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,
Expand All @@ -54,6 +45,18 @@
dropdownOpen = false;
}
);

const FILE_MODALITY_ICONS: Record<string, { icon: typeof Image; label: string }> = {
[AttachmentItemEnabledWhen.HAS_AUDIO_MODALITY]: { icon: Mic, label: 'Audio' },
[AttachmentItemEnabledWhen.HAS_VIDEO_MODALITY]: { icon: Video, label: 'Video' },
[AttachmentItemEnabledWhen.HAS_VISION_MODALITY]: { icon: Image, label: 'Vision' }
};

const supportedModalities = $derived.by(() =>
ATTACHMENT_FILE_ITEMS.filter((item) => attachmentMenu.isItemEnabled(item.enabledWhen))
.map((item) => FILE_MODALITY_ICONS[item.enabledWhen ?? ''])
.filter((modality) => modality !== undefined)
);
</script>

<div class="flex items-center gap-1 {className}">
Expand Down Expand Up @@ -93,54 +96,32 @@
}
}}
>
<ChatFormActionAddReasoningSubmenu />

<DropdownMenu.Separator />

<DropdownMenu.Sub>
<DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2">
<File class={ICON_CLASS_DEFAULT} />
<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[AttachmentAction.FILE_UPLOAD]()}
>
<File class={ICON_CLASS_DEFAULT} />

<span class="flex min-w-0 items-center gap-2">
<span>Add files</span>
</DropdownMenu.SubTrigger>

<DropdownMenu.SubContent class="w-48">
{#each ATTACHMENT_FILE_ITEMS as item (item.id)}
{@const enabled = attachmentMenu.isItemEnabled(item.enabledWhen)}
{#if enabled}
<DropdownMenu.Item
class="{item.class ?? ''} flex cursor-pointer items-center gap-2"
onclick={() => attachmentMenu.callbacks[item.action]()}
>
<item.icon class={ICON_CLASS_DEFAULT} />

<span>{item.label}</span>
</DropdownMenu.Item>
{:else if item.disabledTooltip}
<Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
<Tooltip.Trigger tabindex={-1}>
{#snippet child({ props })}
<div {...props} class="cursor-default">
<DropdownMenu.Item
class="{item.class ?? ''} flex items-center gap-2"
disabled
>
<item.icon class={ICON_CLASS_DEFAULT} />

<span>{item.label}</span>
</DropdownMenu.Item>
</div>
{/snippet}
</Tooltip.Trigger>

<Tooltip.Content side="right">
<p>{item.disabledTooltip}</p>
</Tooltip.Content>
</Tooltip.Root>
{/if}
{/each}
</DropdownMenu.SubContent>
</DropdownMenu.Sub>

{#if supportedModalities.length > 0}
<span class="flex items-center gap-0.75 text-muted-foreground">
{#each supportedModalities as modality (modality.label)}
<Tooltip.Root>
<Tooltip.Trigger>
<modality.icon class="size-2.75" />
</Tooltip.Trigger>

<Tooltip.Content>
<p>{modality.label}</p>
</Tooltip.Content>
</Tooltip.Root>
{/each}
</span>
{/if}
</span>
</DropdownMenu.Item>

<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
Expand All @@ -156,31 +137,14 @@

<ChatFormActionAddToolsSubmenu />

<ChatFormActionAddMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />

{#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} />
<DropdownMenu.Item
class="flex cursor-pointer items-center gap-2"
onclick={chatFormActions.onMcpSettingsClick}
>
<McpLogo class={ICON_CLASS_DEFAULT} />

<span>MCP Resources</span>
</DropdownMenu.Item>
{/if}
<span>MCP Servers</span>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
</div>

This file was deleted.

Loading
Loading