- {!isEnv && (
+ {!isEnv && !isChatVar && (
)}
- {!isEnv &&
}
+ {!isEnv && !isChatVar &&
}
{isEnv &&
}
-
{varName}
+ {isChatVar &&
}
+
{varName}
)
diff --git a/web/app/components/workflow/nodes/variable-assigner/hooks.ts b/web/app/components/workflow/nodes/variable-assigner/hooks.ts
index d9ae25416f..0e5e10c741 100644
--- a/web/app/components/workflow/nodes/variable-assigner/hooks.ts
+++ b/web/app/components/workflow/nodes/variable-assigner/hooks.ts
@@ -143,6 +143,7 @@ export const useGetAvailableVars = () => {
beforeNodes: uniqBy(availableNodes, 'id').filter(node => node.id !== nodeId),
isChatMode,
hideEnv,
+ hideChatVar: hideEnv,
filterVar,
})
.map(node => ({
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/array-value-list.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/array-value-list.tsx
new file mode 100644
index 0000000000..a040f2fd8e
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/array-value-list.tsx
@@ -0,0 +1,72 @@
+'use client'
+import type { FC } from 'react'
+import React, { useCallback } from 'react'
+import { useTranslation } from 'react-i18next'
+import { RiAddLine } from '@remixicon/react'
+import produce from 'immer'
+import RemoveButton from '@/app/components/workflow/nodes/_base/components/remove-button'
+import Button from '@/app/components/base/button'
+
+type Props = {
+ isString: boolean
+ list: any[]
+ onChange: (list: any[]) => void
+}
+
+const ArrayValueList: FC
= ({
+ isString = true,
+ list,
+ onChange,
+}) => {
+ const { t } = useTranslation()
+
+ const handleNameChange = useCallback((index: number) => {
+ return (e: React.ChangeEvent) => {
+ const newList = produce(list, (draft: any[]) => {
+ draft[index] = isString ? e.target.value : Number(e.target.value)
+ })
+ onChange(newList)
+ }
+ }, [isString, list, onChange])
+
+ const handleItemRemove = useCallback((index: number) => {
+ return () => {
+ const newList = produce(list, (draft) => {
+ draft.splice(index, 1)
+ })
+ onChange(newList)
+ }
+ }, [list, onChange])
+
+ const handleItemAdd = useCallback(() => {
+ const newList = produce(list, (draft: any[]) => {
+ draft.push(undefined)
+ })
+ onChange(newList)
+ }, [list, onChange])
+
+ return (
+
+ {list.map((item, index) => (
+
+
+
+
+ ))}
+
+
+ {t('workflow.chatVariable.modal.addArrayValue')}
+
+
+ )
+}
+export default React.memo(ArrayValueList)
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx
new file mode 100644
index 0000000000..6bbdeae08b
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx
@@ -0,0 +1,135 @@
+'use client'
+import type { FC } from 'react'
+import React, { useCallback, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import produce from 'immer'
+import { useContext } from 'use-context-selector'
+import { ToastContext } from '@/app/components/base/toast'
+import VariableTypeSelector from '@/app/components/workflow/panel/chat-variable-panel/components/variable-type-select'
+import RemoveButton from '@/app/components/workflow/nodes/_base/components/remove-button'
+import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
+
+type Props = {
+ index: number
+ list: any[]
+ onChange: (list: any[]) => void
+}
+
+const typeList = [
+ ChatVarType.String,
+ ChatVarType.Number,
+]
+
+export const DEFAULT_OBJECT_VALUE = {
+ key: '',
+ type: ChatVarType.String,
+ value: undefined,
+}
+
+const ObjectValueItem: FC = ({
+ index,
+ list,
+ onChange,
+}) => {
+ const { t } = useTranslation()
+ const { notify } = useContext(ToastContext)
+ const [isFocus, setIsFocus] = useState(false)
+
+ const handleKeyChange = useCallback((index: number) => {
+ return (e: React.ChangeEvent) => {
+ const newList = produce(list, (draft: any[]) => {
+ if (!/^[a-zA-Z0-9_]+$/.test(e.target.value))
+ return notify({ type: 'error', message: 'key is can only contain letters, numbers and underscores' })
+ draft[index].key = e.target.value
+ })
+ onChange(newList)
+ }
+ }, [list, notify, onChange])
+
+ const handleTypeChange = useCallback((index: number) => {
+ return (type: ChatVarType) => {
+ const newList = produce(list, (draft) => {
+ draft[index].type = type
+ if (type === ChatVarType.Number)
+ draft[index].value = isNaN(Number(draft[index].value)) ? undefined : Number(draft[index].value)
+ else
+ draft[index].value = draft[index].value ? String(draft[index].value) : undefined
+ })
+ onChange(newList)
+ }
+ }, [list, onChange])
+
+ const handleValueChange = useCallback((index: number) => {
+ return (e: React.ChangeEvent) => {
+ const newList = produce(list, (draft: any[]) => {
+ draft[index].value = draft[index].type === ChatVarType.String ? e.target.value : isNaN(Number(e.target.value)) ? undefined : Number(e.target.value)
+ })
+ onChange(newList)
+ }
+ }, [list, onChange])
+
+ const handleItemRemove = useCallback((index: number) => {
+ return () => {
+ const newList = produce(list, (draft) => {
+ draft.splice(index, 1)
+ })
+ onChange(newList)
+ }
+ }, [list, onChange])
+
+ const handleItemAdd = useCallback(() => {
+ const newList = produce(list, (draft: any[]) => {
+ draft.push(DEFAULT_OBJECT_VALUE)
+ })
+ onChange(newList)
+ }, [list, onChange])
+
+ const handleFocusChange = useCallback(() => {
+ setIsFocus(true)
+ if (index === list.length - 1)
+ handleItemAdd()
+ }, [handleItemAdd, index, list.length])
+
+ return (
+
+ {/* Key */}
+
+
+
+ {/* Type */}
+
+
+
+ {/* Value */}
+
+ handleFocusChange()}
+ onBlur={() => setIsFocus(false)}
+ type={list[index].type === ChatVarType.Number ? 'number' : 'text'}
+ />
+ {list.length > 1 && !isFocus && (
+
+ )}
+
+
+ )
+}
+export default React.memo(ObjectValueItem)
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/object-value-list.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/object-value-list.tsx
new file mode 100644
index 0000000000..ec287accba
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/object-value-list.tsx
@@ -0,0 +1,36 @@
+'use client'
+import type { FC } from 'react'
+import React from 'react'
+import { useTranslation } from 'react-i18next'
+import ObjectValueItem from '@/app/components/workflow/panel/chat-variable-panel/components/object-value-item'
+
+type Props = {
+ list: any[]
+ onChange: (list: any[]) => void
+}
+
+const ObjectValueList: FC = ({
+ list,
+ onChange,
+}) => {
+ const { t } = useTranslation()
+
+ return (
+
+
+
{t('workflow.chatVariable.modal.objectKey')}
+
{t('workflow.chatVariable.modal.objectType')}
+
{t('workflow.chatVariable.modal.objectValue')}
+
+ {list.map((item, index) => (
+
+ ))}
+
+ )
+}
+export default React.memo(ObjectValueList)
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx
new file mode 100644
index 0000000000..a1a7c9dc3d
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx
@@ -0,0 +1,49 @@
+import { memo, useState } from 'react'
+import { capitalize } from 'lodash-es'
+import { RiDeleteBinLine, RiEditLine } from '@remixicon/react'
+import { BubbleX } from '@/app/components/base/icons/src/vender/line/others'
+import type { ConversationVariable } from '@/app/components/workflow/types'
+import cn from '@/utils/classnames'
+
+type VariableItemProps = {
+ item: ConversationVariable
+ onEdit: (item: ConversationVariable) => void
+ onDelete: (item: ConversationVariable) => void
+}
+
+const VariableItem = ({
+ item,
+ onEdit,
+ onDelete,
+}: VariableItemProps) => {
+ const [destructive, setDestructive] = useState(false)
+ return (
+
+
+
+
+
{item.name}
+
{capitalize(item.value_type)}
+
+
+
+ onEdit(item)}/>
+
+
setDestructive(true)}
+ onMouseOut={() => setDestructive(false)}
+ >
+ onDelete(item)}/>
+
+
+
+
{item.description}
+
+ )
+}
+
+export default memo(VariableItem)
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx
new file mode 100644
index 0000000000..35d5254327
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx
@@ -0,0 +1,69 @@
+'use client'
+import React from 'react'
+import { useTranslation } from 'react-i18next'
+import { RiAddLine } from '@remixicon/react'
+import Button from '@/app/components/base/button'
+import VariableModal from '@/app/components/workflow/panel/chat-variable-panel/components/variable-modal'
+import {
+ PortalToFollowElem,
+ PortalToFollowElemContent,
+ PortalToFollowElemTrigger,
+} from '@/app/components/base/portal-to-follow-elem'
+import type { ConversationVariable } from '@/app/components/workflow/types'
+
+type Props = {
+ open: boolean
+ setOpen: (value: React.SetStateAction) => void
+ showTip: boolean
+ chatVar?: ConversationVariable
+ onClose: () => void
+ onSave: (env: ConversationVariable) => void
+}
+
+const VariableModalTrigger = ({
+ open,
+ setOpen,
+ showTip,
+ chatVar,
+ onClose,
+ onSave,
+}: Props) => {
+ const { t } = useTranslation()
+
+ return (
+ {
+ setOpen(v => !v)
+ open && onClose()
+ }}
+ placement='left-start'
+ offset={{
+ mainAxis: 8,
+ alignmentAxis: showTip ? -278 : -48,
+ }}
+ >
+ {
+ setOpen(v => !v)
+ open && onClose()
+ }}>
+
+
+ {t('workflow.chatVariable.button')}
+
+
+
+ {
+ onClose()
+ setOpen(false)
+ }}
+ />
+
+
+ )
+}
+
+export default VariableModalTrigger
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx
new file mode 100644
index 0000000000..135ee43491
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx
@@ -0,0 +1,388 @@
+import React, { useCallback, useEffect, useMemo } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useContext } from 'use-context-selector'
+import { v4 as uuid4 } from 'uuid'
+import { RiCloseLine, RiDraftLine, RiInputField } from '@remixicon/react'
+import VariableTypeSelector from '@/app/components/workflow/panel/chat-variable-panel/components/variable-type-select'
+import ObjectValueList from '@/app/components/workflow/panel/chat-variable-panel/components/object-value-list'
+import { DEFAULT_OBJECT_VALUE } from '@/app/components/workflow/panel/chat-variable-panel/components/object-value-item'
+import ArrayValueList from '@/app/components/workflow/panel/chat-variable-panel/components/array-value-list'
+import Button from '@/app/components/base/button'
+import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
+import { ToastContext } from '@/app/components/base/toast'
+import { useStore } from '@/app/components/workflow/store'
+import type { ConversationVariable } from '@/app/components/workflow/types'
+import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
+import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
+import cn from '@/utils/classnames'
+
+export type ModalPropsType = {
+ chatVar?: ConversationVariable
+ onClose: () => void
+ onSave: (chatVar: ConversationVariable) => void
+}
+
+type ObjectValueItem = {
+ key: string
+ type: ChatVarType
+ value: string | number | undefined
+}
+
+const typeList = [
+ ChatVarType.String,
+ ChatVarType.Number,
+ ChatVarType.Object,
+ ChatVarType.ArrayString,
+ ChatVarType.ArrayNumber,
+ ChatVarType.ArrayObject,
+]
+
+const objectPlaceholder = `# example
+# {
+# "name": "ray",
+# "age": 20
+# }`
+const arrayStringPlaceholder = `# example
+# [
+# "value1",
+# "value2"
+# ]`
+const arrayNumberPlaceholder = `# example
+# [
+# 100,
+# 200
+# ]`
+const arrayObjectPlaceholder = `# example
+# [
+# {
+# "name": "ray",
+# "age": 20
+# },
+# {
+# "name": "lily",
+# "age": 18
+# }
+# ]`
+
+const ChatVariableModal = ({
+ chatVar,
+ onClose,
+ onSave,
+}: ModalPropsType) => {
+ const { t } = useTranslation()
+ const { notify } = useContext(ToastContext)
+ const varList = useStore(s => s.conversationVariables)
+ const [name, setName] = React.useState('')
+ const [type, setType] = React.useState(ChatVarType.String)
+ const [value, setValue] = React.useState()
+ const [objectValue, setObjectValue] = React.useState([DEFAULT_OBJECT_VALUE])
+ const [editorContent, setEditorContent] = React.useState()
+ const [editInJSON, setEditInJSON] = React.useState(false)
+ const [des, setDes] = React.useState('')
+
+ const editorMinHeight = useMemo(() => {
+ if (type === ChatVarType.ArrayObject)
+ return '240px'
+ return '120px'
+ }, [type])
+ const placeholder = useMemo(() => {
+ if (type === ChatVarType.ArrayString)
+ return arrayStringPlaceholder
+ if (type === ChatVarType.ArrayNumber)
+ return arrayNumberPlaceholder
+ if (type === ChatVarType.ArrayObject)
+ return arrayObjectPlaceholder
+ return objectPlaceholder
+ }, [type])
+ const getObjectValue = useCallback(() => {
+ if (!chatVar)
+ return [DEFAULT_OBJECT_VALUE]
+ return Object.keys(chatVar.value).map((key) => {
+ return {
+ key,
+ type: typeof chatVar.value[key] === 'string' ? ChatVarType.String : ChatVarType.Number,
+ value: chatVar.value[key],
+ }
+ })
+ }, [chatVar])
+ const formatValueFromObject = useCallback((list: ObjectValueItem[]) => {
+ return list.reduce((acc: any, curr) => {
+ if (curr.key)
+ acc[curr.key] = curr.value || null
+ return acc
+ }, {})
+ }, [])
+
+ const formatValue = (value: any) => {
+ switch (type) {
+ case ChatVarType.String:
+ return value || ''
+ case ChatVarType.Number:
+ return value || 0
+ case ChatVarType.Object:
+ return formatValueFromObject(objectValue)
+ case ChatVarType.ArrayString:
+ case ChatVarType.ArrayNumber:
+ case ChatVarType.ArrayObject:
+ return value?.filter(Boolean) || []
+ }
+ }
+
+ const handleNameChange = (v: string) => {
+ if (!v)
+ return setName('')
+ if (!/^[a-zA-Z0-9_]+$/.test(v))
+ return notify({ type: 'error', message: 'name is can only contain letters, numbers and underscores' })
+ if (/^[0-9]/.test(v))
+ return notify({ type: 'error', message: 'name can not start with a number' })
+ setName(v)
+ }
+
+ const handleTypeChange = (v: ChatVarType) => {
+ setValue(undefined)
+ setEditorContent(undefined)
+ if (v === ChatVarType.ArrayObject)
+ setEditInJSON(true)
+ if (v === ChatVarType.String || v === ChatVarType.Number || v === ChatVarType.Object)
+ setEditInJSON(false)
+ setType(v)
+ }
+
+ const handleEditorChange = (editInJSON: boolean) => {
+ if (type === ChatVarType.Object) {
+ if (editInJSON) {
+ const newValue = !objectValue[0].key ? undefined : formatValueFromObject(objectValue)
+ setValue(newValue)
+ setEditorContent(JSON.stringify(newValue))
+ }
+ else {
+ if (!editorContent) {
+ setValue(undefined)
+ setObjectValue([DEFAULT_OBJECT_VALUE])
+ }
+ else {
+ try {
+ const newValue = JSON.parse(editorContent)
+ setValue(newValue)
+ const newObjectValue = Object.keys(newValue).map((key) => {
+ return {
+ key,
+ type: typeof newValue[key] === 'string' ? ChatVarType.String : ChatVarType.Number,
+ value: newValue[key],
+ }
+ })
+ setObjectValue(newObjectValue)
+ }
+ catch (e) {
+ // ignore JSON.parse errors
+ }
+ }
+ }
+ }
+ if (type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) {
+ if (editInJSON) {
+ const newValue = (value?.length && value.filter(Boolean).length) ? value.filter(Boolean) : undefined
+ setValue(newValue)
+ if (!editorContent)
+ setEditorContent(JSON.stringify(newValue))
+ }
+ else {
+ setValue(value?.length ? value : [undefined])
+ }
+ }
+ setEditInJSON(editInJSON)
+ }
+
+ const handleEditorValueChange = (content: string) => {
+ if (!content) {
+ setEditorContent(content)
+ return setValue(undefined)
+ }
+ else {
+ setEditorContent(content)
+ try {
+ const newValue = JSON.parse(content)
+ setValue(newValue)
+ }
+ catch (e) {
+ // ignore JSON.parse errors
+ }
+ }
+ }
+
+ const handleSave = () => {
+ if (!name)
+ return notify({ type: 'error', message: 'name can not be empty' })
+ if (!chatVar && varList.some(chatVar => chatVar.name === name))
+ return notify({ type: 'error', message: 'name is existed' })
+ // if (type !== ChatVarType.Object && !value)
+ // return notify({ type: 'error', message: 'value can not be empty' })
+ if (type === ChatVarType.Object && objectValue.some(item => !item.key && !!item.value))
+ return notify({ type: 'error', message: 'object key can not be empty' })
+
+ onSave({
+ id: chatVar ? chatVar.id : uuid4(),
+ name,
+ value_type: type,
+ value: formatValue(value),
+ description: des,
+ })
+ onClose()
+ }
+
+ useEffect(() => {
+ if (chatVar) {
+ setName(chatVar.name)
+ setType(chatVar.value_type)
+ setValue(chatVar.value)
+ setDes(chatVar.description)
+ setEditInJSON(false)
+ setObjectValue(getObjectValue())
+ }
+ }, [chatVar, getObjectValue])
+
+ return (
+
+
+ {!chatVar ? t('workflow.chatVariable.modal.title') : t('workflow.chatVariable.modal.editTitle')}
+
+
+
+ {/* name */}
+
+
{t('workflow.chatVariable.modal.name')}
+
+ handleNameChange(e.target.value)}
+ type='text'
+ />
+
+
+ {/* type */}
+
+
{t('workflow.chatVariable.modal.type')}
+
+
+
+
+ {/* default value */}
+
+
+
{t('workflow.chatVariable.modal.value')}
+ {(type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) && (
+
handleEditorChange(!editInJSON)}
+ >
+ {editInJSON ? : }
+ {editInJSON ? t('workflow.chatVariable.modal.oneByOne') : t('workflow.chatVariable.modal.editInJSON')}
+
+ )}
+ {type === ChatVarType.Object && (
+
handleEditorChange(!editInJSON)}
+ >
+ {editInJSON ? : }
+ {editInJSON ? t('workflow.chatVariable.modal.editInForm') : t('workflow.chatVariable.modal.editInJSON')}
+
+ )}
+
+
+ {type === ChatVarType.String && (
+
setValue(e.target.value)}
+ />
+ )}
+ {type === ChatVarType.Number && (
+
setValue(Number(e.target.value))}
+ type='number'
+ />
+ )}
+ {type === ChatVarType.Object && !editInJSON && (
+
+ )}
+ {type === ChatVarType.ArrayString && !editInJSON && (
+
+ )}
+ {type === ChatVarType.ArrayNumber && !editInJSON && (
+
+ )}
+ {editInJSON && (
+
+ {placeholder}
}
+ onChange={handleEditorValueChange}
+ />
+
+ )}
+
+
+ {/* description */}
+
+
{t('workflow.chatVariable.modal.description')}
+
+
+
+
+
+
+ {t('common.operation.cancel')}
+ {t('common.operation.save')}
+
+
+
+ )
+}
+
+export default ChatVariableModal
diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-type-select.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-type-select.tsx
new file mode 100644
index 0000000000..94a319514a
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-type-select.tsx
@@ -0,0 +1,66 @@
+'use client'
+import React, { useState } from 'react'
+import { RiArrowDownSLine, RiCheckLine } from '@remixicon/react'
+import {
+ PortalToFollowElem,
+ PortalToFollowElemContent,
+ PortalToFollowElemTrigger,
+} from '@/app/components/base/portal-to-follow-elem'
+import cn from '@/utils/classnames'
+
+type Props = {
+ inCell?: boolean
+ value?: any
+ list: any
+ onSelect: (value: any) => void
+ popupClassName?: string
+}
+
+const VariableTypeSelector = ({
+ inCell = false,
+ value,
+ list,
+ onSelect,
+ popupClassName,
+}: Props) => {
+ const [open, setOpen] = useState(false)
+
+ return (
+
setOpen(v => !v)}
+ placement='bottom'
+ >
+ setOpen(v => !v)}>
+
+
+
+
+ {list.map((item: any) => (
+
{
+ onSelect(item)
+ setOpen(false)
+ }}>
+
{item}
+ {value === item &&
}
+
+ ))}
+
+
+
+ )
+}
+
+export default VariableTypeSelector
diff --git a/web/app/components/workflow/panel/chat-variable-panel/index.tsx b/web/app/components/workflow/panel/chat-variable-panel/index.tsx
new file mode 100644
index 0000000000..8ae17a4db3
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/index.tsx
@@ -0,0 +1,202 @@
+import {
+ memo,
+ useCallback,
+ useState,
+} from 'react'
+import { useContext } from 'use-context-selector'
+import {
+ useStoreApi,
+} from 'reactflow'
+import { RiBookOpenLine, RiCloseLine } from '@remixicon/react'
+import { useTranslation } from 'react-i18next'
+import { useStore } from '@/app/components/workflow/store'
+import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
+import { BubbleX, LongArrowLeft, LongArrowRight } from '@/app/components/base/icons/src/vender/line/others'
+import BlockIcon from '@/app/components/workflow/block-icon'
+import VariableModalTrigger from '@/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger'
+import VariableItem from '@/app/components/workflow/panel/chat-variable-panel/components/variable-item'
+import RemoveEffectVarConfirm from '@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm'
+import type {
+ ConversationVariable,
+} from '@/app/components/workflow/types'
+import { findUsedVarNodes, updateNodeVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
+import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft'
+import { BlockEnum } from '@/app/components/workflow/types'
+import I18n from '@/context/i18n'
+import { LanguagesSupported } from '@/i18n/language'
+import cn from '@/utils/classnames'
+
+const ChatVariablePanel = () => {
+ const { t } = useTranslation()
+ const { locale } = useContext(I18n)
+ const store = useStoreApi()
+ const setShowChatVariablePanel = useStore(s => s.setShowChatVariablePanel)
+ const varList = useStore(s => s.conversationVariables) as ConversationVariable[]
+ const updateChatVarList = useStore(s => s.setConversationVariables)
+ const { doSyncWorkflowDraft } = useNodesSyncDraft()
+
+ const [showTip, setShowTip] = useState(true)
+ const [showVariableModal, setShowVariableModal] = useState(false)
+ const [currentVar, setCurrentVar] = useState
()
+
+ const [showRemoveVarConfirm, setShowRemoveConfirm] = useState(false)
+ const [cacheForDelete, setCacheForDelete] = useState()
+
+ const getEffectedNodes = useCallback((chatVar: ConversationVariable) => {
+ const { getNodes } = store.getState()
+ const allNodes = getNodes()
+ return findUsedVarNodes(
+ ['conversation', chatVar.name],
+ allNodes,
+ )
+ }, [store])
+
+ const removeUsedVarInNodes = useCallback((chatVar: ConversationVariable) => {
+ const { getNodes, setNodes } = store.getState()
+ const effectedNodes = getEffectedNodes(chatVar)
+ const newNodes = getNodes().map((node) => {
+ if (effectedNodes.find(n => n.id === node.id))
+ return updateNodeVars(node, ['conversation', chatVar.name], [])
+
+ return node
+ })
+ setNodes(newNodes)
+ }, [getEffectedNodes, store])
+
+ const handleEdit = (chatVar: ConversationVariable) => {
+ setCurrentVar(chatVar)
+ setShowVariableModal(true)
+ }
+
+ const handleDelete = useCallback((chatVar: ConversationVariable) => {
+ removeUsedVarInNodes(chatVar)
+ updateChatVarList(varList.filter(v => v.id !== chatVar.id))
+ setCacheForDelete(undefined)
+ setShowRemoveConfirm(false)
+ doSyncWorkflowDraft()
+ }, [doSyncWorkflowDraft, removeUsedVarInNodes, updateChatVarList, varList])
+
+ const deleteCheck = useCallback((chatVar: ConversationVariable) => {
+ const effectedNodes = getEffectedNodes(chatVar)
+ if (effectedNodes.length > 0) {
+ setCacheForDelete(chatVar)
+ setShowRemoveConfirm(true)
+ }
+ else {
+ handleDelete(chatVar)
+ }
+ }, [getEffectedNodes, handleDelete])
+
+ const handleSave = useCallback(async (chatVar: ConversationVariable) => {
+ // add chatVar
+ if (!currentVar) {
+ const newList = [chatVar, ...varList]
+ updateChatVarList(newList)
+ doSyncWorkflowDraft()
+ return
+ }
+ // edit chatVar
+ const newList = varList.map(v => v.id === currentVar.id ? chatVar : v)
+ updateChatVarList(newList)
+ // side effects of rename env
+ if (currentVar.name !== chatVar.name) {
+ const { getNodes, setNodes } = store.getState()
+ const effectedNodes = getEffectedNodes(currentVar)
+ const newNodes = getNodes().map((node) => {
+ if (effectedNodes.find(n => n.id === node.id))
+ return updateNodeVars(node, ['conversation', currentVar.name], ['conversation', chatVar.name])
+
+ return node
+ })
+ setNodes(newNodes)
+ }
+ doSyncWorkflowDraft()
+ }, [currentVar, doSyncWorkflowDraft, getEffectedNodes, store, updateChatVarList, varList])
+
+ return (
+
+
+ {t('workflow.chatVariable.panelTitle')}
+
+
setShowTip(!showTip)}>
+
+
+
setShowChatVariablePanel(false)}
+ >
+
+
+
+
+ {showTip && (
+
+
+
TIPS
+
+
+
+
+
conversation_var
+
String
+
+
+
+
+
+
{t('workflow.blocks.assigner')}
+
+
+
+
+
{t('workflow.blocks.llm')}
+
+
+
+
+
+
+ )}
+
+ setCurrentVar(undefined)}
+ />
+
+
+ {varList.map(chatVar => (
+
+ ))}
+
+
setShowRemoveConfirm(false)}
+ onConfirm={() => cacheForDelete && handleDelete(cacheForDelete)}
+ />
+
+ )
+}
+
+export default memo(ChatVariablePanel)
diff --git a/web/app/components/workflow/panel/chat-variable-panel/type.ts b/web/app/components/workflow/panel/chat-variable-panel/type.ts
new file mode 100644
index 0000000000..2a4e776463
--- /dev/null
+++ b/web/app/components/workflow/panel/chat-variable-panel/type.ts
@@ -0,0 +1,8 @@
+export enum ChatVarType {
+ Number = 'number',
+ String = 'string',
+ Object = 'object',
+ ArrayString = 'array[string]',
+ ArrayNumber = 'array[number]',
+ ArrayObject = 'array[object]',
+}
diff --git a/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx b/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx
index 015f85d101..4655940037 100644
--- a/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx
+++ b/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx
@@ -14,6 +14,7 @@ import {
import type { StartNodeType } from '../../nodes/start/types'
import Empty from './empty'
import UserInput from './user-input'
+import ConversationVariableModal from './conversation-variable-modal'
import { useChat } from './hooks'
import type { ChatWrapperRefType } from './index'
import Chat from '@/app/components/base/chat/chat'
@@ -25,7 +26,13 @@ import {
} from '@/service/debug'
import { useStore as useAppStore } from '@/app/components/app/store'
-const ChatWrapper = forwardRef((_, ref) => {
+type ChatWrapperProps = {
+ showConversationVariableModal: boolean
+ onConversationModalHide: () => void
+ showInputsFieldsPanel: boolean
+}
+
+const ChatWrapper = forwardRef(({ showConversationVariableModal, onConversationModalHide, showInputsFieldsPanel }, ref) => {
const nodes = useNodes()
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
const startVariables = startNode?.data.variables
@@ -87,33 +94,41 @@ const ChatWrapper = forwardRef((_, ref) => {
}, [handleRestart])
return (
-
-
- {
- !chatList.length && (
-
- )
- }
- >
+ <>
+
+ {showInputsFieldsPanel && }
+ {
+ !chatList.length && (
+
+ )
+ }
+ >
+ )}
+ suggestedQuestions={suggestedQuestions}
+ showPromptLog
+ chatAnswerContainerInner='!pr-2'
+ />
+ {showConversationVariableModal && (
+
)}
- suggestedQuestions={suggestedQuestions}
- showPromptLog
- chatAnswerContainerInner='!pr-2'
- />
+ >
)
})
diff --git a/web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx b/web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx
new file mode 100644
index 0000000000..a2faa14d89
--- /dev/null
+++ b/web/app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx
@@ -0,0 +1,155 @@
+'use client'
+import React, { useCallback } from 'react'
+import { useMount } from 'ahooks'
+import { useTranslation } from 'react-i18next'
+import { capitalize } from 'lodash-es'
+import copy from 'copy-to-clipboard'
+import { RiCloseLine } from '@remixicon/react'
+import Modal from '@/app/components/base/modal'
+import { BubbleX } from '@/app/components/base/icons/src/vender/line/others'
+import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
+import {
+ Clipboard,
+ ClipboardCheck,
+} from '@/app/components/base/icons/src/vender/line/files'
+import { useStore } from '@/app/components/workflow/store'
+import type {
+ ConversationVariable,
+} from '@/app/components/workflow/types'
+import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
+import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
+import useTimestamp from '@/hooks/use-timestamp'
+import { fetchCurrentValueOfConversationVariable } from '@/service/workflow'
+import cn from '@/utils/classnames'
+
+export type Props = {
+ conversationID: string
+ onHide: () => void
+}
+
+const ConversationVariableModal = ({
+ conversationID,
+ onHide,
+}: Props) => {
+ const { t } = useTranslation()
+ const { formatTime } = useTimestamp()
+ const varList = useStore(s => s.conversationVariables) as ConversationVariable[]
+ const appID = useStore(s => s.appId)
+ const [currentVar, setCurrentVar] = React.useState(varList[0])
+ const [latestValueMap, setLatestValueMap] = React.useState>({})
+ const [latestValueTimestampMap, setLatestValueTimestampMap] = React.useState>({})
+
+ const getChatVarLatestValues = useCallback(async () => {
+ if (conversationID && varList.length > 0) {
+ const res = await fetchCurrentValueOfConversationVariable({
+ url: `/apps/${appID}/conversation-variables`,
+ params: { conversation_id: conversationID },
+ })
+ if (res.data.length > 0) {
+ const valueMap = res.data.reduce((acc: any, cur) => {
+ acc[cur.id] = cur.value
+ return acc
+ }, {})
+ setLatestValueMap(valueMap)
+ const timestampMap = res.data.reduce((acc: any, cur) => {
+ acc[cur.id] = cur.updated_at
+ return acc
+ }, {})
+ setLatestValueTimestampMap(timestampMap)
+ }
+ }
+ }, [appID, conversationID, varList.length])
+
+ const [isCopied, setIsCopied] = React.useState(false)
+ const handleCopy = useCallback(() => {
+ copy(currentVar.value)
+ setIsCopied(true)
+ setTimeout(() => {
+ setIsCopied(false)
+ }, 2000)
+ }, [currentVar.value])
+
+ useMount(() => {
+ getChatVarLatestValues()
+ })
+
+ return (
+ { }}
+ className={cn('w-[920px] max-w-[920px] h-[640px] p-0')}
+ >
+
+
+
+
+ {/* LEFT */}
+
+
{t('workflow.chatVariable.panelTitle')}
+
+ {varList.map(chatVar => (
+
setCurrentVar(chatVar)}>
+
+
{chatVar.name}
+
+ ))}
+
+
+ {/* RIGHT */}
+
+
+
+
{currentVar.name}
+
{capitalize(currentVar.value_type)}
+
+
+
+
+
{t('workflow.chatVariable.storedContent').toLocaleUpperCase()}
+
+ {latestValueTimestampMap[currentVar.id] && (
+
{t('workflow.chatVariable.updatedAt')}{formatTime(latestValueTimestampMap[currentVar.id], t('appLog.dateTimeFormat') as string)}
+ )}
+
+
+ {currentVar.value_type !== ChatVarType.Number && currentVar.value_type !== ChatVarType.String && (
+
+
+
JSON
+
+ {!isCopied
+ ? (
+
+ )
+ : (
+
+ )
+ }
+
+
+
+
+
+
+ )}
+ {(currentVar.value_type === ChatVarType.Number || currentVar.value_type === ChatVarType.String) && (
+
{latestValueMap[currentVar.id] || ''}
+ )}
+
+
+
+
+
+ )
+}
+
+export default ConversationVariableModal
diff --git a/web/app/components/workflow/panel/debug-and-preview/index.tsx b/web/app/components/workflow/panel/debug-and-preview/index.tsx
index 72a601bed9..1f94b4fbc3 100644
--- a/web/app/components/workflow/panel/debug-and-preview/index.tsx
+++ b/web/app/components/workflow/panel/debug-and-preview/index.tsx
@@ -1,19 +1,26 @@
import {
memo,
useRef,
+ useState,
} from 'react'
import { useKeyPress } from 'ahooks'
-import { RiCloseLine } from '@remixicon/react'
+import { RiCloseLine, RiEqualizer2Line } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
+import { useNodes } from 'reactflow'
import {
useEdgesInteractions,
useNodesInteractions,
useWorkflowInteractions,
} from '../../hooks'
+import { BlockEnum } from '../../types'
+import type { StartNodeType } from '../../nodes/start/types'
import ChatWrapper from './chat-wrapper'
import cn from '@/utils/classnames'
-import Button from '@/app/components/base/button'
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
+import { BubbleX } from '@/app/components/base/icons/src/vender/line/others'
+import TooltipPlus from '@/app/components/base/tooltip-plus'
+import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
+import { useStore } from '@/app/components/workflow/store'
export type ChatWrapperRefType = {
handleRestart: () => void
@@ -24,6 +31,13 @@ const DebugAndPreview = () => {
const { handleCancelDebugAndPreviewPanel } = useWorkflowInteractions()
const { handleNodeCancelRunningStatus } = useNodesInteractions()
const { handleEdgeCancelRunningStatus } = useEdgesInteractions()
+ const varList = useStore(s => s.conversationVariables)
+ const [expanded, setExpanded] = useState(true)
+ const nodes = useNodes()
+ const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
+ const variables = startNode?.data.variables || []
+
+ const [showConversationVariableModal, setShowConversationVariableModal] = useState(false)
const handleRestartChat = () => {
handleNodeCancelRunningStatus()
@@ -40,28 +54,43 @@ const DebugAndPreview = () => {
return (
-
- {t('workflow.common.debugAndPreview').toLocaleUpperCase()}
-
-
handleRestartChat()}
+
+
{t('workflow.common.debugAndPreview').toLocaleUpperCase()}
+
+
-
- handleRestartChat()}>
+
+
+
+ {varList.length > 0 && (
+
- {t('common.operation.refresh')}
+ setShowConversationVariableModal(true)}>
+
+
+
+ )}
+ {variables.length > 0 && (
+
+
+ setExpanded(!expanded)}>
+
+
+
+ {expanded &&
}
-
Shift
-
R
-
+ )}
{
-
+ setShowConversationVariableModal(false)}
+ showInputsFieldsPanel={expanded}
+ />
)
diff --git a/web/app/components/workflow/panel/debug-and-preview/user-input.tsx b/web/app/components/workflow/panel/debug-and-preview/user-input.tsx
index 300ea68a4b..d80e3b6005 100644
--- a/web/app/components/workflow/panel/debug-and-preview/user-input.tsx
+++ b/web/app/components/workflow/panel/debug-and-preview/user-input.tsx
@@ -1,10 +1,7 @@
import {
memo,
- useState,
} from 'react'
-import { useTranslation } from 'react-i18next'
import { useNodes } from 'reactflow'
-import { RiArrowDownSLine } from '@remixicon/react'
import FormItem from '../../nodes/_base/components/before-run-form/form-item'
import { BlockEnum } from '../../types'
import {
@@ -12,11 +9,10 @@ import {
useWorkflowStore,
} from '../../store'
import type { StartNodeType } from '../../nodes/start/types'
+import cn from '@/utils/classnames'
const UserInput = () => {
- const { t } = useTranslation()
const workflowStore = useWorkflowStore()
- const [expanded, setExpanded] = useState(true)
const inputs = useStore(s => s.inputs)
const nodes = useNodes
()
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
@@ -33,46 +29,21 @@ const UserInput = () => {
return null
return (
-
-
setExpanded(!expanded)}
- >
-
- {t('workflow.panel.userInputField').toLocaleUpperCase()}
-
-
- {
- expanded && (
-
- {
- variables.map((variable, index) => (
-
- handleValueChange(variable.variable, v)}
- />
-
- ))
- }
-
- )
- }
+
+
+ {variables.map((variable, index) => (
+
+ handleValueChange(variable.variable, v)}
+ />
+
+ ))}
)
diff --git a/web/app/components/workflow/panel/env-panel/env-item.tsx b/web/app/components/workflow/panel/env-panel/env-item.tsx
new file mode 100644
index 0000000000..f7c028389e
--- /dev/null
+++ b/web/app/components/workflow/panel/env-panel/env-item.tsx
@@ -0,0 +1,53 @@
+import { memo, useState } from 'react'
+import { capitalize } from 'lodash-es'
+import { RiDeleteBinLine, RiEditLine, RiLock2Line } from '@remixicon/react'
+import { Env } from '@/app/components/base/icons/src/vender/line/others'
+import { useStore } from '@/app/components/workflow/store'
+import type { EnvironmentVariable } from '@/app/components/workflow/types'
+import cn from '@/utils/classnames'
+
+type EnvItemProps = {
+ env: EnvironmentVariable
+ onEdit: (env: EnvironmentVariable) => void
+ onDelete: (env: EnvironmentVariable) => void
+}
+
+const EnvItem = ({
+ env,
+ onEdit,
+ onDelete,
+}: EnvItemProps) => {
+ const envSecrets = useStore(s => s.envSecrets)
+ const [destructive, setDestructive] = useState(false)
+
+ return (
+
+
+
+
+
{env.name}
+
{capitalize(env.value_type)}
+ {env.value_type === 'secret' &&
}
+
+
+
+ onEdit(env)}/>
+
+
setDestructive(true)}
+ onMouseOut={() => setDestructive(false)}
+ >
+ onDelete(env)} />
+
+
+
+
{env.value_type === 'secret' ? envSecrets[env.id] : env.value}
+
+ )
+}
+
+export default memo(EnvItem)
diff --git a/web/app/components/workflow/panel/env-panel/index.tsx b/web/app/components/workflow/panel/env-panel/index.tsx
index 66a3d0524d..756aa17ac4 100644
--- a/web/app/components/workflow/panel/env-panel/index.tsx
+++ b/web/app/components/workflow/panel/env-panel/index.tsx
@@ -3,15 +3,14 @@ import {
useCallback,
useState,
} from 'react'
-import { capitalize } from 'lodash-es'
import {
useStoreApi,
} from 'reactflow'
-import { RiCloseLine, RiDeleteBinLine, RiEditLine, RiLock2Line } from '@remixicon/react'
+import { RiCloseLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useStore } from '@/app/components/workflow/store'
-import { Env } from '@/app/components/base/icons/src/vender/line/others'
import VariableTrigger from '@/app/components/workflow/panel/env-panel/variable-trigger'
+import EnvItem from '@/app/components/workflow/panel/env-panel/env-item'
import type {
EnvironmentVariable,
} from '@/app/components/workflow/types'
@@ -61,6 +60,11 @@ const EnvPanel = () => {
setNodes(newNodes)
}, [getEffectedNodes, store])
+ const handleEdit = (env: EnvironmentVariable) => {
+ setCurrentVar(env)
+ setShowVariableModal(true)
+ }
+
const handleDelete = useCallback((env: EnvironmentVariable) => {
removeUsedVarInNodes(env)
updateEnvList(envList.filter(e => e.id !== env.id))
@@ -145,7 +149,7 @@ const EnvPanel = () => {
return (
@@ -171,31 +175,12 @@ const EnvPanel = () => {
{envList.map(env => (
-
-
-
-
-
{env.name}
-
{capitalize(env.value_type)}
- {env.value_type === 'secret' &&
}
-
-
-
- {
- setCurrentVar(env)
- setShowVariableModal(true)
- }}/>
-
-
- deleteCheck(env)} />
-
-
-
-
{env.value_type === 'secret' ? envSecrets[env.id] : env.value}
-
+
))}
{/* type */}
-
{t('workflow.env.modal.type')}
+
{t('workflow.env.modal.type')}
{/* name */}
-
{t('workflow.env.modal.name')}
+
{t('workflow.env.modal.name')}
handleNameChange(e.target.value)}
@@ -125,11 +125,11 @@ const VariableModal = ({
{/* value */}
-
{t('workflow.env.modal.value')}
+
{t('workflow.env.modal.value')}
setValue(e.target.value)}
diff --git a/web/app/components/workflow/panel/env-panel/variable-trigger.tsx b/web/app/components/workflow/panel/env-panel/variable-trigger.tsx
index 95706798e5..467f612cdb 100644
--- a/web/app/components/workflow/panel/env-panel/variable-trigger.tsx
+++ b/web/app/components/workflow/panel/env-panel/variable-trigger.tsx
@@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'
import { RiAddLine } from '@remixicon/react'
import Button from '@/app/components/base/button'
import VariableModal from '@/app/components/workflow/panel/env-panel/variable-modal'
-// import cn from '@/utils/classnames'
import {
PortalToFollowElem,
PortalToFollowElemContent,
diff --git a/web/app/components/workflow/panel/index.tsx b/web/app/components/workflow/panel/index.tsx
index 6cd4d4f7b5..864e24aa80 100644
--- a/web/app/components/workflow/panel/index.tsx
+++ b/web/app/components/workflow/panel/index.tsx
@@ -13,6 +13,7 @@ import DebugAndPreview from './debug-and-preview'
import Record from './record'
import WorkflowPreview from './workflow-preview'
import ChatRecord from './chat-record'
+import ChatVariablePanel from './chat-variable-panel'
import EnvPanel from './env-panel'
import cn from '@/utils/classnames'
import { useStore as useAppStore } from '@/app/components/app/store'
@@ -25,6 +26,7 @@ const Panel: FC = () => {
const historyWorkflowData = useStore(s => s.historyWorkflowData)
const showDebugAndPreviewPanel = useStore(s => s.showDebugAndPreviewPanel)
const showEnvPanel = useStore(s => s.showEnvPanel)
+ const showChatVariablePanel = useStore(s => s.showChatVariablePanel)
const isRestoring = useStore(s => s.isRestoring)
const {
enableShortcuts,
@@ -90,6 +92,11 @@ const Panel: FC = () => {
)
}
+ {
+ showChatVariablePanel && (
+
+ )
+ }
)
}
diff --git a/web/app/components/workflow/store.ts b/web/app/components/workflow/store.ts
index 9df22355dd..854684e5c3 100644
--- a/web/app/components/workflow/store.ts
+++ b/web/app/components/workflow/store.ts
@@ -11,6 +11,7 @@ import type {
} from './help-line/types'
import type { VariableAssignerNodeType } from './nodes/variable-assigner/types'
import type {
+ ConversationVariable,
Edge,
EnvironmentVariable,
HistoryWorkflowData,
@@ -21,6 +22,24 @@ import type {
} from './types'
import { WorkflowContext } from './context'
+// #TODO chatVar#
+// const MOCK_DATA = [
+// {
+// id: 'fjlaksdjflkjg-dfjlajfl0dnfkafjk-djfdkafj-djfak',
+// name: 'chat_history',
+// value_type: 'array[message]',
+// value: [],
+// description: 'The chat history of the conversation',
+// },
+// {
+// id: 'fljdaklfjl-dfjlafj0-dklajglje-eknglh',
+// name: 'order_id',
+// value: '123456',
+// value_type: 'string',
+// description: '',
+// },
+// ]
+
type PreviewRunningData = WorkflowRunningData & {
resultTabActive?: boolean
resultText?: string
@@ -90,6 +109,10 @@ type Shape = {
setEnvironmentVariables: (environmentVariables: EnvironmentVariable[]) => void
envSecrets: Record
setEnvSecrets: (envSecrets: Record) => void
+ showChatVariablePanel: boolean
+ setShowChatVariablePanel: (showChatVariablePanel: boolean) => void
+ conversationVariables: ConversationVariable[]
+ setConversationVariables: (conversationVariables: ConversationVariable[]) => void
selection: null | { x1: number; y1: number; x2: number; y2: number }
setSelection: (selection: Shape['selection']) => void
bundleNodeSize: { width: number; height: number } | null
@@ -204,6 +227,10 @@ export const createWorkflowStore = () => {
setEnvironmentVariables: environmentVariables => set(() => ({ environmentVariables })),
envSecrets: {},
setEnvSecrets: envSecrets => set(() => ({ envSecrets })),
+ showChatVariablePanel: false,
+ setShowChatVariablePanel: showChatVariablePanel => set(() => ({ showChatVariablePanel })),
+ conversationVariables: [],
+ setConversationVariables: conversationVariables => set(() => ({ conversationVariables })),
selection: null,
setSelection: selection => set(() => ({ selection })),
bundleNodeSize: null,
diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts
index b34295e6f9..785acd9f3e 100644
--- a/web/app/components/workflow/types.ts
+++ b/web/app/components/workflow/types.ts
@@ -8,6 +8,7 @@ import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/
import type { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
import type { NodeTracing } from '@/types/workflow'
import type { Collection, Tool } from '@/app/components/tools/types'
+import type { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
export enum BlockEnum {
Start = 'start',
@@ -27,6 +28,7 @@ export enum BlockEnum {
Iteration = 'iteration',
DocExtractor = 'doc-extractor',
ListFilter = 'list-filter',
+ Assigner = 'assigner', // is now named as VariableAssigner
}
export type Branch = {
@@ -111,6 +113,14 @@ export type EnvironmentVariable = {
value_type: 'string' | 'number' | 'secret'
}
+export type ConversationVariable = {
+ id: string
+ name: string
+ value_type: ChatVarType
+ value: any
+ description: string
+}
+
export type VariableWithValue = {
key: string
value: string
@@ -136,6 +146,7 @@ export type InputVar = {
nodeType: BlockEnum
nodeName: string
variable: string
+ isChatVar?: boolean
}
variable: string
max_length?: number
@@ -214,6 +225,7 @@ export type Var = {
isSelect?: boolean
options?: string[]
required?: boolean
+ des?: string
}
export type NodeOutPutVar = {
diff --git a/web/app/styles/globals.css b/web/app/styles/globals.css
index 238166a810..f0a8e466d6 100644
--- a/web/app/styles/globals.css
+++ b/web/app/styles/globals.css
@@ -142,6 +142,12 @@ button:focus-within {
line-height: 12px;
}
+.system-2xs-regular {
+ font-size: 10px;
+ font-weight: 400;
+ line-height: 12px;
+}
+
.system-2xs-medium {
font-size: 10px;
font-weight: 500;
diff --git a/web/docker/entrypoint.sh b/web/docker/entrypoint.sh
index 9c30bce748..a19c543d68 100755
--- a/web/docker/entrypoint.sh
+++ b/web/docker/entrypoint.sh
@@ -19,5 +19,6 @@ export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api
export NEXT_PUBLIC_SENTRY_DSN=${SENTRY_DSN}
export NEXT_PUBLIC_SITE_ABOUT=${SITE_ABOUT}
+export NEXT_TELEMETRY_DISABLED=${NEXT_TELEMETRY_DISABLED}
pm2 start ./pm2.json --no-daemon
diff --git a/web/hooks/use-app-favicon.ts b/web/hooks/use-app-favicon.ts
new file mode 100644
index 0000000000..8904b884ce
--- /dev/null
+++ b/web/hooks/use-app-favicon.ts
@@ -0,0 +1,23 @@
+import { useAsyncEffect } from 'ahooks'
+import { appDefaultIconBackground } from '@/config'
+import { searchEmoji } from '@/utils/emoji'
+
+export function useAppFavicon(enable: boolean, icon?: string, icon_background?: string) {
+ useAsyncEffect(async () => {
+ if (!enable)
+ return
+ const link: HTMLLinkElement = document.querySelector('link[rel*="icon"]') || document.createElement('link')
+
+ // eslint-disable-next-line prefer-template
+ link.href = 'data:image/svg+xml,'
+ + ' '
+ + ''
+ + (icon ? await searchEmoji(icon) : '🤖')
+ + ' '
+ + ' '
+
+ link.rel = 'shortcut icon'
+ link.type = 'image/svg'
+ document.getElementsByTagName('head')[0].appendChild(link)
+ }, [enable, icon, icon_background])
+}
diff --git a/web/i18n/de-DE/app.ts b/web/i18n/de-DE/app.ts
index dc7396702c..2101aa8260 100644
--- a/web/i18n/de-DE/app.ts
+++ b/web/i18n/de-DE/app.ts
@@ -50,6 +50,56 @@ const translation = {
ok: 'OK',
cancel: 'Abbrechen',
},
+ switch: 'Zu Workflow-Orchestrierung wechseln',
+ switchTipStart: 'Eine neue App-Kopie wird für Sie erstellt, und die neue Kopie wird zur Workflow-Orchestrierung wechseln. Die neue Kopie wird ',
+ switchTip: 'nicht erlauben',
+ switchTipEnd: ' zur Basis-Orchestrierung zurückzuwechseln.',
+ switchLabel: 'Die zu erstellende App-Kopie',
+ removeOriginal: 'Ursprüngliche App löschen',
+ switchStart: 'Wechsel starten',
+ typeSelector: {
+ all: 'ALLE Typen',
+ chatbot: 'Chatbot',
+ agent: 'Agent',
+ workflow: 'Workflow',
+ completion: 'Vervollständigung',
+ },
+ tracing: {
+ title: 'Anwendungsleistung nachverfolgen',
+ description: 'Konfiguration eines Drittanbieter-LLMOps-Anbieters und Nachverfolgung der Anwendungsleistung.',
+ config: 'Konfigurieren',
+ collapse: 'Einklappen',
+ expand: 'Ausklappen',
+ tracing: 'Nachverfolgung',
+ disabled: 'Deaktiviert',
+ disabledTip: 'Bitte zuerst den Anbieter konfigurieren',
+ enabled: 'In Betrieb',
+ tracingDescription: 'Erfassung des vollständigen Kontexts der Anwendungsausführung, einschließlich LLM-Aufrufe, Kontext, Prompts, HTTP-Anfragen und mehr, auf einer Nachverfolgungsplattform von Drittanbietern.',
+ configProviderTitle: {
+ configured: 'Konfiguriert',
+ notConfigured: 'Anbieter konfigurieren, um Nachverfolgung zu aktivieren',
+ moreProvider: 'Weitere Anbieter',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Eine All-in-One-Entwicklerplattform für jeden Schritt des LLM-gesteuerten Anwendungslebenszyklus.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Traces, Bewertungen, Prompt-Management und Metriken zum Debuggen und Verbessern Ihrer LLM-Anwendung.',
+ },
+ inUse: 'In Verwendung',
+ configProvider: {
+ title: 'Konfigurieren ',
+ placeholder: 'Geben Sie Ihren {{key}} ein',
+ project: 'Projekt',
+ publicKey: 'Öffentlicher Schlüssel',
+ secretKey: 'Geheimer Schlüssel',
+ viewDocsLink: '{{key}}-Dokumentation ansehen',
+ removeConfirmTitle: '{{key}}-Konfiguration entfernen?',
+ removeConfirmContent: 'Die aktuelle Konfiguration wird verwendet. Das Entfernen wird die Nachverfolgungsfunktion ausschalten.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/de-DE/common.ts b/web/i18n/de-DE/common.ts
index bd0ef66e55..a7c7bb58fd 100644
--- a/web/i18n/de-DE/common.ts
+++ b/web/i18n/de-DE/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Abbrechen',
clear: 'Leeren',
save: 'Speichern',
+ saveAndEnable: 'Speichern und Aktivieren',
edit: 'Bearbeiten',
add: 'Hinzufügen',
added: 'Hinzugefügt',
diff --git a/web/i18n/de-DE/workflow.ts b/web/i18n/de-DE/workflow.ts
index 038ff1e675..fe72d68c3e 100644
--- a/web/i18n/de-DE/workflow.ts
+++ b/web/i18n/de-DE/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Zurück zum Editor',
conversationLog: 'Konversationsprotokoll',
features: 'Funktionen',
- debugAndPreview: 'Debuggen und Vorschau',
+ debugAndPreview: 'Vorschau',
restart: 'Neustarten',
currentDraft: 'Aktueller Entwurf',
currentDraftUnpublished: 'Aktueller Entwurf unveröffentlicht',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: 'Nach dem Workflow-Update ist eine Neukonfiguration des Tools erforderlich.',
viewDetailInTracingPanel: 'Details anzeigen',
},
+ env: {
+ envPanelTitle: 'Umgebungsvariablen',
+ envDescription: 'Umgebungsvariablen können zur Speicherung privater Informationen und Anmeldedaten verwendet werden. Sie sind schreibgeschützt und können beim Export vom DSL-File getrennt werden.',
+ envPanelButton: 'Variable hinzufügen',
+ modal: {
+ title: 'Umgebungsvariable hinzufügen',
+ editTitle: 'Umgebungsvariable bearbeiten',
+ type: 'Typ',
+ name: 'Name',
+ namePlaceholder: 'Umgebungsname',
+ value: 'Wert',
+ valuePlaceholder: 'Umgebungswert',
+ secretTip: 'Wird verwendet, um sensible Informationen oder Daten zu definieren, wobei DSL-Einstellungen zur Verhinderung von Lecks konfiguriert sind.',
+ },
+ export: {
+ title: 'Geheime Umgebungsvariablen exportieren?',
+ checkbox: 'Geheime Werte exportieren',
+ ignore: 'DSL exportieren',
+ export: 'DSL mit geheimen Werten exportieren',
+ },
+ },
changeHistory: {
title: 'Änderungsverlauf',
placeholder: 'Du hast noch nichts geändert',
diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts
index 118bfae76c..b0915a1f20 100644
--- a/web/i18n/en-US/workflow.ts
+++ b/web/i18n/en-US/workflow.ts
@@ -99,6 +99,33 @@ const translation = {
export: 'Export DSL with secret values ',
},
},
+ chatVariable: {
+ panelTitle: 'Conversation Variables',
+ panelDescription: 'Conversation Variables are used to store interactive information that LLM needs to remember, including conversation history, uploaded files, user preferences. They are read-write. ',
+ docLink: 'Visit our docs to learn more.',
+ button: 'Add Variable',
+ modal: {
+ title: 'Add Conversation Variable',
+ editTitle: 'Edit Conversation Variable',
+ name: 'Name',
+ namePlaceholder: 'Variable name',
+ type: 'Type',
+ value: 'Default Value',
+ valuePlaceholder: 'Default value, leave blank to not set',
+ description: 'Description',
+ descriptionPlaceholder: 'Describe the variable',
+ editInJSON: 'Edit in JSON',
+ oneByOne: 'Add one by one',
+ editInForm: 'Edit in Form',
+ arrayValue: 'Value',
+ addArrayValue: 'Add Value',
+ objectKey: 'Key',
+ objectType: 'Type',
+ objectValue: 'Default Value',
+ },
+ storedContent: 'Stored content',
+ updatedAt: 'Updated at ',
+ },
changeHistory: {
title: 'Change History',
placeholder: 'You haven\'t changed anything yet',
@@ -150,6 +177,7 @@ const translation = {
tabs: {
'searchBlock': 'Search block',
'blocks': 'Blocks',
+ 'searchTool': 'Search tool',
'tools': 'Tools',
'allTool': 'All',
'builtInTool': 'Built-in',
@@ -174,6 +202,7 @@ const translation = {
'http-request': 'HTTP Request',
'variable-assigner': 'Variable Aggregator',
'variable-aggregator': 'Variable Aggregator',
+ 'assigner': 'Variable Assigner',
'iteration-start': 'Iteration Start',
'iteration': 'Iteration',
'parameter-extractor': 'Parameter Extractor',
@@ -192,6 +221,7 @@ const translation = {
'template-transform': 'Convert data to string using Jinja template syntax',
'http-request': 'Allow server requests to be sent over the HTTP protocol',
'variable-assigner': 'Aggregate multi-branch variables into a single variable for unified configuration of downstream nodes.',
+ 'assigner': 'The variable assignment node is used for assigning values to writable variables(like conversation variables).',
'variable-aggregator': 'Aggregate multi-branch variables into a single variable for unified configuration of downstream nodes.',
'iteration': 'Perform multiple steps on a list object until all results are outputted.',
'parameter-extractor': 'Use LLM to extract structured parameters from natural language for tool invocations or HTTP requests.',
@@ -220,6 +250,7 @@ const translation = {
checklistResolved: 'All issues are resolved',
organizeBlocks: 'Organize blocks',
change: 'Change',
+ optional: '(optional)',
},
nodes: {
common: {
@@ -422,6 +453,17 @@ const translation = {
},
setAssignVariable: 'Set assign variable',
},
+ assigner: {
+ 'assignedVariable': 'Assigned Variable',
+ 'writeMode': 'Write Mode',
+ 'writeModeTip': 'When ASSIGNED VARIABLE is an array, append mode adds to the end.',
+ 'over-write': 'Overwrite',
+ 'append': 'Append',
+ 'plus': 'Plus',
+ 'clear': 'Clear',
+ 'setVariable': 'Set Variable',
+ 'variable': 'Variable',
+ },
tool: {
toAuthorize: 'To authorize',
inputVars: 'Input Variables',
diff --git a/web/i18n/es-ES/workflow.ts b/web/i18n/es-ES/workflow.ts
index 5db18939fe..fbdeff3a6f 100644
--- a/web/i18n/es-ES/workflow.ts
+++ b/web/i18n/es-ES/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Volver al editor',
conversationLog: 'Registro de conversación',
features: 'Funcionalidades',
- debugAndPreview: 'Depurar y previsualizar',
+ debugAndPreview: 'Vista previa',
restart: 'Reiniciar',
currentDraft: 'Borrador actual',
currentDraftUnpublished: 'Borrador actual no publicado',
@@ -78,6 +78,27 @@ const translation = {
importFailure: 'Error al importar',
importSuccess: 'Importación exitosa',
},
+ env: {
+ envPanelTitle: 'Variables de Entorno',
+ envDescription: 'Las variables de entorno se pueden utilizar para almacenar información privada y credenciales. Son de solo lectura y se pueden separar del archivo DSL durante la exportación.',
+ envPanelButton: 'Añadir Variable',
+ modal: {
+ title: 'Añadir Variable de Entorno',
+ editTitle: 'Editar Variable de Entorno',
+ type: 'Tipo',
+ name: 'Nombre',
+ namePlaceholder: 'nombre de env',
+ value: 'Valor',
+ valuePlaceholder: 'valor de env',
+ secretTip: 'Se utiliza para definir información o datos sensibles, con configuraciones DSL configuradas para prevenir fugas.',
+ },
+ export: {
+ title: '¿Exportar variables de entorno secretas?',
+ checkbox: 'Exportar valores secretos',
+ ignore: 'Exportar DSL',
+ export: 'Exportar DSL con valores secretos',
+ },
+ },
changeHistory: {
title: 'Historial de cambios',
placeholder: 'Aún no has realizado cambios',
diff --git a/web/i18n/fa-IR/app-annotation.ts b/web/i18n/fa-IR/app-annotation.ts
new file mode 100644
index 0000000000..e78fc8cd7e
--- /dev/null
+++ b/web/i18n/fa-IR/app-annotation.ts
@@ -0,0 +1,87 @@
+const translation = {
+ title: 'یادداشتها',
+ name: 'پاسخ یادداشت',
+ editBy: 'پاسخ ویرایش شده توسط {{author}}',
+ noData: {
+ title: 'بدون یادداشت',
+ description: 'شما میتوانید یادداشتها را در حین اشکالزدایی برنامه ویرایش کنید یا یادداشتها را به صورت انبوه در اینجا برای پاسخگویی با کیفیت بالا وارد کنید.',
+ },
+ table: {
+ header: {
+ question: 'سوال',
+ answer: 'پاسخ',
+ createdAt: 'ایجاد شده در',
+ hits: 'بازدیدها',
+ actions: 'اقدامات',
+ addAnnotation: 'افزودن یادداشت',
+ bulkImport: 'واردات انبوه',
+ bulkExport: 'صادرات انبوه',
+ clearAll: 'پاک کردن همه یادداشتها',
+ },
+ },
+ editModal: {
+ title: 'ویرایش پاسخ یادداشت',
+ queryName: 'پرسش کاربر',
+ answerName: 'ربات داستانسرا',
+ yourAnswer: 'پاسخ شما',
+ answerPlaceholder: 'پاسخ خود را اینجا بنویسید',
+ yourQuery: 'پرسش شما',
+ queryPlaceholder: 'پرسش خود را اینجا بنویسید',
+ removeThisCache: 'حذف این یادداشت',
+ createdAt: 'ایجاد شده در',
+ },
+ addModal: {
+ title: 'افزودن پاسخ یادداشت',
+ queryName: 'سوال',
+ answerName: 'پاسخ',
+ answerPlaceholder: 'پاسخ را اینجا بنویسید',
+ queryPlaceholder: 'پرسش را اینجا بنویسید',
+ createNext: 'افزودن پاسخ یادداشتشده دیگر',
+ },
+ batchModal: {
+ title: 'واردات انبوه',
+ csvUploadTitle: 'فایل CSV خود را اینجا بکشید و رها کنید، یا ',
+ browse: 'مرور کنید',
+ tip: 'فایل CSV باید از ساختار زیر پیروی کند:',
+ question: 'سوال',
+ answer: 'پاسخ',
+ contentTitle: 'محتوای تکه',
+ content: 'محتوا',
+ template: 'الگو را از اینجا دانلود کنید',
+ cancel: 'لغو',
+ run: 'اجرای دستهای',
+ runError: 'اجرای دستهای ناموفق بود',
+ processing: 'در حال پردازش دستهای',
+ completed: 'واردات تکمیل شد',
+ error: 'خطای واردات',
+ ok: 'تایید',
+ },
+ errorMessage: {
+ answerRequired: 'پاسخ الزامی است',
+ queryRequired: 'سوال الزامی است',
+ },
+ viewModal: {
+ annotatedResponse: 'پاسخ یادداشتشده',
+ hitHistory: 'تاریخچه بازدید',
+ hit: 'بازدید',
+ hits: 'بازدیدها',
+ noHitHistory: 'بدون تاریخچه بازدید',
+ },
+ hitHistoryTable: {
+ query: 'پرسش',
+ match: 'تطابق',
+ response: 'پاسخ',
+ source: 'منبع',
+ score: 'امتیاز',
+ time: 'زمان',
+ },
+ initSetup: {
+ title: 'راهاندازی اولیه پاسخ یادداشت',
+ configTitle: 'تنظیمات پاسخ یادداشت',
+ confirmBtn: 'ذخیره و فعالسازی',
+ configConfirmBtn: 'ذخیره',
+ },
+ embeddingModelSwitchTip: 'مدل برداریسازی متن یادداشت، تغییر مدلها باعث جاسازی مجدد خواهد شد و هزینههای اضافی به همراه خواهد داشت.',
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/app-api.ts b/web/i18n/fa-IR/app-api.ts
new file mode 100644
index 0000000000..0548ef2a2b
--- /dev/null
+++ b/web/i18n/fa-IR/app-api.ts
@@ -0,0 +1,83 @@
+const translation = {
+ apiServer: 'سرور API',
+ apiKey: 'کلید API',
+ status: 'وضعیت',
+ disabled: 'غیرفعال',
+ ok: 'در سرویس',
+ copy: 'کپی',
+ copied: 'کپی شد',
+ play: 'پخش',
+ pause: 'مکث',
+ playing: 'در حال پخش',
+ loading: 'در حال بارگذاری',
+ merMaind: {
+ rerender: 'بازسازی مجدد',
+ },
+ never: 'هرگز',
+ apiKeyModal: {
+ apiSecretKey: 'کلید مخفی API',
+ apiSecretKeyTips: 'برای جلوگیری از سوء استفاده از API، از کلید API خود محافظت کنید. از استفاده از آن به صورت متن ساده در کد فرانتاند خودداری کنید. :)',
+ createNewSecretKey: 'ایجاد کلید مخفی جدید',
+ secretKey: 'کلید مخفی',
+ created: 'ایجاد شده',
+ lastUsed: 'آخرین استفاده',
+ generateTips: 'این کلید را در مکانی امن و قابل دسترس نگه دارید.',
+ },
+ actionMsg: {
+ deleteConfirmTitle: 'این کلید مخفی حذف شود؟',
+ deleteConfirmTips: 'این عمل قابل بازگشت نیست.',
+ ok: 'تایید',
+ },
+ completionMode: {
+ title: 'API برنامه تکمیل',
+ info: 'برای تولید متن با کیفیت بالا، مانند مقالات، خلاصهها و ترجمهها، از API پیامهای تکمیلی با ورودی کاربر استفاده کنید. تولید متن به پارامترهای مدل و قالبهای پرامپت تنظیم شده در مهندسی پرامپت Dify بستگی دارد.',
+ createCompletionApi: 'ایجاد پیام تکمیلی',
+ createCompletionApiTip: 'یک پیام تکمیلی برای پشتیبانی از حالت سوال و جواب ایجاد کنید.',
+ inputsTips: '(اختیاری) فیلدهای ورودی کاربر را به صورت جفتهای کلید-مقدار ارائه دهید که با متغیرهای موجود در مهندسی پرامپت مطابقت دارند. کلید نام متغیر است و مقدار، مقدار پارامتر است. اگر نوع فیلد انتخابی باشد، مقدار ارسال شده باید یکی از گزینههای از پیش تعیین شده باشد.',
+ queryTips: 'محتوای متن ورودی کاربر.',
+ blocking: 'نوع مسدودکننده، منتظر اتمام اجرا و بازگشت نتایج. (درخواستها ممکن است در صورت طولانی بودن فرآیند قطع شوند)',
+ streaming: 'بازگشت جریانی. پیادهسازی بازگشت جریانی بر اساس SSE (رویدادهای ارسالی سرور).',
+ messageFeedbackApi: 'بازخورد پیام (لایک)',
+ messageFeedbackApiTip: 'پیامهای دریافتی را از طرف کاربران نهایی با لایک یا دیسلایک ارزیابی کنید. این دادهها در صفحه گزارشها و یادداشتها قابل مشاهده هستند و برای تنظیم دقیق مدل در آینده استفاده میشوند.',
+ messageIDTip: 'شناسه پیام',
+ ratingTip: 'لایک یا دیسلایک، null برای لغو',
+ parametersApi: 'دریافت اطلاعات پارامترهای برنامه',
+ parametersApiTip: 'بازیابی پارامترهای ورودی پیکربندی شده، شامل نامهای متغیر، نامهای فیلد، انواع و مقادیر پیشفرض. معمولاً برای نمایش این فیلدها در یک فرم یا پر کردن مقادیر پیشفرض پس از بارگیری کلاینت استفاده میشود.',
+ },
+ chatMode: {
+ title: 'API برنامه چت',
+ info: 'برای برنامههای مکالمهای چندمنظوره با استفاده از فرمت سوال و جواب، API پیامهای چت را برای شروع گفتگو فراخوانی کنید. با ارسال شناسه مکالمه بازگشتی، گفتگوهای مداوم را حفظ کنید. پارامترهای پاسخ و قالبها به تنظیمات مهندسی پرامپت Dify بستگی دارند.',
+ createChatApi: 'ایجاد پیام چت',
+ createChatApiTip: 'یک پیام مکالمه جدید ایجاد کنید یا یک گفتگوی موجود را ادامه دهید.',
+ inputsTips: '(اختیاری) فیلدهای ورودی کاربر را به صورت جفتهای کلید-مقدار ارائه دهید که با متغیرهای موجود در مهندسی پرامپت مطابقت دارند. کلید نام متغیر است و مقدار، مقدار پارامتر است. اگر نوع فیلد انتخابی باشد، مقدار ارسال شده باید یکی از گزینههای از پیش تعیین شده باشد.',
+ queryTips: 'محتوای ورودی/سوال کاربر',
+ blocking: 'نوع مسدودکننده، منتظر اتمام اجرا و بازگشت نتایج. (درخواستها ممکن است در صورت طولانی بودن فرآیند قطع شوند)',
+ streaming: 'بازگشت جریانی. پیادهسازی بازگشت جریانی بر اساس SSE (رویدادهای ارسالی سرور).',
+ conversationIdTip: '(اختیاری) شناسه مکالمه: برای اولین مکالمه خالی بگذارید؛ برای ادامه گفتگو، شناسه مکالمه را از متن ارسال کنید.',
+ messageFeedbackApi: 'بازخورد کاربر نهایی پیام، لایک',
+ messageFeedbackApiTip: 'پیامهای دریافتی را از طرف کاربران نهایی با لایک یا دیسلایک ارزیابی کنید. این دادهها در صفحه گزارشها و یادداشتها قابل مشاهده هستند و برای تنظیم دقیق مدل در آینده استفاده میشوند.',
+ messageIDTip: 'شناسه پیام',
+ ratingTip: 'لایک یا دیسلایک، null برای لغو',
+ chatMsgHistoryApi: 'دریافت تاریخچه پیامهای چت',
+ chatMsgHistoryApiTip: 'صفحه اول آخرین `limit` پیام را به صورت معکوس برمیگرداند.',
+ chatMsgHistoryConversationIdTip: 'شناسه مکالمه',
+ chatMsgHistoryFirstId: 'شناسه اولین رکورد چت در صفحه فعلی. پیشفرض هیچ است.',
+ chatMsgHistoryLimit: 'تعداد چتهایی که در یک درخواست برگردانده میشوند',
+ conversationsListApi: 'دریافت لیست مکالمات',
+ conversationsListApiTip: 'لیست جلسات کاربر فعلی را دریافت میکند. به طور پیشفرض، 20 جلسه آخر برگردانده میشود.',
+ conversationsListFirstIdTip: 'شناسه آخرین رکورد در صفحه فعلی، پیشفرض هیچ.',
+ conversationsListLimitTip: 'تعداد چتهایی که در یک درخواست برگردانده میشوند',
+ conversationRenamingApi: 'تغییر نام مکالمه',
+ conversationRenamingApiTip: 'تغییر نام مکالمات؛ نام در رابطهای کاربری چند جلسهای نمایش داده میشود.',
+ conversationRenamingNameTip: 'نام جدید',
+ parametersApi: 'دریافت اطلاعات پارامترهای برنامه',
+ parametersApiTip: 'بازیابی پارامترهای ورودی پیکربندی شده، شامل نامهای متغیر، نامهای فیلد، انواع و مقادیر پیشفرض. معمولاً برای نمایش این فیلدها در یک فرم یا پر کردن مقادیر پیشفرض پس از بارگیری کلاینت استفاده میشود.',
+ },
+ develop: {
+ requestBody: 'بدنه درخواست',
+ pathParams: 'پارامترهای مسیر',
+ query: 'پرسوجو',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/app-debug.ts b/web/i18n/fa-IR/app-debug.ts
new file mode 100644
index 0000000000..863f47bb18
--- /dev/null
+++ b/web/i18n/fa-IR/app-debug.ts
@@ -0,0 +1,455 @@
+const translation = {
+ pageTitle: {
+ line1: 'پرومپت',
+ line2: 'مهندسی',
+ },
+ orchestrate: 'هماهنگ کردن',
+ promptMode: {
+ simple: 'برای ویرایش کل پرومپت به حالت کارشناس بروید',
+ advanced: 'حالت کارشناس',
+ switchBack: 'بازگشت',
+ advancedWarning: {
+ title: 'شما به حالت کارشناس رفتهاید، و پس از تغییر پرومپت، نمیتوانید به حالت ساده برگردید.',
+ description: 'در حالت کارشناس، میتوانید کل پرومپت را ویرایش کنید.',
+ learnMore: 'بیشتر بدانید',
+ ok: 'باشه',
+ },
+ operation: {
+ addMessage: 'اضافه کردن پیام',
+ },
+ contextMissing: 'مولفه زمینهای از دست رفته است، اثر بخشی پرومپت ممکن است خوب نباشد.',
+ },
+ operation: {
+ applyConfig: 'انتشار',
+ resetConfig: 'تنظیم مجدد',
+ debugConfig: 'دیباگ',
+ addFeature: 'اضافه کردن ویژگی',
+ automatic: 'تولید کردن',
+ stopResponding: 'توقف پاسخدهی',
+ agree: 'پسندیدن',
+ disagree: 'نپسندیدن',
+ cancelAgree: 'لغو پسندیدن',
+ cancelDisagree: 'لغو نپسندیدن',
+ userAction: 'عمل کاربر',
+ },
+ notSetAPIKey: {
+ title: 'کلید ارائهدهنده LLM تنظیم نشده است',
+ trailFinished: 'آزمایش تمام شد',
+ description: 'کلید ارائهدهنده LLM تنظیم نشده است و باید قبل از دیباگ تنظیم شود.',
+ settingBtn: 'به تنظیمات بروید',
+ },
+ trailUseGPT4Info: {
+ title: 'در حال حاضر پشتیبانی نمیشود gpt-4',
+ description: 'برای استفاده از gpt-4، لطفاً کلید API را تنظیم کنید.',
+ },
+ feature: {
+ groupChat: {
+ title: 'تقویت گفتگو',
+ description: 'افزودن تنظیمات پیش از گفتگو برای برنامهها میتواند تجربه کاربری را بهبود بخشد.',
+ },
+ groupExperience: {
+ title: 'تقویت تجربه',
+ },
+ conversationOpener: {
+ title: 'شروعکننده گفتگو',
+ description: 'در یک برنامه چت، اولین جملهای که AI فعالانه با کاربر صحبت میکند، معمولاً به عنوان خوشامدگویی استفاده میشود.',
+ },
+ suggestedQuestionsAfterAnswer: {
+ title: 'پیگیری',
+ description: 'تنظیم پیشنهاد سوالات بعدی میتواند به کاربران یک چت بهتر ارائه دهد.',
+ resDes: '3 پیشنهاد برای سوال بعدی کاربر.',
+ tryToAsk: 'سعی کنید بپرسید',
+ },
+ moreLikeThis: {
+ title: 'بیشتر از این',
+ description: 'تولید چندین متن به طور همزمان، و سپس ویرایش و ادامه تولید',
+ generateNumTip: 'تعداد تولید هر بار',
+ tip: 'استفاده از این ویژگی هزینههای اضافی توکنها را به همراه دارد',
+ },
+ speechToText: {
+ title: 'تبدیل گفتار به متن',
+ description: 'پس از فعال شدن، میتوانید از ورودی صوتی استفاده کنید.',
+ resDes: 'ورودی صوتی فعال شده است',
+ },
+ textToSpeech: {
+ title: 'تبدیل متن به گفتار',
+ description: 'پس از فعال شدن، متن میتواند به گفتار تبدیل شود.',
+ resDes: 'تبدیل متن به صدا فعال شده است',
+ },
+ citation: {
+ title: 'ارجاعات و استنادات',
+ description: 'پس از فعال شدن، سند منبع و بخش استناد شده از محتوای تولید شده را نشان میدهد.',
+ resDes: 'ارجاعات و استنادات فعال شده است',
+ },
+ annotation: {
+ title: 'پاسخ حاشیهنویسی',
+ description: 'میتوانید پاسخهای با کیفیت بالا را به صورت دستی به حافظه کش اضافه کنید تا با سوالات مشابه کاربران تطبیق یابد.',
+ resDes: 'پاسخ حاشیهنویسی فعال شده است',
+ scoreThreshold: {
+ title: 'آستانه امتیاز',
+ description: 'Used to set the similarity threshold for annotation reply.',
+ easyMatch: 'تطابق آسان',
+ accurateMatch: 'تطابق دقیق',
+ },
+ matchVariable: {
+ title: 'تغییر متغیر',
+ choosePlaceholder: 'انتخاب متغیر تغییر',
+ },
+ cacheManagement: 'حاشیه نویسی',
+ cached: 'حاشیه نویسی شده',
+ remove: 'حذف',
+ removeConfirm: 'این حاشیه نویسی را حذف کنید؟',
+ add: 'افزودن حاشیه نویسی',
+ edit: 'ویرایش حاشیه نویسی',
+ },
+ dataSet: {
+ title: 'زمینه',
+ noData: 'شما میتوانید دانش را به عنوان زمینه وارد کنید',
+ words: 'کلمات',
+ textBlocks: 'بلوکهای متن',
+ selectTitle: 'انتخاب دانش مرجع',
+ selected: 'دانش انتخاب شده',
+ noDataSet: 'هیچ دانشی یافت نشد',
+ toCreate: 'برای ایجاد بروید',
+ notSupportSelectMulti: 'در حال حاضر فقط یک دانش پشتیبانی میشود',
+ queryVariable: {
+ title: 'متغیر پرس و جو',
+ tip: 'این متغیر به عنوان ورودی پرس و جو برای بازیابی زمینه استفاده خواهد شد و اطلاعات زمینه مرتبط با ورودی این متغیر را به دست میآورد.',
+ choosePlaceholder: 'انتخاب متغیر پرس و جو',
+ noVar: 'بدون متغیر',
+ noVarTip: 'لطفاً متغیری را در بخش متغیرها ایجاد کنید',
+ unableToQueryDataSet: 'عدم امکان پرس و جو از دانش',
+ unableToQueryDataSetTip: 'پرس و جوی موفقیت آمیز دانش ممکن نیست، لطفاً یک متغیر پرس و جو زمینه را در بخش زمینه انتخاب کنید.',
+ ok: 'باشه',
+ contextVarNotEmpty: 'متغیر پرس و جو زمینه نمیتواند خالی باشد',
+ deleteContextVarTitle: 'متغیر "{{varName}}" را حذف کنید؟',
+ deleteContextVarTip: 'این متغیر به عنوان متغیر پرس و جو زمینه تنظیم شده است و حذف آن بر استفاده عادی از دانش تأثیر میگذارد. اگر هنوز نیاز به حذف دارید، لطفاً آن را در بخش زمینه دوباره انتخاب کنید.',
+ },
+ },
+ tools: {
+ title: 'ابزارها',
+ tips: 'ابزارها یک روش استاندارد برای فراخوانی API فراهم میکنند و ورودی کاربر یا متغیرها را به عنوان پارامترهای درخواست برای پرس و جو دادههای خارجی به عنوان زمینه میگیرند.',
+ toolsInUse: '{{count}} ابزار در حال استفاده',
+ modal: {
+ title: 'ابزار',
+ toolType: {
+ title: 'نوع ابزار',
+ placeholder: 'لطفاً نوع ابزار را انتخاب کنید',
+ },
+ name: {
+ title: 'نام',
+ placeholder: 'لطفاً نام را وارد کنید',
+ },
+ variableName: {
+ title: 'نام متغیر',
+ placeholder: 'لطفاً نام متغیر را وارد کنید',
+ },
+ },
+ },
+ conversationHistory: {
+ title: 'تاریخچه مکالمه',
+ description: 'تنظیم پیشوند نامها برای نقشهای مکالمه',
+ tip: 'تاریخچه مکالمه فعال نشده است، لطفاً را در فراخوانی بالا اضافه کنید.',
+ learnMore: 'بیشتر بدانید',
+ editModal: {
+ title: 'ویرایش نام نقشهای مکالمه',
+ userPrefix: 'پیشوند کاربر',
+ assistantPrefix: 'پیشوند دستیار',
+ },
+ },
+ toolbox: {
+ title: 'جعبه ابزار',
+ },
+ moderation: {
+ title: 'مدیریت محتوا',
+ description: 'خروجی مدل را با استفاده از API مدیریت یا نگهداری فهرست کلمات حساس امن کنید.',
+ allEnabled: 'محتوای ورودی/خروجی فعال شده',
+ inputEnabled: 'محتوای ورودی فعال شده',
+ outputEnabled: 'محتوای خروجی فعال شده',
+ modal: {
+ title: 'تنظیمات مدیریت محتوا',
+ provider: {
+ title: 'ارائه دهنده',
+ openai: 'مدیریت OpenAI',
+ openaiTip: {
+ prefix: 'مدیریت OpenAI نیاز به کلید API OpenAI دارد که در ',
+ suffix: ' تنظیم شده باشد.',
+ },
+ keywords: 'کلمات کلیدی',
+ },
+ keywords: {
+ tip: 'هر خط یک کلمه، با شکست خطوط جدا شده. حداکثر 100 کاراکتر در هر خط.',
+ placeholder: 'هر خط یک کلمه، با شکست خطوط جدا شده',
+ line: 'خط',
+ },
+ content: {
+ input: 'مدیریت محتوای ورودی',
+ output: 'مدیریت محتوای خروجی',
+ preset: 'پاسخهای پیش فرض',
+ placeholder: 'محتوای پاسخهای پیش فرض در اینجا',
+ condition: 'مدیریت محتوای ورودی و خروجی حداقل یک مورد فعال شده است',
+ fromApi: 'پاسخهای پیش فرض از API برگردانده میشود',
+ errorMessage: 'پاسخهای پیش فرض نمیتواند خالی باشد',
+ supportMarkdown: 'پشتیبانی از Markdown',
+ },
+ openaiNotConfig: {
+ before: 'مدیریت OpenAI نیاز به کلید API OpenAI دارد که در',
+ after: '',
+ },
+ },
+ },
+ generate: {
+ title: 'تولید کننده دستورالعمل',
+ description: 'تولید کننده دستورالعمل از مدل تنظیم شده برای بهینه سازی دستورالعملها برای کیفیت بالاتر و ساختار بهتر استفاده میکند. لطفاً دستورالعملهای واضح و دقیقی بنویسید.',
+ tryIt: 'امتحان کنید',
+ instruction: 'دستورالعملها',
+ instructionPlaceHolder: 'دستورالعملهای واضح و خاصی بنویسید.',
+ generate: 'تولید',
+ resTitle: 'دستورالعمل تولید شده',
+ noDataLine1: 'موارد استفاده خود را در سمت چپ توصیف کنید،',
+ noDataLine2: 'پیشنمایش ارکستراسیون در اینجا نشان داده خواهد شد.',
+ apply: 'اعمال',
+ loading: 'در حال ارکستراسیون برنامه برای شما...',
+ overwriteTitle: 'آیا تنظیمات موجود را لغو میکنید؟',
+ overwriteMessage: 'اعمال این دستورالعمل تنظیمات موجود را لغو خواهد کرد.',
+ template: {
+ pythonDebugger: {
+ name: 'اشکالزدای پایتون',
+ instruction: 'یک بات که میتواند بر اساس دستورالعمل شما کد تولید و اشکالزدایی کند',
+ },
+ translation: {
+ name: 'ترجمه',
+ instruction: 'یک مترجم که میتواند چندین زبان را ترجمه کند',
+ },
+ professionalAnalyst: {
+ name: 'تحلیلگر حرفهای',
+ instruction: 'استخراج بینشها، شناسایی ریسک و خلاصهسازی اطلاعات کلیدی از گزارشهای طولانی به یک یادداشت کوتاه',
+ },
+ excelFormulaExpert: {
+ name: 'کارشناس فرمول اکسل',
+ instruction: 'یک چتبات که میتواند به کاربران مبتدی کمک کند فرمولهای اکسل را بر اساس دستورالعملهای کاربر درک، استفاده و ایجاد کنند',
+ },
+ travelPlanning: {
+ name: 'برنامهریزی سفر',
+ instruction: 'دستیار برنامهریزی سفر یک ابزار هوشمند است که به کاربران کمک میکند سفرهای خود را به راحتی برنامهریزی کنند',
+ },
+ SQLSorcerer: {
+ name: 'جادوگر SQL',
+ instruction: 'تبدیل زبان روزمره به پرس و جوهای SQL',
+ },
+ GitGud: {
+ name: 'Git gud',
+ instruction: 'تولید دستورات مناسب Git بر اساس اقدامات توصیف شده توسط کاربر در کنترل نسخه',
+ },
+ meetingTakeaways: {
+ name: 'نتایج جلسات',
+ instruction: 'خلاصهسازی جلسات به صورت مختصر شامل موضوعات بحث، نکات کلیدی و موارد اقدام',
+ },
+ writingsPolisher: {
+ name: 'پولیشگر نوشتهها',
+ instruction: 'استفاده از تکنیکهای ویرایش پیشرفته برای بهبود نوشتههای شما',
+ },
+ },
+ },
+ resetConfig: {
+ title: 'بازنشانی تأیید میشود؟',
+ message: 'بازنشانی تغییرات را لغو کرده و تنظیمات منتشر شده آخر را بازیابی میکند.',
+ },
+ errorMessage: {
+ nameOfKeyRequired: 'نام کلید: {{key}} مورد نیاز است',
+ valueOfVarRequired: 'مقدار {{key}} نمیتواند خالی باشد',
+ queryRequired: 'متن درخواست مورد نیاز است.',
+ waitForResponse: 'لطفاً منتظر پاسخ به پیام قبلی بمانید.',
+ waitForBatchResponse: 'لطفاً منتظر پاسخ به کار دستهای بمانید.',
+ notSelectModel: 'لطفاً یک مدل را انتخاب کنید',
+ waitForImgUpload: 'لطفاً منتظر بارگذاری تصویر بمانید',
+ },
+ chatSubTitle: 'دستورالعملها',
+ completionSubTitle: 'پیشوند پرس و جو',
+ promptTip: 'دستورالعملها و محدودیتها پاسخهای AI را هدایت میکنند. متغیرهایی مانند {{input}} را درج کنید. این دستورالعمل برای کاربران قابل مشاهده نخواهد بود.',
+ formattingChangedTitle: 'قالببندی تغییر کرد',
+ formattingChangedText: 'تغییر قالببندی منطقه اشکالزدایی را بازنشانی خواهد کرد، آیا مطمئن هستید؟',
+ variableTitle: 'متغیرها',
+ variableTip: 'کاربران متغیرها را در فرم پر میکنند و به طور خودکار متغیرها را در دستورالعملها جایگزین میکنند.',
+ notSetVar: 'متغیرها به کاربران اجازه میدهند که کلمات پرس و جو یا جملات ابتدایی را هنگام پر کردن فرم معرفی کنند. شما میتوانید سعی کنید "{{input}}" را در کلمات پرس و جو وارد کنید.',
+ autoAddVar: 'متغیرهای تعریف نشدهای که در پیشپرسش ذکر شدهاند، آیا میخواهید آنها را به فرم ورودی کاربر اضافه کنید؟',
+ variableTable: {
+ key: 'کلید متغیر',
+ name: 'نام فیلد ورودی کاربر',
+ optional: 'اختیاری',
+ type: 'نوع ورودی',
+ action: 'اقدامات',
+ typeString: 'رشته',
+ typeSelect: 'انتخاب',
+ },
+ varKeyError: {
+ canNoBeEmpty: 'کلید متغیر نمیتواند خالی باشد',
+ tooLong: 'کلید متغیر: {{key}} طولانی است. نمیتواند بیش از 30 کاراکتر باشد',
+ notValid: 'کلید متغیر: {{key}} نامعتبر است. فقط میتواند شامل حروف، اعداد و زیرخط باشد',
+ notStartWithNumber: 'کلید متغیر: {{key}} نمیتواند با عدد شروع شود',
+ keyAlreadyExists: 'کلید متغیر: :{{key}} از قبل وجود دارد',
+ },
+ otherError: {
+ promptNoBeEmpty: 'پرس و جو نمیتواند خالی باشد',
+ historyNoBeEmpty: 'تاریخچه مکالمه باید در پرس و جو تنظیم شود',
+ queryNoBeEmpty: 'پرس و جو باید در پرس و جو تنظیم شود',
+ },
+ variableConig: {
+ 'addModalTitle': 'افزودن فیلد ورودی',
+ 'editModalTitle': 'ویرایش فیلد ورودی',
+ 'description': 'تنظیم برای متغیر {{varName}}',
+ 'fieldType': 'نوع فیلد',
+ 'string': 'متن کوتاه',
+ 'text-input': 'متن کوتاه',
+ 'paragraph': 'پاراگراف',
+ 'select': 'انتخاب',
+ 'number': 'عدد',
+ 'notSet': 'تنظیم نشده، سعی کنید {{input}} را در پرس و جو وارد کنید',
+ 'stringTitle': 'گزینههای جعبه متن فرم',
+ 'maxLength': 'حداکثر طول',
+ 'options': 'گزینهها',
+ 'addOption': 'افزودن گزینه',
+ 'apiBasedVar': 'متغیر مبتنی بر API',
+ 'varName': 'نام متغیر',
+ 'labelName': 'نام برچسب',
+ 'inputPlaceholder': 'لطفاً وارد کنید',
+ 'content': 'محتوا',
+ 'required': 'مورد نیاز',
+ 'errorMsg': {
+ varNameRequired: 'نام متغیر مورد نیاز است',
+ labelNameRequired: 'نام برچسب مورد نیاز است',
+ varNameCanBeRepeat: 'نام متغیر نمیتواند تکراری باشد',
+ atLeastOneOption: 'حداقل یک گزینه مورد نیاز است',
+ optionRepeat: 'گزینههای تکراری وجود دارد',
+ },
+ },
+ vision: {
+ name: 'بینایی',
+ description: 'فعال کردن بینایی به مدل اجازه میدهد تصاویر را دریافت کند و به سوالات مربوط به آنها پاسخ دهد.',
+ settings: 'تنظیمات',
+ visionSettings: {
+ title: 'تنظیمات بینایی',
+ resolution: 'وضوح',
+ resolutionTooltip: `وضوح پایین به مدل اجازه میدهد نسخه 512x512 کموضوح تصویر را دریافت کند و تصویر را با بودجه 65 توکن نمایش دهد. این به API اجازه میدهد پاسخهای سریعتری بدهد و توکنهای ورودی کمتری برای موارد استفاده که نیاز به جزئیات بالا ندارند مصرف کند.
+ \n
+ وضوح بالا ابتدا به مدل اجازه میدهد تصویر کموضوح را ببیند و سپس قطعات جزئیات تصویر ورودی را به عنوان مربعهای 512px ایجاد کند. هر کدام از قطعات جزئیات از بودجه توکن دو برابر استفاده میکنند که در مجموع 129 توکن است.`,
+ high: 'بالا',
+ low: 'پایین',
+ uploadMethod: 'روش بارگذاری',
+ both: 'هر دو',
+ localUpload: 'بارگذاری محلی',
+ url: 'URL',
+ uploadLimit: 'محدودیت بارگذاری',
+ },
+ },
+ voice: {
+ name: 'صدا',
+ defaultDisplay: 'صدا پیش فرض',
+ description: 'تنظیمات تبدیل متن به گفتار',
+ settings: 'تنظیمات',
+ voiceSettings: {
+ title: 'تنظیمات صدا',
+ language: 'زبان',
+ resolutionTooltip: 'پشتیبانی از زبان صدای تبدیل متن به گفتار.',
+ voice: 'صدا',
+ autoPlay: 'پخش خودکار',
+ autoPlayEnabled: 'روشن کردن',
+ autoPlayDisabled: 'خاموش کردن',
+ },
+ },
+ openingStatement: {
+ title: 'شروع مکالمه',
+ add: 'افزودن',
+ writeOpener: 'نوشتن آغازگر',
+ placeholder: 'پیام آغازگر خود را اینجا بنویسید، میتوانید از متغیرها استفاده کنید، سعی کنید {{variable}} را تایپ کنید.',
+ openingQuestion: 'سوالات آغازین',
+ noDataPlaceHolder: 'شروع مکالمه با کاربر میتواند به AI کمک کند تا ارتباط نزدیکتری با آنها برقرار کند.',
+ varTip: 'میتوانید از متغیرها استفاده کنید، سعی کنید {{variable}} را تایپ کنید',
+ tooShort: 'حداقل 20 کلمه از پرسش اولیه برای تولید نظرات آغازین مکالمه مورد نیاز است.',
+ notIncludeKey: 'پرسش اولیه شامل متغیر: {{key}} نمیشود. لطفاً آن را به پرسش اولیه اضافه کنید.',
+ },
+ modelConfig: {
+ model: 'مدل',
+ setTone: 'تنظیم لحن پاسخها',
+ title: 'مدل و پارامترها',
+ modeType: {
+ chat: 'چت',
+ completion: 'تکمیل',
+ },
+ },
+ inputs: {
+ title: 'اشکالزدایی و پیشنمایش',
+ noPrompt: 'سعی کنید پرسشهایی را در ورودی پیشپرسش بنویسید',
+ userInputField: 'فیلد ورودی کاربر',
+ noVar: 'مقدار متغیر را پر کنید، که به طور خودکار در کلمات پرس و جو در هر بار شروع یک جلسه جدید جایگزین میشود.',
+ chatVarTip: 'مقدار متغیر را پر کنید، که به طور خودکار در کلمات پرس و جو در هر بار شروع یک جلسه جدید جایگزین میشود',
+ completionVarTip: 'مقدار متغیر را پر کنید، که به طور خودکار در کلمات پرس و جو در هر بار ارسال سوال جایگزین میشود.',
+ previewTitle: 'پیشنمایش پرس و جو',
+ queryTitle: 'محتوای پرس و جو',
+ queryPlaceholder: 'لطفاً متن درخواست را وارد کنید.',
+ run: 'اجرا',
+ },
+ result: 'متن خروجی',
+ datasetConfig: {
+ settingTitle: 'تنظیمات بازیابی',
+ knowledgeTip: 'روی دکمه "+" کلیک کنید تا دانش اضافه شود',
+ retrieveOneWay: {
+ title: 'بازیابی N به 1',
+ description: 'بر اساس نیت کاربر و توصیفات دانش، عامل بهترین دانش را برای پرس و جو به طور خودکار انتخاب میکند. بهترین برای برنامههایی با دانش محدود و مشخص.',
+ },
+ retrieveMultiWay: {
+ title: 'بازیابی چند مسیره',
+ description: 'بر اساس نیت کاربر، از تمام دانش پرس و جو میکند، متنهای مرتبط از منابع چندگانه بازیابی میکند و بهترین نتایج مطابقت با پرس و جوی کاربر را پس از مرتبسازی مجدد انتخاب میکند.',
+ },
+ rerankModelRequired: 'مدل مرتبسازی مجدد مورد نیاز است',
+ params: 'پارامترها',
+ top_k: 'Top K',
+ top_kTip: 'برای فیلتر کردن تکههایی که بیشترین شباهت به سوالات کاربر دارند استفاده میشود. سیستم همچنین به طور دینامیک مقدار Top K را بر اساس max_tokens مدل انتخاب شده تنظیم میکند.',
+ score_threshold: 'آستانه نمره',
+ score_thresholdTip: 'برای تنظیم آستانه شباهت برای فیلتر کردن تکهها استفاده میشود.',
+ retrieveChangeTip: 'تغییر حالت شاخص و حالت بازیابی ممکن است بر برنامههای مرتبط با این دانش تأثیر بگذارد.',
+ },
+ debugAsSingleModel: 'اشکالزدایی به عنوان مدل تک',
+ debugAsMultipleModel: 'اشکالزدایی به عنوان مدل چندگانه',
+ duplicateModel: 'تکراری',
+ publishAs: 'انتشار به عنوان',
+ assistantType: {
+ name: 'نوع دستیار',
+ chatAssistant: {
+ name: 'دستیار پایه',
+ description: 'ساخت دستیار مبتنی بر چت با استفاده از مدل زبان بزرگ',
+ },
+ agentAssistant: {
+ name: 'دستیار عامل',
+ description: 'ساخت یک عامل هوشمند که میتواند ابزارها را به طور خودکار برای تکمیل وظایف انتخاب کند',
+ },
+ },
+ agent: {
+ agentMode: 'حالت عامل',
+ agentModeDes: 'تنظیم نوع حالت استنتاج برای عامل',
+ agentModeType: {
+ ReACT: 'ReAct',
+ functionCall: 'فراخوانی تابع',
+ },
+ setting: {
+ name: 'تنظیمات عامل',
+ description: 'تنظیمات دستیار عامل به شما اجازه میدهد حالت عامل و ویژگیهای پیشرفته مانند پرسشهای ساخته شده را تنظیم کنید، فقط در نوع عامل موجود است.',
+ maximumIterations: {
+ name: 'حداکثر تکرارها',
+ description: 'محدود کردن تعداد تکرارهایی که دستیار عامل میتواند اجرا کند',
+ },
+ },
+ buildInPrompt: 'پرسشهای ساخته شده',
+ firstPrompt: 'اولین پرسش',
+ nextIteration: 'تکرار بعدی',
+ promptPlaceholder: 'پرسش خود را اینجا بنویسید',
+ tools: {
+ name: 'ابزارها',
+ description: 'استفاده از ابزارها میتواند قابلیتهای LLM را گسترش دهد، مانند جستجو در اینترنت یا انجام محاسبات علمی',
+ enabled: 'فعال',
+ },
+ },
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/app-log.ts b/web/i18n/fa-IR/app-log.ts
new file mode 100644
index 0000000000..80919c1c3a
--- /dev/null
+++ b/web/i18n/fa-IR/app-log.ts
@@ -0,0 +1,91 @@
+const translation = {
+ title: 'لاگها',
+ description: 'لاگها وضعیت اجرایی برنامه را ثبت میکنند، شامل ورودیهای کاربر و پاسخهای هوش مصنوعی.',
+ dateTimeFormat: 'MM/DD/YYYY hh:mm A',
+ table: {
+ header: {
+ time: 'زمان',
+ endUser: 'کاربر نهایی',
+ input: 'ورودی',
+ output: 'خروجی',
+ summary: 'عنوان',
+ messageCount: 'تعداد پیام',
+ userRate: 'امتیاز کاربر',
+ adminRate: 'امتیاز اپراتور',
+ startTime: 'زمان شروع',
+ status: 'وضعیت',
+ runtime: 'زمان اجرا',
+ tokens: 'توکنها',
+ user: 'کاربر نهایی',
+ version: 'نسخه',
+ },
+ pagination: {
+ previous: 'قبلی',
+ next: 'بعدی',
+ },
+ empty: {
+ noChat: 'هنوز مکالمهای وجود ندارد',
+ noOutput: 'خروجی وجود ندارد',
+ element: {
+ title: 'کسی هست؟',
+ content: 'در اینجا تعاملات بین کاربران نهایی و برنامههای هوش مصنوعی را مشاهده و حاشیهنویسی کنید تا دقت هوش مصنوعی بهبود یابد. میتوانید به اشتراک بگذارید یا برنامه وب را تست کنید و سپس به این صفحه برگردید.',
+ },
+ },
+ },
+ detail: {
+ time: 'زمان',
+ conversationId: 'شناسه مکالمه',
+ promptTemplate: 'قالب درخواست',
+ promptTemplateBeforeChat: 'قالب درخواست قبل از چت · به عنوان پیام سیستمی',
+ annotationTip: 'بهبودها توسط {{user}} علامتگذاری شده است',
+ timeConsuming: '',
+ second: 'ثانیه',
+ tokenCost: 'توکن مصرفی',
+ loading: 'در حال بارگذاری',
+ operation: {
+ like: 'پسندیدن',
+ dislike: 'نپسندیدن',
+ addAnnotation: 'اضافه کردن بهبود',
+ editAnnotation: 'ویرایش بهبود',
+ annotationPlaceholder: 'پاسخ مورد انتظاری که میخواهید هوش مصنوعی بدهد را وارد کنید، که میتواند برای بهبود مدل و کیفیت تولید متن در آینده استفاده شود.',
+ },
+ variables: 'متغیرها',
+ uploadImages: 'تصاویر آپلود شده',
+ },
+ filter: {
+ period: {
+ today: 'امروز',
+ last7days: '7 روز گذشته',
+ last4weeks: '4 هفته گذشته',
+ last3months: '3 ماه گذشته',
+ last12months: '12 ماه گذشته',
+ monthToDate: 'از ابتدای ماه تاکنون',
+ quarterToDate: 'از ابتدای فصل تاکنون',
+ yearToDate: 'از ابتدای سال تاکنون',
+ allTime: 'همه زمانها',
+ },
+ annotation: {
+ all: 'همه',
+ annotated: 'بهبودهای حاشیهنویسی شده ({{count}} آیتم)',
+ not_annotated: 'حاشیهنویسی نشده',
+ },
+ },
+ workflowTitle: 'لاگهای جریان کاری',
+ workflowSubtitle: 'لاگ عملیات خودکار را ثبت کرده است.',
+ runDetail: {
+ title: 'لاگ مکالمه',
+ workflowTitle: 'جزئیات لاگ',
+ },
+ promptLog: 'لاگ درخواست',
+ agentLog: 'لاگ عامل',
+ viewLog: 'مشاهده لاگ',
+ agentLogDetail: {
+ agentMode: 'حالت عامل',
+ toolUsed: 'ابزار استفاده شده',
+ iterations: 'تکرارها',
+ iteration: 'تکرار',
+ finalProcessing: 'پردازش نهایی',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/app-overview.ts b/web/i18n/fa-IR/app-overview.ts
new file mode 100644
index 0000000000..1bbd7a0283
--- /dev/null
+++ b/web/i18n/fa-IR/app-overview.ts
@@ -0,0 +1,156 @@
+const translation = {
+ welcome: {
+ firstStepTip: 'برای شروع،',
+ enterKeyTip: 'کلید API خود را در زیر وارد کنید',
+ getKeyTip: 'کلید API خود را از داشبورد OpenAI دریافت کنید',
+ placeholder: 'کلید API خود را وارد کنید (مثلاً sk-xxxx)',
+ },
+ apiKeyInfo: {
+ cloud: {
+ trial: {
+ title: 'شما از سهمیه آزمایشی {{providerName}} استفاده میکنید.',
+ description: 'سهمیه آزمایشی برای اهداف تست شما ارائه شده است. قبل از اینکه سهمیه آزمایشی تمام شود، لطفاً ارائهدهنده مدل خود را تنظیم کنید یا سهمیه اضافی خریداری کنید.',
+ },
+ exhausted: {
+ title: 'سهمیه آزمایشی شما تمام شده است، لطفاً کلید API خود را تنظیم کنید.',
+ description: 'شما سهمیه آزمایشی خود را مصرف کردهاید. لطفاً ارائهدهنده مدل خود را تنظیم کنید یا سهمیه اضافی خریداری کنید.',
+ },
+ },
+ selfHost: {
+ title: {
+ row1: 'برای شروع،',
+ row2: 'ابتدا ارائهدهنده مدل خود را تنظیم کنید.',
+ },
+ },
+ callTimes: 'تعداد تماسها',
+ usedToken: 'توکنهای مصرفشده',
+ setAPIBtn: 'برو به تنظیمات ارائهدهنده مدل',
+ tryCloud: 'یا نسخه ابری Dify با سهمیه رایگان را امتحان کنید',
+ },
+ overview: {
+ title: 'نمای کلی',
+ appInfo: {
+ explanation: 'برنامه وب AI آماده به کار',
+ accessibleAddress: 'آدرس عمومی',
+ preview: 'پیشنمایش',
+ regenerate: 'تولید مجدد',
+ regenerateNotice: 'آیا میخواهید آدرس عمومی را دوباره تولید کنید؟',
+ preUseReminder: 'لطفاً قبل از ادامه، WebApp را فعال کنید.',
+ settings: {
+ entry: 'تنظیمات',
+ title: 'تنظیمات WebApp',
+ webName: 'نام WebApp',
+ webDesc: 'توضیحات WebApp',
+ webDescTip: 'این متن در سمت مشتری نمایش داده میشود و راهنماییهای اولیه در مورد نحوه استفاده از برنامه را ارائه میدهد',
+ webDescPlaceholder: 'توضیحات WebApp را وارد کنید',
+ language: 'زبان',
+ workflow: {
+ title: 'مراحل کاری',
+ show: 'نمایش',
+ hide: 'مخفی کردن',
+ },
+ chatColorTheme: 'تم رنگی چت',
+ chatColorThemeDesc: 'تم رنگی چتبات را تنظیم کنید',
+ chatColorThemeInverted: 'معکوس',
+ invalidHexMessage: 'مقدار هگز نامعتبر',
+ more: {
+ entry: 'نمایش تنظیمات بیشتر',
+ copyright: 'حق نسخهبرداری',
+ copyRightPlaceholder: 'نام نویسنده یا سازمان را وارد کنید',
+ privacyPolicy: 'سیاست حفظ حریم خصوصی',
+ privacyPolicyPlaceholder: 'لینک سیاست حفظ حریم خصوصی را وارد کنید',
+ privacyPolicyTip: 'به بازدیدکنندگان کمک میکند تا بفهمند برنامه چه دادههایی را جمعآوری میکند، به سیاست حفظ حریم خصوصی Dify نگاه کنید Privacy Policy .',
+ customDisclaimer: 'سلب مسئولیت سفارشی',
+ customDisclaimerPlaceholder: 'متن سلب مسئولیت سفارشی را وارد کنید',
+ customDisclaimerTip: 'متن سلب مسئولیت سفارشی در سمت مشتری نمایش داده میشود و اطلاعات بیشتری درباره برنامه ارائه میدهد',
+ },
+ },
+ embedded: {
+ entry: 'جاسازی شده',
+ title: 'جاسازی در وبسایت',
+ explanation: 'روشهای جاسازی برنامه چت در وبسایت خود را انتخاب کنید',
+ iframe: 'برای افزودن برنامه چت در هرجای وبسایت خود، این iframe را به کد HTML خود اضافه کنید.',
+ scripts: 'برای افزودن برنامه چت به گوشه پایین سمت راست وبسایت خود، این کد را به HTML خود اضافه کنید.',
+ chromePlugin: 'نصب افزونه Chrome Chatbot Dify',
+ copied: 'کپی شد',
+ copy: 'کپی',
+ },
+ qrcode: {
+ title: 'کد QR لینک',
+ scan: 'اسکن برای اشتراکگذاری',
+ download: 'دانلود کد QR',
+ },
+ customize: {
+ way: 'راه',
+ entry: 'سفارشیسازی',
+ title: 'سفارشیسازی WebApp AI',
+ explanation: 'شما میتوانید ظاهر جلویی برنامه وب را برای برآوردن نیازهای سناریو و سبک خود سفارشی کنید.',
+ way1: {
+ name: 'کلاینت را شاخه کنید، آن را تغییر دهید و در Vercel مستقر کنید (توصیه میشود)',
+ step1: 'کلاینت را شاخه کنید و آن را تغییر دهید',
+ step1Tip: 'برای شاخه کردن کد منبع به حساب GitHub خود و تغییر کد اینجا کلیک کنید',
+ step1Operation: 'Dify-WebClient',
+ step2: 'استقرار در Vercel',
+ step2Tip: 'برای وارد کردن مخزن به Vercel و استقرار اینجا کلیک کنید',
+ step2Operation: 'وارد کردن مخزن',
+ step3: 'پیکربندی متغیرهای محیطی',
+ step3Tip: 'متغیرهای محیطی زیر را در Vercel اضافه کنید',
+ },
+ way2: {
+ name: 'نوشتن کد سمت کلاینت برای فراخوانی API و استقرار آن بر روی سرور',
+ operation: 'مستندات',
+ },
+ },
+ },
+ apiInfo: {
+ title: 'API سرویس بکاند',
+ explanation: 'به راحتی در برنامه خود یکپارچه میشود',
+ accessibleAddress: 'نقطه پایانی سرویس API',
+ doc: 'مرجع API',
+ },
+ status: {
+ running: 'در حال سرویسدهی',
+ disable: 'غیرفعال',
+ },
+ },
+ analysis: {
+ title: 'تحلیل',
+ ms: 'میلیثانیه',
+ tokenPS: 'توکن/ثانیه',
+ totalMessages: {
+ title: 'کل پیامها',
+ explanation: 'تعداد تعاملات روزانه با AI؛ مهندسی/اشکالزدایی دستورات مستثنی هستند.',
+ },
+ activeUsers: {
+ title: 'کاربران فعال',
+ explanation: 'کاربران منحصر به فردی که در پرسش و پاسخ با AI شرکت میکنند؛ مهندسی/اشکالزدایی دستورات مستثنی هستند.',
+ },
+ tokenUsage: {
+ title: 'استفاده از توکن',
+ explanation: 'مصرف روزانه توکنهای مدل زبان برای برنامه را نشان میدهد، که برای کنترل هزینهها مفید است.',
+ consumed: 'مصرفشده',
+ },
+ avgSessionInteractions: {
+ title: 'میانگین تعاملات جلسه',
+ explanation: 'تعداد تعاملات پیوسته کاربر-AI؛ برای برنامههای مبتنی بر گفتگو.',
+ },
+ avgUserInteractions: {
+ title: 'میانگین تعاملات کاربران',
+ explanation: 'تکرار استفاده روزانه کاربران را نشان میدهد. این معیار چسبندگی کاربران را نشان میدهد.',
+ },
+ userSatisfactionRate: {
+ title: 'نرخ رضایت کاربران',
+ explanation: 'تعداد لایکها به ازای هر ۱۰۰۰ پیام. این نشاندهنده نسبت پاسخهایی است که کاربران به شدت رضایت دارند.',
+ },
+ avgResponseTime: {
+ title: 'میانگین زمان پاسخ',
+ explanation: 'زمان (میلیثانیه) برای پردازش/پاسخ AI؛ برای برنامههای مبتنی بر متن.',
+ },
+ tps: {
+ title: 'سرعت خروجی توکن',
+ explanation: 'عملکرد مدل زبان بزرگ را اندازهگیری میکند. سرعت خروجی توکنهای مدل زبان بزرگ از آغاز درخواست تا تکمیل خروجی را بشمارید.',
+ },
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/app.ts b/web/i18n/fa-IR/app.ts
new file mode 100644
index 0000000000..8322ff5a14
--- /dev/null
+++ b/web/i18n/fa-IR/app.ts
@@ -0,0 +1,130 @@
+const translation = {
+ createApp: 'ایجاد برنامه',
+ types: {
+ all: 'همه',
+ chatbot: 'چتبات',
+ agent: 'نماینده',
+ workflow: 'گردش کار',
+ completion: 'تکمیل',
+ },
+ duplicate: 'تکرار',
+ duplicateTitle: 'تکرار برنامه',
+ export: 'صادر کردن DSL',
+ exportFailed: 'صادر کردن DSL ناموفق بود.',
+ importDSL: 'وارد کردن فایل DSL',
+ createFromConfigFile: 'ایجاد از فایل DSL',
+ importFromDSL: 'وارد کردن از DSL',
+ importFromDSLFile: 'از فایل DSL',
+ importFromDSLUrl: 'از URL',
+ importFromDSLUrlPlaceholder: 'لینک DSL را اینجا بچسبانید',
+ deleteAppConfirmTitle: 'آیا این برنامه حذف شود؟',
+ deleteAppConfirmContent:
+ 'حذف برنامه غیرقابل برگشت است. کاربران دیگر قادر به دسترسی به برنامه شما نخواهند بود و تمام تنظیمات و گزارشات درخواستها به صورت دائم حذف خواهند شد.',
+ appDeleted: 'برنامه حذف شد',
+ appDeleteFailed: 'حذف برنامه ناموفق بود',
+ join: 'پیوستن به جامعه',
+ communityIntro:
+ 'در کانالهای مختلف با اعضای تیم، مشارکتکنندگان و توسعهدهندگان بحث کنید.',
+ roadmap: 'نقشه راه ما را ببینید',
+ newApp: {
+ startFromBlank: 'ایجاد از خالی',
+ startFromTemplate: 'ایجاد از قالب',
+ captionAppType: 'چه نوع برنامهای میخواهید ایجاد کنید؟',
+ chatbotDescription: 'ساخت برنامهای مبتنی بر چت. این برنامه از قالب پرسش و پاسخ استفاده میکند و امکان چندین دور مکالمه مداوم را فراهم میکند.',
+ completionDescription: 'ساخت برنامهای که متن با کیفیت بالا بر اساس درخواستها تولید میکند، مانند تولید مقالات، خلاصهها، ترجمهها و بیشتر.',
+ completionWarning: 'این نوع برنامه دیگر پشتیبانی نمیشود.',
+ agentDescription: 'ساخت نماینده هوشمند که میتواند ابزارها را برای انجام وظایف به طور خودمختار انتخاب کند',
+ workflowDescription: 'ساخت برنامهای که متن با کیفیت بالا بر اساس گردش کار با درجه بالای سفارشیسازی تولید میکند. مناسب برای کاربران با تجربه.',
+ workflowWarning: 'در حال حاضر در نسخه بتا',
+ chatbotType: 'روش سازماندهی چتبات',
+ basic: 'اساسی',
+ basicTip: 'برای مبتدیان، میتوان بعداً به Chatflow تغییر داد',
+ basicFor: 'برای مبتدیان',
+ basicDescription: 'سازماندهی اساسی به شما اجازه میدهد تا یک برنامه چتبات را با تنظیمات ساده و بدون امکان تغییر درخواستهای داخلی سازماندهی کنید. مناسب برای مبتدیان است.',
+ advanced: 'Chatflow',
+ advancedFor: 'برای کاربران پیشرفته',
+ advancedDescription: 'سازماندهی گردش کار، چتباتها را به صورت گردش کار سازماندهی میکند و درجه بالایی از سفارشیسازی، از جمله امکان ویرایش درخواستهای داخلی را فراهم میکند. مناسب برای کاربران با تجربه است.',
+ captionName: 'آیکون و نام برنامه',
+ appNamePlaceholder: 'به برنامه خود یک نام بدهید',
+ captionDescription: 'توضیحات',
+ appDescriptionPlaceholder: 'توضیحات برنامه را وارد کنید',
+ useTemplate: 'استفاده از این قالب',
+ previewDemo: 'پیشنمایش دمو',
+ chatApp: 'دستیار',
+ chatAppIntro:
+ 'میخواهم یک برنامه مبتنی بر چت بسازم. این برنامه از قالب پرسش و پاسخ استفاده میکند و امکان چندین دور مکالمه مداوم را فراهم میکند.',
+ agentAssistant: 'دستیار نماینده جدید',
+ completeApp: 'تولید کننده متن',
+ completeAppIntro:
+ 'میخواهم برنامهای بسازم که متن با کیفیت بالا بر اساس درخواستها تولید کند، مانند تولید مقالات، خلاصهها، ترجمهها و بیشتر.',
+ showTemplates: 'میخواهم از یک قالب انتخاب کنم',
+ hideTemplates: 'بازگشت به انتخاب حالت',
+ Create: 'ایجاد',
+ Cancel: 'لغو',
+ nameNotEmpty: 'نام نمیتواند خالی باشد',
+ appTemplateNotSelected: 'لطفاً یک قالب انتخاب کنید',
+ appTypeRequired: 'لطفاً نوع برنامه را انتخاب کنید',
+ appCreated: 'برنامه ایجاد شد',
+ appCreateFailed: 'ایجاد برنامه ناموفق بود',
+ },
+ editApp: 'ویرایش اطلاعات',
+ editAppTitle: 'ویرایش اطلاعات برنامه',
+ editDone: 'اطلاعات برنامه بهروزرسانی شد',
+ editFailed: 'بهروزرسانی اطلاعات برنامه ناموفق بود',
+ emoji: {
+ ok: 'باشه',
+ cancel: 'لغو',
+ },
+ switch: 'تغییر به سازماندهی گردش کار',
+ switchTipStart: 'یک نسخه جدید از برنامه برای شما ایجاد خواهد شد و نسخه جدید به سازماندهی گردش کار تغییر خواهد کرد. نسخه جدید ',
+ switchTip: 'اجازه نمیدهد',
+ switchTipEnd: ' تغییر به سازماندهی اساسی بازگردد.',
+ switchLabel: 'نسخه برنامه که ایجاد میشود',
+ removeOriginal: 'حذف برنامه اصلی',
+ switchStart: 'شروع تغییر',
+ typeSelector: {
+ all: 'همه انواع',
+ chatbot: 'چتبات',
+ agent: 'نماینده',
+ workflow: 'گردش کار',
+ completion: 'تکمیل',
+ },
+ tracing: {
+ title: 'ردیابی عملکرد برنامه',
+ description: 'پیکربندی ارائهدهنده شخص ثالث LLMOps و ردیابی عملکرد برنامه.',
+ config: 'پیکربندی',
+ collapse: 'بستن',
+ expand: 'باز کردن',
+ tracing: 'ردیابی',
+ disabled: 'غیرفعال',
+ disabledTip: 'لطفاً ابتدا ارائهدهنده را پیکربندی کنید',
+ enabled: 'در حال خدمت',
+ tracingDescription: 'ثبت کامل متن اجرای برنامه، از جمله تماسهای LLM، متن، درخواستهای HTTP و بیشتر، به یک پلتفرم ردیابی شخص ثالث.',
+ configProviderTitle: {
+ configured: 'پیکربندی شده',
+ notConfigured: 'برای فعالسازی ردیابی ارائهدهنده را پیکربندی کنید',
+ moreProvider: 'ارائهدهندگان بیشتر',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'یک پلتفرم همهکاره برای هر مرحله از چرخه عمر برنامههای مبتنی بر LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'ردیابی، ارزیابی، مدیریت درخواستها و معیارها برای رفع اشکال و بهبود برنامه LLM شما.',
+ },
+ inUse: 'در حال استفاده',
+ configProvider: {
+ title: 'پیکربندی',
+ placeholder: 'کلید {{key}} خود را وارد کنید',
+ project: 'پروژه',
+ publicKey: 'کلید عمومی',
+ secretKey: 'کلید محرمانه',
+ viewDocsLink: 'مشاهده مستندات {{key}}',
+ removeConfirmTitle: 'حذف پیکربندی {{key}}؟',
+ removeConfirmContent: 'پیکربندی فعلی در حال استفاده است، حذف آن ویژگی ردیابی را غیرفعال خواهد کرد.',
+ },
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/billing.ts b/web/i18n/fa-IR/billing.ts
new file mode 100644
index 0000000000..480c31f742
--- /dev/null
+++ b/web/i18n/fa-IR/billing.ts
@@ -0,0 +1,118 @@
+const translation = {
+ currentPlan: 'طرح فعلی',
+ upgradeBtn: {
+ plain: 'ارتقاء طرح',
+ encourage: 'هم اکنون ارتقاء دهید',
+ encourageShort: 'ارتقاء دهید',
+ },
+ viewBilling: 'مدیریت صورتحسابها و اشتراکها',
+ buyPermissionDeniedTip: 'لطفاً با مدیر سازمان خود تماس بگیرید تا اشتراک تهیه کنید',
+ plansCommon: {
+ title: 'یک طرح مناسب برای خود انتخاب کنید',
+ yearlyTip: 'با اشتراک سالانه 2 ماه رایگان دریافت کنید!',
+ mostPopular: 'محبوبترین',
+ planRange: {
+ monthly: 'ماهانه',
+ yearly: 'سالانه',
+ },
+ month: 'ماه',
+ year: 'سال',
+ save: 'صرفهجویی کنید ',
+ free: 'رایگان',
+ currentPlan: 'طرح فعلی',
+ contractSales: 'تماس با فروش',
+ contractOwner: 'تماس با مدیر تیم',
+ startForFree: 'رایگان شروع کنید',
+ getStartedWith: 'شروع کنید با ',
+ contactSales: 'تماس با فروش',
+ talkToSales: 'صحبت با فروش',
+ modelProviders: 'ارائهدهندگان مدل',
+ teamMembers: 'اعضای تیم',
+ annotationQuota: 'سهمیه حاشیهنویسی',
+ buildApps: 'ساخت اپلیکیشنها',
+ vectorSpace: 'فضای وکتور',
+ vectorSpaceBillingTooltip: 'هر 1 مگابایت میتواند حدود 1.2 میلیون کاراکتر از دادههای وکتور شده را ذخیره کند (براساس تخمین با استفاده از OpenAI Embeddings، متفاوت بر اساس مدلها).',
+ vectorSpaceTooltip: 'فضای وکتور سیستم حافظه بلند مدت است که برای درک دادههای شما توسط LLMها مورد نیاز است.',
+ documentsUploadQuota: 'سهمیه بارگذاری مستندات',
+ documentProcessingPriority: 'اولویت پردازش مستندات',
+ documentProcessingPriorityTip: 'برای اولویت پردازش بالاتر مستندات، لطفاً طرح خود را ارتقاء دهید.',
+ documentProcessingPriorityUpgrade: 'دادههای بیشتری را با دقت بالاتر و سرعت بیشتر پردازش کنید.',
+ priority: {
+ 'standard': 'استاندارد',
+ 'priority': 'اولویت',
+ 'top-priority': 'اولویت بالا',
+ },
+ logsHistory: 'تاریخچه گزارشات',
+ customTools: 'ابزارهای سفارشی',
+ unavailable: 'غیرقابل دسترس',
+ days: 'روز',
+ unlimited: 'نامحدود',
+ support: 'پشتیبانی',
+ supportItems: {
+ communityForums: 'انجمنهای اجتماعی',
+ emailSupport: 'پشتیبانی ایمیل',
+ priorityEmail: 'پشتیبانی ایمیل و چت با اولویت',
+ logoChange: 'تغییر لوگو',
+ SSOAuthentication: 'تأیید هویت SSO',
+ personalizedSupport: 'پشتیبانی شخصیسازی شده',
+ dedicatedAPISupport: 'پشتیبانی API اختصاصی',
+ customIntegration: 'یکپارچهسازی و پشتیبانی سفارشی',
+ ragAPIRequest: 'درخواستهای API RAG',
+ bulkUpload: 'بارگذاری دستهای مستندات',
+ agentMode: 'حالت Agent',
+ workflow: 'جریان کار',
+ llmLoadingBalancing: 'توزیع بار LLM',
+ llmLoadingBalancingTooltip: 'اضافه کردن چندین کلید API به مدلها، به طور مؤثر از محدودیتهای نرخ API عبور میکند.',
+ },
+ comingSoon: 'به زودی',
+ member: 'عضو',
+ memberAfter: 'عضو',
+ messageRequest: {
+ title: 'اعتبارات پیام',
+ tooltip: 'سهمیههای فراخوانی پیام برای طرحهای مختلف با استفاده از مدلهای OpenAI (به جز gpt4). پیامهای بیش از حد محدودیت از کلید API OpenAI شما استفاده میکنند.',
+ },
+ annotatedResponse: {
+ title: 'محدودیتهای سهمیه حاشیهنویسی',
+ tooltip: 'ویرایش دستی و حاشیهنویسی پاسخها، قابلیتهای پرسش و پاسخ با کیفیت بالا و قابل تنظیم برای اپلیکیشنها را فراهم میکند. (فقط در اپلیکیشنهای چت اعمال میشود)',
+ },
+ ragAPIRequestTooltip: 'به تعداد درخواستهای API که فقط قابلیتهای پردازش پایگاه دانش Dify را فراخوانی میکنند اشاره دارد.',
+ receiptInfo: 'فقط صاحب تیم و مدیر تیم میتوانند اشتراک تهیه کنند و اطلاعات صورتحساب را مشاهده کنند',
+ },
+ plans: {
+ sandbox: {
+ name: 'محیط آزمایشی',
+ description: '200 بار آزمایش رایگان GPT',
+ includesTitle: 'شامل:',
+ },
+ professional: {
+ name: 'حرفهای',
+ description: 'برای افراد و تیمهای کوچک برای باز کردن قدرت بیشتر به طور مقرون به صرفه.',
+ includesTitle: 'همه چیز در طرح رایگان، به علاوه:',
+ },
+ team: {
+ name: 'تیم',
+ description: 'همکاری بدون محدودیت و لذت بردن از عملکرد برتر.',
+ includesTitle: 'همه چیز در طرح حرفهای، به علاوه:',
+ },
+ enterprise: {
+ name: 'سازمانی',
+ description: 'دریافت کاملترین قابلیتها و پشتیبانی برای سیستمهای بزرگ و بحرانی.',
+ includesTitle: 'همه چیز در طرح تیم، به علاوه:',
+ },
+ },
+ vectorSpace: {
+ fullTip: 'فضای وکتور پر است.',
+ fullSolution: 'طرح خود را ارتقاء دهید تا فضای بیشتری دریافت کنید.',
+ },
+ apps: {
+ fullTipLine1: 'طرح خود را ارتقاء دهید تا',
+ fullTipLine2: 'اپلیکیشنهای بیشتری بسازید.',
+ },
+ annotatedResponse: {
+ fullTipLine1: 'طرح خود را ارتقاء دهید تا',
+ fullTipLine2: 'مکالمات بیشتری را حاشیهنویسی کنید.',
+ quotaTitle: 'سهمیه پاسخ حاشیهنویسی',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/common.ts b/web/i18n/fa-IR/common.ts
new file mode 100644
index 0000000000..2b1c4647db
--- /dev/null
+++ b/web/i18n/fa-IR/common.ts
@@ -0,0 +1,572 @@
+const translation = {
+ api: {
+ success: 'موفقیت',
+ actionSuccess: 'عملیات موفق',
+ saved: 'ذخیره شد',
+ create: 'ایجاد شد',
+ remove: 'حذف شد',
+ },
+ operation: {
+ create: 'ایجاد',
+ confirm: 'تایید',
+ cancel: 'لغو',
+ clear: 'پاک کردن',
+ save: 'ذخیره',
+ saveAndEnable: 'ذخیره و فعال سازی',
+ edit: 'ویرایش',
+ add: 'افزودن',
+ added: 'اضافه شد',
+ refresh: 'شروع مجدد',
+ reset: 'بازنشانی',
+ search: 'جستجو',
+ change: 'تغییر',
+ remove: 'حذف',
+ send: 'ارسال',
+ copy: 'کپی',
+ lineBreak: 'خط جدید',
+ sure: 'مطمئن هستم',
+ download: 'دانلود',
+ delete: 'حذف',
+ settings: 'تنظیمات',
+ setup: 'راه اندازی',
+ getForFree: 'دریافت رایگان',
+ reload: 'بارگذاری مجدد',
+ ok: 'تایید',
+ log: 'گزارش',
+ learnMore: 'اطلاعات بیشتر',
+ params: 'پارامترها',
+ duplicate: 'تکرار',
+ rename: 'تغییر نام',
+ },
+ errorMsg: {
+ fieldRequired: '{{field}} الزامی است',
+ urlError: 'آدرس باید با http:// یا https:// شروع شود',
+ },
+ placeholder: {
+ input: 'لطفا وارد کنید',
+ select: 'لطفا انتخاب کنید',
+ },
+ voice: {
+ language: {
+ zhHans: 'چینی',
+ zhHant: 'چینی سنتی',
+ enUS: 'انگلیسی',
+ deDE: 'آلمانی',
+ frFR: 'فرانسوی',
+ esES: 'اسپانیایی',
+ itIT: 'ایتالیایی',
+ thTH: 'تایلندی',
+ idID: 'اندونزیایی',
+ jaJP: 'ژاپنی',
+ koKR: 'کرهای',
+ ptBR: 'پرتغالی',
+ ruRU: 'روسی',
+ ukUA: 'اوکراینی',
+ viVN: 'ویتنامی',
+ plPL: 'لهستانی',
+ },
+ },
+ unit: {
+ char: 'کاراکتر',
+ },
+ actionMsg: {
+ noModification: 'در حال حاضر تغییری وجود ندارد.',
+ modifiedSuccessfully: 'با موفقیت تغییر یافت',
+ modifiedUnsuccessfully: 'تغییر ناموفق بود',
+ copySuccessfully: 'با موفقیت کپی شد',
+ paySucceeded: 'پرداخت موفق',
+ payCancelled: 'پرداخت لغو شد',
+ generatedSuccessfully: 'با موفقیت تولید شد',
+ generatedUnsuccessfully: 'تولید ناموفق بود',
+ },
+ model: {
+ params: {
+ temperature: 'دما',
+ temperatureTip:
+ 'تصادفی بودن را کنترل میکند: کاهش آن منجر به تکمیلهای کمتر تصادفی میشود. با نزدیک شدن دما به صفر، مدل قطعی و تکراری میشود.',
+ top_p: 'بالاترین P',
+ top_pTip:
+ 'تنوع را از طریق نمونهگیری هسته کنترل میکند: 0.5 به این معنی است که نیمی از همه گزینههای وزندار احتمالی در نظر گرفته میشوند.',
+ presence_penalty: 'جریمه حضور',
+ presence_penaltyTip:
+ 'چقدر توکنهای جدید را بر اساس اینکه آیا در متن تاکنون ظاهر شدهاند جریمه کنیم.\nاحتمال مدل برای صحبت در مورد موضوعات جدید را افزایش میدهد.',
+ frequency_penalty: 'جریمه تکرار',
+ frequency_penaltyTip:
+ 'چقدر توکنهای جدید را بر اساس فراوانی موجود آنها در متن تاکنون جریمه کنیم.\nاحتمال تکرار دقیق همان خط توسط مدل را کاهش میدهد.',
+ max_tokens: 'حداکثر توکن',
+ max_tokensTip:
+ 'برای محدود کردن حداکثر طول پاسخ، در توکنها استفاده میشود. \nمقادیر بزرگتر ممکن است فضای باقیمانده برای کلمات راهنما، گزارشهای چت و دانش را محدود کند. \nتوصیه میشود آن را کمتر از دو سوم تنظیم کنید\ngpt-4-1106-preview، gpt-4-vision-preview حداکثر توکن (ورودی 128k خروجی 4k)',
+ maxTokenSettingTip: 'تنظیم حداکثر توکن شما بالاست، که ممکن است فضا را برای راهنماها، پرس و جوها و دادهها محدود کند. در نظر بگیرید آن را زیر 2/3 تنظیم کنید.',
+ setToCurrentModelMaxTokenTip: 'حداکثر توکن به 80٪ حداکثر توکن مدل فعلی {{maxToken}} بهروزرسانی شد.',
+ stop_sequences: 'توالیهای توقف',
+ stop_sequencesTip: 'حداکثر چهار توالی که API تولید توکنهای بیشتر را متوقف میکند. متن برگردانده شده شامل توالی توقف نخواهد بود.',
+ stop_sequencesPlaceholder: 'توالی را وارد کنید و Tab را فشار دهید',
+ },
+ tone: {
+ Creative: 'خلاقانه',
+ Balanced: 'متعادل',
+ Precise: 'دقیق',
+ Custom: 'سفارشی',
+ },
+ addMoreModel: 'برای افزودن مدلهای بیشتر به تنظیمات بروید',
+ },
+ menus: {
+ status: 'بتا',
+ explore: 'کاوش',
+ apps: 'استودیو',
+ plugins: 'افزونهها',
+ pluginsTips: 'افزونههای شخص ثالث را ادغام کنید یا افزونههای هوش مصنوعی سازگار با ChatGPT ایجاد کنید.',
+ datasets: 'دانش',
+ datasetsTips: 'به زودی: دادههای متنی خود را وارد کنید یا از طریق Webhook دادهها را در زمان واقعی برای بهبود زمینه LLM بنویسید.',
+ newApp: 'برنامه جدید',
+ newDataset: 'ایجاد دانش',
+ tools: 'ابزارها',
+ },
+ userProfile: {
+ settings: 'تنظیمات',
+ emailSupport: 'پشتیبانی ایمیل',
+ workspace: 'فضای کاری',
+ createWorkspace: 'ایجاد فضای کاری',
+ helpCenter: 'راهنما',
+ roadmapAndFeedback: 'بازخورد',
+ community: 'انجمن',
+ about: 'درباره',
+ logout: 'خروج',
+ },
+ settings: {
+ accountGroup: 'حساب کاربری',
+ workplaceGroup: 'فضای کاری',
+ account: 'حساب من',
+ members: 'اعضا',
+ billing: 'صورتحساب',
+ integrations: 'ادغامها',
+ language: 'زبان',
+ provider: 'ارائه دهنده مدل',
+ dataSource: 'منبع داده',
+ plugin: 'افزونهها',
+ apiBasedExtension: 'توسعه مبتنی بر API',
+ },
+ account: {
+ avatar: 'آواتار',
+ name: 'نام',
+ email: 'ایمیل',
+ password: 'رمز عبور',
+ passwordTip: 'اگر نمیخواهید از کدهای ورود موقت استفاده کنید، میتوانید یک رمز عبور دائمی تنظیم کنید',
+ setPassword: 'تنظیم رمز عبور',
+ resetPassword: 'بازنشانی رمز عبور',
+ currentPassword: 'رمز عبور فعلی',
+ newPassword: 'رمز عبور جدید',
+ confirmPassword: 'تأیید رمز عبور',
+ notEqual: 'دو رمز عبور متفاوت هستند.',
+ langGeniusAccount: 'حساب Dify',
+ langGeniusAccountTip: 'حساب Dify شما و دادههای کاربری مرتبط.',
+ editName: 'ویرایش نام',
+ showAppLength: 'نمایش {{length}} برنامه',
+ delete: 'حذف حساب کاربری',
+ deleteTip: 'حذف حساب کاربری شما تمام دادههای شما را به طور دائمی پاک میکند و قابل بازیابی نیست.',
+ deleteConfirmTip: 'برای تأیید، لطفاً موارد زیر را از ایمیل ثبتنام شده خود به این آدرس ارسال کنید ',
+ },
+ members: {
+ team: 'تیم',
+ invite: 'افزودن',
+ name: 'نام',
+ lastActive: 'آخرین فعالیت',
+ role: 'نقشها',
+ pending: 'در انتظار...',
+ owner: 'مالک',
+ admin: 'مدیر',
+ adminTip: 'میتواند برنامهها را بسازد و تنظیمات تیم را مدیریت کند',
+ normal: 'عادی',
+ normalTip: 'فقط میتواند از برنامهها استفاده کند، نمیتواند برنامه بسازد',
+ builder: 'سازنده',
+ builderTip: 'میتواند برنامههای خود را بسازد و ویرایش کند',
+ editor: 'ویرایشگر',
+ editorTip: 'میتواند برنامهها را بسازد و ویرایش کند',
+ datasetOperator: 'مدیر دانش',
+ datasetOperatorTip: 'فقط میتواند پایگاه دانش را مدیریت کند',
+ inviteTeamMember: 'افزودن عضو تیم',
+ inviteTeamMemberTip: 'آنها میتوانند پس از ورود به سیستم، مستقیماً به دادههای تیم شما دسترسی پیدا کنند.',
+ email: 'ایمیل',
+ emailInvalid: 'فرمت ایمیل نامعتبر است',
+ emailPlaceholder: 'لطفاً ایمیلها را وارد کنید',
+ sendInvite: 'ارسال دعوت',
+ invitedAsRole: 'به عنوان کاربر {{role}} دعوت شده',
+ invitationSent: 'دعوتنامه ارسال شد',
+ invitationSentTip: 'دعوتنامه ارسال شد و آنها میتوانند وارد Dify شوند تا به دادههای تیم شما دسترسی پیدا کنند.',
+ invitationLink: 'لینک دعوت',
+ failedinvitationEmails: 'کاربران زیر با موفقیت دعوت نشدند',
+ ok: 'تایید',
+ removeFromTeam: 'حذف از تیم',
+ removeFromTeamTip: 'دسترسی تیم را حذف میکند',
+ setAdmin: 'تنظیم به عنوان مدیر',
+ setMember: 'تنظیم به عنوان عضو عادی',
+ setBuilder: 'تنظیم به عنوان سازنده',
+ setEditor: 'تنظیم به عنوان ویرایشگر',
+ disinvite: 'لغو دعوت',
+ deleteMember: 'حذف عضو',
+ you: '(شما)',
+ },
+ integrations: {
+ connected: 'متصل شده',
+ google: 'گوگل',
+ googleAccount: 'ورود با حساب گوگل',
+ github: 'گیتهاب',
+ githubAccount: 'ورود با حساب گیتهاب',
+ connect: 'اتصال',
+ },
+ language: {
+ displayLanguage: 'زبان نمایش',
+ timezone: 'منطقه زمانی',
+ },
+ provider: {
+ apiKey: 'کلید API',
+ enterYourKey: 'کلید API خود را اینجا وارد کنید',
+ invalidKey: 'کلید API OpenAI نامعتبر است',
+ validatedError: 'اعتبارسنجی ناموفق بود: ',
+ validating: 'در حال اعتبارسنجی کلید...',
+ saveFailed: 'ذخیره کلید API ناموفق بود',
+ apiKeyExceedBill: 'این کلید API سهمیه موجود ندارد، لطفاً بخوانید',
+ addKey: 'افزودن کلید',
+ comingSoon: 'به زودی',
+ editKey: 'ویرایش',
+ invalidApiKey: 'کلید API نامعتبر',
+ azure: {
+ apiBase: 'پایه API',
+ apiBasePlaceholder: 'آدرس پایه API نقطه پایانی Azure OpenAI شما.',
+ apiKey: 'کلید API',
+ apiKeyPlaceholder: 'کلید API خود را اینجا وارد کنید',
+ helpTip: 'آشنایی با سرویس Azure OpenAI',
+ },
+ openaiHosted: {
+ openaiHosted: 'OpenAI میزبانی شده',
+ onTrial: 'در حال آزمایش',
+ exhausted: 'سهمیه تمام شده',
+ desc: 'سرویس میزبانی OpenAI ارائه شده توسط Dify به شما اجازه میدهد از مدلهایی مانند GPT-3.5 استفاده کنید. قبل از اتمام سهمیه آزمایشی خود، باید سایر ارائهدهندگان مدل را تنظیم کنید.',
+ callTimes: 'تعداد فراخوانی',
+ usedUp: 'سهمیه آزمایشی تمام شده است. ارائهدهنده مدل خود را اضافه کنید.',
+ useYourModel: 'در حال حاضر از ارائهدهنده مدل خود استفاده میکنید.',
+ close: 'بستن',
+ },
+ anthropicHosted: {
+ anthropicHosted: 'Anthropic Claude',
+ onTrial: 'در حال آزمایش',
+ exhausted: 'سهمیه تمام شده',
+ desc: 'مدل قدرتمند که در طیف گستردهای از وظایف از گفتگوی پیشرفته و تولید محتوای خلاقانه تا دستورالعملهای دقیق عالی عمل میکند.',
+ callTimes: 'تعداد فراخوانی',
+ usedUp: 'سهمیه آزمایشی تمام شده است. ارائهدهنده مدل خود را اضافه کنید.',
+ useYourModel: 'در حال حاضر از ارائهدهنده مدل خود استفاده میکنید.',
+ close: 'بستن',
+ },
+ anthropic: {
+ using: 'قابلیت تعبیه از این استفاده میکند',
+ enableTip: 'برای فعالسازی مدل Anthropic، ابتدا باید به OpenAI یا سرویس Azure OpenAI متصل شوید.',
+ notEnabled: 'فعال نشده',
+ keyFrom: 'کلید API خود را از Anthropic دریافت کنید',
+ },
+ encrypted: {
+ front: 'کلید API شما با استفاده از فناوری',
+ back: ' رمزگذاری و ذخیره خواهد شد.',
+ },
+ },
+ modelProvider: {
+ notConfigured: 'مدل سیستم هنوز به طور کامل پیکربندی نشده است و برخی از عملکردها ممکن است در دسترس نباشند.',
+ systemModelSettings: 'تنظیمات مدل سیستم',
+ systemModelSettingsLink: 'چرا تنظیم مدل سیستم ضروری است؟',
+ selectModel: 'مدل خود را انتخاب کنید',
+ setupModelFirst: 'لطفاً ابتدا مدل خود را تنظیم کنید',
+ systemReasoningModel: {
+ key: 'مدل استدلال سیستم',
+ tip: 'مدل استنتاج پیشفرض را برای ایجاد برنامهها تنظیم کنید. ویژگیهایی مانند تولید نام گفتگو و پیشنهاد سوال بعدی نیز از مدل استنتاج پیشفرض استفاده خواهند کرد.',
+ },
+ embeddingModel: {
+ key: 'مدل تعبیه',
+ tip: 'مدل پیشفرض را برای پردازش تعبیه اسناد دانش تنظیم کنید. هر دو بازیابی و وارد کردن دانش از این مدل تعبیه برای پردازش برداری استفاده میکنند. تغییر باعث ناسازگاری بُعد برداری بین دانش وارد شده و سوال میشود که منجر به شکست بازیابی میشود. برای جلوگیری از شکست بازیابی، لطفاً این مدل را به دلخواه تغییر ندهید.',
+ required: 'مدل تعبیه الزامی است',
+ },
+ speechToTextModel: {
+ key: 'مدل تبدیل گفتار به متن',
+ tip: 'مدل پیشفرض را برای ورودی گفتار به متن در مکالمه تنظیم کنید.',
+ },
+ ttsModel: {
+ key: 'مدل تبدیل متن به گفتار',
+ tip: 'مدل پیشفرض را برای ورودی متن به گفتار در مکالمه تنظیم کنید.',
+ },
+ rerankModel: {
+ key: 'مدل رتبهبندی مجدد',
+ tip: 'مدل رتبهبندی مجدد، لیست اسناد کاندید را بر اساس تطابق معنایی با پرسش کاربر مرتب میکند و نتایج رتبهبندی معنایی را بهبود میبخشد',
+ },
+ apiKey: 'کلید API',
+ quota: 'سهمیه',
+ searchModel: 'جستجوی مدل',
+ noModelFound: 'هیچ مدلی برای {{model}} یافت نشد',
+ models: 'مدلها',
+ showMoreModelProvider: 'نمایش ارائهدهندگان مدل بیشتر',
+ selector: {
+ tip: 'این مدل حذف شده است. لطفاً یک مدل اضافه کنید یا مدل دیگری را انتخاب کنید.',
+ emptyTip: 'هیچ مدل موجودی وجود ندارد',
+ emptySetting: 'لطفاً به تنظیمات بروید تا پیکربندی کنید',
+ rerankTip: 'لطفاً مدل رتبهبندی مجدد را تنظیم کنید',
+ },
+ card: {
+ quota: 'سهمیه',
+ onTrial: 'در حال آزمایش',
+ paid: 'پرداخت شده',
+ quotaExhausted: 'سهمیه تمام شده',
+ callTimes: 'تعداد فراخوانی',
+ tokens: 'توکنها',
+ buyQuota: 'خرید سهمیه',
+ priorityUse: 'استفاده با اولویت',
+ removeKey: 'حذف کلید API',
+ tip: 'اولویت به سهمیه پرداخت شده داده میشود. سهمیه آزمایشی پس از اتمام سهمیه پرداخت شده استفاده خواهد شد.',
+ },
+ item: {
+ deleteDesc: '{{modelName}} به عنوان مدلهای استدلال سیستم استفاده میشوند. برخی از عملکردها پس از حذف در دسترس نخواهند بود. لطفاً تأیید کنید.',
+ freeQuota: 'سهمیه رایگان',
+ },
+ addApiKey: 'کلید API خود را اضافه کنید',
+ invalidApiKey: 'کلید API نامعتبر',
+ encrypted: {
+ front: 'کلید API شما با استفاده از فناوری',
+ back: ' رمزگذاری و ذخیره خواهد شد.',
+ },
+ freeQuota: {
+ howToEarn: 'چگونه کسب کنیم',
+ },
+ addMoreModelProvider: 'افزودن ارائهدهنده مدل بیشتر',
+ addModel: 'افزودن مدل',
+ modelsNum: '{{num}} مدل',
+ showModels: 'نمایش مدلها',
+ showModelsNum: 'نمایش {{num}} مدل',
+ collapse: 'جمع کردن',
+ config: 'پیکربندی',
+ modelAndParameters: 'مدل و پارامترها',
+ model: 'مدل',
+ featureSupported: '{{feature}} پشتیبانی میشود',
+ callTimes: 'تعداد فراخوانی',
+ credits: 'اعتبار پیام',
+ buyQuota: 'خرید سهمیه',
+ getFreeTokens: 'دریافت توکنهای رایگان',
+ priorityUsing: 'استفاده با اولویت',
+ deprecated: 'منسوخ شده',
+ confirmDelete: 'تأیید حذف؟',
+ quotaTip: 'توکنهای رایگان باقیمانده در دسترس',
+ loadPresets: 'بارگیری تنظیمات از پیش تعیین شده',
+ parameters: 'پارامترها',
+ loadBalancing: 'تعادل بار',
+ loadBalancingDescription: 'کاهش فشار با چندین مجموعه اعتبارنامه.',
+ loadBalancingHeadline: 'تعادل بار',
+ configLoadBalancing: 'پیکربندی تعادل بار',
+ modelHasBeenDeprecated: 'این مدل منسوخ شده است',
+ providerManaged: 'مدیریت شده توسط ارائهدهنده',
+ providerManagedDescription: 'استفاده از مجموعه واحد اعتبارنامه ارائه شده توسط ارائهدهنده مدل.',
+ defaultConfig: 'پیکربندی پیشفرض',
+ apiKeyStatusNormal: 'وضعیت کلید API عادی است',
+ apiKeyRateLimit: 'محدودیت نرخ به دست آمد، پس از {{seconds}} ثانیه در دسترس خواهد بود',
+ addConfig: 'افزودن پیکربندی',
+ editConfig: 'ویرایش پیکربندی',
+ loadBalancingLeastKeyWarning: 'برای فعال کردن تعادل بار، حداقل 2 کلید باید فعال باشند.',
+ loadBalancingInfo: 'به طور پیشفرض، تعادل بار از استراتژی Round-robin استفاده میکند. اگر محدودیت نرخ فعال شود، یک دوره خنک شدن 1 دقیقهای اعمال خواهد شد.',
+ upgradeForLoadBalancing: 'برای فعال کردن تعادل بار، طرح خود را ارتقا دهید.',
+ },
+ dataSource: {
+ add: 'افزودن منبع داده',
+ connect: 'اتصال',
+ configure: 'پیکربندی',
+ notion: {
+ title: 'نوشن',
+ description: 'استفاده از نوشن به عنوان منبع داده برای دانش.',
+ connectedWorkspace: 'فضای کاری متصل',
+ addWorkspace: 'افزودن فضای کاری',
+ connected: 'متصل شده',
+ disconnected: 'قطع شده',
+ changeAuthorizedPages: 'تغییر صفحات مجاز',
+ pagesAuthorized: 'صفحات مجاز',
+ sync: 'همگامسازی',
+ remove: 'حذف',
+ selector: {
+ pageSelected: 'صفحات انتخاب شده',
+ searchPages: 'جستجوی صفحات...',
+ noSearchResult: 'نتیجه جستجویی یافت نشد',
+ addPages: 'افزودن صفحات',
+ preview: 'پیشنمایش',
+ },
+ },
+ website: {
+ title: 'وبسایت',
+ description: 'وارد کردن محتوا از وبسایتها با استفاده از خزنده وب.',
+ with: 'با',
+ configuredCrawlers: 'خزندههای پیکربندی شده',
+ active: 'فعال',
+ inactive: 'غیرفعال',
+ },
+ },
+ plugin: {
+ serpapi: {
+ apiKey: 'کلید API',
+ apiKeyPlaceholder: 'کلید API خود را وارد کنید',
+ keyFrom: 'کلید SerpAPI خود را از صفحه حساب SerpAPI دریافت کنید',
+ },
+ },
+ apiBasedExtension: {
+ title: 'افزونههای مبتنی بر API مدیریت متمرکز API را فراهم میکنند و پیکربندی را برای استفاده آسان در برنامههای Dify ساده میکنند.',
+ link: 'نحوه توسعه افزونه API خود را بیاموزید.',
+ linkUrl: 'https://docs.dify.ai/features/extension/api_based_extension',
+ add: 'افزودن افزونه API',
+ selector: {
+ title: 'افزونه API',
+ placeholder: 'لطفاً افزونه API را انتخاب کنید',
+ manage: 'مدیریت افزونه API',
+ },
+ modal: {
+ title: 'افزودن افزونه API',
+ editTitle: 'ویرایش افزونه API',
+ name: {
+ title: 'نام',
+ placeholder: 'لطفاً نام را وارد کنید',
+ },
+ apiEndpoint: {
+ title: 'نقطه پایانی API',
+ placeholder: 'لطفاً نقطه پایانی API را وارد کنید',
+ },
+ apiKey: {
+ title: 'کلید API',
+ placeholder: 'لطفاً کلید API را وارد کنید',
+ lengthError: 'طول کلید API نمیتواند کمتر از ۵ کاراکتر باشد',
+ },
+ },
+ type: 'نوع',
+ },
+ about: {
+ changeLog: 'تغییرات',
+ updateNow: 'بهروزرسانی اکنون',
+ nowAvailable: 'Dify {{version}} اکنون در دسترس است.',
+ latestAvailable: 'Dify {{version}} آخرین نسخه در دسترس است.',
+ },
+ appMenus: {
+ overview: 'نظارت',
+ promptEng: 'هماهنگسازی',
+ apiAccess: 'دسترسی API',
+ logAndAnn: 'گزارشها و اعلانات',
+ logs: 'گزارشها',
+ },
+ environment: {
+ testing: 'آزمایشی',
+ development: 'توسعه',
+ },
+ appModes: {
+ completionApp: 'تولیدکننده متن',
+ chatApp: 'برنامه چت',
+ },
+ datasetMenus: {
+ documents: 'اسناد',
+ hitTesting: 'آزمایش بازیابی',
+ settings: 'تنظیمات',
+ emptyTip: 'دانش مرتبط نشده است، لطفاً به برنامه یا افزونه بروید تا ارتباط را کامل کنید.',
+ viewDoc: 'مشاهده مستندات',
+ relatedApp: 'برنامههای مرتبط',
+ },
+ voiceInput: {
+ speaking: 'اکنون صحبت کنید...',
+ converting: 'در حال تبدیل به متن...',
+ notAllow: 'میکروفون مجاز نیست',
+ },
+ modelName: {
+ 'gpt-3.5-turbo': 'جیپیتی-۳.۵-توربو',
+ 'gpt-3.5-turbo-16k': 'جیپیتی-۳.۵-توربو-۱۶کا',
+ 'gpt-4': 'جیپیتی-۴',
+ 'gpt-4-32k': 'جیپیتی-۴-۳۲کا',
+ 'text-davinci-003': 'متن-داوینچی-۰۰۳',
+ 'text-embedding-ada-002': 'متن-تعبیه-آدا-۰۰۲',
+ 'whisper-1': 'ویسپر-۱',
+ 'claude-instant-1': 'کلاود-فوری',
+ 'claude-2': 'کلاود-۲',
+ },
+ chat: {
+ renameConversation: 'تغییر نام مکالمه',
+ conversationName: 'نام مکالمه',
+ conversationNamePlaceholder: 'لطفاً نام مکالمه را وارد کنید',
+ conversationNameCanNotEmpty: 'نام مکالمه الزامی است',
+ citation: {
+ title: 'استنادها',
+ linkToDataset: 'پیوند به دانش',
+ characters: 'کاراکترها:',
+ hitCount: 'تعداد بازیابی:',
+ vectorHash: 'هش بردار:',
+ hitScore: 'امتیاز بازیابی:',
+ },
+ },
+ promptEditor: {
+ placeholder: 'دستور خود را اینجا بنویسید، «{» را وارد کنید تا یک متغیر درج کنید، «/» را وارد کنید تا یک بلوک محتوای دستور درج کنید',
+ context: {
+ item: {
+ title: 'زمینه',
+ desc: 'درج الگوی زمینه',
+ },
+ modal: {
+ title: '{{num}} دانش در زمینه',
+ add: 'افزودن زمینه',
+ footer: 'شما میتوانید زمینهها را در بخش زمینه در زیر مدیریت کنید.',
+ },
+ },
+ history: {
+ item: {
+ title: 'تاریخچه مکالمه',
+ desc: 'درج الگوی پیام تاریخی',
+ },
+ modal: {
+ title: 'مثال',
+ user: 'سلام',
+ assistant: 'سلام! چطور میتوانم امروز به شما کمک کنم؟',
+ edit: 'ویرایش نامهای نقش مکالمه',
+ },
+ },
+ variable: {
+ item: {
+ title: 'متغیرها و ابزارهای خارجی',
+ desc: 'درج متغیرها و ابزارهای خارجی',
+ },
+ outputToolDisabledItem: {
+ title: 'متغیرها',
+ desc: 'درج متغیرها',
+ },
+ modal: {
+ add: 'متغیر جدید',
+ addTool: 'ابزار جدید',
+ },
+ },
+ query: {
+ item: {
+ title: 'پرسوجو',
+ desc: 'درج الگوی پرسوجوی کاربر',
+ },
+ },
+ existed: 'در حال حاضر در دستور وجود دارد',
+ },
+ imageUploader: {
+ uploadFromComputer: 'بارگذاری از کامپیوتر',
+ uploadFromComputerReadError: 'خواندن تصویر ناموفق بود، لطفاً دوباره تلاش کنید.',
+ uploadFromComputerUploadError: 'بارگذاری تصویر ناموفق بود، لطفاً دوباره بارگذاری کنید.',
+ uploadFromComputerLimit: 'بارگذاری تصاویر نمیتواند از {{size}} مگابایت بیشتر باشد',
+ pasteImageLink: 'پیوند تصویر را بچسبانید',
+ pasteImageLinkInputPlaceholder: 'پیوند تصویر را اینجا بچسبانید',
+ pasteImageLinkInvalid: 'پیوند تصویر نامعتبر',
+ imageUpload: 'بارگذاری تصویر',
+ },
+ tag: {
+ placeholder: 'همه برچسبها',
+ addNew: 'افزودن برچسب جدید',
+ noTag: 'بدون برچسب',
+ noTagYet: 'هنوز برچسبی وجود ندارد',
+ addTag: 'افزودن برچسبها',
+ editTag: 'ویرایش برچسبها',
+ manageTags: 'مدیریت برچسبها',
+ selectorPlaceholder: 'برای جستجو یا ایجاد تایپ کنید',
+ create: 'ایجاد',
+ delete: 'حذف برچسب',
+ deleteTip: 'برچسب در حال استفاده است، آیا آن را حذف میکنید؟',
+ created: 'برچسب با موفقیت ایجاد شد',
+ failed: 'ایجاد برچسب ناموفق بود',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/custom.ts b/web/i18n/fa-IR/custom.ts
new file mode 100644
index 0000000000..bcf3f26150
--- /dev/null
+++ b/web/i18n/fa-IR/custom.ts
@@ -0,0 +1,30 @@
+const translation = {
+ custom: 'سفارشی سازی',
+ upgradeTip: {
+ prefix: 'طرح خود را ارتقا دهید به',
+ suffix: 'تا برند خود را سفارشی کنید.',
+ },
+ webapp: {
+ title: 'سفارشی سازی برند وب اپ',
+ removeBrand: 'حذف "Powered by Dify"',
+ changeLogo: 'تغییر تصویر برند "Powered by"',
+ changeLogoTip: 'فرمت SVG یا PNG با حداقل اندازه 40x40px',
+ },
+ app: {
+ title: 'سفارشی سازی برند هدر اپلیکیشن',
+ changeLogoTip: 'فرمت SVG یا PNG با حداقل اندازه 80x80px',
+ },
+ upload: 'بارگذاری',
+ uploading: 'در حال بارگذاری',
+ uploadedFail: 'بارگذاری تصویر ناموفق بود، لطفاً دوباره بارگذاری کنید.',
+ change: 'تغییر',
+ apply: 'اعمال',
+ restore: 'بازگرداندن به پیشفرضها',
+ customize: {
+ contactUs: ' با ما تماس بگیرید ',
+ prefix: 'برای سفارشیسازی لوگوی برند در اپلیکیشن، لطفاً',
+ suffix: 'برای ارتقا به نسخه Enterprise.',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/dataset-creation.ts b/web/i18n/fa-IR/dataset-creation.ts
new file mode 100644
index 0000000000..f8483af140
--- /dev/null
+++ b/web/i18n/fa-IR/dataset-creation.ts
@@ -0,0 +1,161 @@
+const translation = {
+ steps: {
+ header: {
+ creation: 'ایجاد دانش',
+ update: 'افزودن داده',
+ },
+ one: 'انتخاب منبع داده',
+ two: 'پیشپردازش و پاکسازی متن',
+ three: 'اجرا و پایان',
+ },
+ error: {
+ unavailable: 'این دانش در دسترس نیست',
+ },
+ firecrawl: {
+ configFirecrawl: 'پیکربندی fireFirecrawl',
+ apiKeyPlaceholder: 'کلید API از firecrawl.dev',
+ getApiKeyLinkText: 'کلید API خود را از firecrawl.dev دریافت کنید',
+ },
+ stepOne: {
+ filePreview: 'پیشنمایش فایل',
+ pagePreview: 'پیشنمایش صفحه',
+ dataSourceType: {
+ file: 'وارد کردن از فایل',
+ notion: 'همگامسازی از Notion',
+ web: 'همگامسازی از وبسایت',
+ },
+ uploader: {
+ title: 'بارگذاری فایل',
+ button: 'کشیدن و رها کردن فایل، یا',
+ browse: 'مرور',
+ tip: 'پشتیبانی از {{supportTypes}}. حداکثر {{size}}MB هر کدام.',
+ validation: {
+ typeError: 'نوع فایل پشتیبانی نمیشود',
+ size: 'فایل خیلی بزرگ است. حداکثر {{size}}MB',
+ count: 'چندین فایل پشتیبانی نمیشود',
+ filesNumber: 'شما به حد مجاز بارگذاری دستهای {{filesNumber}} رسیدهاید.',
+ },
+ cancel: 'لغو',
+ change: 'تغییر',
+ failed: 'بارگذاری ناموفق بود',
+ },
+ notionSyncTitle: 'Notion متصل نیست',
+ notionSyncTip: 'برای همگامسازی با Notion، ابتدا باید اتصال به Notion برقرار شود.',
+ connect: 'رفتن به اتصال',
+ button: 'بعدی',
+ emptyDatasetCreation: 'میخواهم یک دانش خالی ایجاد کنم',
+ modal: {
+ title: 'ایجاد یک دانش خالی',
+ tip: 'یک دانش خالی هیچ سندی نخواهد داشت و شما میتوانید هر زمان اسناد را بارگذاری کنید.',
+ input: 'نام دانش',
+ placeholder: 'لطفاً وارد کنید',
+ nameNotEmpty: 'نام نمیتواند خالی باشد',
+ nameLengthInvaild: 'نام باید بین 1 تا 40 کاراکتر باشد',
+ cancelButton: 'لغو',
+ confirmButton: 'ایجاد',
+ failed: 'ایجاد ناموفق بود',
+ },
+ website: {
+ fireCrawlNotConfigured: 'Firecrawl پیکربندی نشده است',
+ fireCrawlNotConfiguredDescription: 'برای استفاده از Firecrawl با کلید API پیکربندی کنید.',
+ configure: 'پیکربندی',
+ run: 'اجرا',
+ firecrawlTitle: 'استخراج محتوای وب با fireFirecrawl',
+ firecrawlDoc: 'مستندات Firecrawl',
+ firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website ',
+ options: 'گزینهها',
+ crawlSubPage: 'خزش صفحات فرعی',
+ limit: 'محدودیت',
+ maxDepth: 'حداکثر عمق',
+ excludePaths: 'مسیرهای مستثنی',
+ includeOnlyPaths: 'فقط مسیرهای شامل',
+ extractOnlyMainContent: 'فقط محتوای اصلی را استخراج کنید (بدون هدرها، ناوبریها، پاورقیها و غیره)',
+ exceptionErrorTitle: 'یک استثنا در حین اجرای کار Firecrawl رخ داد:',
+ unknownError: 'خطای ناشناخته',
+ totalPageScraped: 'کل صفحات خراشیده شده:',
+ selectAll: 'انتخاب همه',
+ resetAll: 'بازنشانی همه',
+ scrapTimeInfo: 'در مجموع {{total}} صفحه در {{time}} ثانیه خراشیده شد',
+ preview: 'پیشنمایش',
+ maxDepthTooltip: 'حداکثر عمق برای خزش نسبت به URL وارد شده. عمق 0 فقط صفحه URL وارد شده را خراش میدهد، عمق 1 URL و همه چیز بعد از URL وارد شده + یک / را خراش میدهد، و غیره.',
+ },
+ },
+ stepTwo: {
+ segmentation: 'تنظیمات بخشبندی',
+ auto: 'خودکار',
+ autoDescription: 'به طور خودکار قوانین بخشبندی و پیشپردازش را تنظیم کنید. به کاربران ناآشنا توصیه میشود این گزینه را انتخاب کنند.',
+ custom: 'سفارشی',
+ customDescription: 'قوانین بخشبندی، طول بخشها و قوانین پیشپردازش را سفارشی کنید، و غیره.',
+ separator: 'شناسه بخش',
+ separatorPlaceholder: 'برای مثال، خط جدید (\\\\n) یا جداکننده خاص (مانند "***")',
+ maxLength: 'حداکثر طول بخش',
+ overlap: 'همپوشانی بخش',
+ overlapTip: 'تنظیم همپوشانی بخش میتواند ارتباط معنایی بین آنها را حفظ کند و اثر بازیابی را افزایش دهد. توصیه میشود 10%-25% از حداکثر اندازه بخش تنظیم شود.',
+ overlapCheck: 'همپوشانی بخش نباید بزرگتر از طول حداکثر بخش باشد',
+ rules: 'قوانین پیشپردازش متن',
+ removeExtraSpaces: 'جایگزینی فضاهای متوالی، خطوط جدید و تبها',
+ removeUrlEmails: 'حذف همه URLها و آدرسهای ایمیل',
+ removeStopwords: 'حذف کلمات توقف مانند "a"، "an"، "the"',
+ preview: 'تأیید و پیشنمایش',
+ reset: 'بازنشانی',
+ indexMode: 'حالت شاخص',
+ qualified: 'کیفیت بالا',
+ recommend: 'توصیه شده',
+ qualifiedTip: 'رابط جاسازی سیستم پیشفرض را برای پردازش فراخوانی کنید تا دقت بالاتری هنگام پرسش کاربران فراهم شود.',
+ warning: 'لطفاً ابتدا کلید API ارائهدهنده مدل را تنظیم کنید.',
+ click: 'رفتن به تنظیمات',
+ economical: 'اقتصادی',
+ economicalTip: 'از موتورهای برداری آفلاین، شاخصهای کلیدواژه و غیره استفاده کنید تا دقت را بدون صرف توکنها کاهش دهید',
+ QATitle: 'بخشبندی در قالب پرسش و پاسخ',
+ QATip: 'فعال کردن این گزینه توکنهای بیشتری مصرف خواهد کرد',
+ QALanguage: 'بخشبندی با استفاده از',
+ emstimateCost: 'برآورد',
+ emstimateSegment: 'بخشهای برآورد شده',
+ segmentCount: 'بخشها',
+ calculating: 'در حال محاسبه...',
+ fileSource: 'پیشپردازش اسناد',
+ notionSource: 'پیشپردازش صفحات',
+ websiteSource: 'پیشپردازش وبسایت',
+ other: 'و سایر',
+ fileUnit: ' فایلها',
+ notionUnit: ' صفحات',
+ webpageUnit: ' صفحات',
+ previousStep: 'مرحله قبلی',
+ nextStep: 'ذخیره و پردازش',
+ save: 'ذخیره و پردازش',
+ cancel: 'لغو',
+ sideTipTitle: 'چرا بخشبندی و پیشپردازش؟',
+ sideTipP1: 'هنگام پردازش دادههای متنی، بخشبندی و پاکسازی دو مرحله مهم پیشپردازش هستند.',
+ sideTipP2: 'بخشبندی متن طولانی را به پاراگرافها تقسیم میکند تا مدلها بهتر بتوانند آن را درک کنند. این کیفیت و ارتباط نتایج مدل را بهبود میبخشد.',
+ sideTipP3: 'پاکسازی کاراکترها و فرمتهای غیرضروری را حذف میکند و دانش را پاکتر و آسانتر برای تجزیه میکند.',
+ sideTipP4: 'بخشبندی و پاکسازی مناسب عملکرد مدل را بهبود میبخشد و نتایج دقیقتر و ارزشمندتری ارائه میدهد.',
+ previewTitle: 'پیشنمایش',
+ previewTitleButton: 'پیشنمایش',
+ previewButton: 'تغییر به قالب پرسش و پاسخ',
+ previewSwitchTipStart: 'پیشنمایش بخش فعلی در قالب متن است، تغییر به پیشنمایش قالب پرسش و پاسخ',
+ previewSwitchTipEnd: ' توکنهای اضافی مصرف خواهد کرد',
+ characters: 'کاراکترها',
+ indexSettedTip: 'برای تغییر روش شاخص، لطفاً به',
+ retrivalSettedTip: 'برای تغییر روش شاخص، لطفاً به',
+ datasetSettingLink: 'تنظیمات دانش بروید.',
+ },
+ stepThree: {
+ creationTitle: ' دانش ایجاد شد',
+ creationContent: 'ما به طور خودکار نام دانش را تعیین کردیم، شما میتوانید هر زمان آن را تغییر دهید',
+ label: 'نام دانش',
+ additionTitle: ' سند بارگذاری شد',
+ additionP1: 'سند به دانش بارگذاری شده است',
+ additionP2: '، میتوانید آن را در لیست اسناد دانش پیدا کنید.',
+ stop: 'توقف پردازش',
+ resume: 'ادامه پردازش',
+ navTo: 'رفتن به سند',
+ sideTipTitle: 'بعدی چیست',
+ sideTipContent: 'پس از اتمام فهرستبندی سند، دانش میتواند به عنوان زمینه در برنامه یکپارچه شود، میتوانید تنظیمات زمینه را در صفحه ارکستراسیون درخواست پیدا کنید. همچنین میتوانید آن را به عنوان یک افزونه فهرستبندی مستقل ChatGPT برای انتشار ایجاد کنید.',
+ modelTitle: 'آیا مطمئن هستید که میخواهید جاسازی را متوقف کنید؟',
+ modelContent: 'اگر نیاز به ادامه پردازش بعداً دارید، از جایی که متوقف شدهاید ادامه خواهید داد.',
+ modelButtonConfirm: 'تأیید',
+ modelButtonCancel: 'لغو',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/dataset-documents.ts b/web/i18n/fa-IR/dataset-documents.ts
new file mode 100644
index 0000000000..f136353c7b
--- /dev/null
+++ b/web/i18n/fa-IR/dataset-documents.ts
@@ -0,0 +1,351 @@
+const translation = {
+ list: {
+ title: 'اسناد',
+ desc: 'تمامی فایلهای دانش در اینجا نمایش داده میشوند و کل دانش میتواند به ارجاعات Dify متصل شود یا از طریق افزونه چت ایندکس شود.',
+ addFile: 'اضافه کردن فایل',
+ addPages: 'اضافه کردن صفحات',
+ addUrl: 'اضافه کردن URL',
+ table: {
+ header: {
+ fileName: 'نام فایل',
+ words: 'کلمات',
+ hitCount: 'تعداد بازیابی',
+ uploadTime: 'زمان بارگذاری',
+ status: 'وضعیت',
+ action: 'اقدام',
+ },
+ rename: 'تغییر نام',
+ name: 'نام',
+ },
+ action: {
+ uploadFile: 'بارگذاری فایل جدید',
+ settings: 'تنظیمات بخشبندی',
+ addButton: 'اضافه کردن قطعه',
+ add: 'اضافه کردن یک قطعه',
+ batchAdd: 'افزودن گروهی',
+ archive: 'بایگانی',
+ unarchive: 'خارج کردن از بایگانی',
+ delete: 'حذف',
+ enableWarning: 'فایل بایگانی شده نمیتواند فعال شود',
+ sync: 'همگامسازی',
+ },
+ index: {
+ enable: 'فعال کردن',
+ disable: 'غیرفعال کردن',
+ all: 'همه',
+ enableTip: 'فایل میتواند ایندکس شود',
+ disableTip: 'فایل نمیتواند ایندکس شود',
+ },
+ status: {
+ queuing: 'در صف',
+ indexing: 'ایندکسسازی',
+ paused: 'متوقف شده',
+ error: 'خطا',
+ available: 'موجود',
+ enabled: 'فعال شده',
+ disabled: 'غیرفعال شده',
+ archived: 'بایگانی شده',
+ },
+ empty: {
+ title: 'هنوز هیچ سندی وجود ندارد',
+ upload: {
+ tip: 'شما میتوانید فایلها را بارگذاری کنید، از وبسایت همگامسازی کنید، یا از برنامههای وبی مانند Notion، GitHub و غیره.',
+ },
+ sync: {
+ tip: 'Dify بهطور دورهای فایلها را از Notion شما دانلود و پردازش را کامل میکند.',
+ },
+ },
+ delete: {
+ title: 'آیا مطمئن هستید که حذف شود؟',
+ content: 'اگر بعداً نیاز به ادامه پردازش داشتید، از همان جایی که مانده بودید ادامه میدهید',
+ },
+ batchModal: {
+ title: 'افزودن گروهی قطعات',
+ csvUploadTitle: 'فایل CSV خود را اینجا بکشید و رها کنید، یا ',
+ browse: 'مرور کنید',
+ tip: 'فایل CSV باید به ساختار زیر مطابقت داشته باشد:',
+ question: 'سؤال',
+ answer: 'پاسخ',
+ contentTitle: 'محتوای قطعه',
+ content: 'محتوا',
+ template: 'الگو را از اینجا دانلود کنید',
+ cancel: 'لغو',
+ run: 'اجرای گروهی',
+ runError: 'اجرای گروهی ناموفق بود',
+ processing: 'در حال پردازش گروهی',
+ completed: 'واردات کامل شد',
+ error: 'خطای واردات',
+ ok: 'تأیید',
+ },
+ },
+ metadata: {
+ title: 'اطلاعات متا',
+ desc: 'برچسبگذاری متادیتا برای اسناد به هوش مصنوعی اجازه میدهد تا به موقع به آنها دسترسی پیدا کند و منبع ارجاعات را برای کاربران آشکار کند.',
+ dateTimeFormat: 'D MMMM YYYY hh:mm A',
+ docTypeSelectTitle: 'لطفاً یک نوع سند را انتخاب کنید',
+ docTypeChangeTitle: 'تغییر نوع سند',
+ docTypeSelectWarning: 'اگر نوع سند تغییر کند، متادیتای پر شده فعلی دیگر حفظ نخواهد شد',
+ firstMetaAction: 'بزن بریم',
+ placeholder: {
+ add: 'اضافه کردن ',
+ select: 'انتخاب ',
+ },
+ source: {
+ upload_file: 'بارگذاری فایل',
+ notion: 'همگامسازی از Notion',
+ github: 'همگامسازی از Github',
+ },
+ type: {
+ book: 'کتاب',
+ webPage: 'صفحه وب',
+ paper: 'مقاله',
+ socialMediaPost: 'پست شبکههای اجتماعی',
+ personalDocument: 'سند شخصی',
+ businessDocument: 'سند تجاری',
+ IMChat: 'چت IM',
+ wikipediaEntry: 'ورودی ویکیپدیا',
+ notion: 'همگامسازی از Notion',
+ github: 'همگامسازی از Github',
+ technicalParameters: 'پارامترهای فنی',
+ },
+ field: {
+ processRule: {
+ processDoc: 'پردازش سند',
+ segmentRule: 'قانون قطعهبندی',
+ segmentLength: 'طول قطعات',
+ processClean: 'تمیز کردن پردازش متن',
+ },
+ book: {
+ title: 'عنوان',
+ language: 'زبان',
+ author: 'نویسنده',
+ publisher: 'ناشر',
+ publicationDate: 'تاریخ انتشار',
+ ISBN: 'ISBN',
+ category: 'دستهبندی',
+ },
+ webPage: {
+ title: 'عنوان',
+ url: 'URL',
+ language: 'زبان',
+ authorPublisher: 'نویسنده/ناشر',
+ publishDate: 'تاریخ انتشار',
+ topicsKeywords: 'موضوعات/کلیدواژهها',
+ description: 'توضیحات',
+ },
+ paper: {
+ title: 'عنوان',
+ language: 'زبان',
+ author: 'نویسنده',
+ publishDate: 'تاریخ انتشار',
+ journalConferenceName: 'نام ژورنال/کنفرانس',
+ volumeIssuePage: 'جلد/شماره/صفحه',
+ DOI: 'DOI',
+ topicsKeywords: 'موضوعات/کلیدواژهها',
+ abstract: 'چکیده',
+ },
+ socialMediaPost: {
+ platform: 'پلتفرم',
+ authorUsername: 'نویسنده/نام کاربری',
+ publishDate: 'تاریخ انتشار',
+ postURL: 'URL پست',
+ topicsTags: 'موضوعات/برچسبها',
+ },
+ personalDocument: {
+ title: 'عنوان',
+ author: 'نویسنده',
+ creationDate: 'تاریخ ایجاد',
+ lastModifiedDate: 'تاریخ آخرین ویرایش',
+ documentType: 'نوع سند',
+ tagsCategory: 'برچسبها/دستهبندی',
+ },
+ businessDocument: {
+ title: 'عنوان',
+ author: 'نویسنده',
+ creationDate: 'تاریخ ایجاد',
+ lastModifiedDate: 'تاریخ آخرین ویرایش',
+ documentType: 'نوع سند',
+ departmentTeam: 'دپارتمان/تیم',
+ },
+ IMChat: {
+ chatPlatform: 'پلتفرم چت',
+ chatPartiesGroupName: 'طرفین چت/نام گروه',
+ participants: 'شرکتکنندگان',
+ startDate: 'تاریخ شروع',
+ endDate: 'تاریخ پایان',
+ topicsKeywords: 'موضوعات/کلیدواژهها',
+ fileType: 'نوع فایل',
+ },
+ wikipediaEntry: {
+ title: 'عنوان',
+ language: 'زبان',
+ webpageURL: 'URL صفحه وب',
+ editorContributor: 'ویرایشگر/همکار',
+ lastEditDate: 'تاریخ آخرین ویرایش',
+ summaryIntroduction: 'خلاصه/مقدمه',
+ },
+ notion: {
+ title: 'عنوان',
+ language: 'زبان',
+ author: 'نویسنده',
+ createdTime: 'زمان ایجاد',
+ lastModifiedTime: 'زمان آخرین ویرایش',
+ url: 'URL',
+ tag: 'برچسب',
+ description: 'توضیحات',
+ },
+ github: {
+ repoName: 'نام مخزن',
+ repoDesc: 'توضیحات مخزن',
+ repoOwner: 'مالک مخزن',
+ fileName: 'نام فایل',
+ filePath: 'مسیر فایل',
+ programmingLang: 'زبان برنامهنویسی',
+ url: 'URL',
+ license: 'مجوز',
+ lastCommitTime: 'زمان آخرین کامیت',
+ lastCommitAuthor: 'نویسنده آخرین کامیت',
+ },
+ originInfo: {
+ originalFilename: 'نام فایل اصلی',
+ originalFileSize: 'اندازه فایل اصلی',
+ uploadDate: 'تاریخ بارگذاری',
+ lastUpdateDate: 'تاریخ آخرین بروزرسانی',
+ source: 'منبع',
+ },
+ technicalParameters: {
+ segmentSpecification: 'مشخصات قطعات',
+ segmentLength: 'طول قطعات',
+ avgParagraphLength: 'طول متوسط پاراگراف',
+ paragraphs: 'پاراگرافها',
+ hitCount: 'تعداد بازیابی',
+ embeddingTime: 'زمان جاسازی',
+ embeddedSpend: 'هزینه جاسازی',
+ },
+ },
+ languageMap: {
+ zh: 'چینی',
+ en: 'انگلیسی',
+ es: 'اسپانیایی',
+ fr: 'فرانسوی',
+ de: 'آلمانی',
+ ja: 'ژاپنی',
+ ko: 'کرهای',
+ ru: 'روسی',
+ ar: 'عربی',
+ pt: 'پرتغالی',
+ it: 'ایتالیایی',
+ nl: 'هلندی',
+ pl: 'لهستانی',
+ sv: 'سوئدی',
+ tr: 'ترکی',
+ he: 'عبری',
+ hi: 'هندی',
+ da: 'دانمارکی',
+ fi: 'فنلاندی',
+ no: 'نروژی',
+ hu: 'مجاری',
+ el: 'یونانی',
+ cs: 'چکی',
+ th: 'تایلندی',
+ id: 'اندونزیایی',
+ },
+ categoryMap: {
+ book: {
+ fiction: 'داستان',
+ biography: 'زندگینامه',
+ history: 'تاریخ',
+ science: 'علم',
+ technology: 'فناوری',
+ education: 'آموزش',
+ philosophy: 'فلسفه',
+ religion: 'دین',
+ socialSciences: 'علوم اجتماعی',
+ art: 'هنر',
+ travel: 'سفر',
+ health: 'سلامت',
+ selfHelp: 'خودیاری',
+ businessEconomics: 'اقتصاد کسبوکار',
+ cooking: 'آشپزی',
+ childrenYoungAdults: 'کودکان و نوجوانان',
+ comicsGraphicNovels: 'کمیکها و رمانهای گرافیکی',
+ poetry: 'شعر',
+ drama: 'نمایشنامه',
+ other: 'دیگر',
+ },
+ personalDoc: {
+ notes: 'یادداشتها',
+ blogDraft: 'پیشنویس وبلاگ',
+ diary: 'دفتر خاطرات',
+ researchReport: 'گزارش پژوهش',
+ bookExcerpt: 'گزیده کتاب',
+ schedule: 'برنامهریزی',
+ list: 'فهرست',
+ projectOverview: 'نمای کلی پروژه',
+ photoCollection: 'مجموعه عکس',
+ creativeWriting: 'نوشته خلاقانه',
+ codeSnippet: 'قطعه کد',
+ designDraft: 'پیشنویس طراحی',
+ personalResume: 'رزومه شخصی',
+ other: 'دیگر',
+ },
+ businessDoc: {
+ meetingMinutes: 'صورتجلسه',
+ researchReport: 'گزارش پژوهش',
+ proposal: 'پیشنهاد',
+ employeeHandbook: 'راهنمای کارمند',
+ trainingMaterials: 'مواد آموزشی',
+ requirementsDocument: 'سند نیازمندیها',
+ designDocument: 'سند طراحی',
+ productSpecification: 'مشخصات محصول',
+ financialReport: 'گزارش مالی',
+ marketAnalysis: 'تحلیل بازار',
+ projectPlan: 'طرح پروژه',
+ teamStructure: 'ساختار تیم',
+ policiesProcedures: 'سیاستها و رویهها',
+ contractsAgreements: 'قراردادها و توافقنامهها',
+ emailCorrespondence: 'مکاتبات ایمیلی',
+ other: 'دیگر',
+ },
+ },
+ },
+ embedding: {
+ processing: 'در حال پردازش جاسازی...',
+ paused: 'جاسازی متوقف شده',
+ completed: 'جاسازی کامل شد',
+ error: 'خطای جاسازی',
+ docName: 'پیشپردازش سند',
+ mode: 'قانون بخشبندی',
+ segmentLength: 'طول قطعات',
+ textCleaning: 'پیشتعریف و تمیز کردن متن',
+ segments: 'پاراگرافها',
+ highQuality: 'حالت با کیفیت بالا',
+ economy: 'حالت اقتصادی',
+ estimate: 'مصرف تخمینی',
+ stop: 'توقف پردازش',
+ resume: 'ادامه پردازش',
+ automatic: 'خودکار',
+ custom: 'سفارشی',
+ previewTip: 'پیشنمایش پاراگراف پس از اتمام جاسازی در دسترس خواهد بود',
+ },
+ segment: {
+ paragraphs: 'پاراگرافها',
+ keywords: 'کلیدواژهها',
+ addKeyWord: 'اضافه کردن کلیدواژه',
+ keywordError: 'حداکثر طول کلیدواژه ۲۰ کاراکتر است',
+ characters: 'کاراکترها',
+ hitCount: 'تعداد بازیابی',
+ vectorHash: 'هش برداری: ',
+ questionPlaceholder: 'سؤال را اینجا اضافه کنید',
+ questionEmpty: 'سؤال نمیتواند خالی باشد',
+ answerPlaceholder: 'پاسخ را اینجا اضافه کنید',
+ answerEmpty: 'پاسخ نمیتواند خالی باشد',
+ contentPlaceholder: 'محتوا را اینجا اضافه کنید',
+ contentEmpty: 'محتوا نمیتواند خالی باشد',
+ newTextSegment: 'قطعه متن جدید',
+ newQaSegment: 'قطعه پرسش و پاسخ جدید',
+ delete: 'حذف این قطعه؟',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/dataset-hit-testing.ts b/web/i18n/fa-IR/dataset-hit-testing.ts
new file mode 100644
index 0000000000..75b97c7abc
--- /dev/null
+++ b/web/i18n/fa-IR/dataset-hit-testing.ts
@@ -0,0 +1,28 @@
+const translation = {
+ title: 'آزمون بازیابی',
+ desc: 'آزمون اثرگذاری دانش بر اساس متن پرسش داده شده.',
+ dateTimeFormat: 'MM/DD/YYYY hh:mm A',
+ recents: 'اخیرها',
+ table: {
+ header: {
+ source: 'منبع',
+ text: 'متن',
+ time: 'زمان',
+ },
+ },
+ input: {
+ title: 'متن منبع',
+ placeholder: 'لطفاً یک متن وارد کنید، یک جمله کوتاه خبری توصیه میشود.',
+ countWarning: 'تا ۲۰۰ کاراکتر.',
+ indexWarning: 'فقط دانش با کیفیت بالا.',
+ testing: 'در حال آزمون',
+ },
+ hit: {
+ title: 'پاراگرافهای بازیابی',
+ emptyTip: 'نتایج آزمون بازیابی اینجا نمایش داده میشوند',
+ },
+ noRecentTip: 'اینجا نتیجه پرسش اخیر وجود ندارد',
+ viewChart: 'مشاهده نمودار بُرداری',
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/dataset-settings.ts b/web/i18n/fa-IR/dataset-settings.ts
new file mode 100644
index 0000000000..a9c9bd8110
--- /dev/null
+++ b/web/i18n/fa-IR/dataset-settings.ts
@@ -0,0 +1,35 @@
+const translation = {
+ title: 'تنظیمات دانش',
+ desc: 'اینجا میتوانید ویژگیها و روشهای کاری دانش را تغییر دهید.',
+ form: {
+ name: 'نام دانش',
+ namePlaceholder: 'لطفاً نام دانش را وارد کنید',
+ nameError: 'نام نمیتواند خالی باشد',
+ desc: 'توضیحات دانش',
+ descInfo: 'لطفاً یک توضیح متنی واضح بنویسید تا محتوای دانش را مشخص کند. این توضیحات به عنوان مبنایی برای تطبیق هنگام انتخاب از چندین دانش برای استنتاج استفاده خواهد شد.',
+ descPlaceholder: 'توضیح دهید که در این دانش چه چیزی وجود دارد. توضیحات دقیق به هوش مصنوعی اجازه میدهد تا به موقع به محتوای دانش دسترسی پیدا کند. اگر خالی باشد، دیفی از استراتژی پیشفرض استفاده خواهد کرد.',
+ descWrite: 'یاد بگیرید چگونه یک توضیح دانش خوب بنویسید.',
+ permissions: 'مجوزها',
+ permissionsOnlyMe: 'فقط من',
+ permissionsAllMember: 'تمام اعضای تیم',
+ permissionsInvitedMembers: 'برخی از اعضای تیم',
+ me: '(شما)',
+ indexMethod: 'روش نمایهسازی',
+ indexMethodHighQuality: 'کیفیت بالا',
+ indexMethodHighQualityTip: 'مدل تعبیه را برای پردازش فراخوانی کنید تا دقت بالاتری هنگام جستجوی کاربران فراهم شود.',
+ indexMethodEconomy: 'اقتصادی',
+ indexMethodEconomyTip: 'استفاده از موتورهای برداری آفلاین، شاخصهای کلمات کلیدی و غیره برای کاهش دقت بدون صرف توکنها',
+ embeddingModel: 'مدل تعبیه',
+ embeddingModelTip: 'برای تغییر مدل تعبیه، لطفاً به ',
+ embeddingModelTipLink: 'تنظیمات',
+ retrievalSetting: {
+ title: 'تنظیمات بازیابی',
+ learnMore: 'بیشتر بدانید',
+ description: ' درباره روش بازیابی.',
+ longDescription: ' درباره روش بازیابی، میتوانید در هر زمانی در تنظیمات دانش این را تغییر دهید.',
+ },
+ save: 'ذخیره',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/dataset.ts b/web/i18n/fa-IR/dataset.ts
new file mode 100644
index 0000000000..30036dc68f
--- /dev/null
+++ b/web/i18n/fa-IR/dataset.ts
@@ -0,0 +1,76 @@
+const translation = {
+ knowledge: 'دانش',
+ documentCount: ' سند',
+ wordCount: ' هزار کلمه',
+ appCount: ' برنامههای متصل',
+ createDataset: 'ایجاد دانش',
+ createDatasetIntro: 'دادههای متنی خود را وارد کنید یا از طریق Webhook در زمان واقعی برای بهبود زمینه LLM بنویسید.',
+ deleteDatasetConfirmTitle: 'حذف این دانش؟',
+ deleteDatasetConfirmContent:
+ 'حذف دانش غیر قابل برگشت است. کاربران دیگر نمیتوانند به دانش شما دسترسی پیدا کنند و تمام تنظیمات درخواست و گزارشها به طور دائم حذف خواهند شد.',
+ datasetUsedByApp: 'دانش توسط برخی برنامهها استفاده میشود. برنامهها دیگر نمیتوانند از این دانش استفاده کنند و تمام تنظیمات درخواست و گزارشها به طور دائم حذف خواهند شد.',
+ datasetDeleted: 'دانش حذف شد',
+ datasetDeleteFailed: 'حذف دانش ناموفق بود',
+ didYouKnow: 'آیا میدانستید؟',
+ intro1: 'دانش میتواند در برنامه Dify ',
+ intro2: 'به عنوان یک زمینه',
+ intro3: 'ادغام شود',
+ intro4: 'یا میتواند ',
+ intro5: 'به عنوان یک افزونه مستقل ChatGPT برای انتشار',
+ intro6: 'ایجاد شود',
+ unavailable: 'در دسترس نیست',
+ unavailableTip: 'مدل جاسازی در دسترس نیست، نیاز است مدل جاسازی پیشفرض پیکربندی شود',
+ datasets: 'دانش',
+ datasetsApi: 'دسترسی API',
+ retrieval: {
+ semantic_search: {
+ title: 'جستجوی برداری',
+ description: 'تولید جاسازیهای جستجو و جستجوی بخش متنی که بیشترین شباهت را به نمایش برداری آن دارد.',
+ },
+ full_text_search: {
+ title: 'جستجوی متن کامل',
+ description: 'فهرست کردن تمام اصطلاحات در سند، به کاربران اجازه میدهد هر اصطلاحی را جستجو کنند و بخش متنی مربوط به آن اصطلاحات را بازیابی کنند.',
+ },
+ hybrid_search: {
+ title: 'جستجوی هیبریدی',
+ description: 'جستجوی متن کامل و برداری را همزمان اجرا میکند، دوباره رتبهبندی میکند تا بهترین تطابق برای درخواست کاربر انتخاب شود. کاربران میتوانند وزنها را تنظیم کنند یا به یک مدل دوباره رتبهبندی تنظیم کنند.',
+ recommend: 'توصیه',
+ },
+ invertedIndex: {
+ title: 'فهرست معکوس',
+ description: 'فهرست معکوس یک ساختار برای بازیابی کارآمد است. توسط اصطلاحات سازماندهی شده، هر اصطلاح به اسناد یا صفحات وب حاوی آن اشاره میکند.',
+ },
+ change: 'تغییر',
+ changeRetrievalMethod: 'تغییر روش بازیابی',
+ },
+ docsFailedNotice: 'اسناد نتوانستند فهرستبندی شوند',
+ retry: 'تلاش مجدد',
+ indexingTechnique: {
+ high_quality: 'HQ',
+ economy: 'ECO',
+ },
+ indexingMethod: {
+ semantic_search: 'برداری',
+ full_text_search: 'متن کامل',
+ hybrid_search: 'هیبریدی',
+ invertedIndex: 'معکوس',
+ },
+ mixtureHighQualityAndEconomicTip: 'مدل دوباره رتبهبندی برای ترکیب پایگاههای دانش با کیفیت بالا و اقتصادی لازم است.',
+ inconsistentEmbeddingModelTip: 'مدل دوباره رتبهبندی لازم است اگر مدلهای جاسازی پایگاههای دانش انتخابی ناسازگار باشند.',
+ retrievalSettings: 'تنظیمات بازیابی',
+ rerankSettings: 'تنظیمات دوباره رتبهبندی',
+ weightedScore: {
+ title: 'امتیاز وزنی',
+ description: 'با تنظیم وزنهای اختصاص داده شده، این استراتژی دوباره رتبهبندی تعیین میکند که آیا اولویت با تطابق معنایی یا کلمات کلیدی است.',
+ semanticFirst: 'اولویت معنایی',
+ keywordFirst: 'اولویت کلمه کلیدی',
+ customized: 'سفارشیسازی شده',
+ semantic: 'معنایی',
+ keyword: 'کلمه کلیدی',
+ },
+ nTo1RetrievalLegacy: 'بازیابی N-to-1 از سپتامبر به طور رسمی منسوخ خواهد شد. توصیه میشود از بازیابی چند مسیر جدید استفاده کنید تا نتایج بهتری بدست آورید.',
+ nTo1RetrievalLegacyLink: 'بیشتر بدانید',
+ nTo1RetrievalLegacyLinkText: ' بازیابی N-to-1 از سپتامبر به طور رسمی منسوخ خواهد شد.',
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/explore.ts b/web/i18n/fa-IR/explore.ts
new file mode 100644
index 0000000000..404a9f2593
--- /dev/null
+++ b/web/i18n/fa-IR/explore.ts
@@ -0,0 +1,41 @@
+const translation = {
+ title: 'کاوش',
+ sidebar: {
+ discovery: 'کشف',
+ chat: 'چت',
+ workspace: 'فضای کاری',
+ action: {
+ pin: 'سنجاق کردن',
+ unpin: 'برداشتن سنجاق',
+ rename: 'تغییر نام',
+ delete: 'حذف',
+ },
+ delete: {
+ title: 'حذف برنامه',
+ content: 'آیا مطمئن هستید که میخواهید این برنامه را حذف کنید؟',
+ },
+ },
+ apps: {
+ title: 'کاوش برنامهها توسط دیفی',
+ description: 'از این برنامههای قالبی بلافاصله استفاده کنید یا برنامههای خود را بر اساس این قالبها سفارشی کنید.',
+ allCategories: 'پیشنهاد شده',
+ },
+ appCard: {
+ addToWorkspace: 'افزودن به فضای کاری',
+ customize: 'سفارشی کردن',
+ },
+ appCustomize: {
+ title: 'ایجاد برنامه از {{name}}',
+ subTitle: 'آیکون و نام برنامه',
+ nameRequired: 'نام برنامه الزامی است',
+ },
+ category: {
+ Assistant: 'دستیار',
+ Writing: 'نوشتن',
+ Translate: 'ترجمه',
+ Programming: 'برنامهنویسی',
+ HR: 'منابع انسانی',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/layout.ts b/web/i18n/fa-IR/layout.ts
new file mode 100644
index 0000000000..928649474b
--- /dev/null
+++ b/web/i18n/fa-IR/layout.ts
@@ -0,0 +1,4 @@
+const translation = {
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/login.ts b/web/i18n/fa-IR/login.ts
new file mode 100644
index 0000000000..8912561efe
--- /dev/null
+++ b/web/i18n/fa-IR/login.ts
@@ -0,0 +1,75 @@
+const translation = {
+ pageTitle: 'هی، بیایید شروع کنیم!👋',
+ welcome: 'به Dify خوش آمدید، لطفا برای ادامه وارد شوید.',
+ email: 'آدرس ایمیل',
+ emailPlaceholder: 'ایمیل شما',
+ password: 'رمز عبور',
+ passwordPlaceholder: 'رمز عبور شما',
+ name: 'نام کاربری',
+ namePlaceholder: 'نام کاربری شما',
+ forget: 'رمز عبور خود را فراموش کردهاید؟',
+ signBtn: 'ورود',
+ sso: 'ادامه با SSO',
+ installBtn: 'راهاندازی',
+ setAdminAccount: 'راهاندازی حساب مدیر',
+ setAdminAccountDesc: 'بیشترین امتیازات برای حساب مدیر، که میتواند برای ایجاد برنامهها و مدیریت ارائهدهندگان LLM و غیره استفاده شود.',
+ createAndSignIn: 'ایجاد و ورود',
+ oneMoreStep: 'یک مرحله دیگر',
+ createSample: 'بر اساس این اطلاعات، ما برای شما یک نمونه برنامه ایجاد خواهیم کرد',
+ invitationCode: 'کد دعوت',
+ invitationCodePlaceholder: 'کد دعوت شما',
+ interfaceLanguage: 'زبان رابط کاربری',
+ timezone: 'منطقه زمانی',
+ go: 'برو به Dify',
+ sendUsMail: 'ایمیل معرفی خود را برای ما ارسال کنید، و ما درخواست دعوت را بررسی خواهیم کرد.',
+ acceptPP: 'من سیاست حفظ حریم خصوصی را خوانده و قبول میکنم',
+ reset: 'لطفاً برای بازنشانی رمز عبور خود دستور زیر را اجرا کنید',
+ withGitHub: 'ادامه با GitHub',
+ withGoogle: 'ادامه با Google',
+ rightTitle: 'پتانسیل کامل LLM را باز کنید',
+ rightDesc: 'به راحتی برنامههای AI با ظاهری جذاب، قابل اجرا و بهبود پذیر ایجاد کنید.',
+ tos: 'شرایط خدمات',
+ pp: 'سیاست حفظ حریم خصوصی',
+ tosDesc: 'با ثبت نام، شما با شرایط ما موافقت میکنید',
+ goToInit: 'اگر حساب را اولیه نکردهاید، لطفاً به صفحه اولیهسازی بروید',
+ donthave: 'ندارید؟',
+ invalidInvitationCode: 'کد دعوت نامعتبر است',
+ accountAlreadyInited: 'حساب قبلاً اولیه شده است',
+ forgotPassword: 'رمز عبور خود را فراموش کردهاید؟',
+ resetLinkSent: 'لینک بازنشانی ارسال شد',
+ sendResetLink: 'ارسال لینک بازنشانی',
+ backToSignIn: 'بازگشت به ورود',
+ forgotPasswordDesc: 'لطفاً آدرس ایمیل خود را وارد کنید تا رمز عبور خود را بازنشانی کنید. ما یک ایمیل با دستورالعملهای بازنشانی برای شما ارسال خواهیم کرد.',
+ checkEmailForResetLink: 'لطفاً ایمیل خود را برای لینک بازنشانی رمز عبور بررسی کنید. اگر در عرض چند دقیقه ظاهر نشد، پوشه اسپم خود را بررسی کنید.',
+ passwordChanged: 'اکنون وارد شوید',
+ changePassword: 'تغییر رمز عبور',
+ changePasswordTip: 'لطفاً یک رمز عبور جدید برای حساب خود وارد کنید',
+ invalidToken: 'توکن نامعتبر یا منقضی شده است',
+ confirmPassword: 'تایید رمز عبور',
+ confirmPasswordPlaceholder: 'رمز عبور جدید خود را تایید کنید',
+ passwordChangedTip: 'رمز عبور شما با موفقیت تغییر یافت',
+ error: {
+ emailEmpty: 'آدرس ایمیل لازم است',
+ emailInValid: 'لطفاً یک آدرس ایمیل معتبر وارد کنید',
+ nameEmpty: 'نام لازم است',
+ passwordEmpty: 'رمز عبور لازم است',
+ passwordLengthInValid: 'رمز عبور باید حداقل ۸ کاراکتر باشد',
+ passwordInvalid: 'رمز عبور باید شامل حروف و اعداد باشد و طول آن بیشتر از ۸ کاراکتر باشد',
+ },
+ license: {
+ tip: 'قبل از شروع Dify Community Edition، GitHub را بخوانید',
+ link: 'مجوز منبع باز',
+ },
+ join: 'عضویت',
+ joinTipStart: 'شما را دعوت میکنیم به',
+ joinTipEnd: 'تیم در Dify',
+ invalid: 'لینک منقضی شده است',
+ explore: 'کاوش Dify',
+ activatedTipStart: 'شما به',
+ activatedTipEnd: 'تیم پیوستهاید',
+ activated: 'اکنون وارد شوید',
+ adminInitPassword: 'رمز عبور اولیه مدیر',
+ validate: 'اعتبارسنجی',
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/register.ts b/web/i18n/fa-IR/register.ts
new file mode 100644
index 0000000000..928649474b
--- /dev/null
+++ b/web/i18n/fa-IR/register.ts
@@ -0,0 +1,4 @@
+const translation = {
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/run-log.ts b/web/i18n/fa-IR/run-log.ts
new file mode 100644
index 0000000000..4423d4523b
--- /dev/null
+++ b/web/i18n/fa-IR/run-log.ts
@@ -0,0 +1,29 @@
+const translation = {
+ input: 'ورودی',
+ result: 'نتیجه',
+ detail: 'جزئیات',
+ tracing: 'ردیابی',
+ resultPanel: {
+ status: 'وضعیت',
+ time: 'زمان گذشته',
+ tokens: 'کل توکنها',
+ },
+ meta: {
+ title: 'فراداده',
+ status: 'وضعیت',
+ version: 'نسخه',
+ executor: 'اجراکننده',
+ startTime: 'زمان شروع',
+ time: 'زمان گذشته',
+ tokens: 'کل توکنها',
+ steps: 'گامهای اجرا',
+ },
+ resultEmpty: {
+ title: 'این اجرا فقط خروجی به فرمت JSON دارد،',
+ tipLeft: 'لطفاً به ',
+ link: 'پنل جزئیات',
+ tipRight: ' بروید و آن را مشاهده کنید.',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/share-app.ts b/web/i18n/fa-IR/share-app.ts
new file mode 100644
index 0000000000..b74c893e6e
--- /dev/null
+++ b/web/i18n/fa-IR/share-app.ts
@@ -0,0 +1,70 @@
+const translation = {
+ common: {
+ welcome: '',
+ appUnavailable: 'اپ در دسترس نیست',
+ appUnkonwError: 'اپ در دسترس نیست',
+ },
+ chat: {
+ newChat: 'چت جدید',
+ pinnedTitle: 'پین شده',
+ unpinnedTitle: 'چتها',
+ newChatDefaultName: 'مکالمه جدید',
+ resetChat: 'بازنشانی مکالمه',
+ powerBy: 'قدرتگرفته از',
+ prompt: 'پیشنهاد',
+ privatePromptConfigTitle: 'تنظیمات مکالمه',
+ publicPromptConfigTitle: 'پیشنهاد اولیه',
+ configStatusDes: 'قبل از شروع، میتوانید تنظیمات مکالمه را تغییر دهید',
+ configDisabled: 'تنظیمات جلسه قبلی برای این جلسه استفاده شده است.',
+ startChat: 'شروع چت',
+ privacyPolicyLeft: 'لطفاً ',
+ privacyPolicyMiddle: 'سیاست حریم خصوصی',
+ privacyPolicyRight: ' ارائه شده توسط توسعهدهنده اپ را بخوانید.',
+ deleteConversation: {
+ title: 'حذف مکالمه',
+ content: 'آیا مطمئن هستید که میخواهید این مکالمه را حذف کنید؟',
+ },
+ tryToSolve: 'سعی کنید حل کنید',
+ temporarySystemIssue: 'ببخشید، مشکل موقت سیستمی.',
+ },
+ generation: {
+ tabs: {
+ create: 'یکبار اجرا کن',
+ batch: 'اجرا به صورت گروهی',
+ saved: 'ذخیره شده',
+ },
+ savedNoData: {
+ title: 'شما هنوز نتیجهای ذخیره نکردهاید!',
+ description: 'شروع به تولید محتوا کنید و نتایج ذخیره شده خود را اینجا پیدا کنید.',
+ startCreateContent: 'شروع به تولید محتوا',
+ },
+ title: 'تکمیل هوش مصنوعی',
+ queryTitle: 'محتوای درخواست',
+ completionResult: 'نتیجه تکمیل',
+ queryPlaceholder: 'محتوای درخواست خود را بنویسید...',
+ run: 'اجرا',
+ copy: 'کپی',
+ resultTitle: 'تکمیل هوش مصنوعی',
+ noData: 'هوش مصنوعی آنچه را که میخواهید اینجا به شما میدهد.',
+ csvUploadTitle: 'فایل CSV خود را اینجا بکشید و رها کنید، یا ',
+ browse: 'جستجو',
+ csvStructureTitle: 'فایل CSV باید با ساختار زیر مطابقت داشته باشد:',
+ downloadTemplate: 'الگو را اینجا دانلود کنید',
+ field: 'فیلد',
+ batchFailed: {
+ info: '{{num}} اجرای ناموفق',
+ retry: 'تلاش مجدد',
+ outputPlaceholder: 'محتوای خروجی وجود ندارد',
+ },
+ errorMsg: {
+ empty: 'لطفاً محتوا را در فایل بارگذاری شده وارد کنید.',
+ fileStructNotMatch: 'فایل CSV بارگذاری شده با ساختار مطابقت ندارد.',
+ emptyLine: 'ردیف {{rowIndex}} خالی است',
+ invalidLine: 'ردیف {{rowIndex}}: مقدار {{varName}} نمیتواند خالی باشد',
+ moreThanMaxLengthLine: 'ردیف {{rowIndex}}: مقدار {{varName}} نمیتواند بیشتر از {{maxLength}} کاراکتر باشد',
+ atLeastOne: 'لطفاً حداقل یک ردیف در فایل بارگذاری شده وارد کنید.',
+ },
+ },
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/tools.ts b/web/i18n/fa-IR/tools.ts
new file mode 100644
index 0000000000..002f55d1d4
--- /dev/null
+++ b/web/i18n/fa-IR/tools.ts
@@ -0,0 +1,153 @@
+const translation = {
+ title: 'ابزارها',
+ createCustomTool: 'ایجاد ابزار سفارشی',
+ customToolTip: 'بیشتر در مورد ابزارهای سفارشی Dify بیاموزید',
+ type: {
+ all: 'همه',
+ builtIn: 'سفارشی شده',
+ custom: 'سفارشی',
+ workflow: 'جریان کار',
+ },
+ contribute: {
+ line1: 'من علاقهمند به ',
+ line2: 'مشارکت در ابزارهای Dify هستم.',
+ viewGuide: 'مشاهده راهنما',
+ },
+ author: 'توسط',
+ auth: {
+ unauthorized: 'برای مجوز دادن',
+ authorized: 'مجوز داده شده',
+ setup: 'تنظیم مجوز برای استفاده',
+ setupModalTitle: 'تنظیم مجوز',
+ setupModalTitleDescription: 'پس از پیکربندی اعتبارنامهها، همه اعضای موجود در فضای کاری میتوانند از این ابزار هنگام هماهنگی برنامهها استفاده کنند.',
+ },
+ includeToolNum: '{{num}} ابزار شامل شد',
+ addTool: 'افزودن ابزار',
+ addToolModal: {
+ type: 'نوع',
+ category: 'دستهبندی',
+ add: 'افزودن',
+ added: 'افزوده شد',
+ manageInTools: 'مدیریت در ابزارها',
+ emptyTitle: 'هیچ ابزار جریان کاری در دسترس نیست',
+ emptyTip: 'به "جریان کاری -> انتشار به عنوان ابزار" بروید',
+ },
+ createTool: {
+ title: 'ایجاد ابزار سفارشی',
+ editAction: 'پیکربندی',
+ editTitle: 'ویرایش ابزار سفارشی',
+ name: 'نام',
+ toolNamePlaceHolder: 'نام ابزار را وارد کنید',
+ nameForToolCall: 'نام فراخوانی ابزار',
+ nameForToolCallPlaceHolder: 'برای شناسایی ماشین، مانند getCurrentWeather، list_pets',
+ nameForToolCallTip: 'فقط اعداد، حروف و خط زیر پشتیبانی میشود.',
+ description: 'توضیحات',
+ descriptionPlaceholder: 'توضیحات مختصر در مورد هدف ابزار، مثلاً، گرفتن دما برای یک مکان خاص.',
+ schema: 'طرح',
+ schemaPlaceHolder: 'طرح OpenAPI خود را اینجا وارد کنید',
+ viewSchemaSpec: 'مشاهده مشخصات OpenAPI-Swagger',
+ importFromUrl: 'وارد کردن از URL',
+ importFromUrlPlaceHolder: 'https://...',
+ urlError: 'لطفاً یک URL معتبر وارد کنید',
+ examples: 'مثالها',
+ exampleOptions: {
+ json: 'آب و هوا (JSON)',
+ yaml: 'فروشگاه حیوانات خانگی (YAML)',
+ blankTemplate: 'الگوی خالی',
+ },
+ availableTools: {
+ title: 'ابزارهای موجود',
+ name: 'نام',
+ description: 'توضیحات',
+ method: 'روش',
+ path: 'مسیر',
+ action: 'عملیات',
+ test: 'آزمایش',
+ },
+ authMethod: {
+ title: 'روش مجوز',
+ type: 'نوع مجوز',
+ keyTooltip: 'کلید Http Header، میتوانید آن را با "Authorization" ترک کنید اگر نمیدانید چیست یا آن را به یک مقدار سفارشی تنظیم کنید',
+ types: {
+ none: 'هیچ',
+ api_key: 'کلید API',
+ apiKeyPlaceholder: 'نام هدر HTTP برای کلید API',
+ apiValuePlaceholder: 'کلید API را وارد کنید',
+ },
+ key: 'کلید',
+ value: 'مقدار',
+ },
+ authHeaderPrefix: {
+ title: 'نوع مجوز',
+ types: {
+ basic: 'پایه',
+ bearer: 'Bearer',
+ custom: 'سفارشی',
+ },
+ },
+ privacyPolicy: 'سیاست حفظ حریم خصوصی',
+ privacyPolicyPlaceholder: 'لطفاً سیاست حفظ حریم خصوصی را وارد کنید',
+ toolInput: {
+ title: 'ورودی ابزار',
+ name: 'نام',
+ required: 'الزامی',
+ method: 'روش',
+ methodSetting: 'تنظیم',
+ methodSettingTip: 'کاربر پیکربندی ابزار را پر میکند',
+ methodParameter: 'پارامتر',
+ methodParameterTip: 'LLM در طول استنباط پر میکند',
+ label: 'برچسبها',
+ labelPlaceholder: 'برچسبها را انتخاب کنید (اختیاری)',
+ description: 'توضیحات',
+ descriptionPlaceholder: 'توضیحات معنی پارامتر',
+ },
+ customDisclaimer: 'توجهیه سفارشی',
+ customDisclaimerPlaceholder: 'لطفاً توجهیه سفارشی را وارد کنید',
+ confirmTitle: 'آیا میخواهید ذخیره کنید؟',
+ confirmTip: 'برنامههایی که از این ابزار استفاده میکنند تحت تأثیر قرار خواهند گرفت',
+ deleteToolConfirmTitle: 'آیا این ابزار را حذف کنید؟',
+ deleteToolConfirmContent: 'حذف ابزار غیرقابل بازگشت است. کاربران دیگر قادر به دسترسی به ابزار شما نخواهند بود.',
+ },
+ test: {
+ title: 'آزمایش',
+ parametersValue: 'پارامترها و مقدار',
+ parameters: 'پارامترها',
+ value: 'مقدار',
+ testResult: 'نتایج آزمایش',
+ testResultPlaceholder: 'نتیجه آزمایش در اینجا نمایش داده میشود',
+ },
+ thought: {
+ using: 'در حال استفاده',
+ used: 'استفاده شده',
+ requestTitle: 'درخواست به',
+ responseTitle: 'پاسخ از',
+ },
+ setBuiltInTools: {
+ info: 'اطلاعات',
+ setting: 'تنظیمات',
+ toolDescription: 'توضیحات ابزار',
+ parameters: 'پارامترها',
+ string: 'رشته',
+ number: 'عدد',
+ required: 'الزامی',
+ infoAndSetting: 'اطلاعات و تنظیمات',
+ },
+ noCustomTool: {
+ title: 'ابزار سفارشی وجود ندارد!',
+ content: 'ابزارهای سفارشی خود را در اینجا اضافه و مدیریت کنید تا برنامههای هوش مصنوعی بسازید.',
+ createTool: 'ایجاد ابزار',
+ },
+ noSearchRes: {
+ title: 'متأسفیم، نتیجهای پیدا نشد!',
+ content: 'ما نتوانستیم ابزارهایی که با جستجوی شما مطابقت داشته باشد پیدا کنیم.',
+ reset: 'بازنشانی جستجو',
+ },
+ builtInPromptTitle: 'پرامپت',
+ toolRemoved: 'ابزار حذف شد',
+ notAuthorized: 'ابزار مجوز ندارد',
+ howToGet: 'چگونه دریافت کنید',
+ openInStudio: 'باز کردن در استودیو',
+ toolNameUsageTip: 'نام فراخوانی ابزار برای استدلال و پرامپتهای عامل',
+}
+
+export default translation
diff --git a/web/i18n/fa-IR/workflow.ts b/web/i18n/fa-IR/workflow.ts
new file mode 100644
index 0000000000..72f2c12141
--- /dev/null
+++ b/web/i18n/fa-IR/workflow.ts
@@ -0,0 +1,498 @@
+const translation = {
+ common: {
+ undo: 'بازگشت',
+ redo: 'پیشرفت',
+ editing: 'ویرایش',
+ autoSaved: 'ذخیره خودکار',
+ unpublished: 'منتشر نشده',
+ published: 'منتشر شده',
+ publish: 'انتشار',
+ update: 'بهروزرسانی',
+ run: 'اجرا',
+ running: 'در حال اجرا',
+ inRunMode: 'در حالت اجرا',
+ inPreview: 'در پیشنمایش',
+ inPreviewMode: 'در حالت پیشنمایش',
+ preview: 'پیشنمایش',
+ viewRunHistory: 'مشاهده تاریخچه اجرا',
+ runHistory: 'تاریخچه اجرا',
+ goBackToEdit: 'بازگشت به ویرایشگر',
+ conversationLog: 'گزارش مکالمات',
+ features: 'ویژگیها',
+ debugAndPreview: 'پیشنمایش',
+ restart: 'راهاندازی مجدد',
+ currentDraft: 'پیشنویس فعلی',
+ currentDraftUnpublished: 'پیشنویس فعلی منتشر نشده',
+ latestPublished: 'آخرین نسخه منتشر شده',
+ publishedAt: 'منتشر شده',
+ restore: 'بازیابی',
+ runApp: 'اجرای اپلیکیشن',
+ batchRunApp: 'اجرای دستهای اپلیکیشن',
+ accessAPIReference: 'دسترسی به مستندات API',
+ embedIntoSite: 'درج در سایت',
+ addTitle: 'افزودن عنوان...',
+ addDescription: 'افزودن توضیحات...',
+ noVar: 'هیچ متغیری',
+ searchVar: 'جستجوی متغیر',
+ variableNamePlaceholder: 'نام متغیر',
+ setVarValuePlaceholder: 'تنظیم متغیر',
+ needConnecttip: 'این مرحله به هیچ چیزی متصل نیست',
+ maxTreeDepth: 'حداکثر عمق {{depth}} نود در هر شاخه',
+ needEndNode: 'بلوک پایان باید اضافه شود',
+ needAnswerNode: 'بلوک پاسخ باید اضافه شود',
+ workflowProcess: 'فرآیند جریان کار',
+ notRunning: 'هنوز در حال اجرا نیست',
+ previewPlaceholder: 'محتوا را در کادر زیر وارد کنید تا اشکالزدایی چتبات را شروع کنید',
+ effectVarConfirm: {
+ title: 'حذف متغیر',
+ content: 'متغیر در نودهای دیگر استفاده شده است. آیا همچنان میخواهید آن را حذف کنید؟',
+ },
+ insertVarTip: 'برای درج سریع کلید \'/\' را فشار دهید',
+ processData: 'پردازش دادهها',
+ input: 'ورودی',
+ output: 'خروجی',
+ jinjaEditorPlaceholder: 'برای درج متغیر \'/\' یا \'{\' را تایپ کنید',
+ viewOnly: 'فقط مشاهده',
+ showRunHistory: 'نمایش تاریخچه اجرا',
+ enableJinja: 'فعالسازی پشتیبانی از الگوهای Jinja',
+ learnMore: 'اطلاعات بیشتر',
+ copy: 'کپی',
+ duplicate: 'تکرار',
+ addBlock: 'افزودن بلوک',
+ pasteHere: 'چسباندن اینجا',
+ pointerMode: 'حالت اشارهگر',
+ handMode: 'حالت دست',
+ model: 'مدل',
+ workflowAsTool: 'جریان کار به عنوان ابزار',
+ configureRequired: 'پیکربندی مورد نیاز',
+ configure: 'پیکربندی',
+ manageInTools: 'مدیریت در ابزارها',
+ workflowAsToolTip: 'پیکربندی ابزار پس از بهروزرسانی جریان کار مورد نیاز است.',
+ viewDetailInTracingPanel: 'مشاهده جزئیات',
+ syncingData: 'همگامسازی دادهها، فقط چند ثانیه',
+ importDSL: 'وارد کردن DSL',
+ importDSLTip: 'پیشنویس فعلی بر روی هم نوشته خواهد شد. قبل از وارد کردن، جریان کار را به عنوان نسخه پشتیبان صادر کنید.',
+ backupCurrentDraft: 'پشتیبانگیری از پیشنویس فعلی',
+ chooseDSL: 'انتخاب فایل DSL(yml)',
+ overwriteAndImport: 'بازنویسی و وارد کردن',
+ importFailure: 'خطا در وارد کردن',
+ importSuccess: 'وارد کردن موفقیتآمیز',
+ },
+ env: {
+ envPanelTitle: 'متغیرهای محیطی',
+ envDescription: 'متغیرهای محیطی میتوانند برای ذخیره اطلاعات خصوصی و اعتبارنامهها استفاده شوند. آنها فقط خواندنی هستند و میتوانند در حین صادر کردن از فایل DSL جدا شوند.',
+ envPanelButton: 'افزودن متغیر',
+ modal: {
+ title: 'افزودن متغیر محیطی',
+ editTitle: 'ویرایش متغیر محیطی',
+ type: 'نوع',
+ name: 'نام',
+ namePlaceholder: 'نام متغیر',
+ value: 'مقدار',
+ valuePlaceholder: 'مقدار متغیر',
+ secretTip: 'برای تعریف اطلاعات حساس یا دادهها، با تنظیمات DSL برای جلوگیری از نشت پیکربندی شده است.',
+ },
+ export: {
+ title: 'آیا متغیرهای محیطی مخفی را صادر کنید؟',
+ checkbox: 'صادر کردن مقادیر مخفی',
+ ignore: 'صادر کردن DSL',
+ export: 'صادر کردن DSL با مقادیر مخفی',
+ },
+ },
+ changeHistory: {
+ title: 'تاریخچه تغییرات',
+ placeholder: 'هنوز تغییری ایجاد نکردید',
+ clearHistory: 'پاک کردن تاریخچه',
+ hint: 'راهنما',
+ hintText: 'عملیات ویرایش شما در تاریخچه تغییرات پیگیری میشود که برای مدت این جلسه بر روی دستگاه شما ذخیره میشود. این تاریخچه هنگام خروج از ویرایشگر پاک خواهد شد.',
+ stepBackward_one: '{{count}} قدم به عقب',
+ stepBackward_other: '{{count}} قدم به عقب',
+ stepForward_one: '{{count}} قدم به جلو',
+ stepForward_other: '{{count}} قدم به جلو',
+ sessionStart: 'شروع جلسه',
+ currentState: 'وضعیت کنونی',
+ nodeTitleChange: 'عنوان بلوک تغییر کرده است',
+ nodeDescriptionChange: 'توضیحات بلوک تغییر کرده است',
+ nodeDragStop: 'بلوک جابجا شده است',
+ nodeChange: 'بلوک تغییر کرده است',
+ nodeConnect: 'بلوک متصل شده است',
+ nodePaste: 'بلوک چسبانده شده است',
+ nodeDelete: 'بلوک حذف شده است',
+ nodeAdd: 'بلوک اضافه شده است',
+ nodeResize: 'اندازه بلوک تغییر کرده است',
+ noteAdd: 'یادداشت اضافه شده است',
+ noteChange: 'یادداشت تغییر کرده است',
+ noteDelete: 'یادداشت حذف شده است',
+ edgeDelete: 'بلوک قطع شده است',
+ },
+ errorMsg: {
+ fieldRequired: '{{field}} الزامی است',
+ authRequired: 'احراز هویت ضروری است',
+ invalidJson: '{{field}} JSON معتبر نیست',
+ fields: {
+ variable: 'نام متغیر',
+ variableValue: 'مقدار متغیر',
+ code: 'کد',
+ model: 'مدل',
+ rerankModel: 'مدل مجدد رتبهبندی',
+ },
+ invalidVariable: 'متغیر نامعتبر',
+ },
+ singleRun: {
+ testRun: 'اجرای آزمایشی',
+ startRun: 'شروع اجرا',
+ running: 'در حال اجرا',
+ testRunIteration: 'تکرار اجرای آزمایشی',
+ back: 'بازگشت',
+ iteration: 'تکرار',
+ },
+ tabs: {
+ 'searchBlock': 'جستجوی بلوک',
+ 'blocks': 'بلوکها',
+ 'tools': 'ابزارها',
+ 'allTool': 'همه',
+ 'builtInTool': 'درونساخت',
+ 'customTool': 'سفارشی',
+ 'workflowTool': 'جریان کار',
+ 'question-understand': 'درک سوال',
+ 'logic': 'منطق',
+ 'transform': 'تبدیل',
+ 'utilities': 'ابزارهای کاربردی',
+ 'noResult': 'نتیجهای پیدا نشد',
+ },
+ blocks: {
+ 'start': 'شروع',
+ 'end': 'پایان',
+ 'answer': 'پاسخ',
+ 'llm': 'مدل زبان بزرگ',
+ 'knowledge-retrieval': 'استخراج دانش',
+ 'question-classifier': 'دستهبندی سوالات',
+ 'if-else': 'IF/ELSE',
+ 'code': 'کد',
+ 'template-transform': 'الگو',
+ 'http-request': 'درخواست HTTP',
+ 'variable-assigner': 'تخصیصدهنده متغیر',
+ 'variable-aggregator': 'تجمعدهنده متغیر',
+ 'iteration-start': 'شروع تکرار',
+ 'iteration': 'تکرار',
+ 'parameter-extractor': 'استخراجکننده پارامتر',
+ },
+ blocksAbout: {
+ 'start': 'پارامترهای اولیه برای راهاندازی جریان کار را تعریف کنید',
+ 'end': 'پایان و نوع نتیجه یک جریان کار را تعریف کنید',
+ 'answer': 'محتوای پاسخ مکالمه چت را تعریف کنید',
+ 'llm': 'استفاده از مدلهای زبان بزرگ برای پاسخ به سوالات یا پردازش زبان طبیعی',
+ 'knowledge-retrieval': 'اجازه میدهد تا محتوای متنی مرتبط با سوالات کاربر از دانش استخراج شود',
+ 'question-classifier': 'شرایط دستهبندی سوالات کاربر را تعریف کنید، مدل زبان بزرگ میتواند بر اساس توضیحات دستهبندی، نحوه پیشرفت مکالمه را تعریف کند',
+ 'if-else': 'اجازه میدهد تا جریان کار به دو شاخه بر اساس شرایط if/else تقسیم شود',
+ 'code': 'اجرای یک قطعه کد Python یا NodeJS برای پیادهسازی منطق سفارشی',
+ 'template-transform': 'تبدیل دادهها به رشته با استفاده از سینتاکس الگوهای Jinja',
+ 'http-request': 'اجازه میدهد تا درخواستهای سرور از طریق پروتکل HTTP ارسال شوند',
+ 'variable-assigner': 'تجمع متغیرهای چند شاخهای به یک متغیر واحد برای پیکربندی یکپارچه نودهای پاییندستی.',
+ 'variable-aggregator': 'تجمع متغیرهای چند شاخهای به یک متغیر واحد برای پیکربندی یکپارچه نودهای پاییندستی.',
+ 'iteration': 'اجرای چندین مرحله روی یک شیء لیست تا همه نتایج خروجی داده شوند.',
+ 'parameter-extractor': 'استفاده از مدل زبان بزرگ برای استخراج پارامترهای ساختاری از زبان طبیعی برای فراخوانی ابزارها یا درخواستهای HTTP.',
+ },
+ operator: {
+ zoomIn: 'بزرگنمایی',
+ zoomOut: 'کوچکنمایی',
+ zoomTo50: 'بزرگنمایی به 50%',
+ zoomTo100: 'بزرگنمایی به 100%',
+ zoomToFit: 'تناسب با اندازه',
+ },
+ panel: {
+ userInputField: 'فیلد ورودی کاربر',
+ changeBlock: 'تغییر بلوک',
+ helpLink: 'لینک کمک',
+ about: 'درباره',
+ createdBy: 'ساخته شده توسط',
+ nextStep: 'مرحله بعدی',
+ addNextStep: 'افزودن بلوک بعدی به این جریان کار',
+ selectNextStep: 'انتخاب بلوک بعدی',
+ runThisStep: 'اجرا کردن این مرحله',
+ checklist: 'چکلیست',
+ checklistTip: 'اطمینان حاصل کنید که همه مسائل قبل از انتشار حل شدهاند',
+ checklistResolved: 'تمام مسائل حل شدهاند',
+ organizeBlocks: 'سازماندهی بلوکها',
+ change: 'تغییر',
+ },
+ nodes: {
+ common: {
+ outputVars: 'متغیرهای خروجی',
+ insertVarTip: 'درج متغیر',
+ memory: {
+ memory: 'حافظه',
+ memoryTip: 'تنظیمات حافظه چت',
+ windowSize: 'اندازه پنجره',
+ conversationRoleName: 'نام نقش مکالمه',
+ user: 'پیشوند کاربر',
+ assistant: 'پیشوند دستیار',
+ },
+ memories: {
+ title: 'حافظهها',
+ tip: 'حافظه چت',
+ builtIn: 'درونساخت',
+ },
+ },
+ start: {
+ required: 'الزامی',
+ inputField: 'فیلد ورودی',
+ builtInVar: 'متغیرهای درونساخت',
+ outputVars: {
+ query: 'ورودی کاربر',
+ memories: {
+ des: 'تاریخچه مکالمات',
+ type: 'نوع پیام',
+ content: 'محتوای پیام',
+ },
+ files: 'لیست فایلها',
+ },
+ noVarTip: 'ورودیهایی را که میتوان در جریان کار استفاده کرد، تنظیم کنید',
+ },
+ end: {
+ outputs: 'خروجیها',
+ output: {
+ type: 'نوع خروجی',
+ variable: 'متغیر خروجی',
+ },
+ type: {
+ 'none': 'هیچ',
+ 'plain-text': 'متن ساده',
+ 'structured': 'ساختاری',
+ },
+ },
+ answer: {
+ answer: 'پاسخ',
+ outputVars: 'متغیرهای خروجی',
+ },
+ llm: {
+ model: 'مدل',
+ variables: 'متغیرها',
+ context: 'متن',
+ contextTooltip: 'میتوانید دانش را به عنوان متن وارد کنید',
+ notSetContextInPromptTip: 'برای فعال کردن ویژگی متن، لطفاً متغیر متن را در PROMPT پر کنید.',
+ prompt: 'پیشنهاد',
+ roleDescription: {
+ system: 'دستورات سطح بالا برای مکالمه را ارائه دهید',
+ user: 'دستورات، پرسشها، یا هر ورودی متنی را به مدل ارائه دهید',
+ assistant: 'پاسخهای مدل بر اساس پیامهای کاربر',
+ },
+ addMessage: 'افزودن پیام',
+ vision: 'بینایی',
+ files: 'فایلها',
+ resolution: {
+ name: 'وضوح',
+ high: 'بالا',
+ low: 'پایین',
+ },
+ outputVars: {
+ output: 'تولید محتوا',
+ usage: 'اطلاعات استفاده از مدل',
+ },
+ singleRun: {
+ variable: 'متغیر',
+ },
+ sysQueryInUser: 'sys.query در پیام کاربر ضروری است',
+ },
+ knowledgeRetrieval: {
+ queryVariable: 'متغیر جستجو',
+ knowledge: 'دانش',
+ outputVars: {
+ output: 'دادههای تقسیمبندی شده بازیابی',
+ content: 'محتوای تقسیمبندی شده',
+ title: 'عنوان تقسیمبندی شده',
+ icon: 'آیکون تقسیمبندی شده',
+ url: 'URL تقسیمبندی شده',
+ metadata: 'سایر متادادهها',
+ },
+ },
+ http: {
+ inputVars: 'متغیرهای ورودی',
+ api: 'API',
+ apiPlaceholder: 'URL را وارد کنید، برای درج متغیر \' / \' را تایپ کنید',
+ notStartWithHttp: 'API باید با http:// یا https:// شروع شود',
+ key: 'کلید',
+ value: 'مقدار',
+ bulkEdit: 'ویرایش دستهای',
+ keyValueEdit: 'ویرایش کلید-مقدار',
+ headers: 'هدرها',
+ params: 'پارامترها',
+ body: 'بدن',
+ outputVars: {
+ body: 'محتوای پاسخ',
+ statusCode: 'کد وضعیت پاسخ',
+ headers: 'فهرست هدر پاسخ JSON',
+ files: 'لیست فایلها',
+ },
+ authorization: {
+ 'authorization': 'احراز هویت',
+ 'authorizationType': 'نوع احراز هویت',
+ 'no-auth': 'هیچ',
+ 'api-key': 'کلید API',
+ 'auth-type': 'نوع احراز هویت',
+ 'basic': 'پایه',
+ 'bearer': 'دارنده',
+ 'custom': 'سفارشی',
+ 'api-key-title': 'کلید API',
+ 'header': 'هدر',
+ },
+ insertVarPlaceholder: 'برای درج متغیر \'/\' را تایپ کنید',
+ timeout: {
+ title: 'زمانتوقف',
+ connectLabel: 'زمانتوقف اتصال',
+ connectPlaceholder: 'زمانتوقف اتصال را به ثانیه وارد کنید',
+ readLabel: 'زمانتوقف خواندن',
+ readPlaceholder: 'زمانتوقف خواندن را به ثانیه وارد کنید',
+ writeLabel: 'زمانتوقف نوشتن',
+ writePlaceholder: 'زمانتوقف نوشتن را به ثانیه وارد کنید',
+ },
+ },
+ code: {
+ inputVars: 'متغیرهای ورودی',
+ outputVars: 'متغیرهای خروجی',
+ advancedDependencies: 'وابستگیهای پیشرفته',
+ advancedDependenciesTip: 'برخی وابستگیهای پیشبارگذاری شده که زمان بیشتری برای مصرف نیاز دارند یا به طور پیشفرض در اینجا موجود نیستند، اضافه کنید',
+ searchDependencies: 'جستجوی وابستگیها',
+ },
+ templateTransform: {
+ inputVars: 'متغیرهای ورودی',
+ code: 'کد',
+ codeSupportTip: 'فقط Jinja2 را پشتیبانی میکند',
+ outputVars: {
+ output: 'محتوای تبدیلشده',
+ },
+ },
+ ifElse: {
+ if: 'اگر',
+ else: 'در غیر این صورت',
+ elseDescription: 'برای تعریف منطق که باید زمانی که شرط if برآورده نشود، اجرا شود.',
+ and: 'و',
+ or: 'یا',
+ operator: 'عملگر',
+ notSetVariable: 'لطفاً ابتدا متغیر را تنظیم کنید',
+ comparisonOperator: {
+ 'contains': 'شامل',
+ 'not contains': 'شامل نمیشود',
+ 'start with': 'شروع با',
+ 'end with': 'پایان با',
+ 'is': 'است',
+ 'is not': 'نیست',
+ 'empty': 'خالی است',
+ 'not empty': 'خالی نیست',
+ 'null': 'خالی',
+ 'not null': 'خالی نیست',
+ },
+ enterValue: 'مقدار را وارد کنید',
+ addCondition: 'افزودن شرط',
+ conditionNotSetup: 'شرط تنظیم نشده است',
+ selectVariable: 'متغیر را انتخاب کنید...',
+ },
+ variableAssigner: {
+ title: 'تخصیص متغیرها',
+ outputType: 'نوع خروجی',
+ varNotSet: 'متغیر تنظیم نشده است',
+ noVarTip: 'متغیرهایی را که باید اختصاص داده شوند اضافه کنید',
+ type: {
+ string: 'رشته',
+ number: 'عدد',
+ object: 'شیء',
+ array: 'آرایه',
+ },
+ aggregationGroup: 'گروه تجمع',
+ aggregationGroupTip: 'فعال کردن این ویژگی اجازه میدهد تا تجمعکننده متغیرها چندین مجموعه متغیر را تجمیع کند.',
+ addGroup: 'افزودن گروه',
+ outputVars: {
+ varDescribe: '{{groupName}} خروجی',
+ },
+ setAssignVariable: 'تعیین متغیر تخصیص یافته',
+ },
+ tool: {
+ toAuthorize: 'برای مجوز دادن',
+ inputVars: 'متغیرهای ورودی',
+ outputVars: {
+ text: 'محتوای تولید شده توسط ابزار',
+ files: {
+ title: 'فایلهای تولید شده توسط ابزار',
+ type: 'نوع پشتیبانی. در حال حاضر فقط تصاویر پشتیبانی میشود',
+ transfer_method: 'روش انتقال. مقدار آن remote_url یا local_file است',
+ url: 'URL تصویر',
+ upload_file_id: 'شناسه فایل آپلود شده',
+ },
+ json: 'json تولید شده توسط ابزار',
+ },
+ },
+ questionClassifiers: {
+ model: 'مدل',
+ inputVars: 'متغیرهای ورودی',
+ outputVars: {
+ className: 'نام کلاس',
+ },
+ class: 'کلاس',
+ classNamePlaceholder: 'نام کلاس خود را بنویسید',
+ advancedSetting: 'تنظیمات پیشرفته',
+ topicName: 'نام موضوع',
+ topicPlaceholder: 'نام موضوع خود را بنویسید',
+ addClass: 'افزودن کلاس',
+ instruction: 'دستورالعمل',
+ instructionTip: 'دستورالعملهای اضافی را برای کمک به دستهبند سوالات برای درک بهتر نحوه دستهبندی سوالات وارد کنید.',
+ instructionPlaceholder: 'دستورالعمل خود را بنویسید',
+ },
+ parameterExtractor: {
+ inputVar: 'متغیر ورودی',
+ extractParameters: 'استخراج پارامترها',
+ importFromTool: 'وارد کردن از ابزارها',
+ addExtractParameter: 'افزودن پارامتر استخراج شده',
+ addExtractParameterContent: {
+ name: 'نام',
+ namePlaceholder: 'نام پارامتر استخراج شده',
+ type: 'نوع',
+ typePlaceholder: 'نوع پارامتر استخراج شده',
+ description: 'توضیحات',
+ descriptionPlaceholder: 'توضیحات پارامتر استخراج شده',
+ required: 'الزامی',
+ requiredContent: 'الزامی فقط به عنوان مرجع برای استنتاج مدل استفاده میشود و برای اعتبارسنجی اجباری خروجی پارامتر نیست.',
+ },
+ extractParametersNotSet: 'پارامترهای استخراج شده تنظیم نشدهاند',
+ instruction: 'دستورالعمل',
+ instructionTip: 'دستورالعملهای اضافی را برای کمک به استخراجکننده پارامتر برای درک نحوه استخراج پارامترها وارد کنید.',
+ advancedSetting: 'تنظیمات پیشرفته',
+ reasoningMode: 'حالت استدلال',
+ reasoningModeTip: 'میتوانید حالت استدلال مناسب را بر اساس توانایی مدل برای پاسخ به دستورات برای فراخوانی عملکردها یا پیشنهادات انتخاب کنید.',
+ isSuccess: 'موفقیتآمیز است. در صورت موفقیت مقدار 1 و در صورت شکست مقدار 0 است.',
+ errorReason: 'دلیل خطا',
+ },
+ iteration: {
+ deleteTitle: 'حذف نود تکرار؟',
+ deleteDesc: 'حذف نود تکرار باعث حذف تمام نودهای فرزند خواهد شد',
+ input: 'ورودی',
+ output: 'متغیرهای خروجی',
+ iteration_one: '{{count}} تکرار',
+ iteration_other: '{{count}} تکرارها',
+ currentIteration: 'تکرار فعلی',
+ },
+ note: {
+ addNote: 'افزودن یادداشت',
+ editor: {
+ placeholder: 'یادداشت خود را بنویسید...',
+ small: 'کوچک',
+ medium: 'متوسط',
+ large: 'بزرگ',
+ bold: 'پررنگ',
+ italic: 'ایتالیک',
+ strikethrough: 'خطخورده',
+ link: 'لینک',
+ openLink: 'باز کردن',
+ unlink: 'حذف لینک',
+ enterUrl: 'URL را وارد کنید...',
+ invalidUrl: 'URL نامعتبر',
+ bulletList: 'فهرست گلولهای',
+ showAuthor: 'نمایش نویسنده',
+ },
+ },
+ },
+ tracing: {
+ stopBy: 'متوقف شده توسط {{user}}',
+ },
+}
+
+export default translation
diff --git a/web/i18n/fr-FR/app.ts b/web/i18n/fr-FR/app.ts
index 8e79471576..d89208c424 100644
--- a/web/i18n/fr-FR/app.ts
+++ b/web/i18n/fr-FR/app.ts
@@ -85,6 +85,42 @@ const translation = {
workflow: 'Flux de travail',
completion: 'Terminaison',
},
+ tracing: {
+ title: 'Traçage des performances de l\'application',
+ description: 'Configuration d\'un fournisseur LLMOps tiers et traçage des performances de l\'application.',
+ config: 'Configurer',
+ collapse: 'Réduire',
+ expand: 'Développer',
+ tracing: 'Traçage',
+ disabled: 'Désactivé',
+ disabledTip: 'Veuillez d\'abord configurer le fournisseur',
+ enabled: 'En service',
+ tracingDescription: 'Capturez le contexte complet de l\'exécution de l\'application, y compris les appels LLM, le contexte, les prompts, les requêtes HTTP et plus encore, vers une plateforme de traçage tierce.',
+ configProviderTitle: {
+ configured: 'Configuré',
+ notConfigured: 'Configurez le fournisseur pour activer le traçage',
+ moreProvider: 'Plus de fournisseurs',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Une plateforme de développement tout-en-un pour chaque étape du cycle de vie des applications basées sur LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Traces, évaluations, gestion des prompts et métriques pour déboguer et améliorer votre application LLM.',
+ },
+ inUse: 'En utilisation',
+ configProvider: {
+ title: 'Configurer ',
+ placeholder: 'Entrez votre {{key}}',
+ project: 'Projet',
+ publicKey: 'Clé Publique',
+ secretKey: 'Clé Secrète',
+ viewDocsLink: 'Voir la documentation de {{key}}',
+ removeConfirmTitle: 'Supprimer la configuration de {{key}} ?',
+ removeConfirmContent: 'La configuration actuelle est en cours d\'utilisation, sa suppression désactivera la fonction de Traçage.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/fr-FR/common.ts b/web/i18n/fr-FR/common.ts
index bdd94e7a16..424d8e4a99 100644
--- a/web/i18n/fr-FR/common.ts
+++ b/web/i18n/fr-FR/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Annuler',
clear: 'Effacer',
save: 'Enregistrer',
+ saveAndEnable: 'Enregistrer et Activer',
edit: 'Modifier',
add: 'Ajouter',
added: 'Ajouté',
@@ -408,7 +409,7 @@ const translation = {
latestAvailable: 'Dify {{version}} est la dernière version disponible.',
},
appMenus: {
- overview: 'Aperçu',
+ overview: 'Surveillance',
promptEng: 'Orchestrer',
apiAccess: 'Accès API',
logAndAnn: 'Journaux & Annonces.',
diff --git a/web/i18n/fr-FR/workflow.ts b/web/i18n/fr-FR/workflow.ts
index c4b97870d1..6df78331e4 100644
--- a/web/i18n/fr-FR/workflow.ts
+++ b/web/i18n/fr-FR/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Retour à l\'éditeur',
conversationLog: 'Journal de conversation',
features: 'Fonctionnalités',
- debugAndPreview: 'Déboguer et prévisualiser',
+ debugAndPreview: 'Aperçu',
restart: 'Redémarrer',
currentDraft: 'Brouillon actuel',
currentDraftUnpublished: 'Brouillon actuel non publié',
diff --git a/web/i18n/hi-IN/app.ts b/web/i18n/hi-IN/app.ts
index 9286f74c1c..29b0451b2c 100644
--- a/web/i18n/hi-IN/app.ts
+++ b/web/i18n/hi-IN/app.ts
@@ -85,6 +85,42 @@ const translation = {
workflow: 'वर्कफ़्लो',
completion: 'समाप्ति',
},
+ tracing: {
+ title: 'एप्लिकेशन प्रदर्शन ट्रेसिंग',
+ description: 'तृतीय-पक्ष LLMOps प्रदाता को कॉन्फ़िगर करना और एप्लिकेशन प्रदर्शन का ट्रेस करना।',
+ config: 'कॉन्फ़िगर करें',
+ collapse: 'संकुचित करें',
+ expand: 'विस्तृत करें',
+ tracing: 'ट्रेसिंग',
+ disabled: 'अक्षम',
+ disabledTip: 'कृपया पहले प्रदाता को कॉन्फ़िगर करें',
+ enabled: 'सेवा में',
+ tracingDescription: 'एप्लिकेशन निष्पादन का पूरा संदर्भ कैप्चर करें, जिसमें LLM कॉल, संदर्भ, प्रॉम्प्ट्स, HTTP अनुरोध और अधिक शामिल हैं, एक तृतीय-पक्ष ट्रेसिंग प्लेटफ़ॉर्म पर।',
+ configProviderTitle: {
+ configured: 'कॉन्फ़िगर किया गया',
+ notConfigured: 'ट्रेसिंग सक्षम करने के लिए प्रदाता कॉन्फ़िगर करें',
+ moreProvider: 'अधिक प्रदाता',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'LLM-संचालित एप्लिकेशन जीवनचक्र के प्रत्येक चरण के लिए एक ऑल-इन-वन डेवलपर प्लेटफ़ॉर्म।',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'आपके LLM एप्लिकेशन को डीबग और सुधारने के लिए ट्रेस, मूल्यांकन, प्रॉम्प्ट प्रबंधन और मेट्रिक्स।',
+ },
+ inUse: 'उपयोग में',
+ configProvider: {
+ title: 'कॉन्फ़िगर करें ',
+ placeholder: 'अपना {{key}} दर्ज करें',
+ project: 'प्रोजेक्ट',
+ publicKey: 'सार्वजनिक कुंजी',
+ secretKey: 'गुप्त कुंजी',
+ viewDocsLink: '{{key}} दस्तावेज़ देखें',
+ removeConfirmTitle: '{{key}} कॉन्फ़िगरेशन हटाएं?',
+ removeConfirmContent: 'वर्तमान कॉन्फ़िगरेशन उपयोग में है, इसे हटाने से ट्रेसिंग सुविधा बंद हो जाएगी।',
+ },
+ },
}
export default translation
diff --git a/web/i18n/hi-IN/common.ts b/web/i18n/hi-IN/common.ts
index 6f1385cb3d..2be7cddf8f 100644
--- a/web/i18n/hi-IN/common.ts
+++ b/web/i18n/hi-IN/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'रद्द करें',
clear: 'साफ करें',
save: 'सहेजें',
+ saveAndEnable: 'सहेजें और सक्षम करें',
edit: 'संपादित करें',
add: 'जोड़ें',
added: 'जोड़ा गया',
@@ -454,7 +455,7 @@ const translation = {
latestAvailable: 'Dify {{version}} नवीनतम उपलब्ध संस्करण है।',
},
appMenus: {
- overview: 'अवलोकन',
+ overview: 'निगरानी',
promptEng: 'समन्वय करें',
apiAccess: 'API एक्सेस',
logAndAnn: 'लॉग्स और घोषणाएँ',
diff --git a/web/i18n/hi-IN/workflow.ts b/web/i18n/hi-IN/workflow.ts
index 740fa09988..3233d75bfd 100644
--- a/web/i18n/hi-IN/workflow.ts
+++ b/web/i18n/hi-IN/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'संपादक पर वापस जाएं',
conversationLog: 'वार्तालाप लॉग',
features: 'विशेषताएं',
- debugAndPreview: 'डीबग और पूर्वावलोकन',
+ debugAndPreview: 'पूर्वावलोकन',
restart: 'पुनः आरंभ करें',
currentDraft: 'वर्तमान ड्राफ्ट',
currentDraftUnpublished: 'वर्तमान ड्राफ्ट अप्रकाशित',
@@ -74,6 +74,27 @@ const translation = {
viewDetailInTracingPanel: 'विवरण देखें',
syncingData: 'डेटा सिंक हो रहा है, बस कुछ सेकंड।',
},
+ env: {
+ envPanelTitle: 'पर्यावरण चर',
+ envDescription: 'पर्यावरण चर का उपयोग निजी जानकारी और क्रेडेंशियल्स को संग्रहित करने के लिए किया जा सकता है। वे केवल पढ़ने योग्य हैं और निर्यात के दौरान DSL फ़ाइल से अलग किए जा सकते हैं।',
+ envPanelButton: 'चर जोड़ें',
+ modal: {
+ title: 'पर्यावरण चर जोड़ें',
+ editTitle: 'पर्यावरण चर संपादित करें',
+ type: 'प्रकार',
+ name: 'नाम',
+ namePlaceholder: 'पर्यावरण नाम',
+ value: 'मान',
+ valuePlaceholder: 'पर्यावरण मान',
+ secretTip: 'संवेदनशील जानकारी या डेटा को परिभाषित करने के लिए उपयोग किया जाता है, DSL सेटिंग्स लीक रोकथाम के लिए कॉन्फ़िगर की गई हैं।',
+ },
+ export: {
+ title: 'गुप्त पर्यावरण चर निर्यात करें?',
+ checkbox: 'गुप्त मान निर्यात करें',
+ ignore: 'DSL निर्यात करें',
+ export: 'गुप्त मानों के साथ DSL निर्यात करें',
+ },
+ },
changeHistory: {
title: 'परिवर्तन इतिहास',
placeholder: 'आपने अभी तक कुछ भी नहीं बदला है',
diff --git a/web/i18n/it-IT/workflow.ts b/web/i18n/it-IT/workflow.ts
index 6c009fdf69..4ab8a7a111 100644
--- a/web/i18n/it-IT/workflow.ts
+++ b/web/i18n/it-IT/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Torna all\'editor',
conversationLog: 'Registro conversazioni',
features: 'Caratteristiche',
- debugAndPreview: 'Debug e Anteprima',
+ debugAndPreview: 'Anteprima',
restart: 'Riavvia',
currentDraft: 'Bozza corrente',
currentDraftUnpublished: 'Bozza corrente non pubblicata',
@@ -82,6 +82,27 @@ const translation = {
importFailure: 'Importazione fallita',
importSuccess: 'Importazione riuscita',
},
+ env: {
+ envPanelTitle: 'Variabili d\'Ambiente',
+ envDescription: 'Le variabili d\'ambiente possono essere utilizzate per memorizzare informazioni private e credenziali. Sono di sola lettura e possono essere separate dal file DSL durante l\'esportazione.',
+ envPanelButton: 'Aggiungi Variabile',
+ modal: {
+ title: 'Aggiungi Variabile d\'Ambiente',
+ editTitle: 'Modifica Variabile d\'Ambiente',
+ type: 'Tipo',
+ name: 'Nome',
+ namePlaceholder: 'nome env',
+ value: 'Valore',
+ valuePlaceholder: 'valore env',
+ secretTip: 'Utilizzato per definire informazioni o dati sensibili, con impostazioni DSL configurate per la prevenzione delle fughe.',
+ },
+ export: {
+ title: 'Esportare variabili d\'ambiente segrete?',
+ checkbox: 'Esporta valori segreti',
+ ignore: 'Esporta DSL',
+ export: 'Esporta DSL con valori segreti',
+ },
+ },
changeHistory: {
title: 'Cronologia Modifiche',
placeholder: 'Non hai ancora modificato nulla',
diff --git a/web/i18n/ja-JP/app.ts b/web/i18n/ja-JP/app.ts
index 91bca235f5..2ca3109bac 100644
--- a/web/i18n/ja-JP/app.ts
+++ b/web/i18n/ja-JP/app.ts
@@ -94,7 +94,7 @@ const translation = {
title: 'アプリのパフォーマンスの追跡',
description: 'サードパーティのLLMOpsサービスとトレースアプリケーションのパフォーマンス設定を行います。',
config: '設定',
- collapse: 'Collapse',
+ collapse: '折りたたむ',
expand: '展開',
tracing: '追跡',
disabled: '無効しました',
diff --git a/web/i18n/ja-JP/common.ts b/web/i18n/ja-JP/common.ts
index 76d58fa944..f3fb8466f1 100644
--- a/web/i18n/ja-JP/common.ts
+++ b/web/i18n/ja-JP/common.ts
@@ -443,7 +443,7 @@ const translation = {
latestAvailable: 'Dify {{version}} が最新バージョンです。',
},
appMenus: {
- overview: '概要',
+ overview: '監視',
promptEng: 'オーケストレート',
apiAccess: 'APIアクセス',
logAndAnn: 'ログ&アナウンス',
diff --git a/web/i18n/ja-JP/dataset-documents.ts b/web/i18n/ja-JP/dataset-documents.ts
index 53af92aa60..654ae0ef6c 100644
--- a/web/i18n/ja-JP/dataset-documents.ts
+++ b/web/i18n/ja-JP/dataset-documents.ts
@@ -221,7 +221,7 @@ const translation = {
paragraphs: '段落',
hitCount: '検索回数',
embeddingTime: '埋め込み時間',
- embeddedSpend: '埋め込み時間',
+ embeddedSpend: '埋め込みコスト',
},
},
languageMap: {
diff --git a/web/i18n/ja-JP/dataset.ts b/web/i18n/ja-JP/dataset.ts
index 787b1c1e11..2cdc819cd5 100644
--- a/web/i18n/ja-JP/dataset.ts
+++ b/web/i18n/ja-JP/dataset.ts
@@ -60,7 +60,7 @@ const translation = {
rerankSettings: 'Rerank設定',
weightedScore: {
title: 'ウェイト設定',
- description: '割り当てられた重みを調整することで、並べ替え戦略はセマンティックマッチングとキーワードマッチングのどちらを優先するかを決定します。',
+ description: '代入られた重みを調整することで、並べ替え戦略はセマンティックマッチングとキーワードマッチングのどちらを優先するかを決定します。',
semanticFirst: 'セマンティック優先',
keywordFirst: 'キーワード優先',
customized: 'カスタマイズ',
diff --git a/web/i18n/ja-JP/workflow.ts b/web/i18n/ja-JP/workflow.ts
index ed0eebb8db..c00578ca6a 100644
--- a/web/i18n/ja-JP/workflow.ts
+++ b/web/i18n/ja-JP/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: '編集に戻る',
conversationLog: '会話ログ',
features: '機能',
- debugAndPreview: 'デバッグとプレビュー',
+ debugAndPreview: 'プレビュー',
restart: '再起動',
currentDraft: '現在の下書き',
currentDraftUnpublished: '現在の下書き(未公開)',
@@ -171,7 +171,7 @@ const translation = {
'code': 'コード',
'template-transform': 'テンプレート',
'http-request': 'HTTPリクエスト',
- 'variable-assigner': '変数割り当て',
+ 'variable-assigner': '変数代入',
'variable-aggregator': '変数集約器',
'iteration-start': 'イテレーション開始',
'iteration': 'イテレーション',
@@ -387,11 +387,11 @@ const translation = {
conditionNotSetup: '条件が設定されていません',
},
variableAssigner: {
- title: '変数を割り当てる',
+ title: '変数を代入する',
outputType: '出力タイプ',
outputVarType: '出力変数のタイプ',
varNotSet: '変数が設定されていません',
- noVarTip: '割り当てる変数を追加してください',
+ noVarTip: '代入された変数を追加してください',
type: {
string: '文字列',
number: '数値',
@@ -404,7 +404,7 @@ const translation = {
outputVars: {
varDescribe: '{{groupName}} 出力',
},
- setAssignVariable: '割り当て変数を設定',
+ setAssignVariable: '代入された変数を設定',
},
tool: {
toAuthorize: '承認するには',
diff --git a/web/i18n/ko-KR/app.ts b/web/i18n/ko-KR/app.ts
index d9fb7b3788..0e9a11556a 100644
--- a/web/i18n/ko-KR/app.ts
+++ b/web/i18n/ko-KR/app.ts
@@ -81,6 +81,42 @@ const translation = {
workflow: '워크플로우',
completion: '완성',
},
+ tracing: {
+ title: '앱 성능 추적',
+ description: '제3자 LLMOps 제공업체 구성 및 앱 성능 추적.',
+ config: '구성',
+ collapse: '접기',
+ expand: '펼치기',
+ tracing: '추적',
+ disabled: '비활성화됨',
+ disabledTip: '먼저 제공업체를 구성해 주세요',
+ enabled: '서비스 중',
+ tracingDescription: 'LLM 호출, 컨텍스트, 프롬프트, HTTP 요청 등 앱 실행의 전체 컨텍스트를 제3자 추적 플랫폼에 캡처합니다.',
+ configProviderTitle: {
+ configured: '구성됨',
+ notConfigured: '추적을 활성화하려면 제공업체를 구성하세요',
+ moreProvider: '더 많은 제공업체',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'LLM 기반 애플리케이션 수명 주기의 모든 단계를 위한 올인원 개발자 플랫폼.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'LLM 애플리케이션을 디버그하고 개선하기 위한 추적, 평가, 프롬프트 관리 및 메트릭.',
+ },
+ inUse: '사용 중',
+ configProvider: {
+ title: '구성 ',
+ placeholder: '{{key}}를 입력하세요',
+ project: '프로젝트',
+ publicKey: '공개 키',
+ secretKey: '비밀 키',
+ viewDocsLink: '{{key}} 문서 보기',
+ removeConfirmTitle: '{{key}} 구성을 제거하시겠습니까?',
+ removeConfirmContent: '현재 구성이 사용 중입니다. 제거하면 추적 기능이 꺼집니다.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/ko-KR/common.ts b/web/i18n/ko-KR/common.ts
index d517dc9346..9e78510078 100644
--- a/web/i18n/ko-KR/common.ts
+++ b/web/i18n/ko-KR/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: '취소',
clear: '지우기',
save: '저장',
+ saveAndEnable: '저장 및 활성화',
edit: '편집',
add: '추가',
added: '추가됨',
@@ -404,7 +405,7 @@ const translation = {
latestAvailable: 'Dify {{version}} 최신 버전입니다.',
},
appMenus: {
- overview: '개요',
+ overview: '모니터링',
promptEng: '오케스트레이트',
apiAccess: 'API 액세스',
logAndAnn: '로그 및 어노테이션',
diff --git a/web/i18n/ko-KR/workflow.ts b/web/i18n/ko-KR/workflow.ts
index 1cb6384c19..4ea78c1fce 100644
--- a/web/i18n/ko-KR/workflow.ts
+++ b/web/i18n/ko-KR/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: '편집기로 돌아가기',
conversationLog: '대화 로그',
features: '기능',
- debugAndPreview: '디버그 및 미리보기',
+ debugAndPreview: '미리보기',
restart: '재시작',
currentDraft: '현재 초안',
currentDraftUnpublished: '현재 초안 미발행',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: '워크플로우 업데이트 후 도구 재구성이 필요합니다.',
viewDetailInTracingPanel: '세부 정보 보기',
},
+ env: {
+ envPanelTitle: '환경 변수',
+ envDescription: '환경 변수는 개인 정보와 자격 증명을 저장하는 데 사용될 수 있습니다. 이들은 읽기 전용이며 내보내기 중에 DSL 파일과 분리할 수 있습니다.',
+ envPanelButton: '변수 추가',
+ modal: {
+ title: '환경 변수 추가',
+ editTitle: '환경 변수 편집',
+ type: '유형',
+ name: '이름',
+ namePlaceholder: '환경 이름',
+ value: '값',
+ valuePlaceholder: '환경 값',
+ secretTip: '민감한 정보나 데이터를 정의하는 데 사용되며, DSL 설정은 유출 방지를 위해 구성됩니다.',
+ },
+ export: {
+ title: '비밀 환경 변수를 내보내시겠습니까?',
+ checkbox: '비밀 값 내보내기',
+ ignore: 'DSL 내보내기',
+ export: '비밀 값이 포함된 DSL 내보내기',
+ },
+ },
changeHistory: {
title: '변경 기록',
placeholder: '아직 아무 것도 변경하지 않았습니다',
diff --git a/web/i18n/language.ts b/web/i18n/language.ts
index 3320dc8ff1..e65d34d0ff 100644
--- a/web/i18n/language.ts
+++ b/web/i18n/language.ts
@@ -23,6 +23,7 @@ export type I18nText = {
'ro-RO': string
'pl-PL': string
'hi-IN': string
+ 'fa-IR': string
}
export const languages = data.languages
@@ -50,6 +51,7 @@ export const NOTICE_I18N = {
uk_UA: 'Важливе повідомлення',
vi_VN: 'Thông báo quan trọng',
it_IT: 'Avviso Importante',
+ fa_IR: 'هشدار مهم',
},
desc: {
en_US:
@@ -76,6 +78,8 @@ export const NOTICE_I18N = {
'Hệ thống của chúng tôi sẽ ngừng hoạt động từ 19:00 đến 24:00 UTC vào ngày 28 tháng 8 để nâng cấp. Nếu có thắc mắc, vui lòng liên hệ với nhóm hỗ trợ của chúng tôi (support@dify.ai). Chúng tôi đánh giá cao sự kiên nhẫn của bạn.',
tr_TR:
'Sistemimiz, 28 Ağustos\'ta 19:00 ile 24:00 UTC saatleri arasında güncelleme nedeniyle kullanılamayacaktır. Sorularınız için lütfen destek ekibimizle iletişime geçin (support@dify.ai). Sabrınız için teşekkür ederiz.',
+ fa_IR:
+ 'سیستم ما از ساعت 19:00 تا 24:00 UTC در تاریخ 28 اوت برای ارتقاء در دسترس نخواهد بود. برای سؤالات، لطفاً با تیم پشتیبانی ما (support@dify.ai) تماس بگیرید. ما برای صبر شما ارزش قائلیم.',
},
href: '#',
}
diff --git a/web/i18n/languages.json b/web/i18n/languages.json
index c2aa7af717..d819e49089 100644
--- a/web/i18n/languages.json
+++ b/web/i18n/languages.json
@@ -132,6 +132,13 @@
"prompt_name": "Türkçe",
"example": "Selam!",
"supported": "true"
+ },
+ {
+ "value": "fa-IR",
+ "name": "Farsi (Iran)",
+ "prompt_name": "Farsi",
+ "example": "سلام, دیفای!",
+ "supported": true
}
]
}
diff --git a/web/i18n/pl-PL/app.ts b/web/i18n/pl-PL/app.ts
index 1bf6e2f376..3a54f3ec3f 100644
--- a/web/i18n/pl-PL/app.ts
+++ b/web/i18n/pl-PL/app.ts
@@ -92,6 +92,42 @@ const translation = {
workflow: 'Przepływ pracy',
completion: 'Zakończenie',
},
+ tracing: {
+ title: 'Śledzenie wydajności aplikacji',
+ description: 'Konfiguracja zewnętrznego dostawcy LLMOps i śledzenie wydajności aplikacji.',
+ config: 'Konfiguruj',
+ collapse: 'Zwiń',
+ expand: 'Rozwiń',
+ tracing: 'Śledzenie',
+ disabled: 'Wyłączone',
+ disabledTip: 'Najpierw skonfiguruj dostawcę',
+ enabled: 'W użyciu',
+ tracingDescription: 'Przechwytywanie pełnego kontekstu wykonania aplikacji, w tym wywołań LLM, kontekstu, promptów, żądań HTTP i więcej, do platformy śledzenia stron trzecich.',
+ configProviderTitle: {
+ configured: 'Skonfigurowano',
+ notConfigured: 'Skonfiguruj dostawcę, aby włączyć śledzenie',
+ moreProvider: 'Więcej dostawców',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Kompleksowa platforma deweloperska dla każdego etapu cyklu życia aplikacji opartej na LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Śledzenie, oceny, zarządzanie promptami i metryki do debugowania i ulepszania twojej aplikacji LLM.',
+ },
+ inUse: 'W użyciu',
+ configProvider: {
+ title: 'Konfiguruj ',
+ placeholder: 'Wprowadź swój {{key}}',
+ project: 'Projekt',
+ publicKey: 'Klucz publiczny',
+ secretKey: 'Klucz tajny',
+ viewDocsLink: 'Zobacz dokumentację {{key}}',
+ removeConfirmTitle: 'Usunąć konfigurację {{key}}?',
+ removeConfirmContent: 'Obecna konfiguracja jest w użyciu, jej usunięcie wyłączy funkcję Śledzenia.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/pl-PL/common.ts b/web/i18n/pl-PL/common.ts
index d9916e9d38..39572ce09b 100644
--- a/web/i18n/pl-PL/common.ts
+++ b/web/i18n/pl-PL/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Anuluj',
clear: 'Wyczyść',
save: 'Zapisz',
+ saveAndEnable: 'Zapisz i Włącz',
edit: 'Edytuj',
add: 'Dodaj',
added: 'Dodano',
@@ -422,7 +423,7 @@ const translation = {
latestAvailable: 'Dify {{version}} jest najnowszą dostępną wersją.',
},
appMenus: {
- overview: 'Przegląd',
+ overview: 'Monitorowanie',
promptEng: 'Orkiestracja',
apiAccess: 'Dostęp API',
logAndAnn: 'Logi i ogł.',
diff --git a/web/i18n/pl-PL/workflow.ts b/web/i18n/pl-PL/workflow.ts
index 6cbe0588bc..cee5051824 100644
--- a/web/i18n/pl-PL/workflow.ts
+++ b/web/i18n/pl-PL/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Wróć do edytora',
conversationLog: 'Dziennik rozmów',
features: 'Funkcje',
- debugAndPreview: 'Debugowanie i podgląd',
+ debugAndPreview: 'Podgląd',
restart: 'Uruchom ponownie',
currentDraft: 'Bieżący szkic',
currentDraftUnpublished: 'Bieżący szkic nieopublikowany',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: 'Wymagana rekonfiguracja narzędzia po aktualizacji przepływu pracy.',
viewDetailInTracingPanel: 'Zobacz szczegóły',
},
+ env: {
+ envPanelTitle: 'Zmienne Środowiskowe',
+ envDescription: 'Zmienne środowiskowe mogą być używane do przechowywania prywatnych informacji i poświadczeń. Są one tylko do odczytu i mogą być oddzielone od pliku DSL podczas eksportu.',
+ envPanelButton: 'Dodaj Zmienną',
+ modal: {
+ title: 'Dodaj Zmienną Środowiskową',
+ editTitle: 'Edytuj Zmienną Środowiskową',
+ type: 'Typ',
+ name: 'Nazwa',
+ namePlaceholder: 'nazwa środowiska',
+ value: 'Wartość',
+ valuePlaceholder: 'wartość środowiska',
+ secretTip: 'Używane do definiowania wrażliwych informacji lub danych, z ustawieniami DSL skonfigurowanymi do zapobiegania wyciekom.',
+ },
+ export: {
+ title: 'Eksportować tajne zmienne środowiskowe?',
+ checkbox: 'Eksportuj tajne wartości',
+ ignore: 'Eksportuj DSL',
+ export: 'Eksportuj DSL z tajnymi wartościami',
+ },
+ },
changeHistory: {
title: 'Historia Zmian',
placeholder: 'Nie dokonano jeszcze żadnych zmian',
diff --git a/web/i18n/pt-BR/app.ts b/web/i18n/pt-BR/app.ts
index e12a2b62fa..bd5282e760 100644
--- a/web/i18n/pt-BR/app.ts
+++ b/web/i18n/pt-BR/app.ts
@@ -85,6 +85,42 @@ const translation = {
workflow: 'Fluxo de trabalho',
completion: 'Conclusão',
},
+ tracing: {
+ title: 'Rastreamento de desempenho do aplicativo',
+ description: 'Configurando um provedor LLMOps de terceiros e rastreando o desempenho do aplicativo.',
+ config: 'Configurar',
+ collapse: 'Recolher',
+ expand: 'Expandir',
+ tracing: 'Rastreamento',
+ disabled: 'Desativado',
+ disabledTip: 'Por favor, configure o provedor primeiro',
+ enabled: 'Em serviço',
+ tracingDescription: 'Captura o contexto completo da execução do aplicativo, incluindo chamadas LLM, contexto, prompts, solicitações HTTP e mais, para uma plataforma de rastreamento de terceiros.',
+ configProviderTitle: {
+ configured: 'Configurado',
+ notConfigured: 'Configure o provedor para habilitar o rastreamento',
+ moreProvider: 'Mais provedores',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Uma plataforma de desenvolvedor completa para cada etapa do ciclo de vida do aplicativo impulsionado por LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Rastreamentos, avaliações, gerenciamento de prompts e métricas para depurar e melhorar seu aplicativo LLM.',
+ },
+ inUse: 'Em uso',
+ configProvider: {
+ title: 'Configurar ',
+ placeholder: 'Insira sua {{key}}',
+ project: 'Projeto',
+ publicKey: 'Chave Pública',
+ secretKey: 'Chave Secreta',
+ viewDocsLink: 'Ver documentação de {{key}}',
+ removeConfirmTitle: 'Remover configuração de {{key}}?',
+ removeConfirmContent: 'A configuração atual está em uso, removê-la desligará o recurso de Rastreamento.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/pt-BR/common.ts b/web/i18n/pt-BR/common.ts
index b82434d523..1b29d06669 100644
--- a/web/i18n/pt-BR/common.ts
+++ b/web/i18n/pt-BR/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Cancelar',
clear: 'Limpar',
save: 'Salvar',
+ saveAndEnable: 'Salvar e Ativar',
edit: 'Editar',
add: 'Adicionar',
added: 'Adicionado',
@@ -408,7 +409,7 @@ const translation = {
latestAvailable: 'Dify {{version}} é a última versão disponível.',
},
appMenus: {
- overview: 'Visão Geral',
+ overview: 'Monitoramento',
promptEng: 'Orquestrar',
apiAccess: 'Acesso à API',
logAndAnn: 'Logs e Anúncios',
diff --git a/web/i18n/pt-BR/workflow.ts b/web/i18n/pt-BR/workflow.ts
index 6579a1aed4..938bef31c3 100644
--- a/web/i18n/pt-BR/workflow.ts
+++ b/web/i18n/pt-BR/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Voltar para o editor',
conversationLog: 'Registro de conversa',
features: 'Recursos',
- debugAndPreview: 'Depurar e visualizar',
+ debugAndPreview: 'Visualizar',
restart: 'Reiniciar',
currentDraft: 'Rascunho atual',
currentDraftUnpublished: 'Rascunho atual não publicado',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: 'É necessária a reconfiguração da ferramenta após a atualização do fluxo de trabalho.',
viewDetailInTracingPanel: 'Ver detalhes',
},
+ env: {
+ envPanelTitle: 'Variáveis de Ambiente',
+ envDescription: 'Variáveis de ambiente podem ser usadas para armazenar informações privadas e credenciais. Elas são somente leitura e podem ser separadas do arquivo DSL durante a exportação.',
+ envPanelButton: 'Adicionar Variável',
+ modal: {
+ title: 'Adicionar Variável de Ambiente',
+ editTitle: 'Editar Variável de Ambiente',
+ type: 'Tipo',
+ name: 'Nome',
+ namePlaceholder: 'nome da env',
+ value: 'Valor',
+ valuePlaceholder: 'valor da env',
+ secretTip: 'Usado para definir informações ou dados sensíveis, com configurações DSL configuradas para prevenção de vazamentos.',
+ },
+ export: {
+ title: 'Exportar variáveis de ambiente secretas?',
+ checkbox: 'Exportar valores secretos',
+ ignore: 'Exportar DSL',
+ export: 'Exportar DSL com valores secretos',
+ },
+ },
changeHistory: {
title: 'Histórico de alterações',
placeholder: 'Você ainda não alterou nada',
diff --git a/web/i18n/ro-RO/app.ts b/web/i18n/ro-RO/app.ts
index 333678863f..01a158f4c7 100644
--- a/web/i18n/ro-RO/app.ts
+++ b/web/i18n/ro-RO/app.ts
@@ -85,6 +85,42 @@ const translation = {
workflow: 'Flux de lucru',
completion: 'Finalizare',
},
+ tracing: {
+ title: 'Urmărirea performanței aplicației',
+ description: 'Configurarea unui furnizor LLMOps terț și urmărirea performanței aplicației.',
+ config: 'Configurare',
+ collapse: 'Restrânge',
+ expand: 'Extinde',
+ tracing: 'Urmărire',
+ disabled: 'Dezactivat',
+ disabledTip: 'Vă rugăm să configurați mai întâi furnizorul',
+ enabled: 'În serviciu',
+ tracingDescription: 'Captează contextul complet al execuției aplicației, inclusiv apelurile LLM, context, prompt-uri, cereri HTTP și altele, către o platformă de urmărire terță.',
+ configProviderTitle: {
+ configured: 'Configurat',
+ notConfigured: 'Configurați furnizorul pentru a activa urmărirea',
+ moreProvider: 'Mai mulți furnizori',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'O platformă de dezvoltare all-in-one pentru fiecare etapă a ciclului de viață al aplicației bazate pe LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Urmărire, evaluări, gestionarea prompt-urilor și metrici pentru depanarea și îmbunătățirea aplicației dvs. LLM.',
+ },
+ inUse: 'În utilizare',
+ configProvider: {
+ title: 'Configurare ',
+ placeholder: 'Introduceți {{key}}-ul dvs.',
+ project: 'Proiect',
+ publicKey: 'Cheie publică',
+ secretKey: 'Cheie secretă',
+ viewDocsLink: 'Vizualizați documentația {{key}}',
+ removeConfirmTitle: 'Eliminați configurația {{key}}?',
+ removeConfirmContent: 'Configurația curentă este în uz, eliminarea acesteia va dezactiva funcția de Urmărire.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/ro-RO/common.ts b/web/i18n/ro-RO/common.ts
index d61fc63f5c..e7037f65b8 100644
--- a/web/i18n/ro-RO/common.ts
+++ b/web/i18n/ro-RO/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Anulează',
clear: 'Șterge',
save: 'Salvează',
+ saveAndEnable: 'Salvează și Activează',
edit: 'Editează',
add: 'Adaugă',
added: 'Adăugat',
@@ -407,7 +408,7 @@ const translation = {
latestAvailable: 'Dify {{version}} este ultima versiune disponibilă.',
},
appMenus: {
- overview: 'Prezentare generală',
+ overview: 'Monitorizare',
promptEng: 'Orchestrare',
apiAccess: 'Acces API',
logAndAnn: 'Jurnale și Ann.',
diff --git a/web/i18n/ro-RO/workflow.ts b/web/i18n/ro-RO/workflow.ts
index e1f0943179..beefdc1132 100644
--- a/web/i18n/ro-RO/workflow.ts
+++ b/web/i18n/ro-RO/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Înapoi la editor',
conversationLog: 'Jurnal conversație',
features: 'Funcționalități',
- debugAndPreview: 'Depanare și previzualizare',
+ debugAndPreview: 'Previzualizare',
restart: 'Repornește',
currentDraft: 'Schimbare curentă',
currentDraftUnpublished: 'Schimbare curentă nepublicată',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: 'Reconfigurarea instrumentului este necesară după actualizarea fluxului de lucru.',
viewDetailInTracingPanel: 'Vezi detalii',
},
+ env: {
+ envPanelTitle: 'Variabile de Mediu',
+ envDescription: 'Variabilele de mediu pot fi utilizate pentru a stoca informații private și credențiale. Acestea sunt doar pentru citire și pot fi separate de fișierul DSL în timpul exportului.',
+ envPanelButton: 'Adaugă Variabilă',
+ modal: {
+ title: 'Adaugă Variabilă de Mediu',
+ editTitle: 'Editează Variabilă de Mediu',
+ type: 'Tip',
+ name: 'Nume',
+ namePlaceholder: 'nume mediu',
+ value: 'Valoare',
+ valuePlaceholder: 'valoare mediu',
+ secretTip: 'Utilizat pentru a defini informații sau date sensibile, cu setări DSL configurate pentru prevenirea scurgerilor.',
+ },
+ export: {
+ title: 'Exportă variabile de mediu secrete?',
+ checkbox: 'Exportă valori secrete',
+ ignore: 'Exportă DSL',
+ export: 'Exportă DSL cu valori secrete',
+ },
+ },
changeHistory: {
title: 'Istoric modificări',
placeholder: 'Nu ați schimbat nimic încă',
diff --git a/web/i18n/uk-UA/app.ts b/web/i18n/uk-UA/app.ts
index 209bf12598..3add9dfe81 100644
--- a/web/i18n/uk-UA/app.ts
+++ b/web/i18n/uk-UA/app.ts
@@ -85,6 +85,42 @@ const translation = {
workflow: 'Робочий процес',
completion: 'Завершення',
},
+ tracing: {
+ title: 'Відстеження продуктивності додатку',
+ description: 'Налаштування стороннього провайдера LLMOps та відстеження продуктивності додатку.',
+ config: 'Налаштувати',
+ collapse: 'Згорнути',
+ expand: 'Розгорнути',
+ tracing: 'Відстеження',
+ disabled: 'Вимкнено',
+ disabledTip: 'Спочатку налаштуйте провайдера',
+ enabled: 'В роботі',
+ tracingDescription: 'Захоплення повного контексту виконання додатку, включаючи виклики LLM, контекст, підказки, HTTP-запити та інше, на сторонню платформу відстеження.',
+ configProviderTitle: {
+ configured: 'Налаштовано',
+ notConfigured: 'Налаштуйте провайдера для увімкнення відстеження',
+ moreProvider: 'Більше провайдерів',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Універсальна платформа розробника для кожного етапу життєвого циклу додатку на основі LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Трасування, оцінки, управління підказками та метрики для налагодження та покращення вашого LLM-додатку.',
+ },
+ inUse: 'Використовується',
+ configProvider: {
+ title: 'Налаштувати ',
+ placeholder: 'Введіть ваш {{key}}',
+ project: 'Проект',
+ publicKey: 'Публічний ключ',
+ secretKey: 'Секретний ключ',
+ viewDocsLink: 'Переглянути документацію {{key}}',
+ removeConfirmTitle: 'Видалити налаштування {{key}}?',
+ removeConfirmContent: 'Поточне налаштування використовується, його видалення вимкне функцію Відстеження.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/uk-UA/common.ts b/web/i18n/uk-UA/common.ts
index ededdcb228..fb0003d35f 100644
--- a/web/i18n/uk-UA/common.ts
+++ b/web/i18n/uk-UA/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Скасувати',
clear: 'Очистити',
save: 'Зберегти',
+ saveAndEnable: 'Зберегти та Увімкнути',
edit: 'Редагувати',
add: 'Додати',
added: 'Додано',
@@ -408,7 +409,7 @@ const translation = {
latestAvailable: 'Dify {{version}} – це найновіша доступна версія.',
},
appMenus: {
- overview: 'Огляд',
+ overview: 'Моніторинг',
promptEng: 'Налаштування',
apiAccess: 'Доступ до API',
logAndAnn: 'Журнали та Повідомлення.',
diff --git a/web/i18n/uk-UA/workflow.ts b/web/i18n/uk-UA/workflow.ts
index 399b7bde76..db7e76da69 100644
--- a/web/i18n/uk-UA/workflow.ts
+++ b/web/i18n/uk-UA/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: 'Повернутися до редактора',
conversationLog: 'Журнал розмов',
features: 'Функції',
- debugAndPreview: 'Налагодження та попередній перегляд',
+ debugAndPreview: 'Попередній перегляд',
restart: 'Перезапустити',
currentDraft: 'Поточний чернетка',
currentDraftUnpublished: 'Поточний чернетка неопублікований',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: 'Після оновлення робочого потоку необхідна переконфігурація інструменту.',
viewDetailInTracingPanel: 'Переглянути деталі',
},
+ env: {
+ envPanelTitle: 'Змінні середовища',
+ envDescription: 'Змінні середовища можуть використовуватися для зберігання приватної інформації та облікових даних. Вони доступні лише для читання і можуть бути відокремлені від файлу DSL під час експорту.',
+ envPanelButton: 'Додати змінну',
+ modal: {
+ title: 'Додати змінну середовища',
+ editTitle: 'Редагувати змінну середовища',
+ type: 'Тип',
+ name: 'Назва',
+ namePlaceholder: 'назва середовища',
+ value: 'Значення',
+ valuePlaceholder: 'значення середовища',
+ secretTip: 'Використовується для визначення конфіденційної інформації або даних, з налаштуваннями DSL, сконфігурованими для запобігання витоку.',
+ },
+ export: {
+ title: 'Експортувати секретні змінні середовища?',
+ checkbox: 'Експортувати секретні значення',
+ ignore: 'Експортувати DSL',
+ export: 'Експортувати DSL з секретними значеннями',
+ },
+ },
changeHistory: {
title: 'Історія змін',
placeholder: 'Ви ще нічого не змінили',
diff --git a/web/i18n/vi-VN/app-annotation.ts b/web/i18n/vi-VN/app-annotation.ts
index 2b70b8608c..6a9457f3d7 100644
--- a/web/i18n/vi-VN/app-annotation.ts
+++ b/web/i18n/vi-VN/app-annotation.ts
@@ -1,6 +1,6 @@
const translation = {
title: 'Chú thích',
- name: 'Chú thích cho câu Trả lời',
+ name: 'Chú thích cho câu trả lời',
editBy: 'Câu trả lời được chỉnh sửa bởi {{author}}',
noData: {
title: 'Không có chú thích',
@@ -15,45 +15,45 @@ const translation = {
actions: 'hành động',
addAnnotation: 'Thêm chú thích',
bulkImport: 'Nhập hàng loạt',
- bulkExport: 'Xuất hoàng loạt',
+ bulkExport: 'Xuất hàng loạt',
clearAll: 'Xóa tất cả chú thích',
},
},
editModal: {
- title: 'Chỉnh sửa chú thích Trả lời',
- queryName: 'Truy vấn người dùng',
- answerName: 'Câu chuyện của BOT',
+ title: 'Chỉnh sửa chú thích câu trả lời',
+ queryName: 'Câu hỏi của người dùng',
+ answerName: 'Câu trả lời của AI',
yourAnswer: 'Câu trả lời của bạn',
answerPlaceholder: 'Nhập câu trả lời của bạn vào đây',
- yourQuery: 'Truy vấn của bạn',
- queryPlaceholder: 'Nhập truy vấn của bạn ở đây',
+ yourQuery: 'Câu hỏi của bạn',
+ queryPlaceholder: 'Nhập câu hỏi của bạn ở đây',
removeThisCache: 'Xóa chú thích này',
createdAt: 'Được tạo lúc',
},
addModal: {
- title: 'Thêm chú thích Trả lời',
+ title: 'Thêm chú thích câu trả lời',
queryName: 'Câu hỏi',
- answerName: 'Trả lời',
+ answerName: 'Câu trả lời',
answerPlaceholder: 'Nhập câu trả lời vào đây',
- queryPlaceholder: 'Nhập truy vấn ở đây',
- createNext: 'Thêm một phản hồi có chú thích khác',
+ queryPlaceholder: 'Nhập câu hỏi ở đây',
+ createNext: 'Thêm chú thích khác',
},
batchModal: {
title: 'Nhập hàng loạt',
csvUploadTitle: 'Kéo và thả tệp CSV của bạn vào đây hoặc ',
- browse: 'duyệt',
+ browse: 'chọn tệp',
tip: 'Tệp CSV phải tuân theo cấu trúc sau:',
question: 'câu hỏi',
- answer: 'trả lời',
- contentTitle: 'đoạn nội dung',
+ answer: 'câu trả lời',
+ contentTitle: 'tiêu đề nội dung',
content: 'nội dung',
template: 'Tải mẫu tại đây',
- cancel: 'Bỏ',
- run: 'Run Batch',
- runError: 'Run batch failed',
- processing: 'In batch processing',
- completed: 'Import completed',
- error: 'Import Error',
+ cancel: 'Hủy',
+ run: 'Chạy hàng loạt',
+ runError: 'Chạy hàng loạt thất bại',
+ processing: 'Đang xử lý hàng loạt',
+ completed: 'Nhập hoàn tất',
+ error: 'Lỗi khi nhập',
ok: 'OK',
},
errorMessage: {
@@ -61,27 +61,27 @@ const translation = {
queryRequired: 'Câu hỏi là bắt buộc',
},
viewModal: {
- annotatedResponse: 'Chú thích Trả lời',
- hitHistory: 'Lịch sử lượt truy cập',
- hit: 'Truy cập',
+ annotatedResponse: 'Câu trả lời đã chú thích',
+ hitHistory: 'Lịch sử truy cập',
+ hit: 'Lượt truy cập',
hits: 'Lượt truy cập',
noHitHistory: 'Không có lịch sử truy cập',
},
hitHistoryTable: {
- query: 'Truy vấn',
- match: 'Chính xác',
- response: 'Phản ứng',
+ query: 'Câu hỏi',
+ match: 'Độ chính xác',
+ response: 'Phản hồi',
source: 'Nguồn',
score: 'Điểm',
time: 'Thời gian',
},
initSetup: {
- title: 'Chú thích Trả lời Thiết lập ban đầu',
- configTitle: 'Thiết lập trả lời chú thích',
+ title: 'Thiết lập ban đầu cho chú thích câu trả lời',
+ configTitle: 'Thiết lập chú thích câu trả lời',
confirmBtn: 'Lưu & Kích hoạt',
configConfirmBtn: 'Lưu',
},
- embeddingModelSwitchTip: 'Mô hình vector hóa văn bản chú thích, mô hình chuyển đổi sẽ được nhúng lại, dẫn đến phát sinh thêm chi phí.',
+ embeddingModelSwitchTip: 'Mô hình vector hóa văn bản chú thích, việc chuyển đổi mô hình sẽ dẫn đến việc nhúng lại, có thể phát sinh thêm chi phí.',
}
export default translation
diff --git a/web/i18n/vi-VN/app-api.ts b/web/i18n/vi-VN/app-api.ts
index 67c5a8bfa7..cb89b98008 100644
--- a/web/i18n/vi-VN/app-api.ts
+++ b/web/i18n/vi-VN/app-api.ts
@@ -1,35 +1,35 @@
const translation = {
- apiServer: 'API Server',
- apiKey: 'API Key',
+ apiServer: 'Máy chủ API',
+ apiKey: 'Khóa API',
status: 'Trạng thái',
- disabled: 'Tắt',
+ disabled: 'Đã tắt',
ok: 'Đang hoạt động',
copy: 'Sao chép',
- copied: 'Đã chép',
+ copied: 'Đã sao chép',
play: 'Chạy',
- pause: 'Dừng',
+ pause: 'Tạm dừng',
playing: 'Đang chạy',
merMaind: {
- rerender: 'Redo Rerender',
+ rerender: 'Vẽ lại',
},
never: 'Không bao giờ',
apiKeyModal: {
- apiSecretKey: 'API khoá bí mật',
- apiSecretKeyTips: 'Để ngăn chặn việc lạm dụng API, hãy bảo vệ Khóa API của bạn. Tránh sử dụng nó dưới dạng văn bản thuần túy trong mã giao diện người dùng. :)',
+ apiSecretKey: 'Khóa bí mật API',
+ apiSecretKeyTips: 'Để ngăn chặn việc lạm dụng API, hãy bảo vệ Khóa API của bạn. Tránh sử dụng nó dưới dạng văn bản thuần trong mã giao diện người dùng.',
createNewSecretKey: 'Tạo khóa bí mật mới',
secretKey: 'Khóa bí mật',
- created: 'CREATED',
- lastUsed: 'LAST USED',
- generateTips: 'Giữ chìa khóa này ở nơi an toàn và dễ tiếp cận.',
+ created: 'ĐÃ TẠO',
+ lastUsed: 'SỬ DỤNG LẦN CUỐI',
+ generateTips: 'Hãy lưu giữ khóa này ở nơi an toàn và dễ tiếp cận.',
},
actionMsg: {
deleteConfirmTitle: 'Xóa khóa bí mật này?',
- deleteConfirmTips: 'Hành động này không thể được hoàn tác.',
+ deleteConfirmTips: 'Hành động này không thể hoàn tác.',
ok: 'OK',
},
completionMode: {
- title: 'Completion App API',
- info: 'Đối với việc tạo văn bản chất lượng cao, như bài viết, tóm tắt và dịch thuật, hãy sử dụng API hoàn thành tin nhắn với đầu vào người dùng. Việc tạo văn bản dựa trên các thông số mô hình và mẫu đề xuất được thiết lập trong Dify Prompt Engineering.',
+ title: 'API ứng dụng hoàn thành',
+ info: 'Đối với việc tạo văn bản chất lượng cao như bài viết, tóm tắt và dịch thuật, hãy sử dụng API hoàn thành tin nhắn với đầu vào từ người dùng. Việc tạo văn bản dựa trên các thông số mô hình và mẫu đề xuất được thiết lập trong Dify Prompt Engineering.',
createCompletionApi: 'Tạo tin nhắn hoàn thành',
createCompletionApiTip: 'Tạo một tin nhắn hoàn thành để hỗ trợ chế độ câu hỏi và trả lời.',
inputsTips: '(Tùy chọn) Cung cấp các trường đầu vào người dùng dưới dạng cặp khóa-giá trị, tương ứng với các biến trong Prompt Eng. Khóa là tên biến, Giá trị là giá trị tham số. Nếu loại trường là Lựa chọn, Giá trị đã gửi phải là một trong các lựa chọn đã thiết lập trước.',
@@ -44,7 +44,7 @@ const translation = {
parametersApiTip: 'Truy xuất các tham số Đầu vào được cấu hình, bao gồm tên biến, tên trường, loại và giá trị mặc định. Thường được sử dụng để hiển thị các trường này trong một biểu mẫu hoặc điền vào các giá trị mặc định sau khi máy khách tải.',
},
chatMode: {
- title: 'Chat App API',
+ title: 'API ứng dụng trò chuyện',
info: 'Đối với ứng dụng trò chuyện linh hoạt sử dụng định dạng Câu hỏi và Trả lời, gọi API tin nhắn trò chuyện để bắt đầu cuộc trò chuyện. Duy trì cuộc trò chuyện liên tục bằng cách chuyển conversation_id đã trả về. Các tham số phản hồi và mẫu phụ thuộc vào các cài đặt của Dify Prompt Eng.',
createChatApi: 'Tạo tin nhắn trò chuyện',
createChatApiTip: 'Tạo một tin nhắn trò chuyện mới hoặc tiếp tục một cuộc trò chuyện đang tồn tại.',
@@ -53,7 +53,7 @@ const translation = {
blocking: 'Loại chặn, đợi để thực hiện hoàn tất và trả kết quả. (Yêu cầu có thể bị gián đoạn nếu quá trình kéo dài)',
streaming: 'trả về dữ liệu theo luồng. Thực hiện trả dữ liệu theo luồng dựa trên SSE (Sự kiện được gửi từ máy chủ).',
conversationIdTip: '(Tùy chọn) ID cuộc trò chuyện: để trống cho cuộc trò chuyện lần đầu; chuyển conversation_id từ ngữ cảnh để tiếp tục cuộc trò chuyện.',
- messageFeedbackApi: 'Phản hồi của người dùng cuối về tin nhắn, như',
+ messageFeedbackApi: 'Phản hồi của người dùng cuối về tin nhắn',
messageFeedbackApiTip: 'Đánh giá các tin nhắn nhận được thay mặt cho người dùng cuối với các lựa chọn thích hoặc không thích. Dữ liệu này hiển thị trên trang Nhật ký & Chú thích và được sử dụng cho việc điều chỉnh mô hình trong tương lai.',
messageIDTip: 'ID tin nhắn',
ratingTip: 'thích hoặc không thích, null là hủy bỏ',
@@ -61,11 +61,11 @@ const translation = {
chatMsgHistoryApiTip: 'Trang đầu tiên trả về `limit` tin nhắn mới nhất, được sắp xếp theo thứ tự ngược lại.',
chatMsgHistoryConversationIdTip: 'ID Cuộc trò chuyện',
chatMsgHistoryFirstId: 'ID của bản ghi trò chuyện đầu tiên trên trang hiện tại. Giá trị mặc định là không có.',
- chatMsgHistoryLimit: 'Bao nhiêu cuộc trò chuyện được trả lại trong một yêu cầu',
+ chatMsgHistoryLimit: 'Số lượng cuộc trò chuyện được trả về trong một yêu cầu',
conversationsListApi: 'Lấy danh sách cuộc trò chuyện',
conversationsListApiTip: 'Lấy danh sách phiên của người dùng hiện tại. Theo mặc định, trả về 20 phiên cuối cùng.',
conversationsListFirstIdTip: 'ID của bản ghi cuối cùng trên trang hiện tại, mặc định không có.',
- conversationsListLimitTip: 'Bao nhiêu cuộc trò chuyện được trả lại trong một yêu cầu',
+ conversationsListLimitTip: 'Số lượng cuộc trò chuyện được trả về trong một yêu cầu',
conversationRenamingApi: 'Đổi tên cuộc trò chuyện',
conversationRenamingApiTip: 'Đổi tên cuộc trò chuyện; tên sẽ được hiển thị trong giao diện nhiều phiên.',
conversationRenamingNameTip: 'Tên mới',
@@ -74,7 +74,7 @@ const translation = {
},
develop: {
requestBody: 'Nội dung yêu cầu',
- pathParams: 'Thông số đường dẫn',
+ pathParams: 'Tham số đường dẫn',
query: 'Truy vấn',
},
}
diff --git a/web/i18n/vi-VN/app-debug.ts b/web/i18n/vi-VN/app-debug.ts
index 327c1f0ad2..4797f768e3 100644
--- a/web/i18n/vi-VN/app-debug.ts
+++ b/web/i18n/vi-VN/app-debug.ts
@@ -1,102 +1,102 @@
const translation = {
pageTitle: {
- line1: 'PROMPT',
- line2: 'Engineering',
+ line1: 'YÊU CẦU',
+ line2: 'KỸ THUẬT',
},
- orchestrate: 'Dàn nhạc',
+ orchestrate: 'Điều phối',
promptMode: {
- simple: 'Chuyển sang Chế độ Chuyên gia để chỉnh sửa toàn bộ PROMPT',
+ simple: 'Chuyển sang Chế độ Chuyên gia để chỉnh sửa toàn bộ YÊU CẦU',
advanced: 'Chế độ Chuyên gia',
- switchBack: 'Chuyển về',
+ switchBack: 'Quay lại',
advancedWarning: {
- title: 'Bạn đã chuyển sang Chế độ Chuyên gia, và một khi bạn sửa đổi PROMPT, bạn KHÔNG THỂ quay lại chế độ cơ bản.',
- description: 'Trong Chế độ Chuyên gia, bạn có thể chỉnh sửa toàn bộ PROMPT.',
+ title: 'Bạn đã chuyển sang Chế độ Chuyên gia. Sau khi sửa đổi YÊU CẦU, bạn KHÔNG THỂ quay lại chế độ cơ bản.',
+ description: 'Trong Chế độ Chuyên gia, bạn có thể chỉnh sửa toàn bộ YÊU CẦU.',
learnMore: 'Tìm hiểu thêm',
- ok: 'OK',
+ ok: 'Đồng ý',
},
operation: {
- addMessage: 'Thêm Tin nhắn',
+ addMessage: 'Thêm tin nhắn',
},
- contextMissing: 'Thiếu thành phần Ngữ cảnh, hiệu quả của prompt có thể không tốt.',
+ contextMissing: 'Thiếu thành phần Ngữ cảnh, hiệu quả của yêu cầu có thể không tốt.',
},
operation: {
- applyConfig: 'Xuất bản',
+ applyConfig: 'Áp dụng',
resetConfig: 'Đặt lại',
debugConfig: 'Gỡ lỗi',
- addFeature: 'Thêm Tính năng',
+ addFeature: 'Thêm tính năng',
automatic: 'Tự động',
stopResponding: 'Dừng phản hồi',
agree: 'thích',
disagree: 'không thích',
- cancelAgree: 'Hủy thích',
- cancelDisagree: 'Hủy không thích',
- userAction: 'Người dùng ',
+ cancelAgree: 'Bỏ thích',
+ cancelDisagree: 'Bỏ không thích',
+ userAction: 'Hành động người dùng ',
},
notSetAPIKey: {
- title: 'Khóa nhà cung cấp LLM chưa được đặt',
- trailFinished: 'Kết thúc dấu vết',
- description: 'Khóa nhà cung cấp LLM chưa được đặt, và cần được đặt trước khi gỡ lỗi.',
+ title: 'Chưa thiết lập khóa API của nhà cung cấp LLM',
+ trailFinished: 'Kết thúc dùng thử',
+ description: 'Chưa thiết lập khóa API của nhà cung cấp LLM. Cần thiết lập trước khi gỡ lỗi.',
settingBtn: 'Đi đến cài đặt',
},
trailUseGPT4Info: {
- title: 'Hiện không hỗ trợ gpt-4',
- description: 'Sử dụng gpt-4, vui lòng đặt API Key.',
+ title: 'Hiện không hỗ trợ GPT-4',
+ description: 'Để sử dụng GPT-4, vui lòng thiết lập API Key.',
},
feature: {
groupChat: {
title: 'Nâng cao trò chuyện',
- description: 'Thêm cài đặt trước cuộc trò chuyện cho ứng dụng có thể cải thiện trải nghiệm người dùng.',
+ description: 'Thêm cài đặt trước cho cuộc trò chuyện có thể cải thiện trải nghiệm người dùng.',
},
groupExperience: {
title: 'Nâng cao trải nghiệm',
},
conversationOpener: {
- title: 'Khởi động cuộc trò chuyện',
- description: 'Trong một ứng dụng trò chuyện, câu nói đầu tiên mà AI tự động nói với người dùng thường được sử dụng như một lời chào.',
+ title: 'Mở đầu cuộc trò chuyện',
+ description: 'Trong ứng dụng trò chuyện, câu nói đầu tiên mà AI tự động nói với người dùng thường được sử dụng như một lời chào.',
},
suggestedQuestionsAfterAnswer: {
- title: 'Theo dõi',
- description: 'Thiết lập đề xuất câu hỏi tiếp theo có thể mang lại trò chuyện tốt hơn cho người dùng.',
+ title: 'Câu hỏi gợi ý',
+ description: 'Thiết lập đề xuất câu hỏi tiếp theo có thể tạo ra cuộc trò chuyện tốt hơn cho người dùng.',
resDes: '3 đề xuất cho câu hỏi tiếp theo của người dùng.',
tryToAsk: 'Thử hỏi',
},
moreLikeThis: {
- title: 'Nhiều hơn như vậy',
- description: 'Tạo nhiều văn bản cùng một lúc, và sau đó chỉnh sửa và tiếp tục tạo ra.',
- generateNumTip: 'Số lượng mỗi lần tạo ra',
- tip: 'Sử dụng tính năng này sẽ tốn thêm token.',
+ title: 'Thêm tương tự',
+ description: 'Tạo nhiều văn bản cùng một lúc, sau đó chỉnh sửa và tiếp tục tạo ra.',
+ generateNumTip: 'Số lượng mỗi lần tạo',
+ tip: 'Sử dụng tính năng này sẽ tiêu tốn thêm token.',
},
speechToText: {
- title: 'Chuyển đổi Giọng nói thành Văn bản',
- description: 'Một khi được bật, bạn có thể sử dụng đầu vào giọng nói.',
- resDes: 'Đầu vào Giọng nói đã được bật',
+ title: 'Chuyển đổi giọng nói thành văn bản',
+ description: 'Khi được bật, bạn có thể sử dụng đầu vào bằng giọng nói.',
+ resDes: 'Đã bật đầu vào bằng giọng nói',
},
textToSpeech: {
- title: 'Chuyển đổi Văn bản thành Giọng nói',
- description: 'Một khi được bật, văn bản có thể được chuyển đổi thành giọng nói.',
- resDes: 'Chuyển đổi Văn bản thành Âm thanh đã được bật',
+ title: 'Chuyển đổi văn bản thành giọng nói',
+ description: 'Khi được bật, văn bản có thể được chuyển đổi thành giọng nói.',
+ resDes: 'Đã bật chuyển đổi văn bản thành âm thanh',
},
citation: {
- title: 'Trích dẫn và Ghi chú',
- description: 'Một khi được bật, hiển thị tài liệu nguồn và phần được ghi nhận của nội dung được tạo ra.',
- resDes: 'Trích dẫn và Ghi chú đã được bật',
+ title: 'Trích dẫn và chú thích',
+ description: 'Khi được bật, hiển thị nguồn tài liệu và phần được trích dẫn của nội dung được tạo ra.',
+ resDes: 'Đã bật trích dẫn và chú thích',
},
annotation: {
- title: 'Phản hồi Chú thích',
- description: 'Bạn có thể thêm phản hồi chất lượng cao vào bộ nhớ cache để ưu tiên phù hợp với các câu hỏi của người dùng tương tự.',
- resDes: 'Phản hồi Chú thích đã được bật',
+ title: 'Phản hồi có chú thích',
+ description: 'Bạn có thể thêm phản hồi chất lượng cao vào bộ nhớ cache để ưu tiên phù hợp với các câu hỏi tương tự của người dùng.',
+ resDes: 'Đã bật phản hồi có chú thích',
scoreThreshold: {
- title: 'Ngưỡng Điểm',
- description: 'Được sử dụng để đặt ngưỡng tương đồng cho phản hồi chú thích.',
- easyMatch: 'Tương đồng Dễ dàng',
- accurateMatch: 'Tương đồng Chính xác',
+ title: 'Ngưỡng điểm',
+ description: 'Được sử dụng để đặt ngưỡng tương đồng cho phản hồi có chú thích.',
+ easyMatch: 'Khớp dễ dàng',
+ accurateMatch: 'Khớp chính xác',
},
matchVariable: {
- title: 'Biến Phù hợp',
- choosePlaceholder: 'Chọn biến phù hợp',
+ title: 'Biến khớp',
+ choosePlaceholder: 'Chọn biến khớp',
},
- cacheManagement: 'Chú thích',
- cached: 'Đã ghi chú',
+ cacheManagement: 'Quản lý chú thích',
+ cached: 'Đã lưu cache',
remove: 'Xóa',
removeConfirm: 'Xóa chú thích này?',
add: 'Thêm chú thích',
@@ -104,36 +104,36 @@ const translation = {
},
dataSet: {
title: 'Ngữ cảnh',
- noData: 'Bạn có thể nhập Dữ liệu như là ngữ cảnh',
+ noData: 'Bạn có thể nhập dữ liệu làm ngữ cảnh',
words: 'Từ',
- textBlocks: 'Khối Văn bản',
- selectTitle: 'Chọn Kiến thức tham khảo',
+ textBlocks: 'Khối văn bản',
+ selectTitle: 'Chọn kiến thức tham khảo',
selected: 'Kiến thức đã chọn',
- noDataSet: 'Không tìm thấy Kiến thức',
- toCreate: 'Đi tới tạo mới',
- notSupportSelectMulti: 'Hiện chỉ hỗ trợ một Kiến thức',
+ noDataSet: 'Không tìm thấy kiến thức',
+ toCreate: 'Tạo mới',
+ notSupportSelectMulti: 'Hiện chỉ hỗ trợ một kiến thức',
queryVariable: {
- title: 'Biến Truy vấn',
- tip: 'Biến này sẽ được sử dụng làm đầu vào truy vấn cho việc truy xuất ngữ cảnh, lấy thông tin ngữ cảnh liên quan đến đầu vào của biến này.',
+ title: 'Biến truy vấn',
+ tip: 'Biến này sẽ được sử dụng làm đầu vào truy vấn để truy xuất ngữ cảnh, lấy thông tin ngữ cảnh liên quan đến đầu vào của biến này.',
choosePlaceholder: 'Chọn biến truy vấn',
noVar: 'Không có biến',
- noVarTip: 'xin vui lòng tạo một biến dưới phần Biến',
- unableToQueryDataSet: 'Không thể truy vấn Kiến thức',
- unableToQueryDataSetTip: 'Không thể truy vấn Kiến thức thành công, vui lòng chọn một biến truy vấn ngữ cảnh trong phần ngữ cảnh.',
- ok: 'OK',
- contextVarNotEmpty: 'biến truy vấn ngữ cảnh không thể trống',
- deleteContextVarTitle: 'Xóa biến “{{varName}}”?',
- deleteContextVarTip: 'Biến này đã được thiết lập là biến truy vấn ngữ cảnh, và việc loại bỏ nó sẽ ảnh hưởng đến việc sử dụng bình thường của Kiến thức. Nếu bạn vẫn cần xóa nó, vui lòng chọn lại nó trong phần ngữ cảnh.',
+ noVarTip: 'Vui lòng tạo một biến trong phần Biến',
+ unableToQueryDataSet: 'Không thể truy vấn kiến thức',
+ unableToQueryDataSetTip: 'Không thể truy vấn kiến thức thành công, vui lòng chọn một biến truy vấn ngữ cảnh trong phần ngữ cảnh.',
+ ok: 'Đồng ý',
+ contextVarNotEmpty: 'Biến truy vấn ngữ cảnh không thể trống',
+ deleteContextVarTitle: 'Xóa biến "{{varName}}"?',
+ deleteContextVarTip: 'Biến này đã được thiết lập là biến truy vấn ngữ cảnh, và việc xóa nó sẽ ảnh hưởng đến việc sử dụng bình thường của kiến thức. Nếu bạn vẫn cần xóa nó, vui lòng chọn lại biến khác trong phần ngữ cảnh.',
},
},
tools: {
title: 'Công cụ',
- tips: 'Công cụ cung cấp một phương thức gọi API chuẩn, lấy đầu vào người dùng hoặc biến làm tham số yêu cầu để truy vấn dữ liệu bên ngoài như ngữ cảnh.',
- toolsInUse: '{{count}} công cụ đang được sử dụng',
+ tips: 'Công cụ cung cấp phương thức gọi API tiêu chuẩn, sử dụng đầu vào của người dùng hoặc biến làm tham số yêu cầu để truy vấn dữ liệu bên ngoài như ngữ cảnh.',
+ toolsInUse: 'Đang sử dụng {{count}} công cụ',
modal: {
title: 'Công cụ',
toolType: {
- title: 'Loại Công cụ',
+ title: 'Loại công cụ',
placeholder: 'Vui lòng chọn loại công cụ',
},
name: {
@@ -141,20 +141,20 @@ const translation = {
placeholder: 'Vui lòng nhập tên',
},
variableName: {
- title: 'Tên Biến',
+ title: 'Tên biến',
placeholder: 'Vui lòng nhập tên biến',
},
},
},
conversationHistory: {
- title: 'Lịch sử Cuộc trò chuyện',
- description: 'Đặt tên tiền tố cho các vai trò trong cuộc trò chuyện',
- tip: 'Lịch sử Cuộc trò chuyện chưa được bật, vui lòng thêm vào phần prompt ở trên.',
+ title: 'Lịch sử cuộc trò chuyện',
+ description: 'Đặt tiền tố cho các vai trò trong cuộc trò chuyện',
+ tip: 'Lịch sử cuộc trò chuyện chưa được bật, vui lòng thêm vào phần prompt ở trên.',
learnMore: 'Tìm hiểu thêm',
editModal: {
- title: 'Chỉnh sửa Tên Vai trò Cuộc trò chuyện',
- userPrefix: 'Tiền tố Người dùng',
- assistantPrefix: 'Tiền tố Trợ lý',
+ title: 'Chỉnh sửa tên vai trò trong cuộc trò chuyện',
+ userPrefix: 'Tiền tố người dùng',
+ assistantPrefix: 'Tiền tố trợ lý',
},
},
toolbox: {
@@ -162,29 +162,29 @@ const translation = {
},
moderation: {
title: 'Kiểm duyệt nội dung',
- description: 'Bảo vệ đầu ra của mô hình bằng cách sử dụng API kiểm duyệt hoặc duy trì một danh sách từ nhạy cảm.',
- allEnabled: 'Nội dung ĐẦU VÀO/ĐẦU RA Đã Bật',
- inputEnabled: 'Nội dung ĐẦU VÀO Đã Bật',
- outputEnabled: 'Nội dung ĐẦU RA Đã Bật',
+ description: 'Bảo vệ đầu ra của mô hình bằng cách sử dụng API kiểm duyệt hoặc danh sách từ nhạy cảm.',
+ allEnabled: 'Đã bật kiểm duyệt nội dung ĐẦU VÀO/ĐẦU RA',
+ inputEnabled: 'Đã bật kiểm duyệt nội dung ĐẦU VÀO',
+ outputEnabled: 'Đã bật kiểm duyệt nội dung ĐẦU RA',
modal: {
title: 'Cài đặt kiểm duyệt nội dung',
provider: {
title: 'Nhà cung cấp',
openai: 'Kiểm duyệt OpenAI',
openaiTip: {
- prefix: 'Kiểm duyệt OpenAI yêu cầu một khóa API OpenAI được cấu hình trong ',
+ prefix: 'Kiểm duyệt OpenAI yêu cầu cấu hình khóa API OpenAI trong ',
suffix: '.',
},
keywords: 'Từ khóa',
},
keywords: {
- tip: 'Mỗi dòng một từ khóa, phân tách bằng các dòng. Tối đa 100 ký tự mỗi dòng.',
- placeholder: 'Mỗi dòng một từ khóa, phân tách bằng các dòng',
+ tip: 'Mỗi dòng một từ khóa, phân tách bằng dòng mới. Tối đa 100 ký tự mỗi dòng.',
+ placeholder: 'Mỗi dòng một từ khóa, phân tách bằng dòng mới',
line: 'Dòng',
},
content: {
- input: 'Kiểm duyệt Nội dung ĐẦU VÀO',
- output: 'Kiểm duyệt Nội dung ĐẦU RA',
+ input: 'Kiểm duyệt nội dung ĐẦU VÀO',
+ output: 'Kiểm duyệt nội dung ĐẀU RA',
preset: 'Câu trả lời mẫu',
placeholder: 'Nội dung câu trả lời mẫu ở đây',
condition: 'Đã bật ít nhất một kiểm duyệt nội dung ĐẦU VÀO và ĐẦU RA',
@@ -193,7 +193,7 @@ const translation = {
supportMarkdown: 'Hỗ trợ Markdown',
},
openaiNotConfig: {
- before: 'Kiểm duyệt OpenAI yêu cầu một khóa API OpenAI được cấu hình trong',
+ before: 'Kiểm duyệt OpenAI yêu cầu cấu hình khóa API OpenAI trong',
after: '',
},
},
@@ -202,63 +202,57 @@ const translation = {
automatic: {
title: 'Tự động hóa triển khai ứng dụng',
description: 'Mô tả tình huống của bạn, Dify sẽ tự động hóa một ứng dụng cho bạn.',
- intendedAudience: 'Ai là đối tượng mục tiêu?',
- intendedAudiencePlaceHolder: 'ví dụ: Sinh viên',
- solveProblem: 'Họ hy vọng AI có thể giải quyết vấn đề gì cho họ?',
- solveProblemPlaceHolder: 'ví dụ: Đánh giá thành tích học tập',
- generate: 'Tạo ra',
- audiencesRequired: 'Yêu cầu Đối tượng mục tiêu',
- problemRequired: 'Vấn đề cần thiết',
+ intendedAudience: 'Đối tượng mục tiêu là ai?',
+ intendedAudiencePlaceHolder: 'Ví dụ: Sinh viên',
+ solveProblem: 'Họ hy vọng AI có thể giải quyết vấn đề gì?',
+ solveProblemPlaceHolder: 'Ví dụ: Đánh giá thành tích học tập',
+ generate: 'Tạo',
+ audiencesRequired: 'Yêu cầu nhập đối tượng mục tiêu',
+ problemRequired: 'Yêu cầu nhập vấn đề cần giải quyết',
resTitle: 'Chúng tôi đã tự động hóa ứng dụng sau đây cho bạn.',
apply: 'Áp dụng tự động hóa này',
noData: 'Mô tả tình huống sử dụng của bạn ở bên trái, xem trước tự động hóa sẽ hiển thị ở đây.',
- loading: 'Tự động hóa ứng dụng cho bạn...',
+ loading: 'Đang tự động hóa ứng dụng cho bạn...',
overwriteTitle: 'Ghi đè cấu hình hiện tại?',
overwriteMessage: 'Áp dụng tự động hóa này sẽ ghi đè lên cấu hình hiện tại.',
},
resetConfig: {
title: 'Xác nhận đặt lại?',
- message:
- 'Đặt lại sẽ loại bỏ các thay đổi, khôi phục cấu hình đã xuất bản lần cuối.',
+ message: 'Đặt lại sẽ loại bỏ các thay đổi, khôi phục cấu hình đã xuất bản lần cuối.',
},
errorMessage: {
- nameOfKeyRequired: 'tên của khóa: {{key}} được yêu cầu',
- valueOfVarRequired: 'giá trị {{key}} không thể trống',
- queryRequired: 'Văn bản yêu cầu được yêu cầu.',
- waitForResponse:
- 'Vui lòng đợi phản hồi của tin nhắn trước để hoàn thành.',
- waitForBatchResponse:
- 'Vui lòng đợi phản hồi của tác vụ hàng loạt để hoàn thành.',
+ nameOfKeyRequired: 'Tên của khóa: {{key}} là bắt buộc',
+ valueOfVarRequired: 'Giá trị {{key}} không thể trống',
+ queryRequired: 'Văn bản yêu cầu là bắt buộc.',
+ waitForResponse: 'Vui lòng đợi phản hồi của tin nhắn trước để hoàn thành.',
+ waitForBatchResponse: 'Vui lòng đợi phản hồi của tác vụ hàng loạt để hoàn thành.',
notSelectModel: 'Vui lòng chọn một mô hình',
waitForImgUpload: 'Vui lòng đợi hình ảnh được tải lên',
},
chatSubTitle: 'Hướng dẫn',
- completionSubTitle: 'Tiền Tố Lời Nhắc',
- promptTip:
- 'Lời nhắc hướng dẫn các phản hồi của AI với hướng dẫn và ràng buộc. Chèn biến như {{input}}. Lời nhắc này sẽ không được hiển thị cho người dùng.',
+ completionSubTitle: 'Tiền tố lời nhắc',
+ promptTip: 'Lời nhắc hướng dẫn các phản hồi của AI với hướng dẫn và ràng buộc. Chèn biến như {{input}}. Lời nhắc này sẽ không được hiển thị cho người dùng.',
formattingChangedTitle: 'Định dạng đã thay đổi',
- formattingChangedText:
- 'Thay đổi định dạng sẽ đặt lại khu vực gỡ lỗi, bạn có chắc chắn không?',
+ formattingChangedText: 'Thay đổi định dạng sẽ đặt lại khu vực gỡ lỗi, bạn có chắc chắn không?',
variableTitle: 'Biến',
- variableTip:
- 'Người dùng điền các biến vào một biểu mẫu, tự động thay thế các biến trong lời nhắc.',
- notSetVar: 'Biến cho phép người dùng giới thiệu các từ khóa lời nhắc hoặc mở đầu khi điền vào biểu mẫu. Bạn có thể thử nhập "{{input}}" trong các từ khóa lời nhắc.',
- autoAddVar: 'Biến không xác định được tham chiếu trong tiền-lời nhắc, bạn có muốn thêm chúng vào biểu mẫu đầu vào người dùng không?',
+ variableTip: 'Người dùng điền các biến vào một biểu mẫu, tự động thay thế các biến trong lời nhắc.',
+ notSetVar: 'Biến cho phép người dùng đưa ra từ khóa lời nhắc hoặc mở đầu khi điền vào biểu mẫu. Bạn có thể thử nhập "{{input}}" trong các từ khóa lời nhắc.',
+ autoAddVar: 'Phát hiện biến không xác định được tham chiếu trong tiền-lời nhắc, bạn có muốn thêm chúng vào biểu mẫu đầu vào người dùng không?',
variableTable: {
- key: 'Khóa Biến',
- name: 'Tên Trường Nhập Liệu Người Dùng',
+ key: 'Khóa biến',
+ name: 'Tên trường nhập liệu người dùng',
optional: 'Tùy chọn',
- type: 'Loại Nhập Liệu',
+ type: 'Loại nhập liệu',
action: 'Hành động',
typeString: 'Chuỗi',
- typeSelect: 'Chọn',
+ typeSelect: 'Lựa chọn',
},
varKeyError: {
canNoBeEmpty: 'Khóa biến không thể trống',
tooLong: 'Khóa biến: {{key}} quá dài. Không thể dài hơn 30 ký tự',
notValid: 'Khóa biến: {{key}} không hợp lệ. Chỉ có thể chứa chữ cái, số, và dấu gạch dưới',
notStartWithNumber: 'Khóa biến: {{key}} không thể bắt đầu bằng số',
- keyAlreadyExists: 'Khóa biến: :{{key}} đã tồn tại',
+ keyAlreadyExists: 'Khóa biến: {{key}} đã tồn tại',
},
otherError: {
promptNoBeEmpty: 'Lời nhắc không thể trống',
@@ -266,159 +260,156 @@ const translation = {
queryNoBeEmpty: 'Truy vấn phải được thiết lập trong lời nhắc',
},
variableConig: {
- 'addModalTitle': 'Thêm Trường Nhập',
- 'editModalTitle': 'Chỉnh Sửa Trường Nhập',
+ 'addModalTitle': 'Thêm trường nhập',
+ 'editModalTitle': 'Chỉnh sửa trường nhập',
'description': 'Cài đặt cho biến {{varName}}',
- 'fieldType': 'Loại Trường',
+ 'fieldType': 'Loại trường',
'string': 'Văn bản ngắn',
'text-input': 'Văn bản ngắn',
'paragraph': 'Đoạn văn',
- 'select': 'Chọn',
+ 'select': 'Lựa chọn',
'number': 'Số',
- 'notSet': 'Không thiết lập, hãy thử nhập {{input}} trong gợi ý tiền tố',
+ 'notSet': 'Chưa thiết lập, hãy thử nhập {{input}} trong gợi ý tiền tố',
'stringTitle': 'Tùy chọn hộp văn bản biểu mẫu',
'maxLength': 'Độ dài tối đa',
'options': 'Tùy chọn',
'addOption': 'Thêm tùy chọn',
- 'apiBasedVar': 'Biến Dựa trên API',
- 'varName': 'Tên Biến',
- 'labelName': 'Tên Nhãn',
+ 'apiBasedVar': 'Biến dựa trên API',
+ 'varName': 'Tên biến',
+ 'labelName': 'Tên nhãn',
'inputPlaceholder': 'Vui lòng nhập',
'required': 'Bắt buộc',
'errorMsg': {
varNameRequired: 'Tên biến là bắt buộc',
labelNameRequired: 'Tên nhãn là bắt buộc',
- varNameCanBeRepeat: 'Tên biến không được lặp lại',
- atLeastOneOption: 'Ít nhất một tùy chọn là bắt buộc',
+ varNameCanBeRepeat: 'Tên biến không được trùng lặp',
+ atLeastOneOption: 'Cần ít nhất một tùy chọn',
optionRepeat: 'Có các tùy chọn trùng lặp',
},
},
vision: {
- name: 'Tầm nhìn',
- description: 'Cho phép tầm nhìn sẽ cho phép mô hình nhận hình ảnh và trả lời các câu hỏi về chúng.',
+ name: 'Thị giác',
+ description: 'Cho phép tính năng thị giác sẽ cho phép mô hình nhận diện hình ảnh và trả lời các câu hỏi về chúng.',
settings: 'Cài đặt',
visionSettings: {
- title: 'Cài đặt Tầm nhìn',
+ title: 'Cài đặt thị giác',
resolution: 'Độ phân giải',
resolutionTooltip: `Độ phân giải thấp sẽ cho phép mô hình nhận một phiên bản hình ảnh 512 x 512 thấp hơn, và đại diện cho hình ảnh với ngân sách 65 token. Điều này cho phép API trả về phản hồi nhanh hơn và tiêu thụ ít token đầu vào cho các trường hợp sử dụng không yêu cầu chi tiết cao.
\n
- độ phân giải cao sẽ đầu tiên cho phép mô hình nhìn thấy hình ảnh thấp hơn và sau đó tạo ra các cắt chi tiết của hình ảnh đầu vào dưới dạng hình vuông 512px dựa trên kích thước hình ảnh đầu vào. Mỗi cắt chi tiết sử dụng hai lần ngân sách token cho tổng cộng 129 token.`,
+ Độ phân giải cao sẽ đầu tiên cho phép mô hình nhìn thấy hình ảnh thấp hơn và sau đó tạo ra các cắt chi tiết của hình ảnh đầu vào dưới dạng hình vuông 512px dựa trên kích thước hình ảnh đầu vào. Mỗi cắt chi tiết sử dụng hai lần ngân sách token cho tổng cộng 129 token.`,
high: 'Cao',
low: 'Thấp',
- uploadMethod: 'Phương thức Tải lên',
+ uploadMethod: 'Phương thức tải lên',
both: 'Cả hai',
- localUpload: 'Tải lên Nội bộ',
+ localUpload: 'Tải lên nội bộ',
url: 'URL',
- uploadLimit: 'Giới hạn Tải lên',
+ uploadLimit: 'Giới hạn tải lên',
},
},
voice: {
name: 'Giọng nói',
defaultDisplay: 'Giọng mặc định',
- description: 'Cài đặt giọng nói văn bản thành tiếng',
+ description: 'Cài đặt chuyển đổi văn bản thành giọng nói',
settings: 'Cài đặt',
voiceSettings: {
- title: 'Cài đặt Giọng nói',
+ title: 'Cài đặt giọng nói',
language: 'Ngôn ngữ',
- resolutionTooltip: 'Giọng nói văn bản hỗ trợ ngôn ngữ。',
- voice: 'Giọng',
- autoPlay: 'chạy tự động',
- autoPlayEnabled: 'bật',
- autoPlayDisabled: 'Khép kín',
+ resolutionTooltip: 'Chuyển đổi văn bản thành giọng nói hỗ trợ ngôn ngữ.',
+ voice: 'Giọng nói',
+ autoPlay: 'Tự động phát',
+ autoPlayEnabled: 'Đã bật',
+ autoPlayDisabled: 'Đã tắt',
},
},
openingStatement: {
- title: 'Mở đầu Trò chuyện',
+ title: 'Mở đầu cuộc trò chuyện',
add: 'Thêm',
writeOpener: 'Viết câu mở đầu',
placeholder: 'Viết thông điệp mở đầu của bạn ở đây, bạn có thể sử dụng biến, hãy thử nhập {{biến}}.',
- openingQuestion: 'Câu Hỏi Mở đầu',
- noDataPlaceHolder:
- 'Bắt đầu cuộc trò chuyện với người dùng có thể giúp AI thiết lập một mối quan hệ gần gũi hơn với họ trong các ứng dụng trò chuyện.',
+ openingQuestion: 'Câu hỏi mở đầu',
+ noDataPlaceHolder: 'Bắt đầu cuộc trò chuyện với người dùng có thể giúp AI thiết lập mối quan hệ gần gũi hơn với họ trong các ứng dụng trò chuyện.',
varTip: 'Bạn có thể sử dụng biến, hãy thử nhập {{biến}}',
- tooShort: 'Ít nhất 20 từ của lời nhắc ban đầu được yêu cầu để tạo ra các lời nhận đầu tiên cho cuộc trò chuyện.',
- notIncludeKey: 'Lời nhắc ban đầu không bao gồm biến: {{khóa}}. Vui lòng thêm nó vào lời nhắc ban đầu.',
+ tooShort: 'Cần ít nhất 20 từ trong lời nhắc ban đầu để tạo ra các câu mở đầu cho cuộc trò chuyện.',
+ notIncludeKey: 'Lời nhắc ban đầu không bao gồm biến: {{key}}. Vui lòng thêm nó vào lời nhắc ban đầu.',
},
modelConfig: {
model: 'Mô hình',
- setTone: 'Thiết lập tông của phản hồi',
- title: 'Mô hình và Tham số',
+ setTone: 'Thiết lập giọng điệu của phản hồi',
+ title: 'Mô hình và tham số',
modeType: {
chat: 'Trò chuyện',
completion: 'Hoàn thành',
},
},
inputs: {
- title: 'Gỡ Lỗi và Xem Trước',
+ title: 'Gỡ lỗi và xem trước',
noPrompt: 'Hãy thử viết một số lời nhắc trong trường tiền-lời nhắc',
- userInputField: 'Trường Nhập Liệu Người Dùng',
+ userInputField: 'Trường nhập liệu người dùng',
noVar: 'Điền vào giá trị của biến, nó sẽ tự động thay thế từ khóa lời nhắc mỗi khi bắt đầu phiên mới.',
- chatVarTip:
- 'Điền vào giá trị của biến, nó sẽ tự động thay thế từ khóa lời nhắc mỗi khi bắt đầu phiên mới',
- completionVarTip:
- 'Điền vào giá trị của biến, nó sẽ tự động thay thế từ khóa lời nhắc mỗi khi một câu hỏi được gửi.',
- previewTitle: 'Xem Trước Lời Nhắc',
- queryTitle: 'Nội dung Truy vấn',
+ chatVarTip: 'Điền vào giá trị của biến, nó sẽ tự động thay thế từ khóa lời nhắc mỗi khi bắt đầu phiên mới',
+ completionVarTip: 'Điền vào giá trị của biến, nó sẽ tự động thay thế từ khóa lời nhắc mỗi khi một câu hỏi được gửi.',
+ previewTitle: 'Xem trước lời nhắc',
+ queryTitle: 'Nội dung truy vấn',
queryPlaceholder: 'Vui lòng nhập văn bản yêu cầu.',
run: 'CHẠY',
},
- result: 'Văn bản Đầu Ra',
+ result: 'Văn bản đầu ra',
datasetConfig: {
- settingTitle: 'Cài đặt Truy xuất',
- knowledgeTip: 'Nhấn vào nút “+” để thêm kiến thức',
+ settingTitle: 'Cài đặt truy xuất',
+ knowledgeTip: 'Nhấn vào nút "+" để thêm kiến thức',
retrieveOneWay: {
- title: 'N-to-1 Truy xuất',
- description: 'Dựa trên ý định của người dùng và mô tả Kiến thức, Agent tự động chọn Kiến thức tốt nhất để truy vấn. Tốt nhất cho các ứng dụng có Kiến thức cụ thể, giới hạn.',
+ title: 'Truy xuất N-to-1',
+ description: 'Dựa trên ý định của người dùng và mô tả kiến thức, Agent tự động chọn kiến thức tốt nhất để truy vấn. Phù hợp nhất cho các ứng dụng có kiến thức cụ thể, giới hạn.',
},
retrieveMultiWay: {
title: 'Truy xuất đa hướng',
- description: 'Dựa trên ý định của người dùng, truy vấn qua tất cả Kiến thức, truy xuất văn bản liên quan từ nhiều nguồn và chọn ra kết quả tốt nhất phù hợp với truy vấn của người dùng sau khi sắp xếp lại. Yêu cầu cấu hình của API Rerank model.',
+ description: 'Dựa trên ý định của người dùng, truy vấn qua tất cả kiến thức, truy xuất văn bản liên quan từ nhiều nguồn và chọn ra kết quả tốt nhất phù hợp với truy vấn của người dùng sau khi sắp xếp lại. Yêu cầu cấu hình của API mô hình Rerank.',
},
- rerankModelRequired: 'Rerank model là bắt buộc',
+ rerankModelRequired: 'Mô hình Rerank là bắt buộc',
params: 'Tham số',
top_k: 'Top K',
- top_kTip: 'Sử dụng để lọc các phần chính xác nhất với các câu hỏi của người dùng. Hệ thống cũng sẽ tự động điều chỉnh giá trị của Top K, theo max_tokens của mô hình đã chọn.',
- score_threshold: 'Ngưỡng Điểm',
+ top_kTip: 'Sử dụng để lọc các phần chính xác nhất với câu hỏi của người dùng. Hệ thống cũng sẽ tự động điều chỉnh giá trị của Top K, theo max_tokens của mô hình đã chọn.',
+ score_threshold: 'Ngưỡng điểm',
score_thresholdTip: 'Sử dụng để thiết lập ngưỡng tương đồng cho việc lọc các phần.',
- retrieveChangeTip: 'Thay đổi chế độ chỉ mục và chế độ truy xuất có thể ảnh hưởng đến các ứng dụng liên quan đến Kiến thức này.',
+ retrieveChangeTip: 'Thay đổi chế độ chỉ mục và chế độ truy xuất có thể ảnh hưởng đến các ứng dụng liên quan đến kiến thức này.',
},
- debugAsSingleModel: 'Gỡ Lỗi như Một Mô hình',
- debugAsMultipleModel: 'Gỡ Lỗi như Nhiều Mô hình',
+ debugAsSingleModel: 'Gỡ lỗi như một mô hình',
+ debugAsMultipleModel: 'Gỡ lỗi như nhiều mô hình',
duplicateModel: 'Sao chép',
publishAs: 'Xuất bản dưới dạng',
assistantType: {
- name: 'Loại Trợ lý',
+ name: 'Loại trợ lý',
chatAssistant: {
- name: 'Trợ lý Cơ bản',
+ name: 'Trợ lý cơ bản',
description: 'Xây dựng một trợ lý dựa trên trò chuyện sử dụng một Mô hình Ngôn ngữ Lớn.',
},
agentAssistant: {
- name: 'Trợ lý Tác nhân',
- description: 'Xây dựng một Tác nhân thông minh có thể tự động chọn các công cụ để hoàn thành các nhiệm vụ.',
+ name: 'Trợ lý tác nhân',
+ description: 'Xây dựng một tác nhân thông minh có thể tự động chọn các công cụ để hoàn thành các nhiệm vụ.',
},
},
agent: {
- agentMode: 'Chế độ Tác nhân',
+ agentMode: 'Chế độ tác nhân',
agentModeDes: 'Thiết lập loại chế độ suy luận cho tác nhân',
agentModeType: {
ReACT: 'ReAct',
- functionCall: 'Gọi Hàm',
+ functionCall: 'Gọi hàm',
},
setting: {
- name: 'Thiết lập Tác nhân',
- description: 'Thiết lập Tác nhân cho phép thiết lập chế độ tác nhân và các tính năng nâng cao như các lời nhắc tích hợp sẵn, chỉ có sẵn trong loại Tác nhân.',
+ name: 'Thiết lập tác nhân',
+ description: 'Thiết lập tác nhân cho phép cấu hình chế độ tác nhân và các tính năng nâng cao như lời nhắc tích hợp sẵn, chỉ có sẵn trong loại Tác nhân.',
maximumIterations: {
- name: 'Số Lần Lặp Tối đa',
- description: 'Giới hạn số lần lặp một trợ lý tác nhân có thể thực hiện',
+ name: 'Số lần lặp tối đa',
+ description: 'Giới hạn số lần lặp mà một trợ lý tác nhân có thể thực hiện',
},
},
- buildInPrompt: 'Lời Nhắc Tích Hợp',
- firstPrompt: 'Tiền-lời Nhắc Đầu Tiên',
- nextIteration: 'Lần Lặp Tiếp Theo',
- promptPlaceholder: 'Viết tiền-lời nhắc của bạn ở đây',
+ buildInPrompt: 'Lời nhắc tích hợp',
+ firstPrompt: 'Lời nhắc đầu tiên',
+ nextIteration: 'Lần lặp tiếp theo',
+ promptPlaceholder: 'Viết lời nhắc của bạn ở đây',
tools: {
name: 'Công cụ',
- description: 'Sử dụng công cụ có thể mở rộng các khả năng của LLM, như tìm kiếm trên internet hoặc thực hiện các phép tính khoa học',
+ description: 'Sử dụng công cụ có thể mở rộng khả năng của LLM, như tìm kiếm trên internet hoặc thực hiện các phép tính khoa học',
enabled: 'Đã kích hoạt',
},
},
diff --git a/web/i18n/vi-VN/app-log.ts b/web/i18n/vi-VN/app-log.ts
index 193927c91d..7440be6126 100644
--- a/web/i18n/vi-VN/app-log.ts
+++ b/web/i18n/vi-VN/app-log.ts
@@ -5,85 +5,85 @@ const translation = {
table: {
header: {
time: 'Thời gian',
- endUser: 'Người Dùng Cuối',
- input: 'Đầu Vào',
- output: 'Đầu Ra',
- summary: 'Tiêu Đề',
- messageCount: 'Số Lượng Tin Nhắn',
- userRate: 'Tỷ Lệ Người Dùng',
- adminRate: 'Tỷ Lệ Quản Trị',
+ endUser: 'Người dùng cuối',
+ input: 'Đầu vào',
+ output: 'Đầu ra',
+ summary: 'Tóm tắt',
+ messageCount: 'Số lượng tin nhắn',
+ userRate: 'Đánh giá người dùng',
+ adminRate: 'Đánh giá quản trị viên',
startTime: 'THỜI GIAN BẮT ĐẦU',
status: 'TRẠNG THÁI',
runtime: 'THỜI GIAN CHẠY',
- tokens: 'MÃ',
+ tokens: 'TOKEN',
user: 'NGƯỜI DÙNG CUỐI',
version: 'PHIÊN BẢN',
},
pagination: {
previous: 'Trước',
- next: 'Tiếp',
+ next: 'Sau',
},
empty: {
noChat: 'Chưa có cuộc trò chuyện',
noOutput: 'Không có đầu ra',
element: {
- title: 'Có ai đó ở đó không?',
- content: 'Quan sát và chú thích các tương tác giữa người dùng cuối và ứng dụng trí tuệ nhân tạo ở đây để liên tục cải thiện độ chính xác của trí tuệ nhân tạo. Bạn có thể thử chia sẻ hoặc kiểm tra ứng dụng Web một cách tự nhiên, sau đó quay lại trang này.',
+ title: 'Chưa có dữ liệu',
+ content: 'Quan sát và chú thích các tương tác giữa người dùng cuối và ứng dụng trí tuệ nhân tạo ở đây để liên tục cải thiện độ chính xác của AI. Bạn có thể thử chia sẻ hoặc kiểm tra ứng dụng Web, sau đó quay lại trang này.',
},
},
},
detail: {
time: 'Thời gian',
- conversationId: 'ID Cuộc Trò Chuyện',
- promptTemplate: 'Mẫu Nhắc Nhở',
- promptTemplateBeforeChat: 'Mẫu Nhắc Nhở Trước Trò Chuyện · Như Tin Nhắn Hệ Thống',
- annotationTip: 'Cải Thiện Được Đánh Dấu bởi {{user}}',
+ conversationId: 'ID cuộc trò chuyện',
+ promptTemplate: 'Mẫu lời nhắc',
+ promptTemplateBeforeChat: 'Mẫu lời nhắc trước trò chuyện · Tin nhắn hệ thống',
+ annotationTip: 'Cải thiện được đánh dấu bởi {{user}}',
timeConsuming: '',
second: 'giây',
- tokenCost: 'Chi Phí Mã',
- loading: 'đang tải',
+ tokenCost: 'Chi phí token',
+ loading: 'Đang tải',
operation: {
- like: 'thích',
- dislike: 'không thích',
- addAnnotation: 'Thêm Cải Thiện',
- editAnnotation: 'Chỉnh Sửa Cải Thiện',
- annotationPlaceholder: 'Nhập câu trả lời mong muốn mà bạn muốn trí tuệ nhân tạo trả lời, điều này có thể được sử dụng để điều chỉnh mô hình và cải thiện liên tục chất lượng sinh văn bản trong tương lai.',
+ like: 'Thích',
+ dislike: 'Không thích',
+ addAnnotation: 'Thêm chú thích',
+ editAnnotation: 'Chỉnh sửa chú thích',
+ annotationPlaceholder: 'Nhập câu trả lời mong muốn từ AI. Điều này sẽ được sử dụng để điều chỉnh mô hình và cải thiện chất lượng sinh văn bản trong tương lai.',
},
variables: 'Biến',
- uploadImages: 'Ảnh Đã Tải Lên',
+ uploadImages: 'Ảnh đã tải lên',
},
filter: {
period: {
today: 'Hôm nay',
- last7days: '7 Ngày Qua',
- last4weeks: '4 Tuần Qua',
- last3months: '3 Tháng Qua',
- last12months: '12 Tháng Qua',
- monthToDate: 'Tháng Đến Hiện Tại',
- quarterToDate: 'Quý Đến Hiện Tại',
- yearToDate: 'Năm Đến Hiện Tại',
- allTime: 'Tất Cả Thời Gian',
+ last7days: '7 ngày qua',
+ last4weeks: '4 tuần qua',
+ last3months: '3 tháng qua',
+ last12months: '12 tháng qua',
+ monthToDate: 'Tháng hiện tại',
+ quarterToDate: 'Quý hiện tại',
+ yearToDate: 'Năm hiện tại',
+ allTime: 'Tất cả thời gian',
},
annotation: {
all: 'Tất cả',
- annotated: 'Cải Thiện Đã Đánh Dấu ({{count}} mục)',
- not_annotated: 'Chưa Đánh Dấu',
+ annotated: 'Đã chú thích ({{count}} mục)',
+ not_annotated: 'Chưa chú thích',
},
},
- workflowTitle: 'Nhật Ký Quy Trình Làm Việc',
- workflowSubtitle: 'Nhật ký ghi lại hoạt động của Tự Động Hóa.',
+ workflowTitle: 'Nhật ký quy trình làm việc',
+ workflowSubtitle: 'Nhật ký ghi lại hoạt động của Tự động hóa.',
runDetail: {
- title: 'Nhật Ký Cuộc Trò Chuyện',
- workflowTitle: 'Chi Tiết Nhật Ký',
+ title: 'Nhật ký cuộc trò chuyện',
+ workflowTitle: 'Chi tiết nhật ký',
},
- promptLog: 'Nhật Ký Nhắc Nhở',
- AgentLog: 'Nhật ký đại lý',
+ promptLog: 'Nhật ký lời nhắc',
+ AgentLog: 'Nhật ký tác nhân',
viewLog: 'Xem nhật ký',
agentLogDetail: {
- AgentMode: 'Chế độ đại lý',
- toolUsed: 'Công cụ được sử dụng',
- iterations: 'Lặp lại',
- iteration: 'Lặp lại',
+ AgentMode: 'Chế độ tác nhân',
+ toolUsed: 'Công cụ đã sử dụng',
+ iterations: 'Số lần lặp',
+ iteration: 'Lần lặp',
finalProcessing: 'Xử lý cuối cùng',
},
}
diff --git a/web/i18n/vi-VN/app-overview.ts b/web/i18n/vi-VN/app-overview.ts
index c023850d71..55a53d73a2 100644
--- a/web/i18n/vi-VN/app-overview.ts
+++ b/web/i18n/vi-VN/app-overview.ts
@@ -2,153 +2,153 @@ const translation = {
welcome: {
firstStepTip: 'Để bắt đầu,',
enterKeyTip: 'nhập khóa API OpenAI của bạn bên dưới',
- getKeyTip: 'Lấy API Key của bạn từ bảng điều khiển OpenAI',
- placeholder: 'Khóa API OpenAI của bạn (vd. sk-xxxx)',
+ getKeyTip: 'Lấy khóa API từ bảng điều khiển OpenAI',
+ placeholder: 'Khóa API OpenAI của bạn (ví dụ: sk-xxxx)',
},
apiKeyInfo: {
cloud: {
trial: {
- title: 'Bạn đang sử dụng hạn mức thử nghiệm của {{providerName}}.',
- description: 'Hạn mức thử nghiệm được cung cấp cho việc kiểm tra của bạn. Trước khi hết lượt gọi hạn mức thử nghiệm, vui lòng thiết lập nhà cung cấp mô hình của riêng bạn hoặc mua thêm hạn mức.',
+ title: 'Bạn đang sử dụng gói dùng thử của {{providerName}}.',
+ description: 'Gói dùng thử được cung cấp để bạn kiểm tra. Trước khi hết lượt gọi của gói dùng thử, vui lòng thiết lập nhà cung cấp mô hình riêng hoặc mua thêm hạn mức.',
},
exhausted: {
- title: 'Hạn mức thử nghiệm của bạn đã được sử dụng hết, vui lòng thiết lập APIKey của bạn.',
- description: 'Hạn mức thử nghiệm của bạn đã được sử dụng hết. Vui lòng thiết lập nhà cung cấp mô hình của riêng bạn hoặc mua thêm hạn mức.',
+ title: 'Gói dùng thử của bạn đã hết, vui lòng thiết lập khóa API của bạn.',
+ description: 'Gói dùng thử của bạn đã hết. Vui lòng thiết lập nhà cung cấp mô hình riêng hoặc mua thêm hạn mức.',
},
},
selfHost: {
title: {
row1: 'Để bắt đầu,',
- row2: 'thiết lập nhà cung cấp mô hình của bạn trước.',
+ row2: 'hãy thiết lập nhà cung cấp mô hình của bạn trước.',
},
},
callTimes: 'Số lần gọi',
usedToken: 'Token đã sử dụng',
- setAPIBtn: 'Đi đến thiết lập nhà cung cấp mô hình',
- tryCloud: 'Hoặc thử phiên bản điện toán đám mây của Dify với báo giá miễn phí',
+ setAPIBtn: 'Thiết lập nhà cung cấp mô hình',
+ tryCloud: 'Hoặc dùng thử phiên bản đám mây của Dify với gói miễn phí',
},
overview: {
title: 'Tổng quan',
appInfo: {
explanation: 'Ứng dụng web AI sẵn sàng sử dụng',
- accessibleAddress: 'Địa chỉ công cộng',
+ accessibleAddress: 'Địa chỉ công khai',
preview: 'Xem trước',
regenerate: 'Tạo lại',
- regenerateNotice: 'Bạn có muốn tạo lại địa chỉ công cộng không?',
+ regenerateNotice: 'Bạn có muốn tạo lại địa chỉ công khai không?',
preUseReminder: 'Vui lòng kích hoạt ứng dụng web trước khi tiếp tục.',
settings: {
entry: 'Cài đặt',
title: 'Cài đặt ứng dụng web',
webName: 'Tên ứng dụng web',
webDesc: 'Mô tả ứng dụng web',
- webDescTip: 'Văn bản này sẽ được hiển thị ở phía máy khách, cung cấp hướng dẫn cơ bản về cách sử dụng ứng dụng',
+ webDescTip: 'Văn bản này sẽ hiển thị ở phía người dùng, cung cấp hướng dẫn cơ bản về cách sử dụng ứng dụng',
webDescPlaceholder: 'Nhập mô tả của ứng dụng web',
language: 'Ngôn ngữ',
workflow: {
- title: 'Các Bước Quy trình',
+ title: 'Các bước quy trình',
show: 'Hiển thị',
hide: 'Ẩn',
},
- chatColorTheme: 'Chủ đề màu sắc trò chuyện',
- chatColorThemeDesc: 'Thiết lập chủ đề màu sắc của chatbot',
+ chatColorTheme: 'Giao diện màu trò chuyện',
+ chatColorThemeDesc: 'Thiết lập giao diện màu của chatbot',
chatColorThemeInverted: 'Đảo ngược',
- invalidHexMessage: 'Giá trị không hợp lệ của hệ màu hex',
+ invalidHexMessage: 'Giá trị mã màu không hợp lệ',
more: {
entry: 'Hiển thị thêm cài đặt',
copyright: 'Bản quyền',
copyRightPlaceholder: 'Nhập tên tác giả hoặc tổ chức',
privacyPolicy: 'Chính sách bảo mật',
privacyPolicyPlaceholder: 'Nhập liên kết chính sách bảo mật',
- privacyPolicyTip: 'Giúp khách truy cập hiểu được dữ liệu mà ứng dụng thu thập, xem Chính sách bảo mật của Dify.',
- customDisclaimer: 'Tùy chỉnh từ chối trách nhiệm',
- customDisclaimerPlaceholder: 'Nhập liên kết từ chối trách nhiệm',
- customDisclaimerTip: 'Liên kết này sẽ được hiển thị ở phía máy khách, cung cấp thông tin về trách nhiệm của ứng dụng',
+ privacyPolicyTip: 'Giúp người dùng hiểu dữ liệu mà ứng dụng thu thập, xem Chính sách bảo mật của Dify.',
+ customDisclaimer: 'Tuyên bố từ chối trách nhiệm tùy chỉnh',
+ customDisclaimerPlaceholder: 'Nhập liên kết tuyên bố từ chối trách nhiệm',
+ customDisclaimerTip: 'Liên kết này sẽ hiển thị ở phía người dùng, cung cấp thông tin về trách nhiệm của ứng dụng',
},
},
embedded: {
entry: 'Nhúng',
title: 'Nhúng vào trang web',
explanation: 'Chọn cách nhúng ứng dụng trò chuyện vào trang web của bạn',
- iframe: 'Để thêm ứng dụng trò chuyện ở bất kỳ đâu trên trang web của bạn, hãy thêm iframe này vào mã HTML của bạn.',
- scripts: 'Để thêm ứng dụng trò chuyện vào góc dưới bên phải của trang web của bạn, thêm mã này vào mã HTML của bạn.',
- chromePlugin: 'Cài đặt Tiện ích Mở rộng Dify Chatbot cho Chrome',
+ iframe: 'Để thêm ứng dụng trò chuyện vào bất kỳ đâu trên trang web của bạn, hãy thêm iframe này vào mã HTML của bạn.',
+ scripts: 'Để thêm ứng dụng trò chuyện vào góc dưới bên phải của trang web, thêm mã này vào mã HTML của bạn.',
+ chromePlugin: 'Cài đặt tiện ích mở rộng Dify Chatbot cho Chrome',
copied: 'Đã sao chép',
copy: 'Sao chép',
},
qrcode: {
title: 'Mã QR để chia sẻ',
- scan: 'Quét và Chia sẻ Ứng dụng',
- download: 'Tải xuống Mã QR',
+ scan: 'Quét và chia sẻ ứng dụng',
+ download: 'Tải xuống mã QR',
},
customize: {
way: 'cách',
entry: 'Tùy chỉnh',
title: 'Tùy chỉnh ứng dụng web AI',
- explanation: 'Bạn có thể tùy chỉnh giao diện phía trước của Ứng dụng Web để phù hợp với kịch bản và nhu cầu phong cách của mình.',
+ explanation: 'Bạn có thể tùy chỉnh giao diện của ứng dụng web để phù hợp với kịch bản và phong cách mong muốn.',
way1: {
- name: 'Fork mã nguồn của máy khách, sửa đổi và triển khai lên Vercel (được khuyến nghị)',
- step1: 'Fork mã nguồn của máy khách và sửa đổi',
- step1Tip: 'Nhấp vào đây để fork mã nguồn vào tài khoản GitHub của bạn và sửa đổi mã',
+ name: 'Fork mã nguồn phía client, sửa đổi và triển khai lên Vercel (khuyến nghị)',
+ step1: 'Fork mã nguồn phía client và sửa đổi',
+ step1Tip: 'Nhấp vào đây để fork mã nguồn vào tài khoản GitHub của bạn và sửa đổi',
step1Operation: 'Dify-WebClient',
step2: 'Triển khai lên Vercel',
- step2Tip: 'Nhấp vào đây để nhập kho vào Vercel và triển khai',
- step2Operation: 'Nhập kho',
+ step2Tip: 'Nhấp vào đây để nhập kho lưu trữ vào Vercel và triển khai',
+ step2Operation: 'Nhập kho lưu trữ',
step3: 'Cấu hình biến môi trường',
step3Tip: 'Thêm các biến môi trường sau vào Vercel',
},
way2: {
- name: 'Viết mã phía máy khách để gọi API và triển khai lên một máy chủ',
+ name: 'Viết mã phía client để gọi API và triển khai lên máy chủ',
operation: 'Tài liệu',
},
},
},
apiInfo: {
- title: 'API Dịch vụ Backend',
+ title: 'API dịch vụ backend',
explanation: 'Dễ dàng tích hợp vào ứng dụng của bạn',
- accessibleAddress: 'Điểm cuối Dịch vụ API',
+ accessibleAddress: 'Điểm cuối dịch vụ API',
doc: 'Tài liệu tham khảo API',
},
status: {
running: 'Đang hoạt động',
- disable: 'Tắt',
+ disable: 'Đã tắt',
},
},
analysis: {
title: 'Phân tích',
ms: 'ms',
- tokenPS: 'Token/s',
+ tokenPS: 'Token/giây',
totalMessages: {
- title: 'Tổng Số Tin Nhắn',
- explanation: 'Số lần tương tác AI hàng ngày; không tính việc kỹ thuật hóa/nhái lại câu hỏi.',
+ title: 'Tổng số tin nhắn',
+ explanation: 'Số lần tương tác AI hàng ngày; không tính việc tạo lại/lặp lại câu hỏi.',
},
activeUsers: {
- title: 'Người Dùng Hoạt Động',
- explanation: 'Người dùng duy nhất tham gia trò chuyện với AI; không tính việc kỹ thuật hóa/nhái lại câu hỏi.',
+ title: 'Người dùng hoạt động',
+ explanation: 'Số người dùng duy nhất tham gia trò chuyện với AI; không tính việc tạo lại/lặp lại câu hỏi.',
},
tokenUsage: {
- title: 'Sử Dụng Token',
- explanation: 'Phản ánh việc sử dụng hàng ngày của mô hình ngôn ngữ cho ứng dụng, hữu ích cho mục đích kiểm soát chi phí.',
- consumed: 'Đã Sử Dụng',
+ title: 'Sử dụng token',
+ explanation: 'Phản ánh việc sử dụng mô hình ngôn ngữ hàng ngày cho ứng dụng, hữu ích cho mục đích kiểm soát chi phí.',
+ consumed: 'Đã sử dụng',
},
avgSessionInteractions: {
- title: 'Trung Bình Tương Tác Phiên',
- explanation: 'Số lần giao tiếp liên tục giữa người dùng và AI; cho các ứng dụng dựa trên cuộc trò chuyện.',
+ title: 'Trung bình tương tác mỗi phiên',
+ explanation: 'Số lần giao tiếp liên tục giữa người dùng và AI; áp dụng cho các ứng dụng dựa trên trò chuyện.',
},
avgUserInteractions: {
- title: 'Trung Bình Tương Tác Người Dùng',
- explanation: 'Phản ánh tần suất sử dụng hàng ngày của người dùng. Số liệu này phản ánh sự kết dính của người dùng.',
+ title: 'Trung bình tương tác mỗi người dùng',
+ explanation: 'Phản ánh tần suất sử dụng hàng ngày của người dùng. Chỉ số này cho biết mức độ gắn kết của người dùng.',
},
userSatisfactionRate: {
- title: 'Tỷ Lệ Hài Lòng của Người Dùng',
- explanation: 'Số lượt thích trên mỗi 1.000 tin nhắn. Điều này cho biết tỷ lệ câu trả lời mà người dùng rất hài lòng.',
+ title: 'Tỷ lệ hài lòng của người dùng',
+ explanation: 'Số lượt thích trên mỗi 1.000 tin nhắn. Chỉ số này cho biết tỷ lệ câu trả lời mà người dùng rất hài lòng.',
},
avgResponseTime: {
- title: 'Thời Gian Trả Lời Trung Bình',
- explanation: 'Thời gian (ms) để AI xử lý/phản hồi; cho các ứng dụng dựa trên văn bản.',
+ title: 'Thời gian phản hồi trung bình',
+ explanation: 'Thời gian (ms) để AI xử lý/phản hồi; áp dụng cho các ứng dụng dựa trên văn bản.',
},
tps: {
- title: 'Tốc Độ Đầu Ra Token',
- explanation: 'Đo lường hiệu suất của LLM. Đếm tốc độ đầu ra Token của LLM từ khi bắt đầu yêu cầu đến khi hoàn thành đầu ra.',
+ title: 'Tốc độ đầu ra token',
+ explanation: 'Đo lường hiệu suất của LLM. Đếm tốc độ đầu ra token của LLM từ khi bắt đầu yêu cầu đến khi hoàn thành đầu ra.',
},
},
}
diff --git a/web/i18n/vi-VN/app.ts b/web/i18n/vi-VN/app.ts
index ca7eedc434..c8f3167d7c 100644
--- a/web/i18n/vi-VN/app.ts
+++ b/web/i18n/vi-VN/app.ts
@@ -3,19 +3,19 @@ const translation = {
types: {
all: 'Tất cả',
chatbot: 'Chatbot',
- agent: 'Đại lý',
+ agent: 'Tác nhân',
workflow: 'Quy trình',
completion: 'Hoàn thành',
},
duplicate: 'Sao chép',
- duplicateTitle: 'Sao chép Ứng dụng',
+ duplicateTitle: 'Sao chép ứng dụng',
export: 'Xuất DSL',
exportFailed: 'Xuất DSL thất bại.',
importDSL: 'Nhập tệp DSL',
createFromConfigFile: 'Tạo từ tệp DSL',
deleteAppConfirmTitle: 'Xóa ứng dụng này?',
deleteAppConfirmContent:
- 'Việc xóa ứng dụng là không thể đảo ngược. Người dùng sẽ không thể truy cập vào ứng dụng của bạn nữa và tất cả cấu hình và nhật ký nhắc sẽ bị xóa vĩnh viễn.',
+ 'Việc xóa ứng dụng là không thể hoàn tác. Người dùng sẽ không thể truy cập vào ứng dụng của bạn nữa và tất cả cấu hình cũng như nhật ký nhắc sẽ bị xóa vĩnh viễn.',
appDeleted: 'Ứng dụng đã bị xóa',
appDeleteFailed: 'Không thể xóa ứng dụng',
join: 'Tham gia cộng đồng',
@@ -23,23 +23,23 @@ const translation = {
'Thảo luận với các thành viên nhóm, người đóng góp và nhà phát triển trên các kênh khác nhau.',
roadmap: 'Xem lộ trình của chúng tôi',
newApp: {
- startFromBlank: 'Tạo từ Trắng',
- startFromTemplate: 'Tạo từ Mẫu',
- captionAppType: 'Loại ứng dụng bạn muốn tạo?',
- chatbotDescription: 'Xây dựng một ứng dụng dựa trên trò chuyện. Ứng dụng này sử dụng định dạng câu hỏi và trả lời, cho phép nhiều vòng trò chuyện liên tục.',
- completionDescription: 'Xây dựng một ứng dụng tạo văn bản chất lượng cao dựa trên các gợi ý, như tạo bài báo, tóm tắt, dịch và nhiều hơn nữa.',
- completionWarning: 'Loại ứng dụng này sẽ không được hỗ trợ nữa.',
- agentDescription: 'Xây dựng một Đại lý thông minh có thể tự động chọn công cụ để hoàn thành các nhiệm vụ',
- workflowDescription: 'Xây dựng một ứng dụng tạo văn bản chất lượng cao dựa trên quy trình làm việc với mức độ tùy chỉnh cao. Nó phù hợp cho người dùng có kinh nghiệm.',
+ startFromBlank: 'Tạo mới',
+ startFromTemplate: 'Tạo từ mẫu',
+ captionAppType: 'Bạn muốn tạo loại ứng dụng nào?',
+ chatbotDescription: 'Xây dựng một ứng dụng trò chuyện. Ứng dụng này sử dụng định dạng hỏi đáp, cho phép nhiều vòng trò chuyện liên tục.',
+ completionDescription: 'Xây dựng một ứng dụng tạo văn bản chất lượng cao dựa trên gợi ý, như tạo bài viết, tóm tắt, dịch thuật và nhiều hơn nữa.',
+ completionWarning: 'Loại ứng dụng này sẽ không được hỗ trợ trong tương lai.',
+ agentDescription: 'Xây dựng một tác nhân thông minh có thể tự động chọn công cụ để hoàn thành các nhiệm vụ',
+ workflowDescription: 'Xây dựng một ứng dụng tạo văn bản chất lượng cao dựa trên quy trình làm việc với mức độ tùy chỉnh cao. Phù hợp cho người dùng có kinh nghiệm.',
workflowWarning: 'Hiện đang trong phiên bản beta',
chatbotType: 'Phương pháp quản lý Chatbot',
basic: 'Cơ bản',
basicTip: 'Dành cho người mới bắt đầu, có thể chuyển sang Chatflow sau này',
basicFor: 'DÀNH CHO NGƯỜI MỚI BẮT ĐẦU',
- basicDescription: 'Quản lý Cơ bản cho phép quản lý ứng dụng Chatbot bằng cách sử dụng các cài đặt đơn giản, mà không cần phải sửa đổi các nhắc nhở tích hợp sẵn. Nó phù hợp cho người mới bắt đầu.',
+ basicDescription: 'Quản lý cơ bản cho phép quản lý ứng dụng Chatbot bằng cách sử dụng các cài đặt đơn giản, không cần sửa đổi các lời nhắc tích hợp sẵn. Phù hợp cho người mới bắt đầu.',
advanced: 'Chatflow',
advancedFor: 'Dành cho người dùng có kinh nghiệm',
- advancedDescription: 'Quản lý Quy trình quản lý Chatbot dưới dạng các quy trình làm việc, cung cấp mức độ tùy chỉnh cao, bao gồm khả năng chỉnh sửa các nhắc nhở tích hợp sẵn. Nó phù hợp cho người dùng có kinh nghiệm.',
+ advancedDescription: 'Quản lý Chatbot dưới dạng các quy trình làm việc, cung cấp mức độ tùy chỉnh cao, bao gồm khả năng chỉnh sửa các lời nhắc tích hợp sẵn. Phù hợp cho người dùng có kinh nghiệm.',
captionName: 'Biểu tượng và tên ứng dụng',
appNamePlaceholder: 'Đặt tên cho ứng dụng của bạn',
captionDescription: 'Mô tả',
@@ -48,11 +48,11 @@ const translation = {
previewDemo: 'Xem trước demo',
chatApp: 'Trợ lý',
chatAppIntro:
- 'Tôi muốn xây dựng một ứng dụng dựa trên trò chuyện. Ứng dụng này sử dụng định dạng câu hỏi và trả lời, cho phép nhiều vòng trò chuyện liên tục.',
- agentAssistant: 'Trợ lý Đại lý mới',
+ 'Tôi muốn xây dựng một ứng dụng trò chuyện. Ứng dụng này sử dụng định dạng hỏi đáp, cho phép nhiều vòng trò chuyện liên tục.',
+ agentAssistant: 'Trợ lý tác nhân mới',
completeApp: 'Máy tạo văn bản',
completeAppIntro:
- 'Tôi muốn tạo một ứng dụng tạo văn bản chất lượng cao dựa trên các gợi ý, như tạo bài báo, tóm tắt, dịch và nhiều hơn nữa.',
+ 'Tôi muốn tạo một ứng dụng tạo văn bản chất lượng cao dựa trên gợi ý, như tạo bài viết, tóm tắt, dịch thuật và nhiều hơn nữa.',
showTemplates: 'Tôi muốn chọn từ mẫu',
hideTemplates: 'Quay lại chế độ lựa chọn',
Create: 'Tạo',
@@ -63,28 +63,64 @@ const translation = {
appCreated: 'Ứng dụng đã được tạo',
appCreateFailed: 'Không thể tạo ứng dụng',
},
- editApp: 'Chỉnh sửa Thông tin',
- editAppTitle: 'Chỉnh sửa Thông tin Ứng dụng',
+ editApp: 'Chỉnh sửa thông tin',
+ editAppTitle: 'Chỉnh sửa thông tin ứng dụng',
editDone: 'Thông tin ứng dụng đã được cập nhật',
editFailed: 'Không thể cập nhật thông tin ứng dụng',
emoji: {
ok: 'Đồng ý',
cancel: 'Hủy',
},
- switch: 'Chuyển sang Quy trình Quản lý',
- switchTipStart: 'Một bản sao ứng dụng mới sẽ được tạo cho bạn và bản sao mới sẽ chuyển sang Quy trình Quản lý. Bản sao mới sẽ ',
- switchTip: 'không cho phép',
- switchTipEnd: ' chuyển lại Cơ bản Quản lý.',
+ switch: 'Chuyển sang quản lý quy trình',
+ switchTipStart: 'Một bản sao ứng dụng mới sẽ được tạo và chuyển sang quản lý quy trình. Bản sao mới sẽ ',
+ switchTip: 'không thể',
+ switchTipEnd: ' chuyển lại quản lý cơ bản.',
switchLabel: 'Bản sao ứng dụng sẽ được tạo',
removeOriginal: 'Xóa ứng dụng gốc',
switchStart: 'Bắt đầu chuyển',
typeSelector: {
- all: 'TẤT CẢ Loại',
+ all: 'Tất cả loại',
chatbot: 'Chatbot',
- agent: 'Đại lý',
+ agent: 'Tác nhân',
workflow: 'Quy trình',
completion: 'Hoàn thành',
},
+ tracing: {
+ title: 'Theo dõi hiệu suất ứng dụng',
+ description: 'Cấu hình nhà cung cấp LLMOps bên thứ ba và theo dõi hiệu suất ứng dụng.',
+ config: 'Cấu hình',
+ collapse: 'Thu gọn',
+ expand: 'Mở rộng',
+ tracing: 'Theo dõi',
+ disabled: 'Đã tắt',
+ disabledTip: 'Vui lòng cấu hình nhà cung cấp trước',
+ enabled: 'Đang hoạt động',
+ tracingDescription: 'Ghi lại toàn bộ ngữ cảnh thực thi ứng dụng, bao gồm các cuộc gọi LLM, ngữ cảnh, lời nhắc, yêu cầu HTTP và nhiều hơn nữa, đến một nền tảng theo dõi của bên thứ ba.',
+ configProviderTitle: {
+ configured: 'Đã cấu hình',
+ notConfigured: 'Cấu hình nhà cung cấp để bật theo dõi',
+ moreProvider: 'Thêm nhà cung cấp',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: 'Nền tảng phát triển tất cả trong một cho mọi bước của vòng đời ứng dụng được hỗ trợ bởi LLM.',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: 'Theo dõi, đánh giá, quản lý lời nhắc và số liệu để gỡ lỗi và cải thiện ứng dụng LLM của bạn.',
+ },
+ inUse: 'Đang sử dụng',
+ configProvider: {
+ title: 'Cấu hình ',
+ placeholder: 'Nhập {{key}} của bạn',
+ project: 'Dự án',
+ publicKey: 'Khóa công khai',
+ secretKey: 'Khóa bí mật',
+ viewDocsLink: 'Xem tài liệu {{key}}',
+ removeConfirmTitle: 'Xóa cấu hình {{key}}?',
+ removeConfirmContent: 'Cấu hình hiện tại đang được sử dụng, việc xóa nó sẽ tắt tính năng Theo dõi.',
+ },
+ },
}
export default translation
diff --git a/web/i18n/vi-VN/common.ts b/web/i18n/vi-VN/common.ts
index ff0172fafc..80570861b5 100644
--- a/web/i18n/vi-VN/common.ts
+++ b/web/i18n/vi-VN/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: 'Hủy bỏ',
clear: 'Xóa',
save: 'Lưu',
+ saveAndEnable: 'Lưu & Kích hoạt',
edit: 'Chỉnh sửa',
add: 'Thêm',
added: 'Đã thêm',
@@ -77,7 +78,7 @@ const translation = {
params: {
temperature: 'Nhiệt độ',
temperatureTip:
- 'Kiểm soát sự ngẫu nhiên: Giảm nhiệt độ dẫn đến ít kết quả hoàn thành ngẫu nhiên hơn. Khi nhiệt độ tiến gần về không, mô hình sẽ trở nên xác định và lặp lại.',
+ 'Kiểm soát độ ngẫu nhiên: Giảm nhiệt độ dẫn đến ít kết quả ngẫu nhiên hơn. Khi nhiệt độ gần bằng 0, mô hình sẽ trở nên xác định và lặp lại.',
top_p: 'Top P',
top_pTip:
'Kiểm soát đa dạng thông qua lấy mẫu nhân nhóm: 0.5 có nghĩa là nửa số tùy chọn có khả năng cao được xem xét.',
@@ -111,7 +112,7 @@ const translation = {
plugins: 'Plugins',
pluginsTips: 'Tích hợp các plugin bên thứ ba hoặc tạo ra các AI-Plugin tương thích với ChatGPT.',
datasets: 'Kiến thức',
- datasetsTips: 'SẮP RA MẮT: Nhập dữ liệu văn bản của bạn hoặc viết dữ liệu theo thời gian thực thông qua Webhook để cải thiện ngữ cảnh LLM.',
+ datasetsTips: 'SẮP RA MẮT: Nhập dữ liệu văn bản của bạn hoặc cập nhật dữ liệu theo thời gian thực thông qua Webhook để cải thiện ngữ cảnh LLM.',
newApp: 'Ứng dụng mới',
newDataset: 'Tạo Kiến thức',
tools: 'Công cụ',
@@ -128,8 +129,8 @@ const translation = {
logout: 'Đăng xuất',
},
settings: {
- accountGroup: 'ACCOUNT',
- workplaceGroup: 'WORKSPACE',
+ accountGroup: 'TÀI KHOẢN',
+ workplaceGroup: 'KHÔNG GIAN LÀM VIỆC',
account: 'Tài khoản của tôi',
members: 'Thành viên',
billing: 'Thanh toán',
@@ -173,7 +174,7 @@ const translation = {
normal: 'Bình thường',
normalTip: 'Chỉ có thể sử dụng ứng dụng, không thể xây dựng ứng dụng',
editor: 'Biên tập viên',
- editorTip: 'Chỉ có thể xây dựng ứng dụng, không thể quản lý cài đặt nhóm',
+ editorTip: 'Có thể xây dựng ứng dụng, không thể quản lý cài đặt nhóm',
inviteTeamMember: 'Mời thành viên nhóm',
inviteTeamMemberTip: 'Sau khi đăng nhập, họ có thể truy cập trực tiếp vào dữ liệu nhóm của bạn.',
email: 'Email',
@@ -228,7 +229,7 @@ const translation = {
},
openaiHosted: {
openaiHosted: 'OpenAI đang lưu trữ',
- onTrial: 'TRIÊN DÙNG THỬ',
+ onTrial: 'DÙNG THỬ',
exhausted: 'HẾT QUOTA',
desc: 'Dịch vụ lưu trữ OpenAI được cung cấp bởi Dify cho phép bạn sử dụng các mô hình như GPT-3.5. Trước khi hết lượng truy vấn dùng thử, bạn cần thiết lập các nhà cung cấp mô hình khác.',
callTimes: 'Số lần gọi',
@@ -238,7 +239,7 @@ const translation = {
},
anthropicHosted: {
anthropicHosted: 'Anthropic Claude',
- onTrial: 'TRIÊN DÙNG THỬ',
+ onTrial: 'DÙNG THỬ',
exhausted: 'HẾT QUOTA',
desc: 'Mô hình mạnh mẽ, vượt trội trong một loạt các nhiệm vụ từ trò chuyện phức tạp và tạo nội dung sáng tạo đến hướng dẫn chi tiết.',
callTimes: 'Số lần gọi',
@@ -265,7 +266,7 @@ const translation = {
setupModelFirst: 'Vui lòng thiết lập mô hình của bạn trước',
systemReasoningModel: {
key: 'Mô hình lập luận hệ thống',
- tip: 'Thiết lập mô hình suy luận mặc định sẽ được sử dụng để tạo ứng dụng, cũng như các tính năng như việc tạo tên cuộc trò chuyện và đề xuất câu hỏi tiếp theo cũng sẽ sử dụng mô hình suy luận mặc định.',
+ tip: 'Thiết lập mô hình suy luận mặc định sẽ được sử dụng để tạo ứng dụng. Các tính năng như tạo tên cuộc trò chuyện và đề xuất câu hỏi tiếp theo cũng sẽ sử dụng mô hình suy luận mặc định này.',
},
embeddingModel: {
key: 'Mô hình nhúng',
@@ -407,7 +408,7 @@ const translation = {
latestAvailable: 'Dify {{version}} là phiên bản mới nhất hiện có.',
},
appMenus: {
- overview: 'Tổng quan',
+ overview: 'Giám sát',
promptEng: 'Orchestrate',
apiAccess: 'Truy cập API',
logAndAnn: 'Nhật ký & Thông báo',
diff --git a/web/i18n/vi-VN/custom.ts b/web/i18n/vi-VN/custom.ts
index b36476b62a..6c91e519b0 100644
--- a/web/i18n/vi-VN/custom.ts
+++ b/web/i18n/vi-VN/custom.ts
@@ -2,26 +2,26 @@ const translation = {
custom: 'Tùy chỉnh',
upgradeTip: {
prefix: 'Nâng cấp gói của bạn để',
- suffix: 'tùy chỉnh thương hiệu của bạn.',
+ suffix: 'tùy chỉnh thương hiệu.',
},
webapp: {
title: 'Tùy chỉnh thương hiệu WebApp',
- removeBrand: 'Xóa Được hỗ trợ bởi Dify',
- changeLogo: 'Thay đổi Hình ảnh Thương hiệu Được hỗ trợ bởi',
- changeLogoTip: 'Định dạng SVG hoặc PNG với kích thước tối thiểu là 40x40px',
+ removeBrand: 'Xóa "Được hỗ trợ bởi Dify"',
+ changeLogo: 'Thay đổi logo "Được hỗ trợ bởi"',
+ changeLogoTip: 'Định dạng SVG hoặc PNG với kích thước tối thiểu 40x40px',
},
app: {
title: 'Tùy chỉnh thương hiệu tiêu đề ứng dụng',
- changeLogoTip: 'Định dạng SVG hoặc PNG với kích thước tối thiểu là 80x80px',
+ changeLogoTip: 'Định dạng SVG hoặc PNG với kích thước tối thiểu 80x80px',
},
upload: 'Tải lên',
uploading: 'Đang tải lên',
- uploadedFail: 'Tải ảnh lên thất bại, vui lòng tải lên lại.',
+ uploadedFail: 'Tải ảnh lên thất bại, vui lòng thử lại.',
change: 'Thay đổi',
apply: 'Áp dụng',
- restore: 'Khôi phục Mặc định',
+ restore: 'Khôi phục mặc định',
customize: {
- contactUs: ' liên hệ với chúng tôi ',
+ contactUs: 'liên hệ với chúng tôi',
prefix: 'Để tùy chỉnh logo thương hiệu trong ứng dụng, vui lòng',
suffix: 'để nâng cấp lên phiên bản Doanh nghiệp.',
},
diff --git a/web/i18n/vi-VN/dataset-creation.ts b/web/i18n/vi-VN/dataset-creation.ts
index b29cd17c0b..23b210d177 100644
--- a/web/i18n/vi-VN/dataset-creation.ts
+++ b/web/i18n/vi-VN/dataset-creation.ts
@@ -22,7 +22,7 @@ const translation = {
uploader: {
title: 'Tải lên tệp văn bản',
button: 'Kéo và thả tệp, hoặc',
- browse: 'Duyệt',
+ browse: 'Chọn tệp',
tip: 'Hỗ trợ {{supportTypes}}. Tối đa {{size}}MB mỗi tệp.',
validation: {
typeError: 'Loại tệp không được hỗ trợ',
@@ -30,7 +30,7 @@ const translation = {
count: 'Không hỗ trợ tải lên nhiều tệp',
filesNumber: 'Bạn đã đạt đến giới hạn tải lên lô của {{filesNumber}} tệp.',
},
- cancel: 'Hủy bỏ',
+ cancel: 'Hủy',
change: 'Thay đổi',
failed: 'Tải lên thất bại',
},
@@ -46,56 +46,56 @@ const translation = {
placeholder: 'Vui lòng nhập',
nameNotEmpty: 'Tên không thể để trống',
nameLengthInvaild: 'Tên phải từ 1 đến 40 ký tự',
- cancelButton: 'Hủy bỏ',
+ cancelButton: 'Hủy',
confirmButton: 'Tạo',
failed: 'Tạo thất bại',
},
},
stepTwo: {
- segmentation: 'Cài đặt đoạn',
+ segmentation: 'Cài đặt phân đoạn',
auto: 'Tự động',
- autoDescription: 'Tự động thiết lập quy tắc đoạn và tiền xử lý. Người dùng không quen thuộc được khuyến nghị chọn điều này.',
+ autoDescription: 'Tự động thiết lập quy tắc phân đoạn và tiền xử lý. Khuyến nghị cho người dùng mới.',
custom: 'Tùy chỉnh',
- customDescription: 'Tùy chỉnh quy tắc đoạn, độ dài đoạn và quy tắc tiền xử lý, v.v.',
- separator: 'Bộ phận xác định đoạn',
- separatorPlaceholder: 'Ví dụ, dòng mới (\\\\n) hoặc bộ phận phân cách đặc biệt (như "***")',
+ customDescription: 'Tùy chỉnh quy tắc phân đoạn, độ dài đoạn và quy tắc tiền xử lý, v.v.',
+ separator: 'Ký tự phân đoạn',
+ separatorPlaceholder: 'Ví dụ, dòng mới (\\\\n) hoặc ký tự đặc biệt (như "***")',
maxLength: 'Độ dài tối đa của đoạn',
- overlap: 'Chồng lấn đoạn',
- overlapTip: 'Thiết lập chồng lấn đoạn có thể duy trì sự liên quan ngữ nghĩa giữa chúng, tăng cường hiệu ứng truy xuất. Đề xuất thiết lập từ 10% đến 25% của kích thước đoạn tối đa.',
- overlapCheck: 'Chồng lấn đoạn không nên lớn hơn độ dài tối đa của đoạn',
+ overlap: 'Độ chồng lấp đoạn',
+ overlapTip: 'Thiết lập chồng lấp đoạn có thể duy trì sự liên quan ngữ nghĩa giữa chúng, tăng cường hiệu quả truy xuất. Đề xuất thiết lập từ 10% đến 25% của kích thước đoạn tối đa.',
+ overlapCheck: 'Độ chồng lấp đoạn không nên lớn hơn độ dài tối đa của đoạn',
rules: 'Quy tắc tiền xử lý văn bản',
removeExtraSpaces: 'Thay thế khoảng trắng liên tục, dòng mới và tab',
removeUrlEmails: 'Xóa tất cả URL và địa chỉ email',
- removeStopwords: 'Loại bỏ các từ dừng như "một", "một", "những"',
+ removeStopwords: 'Loại bỏ các từ dừng như "một", "và", "những"',
preview: 'Xác nhận & Xem trước',
reset: 'Đặt lại',
- indexMode: 'Chế độ chỉ số',
+ indexMode: 'Chế độ chỉ mục',
qualified: 'Chất lượng cao',
recommend: 'Khuyến nghị',
- qualifiedTip: 'Gọi giao diện nhúng hệ thống mặc định để xử lý để cung cấp độ chính xác cao hơn khi người dùng truy vấn.',
+ qualifiedTip: 'Sử dụng giao diện nhúng hệ thống mặc định để xử lý, cung cấp độ chính xác cao hơn khi người dùng truy vấn.',
warning: 'Vui lòng thiết lập khóa API nhà cung cấp mô hình trước.',
click: 'Đi đến cài đặt',
economical: 'Tiết kiệm',
- economicalTip: 'Sử dụng các động cơ vector ngoại tuyến, chỉ số từ khóa, v.v. để giảm chính xác mà không tốn token',
+ economicalTip: 'Sử dụng các động cơ vector ngoại tuyến, chỉ mục từ khóa, v.v. để giảm độ chính xác mà không tốn token',
QATitle: 'Phân đoạn theo định dạng Câu hỏi & Trả lời',
QATip: 'Bật tùy chọn này sẽ tiêu tốn thêm token',
QALanguage: 'Phân đoạn bằng',
- emstimateCost: 'Ước lượng',
- emstimateSegment: 'Đoạn ước tính',
+ emstimateCost: 'Ước tính',
+ emstimateSegment: 'Số đoạn ước tính',
segmentCount: 'đoạn',
calculating: 'Đang tính toán...',
fileSource: 'Tiền xử lý tài liệu',
notionSource: 'Tiền xử lý trang',
- other: 'và những ',
+ other: 'và ',
fileUnit: ' tệp',
notionUnit: ' trang',
- previousStep: 'Bước trước',
+ previousStep: 'Quay lại',
nextStep: 'Lưu & Xử lý',
save: 'Lưu & Xử lý',
- cancel: 'Hủy bỏ',
+ cancel: 'Hủy',
sideTipTitle: 'Tại sao phải phân đoạn và tiền xử lý?',
sideTipP1: 'Khi xử lý dữ liệu văn bản, phân đoạn và làm sạch là hai bước tiền xử lý quan trọng.',
- sideTipP2: 'Phân đoạn chia nhỏ văn bản dài thành đoạn để mô hình hiểu được tốt hơn. Điều này cải thiện chất lượng và tính liên quan của kết quả mô hình.',
+ sideTipP2: 'Phân đoạn chia nhỏ văn bản dài thành các đoạn để mô hình hiểu được tốt hơn. Điều này cải thiện chất lượng và tính liên quan của kết quả mô hình.',
sideTipP3: 'Làm sạch loại bỏ các ký tự và định dạng không cần thiết, làm cho Kiến thức trở nên sạch sẽ và dễ dàng phân tích hơn.',
sideTipP4: 'Phân đoạn và làm sạch đúng cách cải thiện hiệu suất của mô hình, cung cấp kết quả chính xác và có giá trị hơn.',
previewTitle: 'Xem trước',
@@ -104,8 +104,8 @@ const translation = {
previewSwitchTipStart: 'Xem trước đoạn hiện tại đang ở định dạng văn bản, chuyển sang xem trước dạng câu hỏi và trả lời sẽ',
previewSwitchTipEnd: ' tiêu tốn thêm token',
characters: 'ký tự',
- indexSettedTip: 'Để thay đổi phương pháp chỉ số, vui lòng đi tới ',
- retrivalSettedTip: 'Để thay đổi phương pháp chỉ số, vui lòng đi tới ',
+ indexSettedTip: 'Để thay đổi phương pháp chỉ mục, vui lòng đi tới ',
+ retrivalSettedTip: 'Để thay đổi phương pháp truy xuất, vui lòng đi tới ',
datasetSettingLink: 'cài đặt Kiến thức.',
},
stepThree: {
@@ -119,11 +119,11 @@ const translation = {
resume: 'Tiếp tục xử lý',
navTo: 'Đi đến tài liệu',
sideTipTitle: 'Tiếp theo là gì',
- sideTipContent: 'Sau khi tài liệu hoàn thành chỉ mục, Kiến thức có thể được tích hợp vào ứng dụng như một ngữ cảnh, bạn có thể tìm cài đặt ngữ cảnh trong trang chỉ đạo đoạn. Bạn cũng có thể tạo nó như một plugin chỉ mục ChatGPT độc lập để phát hành.',
+ sideTipContent: 'Sau khi tài liệu hoàn thành chỉ mục, Kiến thức có thể được tích hợp vào ứng dụng như một ngữ cảnh, bạn có thể tìm cài đặt ngữ cảnh trong trang điều chỉnh prompt. Bạn cũng có thể tạo nó như một plugin chỉ mục ChatGPT độc lập để phát hành.',
modelTitle: 'Bạn có chắc chắn muốn dừng việc nhúng?',
modelContent: 'Nếu bạn cần tiếp tục xử lý sau này, bạn sẽ tiếp tục từ vị trí bạn đã dừng lại.',
modelButtonConfirm: 'Xác nhận',
- modelButtonCancel: 'Hủy bỏ',
+ modelButtonCancel: 'Hủy',
},
}
diff --git a/web/i18n/vi-VN/dataset-documents.ts b/web/i18n/vi-VN/dataset-documents.ts
index 3cf486a3c9..5df6e40718 100644
--- a/web/i18n/vi-VN/dataset-documents.ts
+++ b/web/i18n/vi-VN/dataset-documents.ts
@@ -1,17 +1,17 @@
const translation = {
list: {
title: 'Tài liệu',
- desc: 'Tất cả các tệp của Kiến thức được hiển thị ở đây, và toàn bộ Kiến thức có thể được liên kết với trích dẫn của Dify hoặc được lập chỉ mục thông qua plugin Chat.',
+ desc: 'Tất cả các tệp của Kiến thức được hiển thị ở đây. Toàn bộ Kiến thức có thể được liên kết với trích dẫn của Dify hoặc được lập chỉ mục thông qua plugin Chat.',
addFile: 'Thêm tệp',
- addPages: 'Thêm Trang',
+ addPages: 'Thêm trang',
table: {
header: {
fileName: 'TÊN TỆP',
- words: 'TỪ',
+ words: 'SỐ TỪ',
hitCount: 'SỐ LẦN TRUY VẤN',
uploadTime: 'THỜI GIAN TẢI LÊN',
status: 'TRẠNG THÁI',
- action: 'HÀNH ĐỘNG',
+ action: 'THAO TÁC',
},
},
action: {
@@ -23,7 +23,7 @@ const translation = {
archive: 'Lưu trữ',
unarchive: 'Khôi phục',
delete: 'Xóa',
- enableWarning: 'Tệp được lưu trữ không thể được kích hoạt',
+ enableWarning: 'Tệp đã lưu trữ không thể được kích hoạt',
sync: 'Đồng bộ',
},
index: {
@@ -66,41 +66,40 @@ const translation = {
contentTitle: 'nội dung đoạn',
content: 'nội dung',
template: 'Tải mẫu ở đây',
- cancel: 'Hủy bỏ',
- run: 'Chạy Hàng loạt',
+ cancel: 'Hủy',
+ run: 'Chạy hàng loạt',
runError: 'Chạy hàng loạt thất bại',
processing: 'Đang xử lý hàng loạt',
- completed: 'Nhập đã hoàn thành',
+ completed: 'Nhập hoàn tất',
error: 'Lỗi nhập',
ok: 'OK',
},
},
metadata: {
title: 'Siêu dữ liệu',
- desc: 'Gắn nhãn siêu dữ liệu cho các tài liệu cho phép trí tuệ nhân tạo truy cập chúng một cách kịp thời và tiết lộ nguồn của các tài liệu tham chiếu cho người dùng.',
+ desc: 'Gắn nhãn siêu dữ liệu cho các tài liệu cho phép AI truy cập chúng kịp thời và tiết lộ nguồn của các tài liệu tham chiếu cho người dùng.',
dateTimeFormat: 'D MMMM, YYYY hh:mm A',
docTypeSelectTitle: 'Vui lòng chọn loại tài liệu',
docTypeChangeTitle: 'Thay đổi loại tài liệu',
- docTypeSelectWarning:
- 'Nếu thay đổi loại tài liệu, các siêu dữ liệu hiện tại sẽ không được bảo toàn nữa',
+ docTypeSelectWarning: 'Nếu thay đổi loại tài liệu, các siêu dữ liệu hiện tại sẽ không được bảo toàn',
firstMetaAction: 'Bắt đầu',
placeholder: {
add: 'Thêm ',
select: 'Chọn ',
},
source: {
- upload_file: 'Tải lên Tệp',
+ upload_file: 'Tải lên tệp',
notion: 'Đồng bộ từ Notion',
github: 'Đồng bộ từ Github',
},
type: {
book: 'Sách',
- webPage: 'Trang Web',
+ webPage: 'Trang web',
paper: 'Bài báo',
- socialMediaPost: 'Bài viết trên Mạng xã hội',
+ socialMediaPost: 'Bài đăng mạng xã hội',
personalDocument: 'Tài liệu cá nhân',
businessDocument: 'Tài liệu doanh nghiệp',
- IMChat: 'Trò chuyện qua tin nhắn',
+ IMChat: 'Trò chuyện tin nhắn',
wikipediaEntry: 'Bài viết Wikipedia',
notion: 'Đồng bộ từ Notion',
github: 'Đồng bộ từ Github',
@@ -108,10 +107,10 @@ const translation = {
},
field: {
processRule: {
- processDoc: 'Xử lý Tài liệu',
+ processDoc: 'Xử lý tài liệu',
segmentRule: 'Quy tắc phân đoạn',
- segmentLength: 'Chiều dài các đoạn',
- processClean: 'Quy tắc làm sạch Văn bản',
+ segmentLength: 'Độ dài đoạn',
+ processClean: 'Quy tắc làm sạch văn bản',
},
book: {
title: 'Tiêu đề',
@@ -120,7 +119,7 @@ const translation = {
publisher: 'Nhà xuất bản',
publicationDate: 'Ngày xuất bản',
ISBN: 'ISBN',
- category: 'Danh mục',
+ category: 'Thể loại',
},
webPage: {
title: 'Tiêu đề',
@@ -137,7 +136,7 @@ const translation = {
author: 'Tác giả',
publishDate: 'Ngày xuất bản',
journalConferenceName: 'Tên tạp chí/Hội nghị',
- volumeIssuePage: 'Số/Trang',
+ volumeIssuePage: 'Tập/Số/Trang',
DOI: 'DOI',
topicsKeywords: 'Chủ đề/Từ khóa',
abstract: 'Tóm tắt',
@@ -146,14 +145,14 @@ const translation = {
platform: 'Nền tảng',
authorUsername: 'Tác giả/Tên người dùng',
publishDate: 'Ngày đăng',
- postURL: 'URL Bài viết',
+ postURL: 'URL bài đăng',
topicsTags: 'Chủ đề/Thẻ',
},
personalDocument: {
title: 'Tiêu đề',
author: 'Tác giả',
creationDate: 'Ngày tạo',
- lastModifiedDate: 'Ngày sửa đổi cuối cùng',
+ lastModifiedDate: 'Ngày sửa đổi cuối',
documentType: 'Loại tài liệu',
tagsCategory: 'Thẻ/Danh mục',
},
@@ -161,14 +160,14 @@ const translation = {
title: 'Tiêu đề',
author: 'Tác giả',
creationDate: 'Ngày tạo',
- lastModifiedDate: 'Ngày sửa đổi cuối cùng',
+ lastModifiedDate: 'Ngày sửa đổi cuối',
documentType: 'Loại tài liệu',
departmentTeam: 'Phòng ban/Nhóm',
},
IMChat: {
- chatPlatform: 'Nền tảng Trò chuyện',
- chatPartiesGroupName: 'Đối tác Trò chuyện/Tên nhóm',
- participants: 'Tham gia viên',
+ chatPlatform: 'Nền tảng trò chuyện',
+ chatPartiesGroupName: 'Người tham gia/Tên nhóm',
+ participants: 'Người tham gia',
startDate: 'Ngày bắt đầu',
endDate: 'Ngày kết thúc',
topicsKeywords: 'Chủ đề/Từ khóa',
@@ -178,8 +177,8 @@ const translation = {
title: 'Tiêu đề',
language: 'Ngôn ngữ',
webpageURL: 'URL trang web',
- editorContributor: 'Biên tập viên/Đóng góp viên',
- lastEditDate: 'Ngày chỉnh sửa cuối cùng',
+ editorContributor: 'Biên tập viên/Người đóng góp',
+ lastEditDate: 'Ngày chỉnh sửa cuối',
summaryIntroduction: 'Tóm tắt/Giới thiệu',
},
notion: {
@@ -187,7 +186,7 @@ const translation = {
language: 'Ngôn ngữ',
author: 'Tác giả',
createdTime: 'Thời gian tạo',
- lastModifiedTime: 'Thời gian chỉnh sửa cuối cùng',
+ lastModifiedTime: 'Thời gian sửa đổi cuối',
url: 'URL',
tag: 'Thẻ',
description: 'Mô tả',
@@ -201,21 +200,21 @@ const translation = {
programmingLang: 'Ngôn ngữ lập trình',
url: 'URL',
license: 'Giấy phép',
- lastCommitTime: 'Thời gian commit cuối cùng',
- lastCommitAuthor: 'Tác giả commit cuối cùng',
+ lastCommitTime: 'Thời gian commit cuối',
+ lastCommitAuthor: 'Tác giả commit cuối',
},
originInfo: {
originalFilename: 'Tên tệp gốc',
originalFileSize: 'Kích thước tệp gốc',
uploadDate: 'Ngày tải lên',
- lastUpdateDate: 'Ngày cập nhật cuối cùng',
+ lastUpdateDate: 'Ngày cập nhật cuối',
source: 'Nguồn',
},
technicalParameters: {
- segmentSpecification: 'Đặc tả các đoạn',
- segmentLength: 'Chiều dài các đoạn',
- avgParagraphLength: 'Độ dài trung bình của đoạn',
- paragraphs: 'Các đoạn',
+ segmentSpecification: 'Đặc tả đoạn',
+ segmentLength: 'Độ dài đoạn',
+ avgParagraphLength: 'Độ dài trung bình đoạn văn',
+ paragraphs: 'Số đoạn văn',
hitCount: 'Số lần truy vấn',
embeddingTime: 'Thời gian nhúng',
embeddedSpend: 'Chi phí nhúng',
@@ -250,7 +249,7 @@ const translation = {
},
categoryMap: {
book: {
- fiction: 'Hư cấu',
+ fiction: 'Tiểu thuyết',
biography: 'Tiểu sử',
history: 'Lịch sử',
science: 'Khoa học',
@@ -262,18 +261,18 @@ const translation = {
art: 'Nghệ thuật',
travel: 'Du lịch',
health: 'Sức khỏe',
- selfHelp: 'Tự giúp bản thân',
+ selfHelp: 'Tự lực',
businessEconomics: 'Kinh doanh và kinh tế',
cooking: 'Nấu ăn',
- childrenYoungAdults: 'Trẻ em và thanh thiếu niên',
+ childrenYoungAdults: 'Thiếu nhi và thanh thiếu niên',
comicsGraphicNovels: 'Truyện tranh và tiểu thuyết đồ họa',
- poetry: 'Thơ',
+ poetry: 'Thơ ca',
drama: 'Kịch',
other: 'Khác',
},
personalDoc: {
notes: 'Ghi chú',
- blogDraft: 'Nháp Blog',
+ blogDraft: 'Bản nháp blog',
diary: 'Nhật ký',
researchReport: 'Báo cáo nghiên cứu',
bookExcerpt: 'Trích đoạn sách',
@@ -283,7 +282,7 @@ const translation = {
photoCollection: 'Bộ sưu tập ảnh',
creativeWriting: 'Viết sáng tạo',
codeSnippet: 'Đoạn mã',
- designDraft: 'Bản dựng thiết kế',
+ designDraft: 'Bản phác thảo thiết kế',
personalResume: 'Sơ yếu lý lịch cá nhân',
other: 'Khác',
},
@@ -295,31 +294,31 @@ const translation = {
trainingMaterials: 'Tài liệu đào tạo',
requirementsDocument: 'Tài liệu yêu cầu',
designDocument: 'Tài liệu thiết kế',
- productSpecification: 'Thông số sản phẩm',
+ productSpecification: 'Thông số kỹ thuật sản phẩm',
financialReport: 'Báo cáo tài chính',
marketAnalysis: 'Phân tích thị trường',
projectPlan: 'Kế hoạch dự án',
teamStructure: 'Cấu trúc nhóm',
policiesProcedures: 'Chính sách và quy trình',
- contractsAgreements: 'Hợp đồng và thoả thuận',
- emailCorrespondence: 'Thư tín',
+ contractsAgreements: 'Hợp đồng và thỏa thuận',
+ emailCorrespondence: 'Thư từ trao đổi',
other: 'Khác',
},
},
},
embedding: {
processing: 'Đang nhúng...',
- paused: 'Đã tạm dừng việc nhúng',
- completed: 'Hoàn tất việc nhúng',
+ paused: 'Đã tạm dừng nhúng',
+ completed: 'Hoàn tất nhúng',
error: 'Lỗi khi nhúng',
docName: 'Đang xử lý văn bản',
mode: 'Quy tắc phân đoạn',
- segmentLength: 'Chiều dài các đoạn',
- textCleaning: 'Định nghĩa và làm sạch Văn bản',
+ segmentLength: 'Độ dài đoạn',
+ textCleaning: 'Định nghĩa và làm sạch văn bản',
segments: 'Đoạn',
highQuality: 'Chế độ chất lượng cao',
economy: 'Chế độ tiết kiệm',
- estimate: 'Ước lượng tiêu thụ',
+ estimate: 'Ước tính tiêu thụ',
stop: 'Dừng xử lý',
resume: 'Tiếp tục xử lý',
automatic: 'Tự động',
@@ -327,21 +326,21 @@ const translation = {
previewTip: 'Xem trước đoạn sẽ có sẵn sau khi việc nhúng hoàn tất',
},
segment: {
- paragraphs: 'Đoạn',
+ paragraphs: 'Đoạn văn',
keywords: 'Từ khóa',
addKeyWord: 'Thêm từ khóa',
keywordError: 'Độ dài tối đa của từ khóa là 20',
characters: 'ký tự',
hitCount: 'Số lần truy vấn',
- vectorHash: 'Băm vector: ',
+ vectorHash: 'Mã băm vector: ',
questionPlaceholder: 'thêm câu hỏi ở đây',
questionEmpty: 'Câu hỏi không thể trống',
answerPlaceholder: 'thêm câu trả lời ở đây',
answerEmpty: 'Câu trả lời không thể trống',
contentPlaceholder: 'thêm nội dung ở đây',
contentEmpty: 'Nội dung không thể trống',
- newTextSegment: 'Đoạn văn mới',
- newQaSegment: 'Đoạn câu hỏi & trả lời mới',
+ newTextSegment: 'Đoạn văn bản mới',
+ newQaSegment: 'Đoạn hỏi đáp mới',
delete: 'Xóa đoạn này?',
},
}
diff --git a/web/i18n/vi-VN/dataset-hit-testing.ts b/web/i18n/vi-VN/dataset-hit-testing.ts
index 044e34ab5f..a512888250 100644
--- a/web/i18n/vi-VN/dataset-hit-testing.ts
+++ b/web/i18n/vi-VN/dataset-hit-testing.ts
@@ -1,6 +1,6 @@
const translation = {
- title: 'Kiểm Tra Truy Vấn',
- desc: 'Kiểm tra hiệu ứng đánh trúng của Kiến thức dựa trên văn bản truy vấn đã cho.',
+ title: 'Kiểm tra truy vấn',
+ desc: 'Kiểm tra hiệu quả truy xuất của Kiến thức dựa trên văn bản truy vấn đã cho.',
dateTimeFormat: 'MM/DD/YYYY hh:mm A',
recents: 'Gần đây',
table: {
@@ -12,17 +12,17 @@ const translation = {
},
input: {
title: 'Văn bản nguồn',
- placeholder: 'Vui lòng nhập một văn bản, một câu khẳng định ngắn được khuyến nghị.',
+ placeholder: 'Vui lòng nhập một văn bản, khuyến nghị sử dụng một câu khẳng định ngắn.',
countWarning: 'Tối đa 200 ký tự.',
- indexWarning: 'Chỉ có trong Kiến thức chất lượng cao.',
- testing: 'Kiểm tra',
+ indexWarning: 'Chỉ có sẵn trong Kiến thức chất lượng cao.',
+ testing: 'Đang kiểm tra',
},
hit: {
- title: 'RETRIEVAL PARAGRAPHS',
- emptyTip: 'Kết quả Kiểm Tra Truy Vấn sẽ hiển thị ở đây',
+ title: 'CÁC ĐOẠN VĂN ĐƯỢC TRUY XUẤT',
+ emptyTip: 'Kết quả kiểm tra truy vấn sẽ hiển thị ở đây',
},
- noRecentTip: 'Không có kết quả truy vấn gần đây ở đây',
- viewChart: 'Xem VECTOR CHART',
+ noRecentTip: 'Không có kết quả truy vấn gần đây',
+ viewChart: 'Xem BIỂU ĐỒ VECTOR',
}
export default translation
diff --git a/web/i18n/vi-VN/dataset-settings.ts b/web/i18n/vi-VN/dataset-settings.ts
index beb649c30e..e6feb78278 100644
--- a/web/i18n/vi-VN/dataset-settings.ts
+++ b/web/i18n/vi-VN/dataset-settings.ts
@@ -1,30 +1,30 @@
const translation = {
title: 'Cài đặt Kiến thức',
- desc: 'Ở đây, bạn có thể sửa đổi các thuộc tính và phương pháp làm việc của Kiến thức.',
+ desc: 'Tại đây, bạn có thể sửa đổi các thuộc tính và phương pháp làm việc của Kiến thức.',
form: {
name: 'Tên Kiến thức',
namePlaceholder: 'Vui lòng nhập tên Kiến thức',
- nameError: 'Tên không thể trống',
+ nameError: 'Tên không thể để trống',
desc: 'Mô tả Kiến thức',
- descInfo: 'Vui lòng viết mô tả văn bản rõ ràng để chỉ rõ nội dung của Kiến thức. Mô tả này sẽ được sử dụng làm cơ sở cho việc kết hợp khi lựa chọn từ nhiều Kiến thức cho sự suy luận.',
- descPlaceholder: 'Miêu tả những gì có trong Kiến thức này. Một mô tả chi tiết cho phép AI truy cập nội dung của Kiến thức một cách kịp thời. Nếu trống, Dify sẽ sử dụng chiến lược hit mặc định.',
+ descInfo: 'Vui lòng viết mô tả rõ ràng về nội dung của Kiến thức. Mô tả này sẽ được sử dụng làm cơ sở cho việc kết hợp khi lựa chọn từ nhiều Kiến thức trong quá trình suy luận.',
+ descPlaceholder: 'Mô tả những gì có trong Kiến thức này. Một mô tả chi tiết giúp AI truy cập nội dung của Kiến thức một cách hiệu quả. Nếu để trống, Dify sẽ sử dụng chiến lược truy xuất mặc định.',
descWrite: 'Tìm hiểu cách viết mô tả Kiến thức tốt.',
permissions: 'Quyền hạn',
permissionsOnlyMe: 'Chỉ mình tôi',
permissionsAllMember: 'Tất cả thành viên nhóm',
indexMethod: 'Phương pháp chỉ mục',
indexMethodHighQuality: 'Chất lượng cao',
- indexMethodHighQualityTip: 'Gọi mô hình Embedding để xử lý nhằm cung cấp độ chính xác cao hơn khi người dùng truy vấn.',
+ indexMethodHighQualityTip: 'Sử dụng mô hình Embedding để xử lý, cung cấp độ chính xác cao hơn khi người dùng truy vấn.',
indexMethodEconomy: 'Tiết kiệm',
- indexMethodEconomyTip: 'Sử dụng các công cụ nhúng vector ngoại tuyến, chỉ mục từ khóa, v.v. để giảm độ chính xác mà không cần chi tiêu token',
+ indexMethodEconomyTip: 'Sử dụng các công cụ nhúng vector ngoại tuyến, chỉ mục từ khóa, v.v. để giảm độ chính xác mà không tiêu tốn token',
embeddingModel: 'Mô hình nhúng',
embeddingModelTip: 'Để thay đổi mô hình nhúng, vui lòng đi tới ',
embeddingModelTipLink: 'Cài đặt',
retrievalSetting: {
- title: 'Cài đặt truy vấn',
+ title: 'Cài đặt truy xuất',
learnMore: 'Tìm hiểu thêm',
- description: ' về phương pháp truy vấn.',
- longDescription: ' về phương pháp truy vấn, bạn có thể thay đổi điều này bất kỳ lúc nào trong cài đặt Kiến thức.',
+ description: ' về phương pháp truy xuất.',
+ longDescription: ' về phương pháp truy xuất. Bạn có thể thay đổi điều này bất kỳ lúc nào trong cài đặt Kiến thức.',
},
save: 'Lưu',
},
diff --git a/web/i18n/vi-VN/dataset.ts b/web/i18n/vi-VN/dataset.ts
index 6e32079bb2..27dad01f51 100644
--- a/web/i18n/vi-VN/dataset.ts
+++ b/web/i18n/vi-VN/dataset.ts
@@ -1,44 +1,44 @@
const translation = {
knowledge: 'Kiến thức',
documentCount: ' tài liệu',
- wordCount: ' k từ',
+ wordCount: ' nghìn từ',
appCount: ' ứng dụng liên kết',
- createDataset: 'Tạo Kiến thức',
- createDatasetIntro: 'Nhập dữ liệu văn bản của bạn hoặc viết dữ liệu theo thời gian thực qua Webhook để tăng cường ngữ cảnh LLM.',
- deleteDatasetConfirmTitle: 'Xóa Kiến thức này?',
+ createDataset: 'Tạo bộ kiến thức',
+ createDatasetIntro: 'Nhập dữ liệu văn bản của bạn hoặc cập nhật dữ liệu theo thời gian thực qua Webhook để tăng cường ngữ cảnh cho LLM.',
+ deleteDatasetConfirmTitle: 'Xóa bộ kiến thức này?',
deleteDatasetConfirmContent:
- 'Xóa Kiến thức là không thể đảo ngược. Người dùng sẽ không còn có khả năng truy cập Kiến thức của bạn nữa, và tất cả các cấu hình và nhật ký nhắc nhở sẽ bị xóa vĩnh viễn.',
- datasetUsedByApp: 'Kiến thức này đang được sử dụng bởi một số ứng dụng. Các ứng dụng sẽ không thể sử dụng Kiến thức này nữa, và tất cả cấu hình lời nhắc và nhật ký sẽ bị xóa vĩnh viễn.',
- datasetDeleted: 'Kiến thức đã bị xóa',
- datasetDeleteFailed: 'Xóa Kiến thức không thành công',
- didYouKnow: 'Bạn đã biết chưa?',
- intro1: 'Kiến thức có thể được tích hợp vào ứng dụng Dify ',
+ 'Việc xóa bộ kiến thức là không thể hoàn tác. Người dùng sẽ không còn truy cập được vào bộ kiến thức của bạn, và tất cả cấu hình cùng nhật ký lời nhắc sẽ bị xóa vĩnh viễn.',
+ datasetUsedByApp: 'Bộ kiến thức này đang được sử dụng bởi một số ứng dụng. Các ứng dụng sẽ không thể sử dụng bộ kiến thức này nữa, và tất cả cấu hình lời nhắc cùng nhật ký sẽ bị xóa vĩnh viễn.',
+ datasetDeleted: 'Bộ kiến thức đã được xóa',
+ datasetDeleteFailed: 'Xóa bộ kiến thức không thành công',
+ didYouKnow: 'Bạn có biết?',
+ intro1: 'Bộ kiến thức có thể được tích hợp vào ứng dụng Dify ',
intro2: 'như một ngữ cảnh',
intro3: ',',
- intro4: 'hoặc nó ',
+ intro4: 'hoặc ',
intro5: 'có thể được tạo',
- intro6: ' dưới dạng một phần cắm chỉ mục ChatGPT độc lập để xuất bản',
+ intro6: ' dưới dạng một plugin chỉ mục ChatGPT độc lập để xuất bản',
unavailable: 'Không khả dụng',
- unavailableTip: 'Mô hình nhúng không khả dụng, mô hình nhúng mặc định cần được cấu hình',
- datasets: 'KIẾN THỨC',
+ unavailableTip: 'Mô hình nhúng không khả dụng, cần cấu hình mô hình nhúng mặc định',
+ datasets: 'BỘ KIẾN THỨC',
datasetsApi: 'API',
retrieval: {
semantic_search: {
title: 'Tìm kiếm Vector',
- description: 'Tạo các nhúng truy vấn và tìm kiếm phần văn bản giống nhất với biểu diễn vector của nó.',
+ description: 'Tạo các nhúng truy vấn và tìm kiếm đoạn văn bản tương tự nhất với biểu diễn vector của nó.',
},
full_text_search: {
title: 'Tìm kiếm Toàn văn bản',
- description: 'Chỉ mục tất cả các thuật ngữ trong tài liệu, cho phép người dùng tìm kiếm bất kỳ thuật ngữ nào và truy xuất phần văn bản liên quan chứa các thuật ngữ đó.',
+ description: 'Lập chỉ mục cho tất cả các thuật ngữ trong tài liệu, cho phép người dùng tìm kiếm bất kỳ thuật ngữ nào và truy xuất đoạn văn bản liên quan chứa các thuật ngữ đó.',
},
hybrid_search: {
- title: 'Tìm kiếm Hybrid',
- description: 'Thực hiện tìm kiếm toàn văn bản và tìm kiếm vector đồng thời, sắp xếp lại để chọn lựa phù hợp nhất với truy vấn của người dùng. Cấu hình của API mô hình Rerank là cần thiết.',
- recommend: 'Gợi ý',
+ title: 'Tìm kiếm Kết hợp',
+ description: 'Thực hiện tìm kiếm toàn văn bản và tìm kiếm vector đồng thời, sắp xếp lại để chọn kết quả phù hợp nhất với truy vấn của người dùng. Yêu cầu cấu hình API mô hình Rerank.',
+ recommend: 'Đề xuất',
},
invertedIndex: {
- title: 'Chỉ mục Nghịch đảo',
- description: 'Chỉ mục Nghịch đảo là một cấu trúc được sử dụng cho việc truy xuất hiệu quả. Tổ chức theo thuật ngữ, mỗi thuật ngữ trỏ đến tài liệu hoặc trang web chứa nó.',
+ title: 'Chỉ mục Ngược',
+ description: 'Chỉ mục Ngược là một cấu trúc được sử dụng cho việc truy xuất hiệu quả. Nó được tổ chức theo thuật ngữ, mỗi thuật ngữ trỏ đến tài liệu hoặc trang web chứa nó.',
},
change: 'Thay đổi',
changeRetrievalMethod: 'Thay đổi phương pháp truy xuất',
diff --git a/web/i18n/vi-VN/explore.ts b/web/i18n/vi-VN/explore.ts
index b5eb5be50a..9c5d21052e 100644
--- a/web/i18n/vi-VN/explore.ts
+++ b/web/i18n/vi-VN/explore.ts
@@ -2,8 +2,8 @@ const translation = {
title: 'Khám phá',
sidebar: {
discovery: 'Khám phá',
- chat: 'Chat',
- workspace: 'Kho lưu trữ',
+ chat: 'Trò chuyện',
+ workspace: 'Không gian làm việc',
action: {
pin: 'Ghim',
unpin: 'Bỏ ghim',
@@ -16,23 +16,23 @@ const translation = {
},
},
apps: {
- title: 'Khám phá Ứng dụng bởi Dify',
- description: 'Sử dụng ngay các ứng dụng mẫu này hoặc tùy chỉnh các ứng dụng của bạn dựa trên các mẫu.',
+ title: 'Khám phá ứng dụng bởi Dify',
+ description: 'Sử dụng ngay các ứng dụng mẫu này hoặc tùy chỉnh ứng dụng của bạn dựa trên các mẫu có sẵn.',
allCategories: 'Tất cả danh mục',
},
appCard: {
- addToWorkspace: 'Thêm vào Kho lưu trữ',
+ addToWorkspace: 'Thêm vào không gian làm việc',
customize: 'Tùy chỉnh',
},
appCustomize: {
title: 'Tạo ứng dụng từ {{name}}',
subTitle: 'Biểu tượng và tên ứng dụng',
- nameRequired: 'Tên ứng dụng là bắt buộc',
+ nameRequired: 'Vui lòng nhập tên ứng dụng',
},
category: {
Assistant: 'Trợ lý',
- Writing: 'Viết',
- Translate: 'Dịch',
+ Writing: 'Viết lách',
+ Translate: 'Dịch thuật',
Programming: 'Lập trình',
HR: 'Nhân sự',
},
diff --git a/web/i18n/vi-VN/login.ts b/web/i18n/vi-VN/login.ts
index 1fd3e55dfe..8d291c7f33 100644
--- a/web/i18n/vi-VN/login.ts
+++ b/web/i18n/vi-VN/login.ts
@@ -1,70 +1,70 @@
const translation = {
- pageTitle: 'Xin chào, hãy bắt đầu!👋',
+ pageTitle: 'Xin chào, hãy bắt đầu! 👋',
welcome: 'Chào mừng bạn đến với Dify, vui lòng đăng nhập để tiếp tục.',
- email: 'Địa chỉ Email',
- emailPlaceholder: 'Email của bạn',
+ email: 'Địa chỉ email',
+ emailPlaceholder: 'Nhập email của bạn',
password: 'Mật khẩu',
- passwordPlaceholder: 'Mật khẩu của bạn',
+ passwordPlaceholder: 'Nhập mật khẩu của bạn',
name: 'Tên người dùng',
- namePlaceholder: 'Tên người dùng của bạn',
+ namePlaceholder: 'Nhập tên người dùng của bạn',
forget: 'Quên mật khẩu?',
signBtn: 'Đăng nhập',
installBtn: 'Cài đặt',
setAdminAccount: 'Thiết lập tài khoản quản trị',
- setAdminAccountDesc: 'Quyền tối đa cho tài khoản quản trị, có thể được sử dụng để tạo ứng dụng và quản lý các nhà cung cấp LLM, v.v.',
+ setAdminAccountDesc: 'Tài khoản quản trị có quyền tối đa, có thể tạo ứng dụng và quản lý các nhà cung cấp LLM, v.v.',
createAndSignIn: 'Tạo và đăng nhập',
- oneMoreStep: 'Một bước nữa',
+ oneMoreStep: 'Còn một bước nữa',
createSample: 'Dựa trên thông tin này, chúng tôi sẽ tạo một ứng dụng mẫu cho bạn',
invitationCode: 'Mã mời',
- invitationCodePlaceholder: 'Mã mời của bạn',
+ invitationCodePlaceholder: 'Nhập mã mời của bạn',
interfaceLanguage: 'Ngôn ngữ giao diện',
timezone: 'Múi giờ',
go: 'Đi đến Dify',
- sendUsMail: 'Gửi email giới thiệu của bạn cho chúng tôi, và chúng tôi sẽ xử lý yêu cầu mời.',
- acceptPP: 'Tôi đã đọc và chấp nhận chính sách bảo mật',
+ sendUsMail: 'Gửi email giới thiệu cho chúng tôi, chúng tôi sẽ xử lý yêu cầu mời của bạn.',
+ acceptPP: 'Tôi đã đọc và đồng ý với chính sách bảo mật',
reset: 'Vui lòng chạy lệnh sau để đặt lại mật khẩu của bạn',
withGitHub: 'Tiếp tục với GitHub',
withGoogle: 'Tiếp tục với Google',
- rightTitle: 'Mở khóa tiềm năng đầy đủ của LLM',
- rightDesc: 'Dễ dàng xây dựng ứng dụng AI hấp dẫn mắt, có thể vận hành và cải thiện được.',
+ rightTitle: 'Khai phá tiềm năng tối đa của LLM',
+ rightDesc: 'Dễ dàng xây dựng ứng dụng AI hấp dẫn, có thể vận hành và cải thiện được.',
tos: 'Điều khoản dịch vụ',
pp: 'Chính sách bảo mật',
tosDesc: 'Bằng cách đăng ký, bạn đồng ý với',
- goToInit: 'Nếu bạn chưa khởi tạo tài khoản, vui lòng đi đến trang khởi tạo',
- donthave: 'Chưa có?',
+ goToInit: 'Nếu bạn chưa khởi tạo tài khoản, vui lòng chuyển đến trang khởi tạo',
+ donthave: 'Chưa có tài khoản?',
invalidInvitationCode: 'Mã mời không hợp lệ',
accountAlreadyInited: 'Tài khoản đã được khởi tạo',
forgotPassword: 'Quên mật khẩu?',
resetLinkSent: 'Đã gửi liên kết đặt lại mật khẩu',
sendResetLink: 'Gửi liên kết đặt lại mật khẩu',
backToSignIn: 'Quay lại đăng nhập',
- forgotPasswordDesc: 'Vui lòng nhập địa chỉ email của bạn để đặt lại mật khẩu. Chúng tôi sẽ gửi cho bạn một email với hướng dẫn về cách đặt lại mật khẩu.',
- checkEmailForResetLink: 'Vui lòng kiểm tra email của bạn để nhận liên kết đặt lại mật khẩu. Nếu không thấy trong vài phút, hãy kiểm tra thư mục spam.',
+ forgotPasswordDesc: 'Vui lòng nhập địa chỉ email của bạn để đặt lại mật khẩu. Chúng tôi sẽ gửi cho bạn một email hướng dẫn cách đặt lại mật khẩu.',
+ checkEmailForResetLink: 'Vui lòng kiểm tra email để nhận liên kết đặt lại mật khẩu. Nếu không thấy trong vài phút, hãy kiểm tra thư mục spam.',
passwordChanged: 'Đăng nhập ngay',
changePassword: 'Đổi mật khẩu',
changePasswordTip: 'Vui lòng nhập mật khẩu mới cho tài khoản của bạn',
invalidToken: 'Mã thông báo không hợp lệ hoặc đã hết hạn',
confirmPassword: 'Xác nhận mật khẩu',
- confirmPasswordPlaceholder: 'Xác nhận mật khẩu mới của bạn',
+ confirmPasswordPlaceholder: 'Nhập lại mật khẩu mới của bạn',
passwordChangedTip: 'Mật khẩu của bạn đã được thay đổi thành công',
error: {
- emailEmpty: 'Địa chỉ Email là bắt buộc',
+ emailEmpty: 'Vui lòng nhập địa chỉ email',
emailInValid: 'Vui lòng nhập một địa chỉ email hợp lệ',
- nameEmpty: 'Tên là bắt buộc',
- passwordEmpty: 'Mật khẩu là bắt buộc',
- passwordInvalid: 'Mật khẩu phải chứa chữ và số, và độ dài phải lớn hơn 8',
+ nameEmpty: 'Vui lòng nhập tên',
+ passwordEmpty: 'Vui lòng nhập mật khẩu',
+ passwordInvalid: 'Mật khẩu phải chứa cả chữ và số, và có độ dài ít nhất 8 ký tự',
},
license: {
- tip: 'Trước khi bắt đầu Phiên bản Cộng đồng của Dify, hãy đọc',
+ tip: 'Trước khi bắt đầu sử dụng Phiên bản Cộng đồng của Dify, vui lòng đọc',
link: 'Giấy phép mã nguồn mở trên GitHub',
},
join: 'Tham gia',
joinTipStart: 'Mời bạn tham gia',
- joinTipEnd: 'đội tại Dify',
+ joinTipEnd: 'đội ngũ tại Dify',
invalid: 'Liên kết đã hết hạn',
explore: 'Khám phá Dify',
activatedTipStart: 'Bạn đã tham gia',
- activatedTipEnd: 'đội',
+ activatedTipEnd: 'đội ngũ',
activated: 'Đăng nhập ngay',
adminInitPassword: 'Mật khẩu khởi tạo quản trị viên',
validate: 'Xác thực',
diff --git a/web/i18n/vi-VN/share-app.ts b/web/i18n/vi-VN/share-app.ts
index 5ca2dc55b5..d440ad55dc 100644
--- a/web/i18n/vi-VN/share-app.ts
+++ b/web/i18n/vi-VN/share-app.ts
@@ -2,10 +2,10 @@ const translation = {
common: {
welcome: '',
appUnavailable: 'Ứng dụng không khả dụng',
- appUnkonwError: 'Ứng dụng không khả dụng',
+ appUnkonwError: 'Ứng dụng gặp lỗi không xác định',
},
chat: {
- newChat: 'Trò chuyện mới',
+ newChat: 'Cuộc trò chuyện mới',
pinnedTitle: 'Đã ghim',
unpinnedTitle: 'Trò chuyện',
newChatDefaultName: 'Cuộc trò chuyện mới',
@@ -15,58 +15,54 @@ const translation = {
privatePromptConfigTitle: 'Cài đặt cuộc trò chuyện',
publicPromptConfigTitle: 'Lời nhắc ban đầu',
configStatusDes: 'Trước khi bắt đầu, bạn có thể chỉnh sửa cài đặt cuộc trò chuyện',
- configDisabled:
- 'Cài đặt của phiên trước đã được sử dụng cho phiên này.',
+ configDisabled: 'Cài đặt của phiên trước đã được sử dụng cho phiên này.',
startChat: 'Bắt đầu trò chuyện',
- privacyPolicyLeft:
- 'Vui lòng đọc ',
- privacyPolicyMiddle:
- 'chính sách bảo mật',
- privacyPolicyRight:
- ' được cung cấp bởi nhà phát triển ứng dụng.',
+ privacyPolicyLeft: 'Vui lòng đọc ',
+ privacyPolicyMiddle: 'chính sách bảo mật',
+ privacyPolicyRight: ' được cung cấp bởi nhà phát triển ứng dụng.',
deleteConversation: {
title: 'Xóa cuộc trò chuyện',
content: 'Bạn có chắc muốn xóa cuộc trò chuyện này không?',
},
tryToSolve: 'Thử giải quyết',
- temporarySystemIssue: 'Xin lỗi, có sự cố tạm thời của hệ thống.',
+ temporarySystemIssue: 'Xin lỗi, hệ thống đang gặp sự cố tạm thời.',
},
generation: {
tabs: {
- create: 'Chạy Một lần',
- batch: 'Chạy Theo Lô',
- saved: 'Đã Lưu',
+ create: 'Tạo đơn lẻ',
+ batch: 'Tạo hàng loạt',
+ saved: 'Đã lưu',
},
savedNoData: {
title: 'Bạn chưa lưu kết quả nào!',
description: 'Bắt đầu tạo nội dung và tìm kết quả đã lưu của bạn ở đây.',
startCreateContent: 'Bắt đầu tạo nội dung',
},
- title: 'Hoàn Thiện AI',
+ title: 'Hoàn thiện AI',
queryTitle: 'Nội dung truy vấn',
completionResult: 'Kết quả hoàn thiện',
- queryPlaceholder: 'Viết nội dung truy vấn của bạn...',
+ queryPlaceholder: 'Nhập nội dung truy vấn của bạn...',
run: 'Thực thi',
copy: 'Sao chép',
- resultTitle: 'Hoàn Thiện AI',
- noData: 'AI sẽ đưa ra điều bạn muốn ở đây.',
+ resultTitle: 'Kết quả AI',
+ noData: 'AI sẽ hiển thị kết quả ở đây.',
csvUploadTitle: 'Kéo và thả tệp CSV của bạn vào đây, hoặc ',
- browse: 'duyệt',
+ browse: 'chọn tệp',
csvStructureTitle: 'Tệp CSV phải tuân thủ cấu trúc sau:',
downloadTemplate: 'Tải xuống mẫu tại đây',
field: 'Trường',
batchFailed: {
- info: '{{num}} thực thi thất bại',
+ info: '{{num}} lần thực thi thất bại',
retry: 'Thử lại',
outputPlaceholder: 'Không có nội dung đầu ra',
},
errorMsg: {
empty: 'Vui lòng nhập nội dung vào tệp đã tải lên.',
- fileStructNotMatch: 'Tệp CSV tải lên không khớp cấu trúc.',
- emptyLine: 'Hàng {{rowIndex}} trống',
- invalidLine: 'Hàng {{rowIndex}}: {{varName}} không thể để trống',
- moreThanMaxLengthLine: 'Hàng {{rowIndex}}: {{varName}} không thể chứa nhiều hơn {{maxLength}} ký tự',
- atLeastOne: 'Vui lòng nhập ít nhất một hàng vào tệp đã tải lên.',
+ fileStructNotMatch: 'Cấu trúc tệp CSV tải lên không khớp.',
+ emptyLine: 'Dòng {{rowIndex}} trống',
+ invalidLine: 'Dòng {{rowIndex}}: {{varName}} không thể để trống',
+ moreThanMaxLengthLine: 'Dòng {{rowIndex}}: {{varName}} không thể chứa quá {{maxLength}} ký tự',
+ atLeastOne: 'Vui lòng nhập ít nhất một dòng vào tệp đã tải lên.',
},
},
}
diff --git a/web/i18n/vi-VN/tools.ts b/web/i18n/vi-VN/tools.ts
index faf491d892..40e16a5fa9 100644
--- a/web/i18n/vi-VN/tools.ts
+++ b/web/i18n/vi-VN/tools.ts
@@ -1,6 +1,6 @@
const translation = {
title: 'Công cụ',
- createCustomTool: 'Tạo Công cụ Tùy chỉnh',
+ createCustomTool: 'Tạo công cụ tùy chỉnh',
type: {
all: 'Tất cả',
builtIn: 'Tích hợp sẵn',
@@ -11,36 +11,36 @@ const translation = {
line2: 'đóng góp công cụ cho Dify.',
viewGuide: 'Xem hướng dẫn',
},
- author: 'Bởi',
+ author: 'Tác giả',
auth: {
unauthorized: 'Chưa xác thực',
authorized: 'Đã xác thực',
setup: 'Thiết lập xác thực để sử dụng',
- setupModalTitle: 'Thiết lập Xác thực',
- setupModalTitleDescription: 'Sau khi cấu hình thông tin đăng nhập, tất cả các thành viên trong không gian làm việc có thể sử dụng công cụ này khi triển khai ứng dụng.',
+ setupModalTitle: 'Thiết lập xác thực',
+ setupModalTitleDescription: 'Sau khi cấu hình thông tin đăng nhập, tất cả thành viên trong không gian làm việc có thể sử dụng công cụ này khi triển khai ứng dụng.',
},
includeToolNum: 'Bao gồm {{num}} công cụ',
- addTool: 'Thêm Công cụ',
+ addTool: 'Thêm công cụ',
createTool: {
- title: 'Tạo Công cụ Tùy chỉnh',
+ title: 'Tạo công cụ tùy chỉnh',
editAction: 'Cấu hình',
- editTitle: 'Chỉnh sửa Công cụ Tùy chỉnh',
+ editTitle: 'Chỉnh sửa công cụ tùy chỉnh',
name: 'Tên',
toolNamePlaceHolder: 'Nhập tên công cụ',
schema: 'Schema',
schemaPlaceHolder: 'Nhập schema OpenAPI của bạn vào đây',
- viewSchemaSpec: 'Xem Chi tiết OpenAPI-Swagger',
+ viewSchemaSpec: 'Xem chi tiết OpenAPI-Swagger',
importFromUrl: 'Nhập từ URL',
importFromUrlPlaceHolder: 'https://...',
urlError: 'Vui lòng nhập URL hợp lệ',
examples: 'Ví dụ',
exampleOptions: {
json: 'Thời tiết (JSON)',
- yaml: 'Pet Store (YAML)',
- blankTemplate: 'Mẫu Trống',
+ yaml: 'Cửa hàng thú cưng (YAML)',
+ blankTemplate: 'Mẫu trống',
},
availableTools: {
- title: 'Công cụ Hiện có',
+ title: 'Công cụ hiện có',
name: 'Tên',
description: 'Mô tả',
method: 'Phương thức',
@@ -49,9 +49,9 @@ const translation = {
test: 'Kiểm tra',
},
authMethod: {
- title: 'Phương thức Xác thực',
+ title: 'Phương thức xác thực',
type: 'Loại xác thực',
- keyTooltip: 'Khóa Tiêu đề HTTP, Bạn có thể để trống nếu không biết là gì hoặc đặt nó thành một giá trị tùy chỉnh',
+ keyTooltip: 'Khóa tiêu đề HTTP, bạn có thể để trống nếu không biết hoặc đặt một giá trị tùy chỉnh',
types: {
none: 'Không',
api_key: 'Khóa API',
@@ -62,7 +62,7 @@ const translation = {
value: 'Giá trị',
},
authHeaderPrefix: {
- title: 'Loại Xác thực',
+ title: 'Loại xác thực',
types: {
basic: 'Cơ bản',
bearer: 'Bearer',
@@ -71,21 +71,21 @@ const translation = {
},
privacyPolicy: 'Chính sách bảo mật',
privacyPolicyPlaceholder: 'Vui lòng nhập chính sách bảo mật',
- customDisclaimer: 'Tuyên bố Tùy chỉnh',
- customDisclaimerPlaceholder: 'Vui lòng nhập tuyên bố tùy chỉnh',
+ customDisclaimer: 'Tuyên bố từ chối trách nhiệm tùy chỉnh',
+ customDisclaimerPlaceholder: 'Vui lòng nhập tuyên bố từ chối trách nhiệm tùy chỉnh',
deleteToolConfirmTitle: 'Xóa công cụ này?',
- deleteToolConfirmContent: 'Xóa công cụ là không thể hồi tơi. Người dùng sẽ không thể truy cập lại công cụ của bạn.',
+ deleteToolConfirmContent: 'Xóa công cụ là không thể hoàn tác. Người dùng sẽ không thể truy cập lại công cụ của bạn.',
},
test: {
title: 'Kiểm tra',
parametersValue: 'Tham số & Giá trị',
parameters: 'Tham số',
value: 'Giá trị',
- testResult: 'Kết quả Kiểm tra',
+ testResult: 'Kết quả kiểm tra',
testResultPlaceholder: 'Kết quả kiểm tra sẽ hiển thị ở đây',
},
thought: {
- using: 'Sử dụng',
+ using: 'Đang sử dụng',
used: 'Đã sử dụng',
requestTitle: 'Yêu cầu đến',
responseTitle: 'Phản hồi từ',
@@ -93,7 +93,7 @@ const translation = {
setBuiltInTools: {
info: 'Thông tin',
setting: 'Cài đặt',
- toolDescription: 'Mô tả Công cụ',
+ toolDescription: 'Mô tả công cụ',
parameters: 'Tham số',
string: 'chuỗi',
number: 'số',
@@ -101,17 +101,17 @@ const translation = {
infoAndSetting: 'Thông tin & Cài đặt',
},
noCustomTool: {
- title: 'Không có công cụ tùy chỉnh!',
+ title: 'Chưa có công cụ tùy chỉnh!',
content: 'Thêm và quản lý các công cụ tùy chỉnh của bạn ở đây để xây dựng ứng dụng AI.',
- createTool: 'Tạo Công cụ',
+ createTool: 'Tạo công cụ',
},
noSearchRes: {
title: 'Xin lỗi, không có kết quả!',
- content: 'Chúng tôi không thể tìm thấy bất kỳ công cụ nào phù hợp với tìm kiếm của bạn.',
- reset: 'Thiết lập lại Tìm kiếm',
+ content: 'Chúng tôi không tìm thấy công cụ nào phù hợp với tìm kiếm của bạn.',
+ reset: 'Đặt lại tìm kiếm',
},
builtInPromptTitle: 'Lời nhắc',
- toolRemoved: 'Công cụ đã được loại bỏ',
+ toolRemoved: 'Công cụ đã bị xóa',
notAuthorized: 'Công cụ chưa được xác thực',
howToGet: 'Cách nhận',
}
diff --git a/web/i18n/vi-VN/workflow.ts b/web/i18n/vi-VN/workflow.ts
index 4d4a41d14f..cc65ed7aa7 100644
--- a/web/i18n/vi-VN/workflow.ts
+++ b/web/i18n/vi-VN/workflow.ts
@@ -2,34 +2,8 @@ const translation = {
common: {
undo: 'Hoàn tác',
redo: 'Làm lại',
- changeHistory: {
- title: 'Lịch sử thay đổi',
- placeholder: 'Bạn chưa thay đổi gì cả',
- clearHistory: 'Xóa lịch sử',
- hint: 'Gợi ý',
- hintText: 'Các hành động chỉnh sửa của bạn được theo dõi trong lịch sử thay đổi, được lưu trên thiết bị của bạn trong suốt phiên làm việc này. Lịch sử này sẽ bị xóa khi bạn thoát khỏi trình soạn thảo.',
- stepBackward_one: '{{count}} bước lùi',
- stepBackward_other: '{{count}} bước lùi',
- stepForward_one: '{{count}} bước tiến',
- stepForward_other: '{{count}} bước tiến',
- sessionStart: 'Bắt đầu phiên',
- currentState: 'Trạng thái hiện tại',
- nodeTitleChange: 'Tiêu đề khối đã thay đổi',
- nodeDescriptionChange: 'Mô tả khối đã thay đổi',
- nodeDragStop: 'Khối đã di chuyển',
- nodeChange: 'Khối đã thay đổi',
- nodeConnect: 'Khối đã kết nối',
- nodePaste: 'Khối đã dán',
- nodeDelete: 'Khối đã xóa',
- nodeAdd: 'Khối đã thêm',
- nodeResize: 'Khối đã thay đổi kích thước',
- noteAdd: 'Ghi chú đã thêm',
- noteChange: 'Ghi chú đã thay đổi',
- noteDelete: 'Ghi chú đã xóa',
- edgeDelete: 'Khối đã ngắt kết nối',
- },
- editing: 'Chỉnh sửa',
- autoSaved: 'Tự động lưu',
+ editing: 'Đang chỉnh sửa',
+ autoSaved: 'Đã tự động lưu',
unpublished: 'Chưa xuất bản',
published: 'Đã xuất bản',
publish: 'Xuất bản',
@@ -45,12 +19,12 @@ const translation = {
goBackToEdit: 'Quay lại trình chỉnh sửa',
conversationLog: 'Nhật ký cuộc trò chuyện',
features: 'Tính năng',
- debugAndPreview: 'Gỡ lỗi và xem trước',
+ debugAndPreview: 'Xem trước',
restart: 'Khởi động lại',
currentDraft: 'Bản nháp hiện tại',
currentDraftUnpublished: 'Bản nháp hiện tại chưa xuất bản',
latestPublished: 'Xuất bản mới nhất',
- publishedAt: 'Đã xuất bản tại',
+ publishedAt: 'Đã xuất bản lúc',
restore: 'Khôi phục',
runApp: 'Chạy ứng dụng',
batchRunApp: 'Chạy ứng dụng hàng loạt',
@@ -96,6 +70,53 @@ const translation = {
workflowAsToolTip: 'Cần cấu hình lại công cụ sau khi cập nhật quy trình làm việc.',
viewDetailInTracingPanel: 'Xem chi tiết',
},
+ env: {
+ envPanelTitle: 'Biến Môi Trường',
+ envDescription: 'Biến môi trường có thể được sử dụng để lưu trữ thông tin cá nhân và thông tin xác thực. Chúng chỉ được đọc và có thể được tách khỏi tệp DSL trong quá trình xuất.',
+ envPanelButton: 'Thêm Biến',
+ modal: {
+ title: 'Thêm Biến Môi Trường',
+ editTitle: 'Sửa Biến Môi Trường',
+ type: 'Loại',
+ name: 'Tên',
+ namePlaceholder: 'tên môi trường',
+ value: 'Giá trị',
+ valuePlaceholder: 'giá trị môi trường',
+ secretTip: 'Được sử dụng để xác định thông tin hoặc dữ liệu nhạy cảm, với cài đặt DSL được cấu hình để ngăn chặn rò rỉ.',
+ },
+ export: {
+ title: 'Xuất biến môi trường bí mật?',
+ checkbox: 'Xuất giá trị bí mật',
+ ignore: 'Xuất DSL',
+ export: 'Xuất DSL với giá trị bí mật',
+ },
+ },
+ changeHistory: {
+ title: 'Lịch sử thay đổi',
+ placeholder: 'Bạn chưa thay đổi gì cả',
+ clearHistory: 'Xóa lịch sử',
+ hint: 'Gợi ý',
+ hintText: 'Các hành động chỉnh sửa của bạn được theo dõi trong lịch sử thay đổi, được lưu trên thiết bị của bạn trong suốt phiên làm việc này. Lịch sử này sẽ bị xóa khi bạn thoát khỏi trình soạn thảo.',
+ stepBackward_one: '{{count}} bước lùi',
+ stepBackward_other: '{{count}} bước lùi',
+ stepForward_one: '{{count}} bước tiến',
+ stepForward_other: '{{count}} bước tiến',
+ sessionStart: 'Bắt đầu phiên',
+ currentState: 'Trạng thái hiện tại',
+ nodeTitleChange: 'Tiêu đề khối đã thay đổi',
+ nodeDescriptionChange: 'Mô tả khối đã thay đổi',
+ nodeDragStop: 'Khối đã di chuyển',
+ nodeChange: 'Khối đã thay đổi',
+ nodeConnect: 'Khối đã kết nối',
+ nodePaste: 'Khối đã dán',
+ nodeDelete: 'Khối đã xóa',
+ nodeAdd: 'Khối đã thêm',
+ nodeResize: 'Khối đã thay đổi kích thước',
+ noteAdd: 'Ghi chú đã thêm',
+ noteChange: 'Ghi chú đã thay đổi',
+ noteDelete: 'Ghi chú đã xóa',
+ edgeDelete: 'Khối đã ngắt kết nối',
+ },
errorMsg: {
fieldRequired: '{{field}} là bắt buộc',
authRequired: 'Yêu cầu xác thực',
@@ -175,7 +196,7 @@ const translation = {
userInputField: 'Trường đầu vào của người dùng',
changeBlock: 'Thay đổi khối',
helpLink: 'Liên kết trợ giúp',
- about: 'Về',
+ about: 'Giới thiệu',
createdBy: 'Tạo bởi ',
nextStep: 'Bước tiếp theo',
addNextStep: 'Thêm khối tiếp theo trong quy trình làm việc này',
diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts
index 88f47805fb..15f5606d29 100644
--- a/web/i18n/zh-Hans/workflow.ts
+++ b/web/i18n/zh-Hans/workflow.ts
@@ -99,6 +99,33 @@ const translation = {
export: '导出包含 Secret 值的 DSL',
},
},
+ chatVariable: {
+ panelTitle: '会话变量',
+ panelDescription: '会话变量用于存储 LLM 需要的上下文信息,如用户偏好、对话历史等。它是可读写的。',
+ docLink: '查看文档了解更多。',
+ button: '添加变量',
+ modal: {
+ title: '添加会话变量',
+ editTitle: '编辑会话变量',
+ name: '名称',
+ namePlaceholder: '变量名',
+ type: '类型',
+ value: '默认值',
+ valuePlaceholder: '默认值,可以为空',
+ description: '描述',
+ descriptionPlaceholder: '变量的描述',
+ editInJSON: '在 JSON 中编辑',
+ oneByOne: '逐个添加',
+ editInForm: '在表单中编辑',
+ arrayValue: '值',
+ addArrayValue: '添加值',
+ objectKey: '属性',
+ objectType: '类型',
+ objectValue: '默认值',
+ },
+ storedContent: '存储内容',
+ updatedAt: '更新时间 ',
+ },
changeHistory: {
title: '变更历史',
placeholder: '尚未更改任何内容',
@@ -150,6 +177,7 @@ const translation = {
tabs: {
'searchBlock': '搜索节点',
'blocks': '节点',
+ 'searchTool': '搜索工具',
'tools': '工具',
'allTool': '全部',
'builtInTool': '内置',
@@ -174,6 +202,7 @@ const translation = {
'http-request': 'HTTP 请求',
'variable-assigner': '变量聚合器',
'variable-aggregator': '变量聚合器',
+ 'assigner': '变量赋值',
'iteration-start': '迭代开始',
'iteration': '迭代',
'parameter-extractor': '参数提取器',
@@ -192,6 +221,7 @@ const translation = {
'template-transform': '使用 Jinja 模板语法将数据转换为字符串',
'http-request': '允许通过 HTTP 协议发送服务器请求',
'variable-assigner': '将多路分支的变量聚合为一个变量,以实现下游节点统一配置。',
+ 'assigner': '变量赋值节点用于向可写入变量(例如会话变量)进行变量赋值。',
'variable-aggregator': '将多路分支的变量聚合为一个变量,以实现下游节点统一配置。',
'iteration': '对列表对象执行多次步骤直至输出所有结果。',
'parameter-extractor': '利用 LLM 从自然语言内推理提取出结构化参数,用于后置的工具调用或 HTTP 请求。',
@@ -220,6 +250,7 @@ const translation = {
checklistResolved: '所有问题均已解决',
organizeBlocks: '整理节点',
change: '更改',
+ optional: '(选填)',
},
nodes: {
common: {
@@ -422,6 +453,17 @@ const translation = {
},
setAssignVariable: '设置赋值变量',
},
+ assigner: {
+ 'assignedVariable': '赋值的变量',
+ 'writeMode': '写入模式',
+ 'writeModeTip': '赋值的变量为数组时,可添加变量至数组末尾。',
+ 'over-write': '覆盖',
+ 'append': '追加',
+ 'plus': '加',
+ 'clear': '清空',
+ 'setVariable': '设置变量',
+ 'variable': '变量',
+ },
tool: {
toAuthorize: '授权',
inputVars: '输入变量',
diff --git a/web/i18n/zh-Hant/app.ts b/web/i18n/zh-Hant/app.ts
index dfdc0ea7af..3c388065e7 100644
--- a/web/i18n/zh-Hant/app.ts
+++ b/web/i18n/zh-Hant/app.ts
@@ -84,6 +84,42 @@ const translation = {
workflow: '工作流',
completion: '文字生成',
},
+ tracing: {
+ title: '追蹤應用程式效能',
+ description: '配置第三方LLMOps提供商並追蹤應用程式效能。',
+ config: '配置',
+ collapse: '收起',
+ expand: '展開',
+ tracing: '追蹤',
+ disabled: '已禁用',
+ disabledTip: '請先配置提供商',
+ enabled: '服務中',
+ tracingDescription: '捕獲應用程式執行的完整上下文,包括LLM調用、上下文、提示、HTTP請求等,到第三方追蹤平台。',
+ configProviderTitle: {
+ configured: '已配置',
+ notConfigured: '配置提供商以啟用追蹤',
+ moreProvider: '更多提供商',
+ },
+ langsmith: {
+ title: 'LangSmith',
+ description: '一個全方位的開發者平台,用於LLM驅動的應用程式生命週期的每個步驟。',
+ },
+ langfuse: {
+ title: 'Langfuse',
+ description: '追蹤、評估、提示管理和指標,用於調試和改進您的LLM應用程式。',
+ },
+ inUse: '使用中',
+ configProvider: {
+ title: '配置 ',
+ placeholder: '輸入您的{{key}}',
+ project: '專案',
+ publicKey: '公鑰',
+ secretKey: '密鑰',
+ viewDocsLink: '查看{{key}}文檔',
+ removeConfirmTitle: '移除{{key}}配置?',
+ removeConfirmContent: '當前配置正在使用中,移除它將關閉追蹤功能。',
+ },
+ },
}
export default translation
diff --git a/web/i18n/zh-Hant/common.ts b/web/i18n/zh-Hant/common.ts
index 78c34d3351..f4d6952f76 100644
--- a/web/i18n/zh-Hant/common.ts
+++ b/web/i18n/zh-Hant/common.ts
@@ -12,6 +12,7 @@ const translation = {
cancel: '取消',
clear: '清空',
save: '儲存',
+ saveAndEnable: '儲存並啟用',
edit: '編輯',
add: '新增',
added: '已新增',
@@ -408,7 +409,7 @@ const translation = {
latestAvailable: 'Dify {{version}} 已是最新版本。',
},
appMenus: {
- overview: '概覽',
+ overview: '監控',
promptEng: '編排',
apiAccess: '訪問 API',
logAndAnn: '日誌與標註',
diff --git a/web/i18n/zh-Hant/workflow.ts b/web/i18n/zh-Hant/workflow.ts
index a83fae330e..1e73788f16 100644
--- a/web/i18n/zh-Hant/workflow.ts
+++ b/web/i18n/zh-Hant/workflow.ts
@@ -19,7 +19,7 @@ const translation = {
goBackToEdit: '返回編輯模式',
conversationLog: '對話記錄',
features: '功能',
- debugAndPreview: '調試和預覽',
+ debugAndPreview: '預覽',
restart: '重新開始',
currentDraft: '當前草稿',
currentDraftUnpublished: '當前草稿未發佈',
@@ -70,6 +70,27 @@ const translation = {
workflowAsToolTip: '工作流更新後需要重新配置工具參數',
viewDetailInTracingPanel: '查看詳細信息',
},
+ env: {
+ envPanelTitle: '環境變數',
+ envDescription: '環境變數可用於存儲私人信息和憑證。它們是唯讀的,並且可以在導出時與DSL文件分開。',
+ envPanelButton: '添加變數',
+ modal: {
+ title: '添加環境變數',
+ editTitle: '編輯環境變數',
+ type: '類型',
+ name: '名稱',
+ namePlaceholder: '環境名稱',
+ value: '值',
+ valuePlaceholder: '環境值',
+ secretTip: '用於定義敏感信息或數據,DSL設置配置為防止洩露。',
+ },
+ export: {
+ title: '導出機密環境變數?',
+ checkbox: '導出機密值',
+ ignore: '導出DSL',
+ export: '導出帶有機密值的DSL',
+ },
+ },
changeHistory: {
title: '變更履歷',
placeholder: '尚未更改任何內容',
diff --git a/web/models/log.ts b/web/models/log.ts
index 994da445dc..fbd4674c9b 100644
--- a/web/models/log.ts
+++ b/web/models/log.ts
@@ -4,6 +4,7 @@ import type {
Edge,
Node,
} from '@/app/components/workflow/types'
+import type { Metadata } from '@/app/components/base/chat/chat/type'
// Log type contains key:string conversation_id:string created_at:string quesiton:string answer:string
export type Conversation = {
@@ -102,6 +103,7 @@ export type MessageContent = {
from_end_user_id?: string
}>
message_files: VisionFile[]
+ metadata: Metadata
agent_thoughts: any[] // TODO
workflow_run_id: string
}
diff --git a/web/service/base.ts b/web/service/base.ts
index 7d9aac5ba2..bda83f1c8e 100644
--- a/web/service/base.ts
+++ b/web/service/base.ts
@@ -538,14 +538,15 @@ export const ssePost = (
return handleStream(res, (str: string, isFirstMessage: boolean, moreInfo: IOnDataMoreInfo) => {
if (moreInfo.errorMessage) {
onError?.(moreInfo.errorMessage, moreInfo.errorCode)
- if (moreInfo.errorMessage !== 'AbortError: The user aborted a request.')
+ // TypeError: Cannot assign to read only property ... will happen in page leave, so it should be ignored.
+ if (moreInfo.errorMessage !== 'AbortError: The user aborted a request.' && !moreInfo.errorMessage.includes('TypeError: Cannot assign to read only property'))
Toast.notify({ type: 'error', message: moreInfo.errorMessage })
return
}
onData?.(str, isFirstMessage, moreInfo)
}, onCompleted, onThought, onMessageEnd, onMessageReplace, onFile, onWorkflowStarted, onWorkflowFinished, onNodeStarted, onNodeFinished, onIterationStart, onIterationNext, onIterationFinish, onTextChunk, onTTSChunk, onTTSEnd, onTextReplace)
}).catch((e) => {
- if (e.toString() !== 'AbortError: The user aborted a request.')
+ if (e.toString() !== 'AbortError: The user aborted a request.' && !e.toString().errorMessage.includes('TypeError: Cannot assign to read only property'))
Toast.notify({ type: 'error', message: e })
onError?.(e)
})
diff --git a/web/service/workflow.ts b/web/service/workflow.ts
index 1b805dff4f..93ab0006d4 100644
--- a/web/service/workflow.ts
+++ b/web/service/workflow.ts
@@ -3,6 +3,7 @@ import { get, post } from './base'
import type { CommonResponse } from '@/models/common'
import type {
ChatRunHistoryResponse,
+ ConversationVariableResponse,
FetchWorkflowDraftResponse,
NodesDefaultConfigsResponse,
WorkflowRunHistoryResponse,
@@ -13,7 +14,7 @@ export const fetchWorkflowDraft = (url: string) => {
return get(url, {}, { silent: true }) as Promise
}
-export const syncWorkflowDraft = ({ url, params }: { url: string; params: Pick }) => {
+export const syncWorkflowDraft = ({ url, params }: { url: string; params: Pick }) => {
return post(url, { body: params }, { silent: true })
}
@@ -58,3 +59,7 @@ export const fetchNodeDefault = (appId: string, blockType: BlockEnum, query = {}
export const updateWorkflowDraftFromDSL = (appId: string, data: string) => {
return post(`apps/${appId}/workflows/draft/import`, { body: { data } })
}
+
+export const fetchCurrentValueOfConversationVariable: Fetcher = ({ url, params }) => {
+ return get(url, { params })
+}
diff --git a/web/types/workflow.ts b/web/types/workflow.ts
index 35c1bd2791..72475ce55c 100644
--- a/web/types/workflow.ts
+++ b/web/types/workflow.ts
@@ -1,6 +1,7 @@
import type { Viewport } from 'reactflow'
import type {
BlockEnum,
+ ConversationVariable,
Edge,
EnvironmentVariable,
Node,
@@ -58,6 +59,7 @@ export type FetchWorkflowDraftResponse = {
updated_at: number
tool_published: boolean
environment_variables?: EnvironmentVariable[]
+ conversation_variables?: ConversationVariable[]
}
export type NodeTracingListResponse = {
@@ -240,3 +242,11 @@ export type NodesDefaultConfigsResponse = {
type: string
config: any
}[]
+
+export type ConversationVariableResponse = {
+ data: (ConversationVariable & { updated_at: number; created_at: number })[]
+ has_more: boolean
+ limit: number
+ total: number
+ page: number
+}
diff --git a/web/utils/emoji.ts b/web/utils/emoji.ts
new file mode 100644
index 0000000000..9123f780f2
--- /dev/null
+++ b/web/utils/emoji.ts
@@ -0,0 +1,11 @@
+import { SearchIndex } from 'emoji-mart'
+import type { Emoji } from '@emoji-mart/data'
+
+export async function searchEmoji(value: string) {
+ const emojis: Emoji[] = await SearchIndex.search(value) || []
+
+ const results = emojis.map((emoji) => {
+ return emoji.skins[0].native
+ })
+ return results
+}