mirror of
https://github.com/langgenius/dify.git
synced 2026-07-31 17:29:37 +08:00
feat: add upload size guidance and validation for agent files and skills (#39798)
This commit is contained in:
parent
e8b17345c3
commit
b32c900761
@ -79,6 +79,7 @@ describe('useFileSizeLimit', () => {
|
||||
expect(result.current.docSizeLimit).toBe(15 * 1024 * 1024)
|
||||
expect(result.current.audioSizeLimit).toBe(50 * 1024 * 1024)
|
||||
expect(result.current.videoSizeLimit).toBe(100 * 1024 * 1024)
|
||||
expect(result.current.skillSizeLimit).toBe(50 * 1024 * 1024)
|
||||
expect(result.current.maxFileUploadLimit).toBe(10)
|
||||
})
|
||||
|
||||
@ -88,6 +89,7 @@ describe('useFileSizeLimit', () => {
|
||||
file_size_limit: 30,
|
||||
audio_file_size_limit: 100,
|
||||
video_file_size_limit: 200,
|
||||
skill_file_size_limit: 60,
|
||||
workflow_file_upload_limit: 20,
|
||||
} as FileUploadConfigResponse
|
||||
|
||||
@ -97,6 +99,7 @@ describe('useFileSizeLimit', () => {
|
||||
expect(result.current.docSizeLimit).toBe(30 * 1024 * 1024)
|
||||
expect(result.current.audioSizeLimit).toBe(100 * 1024 * 1024)
|
||||
expect(result.current.videoSizeLimit).toBe(200 * 1024 * 1024)
|
||||
expect(result.current.skillSizeLimit).toBe(60 * 1024 * 1024)
|
||||
expect(result.current.maxFileUploadLimit).toBe(20)
|
||||
})
|
||||
|
||||
@ -106,6 +109,7 @@ describe('useFileSizeLimit', () => {
|
||||
file_size_limit: 0,
|
||||
audio_file_size_limit: 0,
|
||||
video_file_size_limit: 0,
|
||||
skill_file_size_limit: 0,
|
||||
workflow_file_upload_limit: 0,
|
||||
} as FileUploadConfigResponse
|
||||
|
||||
@ -115,6 +119,7 @@ describe('useFileSizeLimit', () => {
|
||||
expect(result.current.docSizeLimit).toBe(15 * 1024 * 1024)
|
||||
expect(result.current.audioSizeLimit).toBe(50 * 1024 * 1024)
|
||||
expect(result.current.videoSizeLimit).toBe(100 * 1024 * 1024)
|
||||
expect(result.current.skillSizeLimit).toBe(50 * 1024 * 1024)
|
||||
expect(result.current.maxFileUploadLimit).toBe(10)
|
||||
})
|
||||
})
|
||||
|
||||
@ -3,6 +3,7 @@ export const IMG_SIZE_LIMIT = 10 * 1024 * 1024
|
||||
export const FILE_SIZE_LIMIT = 15 * 1024 * 1024
|
||||
export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024
|
||||
export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024
|
||||
export const SKILL_FILE_SIZE_LIMIT = 50 * 1024 * 1024
|
||||
export const MAX_FILE_UPLOAD_LIMIT = 10
|
||||
|
||||
export const FILE_URL_REGEX = /^(https?|ftp):\/\//
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
FILE_SIZE_LIMIT,
|
||||
IMG_SIZE_LIMIT,
|
||||
MAX_FILE_UPLOAD_LIMIT,
|
||||
SKILL_FILE_SIZE_LIMIT,
|
||||
VIDEO_SIZE_LIMIT,
|
||||
} from '@/app/components/base/file-uploader/constants'
|
||||
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
@ -38,6 +39,8 @@ export const useFileSizeLimit = (fileUploadConfig?: FileUploadConfigResponse) =>
|
||||
Number(fileUploadConfig?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT
|
||||
const videoSizeLimit =
|
||||
Number(fileUploadConfig?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT
|
||||
const skillSizeLimit =
|
||||
Number(fileUploadConfig?.skill_file_size_limit) * 1024 * 1024 || SKILL_FILE_SIZE_LIMIT
|
||||
const maxFileUploadLimit =
|
||||
Number(fileUploadConfig?.workflow_file_upload_limit) || MAX_FILE_UPLOAD_LIMIT
|
||||
|
||||
@ -46,6 +49,7 @@ export const useFileSizeLimit = (fileUploadConfig?: FileUploadConfigResponse) =>
|
||||
docSizeLimit,
|
||||
audioSizeLimit,
|
||||
videoSizeLimit,
|
||||
skillSizeLimit,
|
||||
maxFileUploadLimit,
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +45,13 @@ const mocks = vi.hoisted(() => ({
|
||||
downloadQueryOptions: vi.fn((_options: ConfigFileQueryOptionsInput) => ({})),
|
||||
downloadBlob: vi.fn(),
|
||||
downloadUrl: vi.fn(),
|
||||
fileUploadConfig: {
|
||||
file_size_limit: 15,
|
||||
image_file_size_limit: 10,
|
||||
audio_file_size_limit: 50,
|
||||
video_file_size_limit: 100,
|
||||
workflow_file_upload_limit: 10,
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@langgenius/dify-ui/toast', () => ({
|
||||
@ -59,6 +66,10 @@ vi.mock('@/utils/download', () => ({
|
||||
downloadUrl: mocks.downloadUrl,
|
||||
}))
|
||||
|
||||
vi.mock('@/service/use-common', () => ({
|
||||
useFileUploadConfig: () => ({ data: mocks.fileUploadConfig }),
|
||||
}))
|
||||
|
||||
vi.mock('@/service/client', () => ({
|
||||
consoleQuery: {
|
||||
systemFeatures: {
|
||||
@ -204,6 +215,13 @@ function renderAgentFiles({
|
||||
describe('AgentFiles', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
Object.assign(mocks.fileUploadConfig, {
|
||||
file_size_limit: 15,
|
||||
image_file_size_limit: 10,
|
||||
audio_file_size_limit: 50,
|
||||
video_file_size_limit: 100,
|
||||
workflow_file_upload_limit: 10,
|
||||
})
|
||||
mocks.previewQueryOptions.mockImplementation(({ input }) => ({
|
||||
queryKey: ['preview-config-file', input],
|
||||
queryFn: async () => ({
|
||||
@ -351,6 +369,59 @@ describe('AgentFiles', () => {
|
||||
expect(toast.success).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should show the configured size limit for every supported file type', async () => {
|
||||
const user = userEvent.setup()
|
||||
renderAgentFiles({ initialDraft: defaultAgentSoulConfigFormState })
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.files\.add/i }),
|
||||
)
|
||||
|
||||
const sizeLimitCopy = await screen.findByText(/appDebug\.variableConfig\.maxNumberTip/)
|
||||
expect(sizeLimitCopy).toHaveTextContent('"docLimit":"15.00 MB"')
|
||||
expect(sizeLimitCopy).toHaveTextContent('"imgLimit":"10.00 MB"')
|
||||
expect(sizeLimitCopy).toHaveTextContent('"audioLimit":"50.00 MB"')
|
||||
expect(sizeLimitCopy).toHaveTextContent('"videoLimit":"100.00 MB"')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['document', 'oversized.pdf', 'application/pdf'],
|
||||
['image', 'oversized.png', 'image/png'],
|
||||
['audio', 'oversized.mp3', 'audio/mpeg'],
|
||||
['video', 'oversized.mp4', 'video/mp4'],
|
||||
])('should reject an oversized %s file before upload', async (fileType, fileName, mimeType) => {
|
||||
Object.assign(mocks.fileUploadConfig, {
|
||||
file_size_limit: 1,
|
||||
image_file_size_limit: 1,
|
||||
audio_file_size_limit: 1,
|
||||
video_file_size_limit: 1,
|
||||
})
|
||||
const user = userEvent.setup()
|
||||
renderAgentFiles({ initialDraft: defaultAgentSoulConfigFormState })
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.files\.add/i }),
|
||||
)
|
||||
|
||||
const input = await waitFor(() => {
|
||||
const element = document.querySelector('input[type="file"]')
|
||||
expect(element).not.toBeNull()
|
||||
return element as HTMLInputElement
|
||||
})
|
||||
const file = new File([new Uint8Array(1024 * 1024 + 1)], fileName, { type: mimeType })
|
||||
await user.upload(input, file)
|
||||
|
||||
expect(toast.error).toHaveBeenCalledWith(
|
||||
`common.fileUploader.uploadFromComputerLimit:{"type":"${fileType}","size":"1.00 MB"}`,
|
||||
)
|
||||
expect(mocks.uploadFileMutationFn).not.toHaveBeenCalled()
|
||||
expect(
|
||||
screen.getByRole('button', {
|
||||
name: /agentDetail\.configure\.files\.upload\.action/i,
|
||||
}),
|
||||
).toBeDisabled()
|
||||
})
|
||||
|
||||
it('should use workflow config file endpoints with node_id for preview and upload', async () => {
|
||||
const user = userEvent.setup()
|
||||
renderAgentFiles({
|
||||
|
||||
@ -23,7 +23,11 @@ import { useMutation } from '@tanstack/react-query'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks'
|
||||
import { getSupportFileType } from '@/app/components/base/file-uploader/utils'
|
||||
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { useFileUploadConfig } from '@/service/use-common'
|
||||
import { formatFileSize } from '@/utils/format'
|
||||
import { getFileIconType } from './file-icon'
|
||||
|
||||
@ -46,10 +50,33 @@ function hasDraggedFiles(event: DragEvent<HTMLDivElement>) {
|
||||
|
||||
function AgentFileUploader({ file, onChange }: { file?: File; onChange: (file?: File) => void }) {
|
||||
const { t } = useTranslation('agentV2')
|
||||
const { t: tAppDebug } = useTranslation('appDebug')
|
||||
const { t: tCommon } = useTranslation('common')
|
||||
const { data: fileUploadConfig } = useFileUploadConfig()
|
||||
const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } =
|
||||
useFileSizeLimit(fileUploadConfig)
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const dragDepthRef = useRef(0)
|
||||
const [dragging, setDragging] = useState(false)
|
||||
|
||||
const getSizeLimit = (uploadFile: File) => {
|
||||
const fileType = getSupportFileType(uploadFile.name, uploadFile.type)
|
||||
|
||||
switch (fileType) {
|
||||
case SupportUploadFileTypes.image:
|
||||
return { fileType, sizeLimit: imgSizeLimit }
|
||||
case SupportUploadFileTypes.audio:
|
||||
return { fileType, sizeLimit: audioSizeLimit }
|
||||
case SupportUploadFileTypes.video:
|
||||
return { fileType, sizeLimit: videoSizeLimit }
|
||||
default:
|
||||
return {
|
||||
fileType: SupportUploadFileTypes.document,
|
||||
sizeLimit: docSizeLimit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setUploadFiles = (files: File[]) => {
|
||||
const [uploadFile] = files
|
||||
if (files.length !== 1 || !uploadFile) {
|
||||
@ -57,6 +84,17 @@ function AgentFileUploader({ file, onChange }: { file?: File; onChange: (file?:
|
||||
return
|
||||
}
|
||||
|
||||
const { fileType, sizeLimit } = getSizeLimit(uploadFile)
|
||||
if (uploadFile.size > sizeLimit) {
|
||||
toast.error(
|
||||
tCommon(($) => $['fileUploader.uploadFromComputerLimit'], {
|
||||
type: fileType,
|
||||
size: formatFileSize(sizeLimit),
|
||||
}),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
onChange(uploadFile)
|
||||
}
|
||||
|
||||
@ -158,6 +196,14 @@ function AgentFileUploader({ file, onChange }: { file?: File; onChange: (file?:
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<p className="mt-2 system-xs-regular text-text-tertiary">
|
||||
{tAppDebug(($) => $['variableConfig.maxNumberTip'], {
|
||||
docLimit: formatFileSize(docSizeLimit),
|
||||
imgLimit: formatFileSize(imgSizeLimit),
|
||||
audioLimit: formatFileSize(audioSizeLimit),
|
||||
videoLimit: formatFileSize(videoSizeLimit),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -62,6 +62,9 @@ const mocks = vi.hoisted(() => ({
|
||||
downloadBlob: vi.fn(),
|
||||
downloadUrl: vi.fn(),
|
||||
fetch: vi.fn(),
|
||||
fileUploadConfig: {
|
||||
skill_file_size_limit: 64,
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@langgenius/dify-ui/toast', () => ({
|
||||
@ -76,6 +79,10 @@ vi.mock('@/utils/download', () => ({
|
||||
downloadUrl: mocks.downloadUrl,
|
||||
}))
|
||||
|
||||
vi.mock('@/service/use-common', () => ({
|
||||
useFileUploadConfig: () => ({ data: mocks.fileUploadConfig }),
|
||||
}))
|
||||
|
||||
vi.mock('@/config', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import('@/config')>()),
|
||||
API_PREFIX: 'http://localhost:5001/console/api',
|
||||
@ -218,6 +225,7 @@ function renderAgentSkills({
|
||||
describe('AgentSkills', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mocks.fileUploadConfig.skill_file_size_limit = 64
|
||||
vi.stubGlobal('fetch', mocks.fetch)
|
||||
document.cookie = 'csrf_token=csrf-token; path=/'
|
||||
mocks.fetch.mockResolvedValue(
|
||||
@ -418,6 +426,59 @@ describe('AgentSkills', () => {
|
||||
expect(toast.success).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should show the configured skill package size limit', async () => {
|
||||
const user = userEvent.setup()
|
||||
renderAgentSkills({ initialDraft: defaultAgentSoulConfigFormState })
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.skills\.add/i }),
|
||||
)
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
'agentV2.agentDetail.configure.skills.upload.sizeLimit:{"sizeLimit":"64.00 MB"}',
|
||||
),
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should reject skill packages over the configured size limit', async () => {
|
||||
const user = userEvent.setup()
|
||||
mocks.fileUploadConfig.skill_file_size_limit = 1
|
||||
renderAgentSkills({ initialDraft: defaultAgentSoulConfigFormState })
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /agentV2\.agentDetail\.configure\.skills\.add/i }),
|
||||
)
|
||||
|
||||
const input = await waitFor(() => {
|
||||
const element = document.querySelector('input[type="file"]')
|
||||
expect(element).not.toBeNull()
|
||||
return element as HTMLInputElement
|
||||
})
|
||||
const oversizedFile = new File([new Uint8Array(1024 * 1024 + 1)], 'oversized-skill.skill', {
|
||||
type: 'application/zip',
|
||||
})
|
||||
await user.upload(input, oversizedFile)
|
||||
|
||||
expect(toast.error).toHaveBeenCalledWith(
|
||||
'agentV2.agentDetail.configure.skills.upload.sizeLimit:{"sizeLimit":"1.00 MB"}',
|
||||
)
|
||||
expect(
|
||||
screen.getByRole('button', {
|
||||
name: /agentDetail\.configure\.skills\.upload\.action/i,
|
||||
}),
|
||||
).toBeDisabled()
|
||||
|
||||
vi.mocked(toast.error).mockClear()
|
||||
const allowedFile = new File([new Uint8Array(1024 * 1024)], 'allowed-skill.skill', {
|
||||
type: 'application/zip',
|
||||
})
|
||||
await user.upload(input, allowedFile)
|
||||
|
||||
expect(screen.getByText('allowed-skill.skill')).toBeInTheDocument()
|
||||
expect(toast.error).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should hide skill package guidance before an upload fails', async () => {
|
||||
const user = userEvent.setup()
|
||||
renderAgentSkills({ initialDraft: defaultAgentSoulConfigFormState })
|
||||
|
||||
@ -19,8 +19,10 @@ import { useMutation } from '@tanstack/react-query'
|
||||
import { useRef, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks'
|
||||
import Link from '@/next/link'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { useFileUploadConfig } from '@/service/use-common'
|
||||
import { formatFileSize } from '@/utils/format'
|
||||
|
||||
const skillPackageAccept = '.zip,.skill'
|
||||
@ -68,6 +70,8 @@ function AgentSkillPackageUploader({
|
||||
showWarning: boolean
|
||||
}) {
|
||||
const { t } = useTranslation('agentV2')
|
||||
const { data: fileUploadConfig } = useFileUploadConfig()
|
||||
const { skillSizeLimit } = useFileSizeLimit(fileUploadConfig)
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const dragDepthRef = useRef(0)
|
||||
const [dragging, setDragging] = useState(false)
|
||||
@ -79,6 +83,15 @@ function AgentSkillPackageUploader({
|
||||
return
|
||||
}
|
||||
|
||||
if (uploadFile.size > skillSizeLimit) {
|
||||
toast.error(
|
||||
t(($) => $['agentDetail.configure.skills.upload.sizeLimit'], {
|
||||
sizeLimit: formatFileSize(skillSizeLimit),
|
||||
}),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
onChange(uploadFile)
|
||||
}
|
||||
|
||||
@ -186,6 +199,11 @@ function AgentSkillPackageUploader({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<p className="mt-2 system-xs-regular text-text-tertiary">
|
||||
{t(($) => $['agentDetail.configure.skills.upload.sizeLimit'], {
|
||||
sizeLimit: formatFileSize(skillSizeLimit),
|
||||
})}
|
||||
</p>
|
||||
{showWarning && (
|
||||
<div className="mt-2 flex items-start gap-2 rounded-lg border-[0.5px] border-components-badge-status-light-warning-halo bg-state-warning-hover px-3 py-2.5">
|
||||
<span
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "فشل تحميل المهارة.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "قم بتحميل ملف .zip أو .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "يجب ألا يتجاوز حجم حزمة Skill {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "تم تحميل المهارة.",
|
||||
"agentDetail.configure.skills.upload.title": "تحميل مهارة",
|
||||
"agentDetail.configure.skills.upload.warning.files": "إذا كنت تحتاج فقط إلى استخدام ملفات Markdown، فحمّلها إلى قسم الملفات وأشر إليها في الموجّه الخاص بك.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Skill konnte nicht hochgeladen werden.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Bitte eine .zip- oder .skill-Datei hochladen.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Das Skill-Paket darf maximal {{sizeLimit}} groß sein.",
|
||||
"agentDetail.configure.skills.upload.success": "Skill hochgeladen.",
|
||||
"agentDetail.configure.skills.upload.title": "Skill hochladen",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Wenn du nur Markdown-Dateien verwenden möchtest, lade sie unter „Dateien“ hoch und verweise in deinem Prompt darauf.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Failed to upload skill.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Upload a .zip or .skill file.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill package must be {{sizeLimit}} or smaller.",
|
||||
"agentDetail.configure.skills.upload.success": "Skill uploaded.",
|
||||
"agentDetail.configure.skills.upload.title": "Upload skill",
|
||||
"agentDetail.configure.skills.upload.warning.files": "If you only need to use Markdown files, upload them to Files and reference them in your prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Error al subir la habilidad.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Sube un archivo .zip o .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "El paquete de habilidad debe ocupar {{sizeLimit}} o menos.",
|
||||
"agentDetail.configure.skills.upload.success": "Habilidad subida.",
|
||||
"agentDetail.configure.skills.upload.title": "Subir habilidad",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Si solo necesitas usar archivos Markdown, súbelos a Archivos y haz referencia a ellos en tu prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "بارگذاری مهارت ناموفق بود.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "یک فایل .zip یا .skill بارگذاری کنید.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "حجم بسته Skill باید {{sizeLimit}} یا کمتر باشد.",
|
||||
"agentDetail.configure.skills.upload.success": "مهارت بارگذاری شد.",
|
||||
"agentDetail.configure.skills.upload.title": "بارگذاری مهارت",
|
||||
"agentDetail.configure.skills.upload.warning.files": "اگر فقط میخواهید از فایلهای Markdown استفاده کنید، آنها را در بخش فایلها بارگذاری و در پرامپت خود ارجاع دهید.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Échec du téléversement de la compétence.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Téléversez un fichier .zip ou .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Le paquet de compétence doit faire {{sizeLimit}} ou moins.",
|
||||
"agentDetail.configure.skills.upload.success": "Compétence téléversée.",
|
||||
"agentDetail.configure.skills.upload.title": "Téléverser une compétence",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Si vous souhaitez uniquement utiliser des fichiers Markdown, téléversez-les dans Fichiers et référencez-les dans votre prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "कौशल अपलोड करने में विफल।",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "एक .zip या .skill फ़ाइल अपलोड करें।",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill पैकेज का आकार {{sizeLimit}} या इससे कम होना चाहिए।",
|
||||
"agentDetail.configure.skills.upload.success": "कौशल अपलोड हो गया।",
|
||||
"agentDetail.configure.skills.upload.title": "कौशल अपलोड करें",
|
||||
"agentDetail.configure.skills.upload.warning.files": "यदि आपको केवल Markdown फ़ाइलों का उपयोग करना है, तो उन्हें फ़ाइलें में अपलोड करें और अपने प्रॉम्प्ट में उनका संदर्भ दें।",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Gagal mengunggah keterampilan.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Unggah file .zip atau .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Ukuran paket keterampilan tidak boleh lebih dari {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Keterampilan diunggah.",
|
||||
"agentDetail.configure.skills.upload.title": "Unggah keterampilan",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Jika Anda hanya perlu menggunakan file Markdown, unggah ke File dan rujuk file tersebut dalam prompt Anda.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Impossibile caricare l’abilità.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Carica un file .zip o .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Il pacchetto di abilità deve avere una dimensione massima di {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Abilità caricata.",
|
||||
"agentDetail.configure.skills.upload.title": "Carica abilità",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Se devi usare solo file Markdown, caricali in File e richiamali nel tuo prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "スキルのアップロードに失敗しました。",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": ".zip または .skill ファイルをアップロードしてください。",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill パッケージのサイズは {{sizeLimit}} 以下にしてください。",
|
||||
"agentDetail.configure.skills.upload.success": "スキルをアップロードしました。",
|
||||
"agentDetail.configure.skills.upload.title": "スキルをアップロード",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Markdown ファイルのみを使用する場合は、「ファイル」にアップロードし、プロンプト内で参照してください。",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "스킬 업로드에 실패했습니다.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": ".zip 또는 .skill 파일을 업로드하세요.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill 패키지는 {{sizeLimit}} 이하여야 합니다.",
|
||||
"agentDetail.configure.skills.upload.success": "스킬을 업로드했습니다.",
|
||||
"agentDetail.configure.skills.upload.title": "스킬 업로드",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Markdown 파일만 사용하려면 파일에 업로드하고 프롬프트에서 참조하세요.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Skill uploaden mislukt.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Upload een .zip- of .skill-bestand.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Het skill-pakket mag maximaal {{sizeLimit}} groot zijn.",
|
||||
"agentDetail.configure.skills.upload.success": "Skill geüpload.",
|
||||
"agentDetail.configure.skills.upload.title": "Skill uploaden",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Als je alleen Markdown-bestanden wilt gebruiken, upload ze dan naar Bestanden en verwijs ernaar in je prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Nie udało się przesłać umiejętności.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Prześlij plik .zip lub .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Pakiet umiejętności nie może być większy niż {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Umiejętność przesłana.",
|
||||
"agentDetail.configure.skills.upload.title": "Prześlij umiejętność",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Jeśli chcesz używać tylko plików Markdown, prześlij je do sekcji Pliki i odwołaj się do nich w swoim prompcie.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Falha ao enviar a habilidade.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Envie um arquivo .zip ou .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "O pacote de habilidade deve ter no máximo {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Habilidade enviada.",
|
||||
"agentDetail.configure.skills.upload.title": "Enviar habilidade",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Se você só precisa usar arquivos Markdown, envie-os para Arquivos e faça referência a eles no seu prompt.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Încărcarea abilității a eșuat.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Încărcați un fișier .zip sau .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Pachetul de abilitate trebuie să aibă cel mult {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Abilitate încărcată.",
|
||||
"agentDetail.configure.skills.upload.title": "Încarcă abilitate",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Dacă trebuie doar să folosești fișiere Markdown, încarcă-le în Fișiere și menționează-le în promptul tău.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Не удалось загрузить навык.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Загрузите файл .zip или .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Размер пакета навыка не должен превышать {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Навык загружен.",
|
||||
"agentDetail.configure.skills.upload.title": "Загрузить навык",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Если вам нужно использовать только файлы Markdown, загрузите их в раздел «Файлы» и укажите ссылки на них в своем промпте.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Veščine ni bilo mogoče naložiti.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Naložite datoteko .zip ali .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Paket veščine ne sme biti večji od {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Veščina naložena.",
|
||||
"agentDetail.configure.skills.upload.title": "Naloži veščino",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Če želite uporabljati samo datoteke Markdown, jih naložite v razdelek Datoteke in se nanje sklicujte v svojem pozivu.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "อัปโหลดทักษะไม่สำเร็จ",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "อัปโหลดไฟล์ .zip หรือ .skill",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "แพ็กเกจทักษะต้องมีขนาดไม่เกิน {{sizeLimit}}",
|
||||
"agentDetail.configure.skills.upload.success": "อัปโหลดทักษะแล้ว",
|
||||
"agentDetail.configure.skills.upload.title": "อัปโหลดทักษะ",
|
||||
"agentDetail.configure.skills.upload.warning.files": "หากต้องการใช้เฉพาะไฟล์ Markdown ให้อัปโหลดไปยังส่วนไฟล์และอ้างอิงไฟล์เหล่านั้นในพรอมต์ของคุณ",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Beceri yüklenemedi.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Bir .zip veya .skill dosyası yükleyin.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Beceri paketi en fazla {{sizeLimit}} boyutunda olmalıdır.",
|
||||
"agentDetail.configure.skills.upload.success": "Beceri yüklendi.",
|
||||
"agentDetail.configure.skills.upload.title": "Beceri yükle",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Yalnızca Markdown dosyalarını kullanmanız gerekiyorsa bunları Dosyalar bölümüne yükleyin ve isteminizde referans verin.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Не вдалося завантажити навичку.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Завантажте файл .zip або .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Розмір пакета навички не повинен перевищувати {{sizeLimit}}.",
|
||||
"agentDetail.configure.skills.upload.success": "Навичку завантажено.",
|
||||
"agentDetail.configure.skills.upload.title": "Завантажити навичку",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Якщо потрібно використовувати лише файли Markdown, завантажте їх у розділ «Файли» та посилайтеся на них у своєму промпті.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Tải lên kỹ năng thất bại.",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "Tải lên một tệp .zip hoặc .skill.",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Gói kỹ năng phải có dung lượng {{sizeLimit}} trở xuống.",
|
||||
"agentDetail.configure.skills.upload.success": "Đã tải lên kỹ năng.",
|
||||
"agentDetail.configure.skills.upload.title": "Tải lên kỹ năng",
|
||||
"agentDetail.configure.skills.upload.warning.files": "Nếu bạn chỉ cần sử dụng tệp Markdown, hãy tải chúng lên Tệp và tham chiếu chúng trong prompt của bạn.",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Skill 上传失败。",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "请上传 .zip 或 .skill 文件。",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill 包大小不得超过 {{sizeLimit}}。",
|
||||
"agentDetail.configure.skills.upload.success": "Skill 已上传。",
|
||||
"agentDetail.configure.skills.upload.title": "上传 Skill",
|
||||
"agentDetail.configure.skills.upload.warning.files": "如果只需要使用 Markdown 文件,请将它们上传到「文件」,并在你的提示词中引用。",
|
||||
|
||||
@ -222,6 +222,7 @@
|
||||
"agentDetail.configure.skills.upload.failed": "Skill 上傳失敗。",
|
||||
"agentDetail.configure.skills.upload.fileType": "ZIP / SKILL",
|
||||
"agentDetail.configure.skills.upload.invalidFile": "請上傳 .zip 或 .skill 檔案。",
|
||||
"agentDetail.configure.skills.upload.sizeLimit": "Skill 套件大小不得超過 {{sizeLimit}}。",
|
||||
"agentDetail.configure.skills.upload.success": "Skill 已上傳。",
|
||||
"agentDetail.configure.skills.upload.title": "上傳 Skill",
|
||||
"agentDetail.configure.skills.upload.warning.files": "如果只需要使用 Markdown 檔案,請將它們上傳到「檔案」,並在你的提示詞中引用。",
|
||||
|
||||
@ -127,6 +127,7 @@ export type FileUploadConfigResponse = {
|
||||
file_size_limit: number // default is 15MB
|
||||
audio_file_size_limit?: number // default is 50MB
|
||||
video_file_size_limit?: number // default is 100MB
|
||||
skill_file_size_limit?: number // default is 50MB
|
||||
workflow_file_upload_limit?: number // default is 10
|
||||
file_upload_limit: number // default is 5
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user