📈 feat: Chat rating for feedback (#5878)

* feat: working started for feedback implementation.

TODO:
- needs some refactoring.
- needs some UI animations.

* feat: working rate functionality

* feat: works now as well to reader the already rated responses from the server.

* feat: added the option to give feedback in text (optional)

* feat: added Dismiss option `x` to the `FeedbackTagOptions`

*  feat: Add rating and ratingContent fields to message schema

* 🔧 chore: Bump version to 0.0.3 in package.json

*  feat: Enhance feedback localization and update UI elements

* 🚀 feat: Implement feedback tagging system with thumbs up/down options

* 🚀 feat: Add data-provider package to unused i18n keys detection

* 🎨 style: update HoverButtons' style

* 🎨 style: Update HoverButtons and Fork components for improved styling and visibility

* 🔧 feat: Implement feedback system with rating and content options

* 🔧 feat: Enhance feedback handling with improved rating toggle and tag options

* 🔧 feat: Integrate toast notifications for feedback submission and clean up unused state

* 🔧 feat: Remove unused feedback tag options from translation file

*  refactor: clean up Feedback component and improve HoverButtons structure

*  refactor: remove unused settings switches for auto scroll, hide side panel, and user message markdown

* refactor: reorganize import order

*  refactor: enhance HoverButtons and Fork components with improved styles and animations

*  refactor: update feedback response phrases for improved user engagement

*  refactor: add CheckboxOption component and streamline fork options rendering

* Refactor feedback components and logic

- Consolidated feedback handling into a single Feedback component, removing FeedbackButtons and FeedbackTagOptions.
- Introduced new feedback tagging system with detailed tags for both thumbs up and thumbs down ratings.
- Updated feedback schema to include new tags and improved type definitions.
- Enhanced user interface for feedback collection, including a dialog for additional comments.
- Removed obsolete files and adjusted imports accordingly.
- Updated translations for new feedback tags and placeholders.

*  refactor: update feedback handling by replacing rating fields with feedback in message updates

* fix: add missing validateMessageReq middleware to feedback route and refactor feedback system

* 🗑️ chore: Remove redundant fork option explanations from translation file

* 🔧 refactor: Remove unused dependency from feedback callback

* 🔧 refactor: Simplify message update response structure and improve error logging

* Chore: removed unused tests.

---------

Co-authored-by: Marco Beretta <81851188+berry-13@users.noreply.github.com>
This commit is contained in:
Ruben Talstra 2025-05-30 18:16:34 +02:00 committed by GitHub
parent 4808c5be48
commit 4cbab86b45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
76 changed files with 1592 additions and 835 deletions

View file

@ -113,11 +113,11 @@ export const useEndpoints = ({
hasModels,
icon: Icon
? React.createElement(Icon, {
size: 20,
className: 'text-text-primary shrink-0 icon-md',
iconURL: endpointIconURL,
endpoint: ep,
})
size: 20,
className: 'text-text-primary shrink-0 icon-md',
iconURL: endpointIconURL,
endpoint: ep,
})
: null,
};

View file

@ -1,7 +1,15 @@
import { useRecoilValue } from 'recoil';
import { useCallback, useMemo } from 'react';
import { isAssistantsEndpoint, isAgentsEndpoint } from 'librechat-data-provider';
import type { SearchResultData } from 'librechat-data-provider';
import { useCallback, useMemo, useState } from 'react';
import { useUpdateFeedbackMutation } from 'librechat-data-provider/react-query';
import {
isAssistantsEndpoint,
isAgentsEndpoint,
TUpdateFeedbackRequest,
getTagByKey,
TFeedback,
toMinimalFeedback,
SearchResultData,
} from 'librechat-data-provider';
import type { TMessageProps } from '~/common';
import {
useChatContext,
@ -11,7 +19,7 @@ import {
} from '~/Providers';
import useCopyToClipboard from './useCopyToClipboard';
import { useAuthContext } from '~/hooks/AuthContext';
import useLocalize from '~/hooks/useLocalize';
import { useLocalize } from '~/hooks';
import store from '~/store';
export type TMessageActions = Pick<
@ -50,6 +58,18 @@ export default function useMessageActions(props: TMessageActions) {
const { text, content, messageId = null, isCreatedByUser } = message ?? {};
const edit = useMemo(() => messageId === currentEditId, [messageId, currentEditId]);
const [feedback, setFeedback] = useState<TFeedback | undefined>(() => {
if (message?.feedback) {
const tag = getTagByKey(message.feedback?.tag?.key);
return {
rating: message.feedback.rating,
tag,
text: message.feedback.text,
};
}
return undefined;
});
const enterEdit = useCallback(
(cancel?: boolean) => setCurrentEditId && setCurrentEditId(cancel === true ? -1 : messageId),
[messageId, setCurrentEditId],
@ -113,6 +133,38 @@ export default function useMessageActions(props: TMessageActions) {
}
}, [message, agent, assistant, UsernameDisplay, user, localize]);
const feedbackMutation = useUpdateFeedbackMutation(
conversation?.conversationId || '',
message?.messageId || '',
);
const handleFeedback = useCallback(
({ feedback: newFeedback }: { feedback: TFeedback | undefined }) => {
const payload: TUpdateFeedbackRequest = {
feedback: newFeedback ? toMinimalFeedback(newFeedback) : undefined,
};
feedbackMutation.mutate(payload, {
onSuccess: (data) => {
if (!data.feedback) {
setFeedback(undefined);
} else {
const tag = getTagByKey(data.feedback?.tag ?? undefined);
setFeedback({
rating: data.feedback.rating,
tag,
text: data.feedback.text,
});
}
},
onError: (error) => {
console.error('Failed to update feedback:', error);
},
});
},
[feedbackMutation],
);
return {
ask,
edit,
@ -128,5 +180,7 @@ export default function useMessageActions(props: TMessageActions) {
copyToClipboard,
setLatestMessage,
regenerateMessage,
handleFeedback,
feedback,
};
}