mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
🗃️ feat: General File Support for OpenAI, Azure, Custom, Anthropic and Google (RAG) (#2143)
* refactor: re-purpose `resendImages` as `resendFiles` * refactor: re-purpose `resendImages` as `resendFiles` * feat: upload general files * feat: embed file during upload * feat: delete file embeddings on file deletion * chore(fileConfig): add epub+zip type * feat(encodeAndFormat): handle non-image files * feat(createContextHandlers): build context prompt from file attachments and successful RAG * fix: prevent non-temp files as well as embedded files to be deleted on new conversation * fix: remove temp_file_id on usage, prevent non-temp files as well as embedded files to be deleted on new conversation * fix: prevent non-temp files as well as embedded files to be deleted on new conversation * feat(OpenAI/Anthropic/Google): basic RAG support * fix: delete `resendFiles` only when true (Default) * refactor(RAG): update endpoints and pass JWT * fix(resendFiles): default values * fix(context/processFile): query unique ids only * feat: rag-api.yaml * feat: file upload improved ux for longer uploads * chore: await embed call and catch embedding errors * refactor: store augmentedPrompt in Client * refactor(processFileUpload): throw error if not assistant file upload * fix(useFileHandling): handle markdown empty mimetype issue * chore: necessary compose file changes
This commit is contained in:
parent
af347cccde
commit
f7761df52c
38 changed files with 683 additions and 261 deletions
|
|
@ -2,6 +2,7 @@ import type { TFile } from 'librechat-data-provider';
|
|||
import type { ExtendedFile } from '~/common';
|
||||
import FileIcon from '~/components/svg/Files/FileIcon';
|
||||
import ProgressCircle from './ProgressCircle';
|
||||
import { useProgress } from '~/hooks';
|
||||
import { cn } from '~/utils';
|
||||
|
||||
const FilePreview = ({
|
||||
|
|
@ -19,7 +20,7 @@ const FilePreview = ({
|
|||
}) => {
|
||||
const radius = 55; // Radius of the SVG circle
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
const progress = file?.['progress'] ?? 1;
|
||||
const progress = useProgress(file?.['progress'] ?? 1, 0.001);
|
||||
|
||||
// Calculate the offset based on the loading progress
|
||||
const offset = circumference - progress * circumference;
|
||||
|
|
|
|||
|
|
@ -34,11 +34,12 @@ export default function Presentation({
|
|||
const filesToDelete = localStorage.getItem('filesToDelete');
|
||||
const map = JSON.parse(filesToDelete ?? '{}') as Record<string, ExtendedFile>;
|
||||
const files = Object.values(map)
|
||||
.filter((file) => file.filepath)
|
||||
.filter((file) => file.filepath && file.source && !file.embedded && file.temp_file_id)
|
||||
.map((file) => ({
|
||||
file_id: file.file_id,
|
||||
filepath: file.filepath as string,
|
||||
source: file.source as FileSources,
|
||||
embedded: !!file.embedded,
|
||||
}));
|
||||
|
||||
if (files.length === 0) {
|
||||
|
|
|
|||
|
|
@ -21,16 +21,8 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
if (!conversation) {
|
||||
return null;
|
||||
}
|
||||
const {
|
||||
model,
|
||||
modelLabel,
|
||||
promptPrefix,
|
||||
temperature,
|
||||
topP,
|
||||
topK,
|
||||
maxOutputTokens,
|
||||
resendImages,
|
||||
} = conversation;
|
||||
const { model, modelLabel, promptPrefix, temperature, topP, topK, maxOutputTokens, resendFiles } =
|
||||
conversation;
|
||||
|
||||
const setModel = setOption('model');
|
||||
const setModelLabel = setOption('modelLabel');
|
||||
|
|
@ -39,7 +31,7 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
const setTopP = setOption('topP');
|
||||
const setTopK = setOption('topK');
|
||||
const setMaxOutputTokens = setOption('maxOutputTokens');
|
||||
const setResendImages = setOption('resendImages');
|
||||
const setResendFiles = setOption('resendFiles');
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-5 gap-6">
|
||||
|
|
@ -257,13 +249,13 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
<HoverCard openDelay={500}>
|
||||
<HoverCardTrigger className="grid w-full">
|
||||
<div className="flex justify-between">
|
||||
<Label htmlFor="resend-images" className="text-left text-sm font-medium">
|
||||
{localize('com_endpoint_plug_resend_images')}{' '}
|
||||
<Label htmlFor="resend-files" className="text-left text-sm font-medium">
|
||||
{localize('com_endpoint_plug_resend_files')}{' '}
|
||||
</Label>
|
||||
<Switch
|
||||
id="resend-images"
|
||||
checked={resendImages ?? false}
|
||||
onCheckedChange={(checked: boolean) => setResendImages(checked)}
|
||||
id="resend-files"
|
||||
checked={resendFiles ?? true}
|
||||
onCheckedChange={(checked: boolean) => setResendFiles(checked)}
|
||||
disabled={readonly}
|
||||
className="flex"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
top_p: topP,
|
||||
frequency_penalty: freqP,
|
||||
presence_penalty: presP,
|
||||
resendImages,
|
||||
resendFiles,
|
||||
imageDetail,
|
||||
} = conversation ?? {};
|
||||
const [setChatGptLabel, chatGptLabelValue] = useDebouncedInput({
|
||||
|
|
@ -67,7 +67,7 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
}
|
||||
|
||||
const setModel = setOption('model');
|
||||
const setResendImages = setOption('resendImages');
|
||||
const setResendFiles = setOption('resendFiles');
|
||||
const setImageDetail = setOption('imageDetail');
|
||||
|
||||
const optionEndpoint = endpointType ?? endpoint;
|
||||
|
|
@ -283,10 +283,10 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
<div className="w-full">
|
||||
<div className="mb-2 flex w-full justify-between gap-2">
|
||||
<label
|
||||
htmlFor="resend-images"
|
||||
htmlFor="resend-files"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50"
|
||||
>
|
||||
<small>{localize('com_endpoint_plug_resend_images')}</small>
|
||||
<small>{localize('com_endpoint_plug_resend_files')}</small>
|
||||
</label>
|
||||
<label
|
||||
htmlFor="image-detail-value"
|
||||
|
|
@ -310,9 +310,9 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
|||
<HoverCard openDelay={500}>
|
||||
<HoverCardTrigger>
|
||||
<Switch
|
||||
id="resend-images"
|
||||
checked={resendImages ?? false}
|
||||
onCheckedChange={(checked: boolean) => setResendImages(checked)}
|
||||
id="resend-files"
|
||||
checked={resendFiles ?? true}
|
||||
onCheckedChange={(checked: boolean) => setResendFiles(checked)}
|
||||
disabled={readonly}
|
||||
className="flex"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const openAI = {
|
|||
topp: 'com_endpoint_openai_topp',
|
||||
freq: 'com_endpoint_openai_freq',
|
||||
pres: 'com_endpoint_openai_pres',
|
||||
resend: 'com_endpoint_openai_resend',
|
||||
resend: 'com_endpoint_openai_resend_files',
|
||||
detail: 'com_endpoint_openai_detail',
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue