mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Fix(i18n): Added new translations #3221 - Added and updated internationalization translations in multiple components ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --------- Co-authored-by: Kevin Hu <kevinhu.sh@gmail.com>
This commit is contained in:
@ -12,6 +12,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { LlmModelType } from '@/constants/knowledge';
|
import { LlmModelType } from '@/constants/knowledge';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { Funnel } from 'lucide-react';
|
import { Funnel } from 'lucide-react';
|
||||||
import { useFormContext, useWatch } from 'react-hook-form';
|
import { useFormContext, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -21,15 +22,15 @@ import { Button } from './ui/button';
|
|||||||
|
|
||||||
const ModelTypes = [
|
const ModelTypes = [
|
||||||
{
|
{
|
||||||
title: 'All Models',
|
title: t('flow.allModels'),
|
||||||
value: 'all',
|
value: 'all',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Text-only Models',
|
title: t('flow.textOnlyModels'),
|
||||||
value: LlmModelType.Chat,
|
value: LlmModelType.Chat,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Multimodal Models',
|
title: t('flow.multimodalModels'),
|
||||||
value: LlmModelType.Image2text,
|
value: LlmModelType.Image2text,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -145,9 +145,9 @@ export const SelectWithSearch = forwardRef<
|
|||||||
align="start"
|
align="start"
|
||||||
>
|
>
|
||||||
<Command>
|
<Command>
|
||||||
<CommandInput placeholder="Search ..." />
|
<CommandInput placeholder={t('common.search') + '...'} />
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>No data found.</CommandEmpty>
|
<CommandEmpty>{t('common.noDataFound')}</CommandEmpty>
|
||||||
{options.map((group, idx) => {
|
{options.map((group, idx) => {
|
||||||
if (group.options) {
|
if (group.options) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { t } from 'i18next';
|
||||||
import { Loader2 } from 'lucide-react';
|
import { Loader2 } from 'lucide-react';
|
||||||
import { PropsWithChildren } from 'react';
|
import { PropsWithChildren } from 'react';
|
||||||
import { TableCell, TableRow } from './ui/table';
|
import { TableCell, TableRow } from './ui/table';
|
||||||
@ -28,5 +29,5 @@ export function TableSkeleton({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function TableEmpty({ columnsLength }: { columnsLength: number }) {
|
export function TableEmpty({ columnsLength }: { columnsLength: number }) {
|
||||||
return <Row columnsLength={columnsLength}>No results.</Row>;
|
return <Row columnsLength={columnsLength}>{t('common.noResults')}</Row>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
translation: {
|
translation: {
|
||||||
common: {
|
common: {
|
||||||
|
noResults: 'No results.',
|
||||||
selectPlaceholder: 'select value',
|
selectPlaceholder: 'select value',
|
||||||
delete: 'Delete',
|
delete: 'Delete',
|
||||||
deleteModalTitle: 'Are you sure to delete this item?',
|
deleteModalTitle: 'Are you sure to delete this item?',
|
||||||
@ -40,6 +41,9 @@ export default {
|
|||||||
previousPage: 'Previous',
|
previousPage: 'Previous',
|
||||||
nextPage: 'Next',
|
nextPage: 'Next',
|
||||||
add: 'Add',
|
add: 'Add',
|
||||||
|
remove: 'Remove',
|
||||||
|
search: 'Search',
|
||||||
|
noDataFound: 'No data found.',
|
||||||
promptPlaceholder: `Please input or use / to quickly insert variables.`,
|
promptPlaceholder: `Please input or use / to quickly insert variables.`,
|
||||||
mcp: {
|
mcp: {
|
||||||
namePlaceholder: 'My MCP Server',
|
namePlaceholder: 'My MCP Server',
|
||||||
@ -860,11 +864,85 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
|||||||
pleaseUploadAtLeastOneFile: 'Please upload at least one file',
|
pleaseUploadAtLeastOneFile: 'Please upload at least one file',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
|
beginInput: 'Begin Input',
|
||||||
|
ref: 'Variable',
|
||||||
|
stockCode: 'Stock Code',
|
||||||
|
apiKeyPlaceholder:
|
||||||
|
'YOUR_API_KEY (obtained from https://serpapi.com/manage-api-key)',
|
||||||
|
flowStart: 'Start',
|
||||||
|
flowNum: 'Num',
|
||||||
|
test: 'Test',
|
||||||
|
extractDepth: 'Extract Depth',
|
||||||
|
format: 'Format',
|
||||||
|
basic: 'basic',
|
||||||
|
advanced: 'advanced',
|
||||||
|
general: 'general',
|
||||||
|
searchDepth: 'Search Depth',
|
||||||
|
tavilyTopic: 'Tavily Topic',
|
||||||
|
maxResults: 'Max Results',
|
||||||
|
includeAnswer: 'Include Answer',
|
||||||
|
includeRawContent: 'Include Raw Content',
|
||||||
|
includeImages: 'Include Images',
|
||||||
|
includeImageDescriptions: 'Include Image Descriptions',
|
||||||
|
includeDomains: 'Include Domains',
|
||||||
|
ExcludeDomains: 'Exclude Domains',
|
||||||
|
Days: 'Days',
|
||||||
|
comma: 'Comma',
|
||||||
|
semicolon: 'Semicolon',
|
||||||
|
period: 'Period',
|
||||||
|
lineBreak: 'Line Break',
|
||||||
|
tab: 'Tab',
|
||||||
|
space: 'Space',
|
||||||
|
delimiters: 'Delimiters',
|
||||||
|
merge: 'Merge',
|
||||||
|
split: 'Split',
|
||||||
|
script: 'Script',
|
||||||
|
iterationItemDescription:
|
||||||
|
'It represents the current element in the iteration, which can be referenced and manipulated in subsequent steps.',
|
||||||
|
guidingQuestion: 'Guidance Question',
|
||||||
|
onFailure: 'On Failure',
|
||||||
|
userPromptDefaultValue:
|
||||||
|
'This is the order you need to send to the agent.',
|
||||||
|
search: 'Search',
|
||||||
|
communication: 'Communication',
|
||||||
|
developer: 'Developer',
|
||||||
|
typeCommandOrsearch: 'Type a command or search...',
|
||||||
|
builtIn: 'Built-in',
|
||||||
|
ExceptionDefaultValue: 'Exception default value',
|
||||||
|
exceptionMethod: 'Exception method',
|
||||||
|
maxRounds: 'Max rounds',
|
||||||
|
delayEfterError: 'Delay after error',
|
||||||
|
maxRetries: 'Max retries',
|
||||||
|
advancedSettings: 'Advanced Settings',
|
||||||
|
addTools: 'Add Tools',
|
||||||
|
sysPromptDefultValue: `<role>
|
||||||
|
You are {{agent_name}}, an AI assistant specialized in {{domain_or_task}}.
|
||||||
|
</role>
|
||||||
|
<instructions>
|
||||||
|
1. Understand the user’s request.
|
||||||
|
2. Decompose it into logical subtasks.
|
||||||
|
3. Execute each subtask step by step, reasoning transparently.
|
||||||
|
4. Validate accuracy and consistency.
|
||||||
|
5. Summarize the final result clearly.
|
||||||
|
</instructions>`,
|
||||||
|
singleLineText: 'Single-line text',
|
||||||
|
multimodalModels: 'Multimodal Models',
|
||||||
|
textOnlyModels: 'Text-only Models',
|
||||||
|
allModels: 'All Models',
|
||||||
|
codeExecDescription: 'Write your custom Python or Javascript logic.',
|
||||||
|
stringTransformDescription:
|
||||||
|
'Modifies text content. Currently supports: Splitting or concatenating text.',
|
||||||
|
foundation: 'Foundation',
|
||||||
|
tools: 'Tools',
|
||||||
|
dataManipulation: 'Data Manipulation',
|
||||||
|
flow: 'Flow',
|
||||||
|
dialog: 'Dialogue',
|
||||||
cite: 'Cite',
|
cite: 'Cite',
|
||||||
citeTip: 'citeTip',
|
citeTip: 'citeTip',
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
nameMessage: 'Please input name',
|
nameMessage: 'Please input name',
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
|
descriptionMessage: 'This is an agent for a specific task.',
|
||||||
examples: 'Examples',
|
examples: 'Examples',
|
||||||
to: 'To',
|
to: 'To',
|
||||||
msg: 'Messages',
|
msg: 'Messages',
|
||||||
@ -1289,6 +1367,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
variableSettings: 'Variable settings',
|
variableSettings: 'Variable settings',
|
||||||
globalVariables: 'Global variables',
|
globalVariables: 'Global variables',
|
||||||
systemPrompt: 'System prompt',
|
systemPrompt: 'System prompt',
|
||||||
|
userPrompt: 'User prompt',
|
||||||
addCategory: 'Add category',
|
addCategory: 'Add category',
|
||||||
categoryName: 'Category name',
|
categoryName: 'Category name',
|
||||||
nextStep: 'Next step',
|
nextStep: 'Next step',
|
||||||
@ -1352,10 +1431,15 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
openingSwitchTip:
|
openingSwitchTip:
|
||||||
'Your users will see this welcome message at the beginning.',
|
'Your users will see this welcome message at the beginning.',
|
||||||
modeTip: 'The mode defines how the workflow is initiated.',
|
modeTip: 'The mode defines how the workflow is initiated.',
|
||||||
|
mode: 'Mode',
|
||||||
|
conversational: 'conversational',
|
||||||
|
task: 'task',
|
||||||
beginInputTip:
|
beginInputTip:
|
||||||
'By defining input parameters, this content can be accessed by other components in subsequent processes.',
|
'By defining input parameters, this content can be accessed by other components in subsequent processes.',
|
||||||
query: 'Query variables',
|
query: 'Query variables',
|
||||||
|
queryTip: 'Select the variable you want to use',
|
||||||
agent: 'Agent',
|
agent: 'Agent',
|
||||||
|
addAgent: 'Add 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',
|
maxRecords: 'Max records',
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export default {
|
|||||||
setting: '用戶設置',
|
setting: '用戶設置',
|
||||||
logout: '登出',
|
logout: '登出',
|
||||||
fileManager: '文件管理',
|
fileManager: '文件管理',
|
||||||
flow: 'Agent',
|
flow: '智能體',
|
||||||
search: '搜尋',
|
search: '搜尋',
|
||||||
welcome: '歡迎來到',
|
welcome: '歡迎來到',
|
||||||
},
|
},
|
||||||
@ -764,6 +764,23 @@ export default {
|
|||||||
destinationFolder: '目標資料夾',
|
destinationFolder: '目標資料夾',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
|
line: '單行文本',
|
||||||
|
paragraph: '段落文字',
|
||||||
|
options: '選項',
|
||||||
|
file: '文件',
|
||||||
|
integer: '數字',
|
||||||
|
boolean: '布爾值',
|
||||||
|
multimodalModels: '多模態模型',
|
||||||
|
textOnlyModels: '進文本模型',
|
||||||
|
allModels: '所有模型',
|
||||||
|
codeExecDescription: '用 Python 或者 Javascript 編寫自定義邏輯',
|
||||||
|
stringTransformDescription:
|
||||||
|
'修改文本内容,目前支持文本分割、文本拼接操作',
|
||||||
|
foundation: '基礎',
|
||||||
|
tools: '工具',
|
||||||
|
dataManipulation: '數據操控',
|
||||||
|
flow: '流程',
|
||||||
|
dialog: '對話',
|
||||||
cite: '引用',
|
cite: '引用',
|
||||||
citeTip: 'citeTip',
|
citeTip: 'citeTip',
|
||||||
name: '名稱',
|
name: '名稱',
|
||||||
@ -805,7 +822,7 @@ export default {
|
|||||||
promptText: `請總結以下段落。注意數字,不要胡編亂造。段落如下:
|
promptText: `請總結以下段落。注意數字,不要胡編亂造。段落如下:
|
||||||
{input}
|
{input}
|
||||||
以上就是你需要總結的內容。`,
|
以上就是你需要總結的內容。`,
|
||||||
createGraph: '建立 Agent',
|
createGraph: '創建智能體',
|
||||||
createFromTemplates: '從模板創建',
|
createFromTemplates: '從模板創建',
|
||||||
retrieval: '知識檢索',
|
retrieval: '知識檢索',
|
||||||
generate: '生成回答',
|
generate: '生成回答',
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
translation: {
|
translation: {
|
||||||
common: {
|
common: {
|
||||||
|
noResults: '无结果。',
|
||||||
selectPlaceholder: '请选择',
|
selectPlaceholder: '请选择',
|
||||||
delete: '删除',
|
delete: '删除',
|
||||||
deleteModalTitle: '确定删除吗?',
|
deleteModalTitle: '确定删除吗?',
|
||||||
@ -39,6 +40,9 @@ export default {
|
|||||||
previousPage: '上一页',
|
previousPage: '上一页',
|
||||||
nextPage: '下一页',
|
nextPage: '下一页',
|
||||||
add: '添加',
|
add: '添加',
|
||||||
|
remove: '移除',
|
||||||
|
search: '搜索',
|
||||||
|
noDataFound: '没有找到数据。',
|
||||||
promptPlaceholder: '请输入或使用 / 快速插入变量。',
|
promptPlaceholder: '请输入或使用 / 快速插入变量。',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
@ -71,7 +75,7 @@ export default {
|
|||||||
setting: '用户设置',
|
setting: '用户设置',
|
||||||
logout: '登出',
|
logout: '登出',
|
||||||
fileManager: '文件管理',
|
fileManager: '文件管理',
|
||||||
flow: 'Agent',
|
flow: '智能体',
|
||||||
search: '搜索',
|
search: '搜索',
|
||||||
welcome: '欢迎来到',
|
welcome: '欢迎来到',
|
||||||
dataset: '数据集',
|
dataset: '数据集',
|
||||||
@ -814,6 +818,89 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
pleaseUploadAtLeastOneFile: '请上传至少一个文件',
|
pleaseUploadAtLeastOneFile: '请上传至少一个文件',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
|
beginInput: '开始输入',
|
||||||
|
seconds: '秒',
|
||||||
|
ref: '引用变量',
|
||||||
|
stockCode: '股票代码',
|
||||||
|
apiKeyPlaceholder: '您的API密钥(从https://serpapi.com获取)',
|
||||||
|
flowStart: '开始',
|
||||||
|
flowNum: '编号',
|
||||||
|
test: '测试',
|
||||||
|
extractDepth: '深度提取',
|
||||||
|
format: '格式',
|
||||||
|
basic: '基本',
|
||||||
|
advanced: '高级',
|
||||||
|
general: '通用',
|
||||||
|
searchDepth: '深度搜索',
|
||||||
|
tavilyTopic: 'Tavily话题',
|
||||||
|
maxResults: '最大结果数',
|
||||||
|
includeAnswer: '包含答案',
|
||||||
|
includeRawContent: '包含原始内容',
|
||||||
|
includeImages: '包含图片',
|
||||||
|
includeImageDescriptions: '包含图片描述',
|
||||||
|
includeDomains: '包含域名',
|
||||||
|
ExcludeDomains: '排除域名',
|
||||||
|
Days: 'Days',
|
||||||
|
comma: '逗号',
|
||||||
|
semicolon: '分号',
|
||||||
|
period: '句点',
|
||||||
|
linebreak: '换行符',
|
||||||
|
tab: '制表符',
|
||||||
|
space: '空格',
|
||||||
|
delimiters: '分隔符',
|
||||||
|
merge: '合并',
|
||||||
|
split: '拆分',
|
||||||
|
script: '脚本',
|
||||||
|
iterationItemDescription:
|
||||||
|
'它是迭代过程中的当前元素,可以被后续流程引用和操作。',
|
||||||
|
guidingQuestion: '引导问题',
|
||||||
|
onFailure: '异常时',
|
||||||
|
userPromptDefaultValue:
|
||||||
|
'This is the order you need to send to the agent.',
|
||||||
|
descriptionMessage: '这是一个用于特定任务的代理。',
|
||||||
|
search: '搜索',
|
||||||
|
communication: '通信',
|
||||||
|
developer: '开发者',
|
||||||
|
typeCommandOrsearch: '输入命令或或搜索...',
|
||||||
|
builtIn: '内置',
|
||||||
|
goto: '异常分支',
|
||||||
|
comment: '默认值',
|
||||||
|
ExceptionDefaultValue: '异常处理默认值',
|
||||||
|
exceptionMethod: '异常处理方法',
|
||||||
|
maxRounds: '最大轮数',
|
||||||
|
delayEfterError: '错误后延迟',
|
||||||
|
maxRetries: '最大重试次数',
|
||||||
|
advancedSettings: '高级设置',
|
||||||
|
addTools: '添加工具',
|
||||||
|
sysPromptDefultValue: `<role>
|
||||||
|
您是{{agent_name}},一位专注于{{领域_or_任务}}的AI助手。
|
||||||
|
</role>
|
||||||
|
<instructions>
|
||||||
|
1. 理解用户请求。
|
||||||
|
2. 将其分解为逻辑子任务。
|
||||||
|
3. 逐步执行每个子任务,并清晰地进行推理。
|
||||||
|
4. 验证准确性和一致性。
|
||||||
|
5. 清晰地总结最终结果。
|
||||||
|
</instructions>`,
|
||||||
|
line: '单行文本',
|
||||||
|
paragraph: '段落文字',
|
||||||
|
options: '选项',
|
||||||
|
file: '文件',
|
||||||
|
integer: '数字',
|
||||||
|
boolean: '布尔值',
|
||||||
|
name: '名称',
|
||||||
|
singleLineText: '单行文本',
|
||||||
|
variableSettings: '变量设置',
|
||||||
|
multimodalModels: '多模态模型',
|
||||||
|
textOnlyModels: '仅文本模型',
|
||||||
|
allModels: '所有模型',
|
||||||
|
codeExecDescription: '用 Python 或者 Javascript 编写自定义逻辑',
|
||||||
|
stringTransformDescription:
|
||||||
|
'修改文本内容,目前支持文本分割、文本拼接操作',
|
||||||
|
foundation: '基础',
|
||||||
|
tools: '工具',
|
||||||
|
dataManipulation: '数据操控',
|
||||||
|
dialog: '对话',
|
||||||
flow: '工作流',
|
flow: '工作流',
|
||||||
noMoreData: '没有更多数据了',
|
noMoreData: '没有更多数据了',
|
||||||
historyversion: '历史版本',
|
historyversion: '历史版本',
|
||||||
@ -823,7 +910,6 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
},
|
},
|
||||||
cite: '引用',
|
cite: '引用',
|
||||||
citeTip: '引用',
|
citeTip: '引用',
|
||||||
name: '名称',
|
|
||||||
nameMessage: '请输入名称',
|
nameMessage: '请输入名称',
|
||||||
description: '描述',
|
description: '描述',
|
||||||
examples: '示例',
|
examples: '示例',
|
||||||
@ -839,7 +925,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
'loop为当前组件循环次数上限,当循环次数超过loop的值时,说明组件不能完成当前任务,请重新优化agent',
|
'loop为当前组件循环次数上限,当循环次数超过loop的值时,说明组件不能完成当前任务,请重新优化agent',
|
||||||
yes: '是',
|
yes: '是',
|
||||||
no: '否',
|
no: '否',
|
||||||
key: 'key',
|
key: '键',
|
||||||
componentId: '组件ID',
|
componentId: '组件ID',
|
||||||
add: '新增',
|
add: '新增',
|
||||||
operation: '操作',
|
operation: '操作',
|
||||||
@ -861,7 +947,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
promptText: `请总结以下段落。注意数字,不要胡编乱造。段落如下:
|
promptText: `请总结以下段落。注意数字,不要胡编乱造。段落如下:
|
||||||
{input}
|
{input}
|
||||||
以上就是你需要总结的内容。`,
|
以上就是你需要总结的内容。`,
|
||||||
createGraph: '创建 Agent',
|
createGraph: '创建智能体',
|
||||||
createFromTemplates: '从模板创建',
|
createFromTemplates: '从模板创建',
|
||||||
retrieval: '知识检索',
|
retrieval: '知识检索',
|
||||||
generate: '生成回答',
|
generate: '生成回答',
|
||||||
@ -911,7 +997,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
bing: 'Bing',
|
bing: 'Bing',
|
||||||
bingDescription:
|
bingDescription:
|
||||||
'此组件用于从 https://www.bing.com/ 获取搜索结果。通常,它作为知识库的补充。Top N 和 Bing Subscription-Key 指定您需要调整的搜索结果数量。',
|
'此组件用于从 https://www.bing.com/ 获取搜索结果。通常,它作为知识库的补充。Top N 和 Bing Subscription-Key 指定您需要调整的搜索结果数量。',
|
||||||
apiKey: 'API KEY',
|
apiKey: 'API密钥',
|
||||||
country: '国家和地区',
|
country: '国家和地区',
|
||||||
language: '语言',
|
language: '语言',
|
||||||
googleScholar: '谷歌学术',
|
googleScholar: '谷歌学术',
|
||||||
@ -1255,6 +1341,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
team: '团队',
|
team: '团队',
|
||||||
},
|
},
|
||||||
systemPrompt: '系统提示词',
|
systemPrompt: '系统提示词',
|
||||||
|
userPrompt: '用户提示词',
|
||||||
prompt: '提示词',
|
prompt: '提示词',
|
||||||
promptMessage: '提示词是必填项',
|
promptMessage: '提示词是必填项',
|
||||||
promptTip:
|
promptTip:
|
||||||
@ -1270,21 +1357,26 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
openingCopy: '开场白文案',
|
openingCopy: '开场白文案',
|
||||||
openingSwitchTip: '您的用户将在开始时看到此欢迎消息。',
|
openingSwitchTip: '您的用户将在开始时看到此欢迎消息。',
|
||||||
modeTip: '模式定义了工作流的启动方式。',
|
modeTip: '模式定义了工作流的启动方式。',
|
||||||
|
mode: '模式',
|
||||||
|
conversational: '对话式',
|
||||||
|
task: '任务',
|
||||||
beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。',
|
beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。',
|
||||||
query: '查询变量',
|
query: '查询变量',
|
||||||
|
queryTip: '选择您想要使用的变量',
|
||||||
agent: '智能体',
|
agent: '智能体',
|
||||||
|
addAgent: '添加智能体',
|
||||||
agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。',
|
agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。',
|
||||||
maxRecords: '最大记录数',
|
maxRecords: '最大记录数',
|
||||||
createAgent: 'Create Agent',
|
createAgent: '创建智能体',
|
||||||
stringTransform: '文本处理',
|
stringTransform: '文本处理',
|
||||||
userFillUp: '等待输入',
|
userFillUp: '等待输入',
|
||||||
userFillUpDescription: `此组件会暂停当前的流程并等待用户发送消息,接收到消息之后再进行之后的流程。`,
|
userFillUpDescription: `此组件会暂停当前的流程并等待用户发送消息,接收到消息之后再进行之后的流程。`,
|
||||||
|
|
||||||
codeExec: '代码',
|
codeExec: '代码',
|
||||||
tavilySearch: 'Tavily Search',
|
tavilySearch: 'Tavily 搜索',
|
||||||
tavilySearchDescription: '通过 Tavily 服务搜索结果',
|
tavilySearchDescription: '通过 Tavily 服务搜索结果',
|
||||||
tavilyExtract: 'Tavily Extract',
|
tavilyExtract: 'Tavily 提取',
|
||||||
tavilyExtractDescription: 'Tavily Extract',
|
tavilyExtractDescription: 'Tavily 提取',
|
||||||
log: '日志',
|
log: '日志',
|
||||||
management: '管理',
|
management: '管理',
|
||||||
import: '导入',
|
import: '导入',
|
||||||
|
|||||||
@ -89,7 +89,7 @@ function InnerAgentNode({
|
|||||||
{(isGotoMethod ||
|
{(isGotoMethod ||
|
||||||
exceptionMethod === AgentExceptionMethod.Comment) && (
|
exceptionMethod === AgentExceptionMethod.Comment) && (
|
||||||
<div className="bg-bg-card rounded-sm p-1 flex justify-between gap-2">
|
<div className="bg-bg-card rounded-sm p-1 flex justify-between gap-2">
|
||||||
<span className="text-text-secondary">On Failure</span>
|
<span className="text-text-secondary">{t('flow.onFailure')}</span>
|
||||||
<span className="truncate flex-1 text-right">
|
<span className="truncate flex-1 text-right">
|
||||||
{t(`flow.${exceptionMethod}`)}
|
{t(`flow.${exceptionMethod}`)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import { Operator } from '@/pages/agent/constant';
|
|||||||
import { AgentInstanceContext, HandleContext } from '@/pages/agent/context';
|
import { AgentInstanceContext, HandleContext } from '@/pages/agent/context';
|
||||||
import OperatorIcon from '@/pages/agent/operator-icon';
|
import OperatorIcon from '@/pages/agent/operator-icon';
|
||||||
import { Position } from '@xyflow/react';
|
import { Position } from '@xyflow/react';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { lowerFirst } from 'lodash';
|
import { lowerFirst } from 'lodash';
|
||||||
import {
|
import {
|
||||||
PropsWithChildren,
|
PropsWithChildren,
|
||||||
@ -128,7 +129,9 @@ function AccordionOperators({
|
|||||||
defaultValue={['item-1', 'item-2', 'item-3', 'item-4', 'item-5']}
|
defaultValue={['item-1', 'item-2', 'item-3', 'item-4', 'item-5']}
|
||||||
>
|
>
|
||||||
<AccordionItem value="item-1">
|
<AccordionItem value="item-1">
|
||||||
<AccordionTrigger className="text-xl">Foundation</AccordionTrigger>
|
<AccordionTrigger className="text-xl">
|
||||||
|
{t('flow.foundation')}
|
||||||
|
</AccordionTrigger>
|
||||||
<AccordionContent className="flex flex-col gap-4 text-balance">
|
<AccordionContent className="flex flex-col gap-4 text-balance">
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
operators={[Operator.Agent, Operator.Retrieval]}
|
operators={[Operator.Agent, Operator.Retrieval]}
|
||||||
@ -138,7 +141,9 @@ function AccordionOperators({
|
|||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem value="item-2">
|
<AccordionItem value="item-2">
|
||||||
<AccordionTrigger className="text-xl">Dialogue </AccordionTrigger>
|
<AccordionTrigger className="text-xl">
|
||||||
|
{t('flow.dialog')}
|
||||||
|
</AccordionTrigger>
|
||||||
<AccordionContent className="flex flex-col gap-4 text-balance">
|
<AccordionContent className="flex flex-col gap-4 text-balance">
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
operators={[Operator.Message, Operator.UserFillUp]}
|
operators={[Operator.Message, Operator.UserFillUp]}
|
||||||
@ -148,7 +153,9 @@ function AccordionOperators({
|
|||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem value="item-3">
|
<AccordionItem value="item-3">
|
||||||
<AccordionTrigger className="text-xl">Flow</AccordionTrigger>
|
<AccordionTrigger className="text-xl">
|
||||||
|
{t('flow.flow')}
|
||||||
|
</AccordionTrigger>
|
||||||
<AccordionContent className="flex flex-col gap-4 text-balance">
|
<AccordionContent className="flex flex-col gap-4 text-balance">
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
operators={[
|
operators={[
|
||||||
@ -163,7 +170,7 @@ function AccordionOperators({
|
|||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem value="item-4">
|
<AccordionItem value="item-4">
|
||||||
<AccordionTrigger className="text-xl">
|
<AccordionTrigger className="text-xl">
|
||||||
Data Manipulation
|
{t('flow.dataManipulation')}
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent className="flex flex-col gap-4 text-balance">
|
<AccordionContent className="flex flex-col gap-4 text-balance">
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
@ -174,7 +181,9 @@ function AccordionOperators({
|
|||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
<AccordionItem value="item-5">
|
<AccordionItem value="item-5">
|
||||||
<AccordionTrigger className="text-xl">Tools</AccordionTrigger>
|
<AccordionTrigger className="text-xl">
|
||||||
|
{t('flow.tools')}
|
||||||
|
</AccordionTrigger>
|
||||||
<AccordionContent className="flex flex-col gap-4 text-balance">
|
<AccordionContent className="flex flex-col gap-4 text-balance">
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
operators={[
|
operators={[
|
||||||
@ -244,7 +253,7 @@ export function InnerNextStepDropdown({
|
|||||||
>
|
>
|
||||||
<div className="w-[300px] font-semibold bg-bg-base border border-border rounded-md shadow-lg">
|
<div className="w-[300px] font-semibold bg-bg-base border border-border rounded-md shadow-lg">
|
||||||
<div className="px-3 py-2 border-b border-border">
|
<div className="px-3 py-2 border-b border-border">
|
||||||
<div className="text-sm font-medium">Next Step</div>
|
<div className="text-sm font-medium">{t('flow.nextStep')}</div>
|
||||||
</div>
|
</div>
|
||||||
<HideModalContext.Provider value={hideModal}>
|
<HideModalContext.Provider value={hideModal}>
|
||||||
<OnNodeCreatedContext.Provider value={onNodeCreated}>
|
<OnNodeCreatedContext.Provider value={onNodeCreated}>
|
||||||
@ -273,7 +282,7 @@ export function InnerNextStepDropdown({
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="w-[300px] font-semibold"
|
className="w-[300px] font-semibold"
|
||||||
>
|
>
|
||||||
<DropdownMenuLabel>Next Step</DropdownMenuLabel>
|
<DropdownMenuLabel>{t('flow.nextStep')}</DropdownMenuLabel>
|
||||||
<HideModalContext.Provider value={hideModal}>
|
<HideModalContext.Provider value={hideModal}>
|
||||||
<AccordionOperators></AccordionOperators>
|
<AccordionOperators></AccordionOperators>
|
||||||
</HideModalContext.Provider>
|
</HideModalContext.Provider>
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
import { ModelVariableType } from '@/constants/knowledge';
|
import { ModelVariableType } from '@/constants/knowledge';
|
||||||
import i18n from '@/locales/config';
|
import i18n from '@/locales/config';
|
||||||
import { setInitialChatVariableEnabledFieldValue } from '@/utils/chat';
|
import { setInitialChatVariableEnabledFieldValue } from '@/utils/chat';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
// DuckDuckGo's channel options
|
// DuckDuckGo's channel options
|
||||||
export enum Channel {
|
export enum Channel {
|
||||||
@ -630,16 +631,7 @@ export const initialAgentValues = {
|
|||||||
...initialLlmBaseValues,
|
...initialLlmBaseValues,
|
||||||
description: '',
|
description: '',
|
||||||
user_prompt: '',
|
user_prompt: '',
|
||||||
sys_prompt: `<role>
|
sys_prompt: t('flow.sysPromptDefultValue'),
|
||||||
You are {{agent_name}}, an AI assistant specialized in {{domain_or_task}}.
|
|
||||||
</role>
|
|
||||||
<instructions>
|
|
||||||
1. Understand the user’s request.
|
|
||||||
2. Decompose it into logical subtasks.
|
|
||||||
3. Execute each subtask step by step, reasoning transparently.
|
|
||||||
4. Validate accuracy and consistency.
|
|
||||||
5. Summarize the final result clearly.
|
|
||||||
</instructions>`,
|
|
||||||
prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }],
|
prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }],
|
||||||
message_history_window_size: 12,
|
message_history_window_size: 12,
|
||||||
max_retries: 3,
|
max_retries: 3,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
} from '@/components/ui/tooltip';
|
} from '@/components/ui/tooltip';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Position } from '@xyflow/react';
|
import { Position } from '@xyflow/react';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { PencilLine, X } from 'lucide-react';
|
import { PencilLine, X } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
MouseEventHandler,
|
MouseEventHandler,
|
||||||
@ -106,7 +107,7 @@ export function AgentTools() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="space-y-2.5">
|
<section className="space-y-2.5">
|
||||||
<span className="text-text-secondary">Tools</span>
|
<span className="text-text-secondary">{t('flow.tools')}</span>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{toolNames.map((x) => (
|
{toolNames.map((x) => (
|
||||||
<ToolCard key={x}>
|
<ToolCard key={x}>
|
||||||
@ -133,7 +134,7 @@ export function AgentTools() {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<ToolPopover>
|
<ToolPopover>
|
||||||
<BlockButton>Add Tool</BlockButton>
|
<BlockButton>{t('flow.addTools')}</BlockButton>
|
||||||
</ToolPopover>
|
</ToolPopover>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
@ -160,7 +161,7 @@ export function Agents({ node }: INextOperatorForm) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="space-y-2.5">
|
<section className="space-y-2.5">
|
||||||
<span className="text-text-secondary">Agents</span>
|
<span className="text-text-secondary">{t('flow.agent')}</span>
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{subBottomAgentNodeIds.map((id) => {
|
{subBottomAgentNodeIds.map((id) => {
|
||||||
const currentNode = getNode(id);
|
const currentNode = getNode(id);
|
||||||
@ -183,7 +184,7 @@ export function Agents({ node }: INextOperatorForm) {
|
|||||||
position: Position.Bottom,
|
position: Position.Bottom,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
Add Agent
|
{t('flow.addAgent')}
|
||||||
</BlockButton>
|
</BlockButton>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -144,7 +144,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`sys_prompt`}
|
name={`sys_prompt`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>System Prompt</FormLabel>
|
<FormLabel>{t('flow.systemPrompt')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<PromptEditor
|
<PromptEditor
|
||||||
{...field}
|
{...field}
|
||||||
@ -164,7 +164,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`prompts`}
|
name={`prompts`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>User Prompt</FormLabel>
|
<FormLabel>{t('flow.userPrompt')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<section>
|
<section>
|
||||||
<PromptEditor
|
<PromptEditor
|
||||||
@ -183,7 +183,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
<AgentTools></AgentTools>
|
<AgentTools></AgentTools>
|
||||||
<Agents node={node}></Agents>
|
<Agents node={node}></Agents>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<Collapse title={<div>Advanced Settings</div>}>
|
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<MessageHistoryWindowSizeFormField></MessageHistoryWindowSizeFormField>
|
<MessageHistoryWindowSizeFormField></MessageHistoryWindowSizeFormField>
|
||||||
<FormField
|
<FormField
|
||||||
@ -208,7 +208,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`max_retries`}
|
name={`max_retries`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Max retries</FormLabel>
|
<FormLabel>{t('flow.maxRetries')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field} max={8}></NumberInput>
|
<NumberInput {...field} max={8}></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -220,7 +220,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`delay_after_error`}
|
name={`delay_after_error`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Delay after error</FormLabel>
|
<FormLabel>{t('flow.delayEfterError')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field} max={5} step={0.1}></NumberInput>
|
<NumberInput {...field} max={5} step={0.1}></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -232,7 +232,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`max_rounds`}
|
name={`max_rounds`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Max rounds</FormLabel>
|
<FormLabel>{t('flow.maxRounds')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field}></NumberInput>
|
<NumberInput {...field}></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -244,7 +244,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`exception_method`}
|
name={`exception_method`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Exception method</FormLabel>
|
<FormLabel>{t('flow.exceptionMethod')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<SelectWithSearch
|
<SelectWithSearch
|
||||||
{...field}
|
{...field}
|
||||||
@ -261,7 +261,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
name={`exception_default_value`}
|
name={`exception_default_value`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Exception default value</FormLabel>
|
<FormLabel>{t('flow.ExceptionDefaultValue')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} />
|
<Input {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { Operator } from '@/pages/agent/constant';
|
|||||||
import { AgentFormContext, AgentInstanceContext } from '@/pages/agent/context';
|
import { AgentFormContext, AgentInstanceContext } from '@/pages/agent/context';
|
||||||
import useGraphStore from '@/pages/agent/store';
|
import useGraphStore from '@/pages/agent/store';
|
||||||
import { Position } from '@xyflow/react';
|
import { Position } from '@xyflow/react';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { PropsWithChildren, useCallback, useContext, useEffect } from 'react';
|
import { PropsWithChildren, useCallback, useContext, useEffect } from 'react';
|
||||||
import { useGetAgentMCPIds, useGetAgentToolNames } from '../use-get-tools';
|
import { useGetAgentMCPIds, useGetAgentToolNames } from '../use-get-tools';
|
||||||
import { MCPCommand, ToolCommand } from './tool-command';
|
import { MCPCommand, ToolCommand } from './tool-command';
|
||||||
@ -65,8 +66,12 @@ export function ToolPopover({ children }: PropsWithChildren) {
|
|||||||
<PopoverContent className="w-80 p-4">
|
<PopoverContent className="w-80 p-4">
|
||||||
<Tabs defaultValue={ToolType.Common}>
|
<Tabs defaultValue={ToolType.Common}>
|
||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value={ToolType.Common}>Built-in</TabsTrigger>
|
<TabsTrigger value={ToolType.Common} className="bg-bg-card">
|
||||||
<TabsTrigger value={ToolType.MCP}>MCP</TabsTrigger>
|
{t('flow.builtIn')}
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger value={ToolType.MCP} className="bg-bg-card">
|
||||||
|
MCP
|
||||||
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value={ToolType.Common}>
|
<TabsContent value={ToolType.Common}>
|
||||||
<ToolCommand
|
<ToolCommand
|
||||||
|
|||||||
@ -12,13 +12,14 @@ import { useListMcpServer } from '@/hooks/use-mcp-request';
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Operator } from '@/pages/agent/constant';
|
import { Operator } from '@/pages/agent/constant';
|
||||||
import OperatorIcon from '@/pages/agent/operator-icon';
|
import OperatorIcon from '@/pages/agent/operator-icon';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { lowerFirst } from 'lodash';
|
import { lowerFirst } from 'lodash';
|
||||||
import { PropsWithChildren, useCallback, useEffect, useState } from 'react';
|
import { PropsWithChildren, useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const Menus = [
|
const Menus = [
|
||||||
{
|
{
|
||||||
label: 'Search',
|
label: t('flow.search'),
|
||||||
list: [
|
list: [
|
||||||
Operator.TavilySearch,
|
Operator.TavilySearch,
|
||||||
Operator.TavilyExtract,
|
Operator.TavilyExtract,
|
||||||
@ -34,7 +35,7 @@ const Menus = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Communication',
|
label: t('flow.communication'),
|
||||||
list: [Operator.Email],
|
list: [Operator.Email],
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
@ -42,7 +43,7 @@ const Menus = [
|
|||||||
// list: [],
|
// list: [],
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
label: 'Developer',
|
label: t('flow.developer'),
|
||||||
list: [Operator.GitHub, Operator.ExeSQL, Operator.Code, Operator.Retrieval],
|
list: [Operator.GitHub, Operator.ExeSQL, Operator.Code, Operator.Retrieval],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -116,7 +117,7 @@ export function ToolCommand({ value, onChange }: ToolCommandProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Command>
|
<Command>
|
||||||
<CommandInput placeholder="Type a command or search..." />
|
<CommandInput placeholder={t('flow.typeCommandOrsearch')} />
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
<CommandEmpty>No results found.</CommandEmpty>
|
||||||
{Menus.map((x) => (
|
{Menus.map((x) => (
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import { RAGFlowSelect } from '@/components/ui/select';
|
|||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { FormTooltip } from '@/components/ui/tooltip';
|
import { FormTooltip } from '@/components/ui/tooltip';
|
||||||
import { buildSelectOptions } from '@/utils/component-util';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import { memo, useEffect, useRef } from 'react';
|
import { memo, useEffect, useRef } from 'react';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
@ -27,10 +27,10 @@ import { useEditQueryRecord } from './use-edit-query';
|
|||||||
import { useValues } from './use-values';
|
import { useValues } from './use-values';
|
||||||
import { useWatchFormChange } from './use-watch-change';
|
import { useWatchFormChange } from './use-watch-change';
|
||||||
|
|
||||||
const ModeOptions = buildSelectOptions([
|
const ModeOptions = [
|
||||||
AgentDialogueMode.Conversational,
|
{ value: AgentDialogueMode.Conversational, label: t('flow.conversational') },
|
||||||
AgentDialogueMode.Task,
|
{ value: AgentDialogueMode.Task, label: t('flow.task') },
|
||||||
]);
|
];
|
||||||
|
|
||||||
function BeginForm({ node }: INextOperatorForm) {
|
function BeginForm({ node }: INextOperatorForm) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -103,7 +103,9 @@ function BeginForm({ node }: INextOperatorForm) {
|
|||||||
name={'mode'}
|
name={'mode'}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel tooltip={t('flow.modeTip')}>Mode</FormLabel>
|
<FormLabel tooltip={t('flow.modeTip')}>
|
||||||
|
{t('flow.mode')}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
placeholder={t('common.pleaseSelect')}
|
placeholder={t('common.pleaseSelect')}
|
||||||
|
|||||||
@ -138,7 +138,7 @@ function ParameterForm({
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Type</FormLabel>
|
<FormLabel>{t('type')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect {...field} options={options} />
|
<RAGFlowSelect {...field} options={options} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -151,7 +151,7 @@ function ParameterForm({
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Key</FormLabel>
|
<FormLabel>{t('key')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} autoComplete="off" onBlur={handleKeyChange} />
|
<Input {...field} autoComplete="off" onBlur={handleKeyChange} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -164,7 +164,7 @@ function ParameterForm({
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Name</FormLabel>
|
<FormLabel>{t('name')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input {...field} />
|
<Input {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -177,7 +177,7 @@ function ParameterForm({
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Optional</FormLabel>
|
<FormLabel>{t('optional')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
@ -217,7 +217,7 @@ export function ParameterDialog({
|
|||||||
></ParameterForm>
|
></ParameterForm>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button type="submit" form={FormId}>
|
<Button type="submit" form={FormId}>
|
||||||
Confirm
|
{t('modal.okText')}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@ -53,7 +53,7 @@ export function QueryTable({ data = [], deleteRecord, showModal }: IProps) {
|
|||||||
const columns: ColumnDef<BeginQuery>[] = [
|
const columns: ColumnDef<BeginQuery>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: 'key',
|
accessorKey: 'key',
|
||||||
header: 'Key',
|
header: t('flow.key'),
|
||||||
meta: { cellClassName: 'max-w-30' },
|
meta: { cellClassName: 'max-w-30' },
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const key: string = row.getValue('key');
|
const key: string = row.getValue('key');
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
interface IApiKeyFieldProps {
|
interface IApiKeyFieldProps {
|
||||||
@ -19,7 +20,7 @@ export function ApiKeyField({ placeholder }: IApiKeyFieldProps) {
|
|||||||
name="api_key"
|
name="api_key"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Api Key</FormLabel>
|
<FormLabel>{t('flow.apiKey')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="password" {...field} placeholder={placeholder}></Input>
|
<Input type="password" {...field} placeholder={placeholder}></Input>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
export function DescriptionField() {
|
export function DescriptionField() {
|
||||||
@ -15,7 +16,7 @@ export function DescriptionField() {
|
|||||||
name={`description`}
|
name={`description`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex-1">
|
<FormItem className="flex-1">
|
||||||
<FormLabel>Description</FormLabel>
|
<FormLabel>{t('flow.description')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Textarea {...field}></Textarea>
|
<Textarea {...field}></Textarea>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export type OutputType = {
|
export type OutputType = {
|
||||||
title: string;
|
title: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
@ -17,7 +19,7 @@ export function transferOutputs(outputs: Record<string, any>) {
|
|||||||
export function Output({ list }: OutputProps) {
|
export function Output({ list }: OutputProps) {
|
||||||
return (
|
return (
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<div>Output</div>
|
<div>{t('flow.output')}</div>
|
||||||
<ul>
|
<ul>
|
||||||
{list.map((x, idx) => (
|
{list.map((x, idx) => (
|
||||||
<li
|
<li
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export function QueryVariable({
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
{label || (
|
{label || (
|
||||||
<FormLabel tooltip={t('chat.modelTip')}>
|
<FormLabel tooltip={t('flow.queryTip')}>
|
||||||
{t('flow.query')}
|
{t('flow.query')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -132,7 +132,7 @@ export function ExeSQLFormWidgets({ loading }: { loading: boolean }) {
|
|||||||
|
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<ButtonLoading loading={loading} type="submit">
|
<ButtonLoading loading={loading} type="submit">
|
||||||
Test
|
{t('test')}
|
||||||
</ButtonLoading>
|
</ButtonLoading>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -99,13 +99,13 @@ const GoogleForm = ({ node }: INextOperatorForm) => {
|
|||||||
<QueryVariable name="q"></QueryVariable>
|
<QueryVariable name="q"></QueryVariable>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<ApiKeyField placeholder="YOUR_API_KEY (obtained from https://serpapi.com/manage-api-key)"></ApiKeyField>
|
<ApiKeyField placeholder={t('apiKeyPlaceholder')}></ApiKeyField>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={`start`}
|
name={`start`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>{t('start')}</FormLabel>
|
<FormLabel>{t('flowStart')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field} className="w-full"></NumberInput>
|
<NumberInput {...field} className="w-full"></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -118,7 +118,7 @@ const GoogleForm = ({ node }: INextOperatorForm) => {
|
|||||||
name={`num`}
|
name={`num`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>{t('num')}</FormLabel>
|
<FormLabel>{t('flowNum')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<NumberInput {...field} className="w-full"></NumberInput>
|
<NumberInput {...field} className="w-full"></NumberInput>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@ -134,7 +134,7 @@ export function VariableDialog({
|
|||||||
></VariableForm>
|
></VariableForm>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button type="submit" form={FormId}>
|
<Button type="submit" form={FormId}>
|
||||||
Confirm
|
{t('modal.okText')}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export function VariableTable({
|
|||||||
const columns: ColumnDef<VariableFormSchemaType>[] = [
|
const columns: ColumnDef<VariableFormSchemaType>[] = [
|
||||||
{
|
{
|
||||||
accessorKey: 'key',
|
accessorKey: 'key',
|
||||||
header: 'key',
|
header: t('flow.key'),
|
||||||
meta: { cellClassName: 'max-w-30' },
|
meta: { cellClassName: 'max-w-30' },
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const key: string = row.getValue('key');
|
const key: string = row.getValue('key');
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { ReactNode, useCallback, useMemo } from 'react';
|
import { ReactNode, useCallback, useMemo } from 'react';
|
||||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||||
@ -107,7 +108,7 @@ export function DynamicOutputForm({ node }: IProps) {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<BlockButton onClick={() => append({ name: '', ref: undefined })}>
|
<BlockButton onClick={() => append({ name: '', ref: undefined })}>
|
||||||
Add
|
{t('common.add')}
|
||||||
</BlockButton>
|
</BlockButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -120,7 +121,7 @@ export function VariableTitle({ title }: { title: ReactNode }) {
|
|||||||
export function DynamicOutput({ node }: IProps) {
|
export function DynamicOutput({ node }: IProps) {
|
||||||
return (
|
return (
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<VariableTitle title={'Output'}></VariableTitle>
|
<VariableTitle title={t('flow.output')}></VariableTitle>
|
||||||
<DynamicOutputForm node={node}></DynamicOutputForm>
|
<DynamicOutputForm node={node}></DynamicOutputForm>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -104,7 +104,7 @@ function RetrievalForm({ node }: INextOperatorForm) {
|
|||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<Collapse title={<div>Advanced Settings</div>}>
|
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<SimilaritySliderFormField
|
<SimilaritySliderFormField
|
||||||
vectorSimilarityWeightName="keywords_similarity_weight"
|
vectorSimilarityWeightName="keywords_similarity_weight"
|
||||||
|
|||||||
@ -9,8 +9,9 @@ import {
|
|||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { MultiSelect } from '@/components/ui/multi-select';
|
import { MultiSelect } from '@/components/ui/multi-select';
|
||||||
import { RAGFlowSelect } from '@/components/ui/select';
|
import { RAGFlowSelect } from '@/components/ui/select';
|
||||||
import { buildOptions } from '@/utils/form';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
import { toLower } from 'lodash';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -28,7 +29,7 @@ import { useValues } from './use-values';
|
|||||||
import { useWatchFormChange } from './use-watch-form-change';
|
import { useWatchFormChange } from './use-watch-form-change';
|
||||||
|
|
||||||
const DelimiterOptions = Object.entries(StringTransformDelimiter).map(
|
const DelimiterOptions = Object.entries(StringTransformDelimiter).map(
|
||||||
([key, val]) => ({ label: key, value: val }),
|
([key, val]) => ({ label: t('flow.' + toLower(key)), value: val }),
|
||||||
);
|
);
|
||||||
|
|
||||||
function StringTransformForm({ node }: INextOperatorForm) {
|
function StringTransformForm({ node }: INextOperatorForm) {
|
||||||
@ -84,11 +85,13 @@ function StringTransformForm({ node }: INextOperatorForm) {
|
|||||||
name="method"
|
name="method"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>method</FormLabel>
|
<FormLabel>{t('flow.method')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
{...field}
|
{...field}
|
||||||
options={buildOptions(StringTransformMethod)}
|
options={Object.values(StringTransformMethod).map(
|
||||||
|
(val) => ({ label: t('flow.' + val), value: val }),
|
||||||
|
)}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
handleMethodChange(value);
|
handleMethodChange(value);
|
||||||
field.onChange(value);
|
field.onChange(value);
|
||||||
@ -111,7 +114,7 @@ function StringTransformForm({ node }: INextOperatorForm) {
|
|||||||
name="script"
|
name="script"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>script</FormLabel>
|
<FormLabel>{t('flow.script')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<PromptEditor {...field} showToolbar={false}></PromptEditor>
|
<PromptEditor {...field} showToolbar={false}></PromptEditor>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -125,7 +128,7 @@ function StringTransformForm({ node }: INextOperatorForm) {
|
|||||||
name="delimiters"
|
name="delimiters"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>delimiters</FormLabel>
|
<FormLabel>{t('flow.delimiters')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
{isSplit ? (
|
{isSplit ? (
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { Separator } from '@/components/ui/separator';
|
|||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { toLower } from 'lodash';
|
import { toLower } from 'lodash';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
@ -197,7 +198,7 @@ function ConditionCards({
|
|||||||
className="mt-6"
|
className="mt-6"
|
||||||
onClick={() => append({ operator: switchOperatorOptions[0].value })}
|
onClick={() => append({ operator: switchOperatorOptions[0].value })}
|
||||||
>
|
>
|
||||||
Add
|
{t('common.add')}
|
||||||
</BlockButton>
|
</BlockButton>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -268,7 +269,7 @@ function SwitchForm({ node }: IOperatorForm) {
|
|||||||
className="-translate-y-1"
|
className="-translate-y-1"
|
||||||
onClick={() => remove(index)}
|
onClick={() => remove(index)}
|
||||||
>
|
>
|
||||||
Remove <X />
|
{t('common.remove')} <X />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -317,7 +318,7 @@ function SwitchForm({ node }: IOperatorForm) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Add
|
{t('common.add')}
|
||||||
</BlockButton>
|
</BlockButton>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
import { RAGFlowSelect } from '@/components/ui/select';
|
import { RAGFlowSelect } from '@/components/ui/select';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -79,12 +80,12 @@ function TavilyExtractForm({ node }: INextOperatorForm) {
|
|||||||
name="extract_depth"
|
name="extract_depth"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Extract Depth</FormLabel>
|
<FormLabel>{t('flow.extractDepth')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
placeholder="shadcn"
|
placeholder="shadcn"
|
||||||
{...field}
|
{...field}
|
||||||
options={buildOptions(TavilyExtractDepth)}
|
options={buildOptions(TavilyExtractDepth, t, 'flow')}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@ -96,7 +97,7 @@ function TavilyExtractForm({ node }: INextOperatorForm) {
|
|||||||
name="format"
|
name="format"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Format</FormLabel>
|
<FormLabel>{t('flow.format')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
placeholder="shadcn"
|
placeholder="shadcn"
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||||
@ -51,7 +52,9 @@ export const DynamicDomain = ({ name, label }: DynamicDomainProps) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
<BlockButton onClick={() => append({ value: '' })}>Add</BlockButton>
|
<BlockButton onClick={() => append({ value: '' })}>
|
||||||
|
{t('common.add')}
|
||||||
|
</BlockButton>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { RAGFlowSelect } from '@/components/ui/select';
|
|||||||
import { Switch } from '@/components/ui/switch';
|
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 { t } from 'i18next';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@ -74,12 +75,12 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="search_depth"
|
name="search_depth"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Search Depth</FormLabel>
|
<FormLabel>{t('flow.searchDepth')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
placeholder="shadcn"
|
placeholder="shadcn"
|
||||||
{...field}
|
{...field}
|
||||||
options={buildOptions(TavilySearchDepth)}
|
options={buildOptions(TavilySearchDepth, t, 'flow')}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@ -91,12 +92,12 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="topic"
|
name="topic"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>TavilyTopic</FormLabel>
|
<FormLabel>{t('flow.tavilyTopic')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RAGFlowSelect
|
<RAGFlowSelect
|
||||||
placeholder="shadcn"
|
placeholder="shadcn"
|
||||||
{...field}
|
{...field}
|
||||||
options={buildOptions(TavilyTopic)}
|
options={buildOptions(TavilyTopic, t, 'flow')}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@ -108,7 +109,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="max_results"
|
name="max_results"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Max Results</FormLabel>
|
<FormLabel>{t('flow.maxResults')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type={'number'} {...field}></Input>
|
<Input type={'number'} {...field}></Input>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -121,7 +122,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="days"
|
name="days"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Days</FormLabel>
|
<FormLabel>{t('flow.days')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type={'number'} {...field}></Input>
|
<Input type={'number'} {...field}></Input>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -134,7 +135,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="include_answer"
|
name="include_answer"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Include Answer</FormLabel>
|
<FormLabel>{t('flow.includeAnswer')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
@ -150,7 +151,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="include_raw_content"
|
name="include_raw_content"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Include Raw Content</FormLabel>
|
<FormLabel>{t('flow.includeRawContent')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
@ -166,7 +167,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="include_images"
|
name="include_images"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Include Images</FormLabel>
|
<FormLabel>{t('flow.includeImages')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
@ -182,7 +183,7 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
name="include_image_descriptions"
|
name="include_image_descriptions"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>Include Image Descriptions</FormLabel>
|
<FormLabel>{t('flow.includeImageDescriptions')}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
@ -195,11 +196,11 @@ function TavilyForm({ node }: INextOperatorForm) {
|
|||||||
/>
|
/>
|
||||||
<DynamicDomain
|
<DynamicDomain
|
||||||
name="include_domains"
|
name="include_domains"
|
||||||
label={'Include Domains'}
|
label={t('flow.includeDomains')}
|
||||||
></DynamicDomain>
|
></DynamicDomain>
|
||||||
<DynamicDomain
|
<DynamicDomain
|
||||||
name="exclude_domains"
|
name="exclude_domains"
|
||||||
label={'Exclude Domains'}
|
label={t('flow.ExcludeDomains')}
|
||||||
></DynamicDomain>
|
></DynamicDomain>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { TopNFormField } from '@/components/top-n-item';
|
|||||||
import { Form } from '@/components/ui/form';
|
import { Form } from '@/components/ui/form';
|
||||||
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { DescriptionField } from '../../components/description-field';
|
import { DescriptionField } from '../../components/description-field';
|
||||||
@ -41,7 +42,7 @@ const RetrievalForm = () => {
|
|||||||
<DescriptionField></DescriptionField>
|
<DescriptionField></DescriptionField>
|
||||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<Collapse title={<div>Advanced Settings</div>}>
|
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<SimilaritySliderFormField
|
<SimilaritySliderFormField
|
||||||
vectorSimilarityWeightName="keywords_similarity_weight"
|
vectorSimilarityWeightName="keywords_similarity_weight"
|
||||||
|
|||||||
@ -86,7 +86,7 @@ function UserFillUpForm({ node }: INextOperatorForm) {
|
|||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel tooltip={t('flow.openingSwitchTip')}>
|
<FormLabel tooltip={t('flow.openingSwitchTip')}>
|
||||||
Guiding Question
|
{t('flow.guidingQuestion')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Switch
|
<Switch
|
||||||
@ -104,7 +104,9 @@ function UserFillUpForm({ node }: INextOperatorForm) {
|
|||||||
name={'tips'}
|
name={'tips'}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel tooltip={t('chat.setAnOpenerTip')}>Message</FormLabel>
|
<FormLabel tooltip={t('chat.setAnOpenerTip')}>
|
||||||
|
{t('flow.msg')}
|
||||||
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Textarea
|
<Textarea
|
||||||
rows={5}
|
rows={5}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useFetchModelId } from '@/hooks/logic-hooks';
|
import { useFetchModelId } from '@/hooks/logic-hooks';
|
||||||
import { Connection, Node, Position, ReactFlowInstance } from '@xyflow/react';
|
import { Connection, Node, Position, ReactFlowInstance } from '@xyflow/react';
|
||||||
import humanId from 'human-id';
|
import humanId from 'human-id';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { lowerFirst } from 'lodash';
|
import { lowerFirst } from 'lodash';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -122,8 +123,8 @@ export const useInitializeOperatorParams = () => {
|
|||||||
if (isBottomSubAgent(operatorName, position)) {
|
if (isBottomSubAgent(operatorName, position)) {
|
||||||
return {
|
return {
|
||||||
...initialValues,
|
...initialValues,
|
||||||
description: 'This is an agent for a specific task.',
|
description: t('flow.descriptionMessage'),
|
||||||
user_prompt: 'This is the order you need to send to the agent.',
|
user_prompt: t('flow.userPromptDefaultValue'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useFetchAgent } from '@/hooks/use-agent-request';
|
|||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||||
import { Edge } from '@xyflow/react';
|
import { Edge } from '@xyflow/react';
|
||||||
import { DefaultOptionType } from 'antd/es/select';
|
import { DefaultOptionType } from 'antd/es/select';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
@ -145,7 +146,7 @@ export function useBuildBeginVariableOptions() {
|
|||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: <span>Begin Input</span>,
|
label: <span>{t('flow.beginInput')}</span>,
|
||||||
title: 'Begin Input',
|
title: 'Begin Input',
|
||||||
options: inputs.map((x) => ({
|
options: inputs.map((x) => ({
|
||||||
label: x.name,
|
label: x.name,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { Button } from '@/components/ui/button';
|
|||||||
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { useFetchAgentListByPage } from '@/hooks/use-agent-request';
|
import { useFetchAgentListByPage } from '@/hooks/use-agent-request';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
@ -41,7 +42,7 @@ export default function Agents() {
|
|||||||
>
|
>
|
||||||
<Button onClick={navigateToAgentTemplates}>
|
<Button onClick={navigateToAgentTemplates}>
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
<Plus className="mr-2 h-4 w-4" />
|
||||||
Create Agent
|
{t('flow.createGraph')}
|
||||||
</Button>
|
</Button>
|
||||||
</ListFilterBar>
|
</ListFilterBar>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { variableEnabledFieldMap } from '@/constants/chat';
|
import { variableEnabledFieldMap } from '@/constants/chat';
|
||||||
|
import { TFunction } from 'i18next';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
|
|
||||||
// chat model setting and generate operator
|
// chat model setting and generate operator
|
||||||
@ -27,7 +28,17 @@ export const removeUselessFieldsFromValues = (values: any, prefix?: string) => {
|
|||||||
return nextValues;
|
return nextValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function buildOptions(data: Record<string, any>) {
|
export function buildOptions(
|
||||||
|
data: Record<string, any>,
|
||||||
|
t?: TFunction<['translation', ...string[]], undefined>,
|
||||||
|
prefix?: string,
|
||||||
|
) {
|
||||||
|
if (t) {
|
||||||
|
return Object.values(data).map((val) => ({
|
||||||
|
label: t(`${prefix ? prefix + '.' : ''}${val.toLowerCase()}`),
|
||||||
|
value: val,
|
||||||
|
}));
|
||||||
|
}
|
||||||
return Object.values(data).map((val) => ({ label: val, value: val }));
|
return Object.values(data).map((val) => ({ label: val, value: val }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user