🗓️ feat: Add Special Variables for Prompts & Agents, Prompt UI Improvements (#7123)

* wip: Add Instructions component for agent configuration

*  feat: Implement DropdownPopup for variable insertion in instructions

* refactor: Enhance variable handling by exporting specialVariables and updating Markdown components

* feat: Add special variable support for current date and user in Instructions component

* refactor: Update handleAddVariable to include localized label

* feat: replace special variables in instructions presets

* chore: update parameter type for user in getListAgents function

* refactor: integrate dayjs for date handling and move replaceSpecialVars function to data-provider

* feat: enhance replaceSpecialVars to include day number in current date format

* feat: integrate replaceSpecialVars for processing agent instructions

* feat: add support for current date & time in replaceSpecialVars function

* feat: add iso_datetime support in replaceSpecialVars function

* fix: enforce text parameter to be a required field in replaceSpecialVars function

* feat: add ISO datetime support in translation file

* fix: disable eslint warning for autoFocus in TextareaAutosize component

* feat: add VariablesDropdown component and integrate it into CreatePromptForm and PromptEditor; update translation for special variables

* fix: CategorySelector and related localizations

* fix: add z-index class to LanguageSTTDropdown for proper stacking context

* fix: add max-height and overflow styles to OGDialogContent in VariableDialog and PreviewPrompt components

* fix: update variable detection logic to exclude special variables and improve regex matching

* fix: improve accessibility text for actions menu in ChatGroupItem component

* fix: adjust max-width and height styles for dialog components and improve markdown rendering for light vs. dark, height/widths, etc.

* fix: remove commented-out code for better readability in PromptVariableGfm component

* fix: handle undefined input parameter in setParams function call

* fix: update variable label types to use TSpecialVarLabel for consistency

* fix: remove outdated information from special variables description in translation file

* fix: enhance unused i18next keys detection for special variable keys

* fix: update color classes for consistency/a11y in category and prompt variable components

* fix: update PromptVariableGfm component and special variable styles for consistency

* fix: improve variable highlighting logic in VariableForm component

* fix: update background color classes for consistency in VariableForm component

* fix: add missing ref parameter to Dialog component in OriginalDialog

* refactor: move navigate call for new conversation to after setConversation update

* refactor: move message query hook to client workspace; fix: handle edge case for navigation from finalHandler creating race condition for response message DB save

* chore: bump librechat-data-provider to 0.7.793

* ci: add unit tests for replaceSpecialVars function

* fix: implement getToolkitKey function for image_gen_oai toolkit filtering/including

* ci: enhance dayjs mock for consistent date/time values in tests

* fix: MCP stdio server fail to start when passing env property

* fix: use optional chaining for clientRef dereferencing in AskController and EditController
feat: add context to saveMessage call in streamResponse utility

* fix: only save error messages if the userMessageId was initialized

* refactor: add isNotAppendable check to disable inputs in ChatForm and useTextarea

* feat: enhance error handling in useEventHandlers and update conversation state in useNewConvo

* refactor: prepend underscore to conversationId in newConversation template

* feat: log aborted conversations with minimal messages and use consistent conversationId generation

---------

Co-authored-by: Olivier Schiavo <olivier.schiavo@wengo.com>
Co-authored-by: aka012 <aka012@neowiz.com>
Co-authored-by: jiasheng <jiashengguo@outlook.com>
This commit is contained in:
Danny Avila 2025-04-29 03:49:02 -04:00 committed by GitHub
parent 0e8041bcac
commit 55f5f2d11a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 707 additions and 195 deletions

View file

@ -20,12 +20,13 @@ import type { TGenTitleMutation } from '~/data-provider';
import type { SetterOrUpdater, Resetter } from 'recoil';
import type { ConversationCursorData } from '~/utils';
import {
logger,
scrollToEnd,
getAllContentText,
addConvoToAllQueries,
updateConvoInAllQueries,
removeConvoFromAllQueries,
findConversationInInfinite,
getAllContentText,
} from '~/utils';
import useAttachmentHandler from '~/hooks/SSE/useAttachmentHandler';
import useContentHandler from '~/hooks/SSE/useContentHandler';
@ -487,10 +488,6 @@ export default function useEventHandlers({
}
if (setConversation && isAddedRequest !== true) {
if (location.pathname === '/c/new') {
navigate(`/c/${conversation.conversationId}`, { replace: true });
}
setConversation((prevState) => {
const update = {
...prevState,
@ -508,6 +505,9 @@ export default function useEventHandlers({
}
return update;
});
if (location.pathname === '/c/new') {
navigate(`/c/${conversation.conversationId}`, { replace: true });
}
}
setIsSubmitting(false);
@ -536,6 +536,12 @@ export default function useEventHandlers({
const conversationId =
userMessage.conversationId ?? submission.conversation?.conversationId ?? '';
const setErrorMessages = (convoId: string, errorMessage: TMessage) => {
const finalMessages: TMessage[] = [...messages, userMessage, errorMessage];
setMessages(finalMessages);
queryClient.setQueryData<TMessage[]>([QueryKeys.messages, convoId], finalMessages);
};
const parseErrorResponse = (data: TResData | Partial<TMessage>) => {
const metadata = data['responseMessage'] ?? data;
const errorMessage: Partial<TMessage> = {
@ -553,7 +559,7 @@ export default function useEventHandlers({
};
if (!data) {
const convoId = conversationId || v4();
const convoId = conversationId || `_${v4()}`;
const errorMetadata = parseErrorResponse({
text: 'Error connecting to server, try refreshing the page.',
...submission,
@ -564,7 +570,7 @@ export default function useEventHandlers({
getMessages,
submission,
});
setMessages([...messages, userMessage, errorResponse]);
setErrorMessages(convoId, errorResponse);
if (newConversation) {
newConversation({
template: { conversationId: convoId },
@ -577,9 +583,9 @@ export default function useEventHandlers({
const receivedConvoId = data.conversationId ?? '';
if (!conversationId && !receivedConvoId) {
const convoId = v4();
const convoId = `_${v4()}`;
const errorResponse = parseErrorResponse(data);
setMessages([...messages, userMessage, errorResponse]);
setErrorMessages(convoId, errorResponse);
if (newConversation) {
newConversation({
template: { conversationId: convoId },
@ -590,7 +596,7 @@ export default function useEventHandlers({
return;
} else if (!receivedConvoId) {
const errorResponse = parseErrorResponse(data);
setMessages([...messages, userMessage, errorResponse]);
setErrorMessages(conversationId, errorResponse);
setIsSubmitting(false);
return;
}
@ -601,7 +607,7 @@ export default function useEventHandlers({
parentMessageId: userMessage.messageId,
});
setMessages([...messages, userMessage, errorResponse]);
setErrorMessages(receivedConvoId, errorResponse);
if (receivedConvoId && paramId === Constants.NEW_CONVO && newConversation) {
newConversation({
template: { conversationId: receivedConvoId },
@ -612,7 +618,15 @@ export default function useEventHandlers({
setIsSubmitting(false);
return;
},
[setCompleted, setMessages, paramId, newConversation, setIsSubmitting, getMessages],
[
setCompleted,
setMessages,
paramId,
newConversation,
setIsSubmitting,
getMessages,
queryClient,
],
);
const abortConversation = useCallback(
@ -649,9 +663,11 @@ export default function useEventHandlers({
);
return;
} else if (!isAssistantsEndpoint(endpoint)) {
const convoId = conversationId || `_${v4()}`;
logger.log('conversation', 'Aborted conversation with minimal messages, ID: ' + convoId);
if (newConversation) {
newConversation({
template: { conversationId: conversationId || v4() },
template: { conversationId: convoId },
preset: tPresetSchema.parse(submission.conversation),
});
}