Skip to content

Commit 340b3ab

Browse files
authored
Connect and disconnect issues from evals (#1942)
* WIP - connect and disconnect issues from evals * fix PR comments + move eval issue actions to eval results issue actions * Add new button * fix linter * remove double button * remove consolelog
1 parent 97bced6 commit 340b3ab

File tree

21 files changed

+322
-21
lines changed

21 files changed

+322
-21
lines changed

apps/web/src/actions/evaluationsV2/issues/assignIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/assignIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from '@latitude-data/core/repositories'
77
import { assignEvaluationResultV2ToIssue } from '@latitude-data/core/services/evaluationsV2/results/assign'
88
import { z } from 'zod'
9-
import { withEvaluation, withEvaluationSchema } from '../../procedures'
9+
import { withEvaluation, withEvaluationSchema } from '$/actions/procedures'
1010

1111
export const assignIssueAction = withEvaluation
1212
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/createIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/createIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { EvaluationResultsV2Repository } from '@latitude-data/core/repositories'
44
import { assignEvaluationResultV2ToIssue } from '@latitude-data/core/services/evaluationsV2/results/assign'
55
import { z } from 'zod'
6-
import { withEvaluation, withEvaluationSchema } from '../../procedures'
6+
import { withEvaluation, withEvaluationSchema } from '$/actions/procedures'
77

88
export const createIssueAction = withEvaluation
99
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/generateIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/generateIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { EvaluationResultsV2Repository } from '@latitude-data/core/repositories'
44
import { generateIssue } from '@latitude-data/core/services/issues/generate'
55
import { z } from 'zod'
6-
import { withEvaluation, withEvaluationSchema } from '../../procedures'
6+
import { withEvaluation, withEvaluationSchema } from '$/actions/procedures'
77

88
export const generateIssueAction = withEvaluation
99
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/ignoreIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/ignoreIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { IssuesRepository } from '@latitude-data/core/repositories'
44
import { ignoreIssue } from '@latitude-data/core/services/issues/ignore'
55
import { z } from 'zod'
6-
import { withCommit, withCommitSchema } from '../../procedures'
6+
import { withCommit, withCommitSchema } from '$/actions/procedures'
77

88
export const ignoreIssueAction = withCommit
99
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/resolveIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/resolveIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { IssuesRepository } from '@latitude-data/core/repositories'
44
import { resolveIssue } from '@latitude-data/core/services/issues/resolve'
55
import { z } from 'zod'
6-
import { withCommit, withCommitSchema } from '../../procedures'
6+
import { withCommit, withCommitSchema } from '$/actions/procedures'
77

88
export const resolveIssueAction = withCommit
99
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/unAssignIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/unAssignIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from '@latitude-data/core/repositories'
77
import { unassignEvaluationResultV2FromIssue } from '@latitude-data/core/services/evaluationsV2/results/unassign'
88
import { z } from 'zod'
9-
import { withEvaluation, withEvaluationSchema } from '../../procedures'
9+
import { withEvaluation, withEvaluationSchema } from '$/actions/procedures'
1010

1111
export const unAssignIssueAction = withEvaluation
1212
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/unignoreIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/unignoreIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { IssuesRepository } from '@latitude-data/core/repositories'
44
import { unignoreIssue } from '@latitude-data/core/services/issues/unignore'
55
import { z } from 'zod'
6-
import { withCommit, withCommitSchema } from '../../procedures'
6+
import { withCommit, withCommitSchema } from '$/actions/procedures'
77

88
export const unignoreIssueAction = withCommit
99
.inputSchema(

apps/web/src/actions/evaluationsV2/issues/unresolveIssue.ts renamed to apps/web/src/actions/evaluationsV2/results/issues/unresolveIssue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { IssuesRepository } from '@latitude-data/core/repositories'
44
import { unresolveIssue } from '@latitude-data/core/services/issues/unresolve'
55
import { z } from 'zod'
6-
import { withCommit, withCommitSchema } from '../../procedures'
6+
import { withCommit, withCommitSchema } from '$/actions/procedures'
77

88
export const unresolveIssueAction = withCommit
99
.inputSchema(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
'use client'
2+
3+
import { useCurrentCommit } from '$/app/providers/CommitProvider'
4+
import { Text } from '@latitude-data/web-ui/atoms/Text'
5+
import { useCurrentProject } from '$/app/providers/ProjectProvider'
6+
import { useEvaluationsV2 } from '$/stores/evaluationsV2'
7+
import React, { useCallback, useMemo } from 'react'
8+
import { Select } from '@latitude-data/web-ui/atoms/Select'
9+
import { Icon } from '@latitude-data/web-ui/atoms/Icons'
10+
import { getEvaluationMetricSpecification } from '$/components/evaluations'
11+
import { Button } from '@latitude-data/web-ui/atoms/Button'
12+
import { Skeleton } from '@latitude-data/web-ui/atoms/Skeleton'
13+
import { Issue } from '@latitude-data/core/schema/models/types/Issue'
14+
15+
export function IssueEvaluation({ issue }: { issue: Issue }) {
16+
const { project } = useCurrentProject()
17+
const { commit } = useCurrentCommit()
18+
19+
const {
20+
data: evaluations,
21+
isLoading: isLoadingEvaluations,
22+
updateEvaluation,
23+
isUpdatingEvaluation,
24+
// isGeneratingEvaluationFromIssue,
25+
// generateEvaluationFromIssue,
26+
} = useEvaluationsV2({
27+
project: project,
28+
commit: commit,
29+
document: {
30+
commitId: commit.id,
31+
documentUuid: issue.documentUuid,
32+
},
33+
})
34+
35+
const evaluationsThatCanBeAttachedToIssues = useMemo(
36+
() =>
37+
evaluations.filter(
38+
(e) =>
39+
!getEvaluationMetricSpecification(e).requiresExpectedOutput &&
40+
getEvaluationMetricSpecification(e).supportsLiveEvaluation,
41+
),
42+
[evaluations],
43+
)
44+
45+
const evaluationWithIssue = useMemo(
46+
() =>
47+
evaluationsThatCanBeAttachedToIssues.find((e) => e.issueId === issue.id),
48+
[evaluationsThatCanBeAttachedToIssues, issue.id],
49+
)
50+
51+
const setIssueForNewEvaluation = useCallback(
52+
(newEvaluationUuid: string) => {
53+
// If the issue already had an eval attached, remove it
54+
if (evaluationWithIssue) {
55+
updateEvaluation({
56+
evaluationUuid: evaluationWithIssue.uuid,
57+
issueId: null,
58+
})
59+
}
60+
// If a new evaluation is selected, attach it to the issue
61+
if (newEvaluationUuid) {
62+
updateEvaluation({
63+
evaluationUuid: newEvaluationUuid,
64+
issueId: issue.id,
65+
})
66+
}
67+
},
68+
[evaluationWithIssue, issue.id, updateEvaluation],
69+
)
70+
71+
if (isLoadingEvaluations) {
72+
return (
73+
<div className='grid grid-cols-2 gap-x-4 items-center'>
74+
<Text.H5 color='foregroundMuted'>Evaluation</Text.H5>
75+
<Skeleton className='w-full h-10' />
76+
</div>
77+
)
78+
}
79+
80+
if (evaluationWithIssue) {
81+
return (
82+
<div className='grid grid-cols-2 gap-x-4 items-center'>
83+
<Text.H5 color='foregroundMuted'>Evaluation</Text.H5>
84+
<div>
85+
<Select
86+
badgeLabel
87+
align='end'
88+
searchable
89+
side='bottom'
90+
removable
91+
name='evaluation'
92+
options={evaluations.map((e) => ({
93+
label: e.name,
94+
value: e.uuid,
95+
icon: <Icon name={getEvaluationMetricSpecification(e).icon} />,
96+
}))}
97+
value={evaluationWithIssue?.uuid}
98+
disabled={isUpdatingEvaluation}
99+
loading={isUpdatingEvaluation}
100+
onChange={setIssueForNewEvaluation}
101+
// footerAction={{
102+
// label: 'Generate new evaluation',
103+
// icon: 'wandSparkles',
104+
// onClick: () => undefined,
105+
// }} // TODO(evaluation-generator): Remove this once we have a way to generate evaluations from issues
106+
/>
107+
</div>
108+
</div>
109+
)
110+
}
111+
112+
return (
113+
<div className='grid grid-cols-2 gap-x-4 items-center'>
114+
<Text.H5 color='foregroundMuted'>Evaluation</Text.H5>
115+
<div>
116+
<Button
117+
variant='primaryMuted'
118+
iconProps={{
119+
name: 'wandSparkles',
120+
color: 'primary',
121+
placement: 'left',
122+
}}
123+
disabled={true} // TODO(evaluation-generator): Remove this once we have a way to generate evaluations from issues
124+
onClick={() => {
125+
// e.stopPropagation()
126+
// generateEvaluationFromIssue({ issueId: issue.id })
127+
}} // TODO(evaluation-generator): Uncomment this once we have a way to generate evaluations from issues
128+
// disabled: isGeneratingEvaluationFromIssue,
129+
// isLoading: isGeneratingEvaluationFromIssue,
130+
>
131+
Generate
132+
</Button>
133+
</div>
134+
</div>
135+
)
136+
}

apps/web/src/app/(private)/projects/[projectId]/versions/[commitUuid]/issues/_components/IssueDetailPanel/index.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RefObject, useRef } from 'react'
1+
import { RefObject, useMemo, useRef } from 'react'
22
import { usePanelDomRef } from '@latitude-data/web-ui/atoms/SplitPane'
33
import { Text } from '@latitude-data/web-ui/atoms/Text'
44
import { StickyOffset, useStickyNested } from '$/hooks/useStickyNested'
@@ -9,6 +9,9 @@ import { IssueDetails } from './IssueDetails'
99
import { IssueItemActions } from '../IssueItemActions'
1010
import { Button } from '@latitude-data/web-ui/atoms/Button'
1111
import { Tooltip } from '@latitude-data/web-ui/atoms/Tooltip'
12+
import useFeature from '$/stores/useFeature'
13+
import { IssueEvaluation } from './Evaluation'
14+
import { Separator } from '@latitude-data/web-ui/atoms/Separator'
1215

1316
export function IssuesDetailPanel({
1417
stickyRef,
@@ -24,6 +27,13 @@ export function IssuesDetailPanel({
2427
offset: StickyOffset
2528
}) {
2629
const ref = useRef<HTMLDivElement>(null)
30+
const { isEnabled: itIs, isLoading: isLoadingEvaluationGeneratorEnabled } =
31+
useFeature('evaluationGenerator')
32+
33+
const isEvaluationGeneratorEnabled = useMemo(
34+
() => itIs && !isLoadingEvaluationGeneratorEnabled,
35+
[itIs, isLoadingEvaluationGeneratorEnabled],
36+
)
2737

2838
const scrollableArea = usePanelDomRef({ selfRef: ref.current })
2939
const beacon = stickyRef?.current
@@ -59,7 +69,9 @@ export function IssuesDetailPanel({
5969
</div>
6070
</DetailsPanel.Header>
6171
<DetailsPanel.Body>
62-
<div className='flex flex-col gap-y-6'>
72+
<div className='flex flex-col gap-y-6 pt-1'>
73+
{isEvaluationGeneratorEnabled && <IssueEvaluation issue={issue} />}
74+
{isEvaluationGeneratorEnabled && <Separator variant='dashed' />}
6375
<IssueDetails issue={issue} />
6476
<TracesList issue={issue} />
6577
</div>

0 commit comments

Comments
 (0)