Skip to content

Commit 8695d60

Browse files
authored
Feat: Improve the tavily form infiniflow#3221 (infiniflow#8390)
### What problem does this PR solve? Feat: Improve the tavily form infiniflow#3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
1 parent 936a91c commit 8695d60

File tree

5 files changed

+206
-11
lines changed

5 files changed

+206
-11
lines changed

web/src/pages/agent/form/components/output.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type OutputType = {
1+
export type OutputType = {
22
title: string;
33
type: string;
44
};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { BlockButton, Button } from '@/components/ui/button';
2+
import {
3+
FormControl,
4+
FormField,
5+
FormItem,
6+
FormLabel,
7+
FormMessage,
8+
} from '@/components/ui/form';
9+
import { Input } from '@/components/ui/input';
10+
import { X } from 'lucide-react';
11+
import { ReactNode } from 'react';
12+
import { useFieldArray, useFormContext } from 'react-hook-form';
13+
14+
type DynamicDomainProps = { name: string; label: ReactNode };
15+
16+
export const DynamicDomain = ({ name, label }: DynamicDomainProps) => {
17+
const form = useFormContext();
18+
19+
const { fields, append, remove } = useFieldArray({
20+
name: name,
21+
control: form.control,
22+
});
23+
24+
return (
25+
<FormItem>
26+
<FormLabel>{label}</FormLabel>
27+
<div className="space-y-4">
28+
{fields.map((field, index) => (
29+
<div key={field.id} className="flex">
30+
<div className="space-y-2 flex-1">
31+
<FormField
32+
control={form.control}
33+
name={`${name}.${index}.value`}
34+
render={({ field }) => (
35+
<FormItem className="flex-1">
36+
<FormControl>
37+
<Input {...field}></Input>
38+
</FormControl>
39+
</FormItem>
40+
)}
41+
/>
42+
</div>
43+
<Button
44+
type="button"
45+
variant={'ghost'}
46+
onClick={() => remove(index)}
47+
>
48+
<X />
49+
</Button>
50+
</div>
51+
))}
52+
</div>
53+
<FormMessage />
54+
<BlockButton onClick={() => append({ value: '' })}>Add</BlockButton>
55+
</FormItem>
56+
);
57+
};

web/src/pages/agent/form/tavily-form/index.tsx

Lines changed: 122 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,23 @@ import {
99
} from '@/components/ui/form';
1010
import { Input } from '@/components/ui/input';
1111
import { RAGFlowSelect } from '@/components/ui/select';
12+
import { Switch } from '@/components/ui/switch';
1213
import { buildOptions } from '@/utils/form';
1314
import { zodResolver } from '@hookform/resolvers/zod';
15+
import { useMemo } from 'react';
1416
import { useForm } from 'react-hook-form';
1517
import { z } from 'zod';
18+
import { Output, OutputType } from '../components/output';
1619
import { QueryVariable } from '../components/query-variable';
17-
import { SearchDepth, Topic, useValues } from './use-values';
20+
import { DynamicDomain } from './dynamic-domain';
21+
import { SearchDepth, Topic, defaultValues, useValues } from './use-values';
1822
import { useWatchFormChange } from './use-watch-change';
1923

2024
const TavilyForm = () => {
2125
const values = useValues();
2226

2327
const FormSchema = z.object({
28+
api_key: z.string(),
2429
query: z.string(),
2530
search_depth: z.enum([SearchDepth.Advanced, SearchDepth.Basic]),
2631
topic: z.enum([Topic.News, Topic.General]),
@@ -30,15 +35,25 @@ const TavilyForm = () => {
3035
include_raw_content: z.boolean(),
3136
include_images: z.boolean(),
3237
include_image_descriptions: z.boolean(),
33-
include_domains: z.array(z.string()),
34-
exclude_domains: z.array(z.string()),
38+
include_domains: z.array(z.object({ value: z.any() })), // TODO: z.string should be used, but an error will be reported
39+
exclude_domains: z.array(z.object({ value: z.any() })),
3540
});
3641

37-
const form = useForm({
42+
const form = useForm<z.infer<typeof FormSchema>>({
3843
defaultValues: values,
3944
resolver: zodResolver(FormSchema),
4045
});
4146

47+
const outputList = useMemo(() => {
48+
return Object.entries(defaultValues.outputs).reduce<OutputType[]>(
49+
(pre, [key, val]) => {
50+
pre.push({ title: key, type: val.type });
51+
return pre;
52+
},
53+
[],
54+
);
55+
}, []);
56+
4257
useWatchFormChange(form);
4358

4459
return (
@@ -50,9 +65,23 @@ const TavilyForm = () => {
5065
e.preventDefault();
5166
}}
5267
>
68+
<FormContainer>
69+
<FormField
70+
control={form.control}
71+
name="api_key"
72+
render={({ field }) => (
73+
<FormItem>
74+
<FormLabel>Api Key</FormLabel>
75+
<FormControl>
76+
<Input type="password" {...field}></Input>
77+
</FormControl>
78+
<FormMessage />
79+
</FormItem>
80+
)}
81+
/>
82+
</FormContainer>
5383
<FormContainer>
5484
<QueryVariable></QueryVariable>
55-
5685
<FormField
5786
control={form.control}
5887
name="search_depth"
@@ -100,8 +129,96 @@ const TavilyForm = () => {
100129
</FormItem>
101130
)}
102131
/>
132+
<FormField
133+
control={form.control}
134+
name="days"
135+
render={({ field }) => (
136+
<FormItem>
137+
<FormLabel>Days</FormLabel>
138+
<FormControl>
139+
<Input type={'number'} {...field}></Input>
140+
</FormControl>
141+
<FormMessage />
142+
</FormItem>
143+
)}
144+
/>
145+
<FormField
146+
control={form.control}
147+
name="include_answer"
148+
render={({ field }) => (
149+
<FormItem>
150+
<FormLabel>Include Answer</FormLabel>
151+
<FormControl>
152+
<Switch
153+
checked={field.value}
154+
onCheckedChange={field.onChange}
155+
></Switch>
156+
</FormControl>
157+
<FormMessage />
158+
</FormItem>
159+
)}
160+
/>
161+
<FormField
162+
control={form.control}
163+
name="include_raw_content"
164+
render={({ field }) => (
165+
<FormItem>
166+
<FormLabel>Include Raw Content</FormLabel>
167+
<FormControl>
168+
<Switch
169+
checked={field.value}
170+
onCheckedChange={field.onChange}
171+
></Switch>
172+
</FormControl>
173+
<FormMessage />
174+
</FormItem>
175+
)}
176+
/>
177+
<FormField
178+
control={form.control}
179+
name="include_images"
180+
render={({ field }) => (
181+
<FormItem>
182+
<FormLabel>Include Images</FormLabel>
183+
<FormControl>
184+
<Switch
185+
checked={field.value}
186+
onCheckedChange={field.onChange}
187+
></Switch>
188+
</FormControl>
189+
<FormMessage />
190+
</FormItem>
191+
)}
192+
/>
193+
<FormField
194+
control={form.control}
195+
name="include_image_descriptions"
196+
render={({ field }) => (
197+
<FormItem>
198+
<FormLabel>Include Image Descriptions</FormLabel>
199+
<FormControl>
200+
<Switch
201+
checked={field.value}
202+
onCheckedChange={field.onChange}
203+
></Switch>
204+
</FormControl>
205+
<FormMessage />
206+
</FormItem>
207+
)}
208+
/>
209+
<DynamicDomain
210+
name="include_domains"
211+
label={'Include Domains'}
212+
></DynamicDomain>
213+
<DynamicDomain
214+
name="exclude_domains"
215+
label={'Exclude Domains'}
216+
></DynamicDomain>
103217
</FormContainer>
104218
</form>
219+
<div className="p-5">
220+
<Output list={outputList}></Output>
221+
</div>
105222
</Form>
106223
);
107224
};

web/src/pages/agent/form/tavily-form/use-values.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { AgentGlobals } from '@/constants/agent';
12
import { isEmpty } from 'lodash';
23
import { useMemo } from 'react';
34
import useGraphStore from '../../store';
4-
import { getAgentNodeTools } from '../../utils';
5+
import { convertToObjectArray, getAgentNodeTools } from '../../utils';
56

67
export enum SearchDepth {
78
Basic = 'basic',
@@ -13,8 +14,9 @@ export enum Topic {
1314
General = 'general',
1415
}
1516

16-
const defaultValues = {
17-
query: '',
17+
export const defaultValues = {
18+
api_key: '',
19+
query: AgentGlobals.SysQuery,
1820
search_depth: SearchDepth.Basic,
1921
topic: Topic.General,
2022
max_results: 5,
@@ -25,6 +27,16 @@ const defaultValues = {
2527
include_image_descriptions: false,
2628
include_domains: [],
2729
exclude_domains: [],
30+
outputs: {
31+
formalized_content: {
32+
value: '',
33+
type: 'string',
34+
},
35+
json: {
36+
value: {},
37+
type: 'Object',
38+
},
39+
},
2840
};
2941

3042
export function useValues() {
@@ -46,6 +58,8 @@ export function useValues() {
4658

4759
return {
4860
...formData,
61+
include_domains: convertToObjectArray(formData.include_domains),
62+
exclude_domains: convertToObjectArray(formData.exclude_domains),
4963
};
5064
}, [clickedNodeId, clickedToolId, findUpstreamNodeById]);
5165

web/src/pages/agent/form/tavily-form/use-watch-change.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect } from 'react';
22
import { UseFormReturn, useWatch } from 'react-hook-form';
33
import useGraphStore from '../../store';
4-
import { getAgentNodeTools } from '../../utils';
4+
import { convertToStringArray, getAgentNodeTools } from '../../utils';
55

66
export function useWatchFormChange(form?: UseFormReturn<any>) {
77
let values = useWatch({ control: form?.control });
@@ -18,7 +18,14 @@ export function useWatchFormChange(form?: UseFormReturn<any>) {
1818
values = form?.getValues();
1919
const nextTools = tools.map((x) => {
2020
if (x.component_name === clickedToolId) {
21-
return { ...x, params: { ...values } };
21+
return {
22+
...x,
23+
params: {
24+
...values,
25+
include_domains: convertToStringArray(values.include_domains),
26+
exclude_domains: convertToStringArray(values.exclude_domains),
27+
},
28+
};
2229
}
2330
return x;
2431
});

0 commit comments

Comments
 (0)