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