diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index b357c2cb49..2b8530696a 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -355,7 +355,7 @@ function Form< label={label[language] || label.en_US} required={required} tooltip={tooltip?.[language] || tooltip?.en_US} - value={value[variable]} + value={value[variable] || []} onChange={item => handleFormChange(variable, item as any)} /> {fieldMoreInfo?.(formSchema)} diff --git a/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx index 6adf26ee79..036aa098ea 100644 --- a/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx @@ -25,7 +25,7 @@ type Props = { const MultipleToolSelector = ({ disabled, - value, + value = [], label, required, tooltip, diff --git a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx index c156aac671..ce0613dedf 100644 --- a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx +++ b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx @@ -179,7 +179,7 @@ export const AgentStrategy = (props: AgentStrategyProps) => { return ( void } const AgentLogItem = ({ item, + onShowAgentOrToolLog, }: AgentLogItemProps) => { const { label, @@ -51,7 +53,7 @@ const AgentLogItem = ({ -
/
- + { + !!options.length && ( + <> +
/
+ + + ) + }
/
Run Actions diff --git a/web/app/components/workflow/run/agent-log/agent-log-trigger.tsx b/web/app/components/workflow/run/agent-log/agent-log-trigger.tsx index d50b5b4c55..825f59f085 100644 --- a/web/app/components/workflow/run/agent-log/agent-log-trigger.tsx +++ b/web/app/components/workflow/run/agent-log/agent-log-trigger.tsx @@ -6,11 +6,11 @@ import type { type AgentLogTriggerProps = { nodeInfo: NodeTracing - onShowAgentResultList: (agentLogs: AgentLogItemWithChildren[]) => void + onShowAgentOrToolLog: (detail?: AgentLogItemWithChildren) => void } const AgentLogTrigger = ({ nodeInfo, - onShowAgentResultList, + onShowAgentOrToolLog, }: AgentLogTriggerProps) => { const { agentLog } = nodeInfo @@ -24,7 +24,7 @@ const AgentLogTrigger = ({
onShowAgentResultList(agentLog || [])} + onClick={() => onShowAgentOrToolLog({ id: nodeInfo.id, children: agentLog || [] } as AgentLogItemWithChildren)} > Detail diff --git a/web/app/components/workflow/run/agent-log/agent-result-panel.tsx b/web/app/components/workflow/run/agent-log/agent-result-panel.tsx index 79b207c657..3028384f4a 100644 --- a/web/app/components/workflow/run/agent-log/agent-result-panel.tsx +++ b/web/app/components/workflow/run/agent-log/agent-result-panel.tsx @@ -3,15 +3,24 @@ import AgentLogNav from './agent-log-nav' import type { AgentLogItemWithChildren } from '@/types/workflow' type AgentResultPanelProps = { - list: AgentLogItemWithChildren[] - setAgentResultList: (list: AgentLogItemWithChildren[]) => void + agentOrToolLogItemStack: { id: string; label: string }[] + agentOrToolLogListMap: Record + onShowAgentOrToolLog: (detail?: AgentLogItemWithChildren) => void } const AgentResultPanel = ({ - list, + agentOrToolLogItemStack, + agentOrToolLogListMap, + onShowAgentOrToolLog, }: AgentResultPanelProps) => { + const top = agentOrToolLogItemStack[agentOrToolLogItemStack.length - 1] + const list = agentOrToolLogListMap[top.id] + return (
- + {
{ @@ -19,6 +28,7 @@ const AgentResultPanel = ({ )) } diff --git a/web/app/components/workflow/run/hooks.ts b/web/app/components/workflow/run/hooks.ts index 9b835202f6..b9c879a204 100644 --- a/web/app/components/workflow/run/hooks.ts +++ b/web/app/components/workflow/run/hooks.ts @@ -1,5 +1,6 @@ import { useCallback, + useRef, useState, } from 'react' import { useBoolean } from 'ahooks' @@ -32,10 +33,38 @@ export const useLogs = () => { setIterationResultDurationMap(iterDurationMap) }, [setShowIteratingDetailTrue, setIterationResultList, setIterationResultDurationMap]) - const [agentResultList, setAgentResultList] = useState([]) + const [agentOrToolLogItemStack, setAgentOrToolLogItemStack] = useState<{ id: string; label: string }[]>([]) + const agentOrToolLogItemStackRef = useRef(agentOrToolLogItemStack) + const [agentOrToolLogListMap, setAgentOrToolLogListMap] = useState>({}) + const agentOrToolLogListMapRef = useRef(agentOrToolLogListMap) + const handleShowAgentOrToolLog = useCallback((detail?: AgentLogItemWithChildren) => { + if (!detail) { + setAgentOrToolLogItemStack([]) + agentOrToolLogItemStackRef.current = [] + return + } + const { id, label, children } = detail + let currentAgentOrToolLogItemStack = agentOrToolLogItemStackRef.current.slice() + const index = currentAgentOrToolLogItemStack.findIndex(logItem => logItem.id === id) + + if (index > -1) + currentAgentOrToolLogItemStack = currentAgentOrToolLogItemStack.slice(0, index + 1) + else + currentAgentOrToolLogItemStack = [...currentAgentOrToolLogItemStack.slice(), { id, label }] + + setAgentOrToolLogItemStack(currentAgentOrToolLogItemStack) + agentOrToolLogItemStackRef.current = currentAgentOrToolLogItemStack + + if (children) { + setAgentOrToolLogListMap({ + ...agentOrToolLogListMapRef.current, + [id]: children, + }) + } + }, [setAgentOrToolLogItemStack, setAgentOrToolLogListMap]) return { - showSpecialResultPanel: showRetryDetail || showIteratingDetail || !!agentResultList.length, + showSpecialResultPanel: showRetryDetail || showIteratingDetail || !!agentOrToolLogItemStack.length, showRetryDetail, setShowRetryDetailTrue, setShowRetryDetailFalse, @@ -52,7 +81,8 @@ export const useLogs = () => { setIterationResultDurationMap, handleShowIterationResultList, - agentResultList, - setAgentResultList, + agentOrToolLogItemStack, + agentOrToolLogListMap, + handleShowAgentOrToolLog, } } diff --git a/web/app/components/workflow/run/node.tsx b/web/app/components/workflow/run/node.tsx index b35e3d89bc..2fdab2bb7b 100644 --- a/web/app/components/workflow/run/node.tsx +++ b/web/app/components/workflow/run/node.tsx @@ -34,7 +34,7 @@ type Props = { hideProcessDetail?: boolean onShowIterationDetail?: (detail: NodeTracing[][], iterDurationMap: IterationDurationMap) => void onShowRetryDetail?: (detail: NodeTracing[]) => void - onShowAgentResultList?: (detail: AgentLogItemWithChildren[]) => void + onShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void notShowIterationNav?: boolean } @@ -46,7 +46,7 @@ const NodePanel: FC = ({ hideProcessDetail, onShowIterationDetail, onShowRetryDetail, - onShowAgentResultList, + onShowAgentOrToolLog, notShowIterationNav, }) => { const [collapseState, doSetCollapseState] = useState(true) @@ -144,10 +144,10 @@ const NodePanel: FC = ({ /> )} { - isAgentNode && onShowAgentResultList && ( + isAgentNode && onShowAgentOrToolLog && ( ) } diff --git a/web/app/components/workflow/run/result-panel.tsx b/web/app/components/workflow/run/result-panel.tsx index ce86c73b9f..a39bfe40ab 100644 --- a/web/app/components/workflow/run/result-panel.tsx +++ b/web/app/components/workflow/run/result-panel.tsx @@ -6,7 +6,10 @@ import MetaData from './meta' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip' -import type { NodeTracing } from '@/types/workflow' +import type { + AgentLogItemWithChildren, + NodeTracing, +} from '@/types/workflow' import { BlockEnum } from '@/app/components/workflow/types' import { hasRetryNode } from '@/app/components/workflow/utils' import { IterationLogTrigger } from '@/app/components/workflow/run/iteration-log' @@ -31,7 +34,7 @@ type ResultPanelProps = { execution_metadata?: any handleShowIterationResultList?: (detail: NodeTracing[][], iterDurationMap: any) => void onShowRetryDetail?: (detail: NodeTracing[]) => void - onShowAgentResultList?: () => void + handleShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void } const ResultPanel: FC = ({ @@ -51,7 +54,7 @@ const ResultPanel: FC = ({ execution_metadata, handleShowIterationResultList, onShowRetryDetail, - onShowAgentResultList, + handleShowAgentOrToolLog, }) => { const { t } = useTranslation() const isIterationNode = nodeInfo?.node_type === BlockEnum.Iteration @@ -87,10 +90,10 @@ const ResultPanel: FC = ({ ) } { - isAgentNode && onShowAgentResultList && ( + isAgentNode && handleShowAgentOrToolLog && ( ) } diff --git a/web/app/components/workflow/run/special-result-panel.tsx b/web/app/components/workflow/run/special-result-panel.tsx index 4bf125b15e..f32487146d 100644 --- a/web/app/components/workflow/run/special-result-panel.tsx +++ b/web/app/components/workflow/run/special-result-panel.tsx @@ -17,8 +17,9 @@ export type SpecialResultPanelProps = { iterationResultList?: NodeTracing[][] iterationResultDurationMap?: IterationDurationMap - agentResultList?: AgentLogItemWithChildren[] - setAgentResultList?: (list: AgentLogItemWithChildren[]) => void + agentOrToolLogItemStack?: { id: string; label: string }[] + agentOrToolLogListMap?: Record + handleShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void } const SpecialResultPanel = ({ showRetryDetail, @@ -30,8 +31,9 @@ const SpecialResultPanel = ({ iterationResultList, iterationResultDurationMap, - agentResultList, - setAgentResultList, + agentOrToolLogItemStack, + agentOrToolLogListMap, + handleShowAgentOrToolLog, }: SpecialResultPanelProps) => { return ( <> @@ -53,10 +55,11 @@ const SpecialResultPanel = ({ ) } { - !!agentResultList?.length && setAgentResultList && ( + !!agentOrToolLogItemStack?.length && agentOrToolLogListMap && handleShowAgentOrToolLog && ( ) } diff --git a/web/app/components/workflow/run/tracing-panel.tsx b/web/app/components/workflow/run/tracing-panel.tsx index 29b8838825..d65b7b73eb 100644 --- a/web/app/components/workflow/run/tracing-panel.tsx +++ b/web/app/components/workflow/run/tracing-panel.tsx @@ -79,8 +79,9 @@ const TracingPanel: FC = ({ iterationResultDurationMap, handleShowIterationResultList, - agentResultList, - setAgentResultList, + agentOrToolLogItemStack, + agentOrToolLogListMap, + handleShowAgentOrToolLog, } = useLogs() const renderNode = (node: NodeTracing) => { @@ -136,7 +137,7 @@ const TracingPanel: FC = ({ nodeInfo={node!} onShowIterationDetail={handleShowIterationResultList} onShowRetryDetail={handleShowRetryResultList} - onShowAgentResultList={setAgentResultList} + onShowAgentOrToolLog={handleShowAgentOrToolLog} hideInfo={hideNodeInfo} hideProcessDetail={hideNodeProcessDetail} /> @@ -157,8 +158,9 @@ const TracingPanel: FC = ({ iterationResultList={iterationResultList} iterationResultDurationMap={iterationResultDurationMap} - agentResultList={agentResultList} - setAgentResultList={setAgentResultList} + agentOrToolLogItemStack={agentOrToolLogItemStack} + agentOrToolLogListMap={agentOrToolLogListMap} + handleShowAgentOrToolLog={handleShowAgentOrToolLog} /> ) } diff --git a/web/app/components/workflow/run/utils/format-log/index.ts b/web/app/components/workflow/run/utils/format-log/index.ts index 6beae5eb2b..4e8f6c33c2 100644 --- a/web/app/components/workflow/run/utils/format-log/index.ts +++ b/web/app/components/workflow/run/utils/format-log/index.ts @@ -3,9 +3,10 @@ import formatIterationNode from './iteration' import formatParallelNode from './parallel' import formatRetryNode from './retry' import formatAgentNode from './agent' +import { cloneDeep } from 'lodash-es' const formatToTracingNodeList = (list: NodeTracing[], t: any) => { - const allItems = [...list].sort((a, b) => a.index - b.index) + const allItems = cloneDeep([...list]).sort((a, b) => a.index - b.index) /* * First handle not change list structure node * Because Handle struct node will put the node in different diff --git a/web/app/components/workflow/run/utils/format-log/parallel/index.ts b/web/app/components/workflow/run/utils/format-log/parallel/index.ts index 9501eec7ec..245337dc0c 100644 --- a/web/app/components/workflow/run/utils/format-log/parallel/index.ts +++ b/web/app/components/workflow/run/utils/format-log/parallel/index.ts @@ -69,8 +69,10 @@ function addTitle({ } // list => group by parallel_id(parallel tree). -const format = (list: NodeTracing[], t: any): NodeTracing[] => { - // console.log(list) +const format = (list: NodeTracing[], t: any, isPrint?: boolean): NodeTracing[] => { + if (isPrint) + console.log(list) + const result: NodeTracing[] = [...list] const parallelFirstNodeMap: Record = {} // list to tree by parent_parallel_start_node_id and branch by parallel_start_node_id. Each parallel may has more than one branch. @@ -119,6 +121,7 @@ const format = (list: NodeTracing[], t: any): NodeTracing[] => { // append to parallel start node and after the same branch const parallelStartNode = result.find(item => item.node_id === parallelFirstNodeMap[parallel_id]) + if (parallelStartNode && parallelStartNode.parallelDetail && parallelStartNode!.parallelDetail!.children) { const sameBranchNodesLastIndex = parallelStartNode.parallelDetail.children.findLastIndex((node) => { const currStartNodeId = node.parallel_start_node_id ?? node.execution_metadata?.parallel_start_node_id ?? null @@ -153,12 +156,14 @@ const format = (list: NodeTracing[], t: any): NodeTracing[] => { }) // print node structure for debug - // filteredInParallelSubNodes.forEach((node) => { - // const now = Date.now() - // console.log(`----- p: ${now} start -----`) - // printNodeStructure(node, 0) - // console.log(`----- p: ${now} end -----`) - // }) + if (isPrint) { + filteredInParallelSubNodes.forEach((node) => { + const now = Date.now() + console.log(`----- p: ${now} start -----`) + printNodeStructure(node, 0) + console.log(`----- p: ${now} end -----`) + }) + } addTitle({ list: filteredInParallelSubNodes,