diff --git a/apps/database/fly.toml b/apps/database/fly.toml deleted file mode 100644 index 0afbceb33..000000000 --- a/apps/database/fly.toml +++ /dev/null @@ -1,68 +0,0 @@ -# fly.toml app configuration file generated for latitude-llm-database on 2024-08-13T08:54:27+02:00 -# -# See https://fly.io/docs/reference/configuration/ for information about how to use this file. -# - -app = 'latitude-llm-database' -primary_region = 'mad' - -[env] - PRIMARY_REGION = 'mad' - -[[mounts]] - source = 'pg_data' - destination = '/data' - -[[services]] - protocol = 'tcp' - internal_port = 5432 - auto_start_machines = true - - [[services.ports]] - port = 5432 - handlers = ['pg_tls'] - - [services.concurrency] - type = 'connections' - hard_limit = 1000 - soft_limit = 1000 - -[[services]] - protocol = 'tcp' - internal_port = 5433 - auto_start_machines = true - - [[services.ports]] - port = 5433 - handlers = ['pg_tls'] - - [services.concurrency] - type = 'connections' - hard_limit = 1000 - soft_limit = 1000 - -[checks] - [checks.pg] - port = 5500 - type = 'http' - interval = '15s' - timeout = '10s' - path = '/flycheck/pg' - - [checks.role] - port = 5500 - type = 'http' - interval = '15s' - timeout = '10s' - path = '/flycheck/role' - - [checks.vm] - port = 5500 - type = 'http' - interval = '15s' - timeout = '10s' - path = '/flycheck/vm' - -[[metrics]] - port = 9187 - path = '/metrics' diff --git a/apps/web/src/actions/evaluations/connect.test.ts b/apps/web/src/actions/evaluations/connect.test.ts new file mode 100644 index 000000000..e7974eb4a --- /dev/null +++ b/apps/web/src/actions/evaluations/connect.test.ts @@ -0,0 +1,126 @@ +import { + DocumentVersion, + Project, + ProviderApiKey, + Providers, + User, + Workspace, +} from '@latitude-data/core/browser' +import * as factories from '@latitude-data/core/factories' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { connectEvaluationsAction } from './connect' + +const mocks = vi.hoisted(() => { + return { + getSession: vi.fn(), + } +}) + +vi.mock('$/services/auth/getSession', () => ({ + getSession: mocks.getSession, +})) + +describe('connectEvaluationsAction', () => { + describe('unauthorized', () => { + it('errors when the user is not authenticated', async () => { + const [_, error] = await connectEvaluationsAction({ + projectId: 1, + documentUuid: 'fake-document-uuid', + templateIds: [1], + evaluationUuids: ['fake-evaluation-uuid'], + }) + + expect(error!.name).toEqual('UnauthorizedError') + }) + }) + + describe('authorized', () => { + let workspace: Workspace, + user: User, + document: DocumentVersion, + provider: ProviderApiKey, + project: Project + + beforeEach(async () => { + const setup = await factories.createProject({ + documents: { 'test-doc': 'Test content' }, + }) + workspace = setup.workspace + user = setup.user + document = setup.documents[0]! + project = setup.project + + provider = await factories.createProviderApiKey({ + workspace, + type: Providers.OpenAI, + name: 'Test Provider', + user, + }) + + mocks.getSession.mockReturnValue({ + user, + workspace: { id: workspace.id, name: workspace.name }, + }) + }) + + it('connects evaluations and templates to a document', async () => { + const evaluation = await factories.createLlmAsJudgeEvaluation({ + workspace, + name: 'Test Evaluation', + prompt: factories.helpers.createPrompt({ provider }), + }) + + const template = await factories.createEvaluationTemplate({ + name: 'Test Template', + description: 'Test description', + prompt: 'Test prompt', + }) + + const [result, error] = await connectEvaluationsAction({ + projectId: project.id, + documentUuid: document.documentUuid, + templateIds: [template.id], + evaluationUuids: [evaluation.uuid], + }) + + expect(error).toBeNull() + expect(result).toHaveLength(2) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + documentUuid: document.documentUuid, + evaluationId: evaluation.id, + }), + expect.objectContaining({ + documentUuid: document.documentUuid, + evaluationId: expect.any(Number), + }), + ]), + ) + }) + + it('returns an empty array when no evaluations or templates are provided', async () => { + const [result, error] = await connectEvaluationsAction({ + projectId: project.id, + documentUuid: document.documentUuid, + templateIds: [], + evaluationUuids: [], + }) + + expect(error).toBeNull() + expect(result).toHaveLength(0) + }) + + it('fails when the document does not exist', async () => { + const [_, error] = await connectEvaluationsAction({ + projectId: project.id, + documentUuid: 'non-existent-uuid', + templateIds: [], + evaluationUuids: [], + }) + + expect(error!.name).toEqual('NotFoundError') + }) + }) +}) diff --git a/apps/web/src/actions/evaluations/connect.ts b/apps/web/src/actions/evaluations/connect.ts new file mode 100644 index 000000000..61da116b0 --- /dev/null +++ b/apps/web/src/actions/evaluations/connect.ts @@ -0,0 +1,26 @@ +'use server' + +import { connectEvaluations } from '@latitude-data/core/services/evaluations/connect' +import { z } from 'zod' + +import { withProject } from '../procedures' + +export const connectEvaluationsAction = withProject + .createServerAction() + .input( + z.object({ + documentUuid: z.string(), + templateIds: z.array(z.number()), + evaluationUuids: z.array(z.string()), + }), + ) + .handler(async ({ ctx, input }) => { + const connectedEvaluations = await connectEvaluations({ + workspace: ctx.workspace, + documentUuid: input.documentUuid, + evaluationUuids: input.evaluationUuids, + templateIds: input.templateIds, + }).then((r) => r.unwrap()) + + return connectedEvaluations + }) diff --git a/apps/web/src/app/(private)/evaluations/(evaluation)/[evaluationUuid]/dashboard/_components/ConnectedDocumentsTable/index.tsx b/apps/web/src/app/(private)/evaluations/(evaluation)/[evaluationUuid]/dashboard/_components/ConnectedDocumentsTable/index.tsx index 54957b189..959b18dc7 100644 --- a/apps/web/src/app/(private)/evaluations/(evaluation)/[evaluationUuid]/dashboard/_components/ConnectedDocumentsTable/index.tsx +++ b/apps/web/src/app/(private)/evaluations/(evaluation)/[evaluationUuid]/dashboard/_components/ConnectedDocumentsTable/index.tsx @@ -136,7 +136,7 @@ export default function ConnectedDocumentsTable({ .detail({ id: document.projectId }) .commits.detail({ uuid: HEAD_COMMIT }) .documents.detail({ uuid: document.documentUuid }) - .evaluations.detail(document.evaluationUuid).root, + .evaluations.detail(document.evaluationId).root, ) } /> diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/DatasetForm/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/DatasetForm/index.tsx similarity index 100% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/DatasetForm/index.tsx rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/DatasetForm/index.tsx diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/index.tsx similarity index 87% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/index.tsx rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/index.tsx index e64035cdf..6a9e19d9c 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/index.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/index.tsx @@ -12,7 +12,7 @@ import DatasetForm from './DatasetForm' import { useRunBatch } from './useRunBatch' import { useRunBatchForm } from './useRunBatchForm' -export default function ConnectDatasetModal({ +export default function CreateBatchEvaluationModal({ document, evaluation, documentMetadata, @@ -66,19 +66,19 @@ export default function ConnectDatasetModal({ .detail({ id: Number(projectId) }) .commits.detail({ uuid: commitUuid }) .documents.detail({ uuid: documentUuid }) - .evaluations.detail(evaluation.uuid).root, + .evaluations.detail(evaluation.id).root, ) }} footer={ <> - - + + } > diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/useRunBatch.ts b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/useRunBatch.ts similarity index 90% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/useRunBatch.ts rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/useRunBatch.ts index 3be569930..ee1991ed6 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/useRunBatch.ts +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/useRunBatch.ts @@ -14,8 +14,9 @@ export function useRunBatch({ document: DocumentVersion commitUuid: string }) { - const { execute: run, isPending: isRunning } = - useLatitudeAction(runBatchEvaluationAction) + const { execute: run, isPending: isRunning } = useLatitudeAction( + runBatchEvaluationAction, + ) const runBatch = useCallback( async ({ evaluationIds, @@ -33,7 +34,7 @@ export function useRunBatch({ parameters: RunBatchParameters }) => { console.log('RUNNING BATCH') - const [data, error] = await run({ + const [_data, _error] = await run({ projectId: Number(projectId), documentUuid: document.documentUuid, commitUuid, diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/useRunBatchForm.ts b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/useRunBatchForm.ts similarity index 100% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/_components/CreateBatchEvaluation/useRunBatchForm.ts rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/_components/CreateBatchEvaluationModal/useRunBatchForm.ts diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/page.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/page.tsx new file mode 100644 index 000000000..ff653902c --- /dev/null +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/create-batch/page.tsx @@ -0,0 +1,41 @@ +import { readMetadata } from '@latitude-data/compiler' +import { + getDocumentByUuidCached, + getEvaluationByUuidCached, +} from '$/app/(private)/_data-access' + +import CreateBatchEvaluationModal from './_components/CreateBatchEvaluationModal' + +export default async function ConnectionEvaluationModal({ + params, +}: { + params: { + projectId: string + commitUuid: string + documentUuid: string + evaluationUuid: string + } +}) { + const evaluation = await getEvaluationByUuidCached(params.evaluationUuid) + const projectId = Number(params.projectId) + const documentUuid = params.documentUuid + const commitUuid = params.commitUuid + const document = await getDocumentByUuidCached({ + projectId, + commitUuid, + documentUuid, + }) + const metadata = await readMetadata({ + prompt: document.content ?? '', + fullPath: document.path, + }) + return ( + + ) +} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/page.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/page.tsx new file mode 100644 index 000000000..3fa7db5ca --- /dev/null +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationId]/page.tsx @@ -0,0 +1,20 @@ +import { EvaluationsRepository } from '@latitude-data/core/repositories' +import { getCurrentUser } from '$/services/auth/getCurrentUser' + +export default async function EvaluationPage({ + params: { evaluationId }, +}: { + params: { evaluationId: string } +}) { + const { workspace } = await getCurrentUser() + const evaluationScope = new EvaluationsRepository(workspace.id) + const evaluation = await evaluationScope + .find(evaluationId) + .then((r) => r.unwrap()) + return ( +
+

