From b3018a455f5b5cd84aa2887c3d5f508eeacc0b01 Mon Sep 17 00:00:00 2001 From: balibabu Date: Wed, 16 Jul 2025 17:56:55 +0800 Subject: [PATCH] Feat: Add bing form #3221 (#8875) ### What problem does this PR solve? Feat: Add bing form #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- .../node/dropdown/next-step-dropdown.tsx | 1 + web/src/pages/agent/constant.tsx | 2 +- web/src/pages/agent/form/bing-form/index.tsx | 147 ++++++++++++++---- .../pages/agent/form/exesql-form/index.tsx | 7 +- .../agent/form/tool-form/bing-form/index.tsx | 32 ++++ .../pages/agent/form/tool-form/constant.tsx | 2 +- .../hooks/use-agent-tool-initial-values.ts | 2 + 7 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 web/src/pages/agent/form/tool-form/bing-form/index.tsx diff --git a/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx b/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx index e9333a50f..a277c2ace 100644 --- a/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx +++ b/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx @@ -102,6 +102,7 @@ function AccordionOperators() { Operator.TavilySearch, Operator.Crawler, Operator.ExeSQL, + Operator.Bing, ]} > diff --git a/web/src/pages/agent/constant.tsx b/web/src/pages/agent/constant.tsx index 9f56347d1..41566a076 100644 --- a/web/src/pages/agent/constant.tsx +++ b/web/src/pages/agent/constant.tsx @@ -516,7 +516,7 @@ export const initialBingValues = { 'YOUR_API_KEY (obtained from https://www.microsoft.com/en-us/bing/apis/bing-web-search-api)', country: 'CH', language: 'en', - ...initialQueryBaseValues, + query: '', }; export const initialGoogleScholarValues = { diff --git a/web/src/pages/agent/form/bing-form/index.tsx b/web/src/pages/agent/form/bing-form/index.tsx index dc6f000ba..fae75aa12 100644 --- a/web/src/pages/agent/form/bing-form/index.tsx +++ b/web/src/pages/agent/form/bing-form/index.tsx @@ -1,12 +1,42 @@ -import TopNItem from '@/components/top-n-item'; +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 { Input } from '@/components/ui/input'; import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Input, Select } from 'antd'; -import { useMemo } from 'react'; -import { IOperatorForm } from '../../interface'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { memo, useMemo } from 'react'; +import { useForm, useFormContext } from 'react-hook-form'; +import { z } from 'zod'; +import { initialBingValues } from '../../constant'; +import { useFormValues } from '../../hooks/use-form-values'; +import { useWatchFormChange } from '../../hooks/use-watch-form-change'; +import { INextOperatorForm } from '../../interface'; import { BingCountryOptions, BingLanguageOptions } from '../../options'; -import DynamicInputVariable from '../components/dynamic-input-variable'; +import { FormWrapper } from '../components/form-wrapper'; +import { QueryVariable } from '../components/query-variable'; -const BingForm = ({ onValuesChange, form, node }: IOperatorForm) => { +export const BingFormSchema = { + channel: z.string(), + api_key: z.string(), + country: z.string(), + language: z.string(), + top_n: z.number(), +}; + +export const FormSchema = z.object({ + query: z.string().optional(), + ...BingFormSchema, +}); + +export function BingFormWidgets() { + const form = useFormContext(); const { t } = useTranslate('flow'); const options = useMemo(() => { @@ -14,29 +44,88 @@ const BingForm = ({ onValuesChange, form, node }: IOperatorForm) => { }, []); return ( -
- - - - - - - - - - - - - - + <> + + ( + + {t('channel')} + + + + + + )} + /> + ( + + {t('apiKey')} + + + + + + )} + /> + ( + + {t('country')} + + + + + + )} + /> + ( + + {t('language')} + + + + + + )} + /> + + ); +} + +function BingForm({ node }: INextOperatorForm) { + const defaultValues = useFormValues(initialBingValues, node); + + const form = useForm>({ + resolver: zodResolver(FormSchema), + defaultValues, + }); + + useWatchFormChange(node?.id, form); + + return ( + + + + + ); -}; +} -export default BingForm; +export default memo(BingForm); diff --git a/web/src/pages/agent/form/exesql-form/index.tsx b/web/src/pages/agent/form/exesql-form/index.tsx index 2674a652c..a0e937796 100644 --- a/web/src/pages/agent/form/exesql-form/index.tsx +++ b/web/src/pages/agent/form/exesql-form/index.tsx @@ -13,6 +13,7 @@ import { import { Input, NumberInput } from '@/components/ui/input'; 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 { initialExeSqlValues } from '../../constant'; @@ -135,7 +136,7 @@ export function ExeSQLFormWidgets({ loading }: { loading: boolean }) { ); } -const ExeSQLForm = ({ node }: INextOperatorForm) => { +function ExeSQLForm({ node }: INextOperatorForm) { const defaultValues = useFormValues(initialExeSqlValues, node); const { onSubmit, loading } = useSubmitForm(); @@ -155,6 +156,6 @@ const ExeSQLForm = ({ node }: INextOperatorForm) => { ); -}; +} -export default ExeSQLForm; +export default memo(ExeSQLForm); diff --git a/web/src/pages/agent/form/tool-form/bing-form/index.tsx b/web/src/pages/agent/form/tool-form/bing-form/index.tsx new file mode 100644 index 000000000..00d20a881 --- /dev/null +++ b/web/src/pages/agent/form/tool-form/bing-form/index.tsx @@ -0,0 +1,32 @@ +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 { BingFormSchema, BingFormWidgets } from '../../bing-form'; +import { FormWrapper } from '../../components/form-wrapper'; +import { useValues } from '../use-values'; +import { useWatchFormChange } from '../use-watch-change'; + +export const FormSchema = z.object(BingFormSchema); + +function BingForm() { + const defaultValues = useValues(); + + const form = useForm>({ + resolver: zodResolver(FormSchema), + defaultValues, + }); + + useWatchFormChange(form); + + return ( +
+ + + +
+ ); +} + +export default memo(BingForm); diff --git a/web/src/pages/agent/form/tool-form/constant.tsx b/web/src/pages/agent/form/tool-form/constant.tsx index acbd2171c..c164ae008 100644 --- a/web/src/pages/agent/form/tool-form/constant.tsx +++ b/web/src/pages/agent/form/tool-form/constant.tsx @@ -1,7 +1,6 @@ import { Operator } from '../../constant'; import AkShareForm from '../akshare-form'; import ArXivForm from '../arxiv-form'; -import BingForm from '../bing-form'; import DeepLForm from '../deepl-form'; import DuckDuckGoForm from '../duckduckgo-form'; import EmailForm from '../email-form'; @@ -11,6 +10,7 @@ import GoogleScholarForm from '../google-scholar-form'; import PubMedForm from '../pubmed-form'; import WikipediaForm from '../wikipedia-form'; import YahooFinanceForm from '../yahoo-finance-form'; +import BingForm from './bing-form'; import CrawlerForm from './crawler-form'; import ExeSQLForm from './exesql-form'; import RetrievalForm from './retrieval-form'; diff --git a/web/src/pages/agent/hooks/use-agent-tool-initial-values.ts b/web/src/pages/agent/hooks/use-agent-tool-initial-values.ts index 24ff6e2b4..076cce976 100644 --- a/web/src/pages/agent/hooks/use-agent-tool-initial-values.ts +++ b/web/src/pages/agent/hooks/use-agent-tool-initial-values.ts @@ -22,6 +22,8 @@ export function useAgentToolInitialValues() { }; case Operator.ExeSQL: return omit(initialValues, 'query'); + case Operator.Bing: + return omit(initialValues, 'query'); default: return initialValues;