Skip to content

Commit 0082b00

Browse files
author
Keivan Vosoughi
committed
File Upload for Seeds Instructions
Validation for Generate Custom Prompt Add Http Status Code to Get DatasetDetails Call
1 parent 06bb5b4 commit 0082b00

File tree

11 files changed

+151
-21
lines changed

11 files changed

+151
-21
lines changed

app/client/.eslintrc.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rules": {
3+
"@typescript-eslint/no-explicit-any": "warn"
4+
}
5+
}

app/client/src/pages/DataGenerator/CustomPromptButton.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import styled from "styled-components";
55
import { fetchCustomPrompt } from "./hooks";
66
import Loading from "../Evaluator/Loading";
77
import AiAssistantIcon from "./AiAssistantIcon";
8+
import { isEmpty } from "lodash";
89

910
interface Props {
1011
model_id: string;
@@ -56,11 +57,18 @@ const StyledIcon = styled.div`
5657
const CustomPromptButton: React.FC<Props> = ({ model_id, inference_type, caii_endpoint, use_case, example_path, setPrompt }) => {
5758
const [form] = Form.useForm();
5859
const [showModal, setShowModal] = useState(false);
60+
const [disabled, setDisabled] = useState(false);
61+
const custom_prompt_instructions = Form.useWatch('custom_prompt_instructions', { form, preserve: true });
62+
console.log('custom_prompt_instructions', custom_prompt_instructions);
5963

6064
const mutation = useMutation({
6165
mutationFn: fetchCustomPrompt
6266
});
6367

68+
useEffect(() => {
69+
setDisabled(isEmpty(custom_prompt_instructions));
70+
}, [custom_prompt_instructions]);
71+
6472
useEffect(() => {
6573
if (mutation.isError) {
6674
notification.error({
@@ -112,12 +120,13 @@ const CustomPromptButton: React.FC<Props> = ({ model_id, inference_type, caii_en
112120
okText={`Generate`}
113121
title={`Generate Custom Prompt`}
114122
onClose={() => setShowModal(false)}
123+
onCancel={() => setShowModal(false)}
115124
footer={
116125
<Row>
117126
<Col sm={12} />
118127
<Col sm={12}>
119128
<StyledFlex key="footer-right">
120-
<Button type="primary" style={{ marginLeft: '12px' }} disabled={mutation.isPending} onClick={() => onFinish()}>{'Generate Custom Prompt'}</Button>
129+
<Button type="primary" style={{ marginLeft: '12px' }} disabled={mutation.isPending || disabled} onClick={() => onFinish()}>{'Generate Custom Prompt'}</Button>
121130
<Button disabled={mutation.isPending} style={{ marginLeft: '12px' }} onClick={() => setShowModal(false)}>{'Cancel'}</Button>
122131
</StyledFlex>
123132
</Col>

app/client/src/pages/DataGenerator/DataGenerator.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import isEmpty from 'lodash/isEmpty';
22
import isString from 'lodash/isString';
3-
import { useRef, useState } from 'react';
4-
import { useLocation } from 'react-router-dom';
3+
import { useEffect, useRef, useState } from 'react';
4+
import { useLocation, useParams } from 'react-router-dom';
55
import { Button, Flex, Form, Layout, Steps } from 'antd';
66
import type { FormInstance } from 'antd';
77
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
@@ -99,12 +99,27 @@ const DataGenerator = () => {
9999
const [isStepValid, setIsStepValid] = useState<boolean>(false);
100100
// Data passed from listing table to prepopulate form
101101
const location = useLocation();
102-
console.log('location?.state?.data:', location?.state?.data);
102+
const { generate_file_name } = useParams();
103103
const initialData = location?.state?.data;
104-
105-
const datasetDetailsReq = location?.state?.data && useGetDatasetDetails(location?.state?.data?.generate_file_name)
104+
const datasetDetailsReq = generate_file_name && useGetDatasetDetails(generate_file_name);
106105
console.log('datasetDetailsReq', datasetDetailsReq);
107-
106+
107+
108+
useEffect(() => {
109+
if (
110+
datasetDetailsReq &&
111+
typeof datasetDetailsReq === 'object' &&
112+
'dataset' in datasetDetailsReq &&
113+
!isEmpty(datasetDetailsReq.dataset)
114+
) {
115+
console.log('setting initial dataset....')
116+
form.setFieldsValue({
117+
...initialData,
118+
...(datasetDetailsReq.dataset as any)
119+
});
120+
}
121+
}, [datasetDetailsReq]);
122+
108123
if (initialData?.technique) {
109124
initialData.workflow_type = initialData?.technique === 'sft' ?
110125
WorkflowType.SUPERVISED_FINE_TUNING :

app/client/src/pages/DataGenerator/Finish.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ const Finish = () => {
178178
}
179179

180180
if (formValues.workflow_type === WorkflowType.FREE_FORM_DATA_GENERATION) {
181+
formValues.example_custom = formValues.examples;
181182
delete formValues.examples;
182183
}
183184

app/client/src/pages/DataGenerator/Prompt.tsx

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import { usefetchTopics, useFetchDefaultSchema, useFetchDefaultPrompt } from '..
1212
import { MAX_NUM_QUESTION, MIN_SEED_INSTRUCTIONS, MAX_SEED_INSTRUCTIONS } from './constants'
1313
import { Usecases, WorkflowType } from './types';
1414
import { useWizardCtx } from './utils';
15-
import { useDatasetSize, useGetPromptByUseCase } from './hooks';
15+
import { fetchFileContent, fetchSeedList, useDatasetSize, useGetPromptByUseCase } from './hooks';
1616
import CustomPromptButton from './CustomPromptButton';
1717
import get from 'lodash/get';
1818
import TextArea from 'antd/es/input/TextArea';
19+
import FileSelectorButton from './FileSelectorButton';
20+
import { useMutation } from '@tanstack/react-query';
21+
import first from 'lodash/first';
1922

2023
const { Title } = Typography;
2124

@@ -63,6 +66,13 @@ const AddTopicContainer = styled(Space)`
6366
width: 100% !important;
6467
`;
6568

69+
const SeedsFormItem = styled(StyledFormItem)`
70+
.ant-form-item-control {
71+
width: 45vw;
72+
}
73+
74+
`
75+
6676
const Prompt = () => {
6777
const form = Form.useFormInstance();
6878
const selectedTopics = Form.useWatch('topics');
@@ -97,6 +107,17 @@ const Prompt = () => {
97107
input_value,
98108
output_key
99109
);
110+
const mutation = useMutation({
111+
mutationFn: fetchSeedList
112+
});
113+
114+
useEffect(() => {
115+
if (!isEmpty(mutation.data)) {
116+
setItems(mutation.data);
117+
form.setFieldValue('topics', mutation.data);
118+
}
119+
}, [mutation.data]);
120+
100121

101122
useEffect(() => {
102123
if (isError) {
@@ -193,6 +214,16 @@ const Prompt = () => {
193214
setCustomTopic('');
194215
};
195216

217+
const onAddFiles = (files: File[]) => {
218+
if (!isEmpty (files)) {
219+
const file = first(files);
220+
const path = get(file, '_path');
221+
if (path) {
222+
mutation.mutate({ path });
223+
}
224+
};
225+
}
226+
196227
return (
197228
<Row gutter={[50,0]}>
198229
<LeftCol span={17}>
@@ -284,7 +315,8 @@ const Prompt = () => {
284315
workflow_type === WorkflowType.CUSTOM_DATA_GENERATION ||
285316
workflow_type === WorkflowType.FREE_FORM_DATA_GENERATION) &&
286317
<Flex gap={20} vertical>
287-
<StyledFormItem
318+
<Flex>
319+
<SeedsFormItem
288320
name={'topics'}
289321
label={
290322
<FormLabel level={4}>
@@ -302,6 +334,7 @@ const Prompt = () => {
302334
shouldUpdate
303335
// validateTrigger='onBlur'
304336
>
337+
305338
<Select
306339
allowClear
307340
mode="multiple"
@@ -368,7 +401,12 @@ const Prompt = () => {
368401
disabled: selectedTopics?.length === MAX_SEED_INSTRUCTIONS
369402
}))}
370403
/>
371-
</StyledFormItem>
404+
405+
</SeedsFormItem>
406+
<div style={{ marginTop: '40px'}}>
407+
<FileSelectorButton onAddFiles={onAddFiles} workflowType={form.getFieldValue('workflow_type')} />
408+
</div>
409+
</Flex>
372410
<StyledFormItem
373411
name='num_questions'
374412
label={<FormLabel level={4}>{'Entries Per Seed'}</FormLabel>}

app/client/src/pages/DataGenerator/hooks.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,23 @@ export const fetchFileContent = async (params: unknown) => {
105105
return content;
106106
}
107107

108+
export const fetchSeedList = async (params: unknown) => {
109+
const resp = await fetch(`${BASE_API_URL}/json/get_seeds_list`, {
110+
method: 'POST',
111+
headers: {
112+
'Content-Type': 'application/json',
113+
},
114+
body: JSON.stringify(params),
115+
});
116+
if (resp.status !== 200) {
117+
const error = await resp.json();
118+
throw new Error(error.message || error.detail);
119+
}
120+
const body = await resp.json();
121+
const content = get(body, 'data');
122+
return content;
123+
}
124+
108125
export const listModels = async (params: unknown) => {
109126
const resp = await fetch(`${BASE_API_URL}/model/model_ID`, {
110127
method: 'POST',

app/client/src/pages/DataGenerator/utils.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,39 @@ export const sampleExamplesData = [
6969
"address": "0185 Michelle Gateway\r\nMendozaberg, OK 22690"
7070
}
7171
];
72+
73+
export enum HttpStatusCodeType {
74+
ClientErrorBadRequest = 'Bad Request',
75+
ClientErrorForbidden = 'Forbidden.',
76+
ClientErrorNotFound = 'Not Found',
77+
ClientErrorMethodNotAllowed = 'Method Not Allowed',
78+
ClientErrorUnauthorized = 'Unauthorized',
79+
ServerErrorInternal = 'Internal Server Error',
80+
ServerErrorServiceUnavailable = 'Service Unavailable',
81+
ServerErrorGatewayTimeout = 'Gateway Timeout'
82+
}
83+
84+
85+
export const getHttpStatusCodeVerb = (statusCode: number) => {
86+
switch (statusCode) {
87+
case 400:
88+
return HttpStatusCodeType.ClientErrorBadRequest;
89+
case 401:
90+
return HttpStatusCodeType.ClientErrorUnauthorized;
91+
case 403:
92+
return HttpStatusCodeType.ClientErrorForbidden;
93+
case 404:
94+
return HttpStatusCodeType.ClientErrorNotFound;
95+
case 405:
96+
return HttpStatusCodeType.ClientErrorMethodNotAllowed;
97+
case 500:
98+
return HttpStatusCodeType.ServerErrorInternal;
99+
case 503:
100+
return HttpStatusCodeType.ServerErrorServiceUnavailable;
101+
case 504:
102+
return HttpStatusCodeType.ServerErrorGatewayTimeout;
103+
104+
default:
105+
return null;
106+
}
107+
};

app/client/src/pages/DatasetDetails/hooks.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import get from 'lodash/get';
22
import { notification } from 'antd';
33
import { useQuery } from '@tanstack/react-query';
4+
import { getHttpStatusCodeVerb } from '../DataGenerator/utils';
5+
import toNumber from 'lodash/toNumber';
46

57

68
const BASE_API_URL = import.meta.env.VITE_AMP_URL;
@@ -19,7 +21,8 @@ const fetchDatasetDetails = async (generate_file_name: string) => {
1921

2022
return {
2123
dataset,
22-
datasetDetails
24+
datasetDetails,
25+
statusCode: dataset__resp.status
2326
};
2427
};
2528

@@ -36,11 +39,17 @@ export const useGetDatasetDetails = (generate_file_name: string) => {
3639
);
3740

3841
const dataset = get(data, 'dataset');
42+
const statusCode = get(data, 'statusCode');
3943

4044
if (error) {
45+
const statusVerb = getHttpStatusCodeVerb(toNumber(statusCode));
46+
let description = `An error occurred while fetching the dataset details:\n ${error}`;
47+
if (statusVerb !== null) {
48+
description = `An error occurred while fetching the dataset details (Status Code: ${statusCode} - ${statusVerb} ):\n ${error}`;
49+
}
4150
notification.error({
4251
message: 'Error',
43-
description: `An error occurred while fetching the dataset details:\n ${error}`
52+
description
4453
});
4554
}
4655

app/client/src/pages/Home/DatasetActions.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,14 @@ const DatasetActions: React.FC<DatasetActionsProps> = ({ dataset, refetch, setTo
7171
// await datasetHistoryAPI.triggerGet();
7272
refetch();
7373
}
74-
75-
// dataset/:generate_file_name
74+
7675
const menuActions: MenuProps['items'] = [
7776
{
7877
key: '1',
79-
// label: (
80-
// <Text>
81-
// View Dataset Details
82-
// </Text>
83-
// ),
8478
label:
8579
<Link disabled={isEmpty(dataset?.generate_file_name)} to={`/dataset/${dataset?.generate_file_name}`}>
8680
View Dataset Details
8781
</Link>,
88-
// onClick: () => setShowModal(true),
8982
icon: <FindInPageIcon />
9083
},
9184
{
@@ -100,7 +93,7 @@ const DatasetActions: React.FC<DatasetActionsProps> = ({ dataset, refetch, setTo
10093
{
10194
key: '3',
10295
label: (
103-
<Link to={`/${Pages.GENERATOR}`} state={{
96+
<Link to={`/${Pages.REGENERATE}/${dataset.generate_file_name}`} state={{
10497
data: dataset,
10598
internalRedirect: true,
10699
}}>

app/client/src/routes.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ const router = createBrowserRouter([
3333
errorElement: <ErrorPage />,
3434
loader: async () => null
3535
},
36+
{
37+
path: `${Pages.REGENERATE}/:generate_file_name`,
38+
element: <DataGenerator key={Pages.GENERATOR}/>,
39+
errorElement: <ErrorPage />,
40+
loader: async () => null
41+
},
3642
{
3743
path: `${Pages.EVALUATOR}/create/:generate_file_name`,
3844
element: <EvaluatorPage />,

app/client/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum Pages {
22
GENERATOR = 'data-generator',
3+
REGENERATE = 're-generate',
34
EVALUATOR = 'evaluator',
45
HISTORY = 'history',
56
HOME = 'home',

0 commit comments

Comments
 (0)