import type { Dispatch, SetStateAction } from 'react' import { RotateCcw } from 'lucide-react' import { Alert, AlertDescription } from '@/components/ui/alert' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { ScrollArea } from '@/components/ui/scroll-area' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { TabsContent } from '@/components/ui/tabs' import { cn } from '@/lib/utils' import type { MemoryFeedbackActionLogPayload, MemoryFeedbackCorrectionDetailTaskPayload, MemoryFeedbackCorrectionSummaryPayload, } from '@/lib/memory-api' import { FEEDBACK_ACTION_LOG_PAGE_SIZE, FEEDBACK_CORRECTION_PAGE_SIZE } from '../constants' import { buildFeedbackImpactSummary, describeFeedbackActionLog, formatDeleteOperationTime, formatFeedbackActionType, formatFeedbackDecision, formatFeedbackRollbackStatus, formatFeedbackTaskStatus, getFeedbackCorrectionPreview, getFeedbackStatusVariant, summarizeFeedbackActionPayload, } from '../utils' export interface FeedbackTabProps { feedbackSearch: string setFeedbackSearch: Dispatch> feedbackStatusFilter: string setFeedbackStatusFilter: Dispatch> feedbackRollbackFilter: string setFeedbackRollbackFilter: Dispatch> filteredFeedbackCorrections: MemoryFeedbackCorrectionSummaryPayload[] feedbackCorrections: MemoryFeedbackCorrectionSummaryPayload[] pagedFeedbackCorrections: MemoryFeedbackCorrectionSummaryPayload[] feedbackPage: number setFeedbackPage: Dispatch> feedbackPageCount: number selectedFeedbackCorrection: MemoryFeedbackCorrectionSummaryPayload | null setSelectedFeedbackTaskId: Dispatch> selectedFeedbackResolved: MemoryFeedbackCorrectionDetailTaskPayload | null selectedFeedbackPreview: ReturnType selectedFeedbackImpactSummary: string[] openFeedbackRollbackDialog: () => void feedbackRollingBack: boolean selectedFeedbackTaskLoading: boolean selectedFeedbackTaskError: string | null feedbackActionLogPage: number setFeedbackActionLogPage: Dispatch> feedbackActionLogPageCount: number feedbackActionLogSearch: string setFeedbackActionLogSearch: Dispatch> pagedFeedbackActionLogs: MemoryFeedbackActionLogPayload[] selectedFeedbackActionLogs: MemoryFeedbackActionLogPayload[] } export function FeedbackTab(props: FeedbackTabProps) { const { feedbackSearch, setFeedbackSearch, feedbackStatusFilter, setFeedbackStatusFilter, feedbackRollbackFilter, setFeedbackRollbackFilter, filteredFeedbackCorrections, feedbackCorrections, pagedFeedbackCorrections, feedbackPage, setFeedbackPage, feedbackPageCount, selectedFeedbackCorrection, setSelectedFeedbackTaskId, selectedFeedbackResolved, selectedFeedbackPreview, selectedFeedbackImpactSummary, openFeedbackRollbackDialog, feedbackRollingBack, selectedFeedbackTaskLoading, selectedFeedbackTaskError, feedbackActionLogPage, setFeedbackActionLogPage, feedbackActionLogPageCount, feedbackActionLogSearch, setFeedbackActionLogSearch, pagedFeedbackActionLogs, selectedFeedbackActionLogs, } = props return (
反馈纠错历史 查看 feedback correction 的判定、修改轨迹与回退结果;本期仅覆盖自动纠错任务
setFeedbackSearch(event.target.value)} placeholder="搜索查询编号 / 会话 / 查询内容 / 原因" />
当前命中 {filteredFeedbackCorrections.length} 条记录,已加载最近 {feedbackCorrections.length} 条 第 {feedbackPage} / {feedbackPageCount} 页,每页显示 {FEEDBACK_CORRECTION_PAGE_SIZE} 条
{pagedFeedbackCorrections.length > 0 ? pagedFeedbackCorrections.map((item) => { const isSelected = selectedFeedbackCorrection?.task_id === item.task_id const preview = getFeedbackCorrectionPreview(item) const impactSummary = buildFeedbackImpactSummary(item) return ( ) }) : (
当前筛选条件下没有纠错历史
)}
{selectedFeedbackCorrection ? (
{formatFeedbackTaskStatus(String(selectedFeedbackResolved?.task_status ?? ''))} {formatFeedbackRollbackStatus(String(selectedFeedbackResolved?.rollback_status ?? 'none'))} {formatFeedbackDecision(String(selectedFeedbackResolved?.decision ?? ''))}
{selectedFeedbackPreview.headline}
查询:{selectedFeedbackResolved?.query_text || '无查询文本'}
{selectedFeedbackResolved?.query_tool_id}
本次纠错结论
纠错前
{selectedFeedbackPreview.oldRelation || '当前详情没有记录旧结论'}
纠错后
{selectedFeedbackPreview.newRelation || '当前详情没有记录新结论'}
影响范围摘要
{selectedFeedbackImpactSummary.length > 0 ? selectedFeedbackImpactSummary.map((summary) => ( {summary} )) : (
当前没有可展示的影响范围摘要
)}
会话
{selectedFeedbackResolved?.session_id || '-'}
反馈消息数
{Number(selectedFeedbackResolved?.feedback_message_count ?? 0)}
判定置信度
{Number(selectedFeedbackResolved?.decision_confidence ?? 0).toFixed(2)}
回退时间
{formatDeleteOperationTime(selectedFeedbackResolved?.rolled_back_at)}
{selectedFeedbackTaskLoading ? (
正在加载纠错详情...
) : null} {selectedFeedbackTaskError ? ( {selectedFeedbackTaskError} ) : null} {selectedFeedbackResolved?.rollback_error ? ( {selectedFeedbackResolved.rollback_error} ) : null}
回退后会发生什么
会恢复旧关系状态,并撤销本次纠错写入的段落与关系。
会清理旧段落的待复核标记,并重新触发相关 Episode / Profile 修复。
如果你当前只是核对结果,可以先查看下面的详细数据,不必立刻执行回退。
处理摘要
判定:{formatFeedbackDecision(String(selectedFeedbackResolved?.decision ?? ''))}
任务状态:{formatFeedbackTaskStatus(String(selectedFeedbackResolved?.task_status ?? ''))}
回退状态:{formatFeedbackRollbackStatus(String(selectedFeedbackResolved?.rollback_status ?? 'none'))}
反馈消息数:{Number(selectedFeedbackResolved?.feedback_message_count ?? 0)}
详细数据
查询快照 JSON
                            {JSON.stringify(selectedFeedbackResolved?.query_snapshot ?? {}, null, 2)}
                          
判定结果 JSON
                            {JSON.stringify(selectedFeedbackResolved?.decision_payload ?? {}, null, 2)}
                          
回退计划摘要 JSON
                            {JSON.stringify(selectedFeedbackResolved?.rollback_plan_summary ?? {}, null, 2)}
                          
回退结果 JSON
                            {JSON.stringify(selectedFeedbackResolved?.rollback_result ?? {}, null, 2)}
                          
动作时间线
第 {feedbackActionLogPage} / {feedbackActionLogPageCount} 页,每页 {FEEDBACK_ACTION_LOG_PAGE_SIZE} 项
setFeedbackActionLogSearch(event.target.value)} placeholder="搜索动作 / 目标哈希 / 预览内容" className="lg:w-80" />
{pagedFeedbackActionLogs.length > 0 ? pagedFeedbackActionLogs.map((item: MemoryFeedbackActionLogPayload) => (
{formatFeedbackActionType(item.action_type)} {item.target_hash ? ( {item.target_hash} ) : null}
{formatDeleteOperationTime(item.created_at)}
{describeFeedbackActionLog(item)}
{item.reason ? (
原因:{item.reason}
) : null} {item.before_payload && Object.keys(item.before_payload).length > 0 ? (
处理前: {summarizeFeedbackActionPayload(item.before_payload)}
) : null} {item.after_payload && Object.keys(item.after_payload).length > 0 ? (
处理后: {summarizeFeedbackActionPayload(item.after_payload)}
) : null}
)) : (
{selectedFeedbackActionLogs.length > 0 ? '当前筛选条件下没有动作日志' : '当前任务没有动作日志'}
)}
支持按动作类型、目标哈希和摘要检索
) : (
当前没有可查看的纠错详情
)}
支持按查询内容、任务状态和回退状态检索
) }