mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 09:58:04 +08:00
Merge branch 'feat/llm-support-tools' into feat/support-agent-sandbox
This commit is contained in:
@ -161,6 +161,10 @@ export const LLM_OUTPUT_STRUCT: Var[] = [
|
||||
variable: 'usage',
|
||||
type: VarType.object,
|
||||
},
|
||||
{
|
||||
variable: 'generation',
|
||||
type: VarType.object,
|
||||
},
|
||||
]
|
||||
|
||||
export const KNOWLEDGE_RETRIEVAL_OUTPUT_STRUCT: Var[] = [
|
||||
|
||||
@ -336,6 +336,11 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
|
||||
type="object"
|
||||
description={t(`${i18nPrefix}.outputVars.usage`, { ns: 'workflow' })}
|
||||
/>
|
||||
<VarItem
|
||||
name="generation"
|
||||
type="object"
|
||||
description={t(`${i18nPrefix}.outputVars.generation`, { ns: 'workflow' })}
|
||||
/>
|
||||
{inputs.structured_output_enabled && (
|
||||
<>
|
||||
<Split className="mt-3" />
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { v4 as uuidV4 } from 'uuid'
|
||||
import {
|
||||
getProcessedInputs,
|
||||
processOpeningStatement,
|
||||
@ -266,13 +267,78 @@ export const useChat = (
|
||||
}
|
||||
|
||||
let hasSetResponseId = false
|
||||
let toolCallId = ''
|
||||
let thoughtId = ''
|
||||
|
||||
handleRun(
|
||||
bodyParams,
|
||||
{
|
||||
onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId, taskId }: any) => {
|
||||
onData: (message: string, isFirstMessage: boolean, {
|
||||
conversationId: newConversationId,
|
||||
messageId,
|
||||
taskId,
|
||||
chunk_type,
|
||||
tool_icon,
|
||||
tool_icon_dark,
|
||||
tool_name,
|
||||
tool_arguments,
|
||||
tool_files,
|
||||
tool_error,
|
||||
tool_elapsed_time,
|
||||
}: any) => {
|
||||
responseItem.content = responseItem.content + message
|
||||
|
||||
if (chunk_type === 'tool_call') {
|
||||
if (!responseItem.toolCalls)
|
||||
responseItem.toolCalls = []
|
||||
toolCallId = uuidV4()
|
||||
responseItem.toolCalls?.push({
|
||||
id: toolCallId,
|
||||
type: 'tool',
|
||||
toolName: tool_name,
|
||||
toolArguments: tool_arguments,
|
||||
toolIcon: tool_icon,
|
||||
toolIconDark: tool_icon_dark,
|
||||
})
|
||||
}
|
||||
|
||||
if (chunk_type === 'tool_result') {
|
||||
const currentToolCallIndex = responseItem.toolCalls?.findIndex(item => item.id === toolCallId) ?? -1
|
||||
|
||||
if (currentToolCallIndex > -1) {
|
||||
responseItem.toolCalls![currentToolCallIndex].toolError = tool_error
|
||||
responseItem.toolCalls![currentToolCallIndex].toolDuration = tool_elapsed_time
|
||||
responseItem.toolCalls![currentToolCallIndex].toolFiles = tool_files
|
||||
responseItem.toolCalls![currentToolCallIndex].toolOutput = message
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk_type === 'thought_start') {
|
||||
if (!responseItem.toolCalls)
|
||||
responseItem.toolCalls = []
|
||||
thoughtId = uuidV4()
|
||||
responseItem.toolCalls.push({
|
||||
id: thoughtId,
|
||||
type: 'thought',
|
||||
thoughtOutput: '',
|
||||
})
|
||||
}
|
||||
|
||||
if (chunk_type === 'thought') {
|
||||
const currentThoughtIndex = responseItem.toolCalls?.findIndex(item => item.id === thoughtId) ?? -1
|
||||
if (currentThoughtIndex > -1) {
|
||||
responseItem.toolCalls![currentThoughtIndex].thoughtOutput += message
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk_type === 'thought_end') {
|
||||
const currentThoughtIndex = responseItem.toolCalls?.findIndex(item => item.id === thoughtId) ?? -1
|
||||
if (currentThoughtIndex > -1) {
|
||||
responseItem.toolCalls![currentThoughtIndex].thoughtOutput += message
|
||||
responseItem.toolCalls![currentThoughtIndex].thoughtCompleted = true
|
||||
}
|
||||
}
|
||||
|
||||
if (messageId && !hasSetResponseId) {
|
||||
questionItem.id = `question-${messageId}`
|
||||
responseItem.id = messageId
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
LLMTraceItem,
|
||||
LoopDurationMap,
|
||||
LoopVariableMap,
|
||||
NodeTracing,
|
||||
@ -79,8 +80,18 @@ export const useLogs = () => {
|
||||
}
|
||||
}, [setAgentOrToolLogItemStack, setAgentOrToolLogListMap])
|
||||
|
||||
const [showLLMDetail, {
|
||||
setTrue: setShowLLMDetailTrue,
|
||||
setFalse: setShowLLMDetailFalse,
|
||||
}] = useBoolean(false)
|
||||
const [llmResultList, setLLMResultList] = useState<LLMTraceItem[]>([])
|
||||
const handleShowLLMDetail = useCallback((detail: LLMTraceItem[]) => {
|
||||
setShowLLMDetailTrue()
|
||||
setLLMResultList(detail)
|
||||
}, [setShowLLMDetailTrue, setLLMResultList])
|
||||
|
||||
return {
|
||||
showSpecialResultPanel: showRetryDetail || showIteratingDetail || showLoopingDetail || !!agentOrToolLogItemStack.length,
|
||||
showSpecialResultPanel: showRetryDetail || showIteratingDetail || showLoopingDetail || !!agentOrToolLogItemStack.length || showLLMDetail,
|
||||
showRetryDetail,
|
||||
setShowRetryDetailTrue,
|
||||
setShowRetryDetailFalse,
|
||||
@ -111,5 +122,12 @@ export const useLogs = () => {
|
||||
agentOrToolLogItemStack,
|
||||
agentOrToolLogListMap,
|
||||
handleShowAgentOrToolLog,
|
||||
|
||||
showLLMDetail,
|
||||
setShowLLMDetailTrue,
|
||||
setShowLLMDetailFalse,
|
||||
llmResultList,
|
||||
setLLMResultList,
|
||||
handleShowLLMDetail,
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ const RunPanel: FC<RunProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
{/* panel detail */}
|
||||
<div ref={ref} className={cn('relative h-0 grow overflow-y-auto rounded-b-xl bg-components-panel-bg')}>
|
||||
<div ref={ref} className={cn('relative h-0 grow overflow-y-auto rounded-b-xl bg-background-section')}>
|
||||
{loading && (
|
||||
<div className="flex h-full items-center justify-center bg-components-panel-bg">
|
||||
<Loading />
|
||||
@ -192,7 +192,7 @@ const RunPanel: FC<RunProps> = ({
|
||||
)}
|
||||
{!loading && currentTab === 'TRACING' && (
|
||||
<TracingPanel
|
||||
className="bg-background-section-burn"
|
||||
className="bg-background-section"
|
||||
list={list}
|
||||
/>
|
||||
)}
|
||||
|
||||
2
web/app/components/workflow/run/llm-log/index.tsx
Normal file
2
web/app/components/workflow/run/llm-log/index.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
export { default as LLMLogTrigger } from './llm-log-trigger'
|
||||
export { default as LLMResultPanel } from './llm-result-panel'
|
||||
41
web/app/components/workflow/run/llm-log/llm-log-trigger.tsx
Normal file
41
web/app/components/workflow/run/llm-log/llm-log-trigger.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import type { LLMTraceItem, NodeTracing } from '@/types/workflow'
|
||||
import {
|
||||
RiArrowRightSLine,
|
||||
} from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { Thinking } from '@/app/components/base/icons/src/vender/workflow'
|
||||
|
||||
type LLMLogTriggerProps = {
|
||||
nodeInfo: NodeTracing
|
||||
onShowLLMDetail: (detail: LLMTraceItem[]) => void
|
||||
}
|
||||
const LLMLogTrigger = ({
|
||||
nodeInfo,
|
||||
onShowLLMDetail,
|
||||
}: LLMLogTriggerProps) => {
|
||||
const { t } = useTranslation()
|
||||
const llmTrace = nodeInfo?.execution_metadata?.llm_trace || []
|
||||
|
||||
const handleShowLLMDetail = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation()
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
onShowLLMDetail(llmTrace || [])
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
className="mb-1 flex w-full items-center justify-between"
|
||||
variant="tertiary"
|
||||
onClick={handleShowLLMDetail}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Thinking className="mr-[5px] h-4 w-4 shrink-0 text-components-button-tertiary-text" />
|
||||
{t('detail', { ns: 'runLog' })}
|
||||
</div>
|
||||
<RiArrowRightSLine className="h-4 w-4 shrink-0 text-components-button-tertiary-text" />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export default LLMLogTrigger
|
||||
73
web/app/components/workflow/run/llm-log/llm-result-panel.tsx
Normal file
73
web/app/components/workflow/run/llm-log/llm-result-panel.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type {
|
||||
LLMTraceItem,
|
||||
ToolCallItem,
|
||||
} from '@/types/workflow'
|
||||
import {
|
||||
RiArrowLeftLine,
|
||||
} from '@remixicon/react'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ToolCallItemComponent from '@/app/components/workflow/run/llm-log/tool-call-item'
|
||||
|
||||
type Props = {
|
||||
list: LLMTraceItem[]
|
||||
onBack: () => void
|
||||
}
|
||||
|
||||
const LLMResultPanel: FC<Props> = ({
|
||||
list,
|
||||
onBack,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const formattedList = list.map((item) => {
|
||||
if (item.type === 'tool') {
|
||||
return {
|
||||
type: 'tool',
|
||||
toolName: item.name,
|
||||
toolProvider: item.provider,
|
||||
toolIcon: item.icon,
|
||||
toolIconDark: item.icon_dark,
|
||||
toolArguments: item.output.arguments,
|
||||
toolOutput: item.output.output,
|
||||
toolDuration: item.duration,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'model',
|
||||
modelName: item.name,
|
||||
modelProvider: item.provider,
|
||||
modelIcon: item.icon,
|
||||
modelIconDark: item.icon_dark,
|
||||
modelOutput: item.output,
|
||||
modelDuration: item.duration,
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="system-sm-medium flex h-8 cursor-pointer items-center bg-components-panel-bg px-4 text-text-accent-secondary"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
e.nativeEvent.stopImmediatePropagation()
|
||||
onBack()
|
||||
}}
|
||||
>
|
||||
<RiArrowLeftLine className="mr-1 h-4 w-4" />
|
||||
{t('singleRun.back', { ns: 'workflow' })}
|
||||
</div>
|
||||
<div className="space-y-1 p-2">
|
||||
{
|
||||
formattedList.map((item, index) => (
|
||||
<ToolCallItemComponent key={index} payload={item as ToolCallItem} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default memo(LLMResultPanel)
|
||||
152
web/app/components/workflow/run/llm-log/tool-call-item.tsx
Normal file
152
web/app/components/workflow/run/llm-log/tool-call-item.tsx
Normal file
@ -0,0 +1,152 @@
|
||||
import type { ToolCallItem } from '@/types/workflow'
|
||||
import {
|
||||
RiArrowDownSLine,
|
||||
} from '@remixicon/react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
import { Thinking } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import BlockIcon from '@/app/components/workflow/block-icon'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type ToolCallItemComponentProps = {
|
||||
className?: string
|
||||
payload: ToolCallItem
|
||||
}
|
||||
const ToolCallItemComponent = ({
|
||||
className,
|
||||
payload,
|
||||
}: ToolCallItemComponentProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [expand, setExpand] = useState(false)
|
||||
return (
|
||||
<div
|
||||
className={cn('rounded-[10px] border-[0.5px] border-components-panel-border bg-background-default-subtle px-2 pb-1 pt-2 shadow-xs', className)}
|
||||
>
|
||||
<div
|
||||
className="mb-1 flex cursor-pointer items-center hover:bg-background-gradient-bg-fill-chat-bubble-bg-2"
|
||||
onClick={() => {
|
||||
setExpand(!expand)
|
||||
}}
|
||||
>
|
||||
{
|
||||
payload.type === 'thought' && (
|
||||
<Thinking className="mr-1 h-4 w-4 shrink-0" />
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'tool' && (
|
||||
<BlockIcon
|
||||
type={BlockEnum.Tool}
|
||||
toolIcon={payload.toolIcon}
|
||||
className="mr-1 h-4 w-4 shrink-0"
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'model' && (
|
||||
<AppIcon
|
||||
iconType={typeof payload.modelIcon === 'string' ? 'image' : undefined}
|
||||
imageUrl={typeof payload.modelIcon === 'string' ? payload.modelIcon : undefined}
|
||||
background={typeof payload.modelIcon === 'object' ? payload.modelIcon.background : undefined}
|
||||
className="mr-1 h-4 w-4 shrink-0"
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'thought' && (
|
||||
<div className="system-xs-medium mr-1 grow truncate text-text-secondary" title={payload.thoughtOutput}>
|
||||
{
|
||||
payload.thoughtCompleted && !expand && (payload.thoughtOutput || '') as string
|
||||
}
|
||||
{
|
||||
payload.thoughtCompleted && expand && 'THOUGHT'
|
||||
}
|
||||
{
|
||||
!payload.thoughtCompleted && 'THINKING...'
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'tool' && (
|
||||
<div className="system-xs-medium mr-1 grow truncate text-text-secondary" title={payload.toolName}>{payload.toolName}</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'model' && (
|
||||
<div className="system-xs-medium mr-1 grow truncate text-text-secondary" title={payload.modelName}>{payload.modelName}</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
!!payload.toolDuration && (
|
||||
<div className="system-xs-regular mr-1 shrink-0 text-text-tertiary">
|
||||
{payload.toolDuration?.toFixed(1)}
|
||||
s
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
!!payload.modelDuration && (
|
||||
<div className="system-xs-regular mr-1 shrink-0 text-text-tertiary">
|
||||
{payload.modelDuration?.toFixed(1)}
|
||||
s
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<RiArrowDownSLine className="h-4 w-4 shrink-0" />
|
||||
</div>
|
||||
{
|
||||
expand && (
|
||||
<div className="relative px-2 pl-9">
|
||||
<div className="absolute bottom-1 left-2 top-1 w-[1px] bg-divider-regular"></div>
|
||||
{
|
||||
payload.type === 'thought' && typeof payload.thoughtOutput === 'string' && (
|
||||
<div className="body-sm-medium text-text-tertiary">{payload.thoughtOutput}</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'model' && (
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{t('common.data', { ns: 'workflow' })}</div>}
|
||||
language={CodeLanguage.json}
|
||||
value={payload.modelOutput}
|
||||
isJSONStringifyBeauty
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'tool' && (
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{t('common.input', { ns: 'workflow' })}</div>}
|
||||
language={CodeLanguage.json}
|
||||
value={payload.toolArguments}
|
||||
isJSONStringifyBeauty
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
payload.type === 'tool' && (
|
||||
<CodeEditor
|
||||
readOnly
|
||||
className="mt-1"
|
||||
title={<div>{t('common.output', { ns: 'workflow' })}</div>}
|
||||
language={CodeLanguage.json}
|
||||
value={payload.toolOutput}
|
||||
isJSONStringifyBeauty
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ToolCallItemComponent
|
||||
@ -3,6 +3,7 @@ import type { FC } from 'react'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
LLMTraceItem,
|
||||
LoopDurationMap,
|
||||
LoopVariableMap,
|
||||
NodeTracing,
|
||||
@ -29,6 +30,7 @@ import { BlockEnum } from '../types'
|
||||
import LargeDataAlert from '../variable-inspect/large-data-alert'
|
||||
import { AgentLogTrigger } from './agent-log'
|
||||
import { IterationLogTrigger } from './iteration-log'
|
||||
import { LLMLogTrigger } from './llm-log'
|
||||
import { LoopLogTrigger } from './loop-log'
|
||||
import { RetryLogTrigger } from './retry-log'
|
||||
|
||||
@ -43,6 +45,7 @@ type Props = {
|
||||
onShowLoopDetail?: (detail: NodeTracing[][], loopDurationMap: LoopDurationMap, loopVariableMap: LoopVariableMap) => void
|
||||
onShowRetryDetail?: (detail: NodeTracing[]) => void
|
||||
onShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void
|
||||
onShowLLMDetail?: (detail: LLMTraceItem[]) => void
|
||||
notShowIterationNav?: boolean
|
||||
notShowLoopNav?: boolean
|
||||
}
|
||||
@ -58,6 +61,7 @@ const NodePanel: FC<Props> = ({
|
||||
onShowLoopDetail,
|
||||
onShowRetryDetail,
|
||||
onShowAgentOrToolLog,
|
||||
onShowLLMDetail,
|
||||
notShowIterationNav,
|
||||
notShowLoopNav,
|
||||
}) => {
|
||||
@ -96,6 +100,7 @@ const NodePanel: FC<Props> = ({
|
||||
const isRetryNode = hasRetryNode(nodeInfo.node_type) && !!nodeInfo.retryDetail?.length
|
||||
const isAgentNode = nodeInfo.node_type === BlockEnum.Agent && !!nodeInfo.agentLog?.length
|
||||
const isToolNode = nodeInfo.node_type === BlockEnum.Tool && !!nodeInfo.agentLog?.length
|
||||
const isLLMNode = nodeInfo.node_type === BlockEnum.LLM && !!nodeInfo.execution_metadata?.llm_trace?.length
|
||||
|
||||
const inputsTitle = useMemo(() => {
|
||||
let text = t('common.input', { ns: 'workflow' })
|
||||
@ -193,6 +198,12 @@ const NodePanel: FC<Props> = ({
|
||||
onShowRetryResultList={onShowRetryDetail}
|
||||
/>
|
||||
)}
|
||||
{isLLMNode && onShowLLMDetail && (
|
||||
<LLMLogTrigger
|
||||
nodeInfo={nodeInfo}
|
||||
onShowLLMDetail={onShowLLMDetail}
|
||||
/>
|
||||
)}
|
||||
{
|
||||
(isAgentNode || isToolNode) && onShowAgentOrToolLog && (
|
||||
<AgentLogTrigger
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import type { FC } from 'react'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
LLMTraceItem,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -15,6 +16,7 @@ import { RetryLogTrigger } from '@/app/components/workflow/run/retry-log'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { hasRetryNode } from '@/app/components/workflow/utils'
|
||||
import LargeDataAlert from '../variable-inspect/large-data-alert'
|
||||
import { LLMLogTrigger } from './llm-log'
|
||||
import MetaData from './meta'
|
||||
import StatusPanel from './status'
|
||||
|
||||
@ -45,6 +47,7 @@ export type ResultPanelProps = {
|
||||
handleShowLoopResultList?: (detail: NodeTracing[][], loopDurationMap: any) => void
|
||||
onShowRetryDetail?: (detail: NodeTracing[]) => void
|
||||
handleShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void
|
||||
onShowLLMDetail?: (detail: LLMTraceItem[]) => void
|
||||
}
|
||||
|
||||
const ResultPanel: FC<ResultPanelProps> = ({
|
||||
@ -71,6 +74,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
||||
handleShowLoopResultList,
|
||||
onShowRetryDetail,
|
||||
handleShowAgentOrToolLog,
|
||||
onShowLLMDetail,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const isIterationNode = nodeInfo?.node_type === BlockEnum.Iteration && !!nodeInfo?.details?.length
|
||||
@ -78,6 +82,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
||||
const isRetryNode = hasRetryNode(nodeInfo?.node_type) && !!nodeInfo?.retryDetail?.length
|
||||
const isAgentNode = nodeInfo?.node_type === BlockEnum.Agent && !!nodeInfo?.agentLog?.length
|
||||
const isToolNode = nodeInfo?.node_type === BlockEnum.Tool && !!nodeInfo?.agentLog?.length
|
||||
const isLLMNode = nodeInfo?.node_type === BlockEnum.LLM && !!nodeInfo?.execution_metadata?.llm_trace?.length
|
||||
|
||||
return (
|
||||
<div className="bg-components-panel-bg py-2">
|
||||
@ -116,6 +121,14 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
isLLMNode && onShowLLMDetail && (
|
||||
<LLMLogTrigger
|
||||
nodeInfo={nodeInfo}
|
||||
onShowLLMDetail={onShowLLMDetail}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
(isAgentNode || isToolNode) && handleShowAgentOrToolLog && (
|
||||
<AgentLogTrigger
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
LLMTraceItem,
|
||||
LoopDurationMap,
|
||||
LoopVariableMap,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
import { AgentResultPanel } from './agent-log'
|
||||
import { IterationResultPanel } from './iteration-log'
|
||||
import { LLMResultPanel } from './llm-log'
|
||||
import { LoopResultPanel } from './loop-log'
|
||||
import { RetryResultPanel } from './retry-log'
|
||||
|
||||
@ -29,6 +31,10 @@ export type SpecialResultPanelProps = {
|
||||
agentOrToolLogItemStack?: AgentLogItemWithChildren[]
|
||||
agentOrToolLogListMap?: Record<string, AgentLogItemWithChildren[]>
|
||||
handleShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void
|
||||
|
||||
showLLMDetail?: boolean
|
||||
setShowLLMDetailFalse?: () => void
|
||||
llmResultList?: LLMTraceItem[]
|
||||
}
|
||||
const SpecialResultPanel = ({
|
||||
showRetryDetail,
|
||||
@ -49,6 +55,10 @@ const SpecialResultPanel = ({
|
||||
agentOrToolLogItemStack,
|
||||
agentOrToolLogListMap,
|
||||
handleShowAgentOrToolLog,
|
||||
|
||||
showLLMDetail,
|
||||
setShowLLMDetailFalse,
|
||||
llmResultList,
|
||||
}: SpecialResultPanelProps) => {
|
||||
return (
|
||||
<div onClick={(e) => {
|
||||
@ -64,6 +74,14 @@ const SpecialResultPanel = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
!!showLLMDetail && !!llmResultList?.length && setShowLLMDetailFalse && (
|
||||
<LLMResultPanel
|
||||
list={llmResultList}
|
||||
onBack={setShowLLMDetailFalse}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
showIteratingDetail && !!iterationResultList?.length && setShowIteratingDetailFalse && (
|
||||
<IterationResultPanel
|
||||
|
||||
@ -91,6 +91,11 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
||||
agentOrToolLogItemStack,
|
||||
agentOrToolLogListMap,
|
||||
handleShowAgentOrToolLog,
|
||||
|
||||
showLLMDetail,
|
||||
setShowLLMDetailFalse,
|
||||
llmResultList,
|
||||
handleShowLLMDetail,
|
||||
} = useLogs()
|
||||
|
||||
const renderNode = (node: NodeTracing) => {
|
||||
@ -153,6 +158,7 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
||||
onShowLoopDetail={handleShowLoopResultList}
|
||||
onShowRetryDetail={handleShowRetryResultList}
|
||||
onShowAgentOrToolLog={handleShowAgentOrToolLog}
|
||||
onShowLLMDetail={handleShowLLMDetail}
|
||||
hideInfo={hideNodeInfo}
|
||||
hideProcessDetail={hideNodeProcessDetail}
|
||||
/>
|
||||
@ -182,6 +188,10 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
||||
agentOrToolLogItemStack={agentOrToolLogItemStack}
|
||||
agentOrToolLogListMap={agentOrToolLogListMap}
|
||||
handleShowAgentOrToolLog={handleShowAgentOrToolLog}
|
||||
|
||||
showLLMDetail={showLLMDetail}
|
||||
setShowLLMDetailFalse={setShowLLMDetailFalse}
|
||||
llmResultList={llmResultList}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user