Fix: Improve Agent templates functionality and fix some UI style issues (#9129)

### What problem does this PR solve?

Fix: Improve Agent templates functionality and fix some UI style issues
#3221

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2025-07-31 16:09:45 +08:00
committed by GitHub
parent 3f6177b5e5
commit 26042343d8
14 changed files with 173 additions and 70 deletions

View File

@ -14,12 +14,13 @@ type LogSheetProps = IModalProps<any> &
Pick<
ReturnType<typeof useCacheChatLog>,
'currentEventListWithoutMessageById' | 'currentMessageId'
>;
> & { sendLoading: boolean };
export function LogSheet({
hideModal,
currentEventListWithoutMessageById,
currentMessageId,
sendLoading,
}: LogSheetProps) {
return (
<Sheet open onOpenChange={hideModal} modal={false}>
@ -36,6 +37,7 @@ export function LogSheet({
currentMessageId,
)}
currentMessageId={currentMessageId}
sendLoading={sendLoading}
/>
</section>
</SheetContent>

View File

@ -16,7 +16,13 @@ import { Operator } from '../constant';
import OperatorIcon from '../operator-icon';
import { JsonViewer } from './workFlowTimeline';
const ToolTimelineItem = ({ tools }: { tools: Record<string, any>[] }) => {
const ToolTimelineItem = ({
tools,
sendLoading = false,
}: {
tools: Record<string, any>[];
sendLoading: boolean;
}) => {
if (!tools || tools.length === 0 || !Array.isArray(tools)) return null;
const blackList = ['add_memory', 'gen_citations'];
const filteredTools = tools.filter(
@ -32,6 +38,15 @@ const ToolTimelineItem = ({ tools }: { tools: Record<string, any>[] }) => {
})
.join(' ');
};
const parentName = (str: string, separator: string = '-->') => {
if (!str) return '';
const strs = str.split(separator);
if (strs.length > 1) {
return strs[strs.length - 1];
} else {
return str;
}
};
return (
<>
{filteredTools?.map((tool, idx) => {
@ -58,7 +73,9 @@ const ToolTimelineItem = ({ tools }: { tools: Record<string, any>[] }) => {
'group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 p-1 items-center justify-center group-data-[orientation=vertical]/timeline:-left-7',
{
'border border-blue-500': !(
idx >= filteredTools.length - 1 && tool.result === '...'
idx >= filteredTools.length - 1 &&
tool.result === '...' &&
sendLoading
),
},
)}
@ -69,7 +86,8 @@ const ToolTimelineItem = ({ tools }: { tools: Record<string, any>[] }) => {
className={cn('rounded-full w-6 h-6', {
' border-muted-foreground border-2 border-t-transparent animate-spin ':
idx >= filteredTools.length - 1 &&
tool.result === '...',
tool.result === '...' &&
sendLoading,
})}
></div>
</div>
@ -93,7 +111,7 @@ const ToolTimelineItem = ({ tools }: { tools: Record<string, any>[] }) => {
<AccordionTrigger>
<div className="flex gap-2 items-center">
<span>
{tool.path + ' '}
{parentName(tool.path) + ' '}
{capitalizeWords(tool.tool_name, '_')}
</span>
<span className="text-text-sub-title text-xs">

View File

@ -20,6 +20,7 @@ import {
} from '@/hooks/use-send-message';
import { ITraceData } from '@/interfaces/database/agent';
import { cn } from '@/lib/utils';
import { t } from 'i18next';
import { get } from 'lodash';
import { useCallback, useEffect, useMemo, useState } from 'react';
import JsonView from 'react18-json-view';
@ -30,7 +31,7 @@ import ToolTimelineItem from './toolTimelineItem';
type LogFlowTimelineProps = Pick<
ReturnType<typeof useCacheChatLog>,
'currentEventListWithoutMessage' | 'currentMessageId'
> & { canvasId?: string };
> & { canvasId?: string; sendLoading: boolean };
export function JsonViewer({
data,
title,
@ -67,6 +68,7 @@ export const WorkFlowTimeline = ({
currentEventListWithoutMessage,
currentMessageId,
canvasId,
sendLoading,
}: LogFlowTimelineProps) => {
// const getNode = useGraphStore((state) => state.getNode);
const [isStopFetchTrace, setISStopFetchTrace] = useState(false);
@ -79,31 +81,20 @@ export const WorkFlowTimeline = ({
useEffect(() => {
setMessageId(currentMessageId);
}, [currentMessageId, setMessageId]);
// const getNodeName = useCallback(
// (nodeId: string) => {
// if ('begin' === nodeId) return t('flow.begin');
// return getNode(nodeId)?.data.name;
// },
// [getNode],
// );
// const getNodeById = useCallback(
// (nodeId: string) => {
// const data = currentEventListWithoutMessage
// .map((x) => x.data)
// .filter((x) => x.component_id === nodeId);
// if ('begin' === nodeId) return t('flow.begin');
// if (data && data.length) {
// return data[0];
// }
// return {};
// },
// [currentEventListWithoutMessage],
// );
const getNodeName = (nodeId: string) => {
if ('begin' === nodeId) return t('flow.begin');
return nodeId;
};
useEffect(() => {
setISStopFetchTrace(!sendLoading);
}, [sendLoading]);
const startedNodeList = useMemo(() => {
const finish = currentEventListWithoutMessage?.some(
(item) => item.event === MessageEventType.WorkflowFinished,
);
setISStopFetchTrace(finish);
setISStopFetchTrace(finish || !sendLoading);
const duplicateList = currentEventListWithoutMessage?.filter(
(x) => x.event === MessageEventType.NodeStarted,
) as INodeEvent[];
@ -115,7 +106,7 @@ export const WorkFlowTimeline = ({
}
return pre;
}, []);
}, [currentEventListWithoutMessage]);
}, [currentEventListWithoutMessage, sendLoading]);
const hasTrace = useCallback(
(componentId: string) => {
@ -198,7 +189,8 @@ export const WorkFlowTimeline = ({
<div
className={cn('rounded-full w-6 h-6', {
' border-muted-foreground border-2 border-t-transparent animate-spin ':
!finishNodeIds.includes(x.data.component_id),
!finishNodeIds.includes(x.data.component_id) &&
sendLoading,
})}
></div>
</div>
@ -212,7 +204,7 @@ export const WorkFlowTimeline = ({
</TimelineIndicator>
</TimelineHeader>
<TimelineContent className="text-foreground rounded-lg border mb-5">
<section key={idx}>
<section key={'content_' + idx}>
<Accordion
type="single"
collapsible
@ -221,7 +213,7 @@ export const WorkFlowTimeline = ({
<AccordionItem value={idx.toString()}>
<AccordionTrigger>
<div className="flex gap-2 items-center">
<span>{x.data?.component_name}</span>
<span>{getNodeName(x.data?.component_name)}</span>
<span className="text-text-sub-title text-xs">
{x.data.elapsed_time?.toString().slice(0, 6)}
</span>
@ -253,7 +245,9 @@ export const WorkFlowTimeline = ({
</TimelineItem>
{hasTrace(x.data.component_id) && (
<ToolTimelineItem
key={'tool_' + idx}
tools={filterTrace(x.data.component_id)}
sendLoading={sendLoading}
></ToolTimelineItem>
)}
</>