Feat: Display agent operator call log #3221 (#8169)

### What problem does this PR solve?

Feat: Display agent operator call log #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-06-11 09:22:07 +08:00
committed by GitHub
parent e6d36f3a3a
commit f0a3d91171
23 changed files with 1513 additions and 124 deletions

View File

@ -0,0 +1,220 @@
import { PromptIcon } from '@/assets/icon/Icon';
import CopyToClipboard from '@/components/copy-to-clipboard';
import { useSetModalState } from '@/hooks/common-hooks';
import { IRemoveMessageById } from '@/hooks/logic-hooks';
import { AgentChatContext } from '@/pages/agent/context';
import {
DeleteOutlined,
DislikeOutlined,
LikeOutlined,
PauseCircleOutlined,
SoundOutlined,
SyncOutlined,
} from '@ant-design/icons';
import { Radio, Tooltip } from 'antd';
import { NotebookText } from 'lucide-react';
import { useCallback, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group';
import FeedbackModal from './feedback-modal';
import { useRemoveMessage, useSendFeedback, useSpeech } from './hooks';
import PromptModal from './prompt-modal';
interface IProps {
messageId: string;
content: string;
prompt?: string;
showLikeButton: boolean;
audioBinary?: string;
showLoudspeaker?: boolean;
}
export const AssistantGroupButton = ({
messageId,
content,
prompt,
audioBinary,
showLikeButton,
showLoudspeaker = true,
}: IProps) => {
const { visible, hideModal, showModal, onFeedbackOk, loading } =
useSendFeedback(messageId);
const {
visible: promptVisible,
hideModal: hidePromptModal,
showModal: showPromptModal,
} = useSetModalState();
const { t } = useTranslation();
const { handleRead, ref, isPlaying } = useSpeech(content, audioBinary);
const handleLike = useCallback(() => {
onFeedbackOk({ thumbup: true });
}, [onFeedbackOk]);
const { showLogSheet } = useContext(AgentChatContext);
const handleShowLogSheet = useCallback(() => {
showLogSheet(messageId);
}, [messageId, showLogSheet]);
return (
<>
<ToggleGroup
type={'single'}
size="sm"
variant="outline"
className="space-x-1"
>
<ToggleGroupItem value="a">
<CopyToClipboard text={content}></CopyToClipboard>
</ToggleGroupItem>
{showLoudspeaker && (
<ToggleGroupItem value="b" onClick={handleRead}>
<Tooltip title={t('chat.read')}>
{isPlaying ? <PauseCircleOutlined /> : <SoundOutlined />}
</Tooltip>
<audio src="" ref={ref}></audio>
</ToggleGroupItem>
)}
{showLikeButton && (
<>
<ToggleGroupItem value="c" onClick={handleLike}>
<LikeOutlined />
</ToggleGroupItem>
<ToggleGroupItem value="d" onClick={showModal}>
<DislikeOutlined />
</ToggleGroupItem>
</>
)}
{prompt && (
<Radio.Button value="e" onClick={showPromptModal}>
<PromptIcon style={{ fontSize: '16px' }} />
</Radio.Button>
)}
<ToggleGroupItem value="f" onClick={handleShowLogSheet}>
<NotebookText className="size-4" />
</ToggleGroupItem>
</ToggleGroup>
{visible && (
<FeedbackModal
visible={visible}
hideModal={hideModal}
onOk={onFeedbackOk}
loading={loading}
></FeedbackModal>
)}
{promptVisible && (
<PromptModal
visible={promptVisible}
hideModal={hidePromptModal}
prompt={prompt}
></PromptModal>
)}
</>
);
return (
<>
<Radio.Group size="small">
<Radio.Button value="a">
<CopyToClipboard text={content}></CopyToClipboard>
</Radio.Button>
{showLoudspeaker && (
<Radio.Button value="b" onClick={handleRead}>
<Tooltip title={t('chat.read')}>
{isPlaying ? <PauseCircleOutlined /> : <SoundOutlined />}
</Tooltip>
<audio src="" ref={ref}></audio>
</Radio.Button>
)}
{showLikeButton && (
<>
<Radio.Button value="c" onClick={handleLike}>
<LikeOutlined />
</Radio.Button>
<Radio.Button value="d" onClick={showModal}>
<DislikeOutlined />
</Radio.Button>
</>
)}
{prompt && (
<Radio.Button value="e" onClick={showPromptModal}>
<PromptIcon style={{ fontSize: '16px' }} />
</Radio.Button>
)}
<Radio.Button
value="f"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleShowLogSheet();
}}
>
<NotebookText className="size-4" />
</Radio.Button>
</Radio.Group>
{visible && (
<FeedbackModal
visible={visible}
hideModal={hideModal}
onOk={onFeedbackOk}
loading={loading}
></FeedbackModal>
)}
{promptVisible && (
<PromptModal
visible={promptVisible}
hideModal={hidePromptModal}
prompt={prompt}
></PromptModal>
)}
</>
);
};
interface UserGroupButtonProps extends Partial<IRemoveMessageById> {
messageId: string;
content: string;
regenerateMessage?: () => void;
sendLoading: boolean;
}
export const UserGroupButton = ({
content,
messageId,
sendLoading,
removeMessageById,
regenerateMessage,
}: UserGroupButtonProps) => {
const { onRemoveMessage, loading } = useRemoveMessage(
messageId,
removeMessageById,
);
const { t } = useTranslation();
return (
<Radio.Group size="small">
<Radio.Button value="a">
<CopyToClipboard text={content}></CopyToClipboard>
</Radio.Button>
{regenerateMessage && (
<Radio.Button
value="b"
onClick={regenerateMessage}
disabled={sendLoading}
>
<Tooltip title={t('chat.regenerate')}>
<SyncOutlined spin={sendLoading} />
</Tooltip>
</Radio.Button>
)}
{removeMessageById && (
<Radio.Button value="c" onClick={onRemoveMessage} disabled={loading}>
<Tooltip title={t('common.delete')}>
<DeleteOutlined spin={loading} />
</Tooltip>
</Radio.Button>
)}
</Radio.Group>
);
};