Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
.FormLayout {
width: 800px;
}
/* .FormLayout intentionally has no overrides — uses FormLayout default width (530px) */

.GoldenQAHelper {
margin-top: 8px;
Expand Down Expand Up @@ -47,11 +45,16 @@

.GoldenQaRow {
display: flex;
align-items: flex-start;
align-items: center;
gap: 12px;
}

.UploadGoldenQaButton {
margin-top: 40px;
white-space: nowrap;
border-radius: 20px !important;
flex-shrink: 0;
}

.GoldenQaHelperText {
margin-top: 6px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
createGoldenQaCustomSuccessMock,
createGoldenQaSuccessMock,
getAIEvaluationCreateMocks,
getAssistantConfigVersionsMock,
} from 'mocks/AIEvaluations';
import AIEvaluationCreate, { DUMMY_CREATE, DUMMY_GET_ITEM } from './AIEvaluationCreate';

Expand Down Expand Up @@ -67,12 +68,12 @@ describe('AIEvaluationCreate', () => {
});

expect(
screen.getByText(/Select the Golden QA dataset from the existing list or upload a new set/)
screen.getByText(/Select The Golden QA Dataset From Existing List Or Upload A New Golden Set/)
).toBeInTheDocument();
expect(screen.getByText('Expected CSV Format:')).toBeInTheDocument();
expect(screen.getByText('Question,Answer')).toBeInTheDocument();
expect(screen.getByText('What is the capital of France?,Paris')).toBeInTheDocument();
expect(screen.getByText('Click here for the template CSV')).toBeInTheDocument();
expect(screen.getByText('Question, Answer')).toBeInTheDocument();
expect(screen.getByText('{"What Is X"},{"Answer"}')).toBeInTheDocument();
expect(screen.getByText('Click Here For The Template Csv')).toBeInTheDocument();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@priyanshu6238 why do these values keep changing?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i change it according to the noopur design

});

