Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: build categorize list from object #918 #1276

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 18 additions & 4 deletions web/src/components/llm-select/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { Popover, Select } from 'antd';
import LlmSettingItems from '../llm-setting-items';

const LLMSelect = () => {
interface IProps {
id?: string;
value?: string;
onChange?: (value: string) => void;
}

const LLMSelect = ({ id, value, onChange }: IProps) => {
const content = (
<div>
<LlmSettingItems handleParametersChange={() => {}}></LlmSettingItems>
<div style={{ width: 400 }}>
<LlmSettingItems
formItemLayout={{ labelCol: { span: 10 }, wrapperCol: { span: 14 } }}
></LlmSettingItems>
</div>
);

return (
<Popover content={content} trigger="click" placement="left" arrow={false}>
<Select style={{ width: '100%' }} dropdownStyle={{ display: 'none' }} />
<Select
style={{ width: '100%' }}
dropdownStyle={{ display: 'none' }}
id={id}
value={value}
onChange={onChange}
/>
</Popover>
);
};
Expand Down
45 changes: 37 additions & 8 deletions web/src/components/llm-setting-items/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import { LlmModelType, ModelVariableType } from '@/constants/knowledge';
import {
LlmModelType,
ModelVariableType,
settledModelVariableMap,
} from '@/constants/knowledge';
import { Divider, Flex, Form, InputNumber, Select, Slider, Switch } from 'antd';
import camelCase from 'lodash/camelCase';

import { useTranslate } from '@/hooks/commonHooks';
import { useSelectLlmOptionsByModelType } from '@/hooks/llmHooks';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import styles from './index.less';

interface IProps {
prefix?: string;
handleParametersChange(value: ModelVariableType): void;
formItemLayout?: any;
handleParametersChange?(value: ModelVariableType): void;
}

const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
const LlmSettingItems = ({ prefix, formItemLayout = {} }: IProps) => {
const form = Form.useFormInstance();
const { t } = useTranslate('chat');
const parameterOptions = Object.values(ModelVariableType).map((x) => ({
label: t(camelCase(x)),
value: x,
}));

const handleParametersChange = useCallback(
(value: ModelVariableType) => {
const variable = settledModelVariableMap[value];
form?.setFieldsValue(variable);
},
[form],
);

const memorizedPrefix = useMemo(() => (prefix ? [prefix] : []), [prefix]);

const modelOptions = useSelectLlmOptionsByModelType();
Expand All @@ -29,6 +43,7 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
label={t('model')}
name="llm_id"
tooltip={t('modelTip')}
{...formItemLayout}
rules={[{ required: true, message: t('modelMessage') }]}
>
<Select options={modelOptions[LlmModelType.Chat]} showSearch />
Expand All @@ -38,14 +53,19 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
label={t('freedom')}
name="parameters"
tooltip={t('freedomTip')}
{...formItemLayout}
initialValue={ModelVariableType.Precise}
>
<Select<ModelVariableType>
options={parameterOptions}
onChange={handleParametersChange}
/>
</Form.Item>
<Form.Item label={t('temperature')} tooltip={t('temperatureTip')}>
<Form.Item
label={t('temperature')}
tooltip={t('temperatureTip')}
{...formItemLayout}
>
<Flex gap={20} align="center">
<Form.Item
name={'temperatureEnabled'}
Expand Down Expand Up @@ -87,7 +107,7 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
</Form.Item>
</Flex>
</Form.Item>
<Form.Item label={t('topP')} tooltip={t('topPTip')}>
<Form.Item label={t('topP')} tooltip={t('topPTip')} {...formItemLayout}>
<Flex gap={20} align="center">
<Form.Item name={'topPEnabled'} valuePropName="checked" noStyle>
<Switch size="small" />
Expand Down Expand Up @@ -122,7 +142,11 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
</Form.Item>
</Flex>
</Form.Item>
<Form.Item label={t('presencePenalty')} tooltip={t('presencePenaltyTip')}>
<Form.Item
label={t('presencePenalty')}
tooltip={t('presencePenaltyTip')}
{...formItemLayout}
>
<Flex gap={20} align="center">
<Form.Item
name={'presencePenaltyEnabled'}
Expand Down Expand Up @@ -170,6 +194,7 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
<Form.Item
label={t('frequencyPenalty')}
tooltip={t('frequencyPenaltyTip')}
{...formItemLayout}
>
<Flex gap={20} align="center">
<Form.Item
Expand Down Expand Up @@ -215,7 +240,11 @@ const LlmSettingItems = ({ prefix, handleParametersChange }: IProps) => {
</Form.Item>
</Flex>
</Form.Item>
<Form.Item label={t('maxTokens')} tooltip={t('maxTokensTip')}>
<Form.Item
label={t('maxTokens')}
tooltip={t('maxTokensTip')}
{...formItemLayout}
>
<Flex gap={20} align="center">
<Form.Item name={'maxTokensEnabled'} valuePropName="checked" noStyle>
<Switch size="small" />
Expand Down
16 changes: 1 addition & 15 deletions web/src/pages/chat/chat-configuration-modal/model-setting.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import {
ModelVariableType,
settledModelVariableMap,
} from '@/constants/knowledge';
import classNames from 'classnames';
import { useEffect } from 'react';
import { ISegmentedContentProps } from '../interface';
Expand All @@ -20,11 +16,6 @@ const ModelSetting = ({
initialLlmSetting?: Variable;
visible?: boolean;
}) => {
const handleParametersChange = (value: ModelVariableType) => {
const variable = settledModelVariableMap[value];
form.setFieldsValue({ llm_setting: variable });
};

useEffect(() => {
if (visible) {
const values = Object.keys(variableEnabledFieldMap).reduce<
Expand All @@ -50,12 +41,7 @@ const ModelSetting = ({
[styles.segmentedHidden]: !show,
})}
>
{visible && (
<LlmSettingItems
prefix="llm_setting"
handleParametersChange={handleParametersChange}
></LlmSettingItems>
)}
{visible && <LlmSettingItems prefix="llm_setting"></LlmSettingItems>}
{/* <Form.Item
label={t('model')}
name="llm_id"
Expand Down
79 changes: 79 additions & 0 deletions web/src/pages/flow/categorize-form/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import get from 'lodash/get';
import omit from 'lodash/omit';
import { useCallback, useEffect } from 'react';
import { Operator } from '../constant';
import {
ICategorizeItem,
ICategorizeItemResult,
IOperatorForm,
} from '../interface';
import useGraphStore from '../store';

// exclude some nodes downstream of the classification node
Expand All @@ -11,3 +19,74 @@ export const useBuildCategorizeToOptions = () => {
.filter((x) => excludedNodes.every((y) => y !== x.data.label))
.map((x) => ({ label: x.id, value: x.id }));
};

/**
* convert the following object into a list
*
* {
"product_related": {
"description": "The question is about product usage, appearance and how it works.",
"examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?",
"to": "generate:0"
}
}
*/
const buildCategorizeListFromObject = (
categorizeItem: ICategorizeItemResult,
) => {
return Object.keys(categorizeItem).reduce<Array<ICategorizeItem>>(
(pre, cur) => {
pre.push({ name: cur, ...categorizeItem[cur] });
return pre;
},
[],
);
};

/**
* Convert the list in the following form into an object
* {
"items": [
{
"name": "Categorize 1",
"description": "111",
"examples": "ddd",
"to": "Retrieval:LazyEelsStick"
}
]
}
*/
const buildCategorizeObjectFromList = (list: Array<ICategorizeItem>) => {
return list.reduce<ICategorizeItemResult>((pre, cur) => {
if (cur?.name) {
pre[cur.name] = omit(cur, 'name');
}
return pre;
}, {});
};

export const useHandleFormValuesChange = ({
onValuesChange,
form,
node,
}: IOperatorForm) => {
const handleValuesChange = useCallback(
(changedValues: any, values: any) => {
onValuesChange?.(changedValues, {
...omit(values, 'items'),
category_description: buildCategorizeObjectFromList(values.items),
});
},
[onValuesChange],
);

useEffect(() => {
form?.setFieldsValue({
items: buildCategorizeListFromObject(
get(node, 'data.form.category_description', {}),
),
});
}, [form, node]);

return { handleValuesChange };
};
19 changes: 15 additions & 4 deletions web/src/pages/flow/categorize-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import LLMSelect from '@/components/llm-select';
import { useTranslate } from '@/hooks/commonHooks';
import { Form } from 'antd';
import { useSetLlmSetting } from '../hooks';
import { IOperatorForm } from '../interface';
import DynamicCategorize from './dynamic-categorize';
import { useHandleFormValuesChange } from './hooks';

const CategorizeForm = ({ form, onValuesChange }: IOperatorForm) => {
const CategorizeForm = ({ form, onValuesChange, node }: IOperatorForm) => {
const { t } = useTranslate('flow');
const { handleValuesChange } = useHandleFormValuesChange({
form,
node,
onValuesChange,
});
useSetLlmSetting(form);

return (
<Form
Expand All @@ -14,11 +22,14 @@ const CategorizeForm = ({ form, onValuesChange }: IOperatorForm) => {
wrapperCol={{ span: 15 }}
autoComplete="off"
form={form}
onValuesChange={onValuesChange}
onValuesChange={handleValuesChange}
initialValues={{ items: [{}] }}
// layout={'vertical'}
>
<Form.Item name={['cite']} label={t('cite')} tooltip={t('citeTip')}>
<Form.Item
name={'llm_id'}
label={t('model', { keyPrefix: 'chat' })}
tooltip={t('modelTip', { keyPrefix: 'chat' })}
>
<LLMSelect></LLMSelect>
</Form.Item>
<DynamicCategorize></DynamicCategorize>
Expand Down
1 change: 1 addition & 0 deletions web/src/pages/flow/flow-drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const FlowDrawer = ({
<OperatorForm
onValuesChange={handleValuesChange}
form={form}
node={node}
></OperatorForm>
)}
</Drawer>
Expand Down
39 changes: 3 additions & 36 deletions web/src/pages/flow/generate-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,13 @@
import LlmSettingItems from '@/components/llm-setting-items';
import { variableEnabledFieldMap } from '@/constants/chat';
import {
ModelVariableType,
settledModelVariableMap,
} from '@/constants/knowledge';
import { useTranslate } from '@/hooks/commonHooks';
import { Variable } from '@/interfaces/database/chat';
import { Form, Input, Switch } from 'antd';
import { useCallback, useEffect } from 'react';
import { useSetLlmSetting } from '../hooks';
import { IOperatorForm } from '../interface';

const GenerateForm = ({ onValuesChange, form }: IOperatorForm) => {
const { t } = useTranslate('flow');
const initialLlmSetting = undefined;

const handleParametersChange = useCallback(
(value: ModelVariableType) => {
const variable = settledModelVariableMap[value];
form?.setFieldsValue(variable);
},
[form],
);

useEffect(() => {
const switchBoxValues = Object.keys(variableEnabledFieldMap).reduce<
Record<string, boolean>
>((pre, field) => {
pre[field] =
initialLlmSetting === undefined
? true
: !!initialLlmSetting[
variableEnabledFieldMap[
field as keyof typeof variableEnabledFieldMap
] as keyof Variable
];
return pre;
}, {});
const otherValues = settledModelVariableMap[ModelVariableType.Precise];
form?.setFieldsValue({ ...switchBoxValues, ...otherValues });
}, [form, initialLlmSetting]);
useSetLlmSetting(form);

return (
<Form
Expand All @@ -49,9 +18,7 @@ const GenerateForm = ({ onValuesChange, form }: IOperatorForm) => {
form={form}
onValuesChange={onValuesChange}
>
<LlmSettingItems
handleParametersChange={handleParametersChange}
></LlmSettingItems>
<LlmSettingItems></LlmSettingItems>
<Form.Item
name={['prompt']}
label={t('prompt', { keyPrefix: 'knowledgeConfiguration' })}
Expand Down
Loading