diff --git a/client/src/hooks/Files/__tests__/useFileHandling.test.ts b/client/src/hooks/Files/__tests__/useFileHandling.test.ts index eefb13dbc1..35590d2397 100644 --- a/client/src/hooks/Files/__tests__/useFileHandling.test.ts +++ b/client/src/hooks/Files/__tests__/useFileHandling.test.ts @@ -11,6 +11,7 @@ const mockSetFilesLoading = jest.fn(); const mockMutate = jest.fn(); let mockConversation: Record = {}; +let mockIsTemporary = false; jest.mock('~/Providers/ChatContext', () => ({ useChatContext: jest.fn(() => ({ @@ -30,7 +31,7 @@ jest.mock('@librechat/client', () => ({ jest.mock('recoil', () => ({ ...jest.requireActual('recoil'), useSetRecoilState: jest.fn(() => jest.fn()), - useRecoilValue: jest.fn(() => false), + useRecoilValue: jest.fn(() => mockIsTemporary), })); jest.mock('~/store', () => ({ @@ -102,6 +103,7 @@ describe('useFileHandling', () => { beforeEach(() => { jest.clearAllMocks(); mockConversation = {}; + mockIsTemporary = false; }); const loadHook = async () => (await import('../useFileHandling')).default; @@ -290,5 +292,73 @@ describe('useFileHandling', () => { expect(formData.get('endpoint')).toBe('default'); expect(formData.get('conversationId')).toBeNull(); }); + + it('sends temporary flag for temporary chat uploads', async () => { + mockIsTemporary = true; + mockConversation = { + conversationId: Constants.NEW_CONVO as string, + endpoint: 'openAI', + endpointType: 'custom', + }; + + const useFileHandling = await loadHook(); + const { result } = renderHook(() => useFileHandling()); + + const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' }); + + await act(async () => { + await result.current.handleFiles([textFile]); + }); + + expect(mockMutate).toHaveBeenCalledTimes(1); + const formData: FormData = mockMutate.mock.calls[0][0]; + expect(formData.get('conversationId')).toBeNull(); + expect(formData.get('isTemporary')).toBe('true'); + }); + + it('does not send temporary flag for assistant builder uploads', async () => { + mockIsTemporary = true; + + const useFileHandling = await loadHook(); + const { result } = renderHook(() => + useFileHandling({ + additionalMetadata: { assistant_id: 'asst-123' }, + }), + ); + + const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' }); + + await act(async () => { + await result.current.handleFiles([textFile]); + }); + + expect(mockMutate).toHaveBeenCalledTimes(1); + const formData: FormData = mockMutate.mock.calls[0][0]; + expect(formData.get('assistant_id')).toBe('asst-123'); + expect(formData.get('isTemporary')).toBeNull(); + }); + + it('does not send temporary flag for agent builder uploads', async () => { + mockIsTemporary = true; + + const useFileHandling = await loadHook(); + const { result } = renderHook(() => + useFileHandling({ + endpointOverride: EModelEndpoint.agents, + additionalMetadata: { agent_id: 'agent-123' }, + }), + ); + + const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' }); + + await act(async () => { + await result.current.handleFiles([textFile]); + }); + + expect(mockMutate).toHaveBeenCalledTimes(1); + const formData: FormData = mockMutate.mock.calls[0][0]; + expect(formData.get('agent_id')).toBe('agent-123'); + expect(formData.get('isTemporary')).toBeNull(); + }); }); }); diff --git a/client/src/hooks/Files/useFileHandling.ts b/client/src/hooks/Files/useFileHandling.ts index c511a8136d..5d6eb97c9b 100644 --- a/client/src/hooks/Files/useFileHandling.ts +++ b/client/src/hooks/Files/useFileHandling.ts @@ -66,6 +66,7 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil const agent_id = params?.additionalMetadata?.agent_id ?? ''; const assistant_id = params?.additionalMetadata?.assistant_id ?? ''; + const isConversationUpload = !agent_id && !assistant_id; const endpointOverride = params?.endpointOverride; const endpointTypeOverride = params?.endpointTypeOverride; const endpointType = useMemo( @@ -196,7 +197,7 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil if (conversation?.conversationId && conversation.conversationId !== Constants.NEW_CONVO) { formData.append('conversationId', conversation.conversationId); } - if (isTemporary) { + if (isTemporary && isConversationUpload) { formData.append('isTemporary', 'true'); }