{evaluation.name}

+

{evaluation.description || 'No description for this evaluation'}

+
+ ) +} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/page.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/page.tsx deleted file mode 100644 index 0786632dd..000000000 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/[evaluationUuid]/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { getEvaluationByUuidCached } from '$/app/(private)/_data-access' - -export default async function EvaluationPage({ - params: { evaluationUuid }, -}: { - params: { evaluationUuid: string } -}) { - const evaluation = await getEvaluationByUuidCached(evaluationUuid) - return ( -
-

{evaluation.name}

-

{evaluation.description || 'No description for this evaluation'}

-
- ) -} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/_components/BatchEvaluationsTable.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/_components/BatchEvaluationsTable.tsx index c2fa3330f..f5e8aedd8 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/_components/BatchEvaluationsTable.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/_components/BatchEvaluationsTable.tsx @@ -45,7 +45,7 @@ export default function BatchEvaluationsTable({ .detail({ id: project.id }) .commits.detail({ uuid: commit.uuid }) .documents.detail({ uuid: document.documentUuid }) - .evaluations.detail(evaluation.uuid).root, + .evaluations.detail(evaluation.id).root, ) } > @@ -57,13 +57,11 @@ export default function BatchEvaluationsTable({ e.stopPropagation()}> diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/EvaluationEditor.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/Editor/index.tsx similarity index 100% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/EvaluationEditor.tsx rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/Editor/index.tsx diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/EvaluationList.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/List/index.tsx similarity index 72% rename from apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/EvaluationList.tsx rename to apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/List/index.tsx index 5e0e4aca7..7803c1a9a 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/EvaluationList.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/List/index.tsx @@ -2,10 +2,14 @@ import React from 'react' import { Icon, Input, Text } from '@latitude-data/web-ui' -import { type FilteredItem } from './index' - interface EvaluationListProps { - items: FilteredItem[] + items: { + uuid: string + name: string + description: string + type: 'evaluation' | 'template' + }[] + selectedItems: string[] onSelectItem: (uuid: string) => void searchTerm: string onSearchChange: (term: string) => void @@ -13,6 +17,7 @@ interface EvaluationListProps { export default function EvaluationList({ items, + selectedItems, onSelectItem, searchTerm, onSearchChange, @@ -30,22 +35,31 @@ export default function EvaluationList({ {items.map((item) => (
  • onSelectItem(item.uuid)} > - {item.selected && } + {selectedItems.includes(item.uuid) && ( + + )}
    {item.name} - + {item.description.length > 45 ? `${item.description.slice(0, 42)}...` : item.description} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/index.tsx new file mode 100644 index 000000000..33d424570 --- /dev/null +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectEvaluationModal/index.tsx @@ -0,0 +1,191 @@ +'use client' + +import { useCallback, useMemo, useState } from 'react' +import { xorBy } from 'lodash-es' + +import { + EvaluationDto, + EvaluationTemplateCategory, +} from '@latitude-data/core/browser' +import { + Button, + CloseTrigger, + Icon, + Modal, + TableWithHeader, + Text, +} from '@latitude-data/web-ui' +import { connectEvaluationsAction } from '$/actions/evaluations/connect' +import useLatitudeAction from '$/hooks/useLatitudeAction' +import { useNavigate } from '$/hooks/useNavigate' +import { ROUTES } from '$/services/routes' +import useEvaluations from '$/stores/evaluations' +import useEvaluationTemplates from '$/stores/evaluationTemplates' +import Link from 'next/link' + +import EvaluationEditor from './Editor' +import EvaluationList from './List' + +type SelectableItem = { + uuid: string + name: string + description: string + type: 'evaluation' | 'template' + data: EvaluationDto | EvaluationTemplateCategory +} + +export default function ConnectionEvaluationModal({ + projectId, + commitUuid, + documentUuid, +}: { + projectId: string + commitUuid: string + documentUuid: string +}) { + const [selectedItems, setSelectedItems] = useState([]) + const { execute, isPending: isConnecting } = useLatitudeAction( + connectEvaluationsAction, + ) + const navigate = useNavigate() + const { data: usedEvaluations } = useEvaluations({ + params: { documentUuid }, + }) + const { + data: evaluations, + isLoading: isLoadingEvaluations, + mutate, + } = useEvaluations() + const { data: templates, isLoading: isLoadingTemplates } = + useEvaluationTemplates() + const [searchTerm, setSearchTerm] = useState('') + + const selectableItems: SelectableItem[] = useMemo(() => { + const evaluationItems = xorBy( + evaluations, + usedEvaluations, + (ev) => ev.id, + ).map((e) => ({ + uuid: e.uuid, + name: e.name, + description: e.description, + type: 'evaluation' as const, + data: e, + })) + const templateItems = templates.map((t) => ({ + uuid: t.id.toString(), + name: t.name, + description: t.description, + type: 'template' as const, + data: t, + })) + return [...evaluationItems, ...templateItems] + }, [evaluations, usedEvaluations, templates]) + + const filteredItems = useMemo(() => { + return selectableItems.filter((item) => + item.name.toLowerCase().includes(searchTerm.toLowerCase()), + ) + }, [selectableItems, searchTerm]) + + const handleSelectItem = (uuid: string) => { + setSelectedItems( + selectedItems.includes(uuid) + ? selectedItems.filter((id) => id !== uuid) + : [...selectedItems, uuid], + ) + } + + const createConnection = useCallback(async () => { + const templateIds = selectedItems + .filter((id) => + templates?.some((template) => template.id.toString() === id), + ) + .map(Number) + const evaluationUuids = selectedItems.filter((id) => + evaluations?.some((evaluation) => evaluation.uuid === id), + ) + + const [data] = await execute({ + projectId, + templateIds, + evaluationUuids, + documentUuid, + }) + + if (data) { + mutate() + const connectedEvaluation = data[0]! + navigate.push( + ROUTES.projects + .detail({ id: Number(projectId) }) + .commits.detail({ uuid: commitUuid }) + .documents.detail({ uuid: documentUuid }) + .evaluations.detail(connectedEvaluation.evaluationId).root, + ) + } + }, [execute, projectId, documentUuid, selectedItems, templates, evaluations]) + + const isLoadingList = isLoadingEvaluations || isLoadingTemplates + return ( + { + navigate.push( + ROUTES.projects + .detail({ id: Number(projectId) }) + .commits.detail({ uuid: commitUuid }) + .documents.detail({ uuid: documentUuid }).evaluations.root, + ) + }} + footer={ + <> + + + + } + > +
    + Evaluations and Templates} + actions={ + + + + } + table={ + <> + {!isLoadingList ? ( +
    + + + selectedItems.includes(item.uuid), + )} + /> +
    + ) : null} + + } + /> +
    +
    + ) +} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/index.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/index.tsx deleted file mode 100644 index 920d52753..000000000 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/_components/ConnectToEvaluationStep/index.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { useCallback, useMemo, useState } from 'react' -import { xorBy } from 'lodash-es' - -import { - EvaluationDto, - EvaluationTemplateWithCategory, -} from '@latitude-data/core/browser' -import { Button, Icon, TableWithHeader, Text } from '@latitude-data/web-ui' -import { ROUTES } from '$/services/routes' -import useEvaluations from '$/stores/evaluations' -import useEvaluationTemplates from '$/stores/evaluationTemplates' -import Link from 'next/link' -import { useParams } from 'next/navigation' - -import EvaluationEditor from './EvaluationEditor' -import EvaluationList from './EvaluationList' - -type SelectableType = 'evaluation' | 'template' -type SelectableItem = { - uuid: string - name: string - description: string - type: T - data: T extends 'evaluation' ? EvaluationDto : EvaluationTemplateWithCategory -} - -export type AnySelectable = - | SelectableItem<'template'> - | SelectableItem<'evaluation'> - -export type FilteredItem = AnySelectable & { selected?: boolean } -export default function ConnectEvaluationStep({ - selectedItems, - setSelectedItems, -}: { - selectedItems: AnySelectable[] - setSelectedItems: (items: AnySelectable[]) => void -}) { - const { documentUuid } = useParams() - const { data: usedEvaluations } = useEvaluations({ - params: { documentUuid: documentUuid as string }, - }) - const { data: evaluations, isLoading: isLoadingEvaluations } = - useEvaluations() - const { data: templates, isLoading: isLoadingTemplates } = - useEvaluationTemplates() - const [searchTerm, setSearchTerm] = useState('') - const selectableItems: AnySelectable[] = useMemo(() => { - const evaluationItems: SelectableItem<'evaluation'>[] = xorBy( - evaluations, - usedEvaluations, - (ev) => ev.id, - ).map((e) => ({ - uuid: e.uuid, - name: e.name, - description: e.description, - type: 'evaluation' as const, - data: e, - })) - const templateItems: SelectableItem<'template'>[] = templates.map((t) => ({ - uuid: t.id.toString(), - name: t.name, - description: t.description, - type: 'template' as const, - data: t, - })) - return [...evaluationItems, ...templateItems] - }, [evaluations, usedEvaluations, templates]) - const [filteredItems, setFilteredItems] = - useState(selectableItems) - const handleSelectItem = useCallback( - (uuid: string) => { - const selected = selectedItems.find((s) => s.uuid === uuid) - let newSelectedItems = selectedItems - if (!selected) { - const item = selectableItems.find((item) => item.uuid === uuid) - if (item) { - newSelectedItems = [...selectedItems, item] - } - } else { - newSelectedItems = selectedItems.filter((s) => s.uuid !== uuid) - } - setSelectedItems(newSelectedItems) - const uuids = newSelectedItems.map((item) => item.uuid) - setFilteredItems( - filteredItems.map((item) => ({ - ...item, - selected: uuids.includes(item.uuid), - })), - ) - }, - [selectedItems, setSelectedItems, filteredItems], - ) - - const selectedUuids = selectedItems.map((item) => item.uuid) - const onSearchChange = useCallback( - (term: string) => { - setSearchTerm(term) - return selectableItems - .filter((item) => item.name.toLowerCase().includes(term.toLowerCase())) - .map((item) => ({ - ...item, - selected: selectedUuids.includes(item.uuid), - })) - }, - [selectableItems, selectedItems], - ) - - if (isLoadingEvaluations || isLoadingTemplates) return null - - return ( -
    - Evaluations and Templates} - actions={ - - - - } - table={ -
    - - -
    - } - /> -
    - ) -} diff --git a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/page.tsx b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/page.tsx index bb16528ee..f2d1d967d 100644 --- a/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/page.tsx +++ b/apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/documents/[documentUuid]/evaluations/dashboard/connect/page.tsx @@ -1,9 +1,6 @@ -import { readMetadata } from '@latitude-data/compiler' -import { getDocumentByUuidCached } from '$/app/(private)/_data-access' +import ConnectEvaluationModal from './_components/ConnectEvaluationModal' -import ConnectDatasetModal from './_components/ConnectDatasetModal' - -export default async function ConnectionEvaluationModal({ +export default async function ConnectionEvaluationModalPage({ params, }: { params: { @@ -12,24 +9,13 @@ export default async function ConnectionEvaluationModal({ documentUuid: string } }) { - const projectId = Number(params.projectId) const documentUuid = params.documentUuid const commitUuid = params.commitUuid - const document = await getDocumentByUuidCached({ - projectId, - commitUuid, - documentUuid, - }) - const metadata = await readMetadata({ - prompt: document.content ?? '', - fullPath: document.path, - }) return ( - ) } diff --git a/apps/web/src/services/routes.ts b/apps/web/src/services/routes.ts index 05c33039e..afede9c17 100644 --- a/apps/web/src/services/routes.ts +++ b/apps/web/src/services/routes.ts @@ -92,12 +92,13 @@ export const ROUTES = { connect: { root: `${evaluationsRoot}/dashboard/connect`, }, + destroy: (id: number) => + `${evaluationsRoot}/destroy/${id}`, }, - detail: (uuid: string) => { - const detailRoot = `${evaluationsRoot}/${uuid}` + detail: (id: number) => { + const detailRoot = `${evaluationsRoot}/${id}` return { root: detailRoot, - destroy: `${detailRoot}/destroy`, createBatch: `${detailRoot}/create-batch`, } }, diff --git a/packages/core/src/repositories/connectedEvaluationsRepository/index.ts b/packages/core/src/repositories/connectedEvaluationsRepository/index.ts index f04b89d5f..2cfeed54f 100644 --- a/packages/core/src/repositories/connectedEvaluationsRepository/index.ts +++ b/packages/core/src/repositories/connectedEvaluationsRepository/index.ts @@ -28,6 +28,7 @@ const tt = getTableColumns(connectedEvaluations) export type ConnectedDocumentWithMetadata = DocumentVersion & { projectId: number // This is automatically provided by the DocumentVersionsRepository evaluationUuid: string + evaluationId: number evaluationLogs: number totalTokens: number costInMillicents: number @@ -103,6 +104,7 @@ export class ConnectedEvaluationsRepository extends Repository< .select({ ...lastVersionOfEachDocument._.selectedFields, evaluationUuid: evaluationsScope.scope.uuid, + evaluationId: evaluationsScope.scope.id, }) .from(lastVersionOfEachDocument) .innerJoin(