mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Add invoke and github operators #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1308,6 +1308,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
management: 'Management',
|
management: 'Management',
|
||||||
import: 'Import',
|
import: 'Import',
|
||||||
export: 'Export',
|
export: 'Export',
|
||||||
|
seconds: 'Seconds',
|
||||||
},
|
},
|
||||||
llmTools: {
|
llmTools: {
|
||||||
bad_calculator: {
|
bad_calculator: {
|
||||||
|
|||||||
@ -109,6 +109,9 @@ function AccordionOperators() {
|
|||||||
Operator.Wikipedia,
|
Operator.Wikipedia,
|
||||||
Operator.GoogleScholar,
|
Operator.GoogleScholar,
|
||||||
Operator.ArXiv,
|
Operator.ArXiv,
|
||||||
|
Operator.PubMed,
|
||||||
|
Operator.GitHub,
|
||||||
|
Operator.Invoke,
|
||||||
]}
|
]}
|
||||||
></OperatorItemList>
|
></OperatorItemList>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
|
|||||||
@ -372,9 +372,15 @@ export const initialWikipediaValues = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const initialPubMedValues = {
|
export const initialPubMedValues = {
|
||||||
top_n: 10,
|
top_n: 12,
|
||||||
email: '',
|
email: '',
|
||||||
...initialQueryBaseValues,
|
query: AgentGlobals.SysQuery,
|
||||||
|
outputs: {
|
||||||
|
formalized_content: {
|
||||||
|
value: '',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialArXivValues = {
|
export const initialArXivValues = {
|
||||||
@ -444,7 +450,17 @@ export const initialDeepLValues = {
|
|||||||
|
|
||||||
export const initialGithubValues = {
|
export const initialGithubValues = {
|
||||||
top_n: 5,
|
top_n: 5,
|
||||||
...initialQueryBaseValues,
|
query: AgentGlobals.SysQuery,
|
||||||
|
outputs: {
|
||||||
|
formalized_content: {
|
||||||
|
value: '',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
json: {
|
||||||
|
value: [],
|
||||||
|
type: 'Array<Object>',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialBaiduFanyiValues = {
|
export const initialBaiduFanyiValues = {
|
||||||
@ -540,7 +556,7 @@ export const initialCrawlerValues = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const initialInvokeValues = {
|
export const initialInvokeValues = {
|
||||||
url: 'http://',
|
url: '',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
timeout: 60,
|
timeout: 60,
|
||||||
headers: `{
|
headers: `{
|
||||||
@ -548,8 +564,9 @@ export const initialInvokeValues = {
|
|||||||
"Cache-Control": "no-cache",
|
"Cache-Control": "no-cache",
|
||||||
"Connection": "keep-alive"
|
"Connection": "keep-alive"
|
||||||
}`,
|
}`,
|
||||||
proxy: 'http://',
|
proxy: '',
|
||||||
clean_html: false,
|
clean_html: false,
|
||||||
|
variables: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialTemplateValues = {
|
export const initialTemplateValues = {
|
||||||
@ -852,7 +869,7 @@ export const NodeMap = {
|
|||||||
[Operator.TuShare]: 'ragNode',
|
[Operator.TuShare]: 'ragNode',
|
||||||
[Operator.Note]: 'noteNode',
|
[Operator.Note]: 'noteNode',
|
||||||
[Operator.Crawler]: 'ragNode',
|
[Operator.Crawler]: 'ragNode',
|
||||||
[Operator.Invoke]: 'invokeNode',
|
[Operator.Invoke]: 'ragNode',
|
||||||
[Operator.Template]: 'templateNode',
|
[Operator.Template]: 'templateNode',
|
||||||
[Operator.Email]: 'ragNode',
|
[Operator.Email]: 'ragNode',
|
||||||
[Operator.Iteration]: 'group',
|
[Operator.Iteration]: 'group',
|
||||||
|
|||||||
@ -126,7 +126,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`sys_prompt`}
|
name={`sys_prompt`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Prompt</FormLabel>
|
<FormLabel>System Prompt</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<PromptEditor
|
<PromptEditor
|
||||||
{...field}
|
{...field}
|
||||||
|
|||||||
@ -39,13 +39,7 @@ const Menus = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Developer',
|
label: 'Developer',
|
||||||
list: [
|
list: [Operator.GitHub, Operator.ExeSQL, Operator.Code, Operator.Retrieval],
|
||||||
Operator.GitHub,
|
|
||||||
Operator.ExeSQL,
|
|
||||||
Operator.Invoke,
|
|
||||||
Operator.Code,
|
|
||||||
Operator.Retrieval,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,52 @@
|
|||||||
import TopNItem from '@/components/top-n-item';
|
import { FormContainer } from '@/components/form-container';
|
||||||
import { Form } from 'antd';
|
import { TopNFormField } from '@/components/top-n-item';
|
||||||
import { IOperatorForm } from '../../interface';
|
import { Form } from '@/components/ui/form';
|
||||||
import DynamicInputVariable from '../components/dynamic-input-variable';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { initialGithubValues } from '../../constant';
|
||||||
|
import { useFormValues } from '../../hooks/use-form-values';
|
||||||
|
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||||
|
import { INextOperatorForm } from '../../interface';
|
||||||
|
import { buildOutputList } from '../../utils/build-output-list';
|
||||||
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
|
import { Output } from '../components/output';
|
||||||
|
import { QueryVariable } from '../components/query-variable';
|
||||||
|
|
||||||
|
export const FormSchema = z.object({
|
||||||
|
query: z.string(),
|
||||||
|
top_n: z.number(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const outputList = buildOutputList(initialGithubValues.outputs);
|
||||||
|
|
||||||
|
function GithubForm({ node }: INextOperatorForm) {
|
||||||
|
const defaultValues = useFormValues(initialGithubValues, node);
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
defaultValues,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
});
|
||||||
|
|
||||||
|
useWatchFormChange(node?.id, form);
|
||||||
|
|
||||||
const GithubForm = ({ onValuesChange, form, node }: IOperatorForm) => {
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form {...form}>
|
||||||
name="basic"
|
<FormWrapper>
|
||||||
autoComplete="off"
|
<FormContainer>
|
||||||
form={form}
|
<QueryVariable></QueryVariable>
|
||||||
onValuesChange={onValuesChange}
|
</FormContainer>
|
||||||
layout={'vertical'}
|
<FormContainer>
|
||||||
>
|
<TopNFormField></TopNFormField>
|
||||||
<DynamicInputVariable node={node}></DynamicInputVariable>
|
</FormContainer>
|
||||||
<TopNItem initialValue={5}></TopNItem>
|
</FormWrapper>
|
||||||
|
<div className="p-5">
|
||||||
|
<Output list={outputList}></Output>
|
||||||
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default GithubForm;
|
export default memo(GithubForm);
|
||||||
|
|||||||
@ -1,131 +0,0 @@
|
|||||||
import { EditableCell, EditableRow } from '@/components/editable-cell';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { DeleteOutlined } from '@ant-design/icons';
|
|
||||||
import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd';
|
|
||||||
import { trim } from 'lodash';
|
|
||||||
import { useBuildVariableOptions } from '../../hooks/use-get-begin-query';
|
|
||||||
import { IInvokeVariable } from '../../interface';
|
|
||||||
import { useHandleOperateParameters } from './hooks';
|
|
||||||
|
|
||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
|
||||||
import styles from './index.less';
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
node?: RAGFlowNodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
body: {
|
|
||||||
row: EditableRow,
|
|
||||||
cell: EditableCell,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const DynamicVariablesForm = ({ node }: IProps) => {
|
|
||||||
const nodeId = node?.id;
|
|
||||||
const { t } = useTranslate('flow');
|
|
||||||
|
|
||||||
const options = useBuildVariableOptions(nodeId, node?.parentId);
|
|
||||||
const {
|
|
||||||
dataSource,
|
|
||||||
handleAdd,
|
|
||||||
handleRemove,
|
|
||||||
handleSave,
|
|
||||||
handleComponentIdChange,
|
|
||||||
handleValueChange,
|
|
||||||
} = useHandleOperateParameters(nodeId!);
|
|
||||||
|
|
||||||
const columns: TableProps<IInvokeVariable>['columns'] = [
|
|
||||||
{
|
|
||||||
title: t('key'),
|
|
||||||
dataIndex: 'key',
|
|
||||||
key: 'key',
|
|
||||||
onCell: (record: IInvokeVariable) => ({
|
|
||||||
record,
|
|
||||||
editable: true,
|
|
||||||
dataIndex: 'key',
|
|
||||||
title: 'key',
|
|
||||||
handleSave,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('componentId'),
|
|
||||||
dataIndex: 'component_id',
|
|
||||||
key: 'component_id',
|
|
||||||
align: 'center',
|
|
||||||
width: 140,
|
|
||||||
render(text, record) {
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
allowClear
|
|
||||||
options={options}
|
|
||||||
value={text}
|
|
||||||
disabled={trim(record.value) !== ''}
|
|
||||||
onChange={handleComponentIdChange(record)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('value'),
|
|
||||||
dataIndex: 'value',
|
|
||||||
key: 'value',
|
|
||||||
align: 'center',
|
|
||||||
width: 140,
|
|
||||||
render(text, record) {
|
|
||||||
return (
|
|
||||||
<Input
|
|
||||||
value={text}
|
|
||||||
disabled={!!record.component_id}
|
|
||||||
onChange={handleValueChange(record)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('operation'),
|
|
||||||
dataIndex: 'operation',
|
|
||||||
width: 20,
|
|
||||||
key: 'operation',
|
|
||||||
align: 'center',
|
|
||||||
fixed: 'right',
|
|
||||||
render(_, record) {
|
|
||||||
return <DeleteOutlined onClick={handleRemove(record.id)} />;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Collapse
|
|
||||||
className={styles.dynamicParameterVariable}
|
|
||||||
defaultActiveKey={['1']}
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
label: (
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<span className={styles.title}>{t('parameter')}</span>
|
|
||||||
<Button size="small" onClick={handleAdd}>
|
|
||||||
{t('add')}
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
),
|
|
||||||
children: (
|
|
||||||
<Table
|
|
||||||
dataSource={dataSource}
|
|
||||||
columns={columns}
|
|
||||||
rowKey={'id'}
|
|
||||||
components={components}
|
|
||||||
rowClassName={() => styles.editableRow}
|
|
||||||
scroll={{ x: true }}
|
|
||||||
bordered
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DynamicVariablesForm;
|
|
||||||
@ -1,8 +1,33 @@
|
|||||||
|
import { Collapse } from '@/components/collapse';
|
||||||
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import NumberInput from '@/components/originui/number-input';
|
||||||
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/components/ui/form';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { Switch } from '@/components/ui/switch';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import Editor, { loader } from '@monaco-editor/react';
|
import Editor, { loader } from '@monaco-editor/react';
|
||||||
import { Form, Input, InputNumber, Select, Space, Switch } from 'antd';
|
import { Plus } from 'lucide-react';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IOperatorForm } from '../../interface';
|
import { initialInvokeValues } from '../../constant';
|
||||||
import DynamicVariablesForm from './dynamic-variables';
|
import { useFormValues } from '../../hooks/use-form-values';
|
||||||
|
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||||
|
import { INextOperatorForm } from '../../interface';
|
||||||
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
|
import { FormSchema, FormSchemaType } from './schema';
|
||||||
|
import { useEditVariableRecord } from './use-edit-variable';
|
||||||
|
import { VariableDialog } from './variable-dialog';
|
||||||
|
import { VariableTable } from './variable-table';
|
||||||
|
|
||||||
loader.config({ paths: { vs: '/vs' } });
|
loader.config({ paths: { vs: '/vs' } });
|
||||||
|
|
||||||
@ -25,54 +50,170 @@ interface TimeoutInputProps {
|
|||||||
const TimeoutInput = ({ value, onChange }: TimeoutInputProps) => {
|
const TimeoutInput = ({ value, onChange }: TimeoutInputProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Space>
|
<div className="flex gap-2 items-center">
|
||||||
<InputNumber value={value} onChange={onChange} /> {t('common.s')}
|
<NumberInput value={value} onChange={onChange} /> {t('flow.seconds')}
|
||||||
</Space>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const InvokeForm = ({ onValuesChange, form, node }: IOperatorForm) => {
|
function InvokeForm({ node }: INextOperatorForm) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const defaultValues = useFormValues(initialInvokeValues, node);
|
||||||
|
|
||||||
|
const form = useForm<FormSchemaType>({
|
||||||
|
defaultValues,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
visible,
|
||||||
|
hideModal,
|
||||||
|
showModal,
|
||||||
|
ok,
|
||||||
|
currentRecord,
|
||||||
|
otherThanCurrentQuery,
|
||||||
|
handleDeleteRecord,
|
||||||
|
} = useEditVariableRecord({
|
||||||
|
form,
|
||||||
|
node,
|
||||||
|
});
|
||||||
|
|
||||||
|
const variables = useWatch({ control: form.control, name: 'variables' });
|
||||||
|
|
||||||
|
useWatchFormChange(node?.id, form);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Form {...form}>
|
||||||
<Form
|
<FormWrapper>
|
||||||
name="basic"
|
<FormContainer>
|
||||||
autoComplete="off"
|
<FormField
|
||||||
form={form}
|
control={form.control}
|
||||||
onValuesChange={onValuesChange}
|
name="url"
|
||||||
layout={'vertical'}
|
render={({ field }) => (
|
||||||
>
|
<FormItem>
|
||||||
<Form.Item name={'url'} label={t('flow.url')}>
|
<FormLabel>{t('flow.url')}</FormLabel>
|
||||||
<Input />
|
<FormControl>
|
||||||
</Form.Item>
|
<Input {...field} placeholder="http://" />
|
||||||
<Form.Item
|
</FormControl>
|
||||||
name={'method'}
|
<FormMessage />
|
||||||
label={t('flow.method')}
|
</FormItem>
|
||||||
initialValue={Method.GET}
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="method"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.method')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<SelectWithSearch {...field} options={MethodOptions} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="timeout"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.timeout')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<TimeoutInput {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="headers"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.headers')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Editor
|
||||||
|
height={200}
|
||||||
|
defaultLanguage="json"
|
||||||
|
theme="vs-dark"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="proxy"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.proxy')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="clean_html"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel tooltip={t('flow.cleanHtmlTip')}>
|
||||||
|
{t('flow.cleanHtml')}
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Switch
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
checked={field.value}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{/* Create a hidden field to make Form instance record this */}
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name={'variables'}
|
||||||
|
render={() => <div></div>}
|
||||||
|
/>
|
||||||
|
</FormContainer>
|
||||||
|
<Collapse
|
||||||
|
title={<div>{t('flow.parameter')}</div>}
|
||||||
|
rightContent={
|
||||||
|
<Button
|
||||||
|
variant={'ghost'}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
showModal();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Select options={MethodOptions} />
|
<VariableTable
|
||||||
</Form.Item>
|
data={variables}
|
||||||
<Form.Item name={'timeout'} label={t('flow.timeout')}>
|
showModal={showModal}
|
||||||
<TimeoutInput></TimeoutInput>
|
deleteRecord={handleDeleteRecord}
|
||||||
</Form.Item>
|
nodeId={node?.id}
|
||||||
<Form.Item name={'headers'} label={t('flow.headers')}>
|
></VariableTable>
|
||||||
<Editor height={200} defaultLanguage="json" theme="vs-dark" />
|
</Collapse>
|
||||||
</Form.Item>
|
{visible && (
|
||||||
<Form.Item name={'proxy'} label={t('flow.proxy')}>
|
<VariableDialog
|
||||||
<Input />
|
hideModal={hideModal}
|
||||||
</Form.Item>
|
initialValue={currentRecord}
|
||||||
<Form.Item
|
otherThanCurrentQuery={otherThanCurrentQuery}
|
||||||
name={'clean_html'}
|
submit={ok}
|
||||||
label={t('flow.cleanHtml')}
|
></VariableDialog>
|
||||||
tooltip={t('flow.cleanHtmlTip')}
|
)}
|
||||||
>
|
</FormWrapper>
|
||||||
<Switch />
|
</Form>
|
||||||
</Form.Item>
|
|
||||||
<DynamicVariablesForm node={node}></DynamicVariablesForm>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default InvokeForm;
|
export default memo(InvokeForm);
|
||||||
|
|||||||
21
web/src/pages/agent/form/invoke-form/schema.ts
Normal file
21
web/src/pages/agent/form/invoke-form/schema.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const VariableFormSchema = z.object({
|
||||||
|
key: z.string(),
|
||||||
|
ref: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const FormSchema = z.object({
|
||||||
|
url: z.string().url(),
|
||||||
|
method: z.string(),
|
||||||
|
timeout: z.number(),
|
||||||
|
headers: z.string(),
|
||||||
|
proxy: z.string().url(),
|
||||||
|
clean_html: z.boolean(),
|
||||||
|
variables: z.array(VariableFormSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type FormSchemaType = z.infer<typeof FormSchema>;
|
||||||
|
|
||||||
|
export type VariableFormSchemaType = z.infer<typeof VariableFormSchema>;
|
||||||
70
web/src/pages/agent/form/invoke-form/use-edit-variable.ts
Normal file
70
web/src/pages/agent/form/invoke-form/use-edit-variable.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
|
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
||||||
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
import { UseFormReturn, useWatch } from 'react-hook-form';
|
||||||
|
import { INextOperatorForm } from '../../interface';
|
||||||
|
import { FormSchemaType, VariableFormSchemaType } from './schema';
|
||||||
|
|
||||||
|
export const useEditVariableRecord = ({
|
||||||
|
form,
|
||||||
|
}: INextOperatorForm & { form: UseFormReturn<FormSchemaType> }) => {
|
||||||
|
const { setRecord, currentRecord } =
|
||||||
|
useSetSelectedRecord<VariableFormSchemaType>();
|
||||||
|
|
||||||
|
const { visible, hideModal, showModal } = useSetModalState();
|
||||||
|
const [index, setIndex] = useState(-1);
|
||||||
|
const variables = useWatch({
|
||||||
|
control: form.control,
|
||||||
|
name: 'variables',
|
||||||
|
});
|
||||||
|
|
||||||
|
const otherThanCurrentQuery = useMemo(() => {
|
||||||
|
return variables.filter((item, idx) => idx !== index);
|
||||||
|
}, [index, variables]);
|
||||||
|
|
||||||
|
const handleEditRecord = useCallback(
|
||||||
|
(record: VariableFormSchemaType) => {
|
||||||
|
const variables = form?.getValues('variables') || [];
|
||||||
|
|
||||||
|
const nextVaribales =
|
||||||
|
index > -1
|
||||||
|
? variables.toSpliced(index, 1, record)
|
||||||
|
: [...variables, record];
|
||||||
|
|
||||||
|
form.setValue('variables', nextVaribales);
|
||||||
|
|
||||||
|
hideModal();
|
||||||
|
},
|
||||||
|
[form, hideModal, index],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleShowModal = useCallback(
|
||||||
|
(idx?: number, record?: VariableFormSchemaType) => {
|
||||||
|
setIndex(idx ?? -1);
|
||||||
|
setRecord(record ?? ({} as VariableFormSchemaType));
|
||||||
|
showModal();
|
||||||
|
},
|
||||||
|
[setRecord, showModal],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteRecord = useCallback(
|
||||||
|
(idx: number) => {
|
||||||
|
const variables = form?.getValues('variables') || [];
|
||||||
|
const nextVariables = variables.filter((item, index) => index !== idx);
|
||||||
|
|
||||||
|
form.setValue('variables', nextVariables);
|
||||||
|
},
|
||||||
|
[form],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: handleEditRecord,
|
||||||
|
currentRecord,
|
||||||
|
setRecord,
|
||||||
|
visible,
|
||||||
|
hideModal,
|
||||||
|
showModal: handleShowModal,
|
||||||
|
otherThanCurrentQuery,
|
||||||
|
handleDeleteRecord,
|
||||||
|
};
|
||||||
|
};
|
||||||
143
web/src/pages/agent/form/invoke-form/variable-dialog.tsx
Normal file
143
web/src/pages/agent/form/invoke-form/variable-dialog.tsx
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from '@/components/ui/dialog';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/components/ui/form';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { IModalProps } from '@/interfaces/common';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { QueryVariable } from '../components/query-variable';
|
||||||
|
import { VariableFormSchemaType } from './schema';
|
||||||
|
|
||||||
|
type ModalFormProps = {
|
||||||
|
initialValue: VariableFormSchemaType;
|
||||||
|
otherThanCurrentQuery: VariableFormSchemaType[];
|
||||||
|
submit(values: any): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FormId = 'BeginParameterForm';
|
||||||
|
|
||||||
|
function VariableForm({
|
||||||
|
initialValue,
|
||||||
|
otherThanCurrentQuery,
|
||||||
|
submit,
|
||||||
|
}: ModalFormProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const FormSchema = z.object({
|
||||||
|
key: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1)
|
||||||
|
.refine(
|
||||||
|
(value) =>
|
||||||
|
!value || !otherThanCurrentQuery.some((x) => x.key === value),
|
||||||
|
{ message: 'The key cannot be repeated!' },
|
||||||
|
),
|
||||||
|
ref: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
defaultValues: {
|
||||||
|
key: '',
|
||||||
|
value: '',
|
||||||
|
ref: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isEmpty(initialValue)) {
|
||||||
|
form.reset(initialValue);
|
||||||
|
}
|
||||||
|
}, [form, initialValue]);
|
||||||
|
|
||||||
|
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||||
|
submit(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
id={FormId}
|
||||||
|
className="space-y-5"
|
||||||
|
autoComplete="off"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
name="key"
|
||||||
|
control={form.control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.key')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} autoComplete="off" />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<QueryVariable name="ref" label={t('flow.ref')}></QueryVariable>
|
||||||
|
<FormField
|
||||||
|
name="value"
|
||||||
|
control={form.control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('flow.value')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VariableDialog({
|
||||||
|
initialValue,
|
||||||
|
hideModal,
|
||||||
|
otherThanCurrentQuery,
|
||||||
|
submit,
|
||||||
|
}: ModalFormProps & IModalProps<VariableFormSchemaType>) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open onOpenChange={hideModal}>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{t('flow.variableSettings')}</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<VariableForm
|
||||||
|
initialValue={initialValue}
|
||||||
|
otherThanCurrentQuery={otherThanCurrentQuery}
|
||||||
|
submit={submit}
|
||||||
|
></VariableForm>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="submit" form={FormId}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
199
web/src/pages/agent/form/invoke-form/variable-table.tsx
Normal file
199
web/src/pages/agent/form/invoke-form/variable-table.tsx
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ColumnDef,
|
||||||
|
ColumnFiltersState,
|
||||||
|
SortingState,
|
||||||
|
VisibilityState,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
getFilteredRowModel,
|
||||||
|
getPaginationRowModel,
|
||||||
|
getSortedRowModel,
|
||||||
|
useReactTable,
|
||||||
|
} from '@tanstack/react-table';
|
||||||
|
import { Pencil, Trash2 } from 'lucide-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { TableEmpty } from '@/components/table-skeleton';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '@/components/ui/table';
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from '@/components/ui/tooltip';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useGetVariableLabelByValue } from '../../hooks/use-get-begin-query';
|
||||||
|
import { VariableFormSchemaType } from './schema';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
data: VariableFormSchemaType[];
|
||||||
|
deleteRecord(index: number): void;
|
||||||
|
showModal(index: number, record: VariableFormSchemaType): void;
|
||||||
|
nodeId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VariableTable({
|
||||||
|
data = [],
|
||||||
|
deleteRecord,
|
||||||
|
showModal,
|
||||||
|
nodeId,
|
||||||
|
}: IProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const getLabel = useGetVariableLabelByValue(nodeId!);
|
||||||
|
|
||||||
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
const [columnVisibility, setColumnVisibility] =
|
||||||
|
React.useState<VisibilityState>({});
|
||||||
|
|
||||||
|
const columns: ColumnDef<VariableFormSchemaType>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: 'key',
|
||||||
|
header: 'key',
|
||||||
|
meta: { cellClassName: 'max-w-30' },
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const key: string = row.getValue('key');
|
||||||
|
return (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="truncate">{key}</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>{key}</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'ref',
|
||||||
|
header: t('flow.ref'),
|
||||||
|
meta: { cellClassName: 'max-w-30' },
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const ref: string = row.getValue('ref');
|
||||||
|
const label = getLabel(ref);
|
||||||
|
return (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="truncate">{label}</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>{label}</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'value',
|
||||||
|
header: t('flow.value'),
|
||||||
|
cell: ({ row }) => <div>{row.getValue('value')}</div>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'actions',
|
||||||
|
enableHiding: false,
|
||||||
|
header: t('common.action'),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const record = row.original;
|
||||||
|
const idx = row.index;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
className="bg-transparent text-foreground hover:bg-muted-foreground hover:text-foreground"
|
||||||
|
onClick={() => showModal(idx, record)}
|
||||||
|
>
|
||||||
|
<Pencil />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="bg-transparent text-foreground hover:bg-muted-foreground hover:text-foreground"
|
||||||
|
onClick={() => deleteRecord(idx)}
|
||||||
|
>
|
||||||
|
<Trash2 />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const table = useReactTable({
|
||||||
|
data,
|
||||||
|
columns,
|
||||||
|
onSortingChange: setSorting,
|
||||||
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
getPaginationRowModel: getPaginationRowModel(),
|
||||||
|
getSortedRowModel: getSortedRowModel(),
|
||||||
|
getFilteredRowModel: getFilteredRowModel(),
|
||||||
|
onColumnVisibilityChange: setColumnVisibility,
|
||||||
|
state: {
|
||||||
|
sorting,
|
||||||
|
columnFilters,
|
||||||
|
columnVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="rounded-md border">
|
||||||
|
<Table rootClassName="rounded-md">
|
||||||
|
<TableHeader>
|
||||||
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
<TableRow key={headerGroup.id}>
|
||||||
|
{headerGroup.headers.map((header) => {
|
||||||
|
return (
|
||||||
|
<TableHead key={header.id}>
|
||||||
|
{header.isPlaceholder
|
||||||
|
? null
|
||||||
|
: flexRender(
|
||||||
|
header.column.columnDef.header,
|
||||||
|
header.getContext(),
|
||||||
|
)}
|
||||||
|
</TableHead>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{table.getRowModel().rows?.length ? (
|
||||||
|
table.getRowModel().rows.map((row) => (
|
||||||
|
<TableRow
|
||||||
|
key={row.id}
|
||||||
|
data-state={row.getIsSelected() && 'selected'}
|
||||||
|
>
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCell
|
||||||
|
key={cell.id}
|
||||||
|
className={cn(cell.column.columnDef.meta?.cellClassName)}
|
||||||
|
>
|
||||||
|
{flexRender(
|
||||||
|
cell.column.columnDef.cell,
|
||||||
|
cell.getContext(),
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableEmpty columnsLength={columns.length}></TableEmpty>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { FormContainer } from '@/components/form-container';
|
||||||
import { TopNFormField } from '@/components/top-n-item';
|
import { TopNFormField } from '@/components/top-n-item';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
@ -9,38 +10,81 @@ import {
|
|||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm, useFormContext } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { initialPubMedValues } from '../../constant';
|
||||||
|
import { useFormValues } from '../../hooks/use-form-values';
|
||||||
|
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||||
import { INextOperatorForm } from '../../interface';
|
import { INextOperatorForm } from '../../interface';
|
||||||
import { DynamicInputVariable } from '../components/next-dynamic-input-variable';
|
import { buildOutputList } from '../../utils/build-output-list';
|
||||||
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
|
import { Output } from '../components/output';
|
||||||
|
import { QueryVariable } from '../components/query-variable';
|
||||||
|
|
||||||
const PubMedForm = ({ form, node }: INextOperatorForm) => {
|
export const PubMedFormPartialSchema = {
|
||||||
|
top_n: z.number(),
|
||||||
|
email: z.string().email(),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FormSchema = z.object({
|
||||||
|
...PubMedFormPartialSchema,
|
||||||
|
query: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export function PubMedFormWidgets() {
|
||||||
|
const form = useFormContext();
|
||||||
const { t } = useTranslate('flow');
|
const { t } = useTranslate('flow');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TopNFormField></TopNFormField>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="email"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel tooltip={t('emailTip')}>{t('email')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputList = buildOutputList(initialPubMedValues.outputs);
|
||||||
|
|
||||||
|
function PubMedForm({ node }: INextOperatorForm) {
|
||||||
|
const defaultValues = useFormValues(initialPubMedValues, node);
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
defaultValues,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
});
|
||||||
|
|
||||||
|
useWatchFormChange(node?.id, form);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<FormWrapper>
|
||||||
className="space-y-6"
|
<FormContainer>
|
||||||
onSubmit={(e) => {
|
<QueryVariable></QueryVariable>
|
||||||
e.preventDefault();
|
</FormContainer>
|
||||||
}}
|
<FormContainer>
|
||||||
>
|
<PubMedFormWidgets></PubMedFormWidgets>
|
||||||
<DynamicInputVariable node={node}></DynamicInputVariable>
|
</FormContainer>
|
||||||
<TopNFormField></TopNFormField>
|
</FormWrapper>
|
||||||
<FormField
|
<div className="p-5">
|
||||||
control={form.control}
|
<Output list={outputList}></Output>
|
||||||
name="email"
|
</div>
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel tooltip={t('emailTip')}>{t('email')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default PubMedForm;
|
export default memo(PubMedForm);
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import { Operator } from '../../constant';
|
import { Operator } from '../../constant';
|
||||||
import AkShareForm from '../akshare-form';
|
import AkShareForm from '../akshare-form';
|
||||||
import DeepLForm from '../deepl-form';
|
import DeepLForm from '../deepl-form';
|
||||||
import GithubForm from '../github-form';
|
|
||||||
import PubMedForm from '../pubmed-form';
|
|
||||||
import ArXivForm from './arxiv-form';
|
import ArXivForm from './arxiv-form';
|
||||||
import BingForm from './bing-form';
|
import BingForm from './bing-form';
|
||||||
import CrawlerForm from './crawler-form';
|
import CrawlerForm from './crawler-form';
|
||||||
import DuckDuckGoForm from './duckduckgo-form';
|
import DuckDuckGoForm from './duckduckgo-form';
|
||||||
import EmailForm from './email-form';
|
import EmailForm from './email-form';
|
||||||
import ExeSQLForm from './exesql-form';
|
import ExeSQLForm from './exesql-form';
|
||||||
|
import GithubForm from './github-form';
|
||||||
import GoogleForm from './google-form';
|
import GoogleForm from './google-form';
|
||||||
import GoogleScholarForm from './google-scholar-form';
|
import GoogleScholarForm from './google-scholar-form';
|
||||||
|
import PubMedForm from './pubmed-form';
|
||||||
import RetrievalForm from './retrieval-form';
|
import RetrievalForm from './retrieval-form';
|
||||||
import TavilyForm from './tavily-form';
|
import TavilyForm from './tavily-form';
|
||||||
import WikipediaForm from './wikipedia-form';
|
import WikipediaForm from './wikipedia-form';
|
||||||
|
|||||||
36
web/src/pages/agent/form/tool-form/github-form/index.tsx
Normal file
36
web/src/pages/agent/form/tool-form/github-form/index.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import { TopNFormField } from '@/components/top-n-item';
|
||||||
|
import { Form } from '@/components/ui/form';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { FormWrapper } from '../../components/form-wrapper';
|
||||||
|
import { useValues } from '../use-values';
|
||||||
|
import { useWatchFormChange } from '../use-watch-change';
|
||||||
|
|
||||||
|
function GithubForm() {
|
||||||
|
const values = useValues();
|
||||||
|
|
||||||
|
const FormSchema = z.object({ query: z.string() });
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
defaultValues: values,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
});
|
||||||
|
|
||||||
|
useWatchFormChange(form);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<FormWrapper>
|
||||||
|
<FormContainer>
|
||||||
|
<TopNFormField></TopNFormField>
|
||||||
|
</FormContainer>
|
||||||
|
</FormWrapper>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(GithubForm);
|
||||||
36
web/src/pages/agent/form/tool-form/pubmed-form/index.tsx
Normal file
36
web/src/pages/agent/form/tool-form/pubmed-form/index.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import { Form } from '@/components/ui/form';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { FormWrapper } from '../../components/form-wrapper';
|
||||||
|
import { PubMedFormPartialSchema, PubMedFormWidgets } from '../../pubmed-form';
|
||||||
|
import { useValues } from '../use-values';
|
||||||
|
import { useWatchFormChange } from '../use-watch-change';
|
||||||
|
|
||||||
|
function PubMedForm() {
|
||||||
|
const values = useValues();
|
||||||
|
|
||||||
|
const FormSchema = z.object(PubMedFormPartialSchema);
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
defaultValues: values,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
mode: 'onChange',
|
||||||
|
});
|
||||||
|
|
||||||
|
useWatchFormChange(form);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<FormWrapper>
|
||||||
|
<FormContainer>
|
||||||
|
<PubMedFormWidgets></PubMedFormWidgets>
|
||||||
|
</FormContainer>
|
||||||
|
</FormWrapper>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PubMedForm);
|
||||||
@ -7,7 +7,6 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
@ -21,6 +20,7 @@ import { INextOperatorForm } from '../../interface';
|
|||||||
import { buildOutputList } from '../../utils/build-output-list';
|
import { buildOutputList } from '../../utils/build-output-list';
|
||||||
import { FormWrapper } from '../components/form-wrapper';
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
import { Output } from '../components/output';
|
import { Output } from '../components/output';
|
||||||
|
import { QueryVariable } from '../components/query-variable';
|
||||||
|
|
||||||
export const YahooFinanceFormPartialSchema = {
|
export const YahooFinanceFormPartialSchema = {
|
||||||
info: z.boolean(),
|
info: z.boolean(),
|
||||||
@ -106,19 +106,12 @@ const YahooFinanceForm = ({ node }: INextOperatorForm) => {
|
|||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<FormWrapper>
|
<FormWrapper>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormField
|
<QueryVariable
|
||||||
control={form.control}
|
name="stock_code"
|
||||||
name={`stock_code`}
|
label={t('stockCode')}
|
||||||
render={({ field }) => (
|
></QueryVariable>
|
||||||
<FormItem>
|
</FormContainer>
|
||||||
<FormLabel>{t('stockCode')}</FormLabel>
|
<FormContainer>
|
||||||
<FormControl>
|
|
||||||
<Input {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<YahooFinanceFormWidgets></YahooFinanceFormWidgets>
|
<YahooFinanceFormWidgets></YahooFinanceFormWidgets>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
|
|||||||
@ -48,6 +48,10 @@ export function useAgentToolInitialValues() {
|
|||||||
return omit(initialValues, 'query', 'outputs');
|
return omit(initialValues, 'query', 'outputs');
|
||||||
case Operator.ArXiv:
|
case Operator.ArXiv:
|
||||||
return pick(initialValues, 'top_n', 'sort_by');
|
return pick(initialValues, 'top_n', 'sort_by');
|
||||||
|
case Operator.PubMed:
|
||||||
|
return pick(initialValues, 'top_n', 'email');
|
||||||
|
case Operator.GitHub:
|
||||||
|
return pick(initialValues, 'top_n');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return initialValues;
|
return initialValues;
|
||||||
|
|||||||
Reference in New Issue
Block a user