test('renders Upload Golden QA button', async () => {
Expand Down Expand Up @@ -150,10 +151,10 @@ describe('AIEvaluationCreate', () => {
render(wrapper());

await waitFor(() => {
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment.')).toBeInTheDocument();
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment')).toBeInTheDocument();
});

const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment.');
const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment');
fireEvent.change(nameInput, { target: { value: 'valid_name' } });
fireEvent.click(screen.getByText('Run Evaluation'));

Expand All @@ -166,10 +167,10 @@ describe('AIEvaluationCreate', () => {
render(wrapper());

await waitFor(() => {
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment.')).toBeInTheDocument();
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment')).toBeInTheDocument();
});

const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment.');
const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment');
fireEvent.change(nameInput, { target: { value: 'invalid name with spaces' } });
fireEvent.click(screen.getByText('Run Evaluation'));

Expand All @@ -182,15 +183,34 @@ describe('AIEvaluationCreate', () => {
render(wrapper());

await waitFor(() => {
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment.')).toBeInTheDocument();
expect(screen.getByPlaceholderText('Give a unique name for the evaluation experiment')).toBeInTheDocument();
});

const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment.');
const nameInput = screen.getByPlaceholderText('Give a unique name for the evaluation experiment');
fireEvent.change(nameInput, { target: { value: 'valid_evaluation-name123' } });

expect((nameInput as HTMLInputElement).value).toBe('valid_evaluation-name123');
});

test('shows assistant options from query using assistantName and versionNumber', async () => {
render(wrapper([...defaultMocks, getAssistantConfigVersionsMock]));

await waitFor(() => {
expect(screen.getByText('Create AI Evaluation')).toBeInTheDocument();
});

const dropdowns = screen.getAllByTestId('dropdown');
const assistantDropdown = dropdowns[1];
const selectTrigger =
assistantDropdown.querySelector('[role="combobox"]') ?? assistantDropdown.querySelector('button');
fireEvent.mouseDown(selectTrigger!);

await waitFor(() => {
expect(screen.getByText('Test Assistant (Version 2)')).toBeInTheDocument();
expect(screen.getByText('Test Assistant (Version 1)')).toBeInTheDocument();
});
});

test('shows assistant helper text', async () => {
render(wrapper());

Expand Down
81 changes: 59 additions & 22 deletions src/containers/AIEvals/AIEvaluationCreate/AIEvaluationCreate.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { gql } from '@apollo/client';
import { gql, useMutation, useQuery } from '@apollo/client';
import { Button } from 'components/UI/Form/Button/Button';
import { Dropdown } from 'components/UI/Form/Dropdown/Dropdown';
import { Input } from 'components/UI/Form/Input/Input';
import { FormLayout } from 'containers/Form/FormLayout';
import { CREATE_EVALUATION } from 'graphql/mutations/AIEvaluations';
import { GET_ASSISTANT_CONFIG_VERSIONS } from 'graphql/queries/Assistant';
import React, { useRef, useState } from 'react';
import { useNavigate } from 'react-router';
import * as Yup from 'yup';
import { setNotification } from 'common/notification';

import styles from './AIEvaluationCreate.module.css';
import { UploadGoldenQaDialog } from './UploadGoldenQaDialog';
Expand Down Expand Up @@ -34,50 +38,77 @@ export const DUMMY_CREATE = gql`
const goldenQAHelperContent = (
<div className={styles.GoldenQAHelper}>
<p className={styles.GoldenQAHelperDescription}>
Select the Golden QA dataset from the existing list or upload a new set of Golden QA in CSV format to run the
evaluation on.
Select The Golden QA Dataset From Existing List Or Upload A New Golden Set Of QA In Csv Format To Run The
Evaluation On.
</p>
<div className={styles.CSVFormatBox}>
<div className={styles.CSVFormatLabel}>Expected CSV Format:</div>
<div className={styles.CSVFormatExample}>Question,Answer</div>
<div className={styles.CSVFormatExample}>{'What is the capital of France?,Paris'}</div>
<div className={styles.CSVFormatExample}>Question, Answer</div>
<div className={styles.CSVFormatExample}>{'{"What Is X"},{"Answer"}'}</div>
<a href="#" className={styles.TemplateLink} target="_blank" rel="noopener noreferrer">
Click here for the template CSV
Click Here For The Template Csv
</a>
</div>
</div>
);

const GoldenQaField = (props: any) => {
const { onUploadGoldenQaClick, form, ...dropdownProps } = props;
const { onUploadGoldenQaClick, form, helperText, ...dropdownProps } = props;
return (
<div className={styles.GoldenQaRow}>
<Dropdown {...dropdownProps} form={form} />
<Button
variant="outlined"
color="primary"
type="button"
className={styles.UploadGoldenQaButton}
onClick={onUploadGoldenQaClick}
>
Upload Golden QA
</Button>
<div>
<div className={styles.GoldenQaRow}>
<Dropdown {...dropdownProps} form={form} />
<Button
variant="outlined"
color="primary"
type="button"
className={styles.UploadGoldenQaButton}
onClick={onUploadGoldenQaClick}
>
Upload Golden QA
</Button>
</div>
{helperText && <div className={styles.GoldenQaHelperText}>{helperText}</div>}
</div>
);
};

const SectionDivider = (_props: any) => null;

export default function AIEvaluationCreate() {
const navigate = useNavigate();
const [goldenQADatasets, setGoldenQADatasets] = useState<string[]>([]);
const [showUploadGoldenQaDialog, setShowUploadGoldenQaDialog] = useState(false);
const [selectedGoldenQaFileName, setSelectedGoldenQaFileName] = useState<string | null>(null);
const [selectedGoldenQaFile, setSelectedGoldenQaFile] = useState<File | null>(null);
const fileInputRef = useRef<HTMLInputElement | null>(null);

const [createEvaluation] = useMutation(CREATE_EVALUATION, {
onCompleted: () => {
setNotification('Evaluation started successfully!');
navigate('/ai-evaluations');
},
onError: (error) => {
setNotification(error.message, 'warning');
},
});

const goldenQaOptions =
goldenQADatasets.length === 0
? [{ id: '0', label: 'No Golden QA available, upload one first' }]
: goldenQADatasets.map((name) => ({ id: name, label: name }));
const assistantOptions = [{ id: '', label: 'Pick your assistant & version to evaluate' }];

const { data: versionsData } = useQuery(GET_ASSISTANT_CONFIG_VERSIONS, {
variables: { filter: {} },
});

const assistantOptions =
versionsData?.assistantConfigVersions?.length > 0
? versionsData.assistantConfigVersions.map((v: any) => ({
id: v.id,
label: `${v.assistantName} (Version ${v.versionNumber})`,
}))
: [{ id: '', label: 'No assistants available' }];

const validationSchema = Yup.object().shape({
evaluationName: Yup.string()
Expand Down Expand Up @@ -127,18 +158,25 @@ export default function AIEvaluationCreate() {
helperText: goldenQAHelperContent,
onUploadGoldenQaClick: handleUploadGoldenQaButtonClick,
},
{
component: SectionDivider,
name: '__evaluationDetailsDivider',
label: 'Evaluation Details',
placedolder: '',
},
{
component: Input,
name: 'evaluationName',
type: 'text',
label: 'Evaluation Name*',
placeholder: 'Give a unique name for the evaluation experiment.',
placeholder: 'Give a unique name for the evaluation experiment',
},
{
component: Dropdown,
name: 'assistantId',
label: 'AI Assistant*',
options: assistantOptions,
placeholder: '',
helperText: "This list includes all assistants and versions you've created.",
},
];
Expand Down Expand Up @@ -177,7 +215,6 @@ export default function AIEvaluationCreate() {
noHeading={false}
partialPage={false}
confirmationState={{ show: false, title: '', message: '' }}
customStyles={styles.FormLayout}
/>
<input
ref={fileInputRef}
Expand All @@ -197,4 +234,4 @@ export default function AIEvaluationCreate() {
)}
</div>
);
};
}
8 changes: 8 additions & 0 deletions src/graphql/mutations/AIEvaluations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { gql } from '@apollo/client';

export const CREATE_EVALUATION = gql`
mutation createEvaluation($input: EvaluationInput!) {
createEvaluation(input: $input) {
status
}
}
`;

export const CREATE_GOLDEN_QA = gql`
mutation CreateGoldenQa($input: GoldenQaInput!) {
createGoldenQa(input: $input) {
Expand Down
15 changes: 15 additions & 0 deletions src/graphql/queries/Assistant.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { gql } from '@apollo/client';

export const GET_ASSISTANT_CONFIG_VERSIONS = gql`
query AssistantConfigVersions {
assistantConfigVersions {
id
assistantId
versionNumber
description
model
status
assistantName
kaapiUuid
}
}
`;

export const GET_ASSISTANTS = gql`
query Assistants($filter: AssistantFilter, $opts: Opts) {
assistants(filter: $filter, opts: $opts) {
Expand Down
32 changes: 32 additions & 0 deletions src/mocks/AIEvaluations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CREATE_GOLDEN_QA } from 'graphql/mutations/AIEvaluations';
import { GET_ASSISTANT_CONFIG_VERSIONS } from 'graphql/queries/Assistant';

export const getDummyGetItemMock = (query: unknown) => ({
request: { query },
Expand All @@ -10,9 +11,40 @@ export const getDummyCreateMock = (query: unknown) => ({
result: { data: { __typename: 'Mutation' } },
});

export const getAssistantConfigVersionsMock = {
request: { query: GET_ASSISTANT_CONFIG_VERSIONS, variables: { filter: {} } },
result: {
data: {
assistantConfigVersions: [
{
__typename: 'AssistantConfigVersion',
id: '1',
assistantId: 'a1',
assistantName: 'Test Assistant',
versionNumber: 2,
description: 'v2 config',
model: 'gpt-4',
status: 'ACTIVE',
},
{
__typename: 'AssistantConfigVersion',
id: '2',
assistantId: 'a1',
assistantName: 'Test Assistant',
versionNumber: 1,
description: 'v1 config',
model: 'gpt-4',
status: 'ACTIVE',
},
],
},
},
};

export const getAIEvaluationCreateMocks = (getItemQuery: unknown, createQuery: unknown) => [
getDummyGetItemMock(getItemQuery),
getDummyCreateMock(createQuery),
getAssistantConfigVersionsMock,
];

export const createGoldenQaSuccessMock = {
Expand Down
Loading