Skip to content

Commit

Permalink
Change design for batch evaluation run progress bar.
Browse files Browse the repository at this point in the history
We unify in a unique line completed and errored evaluation counters
  • Loading branch information
andresgutgon committed Oct 21, 2024
1 parent 428dae3 commit 36fb537
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use client'

import {
CommitStatus,
DocumentVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,36 @@

import { useEffect, useRef, useState } from 'react'

import { ProgressIndicator } from '@latitude-data/web-ui'
import { Badge, Text } from '@latitude-data/web-ui'
import { type EventArgs } from '$/components/Providers/WebsocketsProvider/useSockets'

import { isEvaluationRunDone } from '../../../_lib/isEvaluationRunDone'
import { useEvaluationStatusEvent } from '../../../_lib/useEvaluationStatusEvent'

const DISAPERING_IN_MS = 5000

function BatchIndicator({ job }: { job: EventArgs<'evaluationStatus'> }) {
const isDone = isEvaluationRunDone(job)
const badgeLabel = isDone ? 'Finished' : 'Running'
const doneRuns = job.completed + job.errors
return (
<div className='flex flex-row items-center gap-x-4'>
<Badge variant={isDone ? 'muted' : 'accent'}>{badgeLabel}</Badge>
<div className='flex flex-row items-center gap-x-2'>
<Text.H5>{`${doneRuns} of ${job.total} generated`}</Text.H5>
{job.errors > 0 ? (
<>
<Text.H5 color='foregroundMuted'>·</Text.H5>
<Text.H5 color='destructiveMutedForeground'>
{job.errors} Errors
</Text.H5>
</>
) : null}
</div>
</div>
)
}

export function EvaluationStatusBanner({
documentUuid,
evaluationId,
Expand Down Expand Up @@ -59,27 +81,11 @@ export function EvaluationStatusBanner({
return (
<>
{jobs.map((job) => (
<div key={job.batchId} className='flex flex-col gap-4'>
{!isEvaluationRunDone(job) && (
<ProgressIndicator state='running'>
{`Running batch evaluation ${job.completed}/${job.total}`}
</ProgressIndicator>
)}
{job.errors > 0 && (
<ProgressIndicator state='error'>
Some evaluations failed to run. We won't retry them automatically
to avoid increasing provider costs. Total errors:{' '}
<strong>{job.errors}</strong>
</ProgressIndicator>
)}
{isEvaluationRunDone(job) && (
<ProgressIndicator state='completed'>
Batch evaluation completed! Total evaluations:{' '}
<strong>{job.total}</strong> · Total errors:{' '}
<strong>{job.errors}</strong> · Total completed:{' '}
<strong>{job.completed}</strong>
</ProgressIndicator>
)}
<div
key={job.batchId}
className='flex flex-col gap-4 p-4 rounded-lg border border-border'
>
<BatchIndicator job={job} />
</div>
))}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,39 @@ describe('runEvaluationJob', () => {
})
})

it('increment error counter when response has an error', async () => {
runChainResponse = Result.error(
new ChainError({
code: RunErrorCodes.EvaluationRunResponseJsonFormatError,
message: 'malformed json response',
}),
)
runEvaluationSpy.mockResolvedValueOnce(
Result.ok({
stream,
response: new Promise((resolve) => resolve(runChainResponse)),
resolvedContent: 'chain resolved text',
errorableUuid: FAKE_ERRORABLE_UUID,
duration: new Promise((resolve) => resolve(1000)),
}),
)

await runEvaluationJob(jobData)

expect(websockets.WebsocketClient.getSocket).toHaveBeenCalledTimes(1)
expect(incrementErrorsSpy).toHaveBeenCalledTimes(1)
expect(mockEmit).toHaveBeenCalledWith('evaluationStatus', {
workspaceId: workspace.id,
data: {
batchId: 'batch-123',
evaluationId: evaluation.id,
documentUuid,
completed: 1,
total: 1,
},
})
})

it('throws an error if runEvaluation fails', async () => {
runEvaluationSpy.mockRejectedValue(new Error('Some error'))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ export type RunEvaluationJobData = {
batchId: string
}

async function isSuccessful(run: Awaited<ReturnType<typeof runEvaluation>>) {
if (run.error) return { ok: false, error: run.error }

const response = await run.value.response
if (response.error) return { ok: false, error: response.error }

return { ok: true, error: undefined }
}

export async function runEvaluationJob(job: Job<RunEvaluationJobData>) {
const { workspaceId, batchId, documentUuid, documentLogUuid, evaluationId } =
job.data
Expand All @@ -72,13 +81,15 @@ export async function runEvaluationJob(job: Job<RunEvaluationJobData>) {
documentLogUuid,
}).then((r) => r.unwrap())

const result = await runEvaluation({
const run = await runEvaluation({
documentLog,
evaluation,
documentUuid,
})

if (result.ok) {
const { ok, error } = await isSuccessful(run)

if (ok) {
await progressTracker.incrementCompleted()
} else {
await progressTracker.incrementErrors()
Expand All @@ -96,5 +107,5 @@ export async function runEvaluationJob(job: Job<RunEvaluationJobData>) {
},
})

throwIfUnknownError(result.error)
throwIfUnknownError(error)
}
38 changes: 1 addition & 37 deletions packages/web-ui/src/ds/atoms/Alert/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ReactNode } from 'react'

import { cn } from '../../../lib/utils'
import { Icon, IconName } from '../Icons'
import { Icon } from '../Icons'
import {
AlertDescription,
AlertProps,
Expand Down Expand Up @@ -36,38 +35,3 @@ export function Alert({
</AlertRoot>
)
}

type ProgressState = 'completed' | 'error' | 'running'
const ICON_NAME: Record<ProgressState, IconName> = {
completed: 'check',
error: 'alert',
running: 'refresh',
}
const VARIANT_PROGRESS: Record<ProgressState, AlertProps['variant']> = {
completed: 'success',
error: 'destructive',
running: 'default',
}

type ProgressIndicatorProps = {
children: ReactNode
state?: ProgressState
}
export function ProgressIndicator({
children,
state = 'completed',
}: ProgressIndicatorProps) {
const running = state === 'running'
const variant = VARIANT_PROGRESS[state]
return (
<AlertRoot variant={variant}>
<div className='flex flex-row items-center gap-x-2'>
<Icon
name={ICON_NAME[state]}
className={cn({ 'animate-spin': running })}
/>
<div>{children}</div>
</div>
</AlertRoot>
)
}

0 comments on commit 36fb537

Please sign in to comment.