Skip to content

Commit 0209955

Browse files
authored
✨ v0.7.5-rc2 (#3976)
* ✨ v0.7.5-rc2 * docs: update README * refactor(settings): Update rememberForkOption default value * a11y: proper screen reader announcements for content blocks * Update version to 0.7.423 in package-lock.json and packages/data-provider/package.json * chore: rename rememberForkOption -> rememberDefaultFork to apply new default value * fix: headlessui menu stealing focus from Settings Dialog when pressing Enter
1 parent d6c0121 commit 0209955

23 files changed

+92
-43
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# v0.7.5-rc1
1+
# v0.7.5-rc2
22

33
# Base node image
44
FROM node:20-alpine AS node

Dockerfile.multi

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Dockerfile.multi
2-
# v0.7.5-rc1
2+
# v0.7.5-rc2
33

44
# Base for all builds
55
FROM node:20-alpine AS base

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242

4343
- 🖥️ UI matching ChatGPT, including Dark mode, Streaming, and latest updates
4444
- 🤖 AI model selection:
45-
- OpenAI, Azure OpenAI, BingAI, ChatGPT, Google Vertex AI, Anthropic (Claude), Plugins, Assistants API (including Azure Assistants)
45+
- Anthropic (Claude), AWS Bedrock, OpenAI, Azure OpenAI, BingAI, ChatGPT, Google Vertex AI, Plugins, Assistants API (including Azure Assistants)
4646
- ✅ Compatible across both **[Remote & Local AI services](https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints):**
4747
- groq, Ollama, Cohere, Mistral AI, Apple MLX, koboldcpp, OpenRouter, together.ai, Perplexity, ShuttleAI, and more
48-
- 🪄 Generative UI with [Code Artifacts](https://youtu.be/GfTj7O4gmd0?si=WJbdnemZpJzBrJo3)
48+
- 🪄 Generative UI with **[Code Artifacts](https://youtu.be/GfTj7O4gmd0?si=WJbdnemZpJzBrJo3)**
4949
- Create React, HTML code, and Mermaid diagrams right in chat
5050
- 💾 Create, Save, & Share Custom Presets
5151
- 🔀 Switch between AI Endpoints and Presets, mid-chat

api/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@librechat/backend",
3-
"version": "v0.7.5-rc1",
3+
"version": "v0.7.5-rc2",
44
"description": "",
55
"scripts": {
66
"start": "echo 'please run this from the root directory'",

client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@librechat/frontend",
3-
"version": "v0.7.5-rc1",
3+
"version": "v0.7.5-rc2",
44
"description": "",
55
"type": "module",
66
"scripts": {

client/src/Providers/AnnouncerContext.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
// AnnouncerContext.tsx
22
import React from 'react';
3-
4-
export interface AnnounceOptions {
5-
message: string;
6-
isStatus?: boolean;
7-
}
3+
import type { AnnounceOptions } from '~/common';
84

95
interface AnnouncerContextType {
106
announceAssertive: (options: AnnounceOptions) => void;

client/src/common/a11y.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface AnnounceOptions {
2+
message: string;
3+
isStatus?: boolean;
4+
}
5+
6+
export const MESSAGE_UPDATE_INTERVAL = 7000;

client/src/common/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './a11y';
12
export * from './artifacts';
23
export * from './types';
34
export * from './assistants-types';

client/src/components/Conversations/Fork.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export default function Fork({
116116
const [forkSetting, setForkSetting] = useRecoilState(store.forkSetting);
117117
const [activeSetting, setActiveSetting] = useState(optionLabels.default);
118118
const [splitAtTarget, setSplitAtTarget] = useRecoilState(store.splitAtTarget);
119-
const [rememberGlobal, setRememberGlobal] = useRecoilState(store.rememberForkOption);
119+
const [rememberGlobal, setRememberGlobal] = useRecoilState(store.rememberDefaultFork);
120120
const forkConvo = useForkConvoMutation({
121121
onSuccess: (data) => {
122122
if (data) {

client/src/components/Nav/AccountSettings.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ function AccountSettings() {
120120
className={focus ? 'bg-surface-hover' : ''}
121121
svg={() => <GearIcon className="icon-md" />}
122122
text={localize('com_nav_settings')}
123-
clickHandler={() => setShowSettings(true)}
123+
clickHandler={() => {
124+
setTimeout(() => setShowSettings(true), 50);
125+
}}
124126
/>
125127
)}
126128
</MenuItem>

client/src/components/Nav/NavLink.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { FC, forwardRef } from 'react';
1+
import React, { FC, forwardRef } from 'react';
22
import { cn } from '~/utils/';
33

44
interface Props {
55
svg: () => JSX.Element;
66
text: string;
7-
clickHandler?: () => void;
7+
clickHandler?: React.MouseEventHandler<HTMLButtonElement>;
88
className?: string;
99
disabled?: boolean;
1010
}
@@ -13,7 +13,7 @@ const NavLink: FC<Props> = forwardRef<HTMLButtonElement, Props>((props, ref) =>
1313
const { svg, text, clickHandler, disabled, className = '' } = props;
1414
const defaultProps: {
1515
className: string;
16-
onClick?: () => void;
16+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
1717
} = {
1818
className: cn(
1919
'w-full flex gap-2 rounded p-2.5 text-sm cursor-pointer group items-center transition-colors duration-200 text-text-primary hover:bg-surface-hover',

client/src/components/Nav/SettingsTabs/Chat/ForkSettings.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const ForkSettings = () => {
99
const localize = useLocalize();
1010
const [forkSetting, setForkSetting] = useRecoilState(store.forkSetting);
1111
const [splitAtTarget, setSplitAtTarget] = useRecoilState(store.splitAtTarget);
12-
const [remember, setRemember] = useRecoilState<boolean>(store.rememberForkOption);
12+
const [remember, setRemember] = useRecoilState<boolean>(store.rememberDefaultFork);
1313

1414
const forkOptions = [
1515
{ value: ForkOptions.DIRECT_PATH, label: localize('com_ui_fork_visible') },
@@ -39,11 +39,11 @@ export const ForkSettings = () => {
3939
<div className="flex items-center justify-between">
4040
<div> {localize('com_ui_fork_default')} </div>
4141
<Switch
42-
id="rememberForkOption"
42+
id="rememberDefaultFork"
4343
checked={remember}
4444
onCheckedChange={setRemember}
4545
className="ml-4 mt-2"
46-
data-testid="rememberForkOption"
46+
data-testid="rememberDefaultFork"
4747
/>
4848
</div>
4949
</div>

client/src/hooks/SSE/useEventHandlers.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ import type { TGenTitleMutation } from '~/data-provider';
2323
import {
2424
scrollToEnd,
2525
addConversation,
26+
getAllContentText,
2627
deleteConversation,
2728
updateConversation,
2829
getConversationById,
2930
} from '~/utils';
3031
import useContentHandler from '~/hooks/SSE/useContentHandler';
3132
import useStepHandler from '~/hooks/SSE/useStepHandler';
3233
import { useAuthContext } from '~/hooks/AuthContext';
34+
import { MESSAGE_UPDATE_INTERVAL } from '~/common';
3335
import { useLiveAnnouncer } from '~/Providers';
3436
import store from '~/store';
3537

@@ -55,8 +57,6 @@ export type EventHandlerParams = {
5557
resetLatestMessage?: Resetter;
5658
};
5759

58-
const MESSAGE_UPDATE_INTERVAL = 7000;
59-
6060
export default function useEventHandlers({
6161
genTitle,
6262
setMessages,
@@ -78,7 +78,13 @@ export default function useEventHandlers({
7878
const { token } = useAuthContext();
7979

8080
const contentHandler = useContentHandler({ setMessages, getMessages });
81-
const stepHandler = useStepHandler({ setMessages, getMessages });
81+
const stepHandler = useStepHandler({
82+
setMessages,
83+
getMessages,
84+
announcePolite,
85+
setIsSubmitting,
86+
lastAnnouncementTimeRef,
87+
});
8288

8389
const messageHandler = useCallback(
8490
(data: string | undefined, submission: EventSubmission) => {
@@ -356,7 +362,7 @@ export default function useEventHandlers({
356362
});
357363

358364
announcePolite({
359-
message: responseMessage?.text ?? '',
365+
message: getAllContentText(responseMessage),
360366
});
361367

362368
/* Update messages; if assistants endpoint, client doesn't receive responseMessage */

client/src/hooks/SSE/useStepHandler.ts

+24-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import { useCallback, useRef } from 'react';
2-
import { StepTypes, ContentTypes, ToolCallTypes } from 'librechat-data-provider';
2+
import { StepTypes, ContentTypes, ToolCallTypes, getNonEmptyValue } from 'librechat-data-provider';
33
import type {
44
Agents,
5-
PartMetadata,
65
TMessage,
7-
TMessageContentParts,
6+
PartMetadata,
87
EventSubmission,
8+
TMessageContentParts,
99
} from 'librechat-data-provider';
10-
import { getNonEmptyValue } from 'librechat-data-provider';
10+
import type { SetterOrUpdater } from 'recoil';
11+
import type { AnnounceOptions } from '~/common';
12+
import { MESSAGE_UPDATE_INTERVAL } from '~/common';
1113

1214
type TUseStepHandler = {
15+
announcePolite: (options: AnnounceOptions) => void;
1316
setMessages: (messages: TMessage[]) => void;
1417
getMessages: () => TMessage[] | undefined;
18+
setIsSubmitting: SetterOrUpdater<boolean>;
19+
lastAnnouncementTimeRef: React.MutableRefObject<number>;
1520
};
1621

1722
type TStepEvent = {
@@ -28,7 +33,13 @@ type AllContentTypes =
2833
| ContentTypes.IMAGE_URL
2934
| ContentTypes.ERROR;
3035

31-
export default function useStepHandler({ setMessages, getMessages }: TUseStepHandler) {
36+
export default function useStepHandler({
37+
setMessages,
38+
getMessages,
39+
setIsSubmitting,
40+
announcePolite,
41+
lastAnnouncementTimeRef,
42+
}: TUseStepHandler) {
3243
const toolCallIdMap = useRef(new Map<string, string | undefined>());
3344
const messageMap = useRef(new Map<string, TMessage>());
3445
const stepMap = useRef(new Map<string, Agents.RunStep>());
@@ -112,6 +123,13 @@ export default function useStepHandler({ setMessages, getMessages }: TUseStepHan
112123
({ event, data }: TStepEvent, submission: EventSubmission) => {
113124
const messages = getMessages() || [];
114125
const { userMessage } = submission;
126+
setIsSubmitting(true);
127+
128+
const currentTime = Date.now();
129+
if (currentTime - lastAnnouncementTimeRef.current > MESSAGE_UPDATE_INTERVAL) {
130+
announcePolite({ message: 'composing', isStatus: true });
131+
lastAnnouncementTimeRef.current = currentTime;
132+
}
115133

116134
if (event === 'on_run_step') {
117135
const runStep = data as Agents.RunStep;
@@ -249,6 +267,6 @@ export default function useStepHandler({ setMessages, getMessages }: TUseStepHan
249267
stepMap.current.clear();
250268
};
251269
},
252-
[getMessages, stepMap, messageMap, setMessages, toolCallIdMap],
270+
[getMessages, setIsSubmitting, lastAnnouncementTimeRef, announcePolite, setMessages],
253271
);
254272
}

client/src/store/settings.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { atom } from 'recoil';
2-
import { SettingsViews } from 'librechat-data-provider';
2+
import { SettingsViews, LocalStorageKeys } from 'librechat-data-provider';
33
import { atomWithLocalStorage } from '~/store/utils';
44
import type { TOptionSettings } from '~/common';
55

@@ -32,7 +32,7 @@ const localStorageAtoms = {
3232
forkSetting: atomWithLocalStorage('forkSetting', ''),
3333
splitAtTarget: atomWithLocalStorage('splitAtTarget', false),
3434

35-
rememberForkOption: atomWithLocalStorage('rememberForkOption', true),
35+
rememberDefaultFork: atomWithLocalStorage(LocalStorageKeys.REMEMBER_FORK_OPTION, false),
3636

3737
// Beta features settings
3838
modularChat: atomWithLocalStorage('modularChat', true),

client/src/utils/messages.ts

+20
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ export const getLatestText = (message?: TMessage | null, includeIndex?: boolean)
4040
return '';
4141
};
4242

43+
export const getAllContentText = (message?: TMessage | null): string => {
44+
if (!message) {
45+
return '';
46+
}
47+
48+
if (message.text) {
49+
return message.text;
50+
}
51+
52+
if (message.content && message.content.length > 0) {
53+
return message.content
54+
.filter((part) => part.type === ContentTypes.TEXT)
55+
.map((part) => (typeof part.text === 'string' ? part.text : part.text.value) ?? '')
56+
.filter((text) => text.length > 0)
57+
.join('\n');
58+
}
59+
60+
return '';
61+
};
62+
4363
export const getTextKey = (message?: TMessage | null, convoId?: string | null) => {
4464
if (!message) {
4565
return '';

e2e/jestSetup.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
// v0.7.5-rc1
1+
// v0.7.5-rc2
22
// See .env.test.example for an example of the '.env.test' file.
33
require('dotenv').config({ path: './e2e/.env.test' });

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- v0.7.5-rc1 -->
1+
<!-- v0.7.5-rc2 -->
22
<!DOCTYPE html>
33
<html>
44
<head>

package-lock.json

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "LibreChat",
3-
"version": "v0.7.5-rc1",
3+
"version": "v0.7.5-rc2",
44
"description": "",
55
"workspaces": [
66
"api",

packages/data-provider/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "librechat-data-provider",
3-
"version": "0.7.422",
3+
"version": "0.7.423",
44
"description": "data services for librechat apps",
55
"main": "dist/index.js",
66
"module": "dist/index.es.js",

packages/data-provider/src/config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ export enum TTSProviders {
10601060
/** Enum for app-wide constants */
10611061
export enum Constants {
10621062
/** Key for the app's version. */
1063-
VERSION = 'v0.7.5-rc1',
1063+
VERSION = 'v0.7.5-rc2',
10641064
/** Key for the Custom Config's version (librechat.yaml). */
10651065
CONFIG_VERSION = '1.1.7',
10661066
/** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
@@ -1107,7 +1107,7 @@ export enum LocalStorageKeys {
11071107
/** Key for the last selected fork setting */
11081108
FORK_SETTING = 'forkSetting',
11091109
/** Key for remembering the last selected option, instead of manually selecting */
1110-
REMEMBER_FORK_OPTION = 'rememberForkOption',
1110+
REMEMBER_FORK_OPTION = 'rememberDefaultFork',
11111111
/** Key for remembering the split at target fork option modifier */
11121112
FORK_SPLIT_AT_TARGET = 'splitAtTarget',
11131113
/** Key for saving text drafts */

prettier.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// v0.7.5-rc1
1+
// v0.7.5-rc2
22
module.exports = {
33
tailwindConfig: './client/tailwind.config.cjs',
44
printWidth: 100,

0 commit comments

Comments
 (0)