mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 11:18:22 +00:00
fix(feedback): correct run_id mapping for feedback echo
The feedbackMap was keyed by run_id but looked up by LangGraph message ID. Fixed by tracking AI message ordinal index to correlate event store run_ids with LangGraph SDK messages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
18393b55d1
commit
95d5c156a1
@ -4,6 +4,7 @@ import {
|
||||
Conversation,
|
||||
ConversationContent,
|
||||
} from "@/components/ai-elements/conversation";
|
||||
import type { FeedbackData } from "@/core/api/feedback";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import {
|
||||
extractContentFromMessage,
|
||||
@ -18,6 +19,7 @@ import { useRehypeSplitWordsIntoSpans } from "@/core/rehype";
|
||||
import type { Subtask } from "@/core/tasks";
|
||||
import { useUpdateSubtask } from "@/core/tasks/context";
|
||||
import type { AgentThreadState } from "@/core/threads";
|
||||
import { useThreadFeedback } from "@/core/threads/hooks";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { ArtifactFileList } from "../artifacts/artifact-file-list";
|
||||
@ -46,7 +48,11 @@ export function MessageList({
|
||||
const { t } = useI18n();
|
||||
const rehypePlugins = useRehypeSplitWordsIntoSpans(thread.isLoading);
|
||||
const updateSubtask = useUpdateSubtask();
|
||||
const { data: feedbackData } = useThreadFeedback(threadId);
|
||||
const messages = thread.messages;
|
||||
|
||||
// Track AI message ordinal index for feedback mapping
|
||||
let aiMessageIndex = 0;
|
||||
if (thread.isThreadLoading && messages.length === 0) {
|
||||
return <MessageListSkeleton />;
|
||||
}
|
||||
@ -58,12 +64,23 @@ export function MessageList({
|
||||
{groupMessages(messages, (group) => {
|
||||
if (group.type === "human" || group.type === "assistant") {
|
||||
return group.messages.map((msg) => {
|
||||
let runId: string | undefined;
|
||||
let feedback: FeedbackData | null = null;
|
||||
if (msg.type !== "human" && feedbackData) {
|
||||
runId =
|
||||
feedbackData.runIdByAiIndex[aiMessageIndex] ?? undefined;
|
||||
feedback = runId
|
||||
? (feedbackData.feedbackByRunId[runId] ?? null)
|
||||
: null;
|
||||
aiMessageIndex++;
|
||||
}
|
||||
return (
|
||||
<MessageListItem
|
||||
key={`${group.id}/${msg.id}`}
|
||||
message={msg}
|
||||
isLoading={thread.isLoading}
|
||||
threadId={threadId}
|
||||
runId={runId}
|
||||
feedback={feedback}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -167,7 +184,7 @@ export function MessageList({
|
||||
results.push(
|
||||
<div
|
||||
key="subtask-count"
|
||||
className="text-muted-foreground pt-2 text-sm font-normal"
|
||||
className="text-muted-foreground font-norma pt-2 text-sm"
|
||||
>
|
||||
{t.subtasks.executing(tasks.size)}
|
||||
</div>,
|
||||
|
||||
@ -679,15 +679,29 @@ export function useRenameThread() {
|
||||
});
|
||||
}
|
||||
|
||||
export interface ThreadFeedbackData {
|
||||
/** Maps AI message ordinal index (0-based, counting only AI messages) to run_id */
|
||||
runIdByAiIndex: string[];
|
||||
/** Maps run_id to feedback data */
|
||||
feedbackByRunId: Record<
|
||||
string,
|
||||
{ feedback_id: string; rating: number; comment: string | null }
|
||||
>;
|
||||
}
|
||||
|
||||
export function useThreadFeedback(threadId: string | null | undefined) {
|
||||
return useQuery({
|
||||
queryKey: ["thread-feedback", threadId],
|
||||
queryFn: async () => {
|
||||
if (!threadId) return {};
|
||||
queryFn: async (): Promise<ThreadFeedbackData> => {
|
||||
const empty: ThreadFeedbackData = {
|
||||
runIdByAiIndex: [],
|
||||
feedbackByRunId: {},
|
||||
};
|
||||
if (!threadId) return empty;
|
||||
const res = await fetchWithAuth(
|
||||
`${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}/messages?limit=200`,
|
||||
);
|
||||
if (!res.ok) return {};
|
||||
if (!res.ok) return empty;
|
||||
const messages: Array<{
|
||||
run_id: string;
|
||||
event_type: string;
|
||||
@ -697,16 +711,20 @@ export function useThreadFeedback(threadId: string | null | undefined) {
|
||||
comment: string | null;
|
||||
} | null;
|
||||
}> = await res.json();
|
||||
const feedbackMap: Record<
|
||||
const runIdByAiIndex: string[] = [];
|
||||
const feedbackByRunId: Record<
|
||||
string,
|
||||
{ feedback_id: string; rating: number; comment: string | null }
|
||||
> = {};
|
||||
for (const msg of messages) {
|
||||
if (msg.event_type === "ai_message") {
|
||||
runIdByAiIndex.push(msg.run_id);
|
||||
}
|
||||
if (msg.feedback && msg.run_id) {
|
||||
feedbackMap[msg.run_id] = msg.feedback;
|
||||
feedbackByRunId[msg.run_id] = msg.feedback;
|
||||
}
|
||||
}
|
||||
return feedbackMap;
|
||||
return { runIdByAiIndex, feedbackByRunId };
|
||||
},
|
||||
enabled: !!threadId,
|
||||
staleTime: 30_000,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user