feat: add upload size guidance and validation for agent files and skills (#39798)

This commit is contained in:
Joel 2026-07-30 15:57:53 +08:00 committed by GitHub
parent e8b17345c3
commit b32c900761
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 230 additions and 0 deletions

View File

@ -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)
})
})

View File

@ -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):\/\//

View File

@ -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,
}
}

View File

@ -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({

View File

@ -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>
)
}

View File

@ -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 })

View File

@ -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

View File

@ -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، فحمّلها إلى قسم الملفات وأشر إليها في الموجّه الخاص بك.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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 استفاده کنید، آن‌ها را در بخش فایل‌ها بارگذاری و در پرامپت خود ارجاع دهید.",

View File

@ -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.",

View File

@ -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 फ़ाइलों का उपयोग करना है, तो उन्हें फ़ाइलें में अपलोड करें और अपने प्रॉम्प्ट में उनका संदर्भ दें।",

View File

@ -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.",

View File

@ -222,6 +222,7 @@
"agentDetail.configure.skills.upload.failed": "Impossibile caricare labilità.",
"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.",

View File

@ -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 ファイルのみを使用する場合は、「ファイル」にアップロードし、プロンプト内で参照してください。",

View File

@ -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 파일만 사용하려면 파일에 업로드하고 프롬프트에서 참조하세요.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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, загрузите их в раздел «Файлы» и укажите ссылки на них в своем промпте.",

View File

@ -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.",

View File

@ -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 ให้อัปโหลดไปยังส่วนไฟล์และอ้างอิงไฟล์เหล่านั้นในพรอมต์ของคุณ",

View File

@ -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.",

View File

@ -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, завантажте їх у розділ «Файли» та посилайтеся на них у своєму промпті.",

View File

@ -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.",

View File

@ -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 文件,请将它们上传到「文件」,并在你的提示词中引用。",

View File

@ -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 檔案,請將它們上傳到「檔案」,並在你的提示詞中引用。",

View File

@ -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
}