-
+
{(() => {
@@ -723,9 +684,6 @@ export const ThreadContent: React.FC
= ({
const elements: React.ReactNode[] = [];
let assistantMessageCount = 0; // Move this outside the loop
- // Collect processed content for the Feedback component
- const processedContentParts: string[] = [];
-
group.messages.forEach((message, msgIndex) => {
if (message.type === 'assistant') {
const parsedContent = safeJsonParse(message.content, {});
@@ -733,12 +691,6 @@ export const ThreadContent: React.FC = ({
if (!parsedContent.content) return;
- // Extract clean content for copying
- const cleanContent = extractCleanMarkdownContent(parsedContent.content);
- if (cleanContent) {
- processedContentParts.push(cleanContent);
- }
-
const renderedContent = renderMarkdownContent(
parsedContent.content,
handleToolClick,
@@ -761,10 +713,6 @@ export const ThreadContent: React.FC = ({
}
});
- // Store the processed content for the Feedback component
- const processedContent = processedContentParts.join('\n\n');
- group.processedContent = processedContent;
-
return elements;
})()}
@@ -945,34 +893,6 @@ export const ThreadContent: React.FC = ({
)}
-
- {(() => {
- const firstAssistant = group.messages.find(msg => msg.type === 'assistant');
- const messageId = firstAssistant?.message_id;
- if (!messageId) return null;
-
- // Check if this group is currently streaming
- const isCurrentlyStreaming = (() => {
- const isLastGroup = groupIndex === finalGroupedMessages.length - 1;
- const hasStreamingContent = streamingTextContent || streamingToolCall;
- return isLastGroup && hasStreamingContent;
- })();
-
- // Don't show actions for streaming messages
- if (isCurrentlyStreaming) return null;
-
- // Get the processed content that was stored during rendering
- const processedContent = group.processedContent;
- return (
-
-
-
- );
- })()}
);
diff --git a/frontend/src/components/thread/message-actions.tsx b/frontend/src/components/thread/message-actions.tsx
deleted file mode 100644
index 0491f745..00000000
--- a/frontend/src/components/thread/message-actions.tsx
+++ /dev/null
@@ -1,146 +0,0 @@
-import { Dialog, DialogTitle, DialogHeader, DialogContent, DialogFooter, DialogClose } from "@/components/ui/dialog";
-import { Button } from "@/components/ui/button";
-import { ThumbsDown, ThumbsUp, Copy } from "lucide-react";
-import { memo, useState } from "react";
-import { Textarea } from "../ui/textarea";
-import { toast } from "sonner";
-import { backendApi } from '@/lib/api-client';
-
-interface MessageActionsProps {
- messageId: string;
- initialFeedback?: boolean | null;
- processedContent?: string;
-}
-
-export default memo(function MessageActions({ messageId, initialFeedback = null, processedContent }: MessageActionsProps) {
- const [open, setOpen] = useState(false);
- const [submittedFeedback, setSubmittedFeedback] = useState
(initialFeedback);
- const [feedback, setFeedback] = useState('');
- const [isSubmitting, setIsSubmitting] = useState(false);
- const [currentSelection, setCurrentSelection] = useState(null);
-
- const handleClick = (isGood: boolean) => {
- setCurrentSelection(isGood);
- setOpen(true);
- };
-
- const handleCopy = async () => {
- try {
- if (processedContent) {
- await navigator.clipboard.writeText(processedContent);
- toast.success('Response copied to clipboard');
- } else {
- toast.error('No content to copy');
- }
- } catch (error) {
- console.error('Failed to copy to clipboard:', error);
- toast.error('Failed to copy to clipboard');
- }
- };
-
- const handleSubmit = async () => {
- if (currentSelection === null) return;
-
- setIsSubmitting(true);
-
- try {
- const { success } = await backendApi.post('/feedback/', {
- message_id: messageId,
- is_good: currentSelection,
- feedback: feedback.trim() || null,
- });
-
- if (success) {
- setSubmittedFeedback(currentSelection);
- toast.success('Feedback submitted - thank you!');
- setOpen(false);
- setFeedback('');
- setCurrentSelection(null);
- }
- } catch (error) {
- console.error('Failed to submit feedback:', error);
- toast.error('Failed to submit feedback');
- } finally {
- setIsSubmitting(false);
- }
- };
-
- const handleOpenChange = (newOpen: boolean) => {
- setOpen(newOpen);
- if (!newOpen) {
- setFeedback('');
- setCurrentSelection(null);
- }
- };
-
- return (
-
-
-
-
-
-
-
-
-
- );
-});
\ No newline at end of file
diff --git a/frontend/src/components/thread/types.ts b/frontend/src/components/thread/types.ts
index f3f75c70..1e26dbe9 100644
--- a/frontend/src/components/thread/types.ts
+++ b/frontend/src/components/thread/types.ts
@@ -25,7 +25,6 @@ export interface UnifiedMessage {
avatar?: string;
avatar_color?: string;
}; // Agent information from join
- user_feedback?: boolean | null; // Feedback provided by current user: true (liked), false (disliked), null / undefined (no feedback)
}
// Helper type for parsed content - structure depends on message.type
diff --git a/frontend/src/hooks/useAgentStream.ts b/frontend/src/hooks/useAgentStream.ts
index 305edb0b..5855c279 100644
--- a/frontend/src/hooks/useAgentStream.ts
+++ b/frontend/src/hooks/useAgentStream.ts
@@ -29,7 +29,6 @@ interface ApiMessageType {
avatar?: string;
avatar_color?: string;
};
- user_feedback?: boolean | null;
}
// Define the structure returned by the hook
@@ -69,7 +68,6 @@ const mapApiMessagesToUnified = (
metadata: msg.metadata || '{}',
created_at: msg.created_at || new Date().toISOString(),
updated_at: msg.updated_at || new Date().toISOString(),
- user_feedback: msg.user_feedback ?? null,
agent_id: (msg as any).agent_id,
agents: (msg as any).agents,
}));
diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts
index a765b077..ea588626 100644
--- a/frontend/src/lib/api.ts
+++ b/frontend/src/lib/api.ts
@@ -76,11 +76,6 @@ export type Message = {
};
};
-export interface MessageWithFeedback extends Message {
- message_id: string;
- user_feedback?: boolean | null;
-}
-
export type AgentRun = {
id: string;
thread_id: string;
@@ -579,10 +574,10 @@ export const addUserMessage = async (
}
};
-export const getMessages = async (threadId: string): Promise => {
+export const getMessages = async (threadId: string): Promise => {
const supabase = createClient();
- let allMessages: MessageWithFeedback[] = [];
+ let allMessages: Message[] = [];
let from = 0;
const batchSize = 1000;
let hasMore = true;
@@ -619,37 +614,6 @@ export const getMessages = async (threadId: string): Promise m.type === 'assistant')
- .map((m: any) => m.message_id)
- .filter((id) => Boolean(id));
-
- if (messageIds.length > 0) {
- const { data: feedbackData, error: feedbackError } = await supabase
- .from('feedback')
- .select('message_id, is_good')
- .in('message_id', messageIds);
-
- if (feedbackError) {
- console.error('Error fetching feedback data:', feedbackError);
- }
-
- const feedback = Object.fromEntries(
- feedbackData?.map((feedback: { message_id: string; is_good: boolean }) => [feedback.message_id, feedback.is_good]) ?? []
- );
-
- // Attach feedback to messages
- allMessages = allMessages.map((msg: MessageWithFeedback) => ({
- ...msg,
- user_feedback: feedback[msg.message_id] ?? null,
- }));
- }
- } catch (feedbackAttachError) {
- console.error('Failed to attach feedback metadata to messages:', feedbackAttachError);
- }
-
console.log('[API] Messages fetched count:', allMessages.length);
return allMessages;