diff --git a/web/app/components/base/chat/chat/hooks.ts b/web/app/components/base/chat/chat/hooks.ts index 7e780079c5..51e6ad7560 100644 --- a/web/app/components/base/chat/chat/hooks.ts +++ b/web/app/components/base/chat/chat/hooks.ts @@ -12,6 +12,7 @@ import type { IOnDataMoreInfo, IOtherOptions, } from '@/service/base' +import type { NodeTracing } from '@/types/workflow' import { uniqBy } from 'es-toolkit/compat' import { noop } from 'es-toolkit/function' import { produce, setAutoFreeze } from 'immer' @@ -53,6 +54,39 @@ type SendCallback = { isPublicAPI?: boolean } +type ParallelTraceLike = Pick + +const findParallelTraceIndex = ( + tracing: ParallelTraceLike[], + data: Partial, +) => { + const incomingParallelId = data.execution_metadata?.parallel_id ?? data.parallel_id + + if (data.id) { + const matchedByIdIndex = tracing.findIndex((item) => { + if (item.id !== data.id) + return false + + const existingParallelId = item.execution_metadata?.parallel_id ?? item.parallel_id + if (!existingParallelId || !incomingParallelId) + return true + + return existingParallelId === incomingParallelId + }) + + if (matchedByIdIndex > -1) + return matchedByIdIndex + } + + return tracing.findIndex((item) => { + if (item.node_id !== data.node_id) + return false + + const existingParallelId = item.execution_metadata?.parallel_id ?? item.parallel_id + return existingParallelId === incomingParallelId + }) +} + export const useChat = ( config?: ChatConfig, formSettings?: { @@ -396,7 +430,7 @@ export const useChat = ( if (!responseItem.workflowProcess?.tracing) return const tracing = responseItem.workflowProcess.tracing - const iterationIndex = tracing.findIndex(item => item.id === iterationFinishedData.id)! + const iterationIndex = findParallelTraceIndex(tracing, iterationFinishedData) if (iterationIndex > -1) { tracing[iterationIndex] = { ...tracing[iterationIndex], @@ -477,7 +511,7 @@ export const useChat = ( if (!responseItem.workflowProcess?.tracing) return const tracing = responseItem.workflowProcess.tracing - const loopIndex = tracing.findIndex(item => item.id === loopFinishedData.id)! + const loopIndex = findParallelTraceIndex(tracing, loopFinishedData) if (loopIndex > -1) { tracing[loopIndex] = { ...tracing[loopIndex], @@ -943,7 +977,7 @@ export const useChat = ( }, onIterationFinish: ({ data: iterationFinishedData }) => { const tracing = responseItem.workflowProcess!.tracing! - const iterationIndex = tracing.findIndex(item => item.id === iterationFinishedData.id)! + const iterationIndex = findParallelTraceIndex(tracing, iterationFinishedData) if (iterationIndex > -1) { tracing[iterationIndex] = { ...tracing[iterationIndex], @@ -1034,7 +1068,7 @@ export const useChat = ( }, onLoopFinish: ({ data: loopFinishedData }) => { const tracing = responseItem.workflowProcess!.tracing! - const loopIndex = tracing.findIndex(item => item.id === loopFinishedData.id)! + const loopIndex = findParallelTraceIndex(tracing, loopFinishedData) if (loopIndex > -1) { tracing[loopIndex] = { ...tracing[loopIndex], diff --git a/web/app/components/datasets/create/website/jina-reader/__tests__/base.spec.tsx b/web/app/components/datasets/create/website/jina-reader/__tests__/base.spec.tsx index bcfcf39060..953604e5c6 100644 --- a/web/app/components/datasets/create/website/jina-reader/__tests__/base.spec.tsx +++ b/web/app/components/datasets/create/website/jina-reader/__tests__/base.spec.tsx @@ -264,7 +264,7 @@ describe('UrlInput', () => { render() const input = screen.getByRole('textbox') - await userEvent.type(input, longUrl) + fireEvent.change(input, { target: { value: longUrl } }) expect(input).toHaveValue(longUrl) }) @@ -275,7 +275,7 @@ describe('UrlInput', () => { render() const input = screen.getByRole('textbox') - await userEvent.type(input, unicodeUrl) + fireEvent.change(input, { target: { value: unicodeUrl } }) expect(input).toHaveValue(unicodeUrl) }) @@ -285,7 +285,7 @@ describe('UrlInput', () => { render() const input = screen.getByRole('textbox') - await userEvent.type(input, 'https://rapid.com', { delay: 1 }) + fireEvent.change(input, { target: { value: 'https://rapid.com' } }) expect(input).toHaveValue('https://rapid.com') }) @@ -297,7 +297,7 @@ describe('UrlInput', () => { render() const input = screen.getByRole('textbox') - await userEvent.type(input, 'https://enter.com') + fireEvent.change(input, { target: { value: 'https://enter.com' } }) // Focus button and press enter const button = screen.getByRole('button', { name: /run/i }) diff --git a/web/app/components/datasets/list/dataset-card/hooks/__tests__/use-dataset-card-state.spec.ts b/web/app/components/datasets/list/dataset-card/hooks/__tests__/use-dataset-card-state.spec.ts index 63ac30630e..2af16ee5f9 100644 --- a/web/app/components/datasets/list/dataset-card/hooks/__tests__/use-dataset-card-state.spec.ts +++ b/web/app/components/datasets/list/dataset-card/hooks/__tests__/use-dataset-card-state.spec.ts @@ -151,7 +151,7 @@ describe('useDatasetCardState', () => { expect(result.current.modalState.showRenameModal).toBe(false) }) - it('should close confirm delete modal when closeConfirmDelete is called', () => { + it('should close confirm delete modal when closeConfirmDelete is called', async () => { const dataset = createMockDataset() const { result } = renderHook(() => useDatasetCardState({ dataset, onSuccess: vi.fn() }), @@ -162,7 +162,7 @@ describe('useDatasetCardState', () => { result.current.detectIsUsedByApp() }) - waitFor(() => { + await waitFor(() => { expect(result.current.modalState.showConfirmDelete).toBe(true) })