refactor: useResumableStreamToggle hook to manage resumable streams for legacy/assistants endpoints

- Introduced a new hook, useResumableStreamToggle, to automatically toggle resumable streams off for assistants endpoints and restore the previous value when switching away.
- Updated ChatView component to utilize the new hook, enhancing the handling of streaming behavior based on endpoint type.
- Refactored imports in ChatView for better organization.
This commit is contained in:
Danny Avila 2025-12-18 09:52:27 -05:00
parent 6aebccd20a
commit dc81abcc01
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
3 changed files with 54 additions and 1 deletions

View file

@ -7,7 +7,13 @@ import { Constants, buildTree } from 'librechat-data-provider';
import type { TMessage } from 'librechat-data-provider';
import type { ChatFormValues } from '~/common';
import { ChatContext, AddedChatContext, useFileMapContext, ChatFormProvider } from '~/Providers';
import { useChatHelpers, useAddedResponse, useAdaptiveSSE, useResumeOnLoad } from '~/hooks';
import {
useResumableStreamToggle,
useAddedResponse,
useResumeOnLoad,
useAdaptiveSSE,
useChatHelpers,
} from '~/hooks';
import ConversationStarters from './Input/ConversationStarters';
import { useGetMessagesByConvoId } from '~/data-provider';
import MessagesView from './Messages/MessagesView';
@ -50,6 +56,11 @@ function ChatView({ index = 0 }: { index?: number }) {
const chatHelpers = useChatHelpers(index, conversationId);
const addedChatHelpers = useAddedResponse({ rootIndex: index });
useResumableStreamToggle(
chatHelpers.conversation?.endpoint,
chatHelpers.conversation?.endpointType,
);
useAdaptiveSSE(rootSubmission, chatHelpers, false, index);
// Auto-resume if navigating back to conversation with active job

View file

@ -5,3 +5,4 @@ export { default as useResumeOnLoad } from './useResumeOnLoad';
export { default as useStepHandler } from './useStepHandler';
export { default as useContentHandler } from './useContentHandler';
export { default as useAttachmentHandler } from './useAttachmentHandler';
export { default as useResumableStreamToggle } from './useResumableStreamToggle';

View file

@ -0,0 +1,41 @@
import { useEffect, useRef } from 'react';
import { useRecoilState } from 'recoil';
import { isAssistantsEndpoint } from 'librechat-data-provider';
import type { EModelEndpoint } from 'librechat-data-provider';
import store from '~/store';
/**
* Automatically toggles resumable streams off for assistants endpoints
* and restores the previous value when switching away.
*
* Assistants endpoints have their own streaming mechanism and don't support resumable streams.
*/
export default function useResumableStreamToggle(
endpoint: EModelEndpoint | string | null | undefined,
endpointType?: EModelEndpoint | string | null,
) {
const [resumableStreams, setResumableStreams] = useRecoilState(store.resumableStreams);
const savedValueRef = useRef<boolean | null>(null);
const wasAssistantsRef = useRef(false);
useEffect(() => {
const actualEndpoint = endpointType ?? endpoint;
const isAssistants = isAssistantsEndpoint(actualEndpoint);
if (isAssistants && !wasAssistantsRef.current) {
// Switching TO assistants: save current value and disable
savedValueRef.current = resumableStreams;
if (resumableStreams) {
setResumableStreams(false);
}
wasAssistantsRef.current = true;
} else if (!isAssistants && wasAssistantsRef.current) {
// Switching AWAY from assistants: restore saved value
if (savedValueRef.current !== null) {
setResumableStreams(savedValueRef.current);
savedValueRef.current = null;
}
wasAssistantsRef.current = false;
}
}, [endpoint, endpointType, resumableStreams, setResumableStreams]);
}