mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-16 04:36:34 +01:00
⚡ refactor: Optimize Message Re-renders (#12097)
* 🔄 refactor: Update Artifacts and Messages Contexts to Use Latest Message ID and Depth
- Modified ArtifactsContext to retrieve latestMessage using Recoil state management.
- Updated MessagesViewContext to replace latestMessage with latestMessageId and latestMessageDepth for improved clarity and consistency.
- Adjusted various components (HoverButtons, MessageParts, MessageRender, ContentRender) to utilize latestMessageId instead of the entire message object, enhancing performance and reducing unnecessary re-renders.
- Refactored useChatHelpers to extract latestMessageId and latestMessageDepth, streamlining message handling across the application.
* refactor: Introduce PartWithContext Component for Optimized Message Rendering
- Added a new PartWithContext component to encapsulate message part rendering logic, improving context management and reducing redundancy in the ContentParts component.
- Updated MessageRender to utilize the new PartWithContext, streamlining the context provider setup and enhancing code clarity.
- Refactored related logic to ensure proper context values are passed, improving maintainability and performance in message rendering.
* refactor: Update Components to Use Function Declarations and Improve Readability
- Refactored several components (MessageContainer, Markdown, MarkdownCode, MarkdownCodeNoExecution, MarkdownAnchor, MarkdownParagraph, MarkdownImage, TextPart, PlaceholderRow) to use function declarations instead of arrow functions, enhancing readability and consistency across the codebase.
- Added display names to memoized components for better debugging and profiling in React DevTools.
- Improved overall code clarity and maintainability by standardizing component definitions.
* refactor: Standardize MessageRender and ContentRender Components for Improved Clarity
- Refactored MessageRender and ContentRender components to use function declarations, enhancing readability and consistency.
- Streamlined props handling by removing unnecessary parameters and improving the use of hooks for state management.
- Updated memoization and rendering logic to optimize performance and reduce unnecessary re-renders.
- Enhanced overall code clarity and maintainability by standardizing component definitions and structure.
* refactor: Enhance Header Component with Memoization for Performance
- Refactored the Header component to utilize React's memoization by wrapping it with the memo function, improving rendering performance by preventing unnecessary re-renders.
- Changed the export to a memoized version of the Header component, ensuring better debugging with a display name.
- Maintained overall code clarity and consistency in component structure.
* refactor: Transition Components to Use Recoil for State Management
- Updated multiple components (AddMultiConvo, TemporaryChat, HeaderNewChat, PresetsMenu, ModelSelectorChatContext) to utilize Recoil for state management, enhancing consistency and performance.
- Replaced useChatContext with Recoil selectors and atoms, improving data flow and reducing unnecessary re-renders.
- Introduced new selectors for conversation ID and endpoint retrieval, streamlining component logic and enhancing maintainability.
- Improved overall code clarity by standardizing state management practices across components.
* refactor: Integrate getConversation Callback for Enhanced State Management
- Updated multiple components (Mention, ModelSelectorChatContext, ModelSelectorContext, FavoritesList) to utilize a getConversation callback instead of directly accessing conversation state, improving encapsulation and maintainability.
- Refactored useSelectMention hook to accept getConversation, streamlining conversation retrieval and enhancing code clarity.
- Introduced new Recoil selectors for conversation properties, ensuring consistent state management across components.
- Enhanced overall code structure by standardizing the approach to conversation handling, reducing redundancy and improving performance.
* refactor: Optimize LiveAnnouncer Context Value with useMemo
- Updated the LiveAnnouncer component to utilize useMemo for context value creation, enhancing performance by preventing unnecessary recalculations of the context object.
- Improved overall code clarity and maintainability by ensuring that context values are only recomputed when their dependencies change.
* refactor: Update AgentPanelSwitch to Use Recoil for Agent ID Management
- Refactored AgentPanelSwitch component to utilize Recoil for retrieving the current agent ID, replacing the previous use of chat context.
- Improved state management by ensuring the agent ID is derived from Recoil, enhancing code clarity and maintainability.
- Adjusted useEffect dependencies to reflect the new state management approach, streamlining the component's logic.
* refactor: Enhance useLocalize Hook with useCallback for Improved Performance
- Updated the useLocalize hook to utilize useCallback for the translation function, optimizing performance by preventing unnecessary re-creations of the function on each render.
- Improved code clarity by ensuring that the translation function is memoized, enhancing maintainability and efficiency in localization handling.
* refactor: Rename useCreateConversationAtom to useSetConversationAtom for Clarity
- Updated the hook name from useCreateConversationAtom to useSetConversationAtom to better reflect its functionality in managing conversation state.
- Introduced a new implementation for setting conversation state, enhancing clarity and maintainability in the codebase.
- Adjusted related references in the useNewConvo hook to align with the new naming convention.
* refactor: Enhance useKeyDialog Hook with useMemo and useCallback for Improved Performance
- Updated the useKeyDialog hook to utilize useMemo for returning the dialog state and handlers, optimizing performance by preventing unnecessary recalculations.
- Refactored the onOpenChange function to use useCallback, ensuring it only changes when its dependencies do, enhancing maintainability and clarity in the code.
- Improved overall code structure and readability by streamlining the hook's logic and dependencies.
* feat: Add useRenderChangeLog Hook for Debugging Render Changes
- Introduced a new hook, useRenderChangeLog, that logs changes in tracked values between renders when a debug flag is enabled.
- Utilizes useEffect and useRef to track previous values and identify changes, enhancing debugging capabilities for component renders.
- Provides detailed console output for initial renders and value changes, improving developer insights during the rendering process.
* refactor: Update useSelectAgent Hook for Improved State Management and Performance
- Refactored the useSelectAgent hook to utilize useRecoilCallback for fetching conversation data, enhancing state management and performance.
- Replaced the use of useChatContext with a more efficient approach, streamlining the logic for selecting agents and updating conversations.
- Improved error handling and ensured asynchronous operations are properly awaited, enhancing reliability in agent selection and data fetching processes.
* refactor: Optimize useDefaultConvo Hook with useCallback for Improved Performance
- Refactored the getDefaultConversation function within the useDefaultConvo hook to utilize useCallback, enhancing performance by memoizing the function and preventing unnecessary re-creations on re-renders.
- Streamlined the logic for cleaning input and output in the conversation object, improving code clarity and maintainability.
- Ensured that dependencies for useCallback are correctly set, enhancing the reliability of the hook's behavior.
* refactor: Optimize Agent Components with Memoization for Improved Performance
- Refactored multiple agent-related components (AgentAvatar, AgentCategorySelector, AgentSelect, DeleteButton, FileContext, FileSearch, Files) to utilize React.memo for memoization, enhancing rendering performance by preventing unnecessary re-renders.
- Updated the FileRow component to make setFilesLoading optional, improving flexibility in file handling.
- Streamlined component logic and improved maintainability by ensuring that props are compared efficiently in memoized components.
* refactor: Enhance File Handling and Agent Components for Improved Performance
- Refactored multiple components (DeleteButton, FileContext, FileSearch, Files) to utilize new file handling hooks that separate chat context from file operations, improving performance and maintainability.
- Introduced useFileHandlingNoChatContext and useSharePointFileHandlingNoChatContext hooks to streamline file handling logic, enhancing flexibility in managing file states.
- Updated DeleteButton to improve conversation state management and ensure proper handling of agent deletions, enhancing user experience.
- Optimized imports and component structure for better clarity and organization across the affected files.
* refactor: Enhance useRenderChangeLog Hook with Improved Type Safety and Documentation
- Updated the useRenderChangeLog hook to improve type safety by specifying the value types as string, number, boolean, null, or undefined.
- Enhanced documentation to clarify usage and enablement of the debug feature, ensuring better developer insights during rendering.
- Added a production check to prevent logging in production builds, optimizing performance and maintaining clean console output.
* chore: imports
* refactor: Replace useRecoilCallback with useGetConversation Hook for Improved Clarity and Performance
- Refactored multiple components (AddMultiConvo, ModelSelectorChatContext, FavoritesList, useSelectAgent, usePresets) to utilize the new useGetConversation hook, enhancing clarity and reducing complexity by eliminating the use of useRecoilCallback.
- Streamlined conversation retrieval logic across components, improving maintainability and performance.
- Updated imports and component structure for better organization and readability.
* refactor: Enhance Memoization in DeleteButton Component for Improved Performance
- Updated the memoization logic in the DeleteButton component to include a comparison for the setCurrentAgentId prop, ensuring more efficient re-renders.
- This change improves performance by preventing unnecessary updates when the agent ID and current agent ID remain unchanged.
* chore: fix test
* refactor: Improve Memoization Logic in AgentSelect Component
- Updated the memoization comparison in the AgentSelect component to directly compare agentQuery.data objects, enhancing performance by ensuring accurate re-renders.
- Refactored the useCreateConversationAtom function to streamline the logic for updating conversation keys, improving clarity and maintainability.
* refactor: Simplify State Management in DeleteButton Component
- Removed unnecessary setConversationOption function, streamlining the logic for updating conversation state after agent deletion.
- Updated the conversation state directly within the deleteAgent mutation, improving clarity and maintainability of the component.
- Refactored conversationByKeySelector to directly reference conversationByIndex, enhancing performance and reducing complexity in state retrieval.
* refactor: Remove Unused Conversation Prop from Mention Component
- Eliminated the conversation prop from the Mention component, simplifying its interface and reducing unnecessary dependencies.
- Updated the ChatForm component to reflect this change, enhancing clarity and maintainability of the codebase.
- Introduced useGetConversation hook for improved conversation retrieval logic, streamlining the component's functionality.
* refactor: Simplify File Handling State Management Across Components
- Removed the unused setFilesLoading function from FileContext, FileSearch, and Files components, streamlining the file handling state management.
- Updated the FileHandlingState type to make setFilesLoading optional, enhancing flexibility in file operations.
- Improved memoization logic by directly referencing necessary state properties, ensuring better performance and maintainability.
* refactor: Update ArtifactsContext for Improved State Management
- Replaced the useChatContext hook with direct Recoil state retrieval for isSubmitting, latestMessage, and conversationId, simplifying the context provider's logic.
- Enhanced memoization by ensuring relevant state properties are directly referenced, improving performance and maintainability.
- Streamlined the context value creation to reflect the updated state management approach.
* refactor: Adjust Memoization Logic in ArtifactsContext for Consistency
- Updated the memoization logic in the ArtifactsProvider to ensure the messageId is consistently referenced, improving clarity and maintainability.
- This change enhances the performance of the context provider by ensuring all relevant properties are included in the memoization dependencies.
This commit is contained in:
parent
c324a8d9e4
commit
5209f1dc9e
56 changed files with 1578 additions and 1085 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useCallback } from 'react';
|
||||
import { memo, useCallback, useEffect } from 'react';
|
||||
import { useToastContext } from '@librechat/client';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
import { mergeFileConfig, fileConfig as defaultFileConfig } from 'librechat-data-provider';
|
||||
|
|
@ -99,4 +99,10 @@ function Avatar({ avatar }: { avatar: AgentAvatar | null }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default Avatar;
|
||||
const MemoizedAvatar = memo(
|
||||
Avatar,
|
||||
(prevProps, nextProps) => prevProps.avatar?.filepath === nextProps.avatar?.filepath,
|
||||
);
|
||||
MemoizedAvatar.displayName = 'Avatar';
|
||||
|
||||
export default MemoizedAvatar;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { memo, useState } from 'react';
|
||||
import { ControlCombobox } from '@librechat/client';
|
||||
import {
|
||||
useWatch,
|
||||
|
|
@ -95,4 +95,10 @@ const AgentCategorySelector: React.FC<{ className?: string }> = ({ className })
|
|||
);
|
||||
};
|
||||
|
||||
export default AgentCategorySelector;
|
||||
const MemoizedAgentCategorySelector = memo(
|
||||
AgentCategorySelector,
|
||||
(prevProps, nextProps) => prevProps.className === nextProps.className,
|
||||
);
|
||||
MemoizedAgentCategorySelector.displayName = 'AgentCategorySelector';
|
||||
|
||||
export default MemoizedAgentCategorySelector;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { AgentPanelProvider, useAgentPanelContext } from '~/Providers/AgentPanelContext';
|
||||
import { Panel, isEphemeralAgent } from '~/common';
|
||||
import VersionPanel from './Version/VersionPanel';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import ActionsPanel from './ActionsPanel';
|
||||
import AgentPanel from './AgentPanel';
|
||||
import store from '~/store';
|
||||
|
||||
export default function AgentPanelSwitch() {
|
||||
return (
|
||||
|
|
@ -15,15 +16,15 @@ export default function AgentPanelSwitch() {
|
|||
}
|
||||
|
||||
function AgentPanelSwitchWithContext() {
|
||||
const { conversation } = useChatContext();
|
||||
const { activePanel, setCurrentAgentId } = useAgentPanelContext();
|
||||
const agentId = useRecoilValue(store.conversationAgentIdByIndex(0));
|
||||
|
||||
useEffect(() => {
|
||||
const agent_id = conversation?.agent_id ?? '';
|
||||
const agent_id = agentId ?? '';
|
||||
if (!isEphemeralAgent(agent_id)) {
|
||||
setCurrentAgentId(agent_id);
|
||||
}
|
||||
}, [setCurrentAgentId, conversation?.agent_id]);
|
||||
}, [setCurrentAgentId, agentId]);
|
||||
|
||||
if (activePanel === Panel.actions) {
|
||||
return <ActionsPanel />;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EarthIcon } from 'lucide-react';
|
||||
import { ControlCombobox } from '@librechat/client';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
||||
import { useFormContext, Controller } from 'react-hook-form';
|
||||
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
|
||||
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
|
||||
|
|
@ -12,7 +12,7 @@ import { useListAgentsQuery } from '~/data-provider';
|
|||
|
||||
const keys = new Set(Object.keys(defaultAgentFormValues));
|
||||
|
||||
export default function AgentSelect({
|
||||
function AgentSelect({
|
||||
agentQuery,
|
||||
selectedAgentId = null,
|
||||
setCurrentAgentId,
|
||||
|
|
@ -225,3 +225,16 @@ export default function AgentSelect({
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const MemoizedAgentSelect = memo(
|
||||
AgentSelect,
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.selectedAgentId === nextProps.selectedAgentId &&
|
||||
prevProps.agentQuery.data === nextProps.agentQuery.data &&
|
||||
prevProps.agentQuery.isSuccess === nextProps.agentQuery.isSuccess &&
|
||||
prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
|
||||
prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
|
||||
);
|
||||
MemoizedAgentSelect.displayName = 'AgentSelect';
|
||||
|
||||
export default MemoizedAgentSelect;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useRef } from 'react';
|
||||
import { memo, useMemo, useRef, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { AttachmentIcon } from '@librechat/client';
|
||||
import {
|
||||
|
|
@ -9,15 +9,15 @@ import {
|
|||
getEndpointFileConfig,
|
||||
} from 'librechat-data-provider';
|
||||
import type { ExtendedFile, AgentForm } from '~/common';
|
||||
import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
|
||||
import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
|
||||
import FileRow from '~/components/Chat/Input/Files/FileRow';
|
||||
import { useLocalize, useLazyEffect } from '~/hooks';
|
||||
import { useGetFileConfig } from '~/data-provider';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import { isEphemeralAgent } from '~/common';
|
||||
|
||||
const tool_resource = EToolResources.execute_code;
|
||||
|
||||
export default function Files({
|
||||
function Files({
|
||||
agent_id,
|
||||
files: _files,
|
||||
}: {
|
||||
|
|
@ -25,18 +25,21 @@ export default function Files({
|
|||
files?: [string, ExtendedFile][];
|
||||
}) {
|
||||
const localize = useLocalize();
|
||||
const { setFilesLoading } = useChatContext();
|
||||
const { watch } = useFormContext<AgentForm>();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [files, setFiles] = useState<Map<string, ExtendedFile>>(new Map());
|
||||
const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
|
||||
const { data: fileConfig = null } = useGetFileConfig({
|
||||
select: (data) => mergeFileConfig(data),
|
||||
});
|
||||
const { abortUpload, handleFileChange } = useFileHandling({
|
||||
fileSetter: setFiles,
|
||||
additionalMetadata: { agent_id, tool_resource },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
});
|
||||
const { abortUpload, handleFileChange } = useFileHandlingNoChatContext(
|
||||
{
|
||||
fileSetter: setFiles,
|
||||
additionalMetadata: { agent_id, tool_resource },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
},
|
||||
fileHandlingState,
|
||||
);
|
||||
|
||||
useLazyEffect(
|
||||
() => {
|
||||
|
|
@ -81,7 +84,6 @@ export default function Files({
|
|||
agent_id={agent_id}
|
||||
abortUpload={abortUpload}
|
||||
tool_resource={tool_resource}
|
||||
setFilesLoading={setFilesLoading}
|
||||
Wrapper={({ children }) => <div className="flex flex-wrap gap-2">{children}</div>}
|
||||
/>
|
||||
<div>
|
||||
|
|
@ -110,3 +112,8 @@ export default function Files({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const MemoizedFiles = memo(Files);
|
||||
MemoizedFiles.displayName = 'Files';
|
||||
|
||||
export default MemoizedFiles;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { memo } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import {
|
||||
Label,
|
||||
Button,
|
||||
|
|
@ -11,12 +13,12 @@ import {
|
|||
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
|
||||
import type { UseMutationResult } from '@tanstack/react-query';
|
||||
import { logger, getDefaultAgentFormValues } from '~/utils';
|
||||
import { useLocalize, useSetIndexOptions } from '~/hooks';
|
||||
import { useDeleteAgentMutation } from '~/data-provider';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import { isEphemeralAgent } from '~/common';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import store from '~/store';
|
||||
|
||||
export default function DeleteButton({
|
||||
function DeleteButton({
|
||||
agent_id,
|
||||
setCurrentAgentId,
|
||||
createMutation,
|
||||
|
|
@ -28,8 +30,8 @@ export default function DeleteButton({
|
|||
const localize = useLocalize();
|
||||
const { reset } = useFormContext();
|
||||
const { showToast } = useToastContext();
|
||||
const { conversation } = useChatContext();
|
||||
const { setOption } = useSetIndexOptions();
|
||||
const setConversation = useSetRecoilState(store.conversationByIndex(0));
|
||||
const conversationAgentId = useRecoilValue(store.conversationAgentIdByIndex(0));
|
||||
|
||||
const deleteAgent = useDeleteAgentMutation({
|
||||
onSuccess: (_, vars, context) => {
|
||||
|
|
@ -52,15 +54,16 @@ export default function DeleteButton({
|
|||
if (!firstAgent) {
|
||||
setCurrentAgentId(undefined);
|
||||
reset(getDefaultAgentFormValues());
|
||||
return setOption('agent_id')('');
|
||||
setConversation((prev) => (prev ? { ...prev, agent_id: '' } : prev));
|
||||
return;
|
||||
}
|
||||
|
||||
if (vars.agent_id === conversation?.agent_id) {
|
||||
setOption('model')('');
|
||||
return setOption('agent_id')(firstAgent.id);
|
||||
if (vars.agent_id === conversationAgentId) {
|
||||
setConversation((prev) => (prev ? { ...prev, model: '', agent_id: firstAgent.id } : prev));
|
||||
return;
|
||||
}
|
||||
|
||||
const currentAgent = updatedList.find((agent) => agent.id === conversation?.agent_id);
|
||||
const currentAgent = updatedList.find((agent) => agent.id === conversationAgentId);
|
||||
|
||||
if (currentAgent) {
|
||||
setCurrentAgentId(currentAgent.id);
|
||||
|
|
@ -119,3 +122,15 @@ export default function DeleteButton({
|
|||
</OGDialog>
|
||||
);
|
||||
}
|
||||
|
||||
const MemoizedDeleteButton = memo(
|
||||
DeleteButton,
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.agent_id === nextProps.agent_id &&
|
||||
prevProps.setCurrentAgentId === nextProps.setCurrentAgentId &&
|
||||
prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
|
||||
prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
|
||||
);
|
||||
MemoizedDeleteButton.displayName = 'DeleteButton';
|
||||
|
||||
export default MemoizedDeleteButton;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useRef } from 'react';
|
||||
import { memo, useMemo, useRef, useState } from 'react';
|
||||
import { Folder } from 'lucide-react';
|
||||
import * as Ariakit from '@ariakit/react';
|
||||
import {
|
||||
|
|
@ -18,14 +18,15 @@ import {
|
|||
HoverCardTrigger,
|
||||
} from '@librechat/client';
|
||||
import type { ExtendedFile } from '~/common';
|
||||
import { useFileHandling, useLocalize, useLazyEffect, useSharePointFileHandling } from '~/hooks';
|
||||
import { useLocalize, useLazyEffect } from '~/hooks';
|
||||
import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
|
||||
import { SharePointPickerDialog } from '~/components/SharePoint';
|
||||
import FileRow from '~/components/Chat/Input/Files/FileRow';
|
||||
import { ESide, isEphemeralAgent } from '~/common';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
|
||||
import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
|
||||
|
||||
export default function FileContext({
|
||||
function FileContext({
|
||||
agent_id,
|
||||
files: _files,
|
||||
}: {
|
||||
|
|
@ -33,9 +34,9 @@ export default function FileContext({
|
|||
files?: [string, ExtendedFile][];
|
||||
}) {
|
||||
const localize = useLocalize();
|
||||
const { setFilesLoading } = useChatContext();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [files, setFiles] = useState<Map<string, ExtendedFile>>(new Map());
|
||||
const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
|
||||
const [isPopoverActive, setIsPopoverActive] = useState(false);
|
||||
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
|
||||
const { data: startupConfig } = useGetStartupConfig();
|
||||
|
|
@ -45,16 +46,23 @@ export default function FileContext({
|
|||
select: (data) => mergeFileConfig(data),
|
||||
});
|
||||
|
||||
const { handleFileChange } = useFileHandling({
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.context },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
});
|
||||
const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
});
|
||||
const { handleFileChange } = useFileHandlingNoChatContext(
|
||||
{
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.context },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
},
|
||||
fileHandlingState,
|
||||
);
|
||||
const { handleSharePointFiles, isProcessing, downloadProgress } =
|
||||
useSharePointFileHandlingNoChatContext(
|
||||
{
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
},
|
||||
fileHandlingState,
|
||||
);
|
||||
useLazyEffect(
|
||||
() => {
|
||||
if (_files) {
|
||||
|
|
@ -138,7 +146,6 @@ export default function FileContext({
|
|||
<FileRow
|
||||
files={files}
|
||||
setFiles={setFiles}
|
||||
setFilesLoading={setFilesLoading}
|
||||
agent_id={agent_id}
|
||||
tool_resource={EToolResources.context}
|
||||
Wrapper={({ children }) => <div className="flex flex-wrap gap-2">{children}</div>}
|
||||
|
|
@ -199,3 +206,8 @@ export default function FileContext({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const MemoizedFileContext = memo(FileContext);
|
||||
MemoizedFileContext.displayName = 'FileContext';
|
||||
|
||||
export default MemoizedFileContext;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useRef } from 'react';
|
||||
import { memo, useMemo, useRef, useState } from 'react';
|
||||
import { Folder } from 'lucide-react';
|
||||
import * as Ariakit from '@ariakit/react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
|
@ -11,16 +11,16 @@ import {
|
|||
getEndpointFileConfig,
|
||||
} from 'librechat-data-provider';
|
||||
import type { ExtendedFile, AgentForm } from '~/common';
|
||||
import useSharePointFileHandling from '~/hooks/Files/useSharePointFileHandling';
|
||||
import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
|
||||
import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
|
||||
import { useLocalize, useLazyEffect } from '~/hooks';
|
||||
import { SharePointPickerDialog } from '~/components/SharePoint';
|
||||
import FileRow from '~/components/Chat/Input/Files/FileRow';
|
||||
import FileSearchCheckbox from './FileSearchCheckbox';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import { isEphemeralAgent } from '~/common';
|
||||
import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
|
||||
import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
|
||||
|
||||
export default function FileSearch({
|
||||
function FileSearch({
|
||||
agent_id,
|
||||
files: _files,
|
||||
}: {
|
||||
|
|
@ -28,10 +28,10 @@ export default function FileSearch({
|
|||
files?: [string, ExtendedFile][];
|
||||
}) {
|
||||
const localize = useLocalize();
|
||||
const { setFilesLoading } = useChatContext();
|
||||
const { watch } = useFormContext<AgentForm>();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [files, setFiles] = useState<Map<string, ExtendedFile>>(new Map());
|
||||
const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
|
||||
const [isPopoverActive, setIsPopoverActive] = useState(false);
|
||||
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
|
||||
|
||||
|
|
@ -42,17 +42,24 @@ export default function FileSearch({
|
|||
select: (data) => mergeFileConfig(data),
|
||||
});
|
||||
|
||||
const { handleFileChange } = useFileHandling({
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
});
|
||||
const { handleFileChange } = useFileHandlingNoChatContext(
|
||||
{
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
},
|
||||
fileHandlingState,
|
||||
);
|
||||
|
||||
const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
});
|
||||
const { handleSharePointFiles, isProcessing, downloadProgress } =
|
||||
useSharePointFileHandlingNoChatContext(
|
||||
{
|
||||
additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
|
||||
endpointOverride: EModelEndpoint.agents,
|
||||
fileSetter: setFiles,
|
||||
},
|
||||
fileHandlingState,
|
||||
);
|
||||
|
||||
useLazyEffect(
|
||||
() => {
|
||||
|
|
@ -143,7 +150,6 @@ export default function FileSearch({
|
|||
<FileRow
|
||||
files={files}
|
||||
setFiles={setFiles}
|
||||
setFilesLoading={setFilesLoading}
|
||||
agent_id={agent_id}
|
||||
tool_resource={EToolResources.file_search}
|
||||
Wrapper={({ children }) => <div className="flex flex-wrap gap-2">{children}</div>}
|
||||
|
|
@ -203,3 +209,8 @@ export default function FileSearch({
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const MemoizedFileSearch = memo(FileSearch);
|
||||
MemoizedFileSearch.displayName = 'FileSearch';
|
||||
|
||||
export default MemoizedFileSearch;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue