mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
* 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>
125 lines
4.2 KiB
TypeScript
125 lines
4.2 KiB
TypeScript
import { replaceSpecialVars } from '../src/parsers';
|
|
import { specialVariables } from '../src/config';
|
|
import type { TUser } from '../src/types';
|
|
|
|
// Mock dayjs module with consistent date/time values regardless of environment
|
|
jest.mock('dayjs', () => {
|
|
// Create a mock implementation that returns fixed values
|
|
const mockDayjs = () => ({
|
|
format: (format: string) => {
|
|
if (format === 'YYYY-MM-DD') {
|
|
return '2024-04-29';
|
|
}
|
|
if (format === 'YYYY-MM-DD HH:mm:ss') {
|
|
return '2024-04-29 12:34:56';
|
|
}
|
|
return format; // fallback
|
|
},
|
|
day: () => 1, // 1 = Monday
|
|
toISOString: () => '2024-04-29T16:34:56.000Z',
|
|
});
|
|
|
|
// Add any static methods needed
|
|
mockDayjs.extend = jest.fn();
|
|
|
|
return mockDayjs;
|
|
});
|
|
|
|
describe('replaceSpecialVars', () => {
|
|
// Create a partial user object for testing
|
|
const mockUser = {
|
|
name: 'Test User',
|
|
id: 'user123',
|
|
} as TUser;
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
test('should return the original text if text is empty', () => {
|
|
expect(replaceSpecialVars({ text: '' })).toBe('');
|
|
expect(replaceSpecialVars({ text: null as unknown as string })).toBe(null);
|
|
expect(replaceSpecialVars({ text: undefined as unknown as string })).toBe(undefined);
|
|
});
|
|
|
|
test('should replace {{current_date}} with the current date', () => {
|
|
const result = replaceSpecialVars({ text: 'Today is {{current_date}}' });
|
|
// dayjs().day() returns 1 for Monday (April 29, 2024 is a Monday)
|
|
expect(result).toBe('Today is 2024-04-29 (1)');
|
|
});
|
|
|
|
test('should replace {{current_datetime}} with the current datetime', () => {
|
|
const result = replaceSpecialVars({ text: 'Now is {{current_datetime}}' });
|
|
expect(result).toBe('Now is 2024-04-29 12:34:56 (1)');
|
|
});
|
|
|
|
test('should replace {{iso_datetime}} with the ISO datetime', () => {
|
|
const result = replaceSpecialVars({ text: 'ISO time: {{iso_datetime}}' });
|
|
expect(result).toBe('ISO time: 2024-04-29T16:34:56.000Z');
|
|
});
|
|
|
|
test('should replace {{current_user}} with the user name if provided', () => {
|
|
const result = replaceSpecialVars({
|
|
text: 'Hello {{current_user}}!',
|
|
user: mockUser,
|
|
});
|
|
expect(result).toBe('Hello Test User!');
|
|
});
|
|
|
|
test('should not replace {{current_user}} if user is not provided', () => {
|
|
const result = replaceSpecialVars({
|
|
text: 'Hello {{current_user}}!',
|
|
});
|
|
expect(result).toBe('Hello {{current_user}}!');
|
|
});
|
|
|
|
test('should not replace {{current_user}} if user has no name', () => {
|
|
const result = replaceSpecialVars({
|
|
text: 'Hello {{current_user}}!',
|
|
user: { id: 'user123' } as TUser,
|
|
});
|
|
expect(result).toBe('Hello {{current_user}}!');
|
|
});
|
|
|
|
test('should handle multiple replacements in the same text', () => {
|
|
const result = replaceSpecialVars({
|
|
text: 'Hello {{current_user}}! Today is {{current_date}} and the time is {{current_datetime}}. ISO: {{iso_datetime}}',
|
|
user: mockUser,
|
|
});
|
|
expect(result).toBe(
|
|
'Hello Test User! Today is 2024-04-29 (1) and the time is 2024-04-29 12:34:56 (1). ISO: 2024-04-29T16:34:56.000Z',
|
|
);
|
|
});
|
|
|
|
test('should be case-insensitive when replacing variables', () => {
|
|
const result = replaceSpecialVars({
|
|
text: 'Date: {{CURRENT_DATE}}, User: {{Current_User}}',
|
|
user: mockUser,
|
|
});
|
|
expect(result).toBe('Date: 2024-04-29 (1), User: Test User');
|
|
});
|
|
|
|
test('should confirm all specialVariables from config.ts get parsed', () => {
|
|
// Create a text that includes all special variables
|
|
const specialVarsText = Object.keys(specialVariables)
|
|
.map((key) => `{{${key}}}`)
|
|
.join(' ');
|
|
|
|
const result = replaceSpecialVars({
|
|
text: specialVarsText,
|
|
user: mockUser,
|
|
});
|
|
|
|
// Verify none of the original variable placeholders remain in the result
|
|
Object.keys(specialVariables).forEach((key) => {
|
|
const placeholder = `{{${key}}}`;
|
|
expect(result).not.toContain(placeholder);
|
|
});
|
|
|
|
// Verify the expected replacements
|
|
expect(result).toContain('2024-04-29 (1)'); // current_date
|
|
expect(result).toContain('2024-04-29 12:34:56 (1)'); // current_datetime
|
|
expect(result).toContain('2024-04-29T16:34:56.000Z'); // iso_datetime
|
|
expect(result).toContain('Test User'); // current_user
|
|
});
|
|
});
|