diff --git a/web/app/components/share/text-generation/result/__tests__/workflow-stream-handlers.spec.ts b/web/app/components/share/text-generation/result/__tests__/workflow-stream-handlers.spec.ts index 703d43cf3f..8785e77d1e 100644 --- a/web/app/components/share/text-generation/result/__tests__/workflow-stream-handlers.spec.ts +++ b/web/app/components/share/text-generation/result/__tests__/workflow-stream-handlers.spec.ts @@ -163,6 +163,72 @@ describe('workflow-stream-handlers helpers', () => { expect(nextProcess.tracing[0]?.details).toEqual([[], []]) }) + it('should keep separate iteration and loop traces for repeated executions with different ids', () => { + const process = createWorkflowProcess() + process.tracing = [ + createTrace({ + id: 'iter-trace-1', + node_id: 'iter-1', + details: [[]], + }), + createTrace({ + id: 'iter-trace-2', + node_id: 'iter-1', + details: [[]], + }), + createTrace({ + id: 'loop-trace-1', + node_id: 'loop-1', + details: [[]], + }), + createTrace({ + id: 'loop-trace-2', + node_id: 'loop-1', + details: [[]], + }), + ] + + const iterNextProcess = appendParallelNext(process, createTrace({ + id: 'iter-trace-2', + node_id: 'iter-1', + })) + const iterFinishedProcess = finishParallelTrace(iterNextProcess, createTrace({ + id: 'iter-trace-2', + node_id: 'iter-1', + status: NodeRunningStatus.Succeeded, + })) + const loopNextProcess = appendParallelNext(iterFinishedProcess, createTrace({ + id: 'loop-trace-2', + node_id: 'loop-1', + })) + const loopFinishedProcess = finishParallelTrace(loopNextProcess, createTrace({ + id: 'loop-trace-2', + node_id: 'loop-1', + status: NodeRunningStatus.Succeeded, + })) + + expect(loopFinishedProcess.tracing[0]).toEqual(expect.objectContaining({ + id: 'iter-trace-1', + details: [[]], + status: NodeRunningStatus.Running, + })) + expect(loopFinishedProcess.tracing[1]).toEqual(expect.objectContaining({ + id: 'iter-trace-2', + details: [[], []], + status: NodeRunningStatus.Succeeded, + })) + expect(loopFinishedProcess.tracing[2]).toEqual(expect.objectContaining({ + id: 'loop-trace-1', + details: [[]], + status: NodeRunningStatus.Running, + })) + expect(loopFinishedProcess.tracing[3]).toEqual(expect.objectContaining({ + id: 'loop-trace-2', + details: [[], []], + status: NodeRunningStatus.Succeeded, + })) + }) + it('should append a new top-level trace when the same node starts with a different execution id', () => { const process = createWorkflowProcess() process.tracing = [ diff --git a/web/app/components/share/text-generation/result/workflow-stream-handlers.ts b/web/app/components/share/text-generation/result/workflow-stream-handlers.ts index a89cef962a..d4ea59d51e 100644 --- a/web/app/components/share/text-generation/result/workflow-stream-handlers.ts +++ b/web/app/components/share/text-generation/result/workflow-stream-handlers.ts @@ -50,6 +50,15 @@ const matchParallelTrace = (trace: WorkflowProcess['tracing'][number], data: Nod || trace.parallel_id === data.execution_metadata?.parallel_id) } +const findParallelTraceIndex = (tracing: WorkflowProcess['tracing'], data: NodeTracing) => { + return tracing.findIndex((trace) => { + if (trace.id && data.id) + return trace.id === data.id + + return matchParallelTrace(trace, data) + }) +} + const ensureParallelTraceDetails = (details?: NodeTracing['details']) => { return details?.length ? details : [[]] } @@ -69,7 +78,8 @@ const appendParallelStart = (current: WorkflowProcess | undefined, data: NodeTra const appendParallelNext = (current: WorkflowProcess | undefined, data: NodeTracing) => { return updateWorkflowProcess(current, (draft) => { draft.expand = true - const trace = draft.tracing.find(item => matchParallelTrace(item, data)) + const traceIndex = findParallelTraceIndex(draft.tracing, data) + const trace = draft.tracing[traceIndex] if (!trace) return @@ -81,7 +91,7 @@ const appendParallelNext = (current: WorkflowProcess | undefined, data: NodeTrac const finishParallelTrace = (current: WorkflowProcess | undefined, data: NodeTracing) => { return updateWorkflowProcess(current, (draft) => { draft.expand = true - const traceIndex = draft.tracing.findIndex(item => matchParallelTrace(item, data)) + const traceIndex = findParallelTraceIndex(draft.tracing, data) if (traceIndex > -1) { draft.tracing[traceIndex] = { ...data,