From f1fc79c86441efe3ebfeb00972a8f25b27b85844 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Fri, 25 Apr 2025 17:02:30 +0200 Subject: [PATCH] ui: feedback methods and ui --- frontend/app/components/Kai/SocketManager.ts | 5 +++-- .../app/components/Kai/components/ChatLog.tsx | 14 +++++++----- .../app/components/Kai/components/ChatMsg.tsx | 19 ++++++++++++++-- frontend/app/services/AiService.ts | 22 +++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/frontend/app/components/Kai/SocketManager.ts b/frontend/app/components/Kai/SocketManager.ts index da2537ee5..020cf18c8 100644 --- a/frontend/app/components/Kai/SocketManager.ts +++ b/frontend/app/components/Kai/SocketManager.ts @@ -69,11 +69,12 @@ export class ChatManager { } export interface BotChunk { - stage: 'chart' | 'final' | 'title'; + stage: 'start' | 'chart' | 'final' | 'title'; content: string; - data?: any[]; + messageId: string; } export interface Message { text: string; isUser: boolean; + messageId: string; } diff --git a/frontend/app/components/Kai/components/ChatLog.tsx b/frontend/app/components/Kai/components/ChatLog.tsx index 909557909..3904c9fc2 100644 --- a/frontend/app/components/Kai/components/ChatLog.tsx +++ b/frontend/app/components/Kai/components/ChatLog.tsx @@ -27,7 +27,7 @@ function ChatLog({ const chatManager = React.useRef(null); const chatRef = React.useRef(null); const [messages, setMessages] = React.useState( - initialMsg ? [{ text: initialMsg, isUser: true }] : [], + initialMsg ? [{ text: initialMsg, isUser: true, messageId: '123' }] : [], ); const [processingStage, setProcessing] = React.useState( null, @@ -49,6 +49,7 @@ function ChatLog({ return { text: m.content, isUser: isUser, + messageId: m.message_id, }; }), ); @@ -69,6 +70,9 @@ function ChatLog({ if (msg.stage === 'chart') { setProcessing(msg); } + if (msg.stage === 'start') { + setProcessing({ ...msg, content: 'Processing your request...' }); + } if (msg.stage === 'final') { setMessages((prev) => [ ...prev, @@ -76,6 +80,7 @@ function ChatLog({ text: msg.content, isUser: false, userName: 'Kai', + messageId: msg.messageId, }, ]); setProcessing(null); @@ -112,9 +117,8 @@ function ChatLog({ top: chatRef.current.scrollHeight, behavior: 'smooth', }); - }, [messages.length]); + }, [messages.length, processingStage]); - const newChat = messages.length === 1 && processingStage === null; return (
))} {processingStage ? ( ) : null} - {newChat ? ( - - ) : null}
diff --git a/frontend/app/components/Kai/components/ChatMsg.tsx b/frontend/app/components/Kai/components/ChatMsg.tsx index 31a347b41..5186ee76e 100644 --- a/frontend/app/components/Kai/components/ChatMsg.tsx +++ b/frontend/app/components/Kai/components/ChatMsg.tsx @@ -4,19 +4,34 @@ import cn from 'classnames'; import Markdown from 'react-markdown'; import { Loader, ThumbsUp, ThumbsDown, ListRestart } from 'lucide-react'; import { toast } from 'react-toastify'; +import { aiService } from 'App/services'; export function ChatMsg({ text, isUser, userName, + messageId, }: { text: string; isUser: boolean; + messageId: string; userName?: string; }) { const onClick = () => { toast.info('I do nothing!'); }; + const onFeedback = (feedback: 'like' | 'dislike', messageId: string) => { + const settings = { projectId: '2325', userId: '0' }; + aiService + .feedback(feedback === 'like', messageId, settings.projectId, settings.userId) + .then(() => { + toast.success('Feedback saved.'); + }) + .catch((e) => { + console.error(e); + toast.error('Failed to send feedback. Please try again later.'); + }); + } return (
{text} {isUser ? null : (
- + onFeedback('like', messageId)}> - + onFeedback('dislike', messageId)}> diff --git a/frontend/app/services/AiService.ts b/frontend/app/services/AiService.ts index b9501058d..4f1d806f5 100644 --- a/frontend/app/services/AiService.ts +++ b/frontend/app/services/AiService.ts @@ -151,4 +151,26 @@ export default class AiService extends BaseService { const data = await r.json(); return data; } + + feedback = async (positive: boolean | null, messageId: string, projectId: string, userId: string) => { + const jwt = window.env.KAI_TESTING // this.client.getJwt() + const r = await fetch(`http://localhost:8700/kai/${projectId}/messages/feedback`, { + method: 'POST', + headers: new Headers({ + Accept: 'application/json', + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${jwt}` + }), + body: JSON.stringify({ + message_id: messageId, + value: positive, + user_id: userId, + }), + }); + if (!r.ok) { + throw new Error('Failed to send feedback'); + } + + return await r.json() + } }