### What problem does this PR solve? Feat: Add Arxiv GoogleScholar operator #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| @@ -107,6 +107,8 @@ function AccordionOperators() { | |||
| Operator.Email, | |||
| Operator.DuckDuckGo, | |||
| Operator.Wikipedia, | |||
| Operator.GoogleScholar, | |||
| Operator.ArXiv, | |||
| ]} | |||
| ></OperatorItemList> | |||
| </AccordionContent> | |||
| @@ -1,8 +1,8 @@ | |||
| import { IAgentForm, IToolNode } from '@/interfaces/database/agent'; | |||
| import { Handle, NodeProps, Position } from '@xyflow/react'; | |||
| import { get } from 'lodash'; | |||
| import { memo, useCallback } from 'react'; | |||
| import { NodeHandleId } from '../../constant'; | |||
| import { MouseEventHandler, memo, useCallback } from 'react'; | |||
| import { NodeHandleId, Operator } from '../../constant'; | |||
| import { ToolCard } from '../../form/agent-form/agent-tools'; | |||
| import { useFindMcpById } from '../../hooks/use-find-mcp-by-id'; | |||
| import useGraphStore from '../../store'; | |||
| @@ -18,7 +18,16 @@ function InnerToolNode({ | |||
| const upstreamAgentNode = getNode(upstreamAgentNodeId); | |||
| const { findMcpById } = useFindMcpById(); | |||
| const handleClick = useCallback(() => {}, []); | |||
| const handleClick = useCallback( | |||
| (operator: string): MouseEventHandler<HTMLLIElement> => | |||
| (e) => { | |||
| if (operator === Operator.Code) { | |||
| e.preventDefault(); | |||
| e.stopPropagation(); | |||
| } | |||
| }, | |||
| [], | |||
| ); | |||
| const tools: IAgentForm['tools'] = get( | |||
| upstreamAgentNode, | |||
| @@ -44,17 +53,18 @@ function InnerToolNode({ | |||
| {tools.map((x) => ( | |||
| <ToolCard | |||
| key={x.component_name} | |||
| onClick={handleClick} | |||
| onClick={handleClick(x.component_name)} | |||
| className="cursor-pointer" | |||
| data-tool={x.component_name} | |||
| > | |||
| {x.component_name} | |||
| </ToolCard> | |||
| ))} | |||
| {mcpList.map((x) => ( | |||
| <ToolCard | |||
| key={x.mcp_id} | |||
| onClick={handleClick} | |||
| onClick={handleClick(x.mcp_id)} | |||
| className="cursor-pointer" | |||
| data-tool={x.mcp_id} | |||
| > | |||
| @@ -378,18 +378,23 @@ export const initialPubMedValues = { | |||
| }; | |||
| export const initialArXivValues = { | |||
| top_n: 10, | |||
| top_n: 12, | |||
| sort_by: 'relevance', | |||
| ...initialQueryBaseValues, | |||
| query: AgentGlobals.SysQuery, | |||
| outputs: { | |||
| formalized_content: { | |||
| value: '', | |||
| type: 'string', | |||
| }, | |||
| }, | |||
| }; | |||
| export const initialGoogleValues = { | |||
| q: AgentGlobals.SysQuery, | |||
| start: 0, | |||
| num: 12, | |||
| top_n: 10, | |||
| api_key: '', | |||
| country: 'cn', | |||
| country: 'us', | |||
| language: 'en', | |||
| outputs: { | |||
| formalized_content: { | |||
| @@ -414,10 +419,22 @@ export const initialBingValues = { | |||
| }; | |||
| export const initialGoogleScholarValues = { | |||
| top_n: 5, | |||
| top_n: 12, | |||
| sort_by: 'relevance', | |||
| patents: true, | |||
| ...initialQueryBaseValues, | |||
| query: AgentGlobals.SysQuery, | |||
| year_low: undefined, | |||
| year_high: undefined, | |||
| outputs: { | |||
| formalized_content: { | |||
| value: '', | |||
| type: 'string', | |||
| }, | |||
| json: { | |||
| value: [], | |||
| type: 'Array<Object>', | |||
| }, | |||
| }, | |||
| }; | |||
| export const initialDeepLValues = { | |||
| @@ -1,4 +1,9 @@ | |||
| import { BlockButton } from '@/components/ui/button'; | |||
| import { | |||
| Tooltip, | |||
| TooltipContent, | |||
| TooltipTrigger, | |||
| } from '@/components/ui/tooltip'; | |||
| import { cn } from '@/lib/utils'; | |||
| import { Position } from '@xyflow/react'; | |||
| import { PencilLine, X } from 'lucide-react'; | |||
| @@ -25,17 +30,32 @@ export function ToolCard({ | |||
| className, | |||
| ...props | |||
| }: PropsWithChildren & React.HTMLAttributes<HTMLLIElement>) { | |||
| return ( | |||
| <li | |||
| {...props} | |||
| className={cn( | |||
| 'flex bg-background-card p-1 rounded-sm justify-between', | |||
| className, | |||
| )} | |||
| > | |||
| {children} | |||
| </li> | |||
| ); | |||
| const element = useMemo(() => { | |||
| return ( | |||
| <li | |||
| {...props} | |||
| className={cn( | |||
| 'flex bg-background-card p-1 rounded-sm justify-between', | |||
| className, | |||
| )} | |||
| > | |||
| {children} | |||
| </li> | |||
| ); | |||
| }, [children, className, props]); | |||
| if (children === Operator.Code) { | |||
| return ( | |||
| <Tooltip> | |||
| <TooltipTrigger asChild>{element}</TooltipTrigger> | |||
| <TooltipContent> | |||
| <p>It doesn't have any config.</p> | |||
| </TooltipContent> | |||
| </Tooltip> | |||
| ); | |||
| } | |||
| return element; | |||
| } | |||
| type ActionButtonProps<T> = { | |||
| @@ -26,6 +26,7 @@ const Menus = [ | |||
| Operator.YahooFinance, | |||
| Operator.PubMed, | |||
| Operator.GoogleScholar, | |||
| Operator.ArXiv, | |||
| ], | |||
| }, | |||
| { | |||
| @@ -1,11 +1,40 @@ | |||
| import TopNItem from '@/components/top-n-item'; | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import { SelectWithSearch } from '@/components/originui/select-with-search'; | |||
| import { TopNFormField } from '@/components/top-n-item'; | |||
| import { | |||
| Form, | |||
| FormControl, | |||
| FormField, | |||
| FormItem, | |||
| FormLabel, | |||
| FormMessage, | |||
| } from '@/components/ui/form'; | |||
| import { useTranslate } from '@/hooks/common-hooks'; | |||
| import { Form, Select } from 'antd'; | |||
| import { useMemo } from 'react'; | |||
| import { IOperatorForm } from '../../interface'; | |||
| import DynamicInputVariable from '../components/dynamic-input-variable'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { memo, useMemo } from 'react'; | |||
| import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialArXivValues } 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'; | |||
| const ArXivForm = ({ onValuesChange, form, node }: IOperatorForm) => { | |||
| export const ArXivFormPartialSchema = { | |||
| top_n: z.number(), | |||
| sort_by: z.string(), | |||
| }; | |||
| export const FormSchema = z.object({ | |||
| ...ArXivFormPartialSchema, | |||
| query: z.string(), | |||
| }); | |||
| export function ArXivFormWidgets() { | |||
| const form = useFormContext(); | |||
| const { t } = useTranslate('flow'); | |||
| const options = useMemo(() => { | |||
| @@ -16,21 +45,52 @@ const ArXivForm = ({ onValuesChange, form, node }: IOperatorForm) => { | |||
| }, [t]); | |||
| return ( | |||
| <Form | |||
| name="basic" | |||
| autoComplete="off" | |||
| form={form} | |||
| onValuesChange={onValuesChange} | |||
| layout={'vertical'} | |||
| > | |||
| <DynamicInputVariable node={node}></DynamicInputVariable> | |||
| <TopNItem initialValue={10}></TopNItem> | |||
| <Form.Item label={t('sortBy')} name={'sort_by'}> | |||
| <Select options={options}></Select> | |||
| </Form.Item> | |||
| <> | |||
| <TopNFormField></TopNFormField> | |||
| <FormField | |||
| control={form.control} | |||
| name={`sort_by`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('sortBy')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch {...field} options={options}></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| </> | |||
| ); | |||
| } | |||
| const outputList = buildOutputList(initialArXivValues.outputs); | |||
| function ArXivForm({ node }: INextOperatorForm) { | |||
| const defaultValues = useFormValues(initialArXivValues, node); | |||
| const form = useForm<z.infer<typeof FormSchema>>({ | |||
| defaultValues, | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <QueryVariable></QueryVariable> | |||
| </FormContainer> | |||
| <FormContainer> | |||
| <ArXivFormWidgets></ArXivFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| <div className="p-5"> | |||
| <Output list={outputList}></Output> | |||
| </div> | |||
| </Form> | |||
| ); | |||
| }; | |||
| } | |||
| export default ArXivForm; | |||
| export default memo(ArXivForm); | |||
| @@ -16,6 +16,7 @@ import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { Channel, initialDuckValues } 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'; | |||
| @@ -70,6 +71,8 @@ function DuckDuckGoForm({ node }: INextOperatorForm) { | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| @@ -15,6 +15,7 @@ import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialEmailValues } 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'; | |||
| @@ -101,6 +102,8 @@ const EmailForm = ({ node }: INextOperatorForm) => { | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| @@ -1,7 +1,6 @@ | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import NumberInput from '@/components/originui/number-input'; | |||
| import { SelectWithSearch } from '@/components/originui/select-with-search'; | |||
| import { TopNFormField } from '@/components/top-n-item'; | |||
| import { | |||
| Form, | |||
| FormControl, | |||
| @@ -12,10 +11,11 @@ import { | |||
| } from '@/components/ui/form'; | |||
| import { useTranslate } from '@/hooks/common-hooks'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { useForm } from 'react-hook-form'; | |||
| import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialGoogleValues } from '../../constant'; | |||
| import { useFormValues } from '../../hooks/use-form-values'; | |||
| import { useWatchFormChange } from '../../hooks/use-watch-form-change'; | |||
| import { INextOperatorForm } from '../../interface'; | |||
| import { GoogleCountryOptions, GoogleLanguageOptions } from '../../options'; | |||
| import { buildOutputList } from '../../utils/build-output-list'; | |||
| @@ -26,16 +26,61 @@ import { QueryVariable } from '../components/query-variable'; | |||
| const outputList = buildOutputList(initialGoogleValues.outputs); | |||
| export const FormSchema = z.object({ | |||
| top_n: z.number(), | |||
| export const GoogleFormPartialSchema = { | |||
| api_key: z.string(), | |||
| country: z.string(), | |||
| language: z.string(), | |||
| }; | |||
| export const FormSchema = z.object({ | |||
| ...GoogleFormPartialSchema, | |||
| q: z.string(), | |||
| start: z.number(), | |||
| num: z.number(), | |||
| }); | |||
| export function GoogleFormWidgets() { | |||
| const form = useFormContext(); | |||
| const { t } = useTranslate('flow'); | |||
| return ( | |||
| <> | |||
| <FormField | |||
| control={form.control} | |||
| name={`country`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('country')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch | |||
| {...field} | |||
| options={GoogleCountryOptions} | |||
| ></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={`language`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('language')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch | |||
| {...field} | |||
| options={GoogleLanguageOptions} | |||
| ></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| </> | |||
| ); | |||
| } | |||
| const GoogleForm = ({ node }: INextOperatorForm) => { | |||
| const { t } = useTranslate('flow'); | |||
| const defaultValues = useFormValues(initialGoogleValues, node); | |||
| @@ -45,6 +90,8 @@ const GoogleForm = ({ node }: INextOperatorForm) => { | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| @@ -79,39 +126,7 @@ const GoogleForm = ({ node }: INextOperatorForm) => { | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <TopNFormField></TopNFormField> | |||
| <FormField | |||
| control={form.control} | |||
| name={`country`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('country')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch | |||
| {...field} | |||
| options={GoogleCountryOptions} | |||
| ></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={`language`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('language')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch | |||
| {...field} | |||
| options={GoogleLanguageOptions} | |||
| ></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <GoogleFormWidgets></GoogleFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| <div className="p-5"> | |||
| @@ -1,12 +1,33 @@ | |||
| import TopNItem from '@/components/top-n-item'; | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import { SelectWithSearch } from '@/components/originui/select-with-search'; | |||
| import { TopNFormField } from '@/components/top-n-item'; | |||
| import { | |||
| Form, | |||
| FormControl, | |||
| FormField, | |||
| FormItem, | |||
| FormLabel, | |||
| FormMessage, | |||
| } from '@/components/ui/form'; | |||
| import { Switch } from '@/components/ui/switch'; | |||
| import { useTranslate } from '@/hooks/common-hooks'; | |||
| import { DatePicker, DatePickerProps, Form, Select, Switch } from 'antd'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { DatePicker, DatePickerProps } from 'antd'; | |||
| import dayjs from 'dayjs'; | |||
| import { useCallback, useMemo } from 'react'; | |||
| import { memo, useCallback, useMemo } from 'react'; | |||
| import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialGoogleScholarValues } from '../../constant'; | |||
| import { useBuildSortOptions } from '../../form-hooks'; | |||
| import { IOperatorForm } from '../../interface'; | |||
| import DynamicInputVariable from '../components/dynamic-input-variable'; | |||
| 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'; | |||
| // TODO: To be replaced | |||
| const YearPicker = ({ | |||
| onChange, | |||
| value, | |||
| @@ -32,44 +53,114 @@ const YearPicker = ({ | |||
| return <DatePicker picker="year" onChange={handleChange} value={nextValue} />; | |||
| }; | |||
| const GoogleScholarForm = ({ onValuesChange, form, node }: IOperatorForm) => { | |||
| export function GoogleScholarFormWidgets() { | |||
| const form = useFormContext(); | |||
| const { t } = useTranslate('flow'); | |||
| const options = useBuildSortOptions(); | |||
| return ( | |||
| <Form | |||
| name="basic" | |||
| autoComplete="off" | |||
| form={form} | |||
| onValuesChange={onValuesChange} | |||
| layout={'vertical'} | |||
| > | |||
| <DynamicInputVariable node={node}></DynamicInputVariable> | |||
| <TopNItem initialValue={5}></TopNItem> | |||
| <Form.Item | |||
| label={t('sortBy')} | |||
| name={'sort_by'} | |||
| initialValue={'relevance'} | |||
| > | |||
| <Select options={options}></Select> | |||
| </Form.Item> | |||
| <Form.Item label={t('yearLow')} name={'year_low'}> | |||
| <YearPicker /> | |||
| </Form.Item> | |||
| <Form.Item label={t('yearHigh')} name={'year_high'}> | |||
| <YearPicker /> | |||
| </Form.Item> | |||
| <Form.Item | |||
| label={t('patents')} | |||
| name={'patents'} | |||
| valuePropName="checked" | |||
| initialValue={true} | |||
| > | |||
| <Switch></Switch> | |||
| </Form.Item> | |||
| </Form> | |||
| <> | |||
| <TopNFormField></TopNFormField> | |||
| <FormField | |||
| control={form.control} | |||
| name={`sort_by`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('sortBy')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch {...field} options={options}></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={`year_low`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('yearLow')}</FormLabel> | |||
| <FormControl> | |||
| <YearPicker {...field}></YearPicker> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={`year_high`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('yearHigh')}</FormLabel> | |||
| <FormControl> | |||
| <YearPicker {...field}></YearPicker> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={`patents`} | |||
| render={({ field }) => ( | |||
| <FormItem className="flex-1"> | |||
| <FormLabel>{t('patents')}</FormLabel> | |||
| <FormControl> | |||
| <Switch | |||
| checked={field.value} | |||
| onCheckedChange={field.onChange} | |||
| ></Switch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| </> | |||
| ); | |||
| } | |||
| export const GoogleScholarFormPartialSchema = { | |||
| top_n: z.number(), | |||
| sort_by: z.string(), | |||
| year_low: z.number(), | |||
| year_high: z.number(), | |||
| patents: z.boolean(), | |||
| }; | |||
| export default GoogleScholarForm; | |||
| export const FormSchema = z.object({ | |||
| ...GoogleScholarFormPartialSchema, | |||
| query: z.string(), | |||
| }); | |||
| const outputList = buildOutputList(initialGoogleScholarValues.outputs); | |||
| function GoogleScholarForm({ node }: INextOperatorForm) { | |||
| const defaultValues = useFormValues(initialGoogleScholarValues, node); | |||
| const form = useForm<z.infer<typeof FormSchema>>({ | |||
| defaultValues, | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <QueryVariable></QueryVariable> | |||
| </FormContainer> | |||
| <FormContainer> | |||
| <GoogleScholarFormWidgets></GoogleScholarFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| <div className="p-5"> | |||
| <Output list={outputList}></Output> | |||
| </div> | |||
| </Form> | |||
| ); | |||
| } | |||
| export default memo(GoogleScholarForm); | |||
| @@ -0,0 +1,35 @@ | |||
| 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 { ArXivFormPartialSchema, ArXivFormWidgets } from '../../arxiv-form'; | |||
| import { FormWrapper } from '../../components/form-wrapper'; | |||
| import { useValues } from '../use-values'; | |||
| import { useWatchFormChange } from '../use-watch-change'; | |||
| function ArXivForm() { | |||
| const values = useValues(); | |||
| const FormSchema = z.object(ArXivFormPartialSchema); | |||
| const form = useForm<z.infer<typeof FormSchema>>({ | |||
| defaultValues: values, | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <ArXivFormWidgets></ArXivFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| </Form> | |||
| ); | |||
| } | |||
| export default memo(ArXivForm); | |||
| @@ -1,15 +1,16 @@ | |||
| import { Operator } from '../../constant'; | |||
| import AkShareForm from '../akshare-form'; | |||
| import ArXivForm from '../arxiv-form'; | |||
| import DeepLForm from '../deepl-form'; | |||
| import GithubForm from '../github-form'; | |||
| import GoogleScholarForm from '../google-scholar-form'; | |||
| import PubMedForm from '../pubmed-form'; | |||
| import ArXivForm from './arxiv-form'; | |||
| import BingForm from './bing-form'; | |||
| import CrawlerForm from './crawler-form'; | |||
| import DuckDuckGoForm from './duckduckgo-form'; | |||
| import EmailForm from './email-form'; | |||
| import ExeSQLForm from './exesql-form'; | |||
| import GoogleForm from './google-form'; | |||
| import GoogleScholarForm from './google-scholar-form'; | |||
| import RetrievalForm from './retrieval-form'; | |||
| import TavilyForm from './tavily-form'; | |||
| import WikipediaForm from './wikipedia-form'; | |||
| @@ -22,7 +23,7 @@ export const ToolFormConfigMap = { | |||
| [Operator.Wikipedia]: WikipediaForm, | |||
| [Operator.PubMed]: PubMedForm, | |||
| [Operator.ArXiv]: ArXivForm, | |||
| [Operator.Google]: TavilyForm, | |||
| [Operator.Google]: GoogleForm, | |||
| [Operator.Bing]: BingForm, | |||
| [Operator.GoogleScholar]: GoogleScholarForm, | |||
| [Operator.DeepL]: DeepLForm, | |||
| @@ -0,0 +1,37 @@ | |||
| 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 { ApiKeyField } from '../../components/api-key-field'; | |||
| import { FormWrapper } from '../../components/form-wrapper'; | |||
| import { GoogleFormPartialSchema, GoogleFormWidgets } from '../../google-form'; | |||
| import { useValues } from '../use-values'; | |||
| import { useWatchFormChange } from '../use-watch-change'; | |||
| function GoogleForm() { | |||
| const values = useValues(); | |||
| const FormSchema = z.object(GoogleFormPartialSchema); | |||
| const form = useForm<z.infer<typeof FormSchema>>({ | |||
| defaultValues: values, | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <ApiKeyField></ApiKeyField> | |||
| <GoogleFormWidgets></GoogleFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| </Form> | |||
| ); | |||
| } | |||
| export default memo(GoogleForm); | |||
| @@ -0,0 +1,38 @@ | |||
| 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 { | |||
| GoogleScholarFormPartialSchema, | |||
| GoogleScholarFormWidgets, | |||
| } from '../../google-scholar-form'; | |||
| import { useValues } from '../use-values'; | |||
| import { useWatchFormChange } from '../use-watch-change'; | |||
| function GoogleScholarForm() { | |||
| const values = useValues(); | |||
| const FormSchema = z.object(GoogleScholarFormPartialSchema); | |||
| const form = useForm<z.infer<typeof FormSchema>>({ | |||
| defaultValues: values, | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| <FormContainer> | |||
| <GoogleScholarFormWidgets></GoogleScholarFormWidgets> | |||
| </FormContainer> | |||
| </FormWrapper> | |||
| </Form> | |||
| ); | |||
| } | |||
| export default memo(GoogleScholarForm); | |||
| @@ -16,6 +16,7 @@ import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialWikipediaValues } from '../../constant'; | |||
| import { useFormValues } from '../../hooks/use-form-values'; | |||
| import { useWatchFormChange } from '../../hooks/use-watch-form-change'; | |||
| import { INextOperatorForm } from '../../interface'; | |||
| import { LanguageOptions } from '../../options'; | |||
| import { buildOutputList } from '../../utils/build-output-list'; | |||
| @@ -67,6 +68,8 @@ function WikipediaForm({ node }: INextOperatorForm) { | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| @@ -16,6 +16,7 @@ import { useForm, useFormContext } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { initialYahooFinanceValues } 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'; | |||
| @@ -99,6 +100,8 @@ const YahooFinanceForm = ({ node }: INextOperatorForm) => { | |||
| resolver: zodResolver(FormSchema), | |||
| }); | |||
| useWatchFormChange(node?.id, form); | |||
| return ( | |||
| <Form {...form}> | |||
| <FormWrapper> | |||
| @@ -16,7 +16,7 @@ export function useAgentToolInitialValues() { | |||
| ...omit(initialValues, 'query'), | |||
| description: '', | |||
| }; | |||
| case (Operator.TavilySearch, Operator.TavilyExtract, Operator.Google): | |||
| case (Operator.TavilySearch, Operator.TavilyExtract): | |||
| return { | |||
| api_key: '', | |||
| }; | |||
| @@ -42,6 +42,12 @@ export function useAgentToolInitialValues() { | |||
| case Operator.Wikipedia: | |||
| return pick(initialValues, 'top_n', 'language'); | |||
| case Operator.Google: | |||
| return pick(initialValues, 'api_key', 'country', 'language'); | |||
| case Operator.GoogleScholar: | |||
| return omit(initialValues, 'query', 'outputs'); | |||
| case Operator.ArXiv: | |||
| return pick(initialValues, 'top_n', 'sort_by'); | |||
| default: | |||
| return initialValues; | |||