feat: pull up the cost hooks into chatView to reduce api calls

This commit is contained in:
Dustin Healy 2025-08-21 02:15:33 -07:00
parent 3b1c07ff46
commit a820d79bfc
8 changed files with 57 additions and 32 deletions

View file

@ -51,9 +51,12 @@ function ChatView({ index = 0 }: { index?: number }) {
enabled: !!fileMap,
});
const { data: conversationCosts } = useGetConversationCosts(conversationId ?? '', {
enabled: !!conversationId && conversationId !== Constants.NEW_CONVO,
});
const { data: conversationCosts } = useGetConversationCosts(
conversationId && conversationId !== Constants.NEW_CONVO ? conversationId : '',
{
enabled: !!conversationId && conversationId !== Constants.NEW_CONVO && conversationId !== '',
},
);
const chatHelpers = useChatHelpers(index, conversationId);
const addedChatHelpers = useAddedResponse({ rootIndex: index });
@ -168,6 +171,7 @@ function ChatView({ index = 0 }: { index?: number }) {
</div>
)
}
costs={conversationCosts}
/>
);
} else {

View file

@ -1,6 +1,7 @@
import React from 'react';
import { useRecoilValue } from 'recoil';
import { useMessageProcess } from '~/hooks';
import type { TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps } from '~/common';
import MessageRender from './ui/MessageRender';
// eslint-disable-next-line import/no-cycle
@ -28,7 +29,7 @@ const MessageContainer = React.memo(
},
);
export default function Message(props: TMessageProps) {
export default function Message(props: TMessageProps & { costs?: TConversationCosts }) {
const {
showSibling,
conversation,
@ -37,7 +38,7 @@ export default function Message(props: TMessageProps) {
latestMultiMessage,
isSubmittingFamily,
} = useMessageProcess({ message: props.message });
const { message, currentEditId, setCurrentEditId } = props;
const { message, currentEditId, setCurrentEditId, costs } = props;
const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
if (!message || typeof message !== 'object') {
@ -62,6 +63,7 @@ export default function Message(props: TMessageProps) {
message={message}
isSubmittingFamily={isSubmittingFamily}
isCard
costs={costs}
/>
<MessageRender
{...props}
@ -69,12 +71,13 @@ export default function Message(props: TMessageProps) {
isCard
message={siblingMessage ?? latestMultiMessage ?? undefined}
isSubmittingFamily={isSubmittingFamily}
costs={costs}
/>
</div>
</div>
) : (
<div className="m-auto justify-center p-4 py-2 md:gap-6 ">
<MessageRender {...props} />
<div className="m-auto justify-center p-4 py-2 md:gap-6">
<MessageRender {...props} costs={costs} />
</div>
)}
</MessageContainer>
@ -85,6 +88,7 @@ export default function Message(props: TMessageProps) {
messagesTree={children ?? []}
currentEditId={currentEditId}
setCurrentEditId={setCurrentEditId}
costs={costs}
/>
</>
);

View file

@ -1,6 +1,6 @@
import React, { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import type { TMessageContentParts } from 'librechat-data-provider';
import type { TMessageContentParts, TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import { useMessageHelpers, useLocalize, useAttachments } from '~/hooks';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
@ -12,10 +12,17 @@ import SubRow from './SubRow';
import { cn } from '~/utils';
import store from '~/store';
export default function Message(props: TMessageProps) {
export default function Message(props: TMessageProps & { costs?: TConversationCosts }) {
const localize = useLocalize();
const { message, siblingIdx, siblingCount, setSiblingIdx, currentEditId, setCurrentEditId } =
props;
const {
message,
siblingIdx,
siblingCount,
setSiblingIdx,
currentEditId,
setCurrentEditId,
costs,
} = props;
const { attachments, searchResults } = useAttachments({
messageId: message?.messageId,
attachments: message?.attachments,
@ -164,6 +171,7 @@ export default function Message(props: TMessageProps) {
messagesTree={children ?? []}
currentEditId={currentEditId}
setCurrentEditId={setCurrentEditId}
costs={costs}
/>
</>
);

View file

@ -1,7 +1,7 @@
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { CSSTransition } from 'react-transition-group';
import type { TMessage } from 'librechat-data-provider';
import type { TMessage, TConversationCosts } from 'librechat-data-provider';
import { useScreenshot, useMessageScrolling, useLocalize } from '~/hooks';
import ScrollToBottom from '~/components/Messages/ScrollToBottom';
import MultiMessage from './MultiMessage';
@ -11,9 +11,11 @@ import store from '~/store';
export default function MessagesView({
messagesTree: _messagesTree,
costBar,
costs,
}: {
messagesTree?: TMessage[] | null;
costBar?: React.ReactNode;
costs?: TConversationCosts;
}) {
const localize = useLocalize();
const fontSize = useRecoilValue(store.fontSize);
@ -65,6 +67,7 @@ export default function MessagesView({
messageId={conversationId ?? null}
setCurrentEditId={setCurrentEditId}
currentEditId={currentEditId ?? null}
costs={costs}
/>
</div>
</>

View file

@ -1,7 +1,7 @@
import { useRecoilState } from 'recoil';
import { useEffect, useCallback } from 'react';
import { isAssistantsEndpoint } from 'librechat-data-provider';
import type { TMessage } from 'librechat-data-provider';
import type { TMessage, TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps } from '~/common';
import MessageContent from '~/components/Messages/MessageContent';
import MessageParts from './MessageParts';
@ -14,7 +14,8 @@ export default function MultiMessage({
messagesTree,
currentEditId,
setCurrentEditId,
}: TMessageProps) {
costs,
}: TMessageProps & { costs?: TConversationCosts }) {
const [siblingIdx, setSiblingIdx] = useRecoilState(store.messagesSiblingIdxFamily(messageId));
const setSiblingIdxRev = useCallback(
@ -55,6 +56,7 @@ export default function MultiMessage({
siblingIdx={messagesTree.length - siblingIdx - 1}
siblingCount={messagesTree.length}
setSiblingIdx={setSiblingIdxRev}
costs={costs}
/>
);
} else if (message.content) {
@ -67,6 +69,7 @@ export default function MultiMessage({
siblingIdx={messagesTree.length - siblingIdx - 1}
siblingCount={messagesTree.length}
setSiblingIdx={setSiblingIdxRev}
costs={costs}
/>
);
}
@ -80,6 +83,7 @@ export default function MultiMessage({
siblingIdx={messagesTree.length - siblingIdx - 1}
siblingCount={messagesTree.length}
setSiblingIdx={setSiblingIdxRev}
costs={costs}
/>
);
}

View file

@ -1,13 +1,12 @@
import React, { useCallback, useMemo, memo } from 'react';
import { useRecoilValue } from 'recoil';
import { type TMessage } from 'librechat-data-provider';
import { type TMessage, TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import MessageContent from '~/components/Chat/Messages/Content/MessageContent';
import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow';
import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
import HoverButtons from '~/components/Chat/Messages/HoverButtons';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
import { useGetConversationCosts } from '~/data-provider';
import { Plugin } from '~/components/Messages/Content';
import SubRow from '~/components/Chat/Messages/SubRow';
import { MessageContext } from '~/Providers';
@ -20,6 +19,7 @@ type MessageRenderProps = {
isCard?: boolean;
isMultiMessage?: boolean;
isSubmittingFamily?: boolean;
costs?: TConversationCosts;
} & Pick<
TMessageProps,
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
@ -36,6 +36,7 @@ const MessageRender = memo(
isMultiMessage = false,
setCurrentEditId,
isSubmittingFamily = false,
costs,
}: MessageRenderProps) => {
const {
ask,
@ -62,20 +63,17 @@ const MessageRender = memo(
const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
const fontSize = useRecoilValue(store.fontSize);
const convoId = conversation?.conversationId ?? '';
const { data: convoCosts } = useGetConversationCosts(convoId, {
enabled: !!convoId,
});
const perMessageCost = useMemo(() => {
if (!convoCosts || !convoCosts.perMessage || !msg?.messageId) {
if (!costs || !costs.perMessage || !msg?.messageId) {
return null;
}
const entry = convoCosts.perMessage.find((p) => p.messageId === msg.messageId);
const entry = costs.perMessage.find((p) => p.messageId === msg.messageId);
if (!entry) {
return null;
}
return entry;
}, [convoCosts, msg?.messageId]);
}, [costs, msg?.messageId]);
const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
const hasNoChildren = !(msg?.children?.length ?? 0);

View file

@ -1,6 +1,6 @@
import { useRecoilValue } from 'recoil';
import { useCallback, useMemo, memo } from 'react';
import type { TMessage, TMessageContentParts } from 'librechat-data-provider';
import type { TMessage, TMessageContentParts, TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import ContentParts from '~/components/Chat/Messages/Content/ContentParts';
import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow';
@ -8,7 +8,6 @@ import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
import HoverButtons from '~/components/Chat/Messages/HoverButtons';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
import { useAttachments, useMessageActions } from '~/hooks';
import { useGetConversationCosts } from '~/data-provider';
import SubRow from '~/components/Chat/Messages/SubRow';
import { cn, logger } from '~/utils';
import store from '~/store';
@ -18,6 +17,7 @@ type ContentRenderProps = {
isCard?: boolean;
isMultiMessage?: boolean;
isSubmittingFamily?: boolean;
costs?: TConversationCosts;
} & Pick<
TMessageProps,
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
@ -34,6 +34,7 @@ const ContentRender = memo(
isMultiMessage = false,
setCurrentEditId,
isSubmittingFamily = false,
costs,
}: ContentRenderProps) => {
const { attachments, searchResults } = useAttachments({
messageId: msg?.messageId,
@ -64,14 +65,13 @@ const ContentRender = memo(
const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
const fontSize = useRecoilValue(store.fontSize);
const convoId = conversation?.conversationId ?? '';
const { data: convoCosts } = useGetConversationCosts(convoId, { enabled: !!convoId });
const perMessageCost = useMemo(() => {
if (!convoCosts || !convoCosts.perMessage || !msg?.messageId) {
if (!costs || !costs.perMessage || !msg?.messageId) {
return null;
}
return convoCosts.perMessage.find((p) => p.messageId === msg.messageId) ?? null;
}, [convoCosts, msg?.messageId]);
return costs.perMessage.find((p) => p.messageId === msg.messageId) ?? null;
}, [costs, msg?.messageId]);
const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
const isLast = useMemo(

View file

@ -1,5 +1,6 @@
import React from 'react';
import { useMessageProcess } from '~/hooks';
import type { TConversationCosts } from 'librechat-data-provider';
import type { TMessageProps } from '~/common';
// eslint-disable-next-line import/no-cycle
import MultiMessage from '~/components/Chat/Messages/MultiMessage';
@ -25,7 +26,7 @@ const MessageContainer = React.memo(
},
);
export default function MessageContent(props: TMessageProps) {
export default function MessageContent(props: TMessageProps & { costs?: TConversationCosts }) {
const {
showSibling,
conversation,
@ -34,7 +35,7 @@ export default function MessageContent(props: TMessageProps) {
latestMultiMessage,
isSubmittingFamily,
} = useMessageProcess({ message: props.message });
const { message, currentEditId, setCurrentEditId } = props;
const { message, currentEditId, setCurrentEditId, costs } = props;
if (!message || typeof message !== 'object') {
return null;
@ -53,6 +54,7 @@ export default function MessageContent(props: TMessageProps) {
message={message}
isSubmittingFamily={isSubmittingFamily}
isCard
costs={costs}
/>
<ContentRender
{...props}
@ -60,12 +62,13 @@ export default function MessageContent(props: TMessageProps) {
isCard
message={siblingMessage ?? latestMultiMessage ?? undefined}
isSubmittingFamily={isSubmittingFamily}
costs={costs}
/>
</div>
</div>
) : (
<div className="m-auto justify-center p-4 py-2 md:gap-6 ">
<ContentRender {...props} />
<div className="m-auto justify-center p-4 py-2 md:gap-6">
<ContentRender {...props} costs={costs} />
</div>
)}
</MessageContainer>
@ -76,6 +79,7 @@ export default function MessageContent(props: TMessageProps) {
messagesTree={children ?? []}
currentEditId={currentEditId}
setCurrentEditId={setCurrentEditId}
costs={costs}
/>
</>
);