mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
Fix: Fixed share-log UI issues and log-template bugs (#9166)
### What problem does this PR solve? Fix: Fixed share-log UI issues and log-template bugs #3221 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
.messageItemContent {
|
.messageItemContent {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.messageItemContentReverse {
|
.messageItemContentReverse {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|||||||
@ -14,16 +14,18 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import { IRegenerateMessage, IRemoveMessageById } from '@/hooks/logic-hooks';
|
import { IRegenerateMessage, IRemoveMessageById } from '@/hooks/logic-hooks';
|
||||||
import { INodeEvent } from '@/hooks/use-send-message';
|
import { INodeEvent, MessageEventType } from '@/hooks/use-send-message';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { AgentChatContext } from '@/pages/agent/context';
|
import { AgentChatContext } from '@/pages/agent/context';
|
||||||
import { WorkFlowTimeline } from '@/pages/agent/log-sheet/workFlowTimeline';
|
import { WorkFlowTimeline } from '@/pages/agent/log-sheet/workFlowTimeline';
|
||||||
import { IMessage } from '@/pages/chat/interface';
|
import { IMessage } from '@/pages/chat/interface';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
import { Atom, ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
import IndentedTreeModal from '../indented-tree/modal';
|
import IndentedTreeModal from '../indented-tree/modal';
|
||||||
import MarkdownContent from '../next-markdown-content';
|
import MarkdownContent from '../next-markdown-content';
|
||||||
import { RAGFlowAvatar } from '../ragflow-avatar';
|
import { RAGFlowAvatar } from '../ragflow-avatar';
|
||||||
import { useTheme } from '../theme-provider';
|
import { useTheme } from '../theme-provider';
|
||||||
|
import { Button } from '../ui/button';
|
||||||
import { AssistantGroupButton, UserGroupButton } from './group-button';
|
import { AssistantGroupButton, UserGroupButton } from './group-button';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
import { ReferenceDocumentList } from './reference-document-list';
|
import { ReferenceDocumentList } from './reference-document-list';
|
||||||
@ -50,6 +52,7 @@ interface IProps
|
|||||||
showLikeButton?: boolean;
|
showLikeButton?: boolean;
|
||||||
showLoudspeaker?: boolean;
|
showLoudspeaker?: boolean;
|
||||||
showLog?: boolean;
|
showLog?: boolean;
|
||||||
|
isShare?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function MessageItem({
|
function MessageItem({
|
||||||
@ -71,13 +74,14 @@ function MessageItem({
|
|||||||
visibleAvatar = true,
|
visibleAvatar = true,
|
||||||
children,
|
children,
|
||||||
showLog,
|
showLog,
|
||||||
|
isShare,
|
||||||
}: IProps) {
|
}: IProps) {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isAssistant = item.role === MessageType.Assistant;
|
const isAssistant = item.role === MessageType.Assistant;
|
||||||
const isUser = item.role === MessageType.User;
|
const isUser = item.role === MessageType.User;
|
||||||
const { visible, hideModal, showModal } = useSetModalState();
|
const { visible, hideModal } = useSetModalState();
|
||||||
const [clickedDocumentId, setClickedDocumentId] = useState('');
|
const [clickedDocumentId] = useState('');
|
||||||
|
const [showThinking, setShowThinking] = useState(false);
|
||||||
const { setLastSendLoadingFunc } = useContext(AgentChatContext);
|
const { setLastSendLoadingFunc } = useContext(AgentChatContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -101,6 +105,16 @@ function MessageItem({
|
|||||||
setCurrentMessageId(item.id);
|
setCurrentMessageId(item.id);
|
||||||
}
|
}
|
||||||
}, [item.id, setCurrentMessageId]);
|
}, [item.id, setCurrentMessageId]);
|
||||||
|
|
||||||
|
const startedNodeList = useCallback(
|
||||||
|
(item: IMessage) => {
|
||||||
|
const finish = currentEventListWithoutMessageById?.(item.id)?.some(
|
||||||
|
(item) => item.event === MessageEventType.WorkflowFinished,
|
||||||
|
);
|
||||||
|
return !finish && loading;
|
||||||
|
},
|
||||||
|
[currentEventListWithoutMessageById, loading],
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(styles.messageItem, {
|
className={classNames(styles.messageItem, {
|
||||||
@ -123,36 +137,89 @@ function MessageItem({
|
|||||||
(item.role === MessageType.User ? (
|
(item.role === MessageType.User ? (
|
||||||
<RAGFlowAvatar avatar={avatar ?? '/logo.svg'} />
|
<RAGFlowAvatar avatar={avatar ?? '/logo.svg'} />
|
||||||
) : avatarDialog || agentName ? (
|
) : avatarDialog || agentName ? (
|
||||||
<RAGFlowAvatar avatar={avatarDialog} name={agentName} isPerson />
|
<RAGFlowAvatar
|
||||||
|
avatar={avatarDialog as string}
|
||||||
|
name={agentName}
|
||||||
|
isPerson
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<AssistantIcon />
|
<AssistantIcon />
|
||||||
))}
|
))}
|
||||||
<section className="flex-col gap-2 flex-1">
|
<section className="flex-col gap-2 flex-1">
|
||||||
<div className="space-x-1">
|
<div className="flex justify-between items-center">
|
||||||
{isAssistant ? (
|
{isShare && isAssistant && (
|
||||||
<AssistantGroupButton
|
<Button
|
||||||
messageId={item.id}
|
variant={'transparent'}
|
||||||
content={item.content}
|
onClick={() => setShowThinking((think) => !think)}
|
||||||
prompt={item.prompt}
|
>
|
||||||
showLikeButton={showLikeButton}
|
<div className="flex items-center gap-1">
|
||||||
audioBinary={item.audio_binary}
|
<div className="">
|
||||||
showLoudspeaker={showLoudspeaker}
|
<Atom
|
||||||
showLog={showLog}
|
className={startedNodeList(item) ? 'animate-spin' : ''}
|
||||||
></AssistantGroupButton>
|
/>
|
||||||
) : (
|
</div>
|
||||||
<UserGroupButton
|
Thinking
|
||||||
content={item.content}
|
{showThinking ? <ChevronUp /> : <ChevronDown />}
|
||||||
messageId={item.id}
|
</div>
|
||||||
removeMessageById={removeMessageById}
|
</Button>
|
||||||
regenerateMessage={
|
|
||||||
regenerateMessage && handleRegenerateMessage
|
|
||||||
}
|
|
||||||
sendLoading={sendLoading}
|
|
||||||
></UserGroupButton>
|
|
||||||
)}
|
)}
|
||||||
|
<div className="space-x-1">
|
||||||
|
{isAssistant ? (
|
||||||
|
<>
|
||||||
|
{isShare && !sendLoading && !isEmpty(item.content) && (
|
||||||
|
<AssistantGroupButton
|
||||||
|
messageId={item.id}
|
||||||
|
content={item.content}
|
||||||
|
prompt={item.prompt}
|
||||||
|
showLikeButton={showLikeButton}
|
||||||
|
audioBinary={item.audio_binary}
|
||||||
|
showLoudspeaker={showLoudspeaker}
|
||||||
|
showLog={showLog}
|
||||||
|
></AssistantGroupButton>
|
||||||
|
)}
|
||||||
|
{!isShare && (
|
||||||
|
<AssistantGroupButton
|
||||||
|
messageId={item.id}
|
||||||
|
content={item.content}
|
||||||
|
prompt={item.prompt}
|
||||||
|
showLikeButton={showLikeButton}
|
||||||
|
audioBinary={item.audio_binary}
|
||||||
|
showLoudspeaker={showLoudspeaker}
|
||||||
|
showLog={showLog}
|
||||||
|
></AssistantGroupButton>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<UserGroupButton
|
||||||
|
content={item.content}
|
||||||
|
messageId={item.id}
|
||||||
|
removeMessageById={removeMessageById}
|
||||||
|
regenerateMessage={
|
||||||
|
regenerateMessage && handleRegenerateMessage
|
||||||
|
}
|
||||||
|
sendLoading={sendLoading}
|
||||||
|
></UserGroupButton>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* <b>{isAssistant ? '' : nickname}</b> */}
|
{/* <b>{isAssistant ? '' : nickname}</b> */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isAssistant &&
|
||||||
|
currentEventListWithoutMessageById &&
|
||||||
|
showThinking && (
|
||||||
|
<div className="mt-4 mb-4">
|
||||||
|
<WorkFlowTimeline
|
||||||
|
currentEventListWithoutMessage={currentEventListWithoutMessageById(
|
||||||
|
item.id,
|
||||||
|
)}
|
||||||
|
isShare={isShare}
|
||||||
|
currentMessageId={item.id}
|
||||||
|
canvasId={conversationId}
|
||||||
|
sendLoading={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className={cn({
|
className={cn({
|
||||||
[theme === 'dark'
|
[theme === 'dark'
|
||||||
@ -165,7 +232,7 @@ function MessageItem({
|
|||||||
{item.data ? (
|
{item.data ? (
|
||||||
children
|
children
|
||||||
) : sendLoading && isEmpty(item.content) ? (
|
) : sendLoading && isEmpty(item.content) ? (
|
||||||
'searching...'
|
<>{!isShare && 'running...'}</>
|
||||||
) : (
|
) : (
|
||||||
<MarkdownContent
|
<MarkdownContent
|
||||||
loading={loading}
|
loading={loading}
|
||||||
@ -180,18 +247,7 @@ function MessageItem({
|
|||||||
list={referenceDocuments}
|
list={referenceDocuments}
|
||||||
></ReferenceDocumentList>
|
></ReferenceDocumentList>
|
||||||
)}
|
)}
|
||||||
{isAssistant && currentEventListWithoutMessageById && (
|
|
||||||
<div className="mt-4">
|
|
||||||
<WorkFlowTimeline
|
|
||||||
currentEventListWithoutMessage={currentEventListWithoutMessageById(
|
|
||||||
item.id,
|
|
||||||
)}
|
|
||||||
currentMessageId={item.id}
|
|
||||||
canvasId={conversationId}
|
|
||||||
sendLoading={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{isUser && (
|
{isUser && (
|
||||||
<UploadedMessageFiles files={item.files}></UploadedMessageFiles>
|
<UploadedMessageFiles files={item.files}></UploadedMessageFiles>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ const buttonVariants = cva(
|
|||||||
'bg-colors-background-sentiment-solid-primary text-colors-text-persist-light hover:bg-colors-background-sentiment-solid-primary/80',
|
'bg-colors-background-sentiment-solid-primary text-colors-text-persist-light hover:bg-colors-background-sentiment-solid-primary/80',
|
||||||
icon: 'bg-colors-background-inverse-standard text-foreground hover:bg-colors-background-inverse-standard/80',
|
icon: 'bg-colors-background-inverse-standard text-foreground hover:bg-colors-background-inverse-standard/80',
|
||||||
dashed: 'border border-dashed border-input hover:bg-accent',
|
dashed: 'border border-dashed border-input hover:bg-accent',
|
||||||
|
transparent: 'bg-transparent hover:bg-accent border',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'h-8 px-2.5 py-1.5 ',
|
default: 'h-8 px-2.5 py-1.5 ',
|
||||||
|
|||||||
@ -36,6 +36,7 @@ export interface INodeData {
|
|||||||
error: null | string;
|
error: null | string;
|
||||||
elapsed_time: number;
|
elapsed_time: number;
|
||||||
created_at: number;
|
created_at: number;
|
||||||
|
thoughts: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInputData {
|
export interface IInputData {
|
||||||
|
|||||||
@ -1317,6 +1317,29 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
file: 'File upload',
|
file: 'File upload',
|
||||||
integer: 'Number',
|
integer: 'Number',
|
||||||
boolean: 'Boolean',
|
boolean: 'Boolean',
|
||||||
|
|
||||||
|
logTimeline: {
|
||||||
|
begin: 'Ready to begin',
|
||||||
|
agent: 'Agent is thinking',
|
||||||
|
retrieval: 'Looking up knowledge',
|
||||||
|
message: 'Agent says',
|
||||||
|
awaitResponse: 'Waiting for you',
|
||||||
|
switch: 'Choosing the best path',
|
||||||
|
iteration: 'Batch processing',
|
||||||
|
categorize: 'Categorising info',
|
||||||
|
code: 'Running a quick script',
|
||||||
|
textProcessing: 'Tidying up text',
|
||||||
|
tavilySearch: 'Searching the web',
|
||||||
|
tavilyExtract: 'Reading the page',
|
||||||
|
exeSQL: 'Querying database',
|
||||||
|
google: 'Searching the web',
|
||||||
|
wikipedia: 'Searching Wikipedia',
|
||||||
|
googleScholar: 'Academic search',
|
||||||
|
gitHub: 'Searching GitHub',
|
||||||
|
email: 'Sending email',
|
||||||
|
httpRequest: 'Calling an API',
|
||||||
|
wenCai: 'Querying financial data',
|
||||||
|
},
|
||||||
goto: 'Fail Branch',
|
goto: 'Fail Branch',
|
||||||
comment: 'Default Value',
|
comment: 'Default Value',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1261,6 +1261,28 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
import: '导入',
|
import: '导入',
|
||||||
export: '导出',
|
export: '导出',
|
||||||
subject: '主题',
|
subject: '主题',
|
||||||
|
logTimeline: {
|
||||||
|
begin: '准备开始',
|
||||||
|
agent: '智能体正在思考',
|
||||||
|
retrieval: '查找知识',
|
||||||
|
message: '回复',
|
||||||
|
awaitResponse: '等你输入',
|
||||||
|
switch: '选择最佳路线',
|
||||||
|
iteration: '批量处理',
|
||||||
|
categorize: '信息归类',
|
||||||
|
code: '运行小段代码',
|
||||||
|
textProcessing: '整理文字',
|
||||||
|
tavilySearch: '正在网上搜索',
|
||||||
|
tavilyExtract: '读取网页内容',
|
||||||
|
exeSQL: '查询数据库',
|
||||||
|
google: '正在网上搜索',
|
||||||
|
wikipedia: '搜索维基百科',
|
||||||
|
googleScholar: '学术检索',
|
||||||
|
gitHub: '搜索',
|
||||||
|
email: '发送邮件',
|
||||||
|
httpRequest: '请求接口',
|
||||||
|
wenCai: '查询财务数据',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
|||||||
@ -14,14 +14,20 @@ import {
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Operator } from '../constant';
|
import { Operator } from '../constant';
|
||||||
import OperatorIcon from '../operator-icon';
|
import OperatorIcon from '../operator-icon';
|
||||||
import { JsonViewer } from './workFlowTimeline';
|
import {
|
||||||
|
JsonViewer,
|
||||||
|
toLowerCaseStringAndDeleteChar,
|
||||||
|
typeMap,
|
||||||
|
} from './workFlowTimeline';
|
||||||
|
|
||||||
const ToolTimelineItem = ({
|
const ToolTimelineItem = ({
|
||||||
tools,
|
tools,
|
||||||
sendLoading = false,
|
sendLoading = false,
|
||||||
|
isShare = false,
|
||||||
}: {
|
}: {
|
||||||
tools: Record<string, any>[];
|
tools: Record<string, any>[];
|
||||||
sendLoading: boolean;
|
sendLoading: boolean;
|
||||||
|
isShare?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
if (!tools || tools.length === 0 || !Array.isArray(tools)) return null;
|
if (!tools || tools.length === 0 || !Array.isArray(tools)) return null;
|
||||||
const blackList = ['add_memory', 'gen_citations'];
|
const blackList = ['add_memory', 'gen_citations'];
|
||||||
@ -110,10 +116,23 @@ const ToolTimelineItem = ({
|
|||||||
<AccordionItem value={idx.toString()}>
|
<AccordionItem value={idx.toString()}>
|
||||||
<AccordionTrigger>
|
<AccordionTrigger>
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<span>
|
{!isShare && (
|
||||||
{parentName(tool.path) + ' '}
|
<span>
|
||||||
{capitalizeWords(tool.tool_name, '_')}
|
{parentName(tool.path) + ' '}
|
||||||
</span>
|
{capitalizeWords(tool.tool_name, '_')}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isShare && (
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
typeMap[
|
||||||
|
toLowerCaseStringAndDeleteChar(
|
||||||
|
tool.tool_name,
|
||||||
|
) as keyof typeof typeMap
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
<span className="text-text-sub-title text-xs">
|
<span className="text-text-sub-title text-xs">
|
||||||
{/* 0:00
|
{/* 0:00
|
||||||
{x.data.elapsed_time?.toString().slice(0, 6)} */}
|
{x.data.elapsed_time?.toString().slice(0, 6)} */}
|
||||||
@ -129,10 +148,18 @@ const ToolTimelineItem = ({
|
|||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent>
|
<AccordionContent>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<JsonViewer
|
{!isShare && (
|
||||||
data={tool.result}
|
<JsonViewer
|
||||||
title="content"
|
data={tool.result}
|
||||||
></JsonViewer>
|
title="content"
|
||||||
|
></JsonViewer>
|
||||||
|
)}
|
||||||
|
{isShare && (
|
||||||
|
<JsonViewer
|
||||||
|
data={tool.result}
|
||||||
|
title={''}
|
||||||
|
></JsonViewer>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import HightLightMarkdown from '@/components/highlight-markdown';
|
||||||
import {
|
import {
|
||||||
Timeline,
|
Timeline,
|
||||||
TimelineContent,
|
TimelineContent,
|
||||||
@ -31,7 +32,11 @@ import ToolTimelineItem from './toolTimelineItem';
|
|||||||
type LogFlowTimelineProps = Pick<
|
type LogFlowTimelineProps = Pick<
|
||||||
ReturnType<typeof useCacheChatLog>,
|
ReturnType<typeof useCacheChatLog>,
|
||||||
'currentEventListWithoutMessage' | 'currentMessageId'
|
'currentEventListWithoutMessage' | 'currentMessageId'
|
||||||
> & { canvasId?: string; sendLoading: boolean };
|
> & {
|
||||||
|
canvasId?: string;
|
||||||
|
sendLoading: boolean;
|
||||||
|
isShare?: boolean;
|
||||||
|
};
|
||||||
export function JsonViewer({
|
export function JsonViewer({
|
||||||
data,
|
data,
|
||||||
title,
|
title,
|
||||||
@ -46,12 +51,41 @@ export function JsonViewer({
|
|||||||
src={data}
|
src={data}
|
||||||
displaySize
|
displaySize
|
||||||
collapseStringsAfterLength={100000000000}
|
collapseStringsAfterLength={100000000000}
|
||||||
className="w-full h-[200px] break-words overflow-auto p-2 bg-background-card"
|
className="w-full h-[200px] break-words overflow-auto scrollbar-auto p-2 bg-slate-800"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export const typeMap = {
|
||||||
|
begin: t('flow.logTimeline.begin'),
|
||||||
|
agent: t('flow.logTimeline.agent'),
|
||||||
|
retrieval: t('flow.logTimeline.retrieval'),
|
||||||
|
message: t('flow.logTimeline.message'),
|
||||||
|
awaitResponse: t('flow.logTimeline.awaitResponse'),
|
||||||
|
switch: t('flow.logTimeline.switch'),
|
||||||
|
iteration: t('flow.logTimeline.iteration'),
|
||||||
|
categorize: t('flow.logTimeline.categorize'),
|
||||||
|
code: t('flow.logTimeline.code'),
|
||||||
|
textProcessing: t('flow.logTimeline.textProcessing'),
|
||||||
|
tavilySearch: t('flow.logTimeline.tavilySearch'),
|
||||||
|
tavilyExtract: t('flow.logTimeline.tavilyExtract'),
|
||||||
|
exeSQL: t('flow.logTimeline.exeSQL'),
|
||||||
|
google: t('flow.logTimeline.google'),
|
||||||
|
duckDuckGo: t('flow.logTimeline.google'),
|
||||||
|
wikipedia: t('flow.logTimeline.wikipedia'),
|
||||||
|
googleScholar: t('flow.logTimeline.googleScholar'),
|
||||||
|
arXiv: t('flow.logTimeline.googleScholar'),
|
||||||
|
pubMed: t('flow.logTimeline.googleScholar'),
|
||||||
|
gitHub: t('flow.logTimeline.gitHub'),
|
||||||
|
email: t('flow.logTimeline.email'),
|
||||||
|
httpRequest: t('flow.logTimeline.httpRequest'),
|
||||||
|
wenCai: t('flow.logTimeline.wenCai'),
|
||||||
|
yahooFinance: t('flow.logTimeline.yahooFinance'),
|
||||||
|
};
|
||||||
|
export const toLowerCaseStringAndDeleteChar = (
|
||||||
|
str: string,
|
||||||
|
char: string = '_',
|
||||||
|
) => str.toLowerCase().replace(/ /g, '').replaceAll(char, '');
|
||||||
function getInputsOrOutputs(
|
function getInputsOrOutputs(
|
||||||
nodeEventList: INodeData[],
|
nodeEventList: INodeData[],
|
||||||
field: 'inputs' | 'outputs',
|
field: 'inputs' | 'outputs',
|
||||||
@ -69,6 +103,7 @@ export const WorkFlowTimeline = ({
|
|||||||
currentMessageId,
|
currentMessageId,
|
||||||
canvasId,
|
canvasId,
|
||||||
sendLoading,
|
sendLoading,
|
||||||
|
isShare,
|
||||||
}: LogFlowTimelineProps) => {
|
}: LogFlowTimelineProps) => {
|
||||||
// const getNode = useGraphStore((state) => state.getNode);
|
// const getNode = useGraphStore((state) => state.getNode);
|
||||||
const [isStopFetchTrace, setISStopFetchTrace] = useState(false);
|
const [isStopFetchTrace, setISStopFetchTrace] = useState(false);
|
||||||
@ -146,6 +181,7 @@ export const WorkFlowTimeline = ({
|
|||||||
},
|
},
|
||||||
[currentEventListWithoutMessage],
|
[currentEventListWithoutMessage],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Timeline>
|
<Timeline>
|
||||||
{startedNodeList?.map((x, idx) => {
|
{startedNodeList?.map((x, idx) => {
|
||||||
@ -213,7 +249,15 @@ export const WorkFlowTimeline = ({
|
|||||||
<AccordionItem value={idx.toString()}>
|
<AccordionItem value={idx.toString()}>
|
||||||
<AccordionTrigger>
|
<AccordionTrigger>
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<span>{getNodeName(x.data?.component_name)}</span>
|
<span>
|
||||||
|
{!isShare && getNodeName(x.data?.component_name)}
|
||||||
|
{isShare &&
|
||||||
|
typeMap[
|
||||||
|
toLowerCaseStringAndDeleteChar(
|
||||||
|
nodeLabel,
|
||||||
|
) as keyof typeof typeMap
|
||||||
|
]}
|
||||||
|
</span>
|
||||||
<span className="text-text-sub-title text-xs">
|
<span className="text-text-sub-title text-xs">
|
||||||
{x.data.elapsed_time?.toString().slice(0, 6)}
|
{x.data.elapsed_time?.toString().slice(0, 6)}
|
||||||
</span>
|
</span>
|
||||||
@ -228,16 +272,36 @@ export const WorkFlowTimeline = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent>
|
{!isShare && (
|
||||||
<div className="space-y-2">
|
<AccordionContent>
|
||||||
<JsonViewer data={inputs} title="Input"></JsonViewer>
|
<div className="space-y-2">
|
||||||
|
{!isShare && (
|
||||||
|
<>
|
||||||
|
<JsonViewer
|
||||||
|
data={inputs}
|
||||||
|
title="Input"
|
||||||
|
></JsonViewer>
|
||||||
|
|
||||||
<JsonViewer
|
<JsonViewer
|
||||||
data={outputs}
|
data={outputs}
|
||||||
title={'Output'}
|
title={'Output'}
|
||||||
></JsonViewer>
|
></JsonViewer>
|
||||||
</div>
|
</>
|
||||||
</AccordionContent>
|
)}
|
||||||
|
</div>
|
||||||
|
</AccordionContent>
|
||||||
|
)}
|
||||||
|
{isShare && x.data?.thoughts && (
|
||||||
|
<AccordionContent>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="w-full h-[200px] break-words overflow-auto scrollbar-auto p-2 bg-slate-800">
|
||||||
|
<HightLightMarkdown>
|
||||||
|
{x.data.thoughts || ''}
|
||||||
|
</HightLightMarkdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AccordionContent>
|
||||||
|
)}
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</section>
|
</section>
|
||||||
@ -248,6 +312,7 @@ export const WorkFlowTimeline = ({
|
|||||||
key={'tool_' + idx}
|
key={'tool_' + idx}
|
||||||
tools={filterTrace(x.data.component_id)}
|
tools={filterTrace(x.data.component_id)}
|
||||||
sendLoading={sendLoading}
|
sendLoading={sendLoading}
|
||||||
|
isShare={isShare}
|
||||||
></ToolTimelineItem>
|
></ToolTimelineItem>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -25,21 +25,25 @@ export const AgentLogDetailModal: React.FC<CustomModalProps> = ({
|
|||||||
const { data: canvasInfo } = useFetchAgent();
|
const { data: canvasInfo } = useFetchAgent();
|
||||||
|
|
||||||
const shortMessage = useMemo(() => {
|
const shortMessage = useMemo(() => {
|
||||||
const content = derivedMessages[0]?.content || '';
|
if (derivedMessages?.length) {
|
||||||
|
const content = derivedMessages[0]?.content || '';
|
||||||
|
|
||||||
const chineseCharCount = (content.match(/[\u4e00-\u9fa5]/g) || []).length;
|
const chineseCharCount = (content.match(/[\u4e00-\u9fa5]/g) || []).length;
|
||||||
const totalLength = content.length;
|
const totalLength = content.length;
|
||||||
|
|
||||||
if (chineseCharCount > 0) {
|
if (chineseCharCount > 0) {
|
||||||
if (totalLength > 15) {
|
if (totalLength > 15) {
|
||||||
return content.substring(0, 15) + '...';
|
return content.substring(0, 15) + '...';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (totalLength > 30) {
|
||||||
|
return content.substring(0, 30) + '...';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return content;
|
||||||
} else {
|
} else {
|
||||||
if (totalLength > 30) {
|
return '';
|
||||||
return content.substring(0, 30) + '...';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return content;
|
|
||||||
}, [derivedMessages]);
|
}, [derivedMessages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -52,7 +56,7 @@ export const AgentLogDetailModal: React.FC<CustomModalProps> = ({
|
|||||||
className="!w-[900px]"
|
className="!w-[900px]"
|
||||||
>
|
>
|
||||||
<div className="flex items-start mb-4 flex-col gap-4 justify-start">
|
<div className="flex items-start mb-4 flex-col gap-4 justify-start">
|
||||||
<div>
|
<div className="w-full">
|
||||||
{derivedMessages?.map((message, i) => {
|
{derivedMessages?.map((message, i) => {
|
||||||
return (
|
return (
|
||||||
<MessageItem
|
<MessageItem
|
||||||
|
|||||||
@ -147,7 +147,7 @@ const AgentLogPage: React.FC = () => {
|
|||||||
setPagination((pre) => {
|
setPagination((pre) => {
|
||||||
return {
|
return {
|
||||||
...pre,
|
...pre,
|
||||||
current: current ?? pre.current,
|
current: current ?? pre.pageSize ? 1 : pre.current,
|
||||||
pageSize: pageSize ?? pre.pageSize,
|
pageSize: pageSize ?? pre.pageSize,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -196,8 +196,10 @@ const AgentLogPage: React.FC = () => {
|
|||||||
const [openModal, setOpenModal] = useState(false);
|
const [openModal, setOpenModal] = useState(false);
|
||||||
const [modalData, setModalData] = useState<IAgentLogResponse>();
|
const [modalData, setModalData] = useState<IAgentLogResponse>();
|
||||||
const showLogDetail = (item: IAgentLogResponse) => {
|
const showLogDetail = (item: IAgentLogResponse) => {
|
||||||
setModalData(item);
|
if (item?.round) {
|
||||||
setOpenModal(true);
|
setModalData(item);
|
||||||
|
setOpenModal(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { useSetModalState } from '@/hooks/common-hooks';
|
|||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { useFetchAgentTemplates, useSetAgent } from '@/hooks/use-agent-request';
|
import { useFetchAgentTemplates, useSetAgent } from '@/hooks/use-agent-request';
|
||||||
import { IFlowTemplate } from '@/interfaces/database/flow';
|
import { IFlowTemplate } from '@/interfaces/database/flow';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { CreateAgentDialog } from './create-agent-dialog';
|
import { CreateAgentDialog } from './create-agent-dialog';
|
||||||
import { TemplateCard } from './template-card';
|
import { TemplateCard } from './template-card';
|
||||||
@ -70,15 +70,19 @@ export default function AgentTemplates() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
const handleSiderBarChange = (keyword: string) => {
|
const handleSiderBarChange = (keyword: string) => {
|
||||||
const tempList = list.filter(
|
|
||||||
(item, index) =>
|
|
||||||
item.canvas_type
|
|
||||||
?.toLocaleLowerCase()
|
|
||||||
.includes(keyword?.toLocaleLowerCase()) || index === 0,
|
|
||||||
);
|
|
||||||
setTemplateList(tempList);
|
|
||||||
setSelectMenuItem(keyword);
|
setSelectMenuItem(keyword);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tempListFilter = useMemo(() => {
|
||||||
|
if (!selectMenuItem) {
|
||||||
|
return templateList;
|
||||||
|
}
|
||||||
|
return templateList.filter(
|
||||||
|
(item, index) =>
|
||||||
|
item.canvas_type?.toLocaleLowerCase() ===
|
||||||
|
selectMenuItem?.toLocaleLowerCase() || index === 0,
|
||||||
|
);
|
||||||
|
}, [selectMenuItem, templateList]);
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
@ -104,7 +108,7 @@ export default function AgentTemplates() {
|
|||||||
|
|
||||||
<main className="flex-1 bg-text-title-invert/50 h-dvh">
|
<main className="flex-1 bg-text-title-invert/50 h-dvh">
|
||||||
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[94vh] overflow-auto px-8 pt-8">
|
<div className="grid gap-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 max-h-[94vh] overflow-auto px-8 pt-8">
|
||||||
{templateList?.map((x, index) => {
|
{tempListFilter?.map((x, index) => {
|
||||||
return (
|
return (
|
||||||
<TemplateCard
|
<TemplateCard
|
||||||
isCreate={index === 0}
|
isCreate={index === 0}
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import { ParameterDialog } from './parameter-dialog';
|
|||||||
const ChatContainer = () => {
|
const ChatContainer = () => {
|
||||||
const {
|
const {
|
||||||
sharedId: conversationId,
|
sharedId: conversationId,
|
||||||
from,
|
|
||||||
locale,
|
locale,
|
||||||
visibleAvatar,
|
visibleAvatar,
|
||||||
} = useGetSharedChatSearchParams();
|
} = useGetSharedChatSearchParams();
|
||||||
@ -61,7 +60,6 @@ const ChatContainer = () => {
|
|||||||
resetSession,
|
resetSession,
|
||||||
} = useSendNextSharedMessage(addEventList);
|
} = useSendNextSharedMessage(addEventList);
|
||||||
|
|
||||||
// const { data } = useFetchExternalAgentInputs();
|
|
||||||
const sendDisabled = useSendButtonDisabled(value);
|
const sendDisabled = useSendButtonDisabled(value);
|
||||||
const appConf = useFetchAppConf();
|
const appConf = useFetchAppConf();
|
||||||
const { data: inputsData } = useFetchExternalAgentInputs();
|
const { data: inputsData } = useFetchExternalAgentInputs();
|
||||||
@ -95,7 +93,7 @@ const ChatContainer = () => {
|
|||||||
}, [inputsData, setAgentInfo]);
|
}, [inputsData, setAgentInfo]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!isEmpty(inputsData)) {
|
if (inputsData && inputsData.inputs && !isEmpty(inputsData.inputs)) {
|
||||||
showParameterDialog();
|
showParameterDialog();
|
||||||
}
|
}
|
||||||
}, [inputsData, showParameterDialog]);
|
}, [inputsData, showParameterDialog]);
|
||||||
@ -141,7 +139,9 @@ const ChatContainer = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 flex-col p-2.5 h-[90vh] m-3">
|
<div className="flex flex-1 flex-col p-2.5 h-[90vh] m-3">
|
||||||
<div
|
<div
|
||||||
className={cn('flex flex-1 flex-col overflow-auto m-auto w-5/6')}
|
className={cn(
|
||||||
|
'flex flex-1 flex-col overflow-auto scrollbar-auto m-auto w-5/6',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{derivedMessages?.map((message, i) => {
|
{derivedMessages?.map((message, i) => {
|
||||||
@ -162,6 +162,7 @@ const ChatContainer = () => {
|
|||||||
sendLoading &&
|
sendLoading &&
|
||||||
derivedMessages?.length - 1 === i
|
derivedMessages?.length - 1 === i
|
||||||
}
|
}
|
||||||
|
isShare={true}
|
||||||
avatarDialog={agentInfo.avatar}
|
avatarDialog={agentInfo.avatar}
|
||||||
agentName={agentInfo.title}
|
agentName={agentInfo.title}
|
||||||
index={i}
|
index={i}
|
||||||
|
|||||||
@ -239,3 +239,38 @@
|
|||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.scrollbar-auto {
|
||||||
|
/* hide scrollbar */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-auto::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-auto::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-auto::-webkit-scrollbar-thumb {
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-auto:hover::-webkit-scrollbar-thumb,
|
||||||
|
.scrollbar-auto:focus::-webkit-scrollbar-thumb,
|
||||||
|
.scrollbar-auto:active::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .scrollbar-auto:hover::-webkit-scrollbar-thumb,
|
||||||
|
.dark .scrollbar-auto:focus::-webkit-scrollbar-thumb,
|
||||||
|
.dark .scrollbar-auto:active::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user