Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
90ee7fe2
Commit
90ee7fe2
authored
Mar 09, 2024
by
JzoNg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tracing
parent
bc90fc88
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
103 additions
and
35 deletions
+103
-35
detail.tsx
web/app/components/app/workflow-log/detail.tsx
+1
-1
index.tsx
web/app/components/workflow/run/index.tsx
+2
-3
node.tsx
web/app/components/workflow/run/node.tsx
+4
-13
tracing.tsx
web/app/components/workflow/run/tracing.tsx
+59
-18
log.ts
web/service/log.ts
+5
-0
workflow.ts
web/types/workflow.ts
+32
-0
No files found.
web/app/components/app/workflow-log/detail.tsx
View file @
90ee7fe2
...
@@ -18,7 +18,7 @@ const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
...
@@ -18,7 +18,7 @@ const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
<
XClose
className=
'w-4 h-4 text-gray-500'
/>
<
XClose
className=
'w-4 h-4 text-gray-500'
/>
</
span
>
</
span
>
<
h1
className=
'shrink-0 px-4 py-1 text-md font-semibold text-gray-900'
>
{
t
(
'appLog.runDetail.workflowTitle'
)
}
</
h1
>
<
h1
className=
'shrink-0 px-4 py-1 text-md font-semibold text-gray-900'
>
{
t
(
'appLog.runDetail.workflowTitle'
)
}
</
h1
>
<
Run
activeTab=
'TRACING'
runID=
{
runID
}
/>
<
Run
runID=
{
runID
}
/>
</
div
>
</
div
>
)
)
}
}
...
...
web/app/components/workflow/run/index.tsx
View file @
90ee7fe2
...
@@ -5,14 +5,13 @@ import { useTranslation } from 'react-i18next'
...
@@ -5,14 +5,13 @@ import { useTranslation } from 'react-i18next'
import
cn
from
'classnames'
import
cn
from
'classnames'
import
Result
from
'./result'
import
Result
from
'./result'
import
Tracing
from
'./tracing'
import
Tracing
from
'./tracing'
// import type { App } from '@/types/app'
type
RunProps
=
{
type
RunProps
=
{
activeTab
:
'RESULT'
|
'TRACING'
activeTab
?
:
'RESULT'
|
'TRACING'
runID
:
string
runID
:
string
}
}
const
RunPanel
:
FC
<
RunProps
>
=
({
activeTab
,
runID
})
=>
{
const
RunPanel
:
FC
<
RunProps
>
=
({
activeTab
=
'RESULT'
,
runID
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
const
[
currentTab
,
setCurrentTab
]
=
useState
<
string
>
(
activeTab
)
const
[
currentTab
,
setCurrentTab
]
=
useState
<
string
>
(
activeTab
)
...
...
web/app/components/workflow/run/node.tsx
View file @
90ee7fe2
...
@@ -3,24 +3,15 @@ import { useTranslation } from 'react-i18next'
...
@@ -3,24 +3,15 @@ import { useTranslation } from 'react-i18next'
import
type
{
FC
}
from
'react'
import
type
{
FC
}
from
'react'
import
cn
from
'classnames'
import
cn
from
'classnames'
import
BlockIcon
from
'../block-icon'
import
BlockIcon
from
'../block-icon'
import
type
{
BlockEnum
}
from
'../types'
import
CodeEditor
from
'@/app/components/workflow/nodes/_base/components/editor/code-editor'
import
CodeEditor
from
'@/app/components/workflow/nodes/_base/components/editor/code-editor'
import
{
CodeLanguage
}
from
'@/app/components/workflow/nodes/code/types'
import
{
CodeLanguage
}
from
'@/app/components/workflow/nodes/code/types'
import
{
AlertCircle
,
AlertTriangle
}
from
'@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import
{
AlertCircle
,
AlertTriangle
}
from
'@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import
{
CheckCircle
,
Loading02
}
from
'@/app/components/base/icons/src/vender/line/general'
import
{
CheckCircle
,
Loading02
}
from
'@/app/components/base/icons/src/vender/line/general'
import
{
ChevronRight
}
from
'@/app/components/base/icons/src/vender/line/arrows'
import
{
ChevronRight
}
from
'@/app/components/base/icons/src/vender/line/arrows'
import
type
{
NodeTracing
}
from
'@/types/workflow'
export
type
NodeInfo
=
{
type
:
BlockEnum
title
:
string
time
:
number
tokens
:
number
status
:
string
error
?:
string
}
type
Props
=
{
type
Props
=
{
nodeInfo
:
Node
Info
nodeInfo
:
Node
Tracing
collapsed
:
boolean
collapsed
:
boolean
collapseHandle
:
()
=>
void
collapseHandle
:
()
=>
void
}
}
...
@@ -60,9 +51,9 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
...
@@ -60,9 +51,9 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
!
collapsed
&&
'rotate-90'
,
!
collapsed
&&
'rotate-90'
,
)
}
)
}
/>
/>
<
BlockIcon
className=
'shrink-0 mr-2'
type=
{
nodeInfo
.
type
}
/>
<
BlockIcon
className=
'shrink-0 mr-2'
type=
{
nodeInfo
.
node_
type
}
/>
<
div
className=
'grow text-gray-700 text-[13px] leading-[16px] font-semibold truncate'
title=
{
nodeInfo
.
title
}
>
{
nodeInfo
.
title
}
</
div
>
<
div
className=
'grow text-gray-700 text-[13px] leading-[16px] font-semibold truncate'
title=
{
nodeInfo
.
title
}
>
{
nodeInfo
.
title
}
</
div
>
<
div
className=
'shrink-0 text-gray-500 text-xs leading-[18px]'
>
{
`${getTime(nodeInfo.
time)} · ${getTokenCount(nodeInfo.
tokens)} tokens`
}
</
div
>
<
div
className=
'shrink-0 text-gray-500 text-xs leading-[18px]'
>
{
`${getTime(nodeInfo.
elapsed_time)} · ${getTokenCount(nodeInfo.execution_metadata.total_
tokens)} tokens`
}
</
div
>
{
nodeInfo
.
status
===
'succeeded'
&&
(
{
nodeInfo
.
status
===
'succeeded'
&&
(
<
CheckCircle
className=
'shrink-0 ml-2 w-3.5 h-3.5 text-[#12B76A]'
/>
<
CheckCircle
className=
'shrink-0 ml-2 w-3.5 h-3.5 text-[#12B76A]'
/>
)
}
)
}
...
...
web/app/components/workflow/run/tracing.tsx
View file @
90ee7fe2
'use client'
'use client'
import
type
{
FC
}
from
'react'
import
type
{
FC
}
from
'react'
import
React
,
{
useState
}
from
'react'
import
React
,
{
useCallback
,
useEffect
,
useState
}
from
'react'
// import { useTranslation } from 'react-i18next'
import
{
useContext
}
from
'use-context-selector'
// import cn from 'classnames'
import
produce
from
'immer'
import
{
BlockEnum
}
from
'../types'
import
NodePanel
from
'./node'
import
NodePanel
from
'./node'
import
Loading
from
'@/app/components/base/loading'
import
{
fetchTracingList
}
from
'@/service/log'
import
{
useStore
as
useAppStore
}
from
'@/app/components/app/store'
import
type
{
NodeTracing
}
from
'@/types/workflow'
import
{
ToastContext
}
from
'@/app/components/base/toast'
type
TracingProps
=
{
type
TracingProps
=
{
runID
:
string
runID
:
string
}
}
const
nodeInfoFake
=
{
type
:
BlockEnum
.
Start
,
title
:
'START'
,
time
:
67.349
,
tokens
:
2708
,
status
:
'failed'
,
error
:
'lvlvlvlv'
,
}
const
Tracing
:
FC
<
TracingProps
>
=
({
runID
})
=>
{
const
Tracing
:
FC
<
TracingProps
>
=
({
runID
})
=>
{
// const { t } = useTranslation()
const
{
notify
}
=
useContext
(
ToastContext
)
const
[
nodeCollapsed
,
setCurrentTab
]
=
useState
<
boolean
>
(
false
)
const
{
appDetail
}
=
useAppStore
()
const
[
loading
,
setLoading
]
=
useState
<
boolean
>
(
true
)
const
[
list
,
setList
]
=
useState
<
NodeTracing
[]
>
([])
const
[
collapseState
,
setCollapseState
]
=
useState
<
boolean
[]
>
([])
const
getTracingList
=
useCallback
(
async
(
appID
:
string
,
runID
:
string
)
=>
{
setLoading
(
true
)
try
{
const
{
data
:
nodeList
}
=
await
fetchTracingList
({
url
:
`/apps/
${
appID
}
/workflow-runs/
${
runID
}
/node-executions`
,
})
const
collapseState
=
nodeList
.
map
(
node
=>
node
.
status
===
'succeeded'
)
setList
(
nodeList
)
setCollapseState
(
collapseState
)
setLoading
(
false
)
}
catch
(
err
)
{
notify
({
type
:
'error'
,
message
:
`
${
err
}
`
,
})
setLoading
(
false
)
}
},
[
notify
])
useEffect
(()
=>
{
if
(
appDetail
&&
runID
)
getTracingList
(
appDetail
.
id
,
runID
)
},
[
appDetail
,
getTracingList
,
runID
])
const
collapseStateChange
=
(
index
:
number
)
=>
{
const
newCollapseState
=
produce
(
collapseState
,
(
draft
:
boolean
[])
=>
{
draft
[
index
]
=
!
draft
[
index
]
})
setCollapseState
(
newCollapseState
)
}
const
collapseStateChange
=
()
=>
{
if
(
loading
)
{
setCurrentTab
(
!
nodeCollapsed
)
return
(
<
div
className=
'flex h-full items-center justify-center bg-white'
>
<
Loading
/>
</
div
>
)
}
}
return
(
return
(
<
div
className=
'bg-gray-50 py-2'
>
<
div
className=
'bg-gray-50 py-2'
>
<
NodePanel
nodeInfo=
{
nodeInfoFake
}
collapsed=
{
nodeCollapsed
}
collapseHandle=
{
collapseStateChange
}
/>
{
list
.
map
((
node
,
index
)
=>
(
<
NodePanel
key=
{
node
.
id
}
nodeInfo=
{
node
}
collapsed=
{
collapseState
[
index
]
}
collapseHandle=
{
()
=>
collapseStateChange
(
index
)
}
/>
))
}
</
div
>
</
div
>
)
)
}
}
...
...
web/service/log.ts
View file @
90ee7fe2
...
@@ -19,6 +19,7 @@ import type {
...
@@ -19,6 +19,7 @@ import type {
WorkflowLogsResponse
,
WorkflowLogsResponse
,
WorkflowRunDetailResponse
,
WorkflowRunDetailResponse
,
}
from
'@/models/log'
}
from
'@/models/log'
import
type
{
NodeTracingListResponse
}
from
'@/types/workflow'
export
const
fetchConversationList
:
Fetcher
<
ConversationListResponse
,
{
name
:
string
;
appId
:
string
;
params
?:
Record
<
string
,
any
>
}
>
=
({
appId
,
params
})
=>
{
export
const
fetchConversationList
:
Fetcher
<
ConversationListResponse
,
{
name
:
string
;
appId
:
string
;
params
?:
Record
<
string
,
any
>
}
>
=
({
appId
,
params
})
=>
{
return
get
<
ConversationListResponse
>
(
`/console/api/apps/
${
appId
}
/messages`
,
params
)
return
get
<
ConversationListResponse
>
(
`/console/api/apps/
${
appId
}
/messages`
,
params
)
...
@@ -68,3 +69,7 @@ export const fetchWorkflowLogs: Fetcher<WorkflowLogsResponse, { url: string; par
...
@@ -68,3 +69,7 @@ export const fetchWorkflowLogs: Fetcher<WorkflowLogsResponse, { url: string; par
export
const
fetchRunDetail
=
({
appID
,
runID
}:
{
appID
:
string
;
runID
:
string
})
=>
{
export
const
fetchRunDetail
=
({
appID
,
runID
}:
{
appID
:
string
;
runID
:
string
})
=>
{
return
get
<
WorkflowRunDetailResponse
>
(
`/apps/
${
appID
}
/workflow-run/
${
runID
}
`
)
return
get
<
WorkflowRunDetailResponse
>
(
`/apps/
${
appID
}
/workflow-run/
${
runID
}
`
)
}
}
export
const
fetchTracingList
:
Fetcher
<
NodeTracingListResponse
,
{
url
:
string
}
>
=
({
url
})
=>
{
return
get
<
NodeTracingListResponse
>
(
url
)
}
web/types/workflow.ts
View file @
90ee7fe2
import
type
{
Viewport
}
from
'reactflow'
import
type
{
Viewport
}
from
'reactflow'
import
type
{
import
type
{
BlockEnum
,
Edge
,
Edge
,
Node
,
Node
,
}
from
'@/app/components/workflow/types'
}
from
'@/app/components/workflow/types'
export
type
NodeTracing
=
{
id
:
string
index
:
number
predecessor_node_id
:
string
node_id
:
string
node_type
:
BlockEnum
title
:
string
inputs
:
any
process_data
:
any
outputs
?:
any
status
:
string
error
?:
string
elapsed_time
:
number
execution_metadata
:
{
total_tokens
:
number
total_price
:
number
currency
:
string
}
created_at
:
number
created_by
:
{
id
:
string
name
:
string
email
:
string
}
finished_at
:
number
}
export
type
FetchWorkflowDraftResponse
=
{
export
type
FetchWorkflowDraftResponse
=
{
id
:
string
id
:
string
graph
:
{
graph
:
{
...
@@ -14,3 +42,7 @@ export type FetchWorkflowDraftResponse = {
...
@@ -14,3 +42,7 @@ export type FetchWorkflowDraftResponse = {
features
?:
any
features
?:
any
updated_at
:
number
updated_at
:
number
}
}
export
type
NodeTracingListResponse
=
{
data
:
NodeTracing
[]
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment