🗣 fix: Add Various State Change Announcements (#11495)
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run

* fix: Agent Builder Reset button announcements

* fix: special variables announcements

* fix: model select announcements

* fix: prompt deletion announcement

* refactor: encapsulate model display name logic

* chore: address comments

* chore: re-order i18n strings
This commit is contained in:
Dustin Healy 2026-02-05 16:42:15 +01:00 committed by GitHub
parent fcb363403a
commit 46624798b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 2 deletions

View file

@ -1,5 +1,5 @@
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import React, { createContext, useContext, useState, useMemo } from 'react'; import React, { createContext, useContext, useState, useMemo, useCallback } from 'react';
import { EModelEndpoint, isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider'; import { EModelEndpoint, isAgentsEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
import type * as t from 'librechat-data-provider'; import type * as t from 'librechat-data-provider';
import type { Endpoint, SelectedValues } from '~/common'; import type { Endpoint, SelectedValues } from '~/common';
@ -8,8 +8,9 @@ import {
useSelectorEffects, useSelectorEffects,
useKeyDialog, useKeyDialog,
useEndpoints, useEndpoints,
useLocalize,
} from '~/hooks'; } from '~/hooks';
import { useAgentsMapContext, useAssistantsMapContext } from '~/Providers'; import { useAgentsMapContext, useAssistantsMapContext, useLiveAnnouncer } from '~/Providers';
import { useGetEndpointsQuery, useListAgentsQuery } from '~/data-provider'; import { useGetEndpointsQuery, useListAgentsQuery } from '~/data-provider';
import { useModelSelectorChatContext } from './ModelSelectorChatContext'; import { useModelSelectorChatContext } from './ModelSelectorChatContext';
import useSelectMention from '~/hooks/Input/useSelectMention'; import useSelectMention from '~/hooks/Input/useSelectMention';
@ -59,6 +60,8 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
const { data: endpointsConfig } = useGetEndpointsQuery(); const { data: endpointsConfig } = useGetEndpointsQuery();
const { endpoint, model, spec, agent_id, assistant_id, conversation, newConversation } = const { endpoint, model, spec, agent_id, assistant_id, conversation, newConversation } =
useModelSelectorChatContext(); useModelSelectorChatContext();
const localize = useLocalize();
const { announcePolite } = useLiveAnnouncer();
const modelSpecs = useMemo(() => { const modelSpecs = useMemo(() => {
const specs = startupConfig?.modelSpecs?.list ?? []; const specs = startupConfig?.modelSpecs?.list ?? [];
if (!agentsMap) { if (!agentsMap) {
@ -93,6 +96,21 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
endpointsConfig, endpointsConfig,
}); });
const getModelDisplayName = useCallback(
(endpoint: Endpoint, model: string): string => {
if (isAgentsEndpoint(endpoint.value)) {
return endpoint.agentNames?.[model] ?? agentsMap?.[model]?.name ?? model;
}
if (isAssistantsEndpoint(endpoint.value)) {
return endpoint.assistantNames?.[model] ?? model;
}
return model;
},
[agentsMap],
);
const { onSelectEndpoint, onSelectSpec } = useSelectMention({ const { onSelectEndpoint, onSelectSpec } = useSelectMention({
// presets, // presets,
modelSpecs, modelSpecs,
@ -207,6 +225,10 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
model, model,
modelSpec: '', modelSpec: '',
}); });
const modelDisplayName = getModelDisplayName(endpoint, model);
const announcement = localize('com_ui_model_selected', { 0: modelDisplayName });
announcePolite({ message: announcement, isStatus: true });
}; };
const value = { const value = {

View file

@ -14,6 +14,7 @@ import {
import { useDeletePromptGroup, useUpdatePromptGroup } from '~/data-provider'; import { useDeletePromptGroup, useUpdatePromptGroup } from '~/data-provider';
import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon'; import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon';
import { useLocalize, useResourcePermissions } from '~/hooks'; import { useLocalize, useResourcePermissions } from '~/hooks';
import { useLiveAnnouncer } from '~/Providers';
import { cn } from '~/utils'; import { cn } from '~/utils';
interface DashGroupItemProps { interface DashGroupItemProps {
@ -25,6 +26,7 @@ function DashGroupItemComponent({ group, instanceProjectId }: DashGroupItemProps
const params = useParams(); const params = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const localize = useLocalize(); const localize = useLocalize();
const { announcePolite } = useLiveAnnouncer();
const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null); const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const [nameInputValue, setNameInputValue] = useState(group.name); const [nameInputValue, setNameInputValue] = useState(group.name);
@ -49,6 +51,8 @@ function DashGroupItemComponent({ group, instanceProjectId }: DashGroupItemProps
const deleteGroup = useDeletePromptGroup({ const deleteGroup = useDeletePromptGroup({
onSuccess: (_response, variables) => { onSuccess: (_response, variables) => {
if (variables.id === group._id) { if (variables.id === group._id) {
const announcement = localize('com_ui_prompt_deleted', { 0: group.name });
announcePolite({ message: announcement, isStatus: true });
navigate('/d/prompts'); navigate('/d/prompts');
} }
}, },

View file

@ -5,6 +5,7 @@ import { useFormContext } from 'react-hook-form';
import { DropdownPopup } from '@librechat/client'; import { DropdownPopup } from '@librechat/client';
import { specialVariables } from 'librechat-data-provider'; import { specialVariables } from 'librechat-data-provider';
import type { TSpecialVarLabel } from 'librechat-data-provider'; import type { TSpecialVarLabel } from 'librechat-data-provider';
import { useLiveAnnouncer } from '~/Providers';
import { useLocalize } from '~/hooks'; import { useLocalize } from '~/hooks';
interface VariableOption { interface VariableOption {
@ -30,6 +31,7 @@ export default function VariablesDropdown({
const localize = useLocalize(); const localize = useLocalize();
const methods = useFormContext(); const methods = useFormContext();
const { setValue, getValues } = methods; const { setValue, getValues } = methods;
const { announcePolite } = useLiveAnnouncer();
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
@ -39,6 +41,8 @@ export default function VariablesDropdown({
const prefix = localize(label); const prefix = localize(label);
setValue(fieldName, currentText + spacer + prefix + ': ' + value); setValue(fieldName, currentText + spacer + prefix + ': ' + value);
setIsMenuOpen(false); setIsMenuOpen(false);
const announcement = localize('com_ui_special_variable_added', { 0: prefix });
announcePolite({ message: announcement, isStatus: true });
}; };
return ( return (

View file

@ -15,6 +15,7 @@ import {
import type * as t from 'librechat-data-provider'; import type * as t from 'librechat-data-provider';
import type { AgentForm, AgentModelPanelProps, StringOption } from '~/common'; import type { AgentForm, AgentModelPanelProps, StringOption } from '~/common';
import { useGetEndpointsQuery } from '~/data-provider'; import { useGetEndpointsQuery } from '~/data-provider';
import { useLiveAnnouncer } from '~/Providers';
import { useLocalize } from '~/hooks'; import { useLocalize } from '~/hooks';
import { Panel } from '~/common'; import { Panel } from '~/common';
import { cn } from '~/utils'; import { cn } from '~/utils';
@ -25,6 +26,7 @@ export default function ModelPanel({
models: modelsData, models: modelsData,
}: Pick<AgentModelPanelProps, 'models' | 'providers' | 'setActivePanel'>) { }: Pick<AgentModelPanelProps, 'models' | 'providers' | 'setActivePanel'>) {
const localize = useLocalize(); const localize = useLocalize();
const { announcePolite } = useLiveAnnouncer();
const { control, setValue } = useFormContext<AgentForm>(); const { control, setValue } = useFormContext<AgentForm>();
@ -91,6 +93,7 @@ export default function ModelPanel({
const handleResetParameters = () => { const handleResetParameters = () => {
setValue('model_parameters', {} as t.AgentModelParameters); setValue('model_parameters', {} as t.AgentModelParameters);
announcePolite({ message: localize('com_ui_model_parameters_reset'), isStatus: true });
}; };
return ( return (

View file

@ -1174,6 +1174,8 @@
"com_ui_misc": "Misc.", "com_ui_misc": "Misc.",
"com_ui_model": "Model", "com_ui_model": "Model",
"com_ui_model_parameters": "Model Parameters", "com_ui_model_parameters": "Model Parameters",
"com_ui_model_parameters_reset": "Model Parameters have been reset.",
"com_ui_model_selected": "{{0}} selected",
"com_ui_more_info": "More info", "com_ui_more_info": "More info",
"com_ui_my_prompts": "My Prompts", "com_ui_my_prompts": "My Prompts",
"com_ui_name": "Name", "com_ui_name": "Name",
@ -1240,6 +1242,7 @@
"com_ui_privacy_policy": "Privacy policy", "com_ui_privacy_policy": "Privacy policy",
"com_ui_privacy_policy_url": "Privacy Policy URL", "com_ui_privacy_policy_url": "Privacy Policy URL",
"com_ui_prompt": "Prompt", "com_ui_prompt": "Prompt",
"com_ui_prompt_deleted": "{{0}} deleted",
"com_ui_prompt_group_button": "{{name}} prompt, {{category}} category", "com_ui_prompt_group_button": "{{name}} prompt, {{category}} category",
"com_ui_prompt_group_button_no_category": "{{name}} prompt", "com_ui_prompt_group_button_no_category": "{{name}} prompt",
"com_ui_prompt_groups": "Prompt Groups List", "com_ui_prompt_groups": "Prompt Groups List",
@ -1380,6 +1383,7 @@
"com_ui_special_var_current_datetime": "Current Date & Time", "com_ui_special_var_current_datetime": "Current Date & Time",
"com_ui_special_var_current_user": "Current User", "com_ui_special_var_current_user": "Current User",
"com_ui_special_var_iso_datetime": "UTC ISO Datetime", "com_ui_special_var_iso_datetime": "UTC ISO Datetime",
"com_ui_special_variable_added": "{{0}} special variable added.",
"com_ui_special_variables": "Special variables:", "com_ui_special_variables": "Special variables:",
"com_ui_special_variables_more_info": "You can select special variables from the dropdown: `{{current_date}}` (today's date and day of week), `{{current_datetime}}` (local date and time), `{{utc_iso_datetime}}` (UTC ISO datetime), and `{{current_user}}` (your account name).", "com_ui_special_variables_more_info": "You can select special variables from the dropdown: `{{current_date}}` (today's date and day of week), `{{current_datetime}}` (local date and time), `{{utc_iso_datetime}}` (UTC ISO datetime), and `{{current_user}}` (your account name).",
"com_ui_speech_not_supported": "Your browser does not support speech recognition", "com_ui_speech_not_supported": "Your browser does not support speech recognition",