ui: Improve Chat Form Actions UI/UX (models selector, add panel) (#27746)
* ui : strip trailing container-format segments from parsed model names * ui : show reasoning and modality icons on model options and search by modality * ui : keep reasoning submenu visible regardless of model state * ui : add show-org-name-in-trigger display setting * ui : move model list into a submenu within the model selector * ui : make model option hover and focus highlight override the active state * ui : add raw model id tooltip to model selector options * feat: Enable microphone input as default for audio models * ui : fix eslint issues in chat form and model selector * ui: show modality icons instead of file submenu in chat add menu Assisted-by: pi * chore: Format * chore: Format * ui: add ModelCapability enum and shared modality/capability icon constants Assisted by: pi:GLM-5.3-Flash * ui: derive modality badge icons and labels from shared constants Assisted by: pi:GLM-5.3-Flash * ui: split model option icons into capabilities and modalities Replace the supportsThinking flag on ModelId with a capabilities object keyed like ModelModalities, so future capabilities (tool calls, etc.) slot in alongside reasoning. Icons and labels now come from the shared CAPABILITY_ICONS/MODALITY_ICONS constants. Assisted by: pi:GLM-5.3-Flash
This commit is contained in:
@@ -8,10 +8,13 @@ import {
|
||||
File as FileIcon,
|
||||
FileText as FileTextIcon,
|
||||
Image as ImageIcon,
|
||||
Lightbulb as ReasoningIcon,
|
||||
Mic as AudioIcon,
|
||||
Video as VideoIcon
|
||||
} from '@lucide/svelte';
|
||||
import { FileTypeCategory, ModelModality } from '$lib/enums';
|
||||
import { FileTypeCategory, ModelCapability, ModelModality } from '$lib/enums';
|
||||
import type { ModelCapabilities, ModelModalities } from '$lib/types/models';
|
||||
import type { Component } from 'svelte';
|
||||
|
||||
export const FILE_TYPE_ICONS = {
|
||||
[FileTypeCategory.AUDIO]: AudioIcon,
|
||||
@@ -35,6 +38,29 @@ export const MODALITY_LABELS = {
|
||||
[ModelModality.VISION]: 'Vision'
|
||||
} as const;
|
||||
|
||||
/** Maps an input ModelModality to the boolean flag it drives on the ModelModalities type */
|
||||
export const MODALITY_FLAG_KEYS: Record<
|
||||
Exclude<ModelModality, ModelModality.TEXT>,
|
||||
keyof ModelModalities
|
||||
> = {
|
||||
[ModelModality.AUDIO]: 'audio',
|
||||
[ModelModality.VIDEO]: 'video',
|
||||
[ModelModality.VISION]: 'vision'
|
||||
};
|
||||
|
||||
export const CAPABILITY_ICONS: Record<ModelCapability, Component> = {
|
||||
[ModelCapability.REASONING]: ReasoningIcon
|
||||
} as const;
|
||||
|
||||
export const CAPABILITY_LABELS: Record<ModelCapability, string> = {
|
||||
[ModelCapability.REASONING]: 'Reasoning'
|
||||
} as const;
|
||||
|
||||
/** Maps a ModelCapability to the boolean flag it drives on the ModelCapabilities type */
|
||||
export const CAPABILITY_FLAG_KEYS: Record<ModelCapability, keyof ModelCapabilities> = {
|
||||
[ModelCapability.REASONING]: 'reasoning'
|
||||
};
|
||||
|
||||
// Shared SVG icon strings for copy and preview buttons
|
||||
export const COPY_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy-icon lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ export const SETTINGS_KEYS = {
|
||||
SHOW_FULL_PATH_IN_MENTIONS: 'showFullPathInMentions',
|
||||
// Display
|
||||
SHOW_MESSAGE_STATS: 'showMessageStats',
|
||||
SHOW_MODEL_ORG_NAME_IN_TRIGGER: 'showModelOrgNameInTrigger',
|
||||
SHOW_MODEL_QUANTIZATION: 'showModelQuantization',
|
||||
SHOW_MODEL_TAGS: 'showModelTags',
|
||||
SHOW_RAW_MODEL_NAMES: 'showRawModelNames',
|
||||
|
||||
@@ -111,9 +111,8 @@ export const SETTINGS_REGISTRY: SettingsSectionEntry[] = [
|
||||
type: SettingsFieldType.CHECKBOX
|
||||
},
|
||||
{
|
||||
defaultValue: false,
|
||||
defaultValue: true,
|
||||
help: 'Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.',
|
||||
isExperimental: true,
|
||||
key: SETTINGS_KEYS.AUTO_MIC_ON_EMPTY,
|
||||
label: 'Show microphone on empty input',
|
||||
type: SettingsFieldType.CHECKBOX
|
||||
@@ -283,6 +282,13 @@ export const SETTINGS_REGISTRY: SettingsSectionEntry[] = [
|
||||
label: 'Show model tags',
|
||||
type: SettingsFieldType.CHECKBOX
|
||||
},
|
||||
{
|
||||
defaultValue: false,
|
||||
help: 'Display the organization name in the model selector trigger button.',
|
||||
key: SETTINGS_KEYS.SHOW_MODEL_ORG_NAME_IN_TRIGGER,
|
||||
label: 'Show organization name in model selector trigger',
|
||||
type: SettingsFieldType.CHECKBOX
|
||||
},
|
||||
{
|
||||
defaultValue: false,
|
||||
help: 'Display the current build version in the bottom-right corner of the interface.',
|
||||
|
||||
Reference in New Issue
Block a user