mirror of https://github.com/langgenius/dify.git
fix: address workflow tracing review feedback
This commit is contained in:
parent
37df3899ff
commit
64308c3d0d
|
|
@ -452,7 +452,7 @@ export const useChat = (
|
|||
|
||||
upsertTopLevelTracingNodeOnStart(responseItem.workflowProcess.tracing, {
|
||||
...nodeStartedData,
|
||||
status: WorkflowRunningStatus.Running,
|
||||
status: NodeRunningStatus.Running,
|
||||
})
|
||||
})
|
||||
},
|
||||
|
|
@ -1005,7 +1005,7 @@ export const useChat = (
|
|||
|
||||
upsertTopLevelTracingNodeOnStart(responseItem.workflowProcess.tracing, {
|
||||
...nodeStartedData,
|
||||
status: WorkflowRunningStatus.Running,
|
||||
status: NodeRunningStatus.Running,
|
||||
})
|
||||
updateCurrentQAOnTree({
|
||||
placeholderQuestionId,
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const createHumanInput = (overrides: Partial<HumanInputFormData> = {}): HumanInp
|
|||
describe('workflow-stream-handlers helpers', () => {
|
||||
it('should update tracing, result text, and human input state', () => {
|
||||
const parallelTrace = createTrace({
|
||||
id: 'parallel-trace-1',
|
||||
node_id: 'parallel-node',
|
||||
execution_metadata: { parallel_id: 'parallel-1' },
|
||||
details: [[]],
|
||||
|
|
@ -109,11 +110,13 @@ describe('workflow-stream-handlers helpers', () => {
|
|||
let workflowProcessData = appendParallelStart(undefined, parallelTrace)
|
||||
workflowProcessData = appendParallelNext(workflowProcessData, parallelTrace)
|
||||
workflowProcessData = finishParallelTrace(workflowProcessData, createTrace({
|
||||
id: 'parallel-trace-1',
|
||||
node_id: 'parallel-node',
|
||||
execution_metadata: { parallel_id: 'parallel-1' },
|
||||
error: 'failed',
|
||||
}))
|
||||
workflowProcessData = upsertWorkflowNode(workflowProcessData, createTrace({
|
||||
id: 'node-trace-1',
|
||||
node_id: 'node-1',
|
||||
execution_metadata: { parallel_id: 'parallel-2' },
|
||||
}))!
|
||||
|
|
@ -160,6 +163,29 @@ describe('workflow-stream-handlers helpers', () => {
|
|||
expect(nextProcess.tracing[0]?.details).toEqual([[], []])
|
||||
})
|
||||
|
||||
it('should append a new top-level trace when the same node starts with a different execution id', () => {
|
||||
const process = createWorkflowProcess()
|
||||
process.tracing = [
|
||||
createTrace({
|
||||
id: 'trace-1',
|
||||
node_id: 'node-1',
|
||||
status: NodeRunningStatus.Succeeded,
|
||||
}),
|
||||
]
|
||||
|
||||
const updatedProcess = upsertWorkflowNode(process, createTrace({
|
||||
id: 'trace-2',
|
||||
node_id: 'node-1',
|
||||
}))!
|
||||
|
||||
expect(updatedProcess.tracing).toHaveLength(2)
|
||||
expect(updatedProcess.tracing[1]).toEqual(expect.objectContaining({
|
||||
id: 'trace-2',
|
||||
node_id: 'node-1',
|
||||
status: NodeRunningStatus.Running,
|
||||
}))
|
||||
})
|
||||
|
||||
it('should leave tracing unchanged when a parallel next event has no matching trace', () => {
|
||||
const process = createWorkflowProcess()
|
||||
process.tracing = [
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import type { HumanInputFormTimeoutData, NodeTracing, WorkflowFinishedResponse }
|
|||
import { produce } from 'immer'
|
||||
import { getFilesInLogs } from '@/app/components/base/file-uploader/utils'
|
||||
import { NodeRunningStatus, WorkflowRunningStatus } from '@/app/components/workflow/types'
|
||||
import { upsertTopLevelTracingNodeOnStart } from '@/app/components/workflow/utils/top-level-tracing'
|
||||
import { sseGet } from '@/service/base'
|
||||
|
||||
type Notify = (payload: { type: 'error' | 'warning', message: string }) => void
|
||||
|
|
@ -96,17 +97,13 @@ const upsertWorkflowNode = (current: WorkflowProcess | undefined, data: NodeTrac
|
|||
|
||||
return updateWorkflowProcess(current, (draft) => {
|
||||
draft.expand = true
|
||||
const currentIndex = draft.tracing.findIndex(item => item.node_id === data.node_id)
|
||||
const nextTrace = {
|
||||
...data,
|
||||
status: NodeRunningStatus.Running,
|
||||
expand: true,
|
||||
}
|
||||
|
||||
if (currentIndex > -1)
|
||||
draft.tracing[currentIndex] = nextTrace
|
||||
else
|
||||
draft.tracing.push(nextTrace)
|
||||
upsertTopLevelTracingNodeOnStart(draft.tracing, nextTrace)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,13 +109,13 @@ describe('useWorkflowAgentLog', () => {
|
|||
const { result, store } = renderWorkflowHook(() => useWorkflowAgentLog(), {
|
||||
initialStoreState: {
|
||||
workflowRunningData: baseRunningData({
|
||||
tracing: [{ node_id: 'n1', execution_metadata: {} }],
|
||||
tracing: [{ id: 'trace-1', node_id: 'n1', execution_metadata: {} }],
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
result.current.handleWorkflowAgentLog({
|
||||
data: { node_id: 'n1', message_id: 'm1' },
|
||||
data: { node_id: 'n1', node_execution_id: 'trace-1', message_id: 'm1' },
|
||||
} as AgentLogResponse)
|
||||
|
||||
const trace = store.getState().workflowRunningData!.tracing![0]
|
||||
|
|
@ -128,6 +128,7 @@ describe('useWorkflowAgentLog', () => {
|
|||
initialStoreState: {
|
||||
workflowRunningData: baseRunningData({
|
||||
tracing: [{
|
||||
id: 'trace-1',
|
||||
node_id: 'n1',
|
||||
execution_metadata: { agent_log: [{ message_id: 'm1', text: 'log1' }] },
|
||||
}],
|
||||
|
|
@ -136,7 +137,7 @@ describe('useWorkflowAgentLog', () => {
|
|||
})
|
||||
|
||||
result.current.handleWorkflowAgentLog({
|
||||
data: { node_id: 'n1', message_id: 'm2' },
|
||||
data: { node_id: 'n1', node_execution_id: 'trace-1', message_id: 'm2' },
|
||||
} as AgentLogResponse)
|
||||
|
||||
expect(store.getState().workflowRunningData!.tracing![0].execution_metadata!.agent_log).toHaveLength(2)
|
||||
|
|
@ -147,6 +148,7 @@ describe('useWorkflowAgentLog', () => {
|
|||
initialStoreState: {
|
||||
workflowRunningData: baseRunningData({
|
||||
tracing: [{
|
||||
id: 'trace-1',
|
||||
node_id: 'n1',
|
||||
execution_metadata: { agent_log: [{ message_id: 'm1', text: 'old' }] },
|
||||
}],
|
||||
|
|
@ -155,7 +157,7 @@ describe('useWorkflowAgentLog', () => {
|
|||
})
|
||||
|
||||
result.current.handleWorkflowAgentLog({
|
||||
data: { node_id: 'n1', message_id: 'm1', text: 'new' },
|
||||
data: { node_id: 'n1', node_execution_id: 'trace-1', message_id: 'm1', text: 'new' },
|
||||
} as unknown as AgentLogResponse)
|
||||
|
||||
const log = store.getState().workflowRunningData!.tracing![0].execution_metadata!.agent_log!
|
||||
|
|
@ -167,13 +169,13 @@ describe('useWorkflowAgentLog', () => {
|
|||
const { result, store } = renderWorkflowHook(() => useWorkflowAgentLog(), {
|
||||
initialStoreState: {
|
||||
workflowRunningData: baseRunningData({
|
||||
tracing: [{ node_id: 'n1' }],
|
||||
tracing: [{ id: 'trace-1', node_id: 'n1' }],
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
result.current.handleWorkflowAgentLog({
|
||||
data: { node_id: 'n1', message_id: 'm1' },
|
||||
data: { node_id: 'n1', node_execution_id: 'trace-1', message_id: 'm1' },
|
||||
} as AgentLogResponse)
|
||||
|
||||
expect(store.getState().workflowRunningData!.tracing![0].execution_metadata!.agent_log).toHaveLength(1)
|
||||
|
|
@ -200,6 +202,22 @@ describe('useWorkflowAgentLog', () => {
|
|||
expect(tracing[1].execution_metadata!.agent_log).toHaveLength(1)
|
||||
expect(tracing[1].execution_metadata!.agent_log![0].message_id).toBe('m2')
|
||||
})
|
||||
|
||||
it('should ignore agent logs when node_execution_id is missing', () => {
|
||||
const { result, store } = renderWorkflowHook(() => useWorkflowAgentLog(), {
|
||||
initialStoreState: {
|
||||
workflowRunningData: baseRunningData({
|
||||
tracing: [{ id: 'trace-1', node_id: 'n1', execution_metadata: {} }],
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
result.current.handleWorkflowAgentLog({
|
||||
data: { node_id: 'n1', message_id: 'm1' },
|
||||
} as AgentLogResponse)
|
||||
|
||||
expect(store.getState().workflowRunningData!.tracing![0].execution_metadata!.agent_log).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('useWorkflowNodeHumanInputFormFilled', () => {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ describe('useWorkflowNodeStarted', () => {
|
|||
})
|
||||
|
||||
result.current.handleWorkflowNodeStarted(
|
||||
{ data: { node_id: 'n1' } } as NodeStartedResponse,
|
||||
{ data: { id: 'trace-n1', node_id: 'n1' } } as NodeStartedResponse,
|
||||
containerParams,
|
||||
)
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ describe('useWorkflowNodeStarted', () => {
|
|||
})
|
||||
|
||||
result.current.handleWorkflowNodeStarted(
|
||||
{ data: { node_id: 'n2' } } as NodeStartedResponse,
|
||||
{ data: { id: 'trace-n2', node_id: 'n2' } } as NodeStartedResponse,
|
||||
containerParams,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,11 @@ export const useWorkflowAgentLog = () => {
|
|||
setWorkflowRunningData,
|
||||
} = workflowStore.getState()
|
||||
|
||||
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
|
||||
const currentIndex = draft.tracing!.findIndex((item) => {
|
||||
if (data.node_execution_id)
|
||||
return item.id === data.node_execution_id
|
||||
if (!data.node_execution_id)
|
||||
return
|
||||
|
||||
return item.node_id === data.node_id
|
||||
})
|
||||
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
|
||||
const currentIndex = draft.tracing!.findIndex(item => item.id === data.node_execution_id)
|
||||
if (currentIndex > -1) {
|
||||
const current = draft.tracing![currentIndex]
|
||||
|
||||
|
|
|
|||
|
|
@ -530,7 +530,10 @@ export const useChat = (
|
|||
}
|
||||
},
|
||||
onAgentLog: ({ data }) => {
|
||||
const currentNodeIndex = responseItem.workflowProcess!.tracing!.findIndex(item => item.node_id === data.node_id)
|
||||
if (!data.node_execution_id)
|
||||
return
|
||||
|
||||
const currentNodeIndex = responseItem.workflowProcess!.tracing!.findIndex(item => item.id === data.node_execution_id)
|
||||
if (currentNodeIndex > -1) {
|
||||
const current = responseItem.workflowProcess!.tracing![currentNodeIndex]
|
||||
|
||||
|
|
@ -775,7 +778,7 @@ export const useChat = (
|
|||
|
||||
upsertTopLevelTracingNodeOnStart(responseItem.workflowProcess.tracing, {
|
||||
...nodeStartedData,
|
||||
status: WorkflowRunningStatus.Running,
|
||||
status: NodeRunningStatus.Running,
|
||||
})
|
||||
})
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue