mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-07 11:08:52 +01:00
🌿 feat: Fork Messages/Conversations (#2617)
* typedef for ImportBatchBuilder * feat: first pass, fork conversations * feat: fork - getMessagesUpToTargetLevel * fix: additional tests and fix getAllMessagesUpToParent * chore: arrow function return * refactor: fork 3 options * chore: remove unused genbuttons * chore: remove unused hover buttons code * feat: fork first pass * wip: fork remember setting * style: user icon * chore: move clear chats to data tab * WIP: fork UI options * feat: data-provider fork types/services/vars and use generic MutationOptions * refactor: use single param for fork option, use enum, fix mongo errors, use Date.now(), add records flag for testing, use endpoint from original convo and messages, pass originalConvo to finishConversation * feat: add fork mutation hook and consolidate type imports * refactor: use enum * feat: first pass, fork mutation * chore: add enum for target level fork option * chore: add enum for target level fork option * show toast when checking remember selection * feat: splitAtTarget * feat: split at target option * feat: navigate to new fork, show toasts, set result query data * feat: hover info for all fork options * refactor: add Messages settings tab * fix(Fork): remember text info * ci: test for single message and is target edge case * feat: additional tests for getAllMessagesUpToParent * ci: additional tests and cycle detection for getMessagesUpToTargetLevel * feat: circular dependency checks for getAllMessagesUpToParent * fix: getMessagesUpToTargetLevel circular dep. check * ci: more tests for getMessagesForConversation * style: hover text for checkbox fork items * refactor: add statefulness to conversation import
This commit is contained in:
parent
c8baceac76
commit
25fceb78b7
37 changed files with 1831 additions and 523 deletions
|
|
@ -1,86 +0,0 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import type { TMessage } from 'librechat-data-provider';
|
||||
import { useMediaQuery, useGenerationsByLatest } from '~/hooks';
|
||||
import Regenerate from '~/components/Input/Generations/Regenerate';
|
||||
import Continue from '~/components/Input/Generations/Continue';
|
||||
import Stop from '~/components/Input/Generations/Stop';
|
||||
import { useChatContext } from '~/Providers';
|
||||
import { cn } from '~/utils';
|
||||
|
||||
type GenerationButtonsProps = {
|
||||
endpoint: string;
|
||||
showPopover?: boolean;
|
||||
opacityClass?: string;
|
||||
};
|
||||
|
||||
export default function GenerationButtons({
|
||||
endpoint,
|
||||
showPopover = false,
|
||||
opacityClass = 'full-opacity',
|
||||
}: GenerationButtonsProps) {
|
||||
const {
|
||||
getMessages,
|
||||
isSubmitting,
|
||||
latestMessage,
|
||||
handleContinue,
|
||||
handleRegenerate,
|
||||
handleStopGenerating,
|
||||
} = useChatContext();
|
||||
const isSmallScreen = useMediaQuery('(max-width: 768px)');
|
||||
const { continueSupported, regenerateEnabled } = useGenerationsByLatest({
|
||||
endpoint,
|
||||
message: latestMessage as TMessage,
|
||||
isSubmitting,
|
||||
latestMessage,
|
||||
});
|
||||
|
||||
const [userStopped, setUserStopped] = useState(false);
|
||||
const messages = getMessages();
|
||||
|
||||
const handleStop = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setUserStopped(true);
|
||||
handleStopGenerating(e);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let timer: NodeJS.Timeout;
|
||||
|
||||
if (userStopped) {
|
||||
timer = setTimeout(() => {
|
||||
setUserStopped(false);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [userStopped]);
|
||||
|
||||
if (isSmallScreen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let button: React.ReactNode = null;
|
||||
|
||||
if (isSubmitting) {
|
||||
button = <Stop onClick={handleStop} />;
|
||||
} else if (userStopped || continueSupported) {
|
||||
button = <Continue onClick={handleContinue} />;
|
||||
} else if (messages && messages.length > 0 && regenerateEnabled) {
|
||||
button = <Regenerate onClick={handleRegenerate} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="absolute bottom-0 right-0 z-[62]">
|
||||
<div className="grow" />
|
||||
<div className="flex items-center md:items-end">
|
||||
<div
|
||||
className={cn('option-buttons', showPopover ? '' : opacityClass)}
|
||||
data-projection-id="173"
|
||||
>
|
||||
{button}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue