Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9f6197a
ui : strip trailing container-format segments from parsed model names
allozaur Aug 15, 2026
ff90a6a
ui : show reasoning and modality icons on model options and search by…
allozaur Aug 15, 2026
a128088
ui : keep reasoning submenu visible regardless of model state
allozaur Aug 15, 2026
ccd59b5
ui : add show-org-name-in-trigger display setting
allozaur Aug 15, 2026
f9e2ace
ui : move model list into a submenu within the model selector
allozaur Aug 15, 2026
8502604
ui : make model option hover and focus highlight override the active …
allozaur Aug 15, 2026
9cda9d7
ui : add raw model id tooltip to model selector options
allozaur Aug 15, 2026
7ef7827
feat: Enable microphone input as default for audio models
allozaur Aug 16, 2026
2e53a6a
ui : fix formatting in chat form and model selector
allozaur Aug 17, 2026
ea7e1b0
ui : fix eslint issues in chat form and model selector
allozaur Aug 17, 2026
b931787
ui : open MCP servers in a dialog from the chat form
allozaur Aug 22, 2026
2bbc43c
ui : browse MCP resources from the server card
allozaur Aug 22, 2026
130b7f3
ui : remove mcp-servers route and sidebar entry
allozaur Aug 22, 2026
ed0dc2a
ui : remove unused MCP servers submenu component
allozaur Aug 22, 2026
6fb7c99
chore: Format
allozaur Aug 22, 2026
b7be05c
ui: replace per-conversation MCP overrides with per-conversation tool…
allozaur Aug 22, 2026
a1aac63
feat(ui): make base dialog responsive and support sticky headers
allozaur Aug 22, 2026
54d49c2
feat(ui): add DialogSettingsChat dialog
allozaur Aug 22, 2026
efc521d
refactor(ui): switch SettingsChat to in-app section navigation
allozaur Aug 22, 2026
d6c5335
feat(ui): open settings as dialog from sidebar
allozaur Aug 22, 2026
ce8ca1d
refactor(ui): remove settings route and URL-based settings navigation
allozaur Aug 22, 2026
f905439
fix(ui): adjust MCP dialogs for new base sizing and close add sheet b…
allozaur Aug 22, 2026
a1d2bc5
ui: show modality icons instead of file submenu in chat add menu
allozaur Aug 22, 2026
386aa6b
ui: move dialog close button to the sticky header
allozaur Aug 22, 2026
c1249de
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 @@ -624,13 +627,14 @@
onSystemPromptClick={() => onSystemPromptClick?.({ files: uploadedFiles, message: value })}
onMcpPromptClick={showMcpPromptButton ? () => pickers.openPromptPicker() : undefined}
onMcpResourcesClick={() => (isResourceDialogOpen = true)}
onMcpSettingsClick={() => (isMcpServersDialogOpen = true)}
/>
</div>
</div>

<ContextGaugePopup />

{#if toolsStore.hasEnabledCwdTools}
{#if conversationsStore.preferences.hasEnabledCwdTools()}
<ChatFormCurrentWorkingDirectory
directory={cwd}
isOpen={pickers.isWorkingDirectoryPickerOpen}
Expand All @@ -656,3 +660,5 @@
}
}}
/>

<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