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 TavilyExtract operator #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1291,6 +1291,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
agent: 'Agent',
|
agent: 'Agent',
|
||||||
agentDescription:
|
agentDescription:
|
||||||
'Builds agent components equipped with reasoning, tool usage, and multi-agent collaboration. ',
|
'Builds agent components equipped with reasoning, tool usage, and multi-agent collaboration. ',
|
||||||
|
maxRecords: 'Max records',
|
||||||
},
|
},
|
||||||
llmTools: {
|
llmTools: {
|
||||||
bad_calculator: {
|
bad_calculator: {
|
||||||
|
|||||||
@ -1244,6 +1244,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
query: '查询变量',
|
query: '查询变量',
|
||||||
agent: 'Agent',
|
agent: 'Agent',
|
||||||
agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。',
|
agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。',
|
||||||
|
maxRecords: '最大记录数',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
|||||||
@ -1,112 +0,0 @@
|
|||||||
import { SideDown } from '@/assets/icon/Icon';
|
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
|
||||||
import {
|
|
||||||
Collapsible,
|
|
||||||
CollapsibleContent,
|
|
||||||
CollapsibleTrigger,
|
|
||||||
} from '@/components/ui/collapsible';
|
|
||||||
import {
|
|
||||||
Sidebar,
|
|
||||||
SidebarContent,
|
|
||||||
SidebarGroup,
|
|
||||||
SidebarGroupContent,
|
|
||||||
SidebarGroupLabel,
|
|
||||||
SidebarHeader,
|
|
||||||
SidebarMenu,
|
|
||||||
} from '@/components/ui/sidebar';
|
|
||||||
import { memo, useMemo } from 'react';
|
|
||||||
import {
|
|
||||||
AgentOperatorList,
|
|
||||||
Operator,
|
|
||||||
componentMenuList,
|
|
||||||
operatorMap,
|
|
||||||
} from './constant';
|
|
||||||
import { useHandleDrag } from './hooks';
|
|
||||||
import OperatorIcon from './operator-icon';
|
|
||||||
|
|
||||||
type OperatorItem = {
|
|
||||||
name: Operator;
|
|
||||||
};
|
|
||||||
|
|
||||||
function OperatorCard({ name }: OperatorItem) {
|
|
||||||
const { handleDragStart } = useHandleDrag();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
draggable
|
|
||||||
onDragStart={handleDragStart(name)}
|
|
||||||
className="bg-colors-background-inverse-weak border-colors-outline-neutral-standard cursor-pointer"
|
|
||||||
>
|
|
||||||
<CardContent className="p-2 flex items-center gap-2">
|
|
||||||
<OperatorIcon
|
|
||||||
name={name}
|
|
||||||
color={operatorMap[name].color}
|
|
||||||
></OperatorIcon>
|
|
||||||
{name}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type OperatorCollapsibleProps = { operatorList: OperatorItem[]; title: string };
|
|
||||||
|
|
||||||
function OperatorCollapsible({
|
|
||||||
operatorList,
|
|
||||||
title,
|
|
||||||
}: OperatorCollapsibleProps) {
|
|
||||||
return (
|
|
||||||
<Collapsible defaultOpen className="group/collapsible">
|
|
||||||
<SidebarGroup>
|
|
||||||
<SidebarGroupLabel asChild className="mb-1">
|
|
||||||
<CollapsibleTrigger>
|
|
||||||
<span className="font-bold text-base">{title}</span>
|
|
||||||
<SideDown className="ml-auto" />
|
|
||||||
</CollapsibleTrigger>
|
|
||||||
</SidebarGroupLabel>
|
|
||||||
<CollapsibleContent className="px-2">
|
|
||||||
<SidebarGroupContent>
|
|
||||||
<SidebarMenu className="gap-2">
|
|
||||||
{operatorList.map((item) => (
|
|
||||||
<OperatorCard key={item.name} name={item.name}></OperatorCard>
|
|
||||||
))}
|
|
||||||
</SidebarMenu>
|
|
||||||
</SidebarGroupContent>
|
|
||||||
</CollapsibleContent>
|
|
||||||
</SidebarGroup>
|
|
||||||
</Collapsible>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function InnerAgentSidebar() {
|
|
||||||
const agentOperatorList = useMemo(() => {
|
|
||||||
return componentMenuList.filter((x) =>
|
|
||||||
AgentOperatorList.some((y) => y === x.name),
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const thirdOperatorList = useMemo(() => {
|
|
||||||
return componentMenuList.filter(
|
|
||||||
(x) => !AgentOperatorList.some((y) => y === x.name),
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Sidebar variant={'floating'} className="top-16">
|
|
||||||
<SidebarHeader>
|
|
||||||
<p className="font-bold text-2xl">All nodes</p>
|
|
||||||
</SidebarHeader>
|
|
||||||
<SidebarContent>
|
|
||||||
<OperatorCollapsible
|
|
||||||
title="Agent operator"
|
|
||||||
operatorList={agentOperatorList}
|
|
||||||
></OperatorCollapsible>
|
|
||||||
<OperatorCollapsible
|
|
||||||
title="Third-party tools"
|
|
||||||
operatorList={thirdOperatorList}
|
|
||||||
></OperatorCollapsible>
|
|
||||||
</SidebarContent>
|
|
||||||
</Sidebar>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AgentSidebar = memo(InnerAgentSidebar);
|
|
||||||
@ -100,7 +100,7 @@ function AccordionOperators() {
|
|||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
operators={[
|
operators={[
|
||||||
Operator.TavilySearch,
|
Operator.TavilySearch,
|
||||||
Operator.Crawler,
|
Operator.TavilyExtract,
|
||||||
Operator.ExeSQL,
|
Operator.ExeSQL,
|
||||||
Operator.Bing,
|
Operator.Bing,
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -87,6 +87,7 @@ export enum Operator {
|
|||||||
Agent = 'Agent',
|
Agent = 'Agent',
|
||||||
Tool = 'Tool',
|
Tool = 'Tool',
|
||||||
TavilySearch = 'TavilySearch',
|
TavilySearch = 'TavilySearch',
|
||||||
|
TavilyExtract = 'TavilyExtract',
|
||||||
UserFillUp = 'UserFillUp',
|
UserFillUp = 'UserFillUp',
|
||||||
StringTransform = 'StringTransform',
|
StringTransform = 'StringTransform',
|
||||||
}
|
}
|
||||||
@ -114,148 +115,6 @@ export const AgentOperatorList = [
|
|||||||
Operator.Agent,
|
Operator.Agent,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const operatorMap: Record<
|
|
||||||
Operator,
|
|
||||||
{
|
|
||||||
backgroundColor?: string;
|
|
||||||
color?: string;
|
|
||||||
width?: number;
|
|
||||||
height?: number;
|
|
||||||
fontSize?: number;
|
|
||||||
iconFontSize?: number;
|
|
||||||
iconWidth?: number;
|
|
||||||
moreIconColor?: string;
|
|
||||||
}
|
|
||||||
> = {
|
|
||||||
[Operator.Retrieval]: {
|
|
||||||
backgroundColor: '#cad6e0',
|
|
||||||
color: '#385974',
|
|
||||||
},
|
|
||||||
[Operator.Generate]: {
|
|
||||||
backgroundColor: '#ebd6d6',
|
|
||||||
width: 150,
|
|
||||||
height: 150,
|
|
||||||
fontSize: 20,
|
|
||||||
iconFontSize: 30,
|
|
||||||
color: '#996464',
|
|
||||||
},
|
|
||||||
[Operator.Answer]: {
|
|
||||||
backgroundColor: '#f4816d',
|
|
||||||
color: '#f4816d',
|
|
||||||
},
|
|
||||||
[Operator.Begin]: {
|
|
||||||
backgroundColor: '#4f51d6',
|
|
||||||
},
|
|
||||||
[Operator.Categorize]: {
|
|
||||||
backgroundColor: '#ffebcd',
|
|
||||||
color: '#cc8a26',
|
|
||||||
},
|
|
||||||
[Operator.Message]: {
|
|
||||||
backgroundColor: '#c5ddc7',
|
|
||||||
color: 'green',
|
|
||||||
},
|
|
||||||
[Operator.Relevant]: {
|
|
||||||
backgroundColor: '#9fd94d',
|
|
||||||
color: '#8ef005',
|
|
||||||
width: 70,
|
|
||||||
height: 70,
|
|
||||||
fontSize: 12,
|
|
||||||
iconFontSize: 16,
|
|
||||||
},
|
|
||||||
[Operator.RewriteQuestion]: {
|
|
||||||
backgroundColor: '#f8c7f8',
|
|
||||||
color: '#f32bf3',
|
|
||||||
width: 70,
|
|
||||||
height: 70,
|
|
||||||
fontSize: 12,
|
|
||||||
iconFontSize: 16,
|
|
||||||
},
|
|
||||||
[Operator.KeywordExtract]: {
|
|
||||||
width: 70,
|
|
||||||
height: 70,
|
|
||||||
backgroundColor: '#6E5494',
|
|
||||||
color: '#6E5494',
|
|
||||||
fontSize: 12,
|
|
||||||
iconWidth: 16,
|
|
||||||
},
|
|
||||||
[Operator.DuckDuckGo]: {
|
|
||||||
backgroundColor: '#e7e389',
|
|
||||||
color: '#aea00c',
|
|
||||||
},
|
|
||||||
[Operator.Baidu]: {
|
|
||||||
backgroundColor: '#d9e0f8',
|
|
||||||
},
|
|
||||||
[Operator.Wikipedia]: {
|
|
||||||
backgroundColor: '#dee0e2',
|
|
||||||
},
|
|
||||||
[Operator.PubMed]: {
|
|
||||||
backgroundColor: '#a2ccf0',
|
|
||||||
},
|
|
||||||
[Operator.ArXiv]: {
|
|
||||||
width: 70,
|
|
||||||
height: 70,
|
|
||||||
fontSize: 12,
|
|
||||||
iconWidth: 16,
|
|
||||||
iconFontSize: 16,
|
|
||||||
moreIconColor: 'white',
|
|
||||||
backgroundColor: '#b31b1b',
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
[Operator.Google]: {
|
|
||||||
backgroundColor: 'pink',
|
|
||||||
},
|
|
||||||
[Operator.Bing]: {
|
|
||||||
backgroundColor: '#c0dcc4',
|
|
||||||
},
|
|
||||||
[Operator.GoogleScholar]: {
|
|
||||||
backgroundColor: '#b4e4f6',
|
|
||||||
},
|
|
||||||
[Operator.DeepL]: {
|
|
||||||
backgroundColor: '#f5e8e6',
|
|
||||||
},
|
|
||||||
[Operator.GitHub]: {
|
|
||||||
backgroundColor: 'purple',
|
|
||||||
color: 'purple',
|
|
||||||
},
|
|
||||||
[Operator.BaiduFanyi]: { backgroundColor: '#e5f2d3' },
|
|
||||||
[Operator.QWeather]: {
|
|
||||||
backgroundColor: '#a4bbf3',
|
|
||||||
color: '#a4bbf3',
|
|
||||||
},
|
|
||||||
[Operator.ExeSQL]: { backgroundColor: '#b9efe8' },
|
|
||||||
[Operator.Switch]: { backgroundColor: '#dbaff6', color: '#dbaff6' },
|
|
||||||
[Operator.WenCai]: { backgroundColor: '#faac5b' },
|
|
||||||
[Operator.AkShare]: { backgroundColor: '#8085f5' },
|
|
||||||
[Operator.YahooFinance]: { backgroundColor: '#b474ff' },
|
|
||||||
[Operator.Jin10]: { backgroundColor: '#a0b9f8' },
|
|
||||||
[Operator.Concentrator]: {
|
|
||||||
backgroundColor: '#32d2a3',
|
|
||||||
color: '#32d2a3',
|
|
||||||
width: 70,
|
|
||||||
height: 70,
|
|
||||||
fontSize: 10,
|
|
||||||
iconFontSize: 16,
|
|
||||||
},
|
|
||||||
[Operator.TuShare]: { backgroundColor: '#f8cfa0' },
|
|
||||||
[Operator.Note]: { backgroundColor: '#f8cfa0' },
|
|
||||||
[Operator.Crawler]: {
|
|
||||||
backgroundColor: '#dee0e2',
|
|
||||||
},
|
|
||||||
[Operator.Invoke]: {
|
|
||||||
backgroundColor: '#dee0e2',
|
|
||||||
},
|
|
||||||
[Operator.Template]: {
|
|
||||||
backgroundColor: '#dee0e2',
|
|
||||||
},
|
|
||||||
[Operator.Email]: { backgroundColor: '#e6f7ff' },
|
|
||||||
[Operator.Iteration]: { backgroundColor: '#e6f7ff' },
|
|
||||||
[Operator.IterationStart]: { backgroundColor: '#e6f7ff' },
|
|
||||||
[Operator.Code]: { backgroundColor: '#4c5458' },
|
|
||||||
[Operator.WaitingDialogue]: { backgroundColor: '#a5d65c' },
|
|
||||||
[Operator.Agent]: { backgroundColor: '#a5d65c' },
|
|
||||||
[Operator.TavilySearch]: { backgroundColor: '#a5d65c' },
|
|
||||||
};
|
|
||||||
|
|
||||||
export const componentMenuList = [
|
export const componentMenuList = [
|
||||||
{
|
{
|
||||||
name: Operator.Retrieval,
|
name: Operator.Retrieval,
|
||||||
@ -552,16 +411,14 @@ export const initialQWeatherValues = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const initialExeSqlValues = {
|
export const initialExeSqlValues = {
|
||||||
...initialLlmBaseValues,
|
sql: '',
|
||||||
db_type: 'mysql',
|
db_type: 'mysql',
|
||||||
database: '',
|
database: '',
|
||||||
username: '',
|
username: '',
|
||||||
host: '',
|
host: '',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
password: '',
|
password: '',
|
||||||
loop: 3,
|
max_records: 1024,
|
||||||
top_n: 30,
|
|
||||||
query: '',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialSwitchValues = {
|
export const initialSwitchValues = {
|
||||||
@ -775,8 +632,34 @@ export const initialTavilyValues = {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
json: {
|
json: {
|
||||||
value: {},
|
value: [],
|
||||||
type: 'Object',
|
type: 'Array<Object>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum TavilyExtractDepth {
|
||||||
|
Basic = 'basic',
|
||||||
|
Advanced = 'advanced',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TavilyExtractFormat {
|
||||||
|
Text = 'text',
|
||||||
|
Markdown = 'markdown',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialTavilyExtractValues = {
|
||||||
|
urls: '',
|
||||||
|
extract_depth: TavilyExtractDepth.Basic,
|
||||||
|
format: TavilyExtractFormat.Markdown,
|
||||||
|
outputs: {
|
||||||
|
formalized_content: {
|
||||||
|
value: '',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
json: {
|
||||||
|
value: [],
|
||||||
|
type: 'Array<Object>',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -866,6 +749,7 @@ export const RestrictedUpstreamMap = {
|
|||||||
[Operator.WaitingDialogue]: [Operator.Begin],
|
[Operator.WaitingDialogue]: [Operator.Begin],
|
||||||
[Operator.Agent]: [Operator.Begin],
|
[Operator.Agent]: [Operator.Begin],
|
||||||
[Operator.TavilySearch]: [Operator.Begin],
|
[Operator.TavilySearch]: [Operator.Begin],
|
||||||
|
[Operator.TavilyExtract]: [Operator.Begin],
|
||||||
[Operator.StringTransform]: [Operator.Begin],
|
[Operator.StringTransform]: [Operator.Begin],
|
||||||
[Operator.UserFillUp]: [Operator.Begin],
|
[Operator.UserFillUp]: [Operator.Begin],
|
||||||
};
|
};
|
||||||
@ -914,6 +798,7 @@ export const NodeMap = {
|
|||||||
[Operator.TavilySearch]: 'ragNode',
|
[Operator.TavilySearch]: 'ragNode',
|
||||||
[Operator.UserFillUp]: 'ragNode',
|
[Operator.UserFillUp]: 'ragNode',
|
||||||
[Operator.StringTransform]: 'ragNode',
|
[Operator.StringTransform]: 'ragNode',
|
||||||
|
[Operator.TavilyExtract]: 'ragNode',
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum BeginQueryType {
|
export enum BeginQueryType {
|
||||||
|
|||||||
182
web/src/pages/agent/form-sheet/form-config-map.tsx
Normal file
182
web/src/pages/agent/form-sheet/form-config-map.tsx
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
import { Operator } from '../constant';
|
||||||
|
import AgentForm from '../form/agent-form';
|
||||||
|
import AkShareForm from '../form/akshare-form';
|
||||||
|
import AnswerForm from '../form/answer-form';
|
||||||
|
import ArXivForm from '../form/arxiv-form';
|
||||||
|
import BaiduFanyiForm from '../form/baidu-fanyi-form';
|
||||||
|
import BaiduForm from '../form/baidu-form';
|
||||||
|
import BeginForm from '../form/begin-form';
|
||||||
|
import BingForm from '../form/bing-form';
|
||||||
|
import CategorizeForm from '../form/categorize-form';
|
||||||
|
import CodeForm from '../form/code-form';
|
||||||
|
import CrawlerForm from '../form/crawler-form';
|
||||||
|
import DeepLForm from '../form/deepl-form';
|
||||||
|
import DuckDuckGoForm from '../form/duckduckgo-form';
|
||||||
|
import EmailForm from '../form/email-form';
|
||||||
|
import ExeSQLForm from '../form/exesql-form';
|
||||||
|
import GenerateForm from '../form/generate-form';
|
||||||
|
import GithubForm from '../form/github-form';
|
||||||
|
import GoogleForm from '../form/google-form';
|
||||||
|
import GoogleScholarForm from '../form/google-scholar-form';
|
||||||
|
import InvokeForm from '../form/invoke-form';
|
||||||
|
import IterationForm from '../form/iteration-form';
|
||||||
|
import IterationStartForm from '../form/iteration-start-from';
|
||||||
|
import Jin10Form from '../form/jin10-form';
|
||||||
|
import KeywordExtractForm from '../form/keyword-extract-form';
|
||||||
|
import MessageForm from '../form/message-form';
|
||||||
|
import PubMedForm from '../form/pubmed-form';
|
||||||
|
import QWeatherForm from '../form/qweather-form';
|
||||||
|
import RelevantForm from '../form/relevant-form';
|
||||||
|
import RetrievalForm from '../form/retrieval-form/next';
|
||||||
|
import RewriteQuestionForm from '../form/rewrite-question-form';
|
||||||
|
import { StringTransformForm } from '../form/string-transform-form';
|
||||||
|
import SwitchForm from '../form/switch-form';
|
||||||
|
import TavilyExtractForm from '../form/tavily-extract-form';
|
||||||
|
import TavilyForm from '../form/tavily-form';
|
||||||
|
import TemplateForm from '../form/template-form';
|
||||||
|
import ToolForm from '../form/tool-form';
|
||||||
|
import TuShareForm from '../form/tushare-form';
|
||||||
|
import UserFillUpForm from '../form/user-fill-up-form';
|
||||||
|
import WenCaiForm from '../form/wencai-form';
|
||||||
|
import WikipediaForm from '../form/wikipedia-form';
|
||||||
|
import YahooFinanceForm from '../form/yahoo-finance-form';
|
||||||
|
|
||||||
|
export const FormConfigMap = {
|
||||||
|
[Operator.Begin]: {
|
||||||
|
component: BeginForm,
|
||||||
|
},
|
||||||
|
[Operator.Retrieval]: {
|
||||||
|
component: RetrievalForm,
|
||||||
|
},
|
||||||
|
[Operator.Generate]: {
|
||||||
|
component: GenerateForm,
|
||||||
|
},
|
||||||
|
[Operator.Answer]: {
|
||||||
|
component: AnswerForm,
|
||||||
|
},
|
||||||
|
[Operator.Categorize]: {
|
||||||
|
component: CategorizeForm,
|
||||||
|
},
|
||||||
|
[Operator.Message]: {
|
||||||
|
component: MessageForm,
|
||||||
|
},
|
||||||
|
[Operator.Relevant]: {
|
||||||
|
component: RelevantForm,
|
||||||
|
},
|
||||||
|
[Operator.RewriteQuestion]: {
|
||||||
|
component: RewriteQuestionForm,
|
||||||
|
},
|
||||||
|
[Operator.Code]: {
|
||||||
|
component: CodeForm,
|
||||||
|
},
|
||||||
|
[Operator.WaitingDialogue]: {
|
||||||
|
component: CodeForm,
|
||||||
|
},
|
||||||
|
[Operator.Agent]: {
|
||||||
|
component: AgentForm,
|
||||||
|
defaultValues: {},
|
||||||
|
schema: z.object({}),
|
||||||
|
},
|
||||||
|
[Operator.Baidu]: {
|
||||||
|
component: BaiduForm,
|
||||||
|
},
|
||||||
|
[Operator.DuckDuckGo]: {
|
||||||
|
component: DuckDuckGoForm,
|
||||||
|
},
|
||||||
|
[Operator.KeywordExtract]: {
|
||||||
|
component: KeywordExtractForm,
|
||||||
|
},
|
||||||
|
[Operator.Wikipedia]: {
|
||||||
|
component: WikipediaForm,
|
||||||
|
},
|
||||||
|
[Operator.PubMed]: {
|
||||||
|
component: PubMedForm,
|
||||||
|
},
|
||||||
|
[Operator.ArXiv]: {
|
||||||
|
component: ArXivForm,
|
||||||
|
},
|
||||||
|
[Operator.Google]: {
|
||||||
|
component: GoogleForm,
|
||||||
|
},
|
||||||
|
[Operator.Bing]: {
|
||||||
|
component: BingForm,
|
||||||
|
},
|
||||||
|
[Operator.GoogleScholar]: {
|
||||||
|
component: GoogleScholarForm,
|
||||||
|
},
|
||||||
|
[Operator.DeepL]: {
|
||||||
|
component: DeepLForm,
|
||||||
|
defaultValues: {},
|
||||||
|
schema: z.object({}),
|
||||||
|
},
|
||||||
|
[Operator.GitHub]: {
|
||||||
|
component: GithubForm,
|
||||||
|
},
|
||||||
|
[Operator.BaiduFanyi]: {
|
||||||
|
component: BaiduFanyiForm,
|
||||||
|
},
|
||||||
|
[Operator.QWeather]: {
|
||||||
|
component: QWeatherForm,
|
||||||
|
},
|
||||||
|
[Operator.ExeSQL]: {
|
||||||
|
component: ExeSQLForm,
|
||||||
|
},
|
||||||
|
[Operator.Switch]: {
|
||||||
|
component: SwitchForm,
|
||||||
|
},
|
||||||
|
[Operator.WenCai]: {
|
||||||
|
component: WenCaiForm,
|
||||||
|
},
|
||||||
|
[Operator.AkShare]: {
|
||||||
|
component: AkShareForm,
|
||||||
|
},
|
||||||
|
[Operator.YahooFinance]: {
|
||||||
|
component: YahooFinanceForm,
|
||||||
|
},
|
||||||
|
[Operator.Jin10]: {
|
||||||
|
component: Jin10Form,
|
||||||
|
},
|
||||||
|
[Operator.TuShare]: {
|
||||||
|
component: TuShareForm,
|
||||||
|
},
|
||||||
|
[Operator.Crawler]: {
|
||||||
|
component: CrawlerForm,
|
||||||
|
},
|
||||||
|
[Operator.Invoke]: {
|
||||||
|
component: InvokeForm,
|
||||||
|
},
|
||||||
|
[Operator.Concentrator]: {
|
||||||
|
component: () => <></>,
|
||||||
|
},
|
||||||
|
[Operator.Note]: {
|
||||||
|
component: () => <></>,
|
||||||
|
},
|
||||||
|
[Operator.Template]: {
|
||||||
|
component: TemplateForm,
|
||||||
|
},
|
||||||
|
[Operator.Email]: {
|
||||||
|
component: EmailForm,
|
||||||
|
},
|
||||||
|
[Operator.Iteration]: {
|
||||||
|
component: IterationForm,
|
||||||
|
},
|
||||||
|
[Operator.IterationStart]: {
|
||||||
|
component: IterationStartForm,
|
||||||
|
},
|
||||||
|
[Operator.Tool]: {
|
||||||
|
component: ToolForm,
|
||||||
|
},
|
||||||
|
[Operator.TavilySearch]: {
|
||||||
|
component: TavilyForm,
|
||||||
|
},
|
||||||
|
[Operator.UserFillUp]: {
|
||||||
|
component: UserFillUpForm,
|
||||||
|
},
|
||||||
|
[Operator.StringTransform]: {
|
||||||
|
component: StringTransformForm,
|
||||||
|
},
|
||||||
|
[Operator.TavilyExtract]: {
|
||||||
|
component: TavilyExtractForm,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -19,8 +19,8 @@ import { useHandleNodeNameChange } from '../hooks/use-change-node-name';
|
|||||||
import OperatorIcon from '../operator-icon';
|
import OperatorIcon from '../operator-icon';
|
||||||
import useGraphStore from '../store';
|
import useGraphStore from '../store';
|
||||||
import { needsSingleStepDebugging } from '../utils';
|
import { needsSingleStepDebugging } from '../utils';
|
||||||
|
import { FormConfigMap } from './form-config-map';
|
||||||
import SingleDebugDrawer from './single-debug-drawer';
|
import SingleDebugDrawer from './single-debug-drawer';
|
||||||
import { useFormConfigMap } from './use-form-config-map';
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
node?: RAGFlowNodeType;
|
node?: RAGFlowNodeType;
|
||||||
@ -44,8 +44,6 @@ const FormSheet = ({
|
|||||||
const operatorName: Operator = node?.data.label as Operator;
|
const operatorName: Operator = node?.data.label as Operator;
|
||||||
const clickedToolId = useGraphStore((state) => state.clickedToolId);
|
const clickedToolId = useGraphStore((state) => state.clickedToolId);
|
||||||
|
|
||||||
const FormConfigMap = useFormConfigMap();
|
|
||||||
|
|
||||||
const currentFormMap = FormConfigMap[operatorName];
|
const currentFormMap = FormConfigMap[operatorName];
|
||||||
|
|
||||||
const OperatorForm = currentFormMap?.component ?? EmptyContent;
|
const OperatorForm = currentFormMap?.component ?? EmptyContent;
|
||||||
|
|||||||
@ -1,400 +0,0 @@
|
|||||||
import { LlmSettingSchema } from '@/components/llm-setting-items/next';
|
|
||||||
import { CodeTemplateStrMap, ProgrammingLanguage } from '@/constants/agent';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { z } from 'zod';
|
|
||||||
import { Operator } from '../constant';
|
|
||||||
import AgentForm from '../form/agent-form';
|
|
||||||
import AkShareForm from '../form/akshare-form';
|
|
||||||
import AnswerForm from '../form/answer-form';
|
|
||||||
import ArXivForm from '../form/arxiv-form';
|
|
||||||
import BaiduFanyiForm from '../form/baidu-fanyi-form';
|
|
||||||
import BaiduForm from '../form/baidu-form';
|
|
||||||
import BeginForm from '../form/begin-form';
|
|
||||||
import BingForm from '../form/bing-form';
|
|
||||||
import CategorizeForm from '../form/categorize-form';
|
|
||||||
import CodeForm from '../form/code-form';
|
|
||||||
import CrawlerForm from '../form/crawler-form';
|
|
||||||
import DeepLForm from '../form/deepl-form';
|
|
||||||
import DuckDuckGoForm from '../form/duckduckgo-form';
|
|
||||||
import EmailForm from '../form/email-form';
|
|
||||||
import ExeSQLForm from '../form/exesql-form';
|
|
||||||
import GenerateForm from '../form/generate-form';
|
|
||||||
import GithubForm from '../form/github-form';
|
|
||||||
import GoogleForm from '../form/google-form';
|
|
||||||
import GoogleScholarForm from '../form/google-scholar-form';
|
|
||||||
import InvokeForm from '../form/invoke-form';
|
|
||||||
import IterationForm from '../form/iteration-form';
|
|
||||||
import IterationStartForm from '../form/iteration-start-from';
|
|
||||||
import Jin10Form from '../form/jin10-form';
|
|
||||||
import KeywordExtractForm from '../form/keyword-extract-form';
|
|
||||||
import MessageForm from '../form/message-form';
|
|
||||||
import PubMedForm from '../form/pubmed-form';
|
|
||||||
import QWeatherForm from '../form/qweather-form';
|
|
||||||
import RelevantForm from '../form/relevant-form';
|
|
||||||
import RetrievalForm from '../form/retrieval-form/next';
|
|
||||||
import RewriteQuestionForm from '../form/rewrite-question-form';
|
|
||||||
import { StringTransformForm } from '../form/string-transform-form';
|
|
||||||
import SwitchForm from '../form/switch-form';
|
|
||||||
import TavilyForm from '../form/tavily-form';
|
|
||||||
import TemplateForm from '../form/template-form';
|
|
||||||
import ToolForm from '../form/tool-form';
|
|
||||||
import TuShareForm from '../form/tushare-form';
|
|
||||||
import UserFillUpForm from '../form/user-fill-up-form';
|
|
||||||
import WenCaiForm from '../form/wencai-form';
|
|
||||||
import WikipediaForm from '../form/wikipedia-form';
|
|
||||||
import YahooFinanceForm from '../form/yahoo-finance-form';
|
|
||||||
|
|
||||||
export function useFormConfigMap() {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const FormConfigMap = {
|
|
||||||
[Operator.Begin]: {
|
|
||||||
component: BeginForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({
|
|
||||||
enablePrologue: z.boolean().optional(),
|
|
||||||
prologue: z
|
|
||||||
.string()
|
|
||||||
.min(1, {
|
|
||||||
message: t('common.namePlaceholder'),
|
|
||||||
})
|
|
||||||
.trim()
|
|
||||||
.optional(),
|
|
||||||
mode: z.string(),
|
|
||||||
query: z
|
|
||||||
.array(
|
|
||||||
z.object({
|
|
||||||
key: z.string(),
|
|
||||||
type: z.string(),
|
|
||||||
value: z.string(),
|
|
||||||
optional: z.boolean(),
|
|
||||||
name: z.string(),
|
|
||||||
options: z.array(z.union([z.number(), z.string(), z.boolean()])),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.optional(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Retrieval]: {
|
|
||||||
component: RetrievalForm,
|
|
||||||
defaultValues: { query: [] },
|
|
||||||
schema: z.object({
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, {
|
|
||||||
message: t('common.namePlaceholder'),
|
|
||||||
})
|
|
||||||
.trim(),
|
|
||||||
age: z
|
|
||||||
.string()
|
|
||||||
.min(1, {
|
|
||||||
message: t('common.namePlaceholder'),
|
|
||||||
})
|
|
||||||
.trim(),
|
|
||||||
query: z.array(
|
|
||||||
z.object({
|
|
||||||
type: z.string(),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Generate]: {
|
|
||||||
component: GenerateForm,
|
|
||||||
defaultValues: {
|
|
||||||
cite: true,
|
|
||||||
prompt: t('flow.promptText'),
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
prompt: z.string().min(1, {
|
|
||||||
message: t('flow.promptMessage'),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Answer]: {
|
|
||||||
component: AnswerForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Categorize]: {
|
|
||||||
component: CategorizeForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({
|
|
||||||
parameter: z.string().optional(),
|
|
||||||
...LlmSettingSchema,
|
|
||||||
message_history_window_size: z.coerce.number(),
|
|
||||||
items: z.array(
|
|
||||||
z
|
|
||||||
.object({
|
|
||||||
name: z.string().min(1, t('flow.nameMessage')).trim(),
|
|
||||||
description: z.string().optional(),
|
|
||||||
// examples: z
|
|
||||||
// .array(
|
|
||||||
// z.object({
|
|
||||||
// value: z.string(),
|
|
||||||
// }),
|
|
||||||
// )
|
|
||||||
// .optional(),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Message]: {
|
|
||||||
component: MessageForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({
|
|
||||||
content: z
|
|
||||||
.array(
|
|
||||||
z.object({
|
|
||||||
value: z.string(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.optional(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Relevant]: {
|
|
||||||
component: RelevantForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.RewriteQuestion]: {
|
|
||||||
component: RewriteQuestionForm,
|
|
||||||
defaultValues: {
|
|
||||||
message_history_window_size: 6,
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
llm_id: z.string(),
|
|
||||||
message_history_window_size: z.number(),
|
|
||||||
language: z.string(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Code]: {
|
|
||||||
component: CodeForm,
|
|
||||||
defaultValues: {
|
|
||||||
lang: ProgrammingLanguage.Python,
|
|
||||||
script: CodeTemplateStrMap[ProgrammingLanguage.Python],
|
|
||||||
arguments: [],
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
lang: z.string(),
|
|
||||||
script: z.string(),
|
|
||||||
arguments: z.array(
|
|
||||||
z.object({ name: z.string(), component_id: z.string() }),
|
|
||||||
),
|
|
||||||
return: z.union([
|
|
||||||
z
|
|
||||||
.array(z.object({ name: z.string(), component_id: z.string() }))
|
|
||||||
.optional(),
|
|
||||||
z.object({ name: z.string(), component_id: z.string() }),
|
|
||||||
]),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.WaitingDialogue]: {
|
|
||||||
component: CodeForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({
|
|
||||||
arguments: z.array(
|
|
||||||
z.object({ name: z.string(), component_id: z.string() }),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Agent]: {
|
|
||||||
component: AgentForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Baidu]: {
|
|
||||||
component: BaiduForm,
|
|
||||||
defaultValues: { top_n: 10 },
|
|
||||||
schema: z.object({ top_n: z.number() }),
|
|
||||||
},
|
|
||||||
[Operator.DuckDuckGo]: {
|
|
||||||
component: DuckDuckGoForm,
|
|
||||||
defaultValues: {
|
|
||||||
top_n: 10,
|
|
||||||
channel: 'text',
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
top_n: z.number(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.KeywordExtract]: {
|
|
||||||
component: KeywordExtractForm,
|
|
||||||
defaultValues: { top_n: 3 },
|
|
||||||
schema: z.object({
|
|
||||||
llm_id: z.string(),
|
|
||||||
top_n: z.number(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.Wikipedia]: {
|
|
||||||
component: WikipediaForm,
|
|
||||||
defaultValues: {
|
|
||||||
top_n: 10,
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
language: z.string(),
|
|
||||||
top_n: z.number(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.PubMed]: {
|
|
||||||
component: PubMedForm,
|
|
||||||
defaultValues: { top_n: 10 },
|
|
||||||
schema: z.object({
|
|
||||||
top_n: z.number(),
|
|
||||||
email: z.string(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.ArXiv]: {
|
|
||||||
component: ArXivForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Google]: {
|
|
||||||
component: GoogleForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Bing]: {
|
|
||||||
component: BingForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.GoogleScholar]: {
|
|
||||||
component: GoogleScholarForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.DeepL]: {
|
|
||||||
component: DeepLForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.GitHub]: {
|
|
||||||
component: GithubForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.BaiduFanyi]: {
|
|
||||||
component: BaiduFanyiForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.QWeather]: {
|
|
||||||
component: QWeatherForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({
|
|
||||||
web_apikey: z.string(),
|
|
||||||
lang: z.string(),
|
|
||||||
type: z.string(),
|
|
||||||
user_type: z.string(),
|
|
||||||
time_period: z.string().optional(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.ExeSQL]: {
|
|
||||||
component: ExeSQLForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Switch]: {
|
|
||||||
component: SwitchForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.WenCai]: {
|
|
||||||
component: WenCaiForm,
|
|
||||||
defaultValues: {
|
|
||||||
top_n: 20,
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
top_n: z.number(),
|
|
||||||
query_type: z.string(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.AkShare]: {
|
|
||||||
component: AkShareForm,
|
|
||||||
defaultValues: {
|
|
||||||
top_n: 10,
|
|
||||||
},
|
|
||||||
schema: z.object({
|
|
||||||
top_n: z.number(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
[Operator.YahooFinance]: {
|
|
||||||
component: YahooFinanceForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Jin10]: {
|
|
||||||
component: Jin10Form,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.TuShare]: {
|
|
||||||
component: TuShareForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Crawler]: {
|
|
||||||
component: CrawlerForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Invoke]: {
|
|
||||||
component: InvokeForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Concentrator]: {
|
|
||||||
component: () => <></>,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Note]: {
|
|
||||||
component: () => <></>,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Template]: {
|
|
||||||
component: TemplateForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Email]: {
|
|
||||||
component: EmailForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Iteration]: {
|
|
||||||
component: IterationForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.IterationStart]: {
|
|
||||||
component: IterationStartForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.Tool]: {
|
|
||||||
component: ToolForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.TavilySearch]: {
|
|
||||||
component: TavilyForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.UserFillUp]: {
|
|
||||||
component: UserFillUpForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
[Operator.StringTransform]: {
|
|
||||||
component: StringTransformForm,
|
|
||||||
defaultValues: {},
|
|
||||||
schema: z.object({}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return FormConfigMap;
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
|
||||||
import { get, isEmpty, isPlainObject, omit } from 'lodash';
|
|
||||||
import { useMemo, useRef } from 'react';
|
|
||||||
import { Operator } from '../constant';
|
|
||||||
import { buildCategorizeListFromObject, convertToObjectArray } from '../utils';
|
|
||||||
import { useFormConfigMap } from './use-form-config-map';
|
|
||||||
|
|
||||||
export function useValues(node?: RAGFlowNodeType, isDirty?: boolean) {
|
|
||||||
const operatorName: Operator = node?.data.label as Operator;
|
|
||||||
const previousId = useRef<string | undefined>(node?.id);
|
|
||||||
|
|
||||||
const FormConfigMap = useFormConfigMap();
|
|
||||||
|
|
||||||
const currentFormMap = FormConfigMap[operatorName];
|
|
||||||
|
|
||||||
const values = useMemo(() => {
|
|
||||||
const formData = node?.data?.form;
|
|
||||||
if (operatorName === Operator.Categorize) {
|
|
||||||
const items = buildCategorizeListFromObject(
|
|
||||||
get(node, 'data.form.category_description', {}),
|
|
||||||
);
|
|
||||||
if (isPlainObject(formData)) {
|
|
||||||
console.info('xxx');
|
|
||||||
const nextValues = {
|
|
||||||
...omit(formData, 'category_description'),
|
|
||||||
items,
|
|
||||||
};
|
|
||||||
|
|
||||||
return nextValues;
|
|
||||||
}
|
|
||||||
} else if (operatorName === Operator.Message) {
|
|
||||||
return {
|
|
||||||
...formData,
|
|
||||||
content: convertToObjectArray(formData.content),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return isEmpty(formData) ? currentFormMap : formData;
|
|
||||||
}
|
|
||||||
}, [currentFormMap, node, operatorName]);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
@ -18,6 +18,7 @@ const Menus = [
|
|||||||
label: 'Search',
|
label: 'Search',
|
||||||
list: [
|
list: [
|
||||||
Operator.TavilySearch,
|
Operator.TavilySearch,
|
||||||
|
Operator.TavilyExtract,
|
||||||
Operator.Google,
|
Operator.Google,
|
||||||
Operator.Bing,
|
Operator.Bing,
|
||||||
Operator.DuckDuckGo,
|
Operator.DuckDuckGo,
|
||||||
@ -41,7 +42,6 @@ const Menus = [
|
|||||||
Operator.GitHub,
|
Operator.GitHub,
|
||||||
Operator.ExeSQL,
|
Operator.ExeSQL,
|
||||||
Operator.Invoke,
|
Operator.Invoke,
|
||||||
Operator.Crawler,
|
|
||||||
Operator.Code,
|
Operator.Code,
|
||||||
Operator.Retrieval,
|
Operator.Retrieval,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { LargeModelFormField } from '@/components/large-model-form-field';
|
import NumberInput from '@/components/originui/number-input';
|
||||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
import { TopNFormField } from '@/components/top-n-item';
|
|
||||||
import { ButtonLoading } from '@/components/ui/button';
|
import { ButtonLoading } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
@ -10,7 +9,7 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input, NumberInput } 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 { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -31,7 +30,6 @@ export function ExeSQLFormWidgets({ loading }: { loading: boolean }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LargeModelFormField></LargeModelFormField>
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="db_type"
|
name="db_type"
|
||||||
@ -94,7 +92,7 @@ export function ExeSQLFormWidgets({ loading }: { loading: boolean }) {
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>{t('port')}</FormLabel>
|
<FormLabel>{t('port')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field}></NumberInput>
|
<NumberInput {...field} className="w-full"></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -113,20 +111,21 @@ export function ExeSQLFormWidgets({ loading }: { loading: boolean }) {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="loop"
|
name="max_records"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel tooltip={t('loopTip')}>{t('loop')}</FormLabel>
|
<FormLabel>{t('maxRecords')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field}></NumberInput>
|
<NumberInput {...field} className="w-full"></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<TopNFormField max={1000}></TopNFormField>
|
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<ButtonLoading loading={loading} type="submit">
|
<ButtonLoading loading={loading} type="submit">
|
||||||
Test
|
Test
|
||||||
@ -151,7 +150,7 @@ function ExeSQLForm({ node }: INextOperatorForm) {
|
|||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<FormWrapper onSubmit={form.handleSubmit(onSubmit)}>
|
<FormWrapper onSubmit={form.handleSubmit(onSubmit)}>
|
||||||
<QueryVariable></QueryVariable>
|
<QueryVariable name="sql"></QueryVariable>
|
||||||
<ExeSQLFormWidgets loading={loading}></ExeSQLFormWidgets>
|
<ExeSQLFormWidgets loading={loading}></ExeSQLFormWidgets>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@ -3,15 +3,14 @@ import { useCallback } from 'react';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
export const ExeSQLFormSchema = {
|
export const ExeSQLFormSchema = {
|
||||||
llm_id: z.string().min(1),
|
sql: z.string(),
|
||||||
db_type: z.string().min(1),
|
db_type: z.string().min(1),
|
||||||
database: z.string().min(1),
|
database: z.string().min(1),
|
||||||
username: z.string().min(1),
|
username: z.string().min(1),
|
||||||
host: z.string().min(1),
|
host: z.string().min(1),
|
||||||
port: z.number(),
|
port: z.number(),
|
||||||
password: z.string().min(1),
|
password: z.string().min(1),
|
||||||
loop: z.number(),
|
max_records: z.number(),
|
||||||
top_n: z.number(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormSchema = z.object({
|
export const FormSchema = z.object({
|
||||||
|
|||||||
115
web/src/pages/agent/form/tavily-extract-form/index.tsx
Normal file
115
web/src/pages/agent/form/tavily-extract-form/index.tsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { FormContainer } from '@/components/form-container';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@/components/ui/form';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { RAGFlowSelect } from '@/components/ui/select';
|
||||||
|
import { buildOptions } from '@/utils/form';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import {
|
||||||
|
TavilyExtractDepth,
|
||||||
|
TavilyExtractFormat,
|
||||||
|
initialTavilyExtractValues,
|
||||||
|
} 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 { TavilyApiKeyField, TavilyFormSchema } from '../tavily-form';
|
||||||
|
|
||||||
|
const outputList = buildOutputList(initialTavilyExtractValues.outputs);
|
||||||
|
|
||||||
|
function TavilyExtractForm({ node }: INextOperatorForm) {
|
||||||
|
const values = useFormValues(initialTavilyExtractValues, node);
|
||||||
|
|
||||||
|
const FormSchema = z.object({
|
||||||
|
...TavilyFormSchema,
|
||||||
|
urls: z.string(),
|
||||||
|
extract_depth: z.enum([
|
||||||
|
TavilyExtractDepth.Advanced,
|
||||||
|
TavilyExtractDepth.Basic,
|
||||||
|
]),
|
||||||
|
format: z.enum([TavilyExtractFormat.Text, TavilyExtractFormat.Markdown]),
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
defaultValues: values,
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useWatchFormChange(node?.id, form);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<FormWrapper>
|
||||||
|
<FormContainer>
|
||||||
|
<TavilyApiKeyField></TavilyApiKeyField>
|
||||||
|
</FormContainer>
|
||||||
|
<FormContainer>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="urls"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>URL</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="extract_depth"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Extract Depth</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<RAGFlowSelect
|
||||||
|
placeholder="shadcn"
|
||||||
|
{...field}
|
||||||
|
options={buildOptions(TavilyExtractDepth)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="format"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Format</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<RAGFlowSelect
|
||||||
|
placeholder="shadcn"
|
||||||
|
{...field}
|
||||||
|
options={buildOptions(TavilyExtractFormat)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FormContainer>
|
||||||
|
</FormWrapper>
|
||||||
|
<div className="p-5">
|
||||||
|
<Output list={outputList}></Output>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(TavilyExtractForm);
|
||||||
@ -13,7 +13,7 @@ import { Switch } from '@/components/ui/switch';
|
|||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm, useFormContext } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import {
|
import {
|
||||||
TavilySearchDepth,
|
TavilySearchDepth,
|
||||||
@ -21,17 +21,41 @@ import {
|
|||||||
initialTavilyValues,
|
initialTavilyValues,
|
||||||
} from '../../constant';
|
} from '../../constant';
|
||||||
import { INextOperatorForm } from '../../interface';
|
import { INextOperatorForm } from '../../interface';
|
||||||
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
import { Output, OutputType } from '../components/output';
|
import { Output, OutputType } from '../components/output';
|
||||||
import { QueryVariable } from '../components/query-variable';
|
import { QueryVariable } from '../components/query-variable';
|
||||||
import { DynamicDomain } from './dynamic-domain';
|
import { DynamicDomain } from './dynamic-domain';
|
||||||
import { useValues } from './use-values';
|
import { useValues } from './use-values';
|
||||||
import { useWatchFormChange } from './use-watch-change';
|
import { useWatchFormChange } from './use-watch-change';
|
||||||
|
|
||||||
|
export function TavilyApiKeyField() {
|
||||||
|
const form = useFormContext();
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="api_key"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Api Key</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input type="password" {...field}></Input>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TavilyFormSchema = {
|
||||||
|
api_key: z.string(),
|
||||||
|
};
|
||||||
|
|
||||||
function TavilyForm({ node }: INextOperatorForm) {
|
function TavilyForm({ node }: INextOperatorForm) {
|
||||||
const values = useValues(node);
|
const values = useValues(node);
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
api_key: z.string(),
|
...TavilyFormSchema,
|
||||||
query: z.string(),
|
query: z.string(),
|
||||||
search_depth: z.enum([TavilySearchDepth.Advanced, TavilySearchDepth.Basic]),
|
search_depth: z.enum([TavilySearchDepth.Advanced, TavilySearchDepth.Basic]),
|
||||||
topic: z.enum([TavilyTopic.News, TavilyTopic.General]),
|
topic: z.enum([TavilyTopic.News, TavilyTopic.General]),
|
||||||
@ -64,27 +88,9 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<FormWrapper>
|
||||||
className="space-y-5 px-5 "
|
|
||||||
autoComplete="off"
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormField
|
<TavilyApiKeyField></TavilyApiKeyField>
|
||||||
control={form.control}
|
|
||||||
name="api_key"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Api Key</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input type="password" {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<QueryVariable></QueryVariable>
|
<QueryVariable></QueryVariable>
|
||||||
@ -221,7 +227,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
label={'Exclude Domains'}
|
label={'Exclude Domains'}
|
||||||
></DynamicDomain>
|
></DynamicDomain>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
</form>
|
</FormWrapper>
|
||||||
<div className="p-5">
|
<div className="p-5">
|
||||||
<Output list={outputList}></Output>
|
<Output list={outputList}></Output>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Manually triggered form updates are synchronized to the canvas
|
// Manually triggered form updates are synchronized to the canvas
|
||||||
if (id && form?.formState.isDirty) {
|
if (id) {
|
||||||
values = form?.getValues();
|
values = form?.getValues();
|
||||||
let nextValues: any = {
|
let nextValues: any = {
|
||||||
...values,
|
...values,
|
||||||
|
|||||||
@ -34,4 +34,5 @@ export const ToolFormConfigMap = {
|
|||||||
[Operator.Crawler]: CrawlerForm,
|
[Operator.Crawler]: CrawlerForm,
|
||||||
[Operator.Email]: EmailForm,
|
[Operator.Email]: EmailForm,
|
||||||
[Operator.TavilySearch]: TavilyForm,
|
[Operator.TavilySearch]: TavilyForm,
|
||||||
|
[Operator.TavilyExtract]: TavilyForm,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,25 +1,17 @@
|
|||||||
import { FormContainer } from '@/components/form-container';
|
import { FormContainer } from '@/components/form-container';
|
||||||
import {
|
import { Form } from '@/components/ui/form';
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { FormWrapper } from '../../components/form-wrapper';
|
||||||
|
import { TavilyApiKeyField, TavilyFormSchema } from '../../tavily-form';
|
||||||
import { useValues } from '../use-values';
|
import { useValues } from '../use-values';
|
||||||
import { useWatchFormChange } from '../use-watch-change';
|
import { useWatchFormChange } from '../use-watch-change';
|
||||||
|
|
||||||
const TavilyForm = () => {
|
const TavilyForm = () => {
|
||||||
const values = useValues();
|
const values = useValues();
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object(TavilyFormSchema);
|
||||||
api_key: z.string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
defaultValues: values,
|
defaultValues: values,
|
||||||
@ -30,29 +22,11 @@ const TavilyForm = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<FormWrapper>
|
||||||
className="space-y-5 px-5 "
|
|
||||||
autoComplete="off"
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormField
|
<TavilyApiKeyField></TavilyApiKeyField>
|
||||||
control={form.control}
|
|
||||||
name="api_key"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Api Key</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input type="password" {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
</form>
|
</FormWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -41,6 +41,7 @@ import {
|
|||||||
initialRewriteQuestionValues,
|
initialRewriteQuestionValues,
|
||||||
initialStringTransformValues,
|
initialStringTransformValues,
|
||||||
initialSwitchValues,
|
initialSwitchValues,
|
||||||
|
initialTavilyExtractValues,
|
||||||
initialTavilyValues,
|
initialTavilyValues,
|
||||||
initialTemplateValues,
|
initialTemplateValues,
|
||||||
initialTuShareValues,
|
initialTuShareValues,
|
||||||
@ -94,7 +95,7 @@ export const useInitializeOperatorParams = () => {
|
|||||||
[Operator.GitHub]: initialGithubValues,
|
[Operator.GitHub]: initialGithubValues,
|
||||||
[Operator.BaiduFanyi]: initialBaiduFanyiValues,
|
[Operator.BaiduFanyi]: initialBaiduFanyiValues,
|
||||||
[Operator.QWeather]: initialQWeatherValues,
|
[Operator.QWeather]: initialQWeatherValues,
|
||||||
[Operator.ExeSQL]: { ...initialExeSqlValues, llm_id: llmId },
|
[Operator.ExeSQL]: initialExeSqlValues,
|
||||||
[Operator.Switch]: initialSwitchValues,
|
[Operator.Switch]: initialSwitchValues,
|
||||||
[Operator.WenCai]: initialWenCaiValues,
|
[Operator.WenCai]: initialWenCaiValues,
|
||||||
[Operator.AkShare]: initialAkShareValues,
|
[Operator.AkShare]: initialAkShareValues,
|
||||||
@ -116,6 +117,7 @@ export const useInitializeOperatorParams = () => {
|
|||||||
[Operator.TavilySearch]: initialTavilyValues,
|
[Operator.TavilySearch]: initialTavilyValues,
|
||||||
[Operator.UserFillUp]: initialUserFillUpValues,
|
[Operator.UserFillUp]: initialUserFillUpValues,
|
||||||
[Operator.StringTransform]: initialStringTransformValues,
|
[Operator.StringTransform]: initialStringTransformValues,
|
||||||
|
[Operator.TavilyExtract]: initialTavilyExtractValues,
|
||||||
};
|
};
|
||||||
}, [llmId]);
|
}, [llmId]);
|
||||||
|
|
||||||
|
|||||||
@ -16,12 +16,12 @@ export function useAgentToolInitialValues() {
|
|||||||
...omit(initialValues, 'query'),
|
...omit(initialValues, 'query'),
|
||||||
description: '',
|
description: '',
|
||||||
};
|
};
|
||||||
case Operator.TavilySearch:
|
case (Operator.TavilySearch, Operator.TavilyExtract):
|
||||||
return {
|
return {
|
||||||
api_key: '',
|
api_key: '',
|
||||||
};
|
};
|
||||||
case Operator.ExeSQL:
|
case Operator.ExeSQL:
|
||||||
return omit(initialValues, 'query');
|
return omit(initialValues, 'sql');
|
||||||
case Operator.Bing:
|
case Operator.Bing:
|
||||||
return omit(initialValues, 'query');
|
return omit(initialValues, 'query');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user