diff --git a/apps/web/src/actions/evaluations/computeEvaluationResultsWithMetadata.ts b/apps/web/src/actions/evaluations/computeEvaluationResultsWithMetadata.ts
new file mode 100644
index 000000000..1520853b9
--- /dev/null
+++ b/apps/web/src/actions/evaluations/computeEvaluationResultsWithMetadata.ts
@@ -0,0 +1,40 @@
+'use server'
+
+import {
+ CommitsRepository,
+ EvaluationsRepository,
+} from '@latitude-data/core/repositories'
+import { computeEvaluationResultsWithMetadata } from '@latitude-data/core/services/evaluationResults/computeEvaluationResultsWithMetadata'
+import { z } from 'zod'
+
+import { withProject } from '../procedures'
+
+export const computeEvaluationResultsWithMetadataAction = withProject
+ .createServerAction()
+ .input(
+ z.object({
+ evaluationId: z.number(),
+ documentUuid: z.string(),
+ commitUuid: z.string(),
+ }),
+ )
+ .handler(async ({ input, ctx }) => {
+ const { documentUuid } = input
+ const { workspace, project } = ctx
+ const commitsScope = new CommitsRepository(workspace.id)
+ const evaluationScope = new EvaluationsRepository(workspace.id)
+ const evaluation = await evaluationScope
+ .find(input.evaluationId)
+ .then((r) => r.unwrap())
+ const commit = await commitsScope
+ .getCommitByUuid({ projectId: project.id, uuid: input.commitUuid })
+ .then((r) => r.unwrap())
+
+ return await computeEvaluationResultsWithMetadata({
+ workspaceId: ctx.workspace.id,
+ evaluation,
+ documentUuid,
+ draft: commit,
+ limit: 1000,
+ }).then((r) => r.unwrap())
+ })
diff --git a/apps/web/src/actions/evaluations/runBatch.ts b/apps/web/src/actions/evaluations/runBatch.ts
index b15d8d7f0..ed3696099 100644
--- a/apps/web/src/actions/evaluations/runBatch.ts
+++ b/apps/web/src/actions/evaluations/runBatch.ts
@@ -10,11 +10,11 @@ import { nanoid } from 'nanoid'
import { z } from 'zod'
import { createServerActionProcedure } from 'zsa'
-import { widthDocument } from '../procedures'
+import { withDocument } from '../procedures'
const USER_DECIDED_TO_IGNORE_THIS_PARAMETER = -1
-const withDataset = createServerActionProcedure(widthDocument)
+const withDataset = createServerActionProcedure(withDocument)
.input(z.object({ datasetId: z.number() }))
.handler(async ({ input, ctx }) => {
const datasetsRepo = new DatasetsRepository(ctx.workspace.id)
diff --git a/apps/web/src/actions/procedures/index.ts b/apps/web/src/actions/procedures/index.ts
index c5ae1fabd..32512117c 100644
--- a/apps/web/src/actions/procedures/index.ts
+++ b/apps/web/src/actions/procedures/index.ts
@@ -54,7 +54,7 @@ export const withProject = createServerActionProcedure(authProcedure)
return { ...ctx, project }
})
-export const widthDocument = createServerActionProcedure(withProject)
+export const withDocument = createServerActionProcedure(withProject)
.input(z.object({ commitUuid: z.string(), documentUuid: z.string() }))
.handler(async ({ input, ctx }) => {
const repo = new DocumentVersionsRepository(ctx.workspace.id)
diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/_components/EvaluationResults/EvaluationResultInfo/Messages.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/_components/EvaluationResults/EvaluationResultInfo/Messages.tsx
index 3d76def6c..38c540076 100644
--- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/_components/EvaluationResults/EvaluationResultInfo/Messages.tsx
+++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/_components/EvaluationResults/EvaluationResultInfo/Messages.tsx
@@ -25,6 +25,7 @@ export function EvaluationResultMessages({
return (
(undefined)
+ const document = useCurrentDocument()
+ const { project } = useCurrentProject()
+ const { commit } = useCurrentCommit()
+ const { data: evaluationResults, mutate } = useEvaluationResultsWithMetadata(
+ {
+ evaluationId: evaluation.id,
+ documentUuid: document.documentUuid,
+ commitUuid: commit.uuid,
+ projectId: project.id,
+ },
+ {
+ fallbackData: serverData,
+ },
+ )
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ mutate()
+ }, FIVE_SECONDS)
+
+ return () => clearInterval(interval)
+ }, [mutate])
const { data: providerLog } = useProviderLog(selectedResult?.providerLogId)
return (
diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/layout.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/layout.tsx
index 293d97ccb..49c28dab3 100644
--- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/layout.tsx
+++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/layout.tsx
@@ -40,6 +40,7 @@ export default async function ConnectedEvaluationLayout({
evaluation,
documentUuid: params.documentUuid,
draft: commit,
+ limit: 1000,
}).then((r) => r.unwrap())
return (
diff --git a/apps/web/src/stores/evaluationResultsWithMetadata.ts b/apps/web/src/stores/evaluationResultsWithMetadata.ts
new file mode 100644
index 000000000..760099fe5
--- /dev/null
+++ b/apps/web/src/stores/evaluationResultsWithMetadata.ts
@@ -0,0 +1,51 @@
+import { useMemo } from 'react'
+
+import { EvaluationResultWithMetadata } from '@latitude-data/core/repositories'
+import { useToast } from '@latitude-data/web-ui'
+import { computeEvaluationResultsWithMetadataAction } from '$/actions/evaluations/computeEvaluationResultsWithMetadata'
+import useSWR, { SWRConfiguration } from 'swr'
+
+const EMPTY_ARRAY: [] = []
+export default function useEvaluationResultsWithMetadata(
+ {
+ evaluationId,
+ documentUuid,
+ commitUuid,
+ projectId,
+ }: {
+ evaluationId: number
+ documentUuid: string
+ commitUuid: string
+ projectId: number
+ },
+ opts: SWRConfiguration,
+) {
+ const { toast } = useToast()
+ const { data = EMPTY_ARRAY, ...rest } = useSWR<
+ EvaluationResultWithMetadata[]
+ >(
+ ['evaluationResults', evaluationId, documentUuid, commitUuid, projectId],
+ async () => {
+ const [data, error] = await computeEvaluationResultsWithMetadataAction({
+ evaluationId,
+ documentUuid,
+ commitUuid,
+ projectId,
+ })
+
+ if (error) {
+ toast({
+ title: 'Error fetching evaluations',
+ description: error.formErrors?.[0] || error.message,
+ variant: 'destructive',
+ })
+ throw error
+ }
+
+ return data
+ },
+ opts,
+ )
+
+ return useMemo(() => ({ data, ...rest }), [data, rest])
+}
diff --git a/packages/core/src/services/evaluationResults/computeEvaluationResultsWithMetadata.ts b/packages/core/src/services/evaluationResults/computeEvaluationResultsWithMetadata.ts
index 2c31443de..d8780cb78 100644
--- a/packages/core/src/services/evaluationResults/computeEvaluationResultsWithMetadata.ts
+++ b/packages/core/src/services/evaluationResults/computeEvaluationResultsWithMetadata.ts
@@ -15,18 +15,20 @@ export async function computeEvaluationResultsWithMetadata(
evaluation,
documentUuid,
draft,
+ limit,
}: {
workspaceId: number
evaluation: Evaluation
documentUuid: string
draft?: Commit
+ limit?: number
},
db = database,
): Promise> {
const { evaluationResultsScope, documentLogsScope, baseQuery } =
createEvaluationResultQuery(workspaceId, db)
- const result = await baseQuery
+ const query = baseQuery
.where(
and(
eq(evaluationResultsScope.evaluationId, evaluation.id),
@@ -36,5 +38,7 @@ export async function computeEvaluationResultsWithMetadata(
)
.orderBy(desc(evaluationResultsScope.createdAt))
+ const result = await (limit ? query.limit(limit) : query)
+
return Result.ok(result)
}
diff --git a/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.test.ts b/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.test.ts
index 7c31072f8..d24ce70ea 100644
--- a/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.test.ts
+++ b/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.test.ts
@@ -97,13 +97,16 @@ describe('runDocumentJob', () => {
expect(
mocks.queues.defaultQueue.jobs.enqueueRunEvaluationJob,
- ).toHaveBeenCalledWith({
- workspaceId: workspace.id,
- documentUuid: document.documentUuid,
- documentLogUuid: 'log1',
- evaluationId: evaluation.id,
- batchId: 'batch1',
- })
+ ).toHaveBeenCalledWith(
+ {
+ workspaceId: workspace.id,
+ documentUuid: document.documentUuid,
+ documentLogUuid: 'log1',
+ evaluationId: evaluation.id,
+ batchId: 'batch1',
+ },
+ { lifo: true },
+ )
expect(ProgressTracker.prototype.incrementErrors).not.toHaveBeenCalled()
expect(ProgressTracker.prototype.decrementTotal).not.toHaveBeenCalled()
diff --git a/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.ts b/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.ts
index 2513d8dac..4770308ad 100644
--- a/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.ts
+++ b/packages/jobs/src/job-definitions/batchEvaluations/runDocumentJob.ts
@@ -61,13 +61,16 @@ export const runDocumentJob = async (job: Job) => {
const queues = await setupJobs()
// Enqueue the evaluation job
- await queues.defaultQueue.jobs.enqueueRunEvaluationJob({
- workspaceId,
- documentUuid: document.documentUuid,
- documentLogUuid: result.documentLogUuid,
- evaluationId,
- batchId,
- })
+ await queues.defaultQueue.jobs.enqueueRunEvaluationJob(
+ {
+ workspaceId,
+ documentUuid: document.documentUuid,
+ documentLogUuid: result.documentLogUuid,
+ evaluationId,
+ batchId,
+ },
+ { lifo: true },
+ )
} catch (error) {
if (env.NODE_ENV !== 'production') {
console.error(error)
diff --git a/packages/web-ui/src/ds/molecules/Chat/MessageList/index.tsx b/packages/web-ui/src/ds/molecules/Chat/MessageList/index.tsx
index d1683bffa..8cdb6ab62 100644
--- a/packages/web-ui/src/ds/molecules/Chat/MessageList/index.tsx
+++ b/packages/web-ui/src/ds/molecules/Chat/MessageList/index.tsx
@@ -1,6 +1,10 @@
+'use client'
+
+import { Fragment, useState } from 'react'
+
import { Message as ConversationMessage } from '@latitude-data/compiler'
-import { Fragment } from 'react/jsx-runtime'
+import { Button } from '../../../atoms'
import { Message, MessageProps } from '../Message'
export function MessageList({
@@ -8,29 +12,66 @@ export function MessageList({
variant,
messageLayout,
separator = false,
+ collapsed = false,
size,
}: {
messages: ConversationMessage[]
variant?: MessageProps['variant']
messageLayout?: MessageProps['layout']
+ collapsed?: boolean
size?: MessageProps['size']
separator?: boolean
}) {
- return messages.map((message, index) => (
-
- {separator && index > 0 && (
-
+ const [isCollapsed, setIsCollapsed] = useState(
+ collapsed && messages.length > 1,
+ )
+
+ const visibleMessages = isCollapsed ? messages.slice(-1) : messages
+ const hiddenMessagesCount = messages.length - visibleMessages.length
+
+ return (
+
+ {isCollapsed && messages.length > 1 && (
+
+
+
+
+
+
+
+
+
+ )}
+ {visibleMessages.map((message, index) => (
+
+ {separator && index > 0 && (
+
+ )}
+
+
+ ))}
+ {!isCollapsed && messages.length > 1 && (
+
+
+
)}
-
-
- ))
+
+ )
}