Просмотр исходного кода

feat: fetch flow (#1068)

### What problem does this PR solve?
feat: fetch flow #918 
feat: save graph

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
tags/v0.8.0
balibabu 1 год назад
Родитель
Сommit
72c6784ff8
Аккаунт пользователя с таким Email не найден

+ 1
- 1
web/package.json Просмотреть файл

{ {
"private": true, "private": true,
"author": "zhaofengchao <13723060510@163.com>",
"author": "bill",
"scripts": { "scripts": {
"build": "umi build", "build": "umi build",
"dev": "cross-env UMI_DEV_SERVER_COMPRESS=none umi dev", "dev": "cross-env UMI_DEV_SERVER_COMPRESS=none umi dev",

+ 8
- 4
web/src/components/similarity-slider/index.tsx Просмотреть файл



type FieldType = { type FieldType = {
similarity_threshold?: number; similarity_threshold?: number;
vector_similarity_weight?: number;
// vector_similarity_weight?: number;
}; };


interface IProps { interface IProps {
isTooltipShown?: boolean; isTooltipShown?: boolean;
vectorSimilarityWeightName?: string;
} }


const SimilaritySlider = ({ isTooltipShown = false }: IProps) => {
const SimilaritySlider = ({
isTooltipShown = false,
vectorSimilarityWeightName = 'vector_similarity_weight',
}: IProps) => {
const { t } = useTranslate('knowledgeDetails'); const { t } = useTranslate('knowledgeDetails');


return ( return (
> >
<Slider max={1} step={0.01} /> <Slider max={1} step={0.01} />
</Form.Item> </Form.Item>
<Form.Item<FieldType>
<Form.Item
label={t('vectorSimilarityWeight')} label={t('vectorSimilarityWeight')}
name={'vector_similarity_weight'}
name={vectorSimilarityWeightName}
initialValue={1 - 0.3} initialValue={1 - 0.3}
tooltip={isTooltipShown && t('vectorSimilarityWeightTip')} tooltip={isTooltipShown && t('vectorSimilarityWeightTip')}
> >

+ 8
- 0
web/src/constants/chat.ts Просмотреть файл

Assistant = 'assistant', Assistant = 'assistant',
User = 'user', User = 'user',
} }

export const variableEnabledFieldMap = {
temperatureEnabled: 'temperature',
topPEnabled: 'top_p',
presencePenaltyEnabled: 'presence_penalty',
frequencyPenaltyEnabled: 'frequency_penalty',
maxTokensEnabled: 'max_tokens',
};

+ 24
- 2
web/src/hooks/flow-hooks.ts Просмотреть файл

import { DSL, IFlow } from '@/interfaces/database/flow';
import i18n from '@/locales/config';
import flowService from '@/services/flow-service'; import flowService from '@/services/flow-service';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { message } from 'antd';
import { useParams } from 'umi';


export const useFetchFlowTemplates = () => { export const useFetchFlowTemplates = () => {
const { data } = useQuery({ const { data } = useQuery({
return data; return data;
}; };


export const useFetchFlowList = () => {
export const useFetchFlowList = (): { data: IFlow[]; loading: boolean } => {
const { data, isFetching: loading } = useQuery({ const { data, isFetching: loading } = useQuery({
queryKey: ['fetchFlowList'], queryKey: ['fetchFlowList'],
initialData: [], initialData: [],
return { data, loading }; return { data, loading };
}; };


export const useFetchFlow = (): { data: IFlow; loading: boolean } => {
const { id } = useParams();
const { data, isFetching: loading } = useQuery({
queryKey: ['flowDetail'],
initialData: {} as IFlow,
queryFn: async () => {
const { data } = await flowService.getCanvas({}, id);

return data?.data ?? {};
},
});

return { data, loading };
};

export const useSetFlow = () => { export const useSetFlow = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { const {
mutateAsync, mutateAsync,
} = useMutation({ } = useMutation({
mutationKey: ['setFlow'], mutationKey: ['setFlow'],
mutationFn: async (params: any) => {
mutationFn: async (params: { id?: string; title?: string; dsl?: DSL }) => {
const { data } = await flowService.setCanvas(params); const { data } = await flowService.setCanvas(params);
if (data.retcode === 0) { if (data.retcode === 0) {
message.success(
i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
);
queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] }); queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
} }
return data?.retcode; return data?.retcode;

+ 31
- 3
web/src/interfaces/database/flow.ts Просмотреть файл

import { Edge, Node } from 'reactflow';

export type DSLComponents = Record<string, IOperator>; export type DSLComponents = Record<string, IOperator>;


export interface DSL { export interface DSL {
components: DSLComponents; components: DSLComponents;
history: any[];
path: string[];
answer: any[];
history?: any[];
path?: string[];
answer?: any[];
graph?: IGraph;
} }


export interface IOperator { export interface IOperator {
component_name: string; component_name: string;
params: Record<string, unknown>; params: Record<string, unknown>;
} }

export interface IGraph {
nodes: Node[];
edges: Edge[];
}

export interface IFlow {
avatar: null;
canvas_type: null;
create_date: string;
create_time: number;
description: null;
dsl: {
answer: any[];
components: DSLComponents;
graph: IGraph;
history: any[];
path: string[];
};
id: string;
title: string;
update_date: string;
update_time: number;
user_id: string;
}

+ 5
- 8
web/src/pages/chat/chat-configuration-modal/index.tsx Просмотреть файл

import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd'; import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd';
import { SegmentedValue } from 'antd/es/segmented'; import { SegmentedValue } from 'antd/es/segmented';
import camelCase from 'lodash/camelCase'; import camelCase from 'lodash/camelCase';
import omit from 'lodash/omit';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { variableEnabledFieldMap } from '../constants';
import { IPromptConfigParameters } from '../interface'; import { IPromptConfigParameters } from '../interface';
import { excludeUnEnabledVariables } from '../utils';
import AssistantSetting from './assistant-setting'; import AssistantSetting from './assistant-setting';
import { useFetchLlmModelOnVisible, useFetchModelId } from './hooks'; import { useFetchLlmModelOnVisible, useFetchModelId } from './hooks';
import ModelSetting from './model-setting'; import ModelSetting from './model-setting';


import { useTranslate } from '@/hooks/commonHooks'; import { useTranslate } from '@/hooks/commonHooks';
import { getBase64FromUploadFileList } from '@/utils/fileUtil'; import { getBase64FromUploadFileList } from '@/utils/fileUtil';
import { removeUselessFieldsFromValues } from '@/utils/form';
import styles from './index.less'; import styles from './index.less';


const layout = { const layout = {


const handleOk = async () => { const handleOk = async () => {
const values = await form.validateFields(); const values = await form.validateFields();
const nextValues: any = omit(values, [
...Object.keys(variableEnabledFieldMap),
'parameters',
...excludeUnEnabledVariables(values),
]);
const nextValues: any = removeUselessFieldsFromValues(
values,
'llm_setting.',
);
const emptyResponse = nextValues.prompt_config?.empty_response ?? ''; const emptyResponse = nextValues.prompt_config?.empty_response ?? '';


const icon = await getBase64FromUploadFileList(values.icon); const icon = await getBase64FromUploadFileList(values.icon);

+ 1
- 1
web/src/pages/chat/chat-configuration-modal/model-setting.tsx Просмотреть файл

import { ISegmentedContentProps } from '../interface'; import { ISegmentedContentProps } from '../interface';


import LlmSettingItems from '@/components/llm-setting-items'; import LlmSettingItems from '@/components/llm-setting-items';
import { variableEnabledFieldMap } from '@/constants/chat';
import { Variable } from '@/interfaces/database/chat'; import { Variable } from '@/interfaces/database/chat';
import { variableEnabledFieldMap } from '../constants';
import styles from './index.less'; import styles from './index.less';


const ModelSetting = ({ const ModelSetting = ({

+ 0
- 8
web/src/pages/chat/constants.ts Просмотреть файл

export const variableEnabledFieldMap = {
temperatureEnabled: 'temperature',
topPEnabled: 'top_p',
presencePenaltyEnabled: 'presence_penalty',
frequencyPenaltyEnabled: 'frequency_penalty',
maxTokensEnabled: 'max_tokens',
};

export enum ChatSearchParams { export enum ChatSearchParams {
DialogId = 'dialogId', DialogId = 'dialogId',
ConversationId = 'conversationId', ConversationId = 'conversationId',

+ 1
- 12
web/src/pages/chat/utils.ts Просмотреть файл

import { MessageType } from '@/constants/chat'; import { MessageType } from '@/constants/chat';
import { IConversation, IReference } from '@/interfaces/database/chat'; import { IConversation, IReference } from '@/interfaces/database/chat';
import { EmptyConversationId, variableEnabledFieldMap } from './constants';
import { EmptyConversationId } from './constants';
import { IClientConversation, IMessage } from './interface'; import { IClientConversation, IMessage } from './interface';


export const excludeUnEnabledVariables = (values: any) => {
const unEnabledFields: Array<keyof typeof variableEnabledFieldMap> =
Object.keys(variableEnabledFieldMap).filter((key) => !values[key]) as Array<
keyof typeof variableEnabledFieldMap
>;

return unEnabledFields.map(
(key) => `llm_setting.${variableEnabledFieldMap[key]}`,
);
};

export const isConversationIdExist = (conversationId: string) => { export const isConversationIdExist = (conversationId: string) => {
return conversationId !== EmptyConversationId && conversationId !== ''; return conversationId !== EmptyConversationId && conversationId !== '';
}; };

+ 1
- 2
web/src/pages/flow/begin-form/index.tsx Просмотреть файл

console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; };


const BeginForm = ({ onValuesChange }: IOperatorForm) => {
const BeginForm = ({ onValuesChange, form }: IOperatorForm) => {
const { t } = useTranslate('chat'); const { t } = useTranslate('chat');
const [form] = Form.useForm();


return ( return (
<Form <Form

+ 26
- 0
web/src/pages/flow/constant.ts Просмотреть файл

import { ModelVariableType } from '@/constants/knowledge';

export enum Operator { export enum Operator {
Begin = 'Begin', Begin = 'Begin',
Retrieval = 'Retrieval', Retrieval = 'Retrieval',
Generate = 'Generate', Generate = 'Generate',
Answer = 'Answer', Answer = 'Answer',
} }

export const initialRetrievalValues = {
similarity_threshold: 0.2,
keywords_similarity_weight: 0.3,
top_n: 8,
};

export const initialBeginValues = {
prologue: `Hi! I'm your assistant, what can I do for you?`,
};

export const initialGenerateValues = {
parameters: ModelVariableType.Precise,
temperatureEnabled: false,
temperature: 0.1,
top_p: 0.3,
frequency_penalty: 0.7,
presence_penalty: 0.4,
max_tokens: 512,
prompt: `Please summarize the following paragraphs. Be careful with the numbers, do not make things up. Paragraphs as following:
{cluster_content}
The above is the content you need to summarize.`,
cite: true,
};

+ 14
- 2
web/src/pages/flow/flow-drawer/index.tsx Просмотреть файл

import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { Drawer } from 'antd';
import { Drawer, Form } from 'antd';
import { useEffect } from 'react';
import { Node } from 'reactflow'; import { Node } from 'reactflow';
import AnswerForm from '../answer-form'; import AnswerForm from '../answer-form';
import BeginForm from '../begin-form'; import BeginForm from '../begin-form';
}: IModalProps<any> & IProps) => { }: IModalProps<any> & IProps) => {
const operatorName: Operator = node?.data.label; const operatorName: Operator = node?.data.label;
const OperatorForm = FormMap[operatorName]; const OperatorForm = FormMap[operatorName];
const [form] = Form.useForm();

const { handleValuesChange } = useHandleFormValuesChange(node?.id); const { handleValuesChange } = useHandleFormValuesChange(node?.id);


useEffect(() => {
if (visible) {
form.setFieldsValue(node?.data?.form);
}
}, [visible, form, node?.data?.form]);

return ( return (
<Drawer <Drawer
title={node?.data.label} title={node?.data.label}
width={470} width={470}
> >
{visible && ( {visible && (
<OperatorForm onValuesChange={handleValuesChange}></OperatorForm>
<OperatorForm
onValuesChange={handleValuesChange}
form={form}
></OperatorForm>
)} )}
</Drawer> </Drawer>
); );

+ 4
- 5
web/src/pages/flow/generate-form/index.tsx Просмотреть файл

import LlmSettingItems from '@/components/llm-setting-items'; import LlmSettingItems from '@/components/llm-setting-items';
import { variableEnabledFieldMap } from '@/constants/chat';
import { import {
ModelVariableType, ModelVariableType,
settledModelVariableMap, settledModelVariableMap,
} from '@/constants/knowledge'; } from '@/constants/knowledge';
import { useTranslate } from '@/hooks/commonHooks'; import { useTranslate } from '@/hooks/commonHooks';
import { Variable } from '@/interfaces/database/chat'; import { Variable } from '@/interfaces/database/chat';
import { variableEnabledFieldMap } from '@/pages/chat/constants';
import { Form, Input, Switch } from 'antd'; import { Form, Input, Switch } from 'antd';
import { useCallback, useEffect } from 'react'; import { useCallback, useEffect } from 'react';
import { IOperatorForm } from '../interface'; import { IOperatorForm } from '../interface';


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


const handleParametersChange = useCallback( const handleParametersChange = useCallback(
(value: ModelVariableType) => { (value: ModelVariableType) => {
const variable = settledModelVariableMap[value]; const variable = settledModelVariableMap[value];
form.setFieldsValue(variable);
form?.setFieldsValue(variable);
}, },
[form], [form],
); );
return pre; return pre;
}, {}); }, {});
const otherValues = settledModelVariableMap[ModelVariableType.Precise]; const otherValues = settledModelVariableMap[ModelVariableType.Precise];
form.setFieldsValue({ ...switchBoxValues, ...otherValues });
form?.setFieldsValue({ ...switchBoxValues, ...otherValues });
}, [form, initialLlmSetting]); }, [form, initialLlmSetting]);


return ( return (

+ 55
- 6
web/src/pages/flow/hooks.ts Просмотреть файл

import { useSetModalState } from '@/hooks/commonHooks'; import { useSetModalState } from '@/hooks/commonHooks';
import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
import {
useFetchFlow,
useFetchFlowTemplates,
useSetFlow,
} from '@/hooks/flow-hooks';
import { useFetchLlmList } from '@/hooks/llmHooks'; import { useFetchLlmList } from '@/hooks/llmHooks';
import React, { KeyboardEventHandler, useCallback, useState } from 'react';
import { IGraph } from '@/interfaces/database/flow';
import { useIsFetching } from '@tanstack/react-query';
import React, {
KeyboardEventHandler,
useCallback,
useEffect,
useState,
} from 'react';
import { Node, Position, ReactFlowInstance } from 'reactflow'; import { Node, Position, ReactFlowInstance } from 'reactflow';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
// import { shallow } from 'zustand/shallow';
import { useParams } from 'umi';
import useStore, { RFState } from './store'; import useStore, { RFState } from './store';
import { buildDslComponentsByGraph } from './utils'; import { buildDslComponentsByGraph } from './utils';


}); });


export const useSelectCanvasData = () => { export const useSelectCanvasData = () => {
// return useStore(useShallow(selector)); throw error
// return useStore(useShallow(selector)); // throw error
// return useStore(selector, shallow);
return useStore(selector); return useStore(selector);
}; };


}; };


export const useSaveGraph = () => { export const useSaveGraph = () => {
const { data } = useFetchFlow();
const { setFlow } = useSetFlow();
const { id } = useParams();
const { nodes, edges } = useStore((state) => state); const { nodes, edges } = useStore((state) => state);
const saveGraph = useCallback(() => { const saveGraph = useCallback(() => {
const x = buildDslComponentsByGraph(nodes, edges);
console.info('components:', x);
}, [nodes, edges]);
const dslComponents = buildDslComponentsByGraph(nodes, edges);
console.info('components:', dslComponents);
setFlow({
id,
title: data.title,
dsl: { ...data.dsl, graph: { nodes, edges }, components: dslComponents },
});
}, [nodes, edges, setFlow, id, data]);


return { saveGraph }; return { saveGraph };
}; };
return { handleValuesChange }; return { handleValuesChange };
}; };


const useSetGraphInfo = () => {
const { setEdges, setNodes } = useStore((state) => state);
const setGraphInfo = useCallback(
({ nodes = [], edges = [] }: IGraph) => {
if (nodes.length && edges.length) {
setNodes(nodes);
setEdges(edges);
}
},
[setEdges, setNodes],
);
return setGraphInfo;
};

export const useFetchDataOnMount = () => { export const useFetchDataOnMount = () => {
const { loading, data } = useFetchFlow();
const setGraphInfo = useSetGraphInfo();

useEffect(() => {
setGraphInfo(data?.dsl?.graph ?? {});
}, [setGraphInfo, data?.dsl?.graph]);

useFetchFlowTemplates(); useFetchFlowTemplates();
useFetchLlmList(); useFetchLlmList();

return { loading, flowDetail: data };
};

export const useFlowIsFetching = () => {
return useIsFetching({ queryKey: ['flowDetail'] }) > 0;
}; };

+ 2
- 21
web/src/pages/flow/interface.ts Просмотреть файл

import { Edge, Node } from 'reactflow';
import { FormInstance } from 'antd';


export interface DSLComponentList { export interface DSLComponentList {
id: string; id: string;


export interface IOperatorForm { export interface IOperatorForm {
onValuesChange?(changedValues: any, values: any): void; onValuesChange?(changedValues: any, values: any): void;
form?: FormInstance;
} }


export interface IBeginForm { export interface IBeginForm {
color: string; color: string;
form: IBeginForm | IRetrievalForm | IGenerateForm; form: IBeginForm | IRetrievalForm | IGenerateForm;
}; };

export interface IFlow {
avatar: null;
canvas_type: null;
create_date: string;
create_time: number;
description: null;
dsl: {
answer: any[];
components: DSLComponentList;
graph: { nodes: Node[]; edges: Edge[] };
history: any[];
path: string[];
};
id: string;
title: string;
update_date: string;
update_time: number;
user_id: string;
}

+ 1
- 1
web/src/pages/flow/list/flow-card/index.tsx Просмотреть файл

import { useNavigate } from 'umi'; import { useNavigate } from 'umi';


import { useDeleteFlow } from '@/hooks/flow-hooks'; import { useDeleteFlow } from '@/hooks/flow-hooks';
import { IFlow } from '../../interface';
import { IFlow } from '@/interfaces/database/flow';
import styles from './index.less'; import styles from './index.less';


interface IProps { interface IProps {

+ 2
- 2
web/src/pages/flow/list/index.tsx Просмотреть файл

<Spin spinning={loading}> <Spin spinning={loading}>
<Flex gap={'large'} wrap="wrap" className={styles.flowCardContainer}> <Flex gap={'large'} wrap="wrap" className={styles.flowCardContainer}>
{list.length > 0 ? ( {list.length > 0 ? (
list.map((item: any) => {
return <FlowCard item={item} key={item.name}></FlowCard>;
list.map((item) => {
return <FlowCard item={item} key={item.id}></FlowCard>;
}) })
) : ( ) : (
<Empty className={styles.knowledgeEmpty}></Empty> <Empty className={styles.knowledgeEmpty}></Empty>

+ 5
- 4
web/src/pages/flow/retrieval-form/index.tsx Просмотреть файл

console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; };


const RetrievalForm = ({ onValuesChange }: IOperatorForm) => {
const [form] = Form.useForm();

const RetrievalForm = ({ onValuesChange, form }: IOperatorForm) => {
return ( return (
<Form <Form
name="basic" name="basic"
onValuesChange={onValuesChange} onValuesChange={onValuesChange}
form={form} form={form}
> >
<SimilaritySlider isTooltipShown></SimilaritySlider>
<SimilaritySlider
isTooltipShown
vectorSimilarityWeightName="keywords_similarity_weight"
></SimilaritySlider>
<TopNItem></TopNItem> <TopNItem></TopNItem>
<Rerank></Rerank> <Rerank></Rerank>
<KnowledgeBaseItem></KnowledgeBaseItem> <KnowledgeBaseItem></KnowledgeBaseItem>

+ 2
- 5
web/src/pages/flow/store.ts Просмотреть файл

import { create } from 'zustand'; import { create } from 'zustand';
import { devtools } from 'zustand/middleware'; import { devtools } from 'zustand/middleware';
import { NodeData } from './interface'; import { NodeData } from './interface';
import { dsl } from './mock';

const { nodes: initialNodes, edges: initialEdges } = dsl.graph;


export type RFState = { export type RFState = {
nodes: Node<NodeData>[]; nodes: Node<NodeData>[];
// this is our useStore hook that we can use in our components to get parts of the store and call actions // this is our useStore hook that we can use in our components to get parts of the store and call actions
const useStore = create<RFState>()( const useStore = create<RFState>()(
devtools((set, get) => ({ devtools((set, get) => ({
nodes: initialNodes as Node[],
edges: initialEdges as Edge[],
nodes: [] as Node[],
edges: [] as Edge[],
selectedNodeIds: [], selectedNodeIds: [],
selectedEdgeIds: [], selectedEdgeIds: [],
onNodesChange: (changes: NodeChange[]) => { onNodesChange: (changes: NodeChange[]) => {

+ 18
- 2
web/src/pages/flow/utils.ts Просмотреть файл

import { DSLComponents } from '@/interfaces/database/flow'; import { DSLComponents } from '@/interfaces/database/flow';
import { removeUselessFieldsFromValues } from '@/utils/form';
import dagre from 'dagre'; import dagre from 'dagre';
import { Edge, MarkerType, Node, Position } from 'reactflow'; import { Edge, MarkerType, Node, Position } from 'reactflow';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
.map((y) => y[isBuildDownstream ? 'target' : 'source']); .map((y) => y[isBuildDownstream ? 'target' : 'source']);
}; };


const removeUselessDataInTheOperator = (
operatorName: string,
params: Record<string, unknown>,
) => {
if (operatorName === 'Generate') {
return removeUselessFieldsFromValues(params, '');
}
return params;
};

// construct a dsl based on the node information of the graph // construct a dsl based on the node information of the graph
export const buildDslComponentsByGraph = ( export const buildDslComponentsByGraph = (
nodes: Node<NodeData>[], nodes: Node<NodeData>[],


nodes.forEach((x) => { nodes.forEach((x) => {
const id = x.id; const id = x.id;
const operatorName = x.data.label;
components[id] = { components[id] = {
obj: { obj: {
component_name: x.data.label,
params: x.data.form as Record<string, unknown>,
component_name: operatorName,
params:
removeUselessDataInTheOperator(
operatorName,
x.data.form as Record<string, unknown>,
) ?? {},
}, },
downstream: buildComponentDownstreamOrUpstream(edges, id, true), downstream: buildComponentDownstreamOrUpstream(edges, id, true),
upstream: buildComponentDownstreamOrUpstream(edges, id, false), upstream: buildComponentDownstreamOrUpstream(edges, id, false),

+ 28
- 0
web/src/utils/form.ts Просмотреть файл

import { variableEnabledFieldMap } from '@/constants/chat';
import omit from 'lodash/omit';

// chat model setting and generate operator
export const excludeUnEnabledVariables = (
values: any,
prefix = 'llm_setting.',
) => {
const unEnabledFields: Array<keyof typeof variableEnabledFieldMap> =
Object.keys(variableEnabledFieldMap).filter((key) => !values[key]) as Array<
keyof typeof variableEnabledFieldMap
>;

return unEnabledFields.map(
(key) => `${prefix}${variableEnabledFieldMap[key]}`,
);
};

// chat model setting and generate operator
export const removeUselessFieldsFromValues = (values: any, prefix?: string) => {
const nextValues: any = omit(values, [
...Object.keys(variableEnabledFieldMap),
'parameters',
...excludeUnEnabledVariables(values, prefix),
]);

return nextValues;
};

+ 4
- 1
web/src/utils/registerServer.ts Просмотреть файл

import omit from 'lodash/omit'; import omit from 'lodash/omit';
import { RequestMethod } from 'umi-request'; import { RequestMethod } from 'umi-request';
type Service<T extends string> = Record<T, (params?: any) => any>;
type Service<T extends string> = Record<
T,
(params?: any, urlAppendix?: string) => any
>;
const registerServer = <T extends string>( const registerServer = <T extends string>(
opt: Record<T, { url: string; method: string }>, opt: Record<T, { url: string; method: string }>,

Загрузка…
Отмена
Сохранить