diff --git a/web/app/components/base/chat/chat/answer/tool-calls/index.tsx b/web/app/components/base/chat/chat/answer/tool-calls/index.tsx index 9de41233aa..f51daa7497 100644 --- a/web/app/components/base/chat/chat/answer/tool-calls/index.tsx +++ b/web/app/components/base/chat/chat/answer/tool-calls/index.tsx @@ -1,5 +1,5 @@ -import type { ToolCallItem } from '../../type' -import ToolCallsItem from './item' +import type { ToolCallItem } from '@/types/workflow' +import ToolCallItemComponent from '@/app/components/workflow/run/llm-log/tool-call-item' type ToolCallsProps = { toolCalls: ToolCallItem[] @@ -8,9 +8,13 @@ const ToolCalls = ({ toolCalls, }: ToolCallsProps) => { return ( -
+
{toolCalls.map((toolCall: ToolCallItem) => ( - + ))}
) diff --git a/web/app/components/base/chat/chat/answer/workflow-process.tsx b/web/app/components/base/chat/chat/answer/workflow-process.tsx index fd8c1daf3e..12f0001bd4 100644 --- a/web/app/components/base/chat/chat/answer/workflow-process.tsx +++ b/web/app/components/base/chat/chat/answer/workflow-process.tsx @@ -45,7 +45,7 @@ const WorkflowProcessItem = ({ return (
+ + + diff --git a/web/app/components/base/icons/src/vender/workflow/Thinking.json b/web/app/components/base/icons/src/vender/workflow/Thinking.json new file mode 100644 index 0000000000..6fe807775d --- /dev/null +++ b/web/app/components/base/icons/src/vender/workflow/Thinking.json @@ -0,0 +1,35 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "12", + "height": "14", + "viewBox": "0 0 12 14", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M2 9.49479C0.782372 8.51826 0 7.01768 0 5.33333C0 2.38782 2.38782 0 5.33333 0C8.20841 0 10.5503 2.27504 10.6608 5.12305L11.888 6.96354C12.0843 7.25794 12.0161 7.65424 11.7331 7.86654L10.6667 8.66602V10C10.6667 10.7364 10.0697 11.3333 9.33333 11.3333H8V13.3333H6.66667V10.6667C6.66667 10.2985 6.96514 10 7.33333 10H9.33333V8.33333C9.33333 8.12349 9.43239 7.92603 9.60026 7.80013L10.4284 7.17838L9.44531 5.70312C9.3723 5.59361 9.33333 5.46495 9.33333 5.33333C9.33333 3.1242 7.54248 1.33333 5.33333 1.33333C3.1242 1.33333 1.33333 3.1242 1.33333 5.33333C1.33333 6.69202 2.0103 7.89261 3.04818 8.61654C3.2269 8.74119 3.33329 8.94552 3.33333 9.16341V13.3333H2V9.49479Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M6.04367 4.24012L5.6504 3.21778C5.59993 3.08657 5.47393 3 5.33333 3C5.19273 3 5.06673 3.08657 5.01627 3.21778L4.62303 4.24012C4.55531 4.41618 4.41618 4.55531 4.24012 4.62303L3.21778 5.01624C3.08657 5.0667 3 5.19276 3 5.33333C3 5.47393 3.08657 5.59993 3.21778 5.6504L4.24012 6.04367C4.41618 6.11133 4.55531 6.25047 4.62303 6.42653L5.01627 7.44887C5.06673 7.58007 5.19273 7.66667 5.33333 7.66667C5.47393 7.66667 5.59993 7.58007 5.6504 7.44887L6.04367 6.42653C6.11133 6.25047 6.25047 6.11133 6.42653 6.04367L7.44887 5.6504C7.58007 5.59993 7.66667 5.47393 7.66667 5.33333C7.66667 5.19276 7.58007 5.0667 7.44887 5.01624L6.42653 4.62303C6.25047 4.55531 6.11133 4.41618 6.04367 4.24012Z", + "fill": "currentColor" + }, + "children": [] + } + ] + }, + "name": "Thinking" +} diff --git a/web/app/components/base/icons/src/vender/workflow/Thinking.tsx b/web/app/components/base/icons/src/vender/workflow/Thinking.tsx new file mode 100644 index 0000000000..dbe3716a24 --- /dev/null +++ b/web/app/components/base/icons/src/vender/workflow/Thinking.tsx @@ -0,0 +1,20 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import type { IconData } from '@/app/components/base/icons/IconBase' +import * as React from 'react' +import IconBase from '@/app/components/base/icons/IconBase' +import data from './Thinking.json' + +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject> + }, +) => + +Icon.displayName = 'Thinking' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/workflow/index.ts b/web/app/components/base/icons/src/vender/workflow/index.ts index ec8dce100d..b559d9c6aa 100644 --- a/web/app/components/base/icons/src/vender/workflow/index.ts +++ b/web/app/components/base/icons/src/vender/workflow/index.ts @@ -24,6 +24,7 @@ export { default as ParameterExtractor } from './ParameterExtractor' export { default as QuestionClassifier } from './QuestionClassifier' export { default as Schedule } from './Schedule' export { default as TemplatingTransform } from './TemplatingTransform' +export { default as Thinking } from './Thinking' export { default as TriggerAll } from './TriggerAll' export { default as VariableX } from './VariableX' export { default as WebhookLine } from './WebhookLine' diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx index 8e6e4567ff..5a3ada80ba 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import { RiFileTextLine, RiFilmAiLine, + RiHammerLine, RiImageCircleAiLine, RiVoiceAiFill, } from '@remixicon/react' @@ -38,17 +39,33 @@ const FeatureIcon: FC = ({ // ) // } - // if (feature === ModelFeatureEnum.toolCall) { - // return ( - // - // - // - // - // - // ) - // } + if (feature === ModelFeatureEnum.toolCall) { + if (showFeaturesLabel) { + return ( + + + {ModelFeatureTextEnum.toolCall} + + ) + } + + return ( + +
+ + + +
+
+ ) + } // if (feature === ModelFeatureEnum.multiToolCall) { // return ( diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx index bfa6f8d867..afda9846de 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx @@ -96,6 +96,14 @@ const PopupItem: FC = ({
{currentProvider?.description?.[language] || currentProvider?.description?.en_US}
)} */}
+ { + modelItem.features?.includes(ModelFeatureEnum.toolCall) && ( + + ) + } {modelItem.model_type && ( {modelTypeFormat(modelItem.model_type)} @@ -118,7 +126,7 @@ const PopupItem: FC = ({
{t('model.capabilities', { ns: 'common' })}
- {modelItem.features?.map(feature => ( + {modelItem.features?.filter(feature => feature !== ModelFeatureEnum.toolCall).map(feature => ( item.is_thought) ?? -1 + // if (currentThoughtIndex > -1) + // responseItem.toolCalls![currentThoughtIndex].tool_output = message + } + if (chunk_type === 'thought') { - const currentThoughtIndex = responseItem.toolCalls?.findIndex(item => item.is_thought) ?? -1 - if (currentThoughtIndex > -1) - responseItem.toolCalls![currentThoughtIndex].tool_output = message + console.log(message, 'xx3') } if (messageId && !hasSetResponseId) { diff --git a/web/app/components/workflow/run/hooks.ts b/web/app/components/workflow/run/hooks.ts index 593836f5b3..9aa6d253a1 100644 --- a/web/app/components/workflow/run/hooks.ts +++ b/web/app/components/workflow/run/hooks.ts @@ -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([]) + 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, } } diff --git a/web/app/components/workflow/run/index.tsx b/web/app/components/workflow/run/index.tsx index 51f641f265..9590dc24d7 100644 --- a/web/app/components/workflow/run/index.tsx +++ b/web/app/components/workflow/run/index.tsx @@ -153,7 +153,7 @@ const RunPanel: FC = ({
{/* panel detail */} -
+
{loading && (
@@ -192,7 +192,7 @@ const RunPanel: FC = ({ )} {!loading && currentTab === 'TRACING' && ( )} diff --git a/web/app/components/workflow/run/llm-log/llm-log-trigger.tsx b/web/app/components/workflow/run/llm-log/llm-log-trigger.tsx index 4714fe6330..1d65f754b4 100644 --- a/web/app/components/workflow/run/llm-log/llm-log-trigger.tsx +++ b/web/app/components/workflow/run/llm-log/llm-log-trigger.tsx @@ -1,37 +1,37 @@ -import type { NodeTracing } from '@/types/workflow' +import type { LLMTraceItem, NodeTracing } from '@/types/workflow' import { RiArrowRightSLine, - RiRestartFill, } 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: NodeTracing[]) => void + onShowLLMDetail: (detail: LLMTraceItem[]) => void } const LLMLogTrigger = ({ nodeInfo, onShowLLMDetail, }: LLMLogTriggerProps) => { const { t } = useTranslation() - const { retryDetail } = nodeInfo + const llmTrace = nodeInfo?.execution_metadata?.llm_trace || [] - const handleShowRetryResultList = (e: React.MouseEvent) => { + const handleShowLLMDetail = (e: React.MouseEvent) => { e.stopPropagation() e.nativeEvent.stopImmediatePropagation() - onShowLLMDetail(retryDetail || []) + onShowLLMDetail(llmTrace || []) } return ( diff --git a/web/app/components/workflow/run/llm-log/llm-result-panel.tsx b/web/app/components/workflow/run/llm-log/llm-result-panel.tsx index 8f42486df1..0223a4cdec 100644 --- a/web/app/components/workflow/run/llm-log/llm-result-panel.tsx +++ b/web/app/components/workflow/run/llm-log/llm-result-panel.tsx @@ -1,16 +1,19 @@ 'use client' import type { FC } from 'react' -import type { NodeTracing } from '@/types/workflow' +import type { + LLMTraceItem, + ToolCallItem, +} from '@/types/workflow' import { RiArrowLeftLine, } from '@remixicon/react' import { memo } from 'react' import { useTranslation } from 'react-i18next' -import TracingPanel from '../tracing-panel' +import ToolCallItemComponent from '@/app/components/workflow/run/llm-log/tool-call-item' type Props = { - list: NodeTracing[] + list: LLMTraceItem[] onBack: () => void } @@ -19,6 +22,18 @@ const LLMResultPanel: FC = ({ onBack, }) => { const { t } = useTranslation() + const formattedList = list.map(item => ({ + type: item.type, + tool_call_id: item.provider, + tool_name: item.name, + tool_arguments: item.type === 'tool' ? item.output.arguments : undefined, + tool_icon: item.icon, + tool_icon_dark: item.icon_dark, + tool_files: [], + tool_error: item.error, + tool_output: item.type === 'tool' ? item.output.output : item.output, + tool_elapsed_time: item.duration, + })) return (
@@ -33,13 +48,13 @@ const LLMResultPanel: FC = ({ {t('singleRun.back', { ns: 'workflow' })}
- ({ - ...item, - title: `${t('nodes.common.retry.retry', { ns: 'workflow' })} ${index + 1}`, - }))} - className="bg-background-section-burn" - /> +
+ { + formattedList.map((item, index) => ( + + )) + } +
) } diff --git a/web/app/components/base/chat/chat/answer/tool-calls/item.tsx b/web/app/components/workflow/run/llm-log/tool-call-item.tsx similarity index 55% rename from web/app/components/base/chat/chat/answer/tool-calls/item.tsx rename to web/app/components/workflow/run/llm-log/tool-call-item.tsx index 539f1a83ba..026f85df9a 100644 --- a/web/app/components/base/chat/chat/answer/tool-calls/item.tsx +++ b/web/app/components/workflow/run/llm-log/tool-call-item.tsx @@ -1,30 +1,40 @@ -import type { ToolCallItem } from '../../type' +import type { ToolCallItem } from '@/types/workflow' import { RiArrowDownSLine, } from '@remixicon/react' import { useState } from 'react' import { useTranslation } from 'react-i18next' +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 ToolCallsItemProps = { +type ToolCallItemComponentProps = { + className?: string payload: ToolCallItem } -const ToolCallsItem = ({ +const ToolCallItemComponent = ({ + className, payload, -}: ToolCallsItemProps) => { +}: ToolCallItemComponentProps) => { const { t } = useTranslation() const [expand, setExpand] = useState(false) return (
setExpand(!expand)}> -
{payload.tool_name}
+ +
{payload.tool_name}
{ !!payload.tool_elapsed_time && (
- {payload.tool_elapsed_time?.toFixed(3)} + {payload.tool_elapsed_time?.toFixed(1)} s
) @@ -36,31 +46,40 @@ const ToolCallsItem = ({
{ - payload.is_thought && ( + payload.type === 'thought' && typeof payload.tool_output === 'string' && (
{payload.tool_output}
) } { - !payload.is_thought && ( + payload.type === 'model' && ( {t('common.input', { ns: 'workflow' })}
} + title={
{t('common.data', { ns: 'workflow' })}
} language={CodeLanguage.json} - value={JSON.parse(payload.tool_arguments || '{}')} + value={payload.tool_output} isJSONStringifyBeauty /> ) } { - !payload.is_thought && ( + payload.type === 'tool' && ( + {t('common.input', { ns: 'workflow' })}
} + language={CodeLanguage.json} + value={payload.tool_arguments} + isJSONStringifyBeauty + /> + ) + } + { + payload.type === 'tool' && ( {t('common.output', { ns: 'workflow' })}
} language={CodeLanguage.json} - value={{ - answer: payload.tool_output, - }} + value={payload.tool_output} isJSONStringifyBeauty /> ) @@ -72,4 +91,4 @@ const ToolCallsItem = ({ ) } -export default ToolCallsItem +export default ToolCallItemComponent diff --git a/web/app/components/workflow/run/node.tsx b/web/app/components/workflow/run/node.tsx index d4316f285f..ffec4392b6 100644 --- a/web/app/components/workflow/run/node.tsx +++ b/web/app/components/workflow/run/node.tsx @@ -3,6 +3,7 @@ import type { FC } from 'react' import type { AgentLogItemWithChildren, IterationDurationMap, + LLMTraceItem, LoopDurationMap, LoopVariableMap, NodeTracing, @@ -44,7 +45,7 @@ type Props = { onShowLoopDetail?: (detail: NodeTracing[][], loopDurationMap: LoopDurationMap, loopVariableMap: LoopVariableMap) => void onShowRetryDetail?: (detail: NodeTracing[]) => void onShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void - onShowLLMDetail?: (detail: NodeTracing[]) => void + onShowLLMDetail?: (detail: LLMTraceItem[]) => void notShowIterationNav?: boolean notShowLoopNav?: boolean } @@ -99,7 +100,7 @@ const NodePanel: FC = ({ 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.generation_detail + const isLLMNode = nodeInfo.node_type === BlockEnum.LLM && !!nodeInfo.execution_metadata?.llm_trace?.length const inputsTitle = useMemo(() => { let text = t('common.input', { ns: 'workflow' }) diff --git a/web/app/components/workflow/run/result-panel.tsx b/web/app/components/workflow/run/result-panel.tsx index 8bc55a504b..00e8b028d1 100644 --- a/web/app/components/workflow/run/result-panel.tsx +++ b/web/app/components/workflow/run/result-panel.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import type { AgentLogItemWithChildren, + LLMTraceItem, NodeTracing, } from '@/types/workflow' import { useTranslation } from 'react-i18next' @@ -46,7 +47,7 @@ export type ResultPanelProps = { handleShowLoopResultList?: (detail: NodeTracing[][], loopDurationMap: any) => void onShowRetryDetail?: (detail: NodeTracing[]) => void handleShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void - onShowLLMDetail?: (detail: NodeTracing[]) => void + onShowLLMDetail?: (detail: LLMTraceItem[]) => void } const ResultPanel: FC = ({ @@ -81,7 +82,7 @@ const ResultPanel: FC = ({ 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?.generation_detail + const isLLMNode = nodeInfo?.node_type === BlockEnum.LLM && !!nodeInfo?.execution_metadata?.llm_trace?.length return (
diff --git a/web/app/components/workflow/run/special-result-panel.tsx b/web/app/components/workflow/run/special-result-panel.tsx index f12d51ef20..4ccc832417 100644 --- a/web/app/components/workflow/run/special-result-panel.tsx +++ b/web/app/components/workflow/run/special-result-panel.tsx @@ -1,6 +1,7 @@ import type { AgentLogItemWithChildren, IterationDurationMap, + LLMTraceItem, LoopDurationMap, LoopVariableMap, NodeTracing, @@ -33,7 +34,7 @@ export type SpecialResultPanelProps = { showLLMDetail?: boolean setShowLLMDetailFalse?: () => void - llmResultList?: NodeTracing[] + llmResultList?: LLMTraceItem[] } const SpecialResultPanel = ({ showRetryDetail, diff --git a/web/app/components/workflow/run/tracing-panel.tsx b/web/app/components/workflow/run/tracing-panel.tsx index 8931c8f7fe..51686bd839 100644 --- a/web/app/components/workflow/run/tracing-panel.tsx +++ b/web/app/components/workflow/run/tracing-panel.tsx @@ -91,6 +91,11 @@ const TracingPanel: FC = ({ agentOrToolLogItemStack, agentOrToolLogListMap, handleShowAgentOrToolLog, + + showLLMDetail, + setShowLLMDetailFalse, + llmResultList, + handleShowLLMDetail, } = useLogs() const renderNode = (node: NodeTracing) => { @@ -153,6 +158,7 @@ const TracingPanel: FC = ({ onShowLoopDetail={handleShowLoopResultList} onShowRetryDetail={handleShowRetryResultList} onShowAgentOrToolLog={handleShowAgentOrToolLog} + onShowLLMDetail={handleShowLLMDetail} hideInfo={hideNodeInfo} hideProcessDetail={hideNodeProcessDetail} /> @@ -182,6 +188,10 @@ const TracingPanel: FC = ({ agentOrToolLogItemStack={agentOrToolLogItemStack} agentOrToolLogListMap={agentOrToolLogListMap} handleShowAgentOrToolLog={handleShowAgentOrToolLog} + + showLLMDetail={showLLMDetail} + setShowLLMDetailFalse={setShowLLMDetailFalse} + llmResultList={llmResultList} /> ) } diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 9dc21e79e6..371487856d 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -126,6 +126,7 @@ "common.currentDraftUnpublished": "Current Draft Unpublished", "common.currentView": "Current View", "common.currentWorkflow": "Current Workflow", + "common.data": "Data", "common.debugAndPreview": "Preview", "common.disconnect": "Disconnect", "common.duplicate": "Duplicate", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 7787c9db4b..50a0801706 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -126,6 +126,7 @@ "common.currentDraftUnpublished": "当前草稿未发布", "common.currentView": "当前视图", "common.currentWorkflow": "整个工作流", + "common.data": "数据", "common.debugAndPreview": "预览", "common.disconnect": "断开连接", "common.duplicate": "复制", diff --git a/web/service/base.ts b/web/service/base.ts index bbb05cf357..cc421b0f75 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -34,16 +34,24 @@ import { getWebAppPassport } from './webapp-auth' const TIME_OUT = 100000 +export type IconObject = { + background: string + content: string +} + export type IOnDataMoreInfo = { conversationId?: string taskId?: string messageId: string errorMessage?: string errorCode?: string - chunk_type?: 'text' | 'tool_call' | 'tool_result' | 'thought' | 'thought_start' + chunk_type?: 'text' | 'tool_call' | 'tool_result' | 'thought' | 'thought_start' | 'thought_end' tool_call_id?: string tool_name?: string tool_arguments?: string + tool_icon?: string | IconObject + tool_icon_dark?: string | IconObject + tool_files?: string[] tool_error?: string tool_elapsed_time?: number @@ -245,6 +253,8 @@ export const handleStream = ( tool_call_id: bufferObj.tool_call_id, tool_name: bufferObj.tool_name, tool_arguments: bufferObj.tool_arguments, + tool_icon: bufferObj.tool_icon, + tool_icon_dark: bufferObj.tool_icon_dark, tool_files: bufferObj.tool_files, tool_error: bufferObj.tool_error, tool_elapsed_time: bufferObj.tool_elapsed_time, diff --git a/web/types/workflow.ts b/web/types/workflow.ts index 3f7ea304b3..3241ff0732 100644 --- a/web/types/workflow.ts +++ b/web/types/workflow.ts @@ -28,11 +28,33 @@ export type AgentLogItemWithChildren = AgentLogItem & { children: AgentLogItemWithChildren[] } +export type IconObject = { + background: string + content: string +} + +export type ToolCallItem = { + type: 'model' | 'tool' | 'thought' + tool_call_id?: string + tool_name?: string + tool_arguments?: string + tool_icon?: string | IconObject + tool_icon_dark?: string | IconObject + tool_files?: string[] + tool_error?: string + tool_output?: Record | string + tool_elapsed_time?: number +} + export type ToolCallDetail = { id: string name: string arguments: string - result: string + output: string + files: string[] + error: string + elapsed_time?: number + status: string } export type SequenceSegment = | { type: 'context', start: number, end: number } @@ -45,6 +67,18 @@ export type LLMLogItem = { sequence: SequenceSegment[] } +export type LLMTraceItem = { + type: 'model' | 'tool' + duration: number + output: Record + provider?: string + name: string + icon?: string | IconObject + icon_dark?: string | IconObject + error?: string + status?: 'success' | 'error' +} + export type NodeTracing = { id: string index: number @@ -89,6 +123,7 @@ export type NodeTracing = { icon?: string } loop_variable_map?: Record + llm_trace?: LLMTraceItem[] } metadata: { iterator_length: number