From c2fb3604de533838a85b1a80a322e7e6121ebf2f Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 11 Feb 2026 11:44:44 +0800 Subject: [PATCH] feat: can show add files --- .../plugins/component-picker-block/index.tsx | 48 ++- .../plugins/file-picker-panel.tsx | 23 ++ .../plugins/file-picker-upload-modal.tsx | 313 ++++++++++++++++++ web/i18n/ar-TN/workflow.json | 3 + web/i18n/de-DE/workflow.json | 3 + web/i18n/en-US/workflow.json | 3 + web/i18n/es-ES/workflow.json | 3 + web/i18n/fa-IR/workflow.json | 3 + web/i18n/fr-FR/workflow.json | 3 + web/i18n/hi-IN/workflow.json | 3 + web/i18n/id-ID/workflow.json | 3 + web/i18n/it-IT/workflow.json | 3 + web/i18n/ja-JP/workflow.json | 3 + web/i18n/ko-KR/workflow.json | 3 + web/i18n/pl-PL/workflow.json | 3 + web/i18n/pt-BR/workflow.json | 3 + web/i18n/ro-RO/workflow.json | 3 + web/i18n/ru-RU/workflow.json | 3 + web/i18n/sl-SI/workflow.json | 3 + web/i18n/th-TH/workflow.json | 3 + web/i18n/tr-TR/workflow.json | 3 + web/i18n/uk-UA/workflow.json | 3 + web/i18n/vi-VN/workflow.json | 3 + web/i18n/zh-Hans/workflow.json | 3 + web/i18n/zh-Hant/workflow.json | 3 + 25 files changed, 436 insertions(+), 14 deletions(-) create mode 100644 web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-upload-modal.tsx diff --git a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx index a4c6335b44..bbee477976 100644 --- a/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx @@ -46,6 +46,7 @@ import { SegmentedControl } from '@/app/components/base/segmented-control' import AgentNodeList from '@/app/components/workflow/nodes/_base/components/agent-node-list' import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars' import { FilePickerPanel } from '@/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-panel' +import FilePickerUploadModal from '@/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-upload-modal' import { $createFileReferenceNode } from '@/app/components/workflow/skill/editor/skill-editor/plugins/file-reference-block/node' import { BlockEnum } from '@/app/components/workflow/types' import { useEventEmitterContextContext } from '@/context/event-emitter' @@ -138,6 +139,8 @@ const ComponentPicker = ({ const [queryString, setQueryString] = useState(null) const [activeTab, setActiveTab] = useState<'variables' | 'files'>('variables') + const [isFileUploadModalOpen, setIsFileUploadModalOpen] = useState(false) + const [fileUploadModalKey, setFileUploadModalKey] = useState(0) eventEmitter?.useSubscription((v: any) => { if (v.type === INSERT_VARIABLE_VALUE_BLOCK_COMMAND) @@ -298,6 +301,10 @@ const ComponentPicker = ({ visibility: isPositioned ? 'visible' : 'hidden', }} ref={refs.setFloating} + onMouseDown={(event) => { + event.preventDefault() + event.stopPropagation() + }} >
{ + setFileUploadModalKey(key => key + 1) + setIsFileUploadModalOpen(true) + handleClose() + }} /> )}
@@ -473,20 +486,27 @@ const ComponentPicker = ({ }, [isAgentTrigger, isSupportSandbox, triggerString, allFlattenOptions.length, workflowVariableBlock?.show, workflowVariableBlock?.showManageInputField, workflowVariableBlock?.onManageInputField, floatingStyles, isPositioned, refs, agentNodes, handleSelectAgent, handleClose, useExternalSearch, queryString, workflowVariableOptions, isSupportFileVar, showAssembleVariables, handleSelectAssembleVariables, currentBlock?.generatorType, t, activeTab, handleSelectWorkflowVariable, handleSelectFileReference]) return ( - + <> + + setIsFileUploadModalOpen(false)} + /> + ) } diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-panel.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-panel.tsx index a6423d50c3..deaf6fdafc 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-panel.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-panel.tsx @@ -118,6 +118,8 @@ type FilePickerPanelProps = { className?: string contentClassName?: string showHeader?: boolean + showAddFiles?: boolean + onAddFiles?: () => void } const FilePickerPanel = ({ @@ -126,6 +128,8 @@ const FilePickerPanel = ({ className, contentClassName, showHeader = true, + showAddFiles = false, + onAddFiles, }: FilePickerPanelProps) => { const { t } = useTranslation('workflow') const { data: treeData, isLoading, error } = useSkillAssetTreeData() @@ -133,6 +137,7 @@ const FilePickerPanel = ({ const containerSize = useSize(containerRef) const treeNodes = useMemo(() => treeData?.children || [], [treeData?.children]) + const initialOpenState = useMemo(() => { const nextState: Record = {} if (!focusNodeId || treeNodes.length === 0) @@ -162,6 +167,7 @@ const FilePickerPanel = ({ if (target.closest('input, textarea, select')) return e.preventDefault() + e.stopPropagation() }} > {showHeader && ( @@ -214,6 +220,23 @@ const FilePickerPanel = ({ )} + {showAddFiles && ( + <> +
+ + + )}
) } diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-upload-modal.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-upload-modal.tsx new file mode 100644 index 0000000000..ce9815efbd --- /dev/null +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/file-picker-upload-modal.tsx @@ -0,0 +1,313 @@ +import type { Item } from '@/app/components/base/select' +import type { TreeNodeData } from '@/app/components/workflow/skill/type' +import { noop } from 'es-toolkit/function' +import * as React from 'react' +import { useCallback, useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useStore as useAppStore } from '@/app/components/app/store' +import Button from '@/app/components/base/button' +import Input from '@/app/components/base/input' +import Modal from '@/app/components/base/modal' +import { SimpleSelect } from '@/app/components/base/select' +import Toast from '@/app/components/base/toast' +import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card' +import { ROOT_ID } from '@/app/components/workflow/skill/constants' +import { useSkillAssetTreeData } from '@/app/components/workflow/skill/hooks/file-tree/data/use-skill-asset-tree' +import { useSkillTreeUpdateEmitter } from '@/app/components/workflow/skill/hooks/file-tree/data/use-skill-tree-collaboration' +import { useCreateOperations } from '@/app/components/workflow/skill/hooks/file-tree/operations/use-create-operations' +import { toApiParentId } from '@/app/components/workflow/skill/utils/tree-utils' +import { useWorkflowStore } from '@/app/components/workflow/store' +import { useUploadFileWithPresignedUrl } from '@/service/use-app-asset' +import { cn } from '@/utils/classnames' + +type FilePickerUploadModalProps = { + isOpen: boolean + onClose: () => void + defaultFolderId?: string +} + +type AddFileMode = 'create' | 'upload' +type FolderOption = Item & { + pathLabel: string + depth: number + hasChildren: boolean +} + +const FilePickerUploadModal = ({ + isOpen, + onClose, + defaultFolderId, +}: FilePickerUploadModalProps) => { + const { t } = useTranslation('workflow') + const appDetail = useAppStore(s => s.appDetail) + const appId = appDetail?.id || '' + const storeApi = useWorkflowStore() + const { data: treeData } = useSkillAssetTreeData() + const emitTreeUpdate = useSkillTreeUpdateEmitter() + const uploadFile = useUploadFileWithPresignedUrl() + const [mode, setMode] = useState('create') + const [uploadFolderId, setUploadFolderId] = useState(defaultFolderId || ROOT_ID) + const [fileName, setFileName] = useState('') + const [isDragOver, setIsDragOver] = useState(false) + + const treeNodes = useMemo(() => treeData?.children || [], [treeData?.children]) + const folderOptions = useMemo(() => { + const options: FolderOption[] = [{ + value: ROOT_ID, + name: t('skillSidebar.rootFolder'), + pathLabel: t('skillSidebar.rootFolder'), + depth: 0, + hasChildren: true, + }] + + const travelFolders = (nodes: TreeNodeData[]) => { + nodes.forEach((node) => { + if (node.node_type !== 'folder') + return + + const folderPath = node.path.replace(/^\//, '') || node.name + const depth = Math.max(0, folderPath.split('/').length - 1) + options.push({ + value: node.id, + name: node.name, + pathLabel: folderPath, + depth, + hasChildren: node.children.some(child => child.node_type === 'folder'), + }) + if (node.children.length > 0) + travelFolders(node.children) + }) + } + travelFolders(treeNodes) + return options + }, [t, treeNodes]) + + const effectiveUploadFolderId = useMemo(() => { + return folderOptions.some(item => item.value === uploadFolderId) + ? uploadFolderId + : ROOT_ID + }, [folderOptions, uploadFolderId]) + const selectedFolderOption = useMemo(() => { + return folderOptions.find(item => item.value === effectiveUploadFolderId) || folderOptions[0] + }, [effectiveUploadFolderId, folderOptions]) + + const { + fileInputRef, + isCreating, + handleFileChange: handleRawFileChange, + } = useCreateOperations({ + parentId: toApiParentId(effectiveUploadFolderId), + appId, + storeApi, + onClose: noop, + }) + const isCreatingFile = uploadFile.isPending + const isBusy = isCreating || isCreatingFile + const trimmedFileName = fileName.trim() + const canCreate = !!appId && !!trimmedFileName && !isBusy + + const handleClose = useCallback(() => { + if (isBusy) + return + onClose() + }, [isBusy, onClose]) + + const handleUploadFilesChange = useCallback(async (e: React.ChangeEvent) => { + const hasSelectedFiles = (e.target.files?.length ?? 0) > 0 + await handleRawFileChange(e) + if (hasSelectedFiles) + onClose() + }, [handleRawFileChange, onClose]) + const handleDrop = useCallback(async (e: React.DragEvent) => { + e.preventDefault() + if (isBusy || !appId) + return + setIsDragOver(false) + const droppedFiles = Array.from(e.dataTransfer.files || []) + if (!droppedFiles.length) + return + const transfer = new DataTransfer() + droppedFiles.forEach(file => transfer.items.add(file)) + await handleUploadFilesChange({ + target: { + files: transfer.files, + value: '', + }, + } as React.ChangeEvent) + }, [appId, handleUploadFilesChange, isBusy]) + const handleCreateFile = useCallback(async () => { + if (!canCreate) + return + + try { + const emptyBlob = new Blob([''], { type: 'text/plain' }) + const file = new File([emptyBlob], trimmedFileName) + await uploadFile.mutateAsync({ + appId, + file, + parentId: toApiParentId(effectiveUploadFolderId), + }) + emitTreeUpdate() + onClose() + } + catch { + Toast.notify({ + type: 'error', + message: t('skillSidebar.menu.createError'), + }) + } + }, [appId, canCreate, effectiveUploadFolderId, emitTreeUpdate, onClose, t, trimmedFileName, uploadFile]) + const modeLabel = t('skillEditor.uploadIn') + + return ( + +
+
+
+ setMode('create')} + selected={mode === 'create'} + disabled={isBusy} + /> + setMode('upload')} + selected={mode === 'upload'} + disabled={isBusy} + /> +
+
+
{modeLabel}
+ { + const currentOption = selectedItem as FolderOption | null + const label = currentOption?.pathLabel || selectedFolderOption?.pathLabel || t('skillSidebar.rootFolder') + return ( +
+
+ ) + }} + renderOption={({ item }) => { + const option = item as FolderOption + return ( +
+
+ ) + }} + onSelect={item => setUploadFolderId(String(item.value))} + /> +
+ {mode === 'create' && ( +
+
{t('skillSidebar.fileNamePlaceholder')}
+ setFileName(e.target.value)} + placeholder={t('skillSidebar.fileNamePlaceholder') || ''} + disabled={isBusy} + onKeyDown={(e) => { + if (e.key === 'Enter') + void handleCreateFile() + }} + /> +
+ )} + + {mode === 'upload' && ( +
{ + if (!isBusy && appId) + fileInputRef.current?.click() + }} + onDragOver={(e) => { + e.preventDefault() + if (!isBusy) + setIsDragOver(true) + }} + onDragLeave={(e) => { + e.preventDefault() + setIsDragOver(false) + }} + onDrop={handleDrop} + onKeyDown={(e) => { + if ((e.key === 'Enter' || e.key === ' ') && !isBusy && appId) + fileInputRef.current?.click() + }} + > +
+ )} +
+ + {mode === 'create' + ? ( + + ) + : ( + + )} +
+
+ + ) +} + +export default React.memo(FilePickerUploadModal) diff --git a/web/i18n/ar-TN/workflow.json b/web/i18n/ar-TN/workflow.json index 162f804d85..b7d413e344 100644 --- a/web/i18n/ar-TN/workflow.json +++ b/web/i18n/ar-TN/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "تشغيل اختياري", "singleRun.testRunIteration": "تكرار تشغيل الاختبار", "singleRun.testRunLoop": "حلقة اختبار التشغيل", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "افتراضي", "tabs.addAll": "إضافة الكل", "tabs.agent": "استراتيجية الوكيل", diff --git a/web/i18n/de-DE/workflow.json b/web/i18n/de-DE/workflow.json index d9d82bde5e..56e4a6ab9c 100644 --- a/web/i18n/de-DE/workflow.json +++ b/web/i18n/de-DE/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Testlauf ", "singleRun.testRunIteration": "Testlaufiteration", "singleRun.testRunLoop": "Testdurchlauf-Schleife", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Standard", "tabs.addAll": "Alles hinzufügen", "tabs.agent": "Agenten-Strategie", diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 15a4213e6b..50aceaa86f 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -1219,6 +1219,7 @@ "skill.startTab.templatesDesc": "Choose a template to bootstrap your agent's capabilities", "skill.startTab.templatesTitle": "Skill Templates", "skill.startTab.useThisSkill": "Use this Skill", + "skillEditor.addFiles": "Add files", "skillEditor.authorizationBadge": "Auth", "skillEditor.authorizationRequired": "Authorization required before use.", "skillEditor.fileNotFound": "The file does not exist", @@ -1229,6 +1230,8 @@ "skillEditor.toolMissing": "Tool missing", "skillEditor.toolMissingDesc": "Go to Plugins to install", "skillEditor.unsupportedPreview": "This file type is not supported for preview", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "skillSidebar.addFile": "Upload File", "skillSidebar.addFolder": "New Folder", "skillSidebar.artifacts.emptyState": "Files generated by the agent during test runs. They may be automatically cleared later.", diff --git a/web/i18n/es-ES/workflow.json b/web/i18n/es-ES/workflow.json index a5e65b709c..40fca5f17f 100644 --- a/web/i18n/es-ES/workflow.json +++ b/web/i18n/es-ES/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Ejecución de prueba", "singleRun.testRunIteration": "Iteración de ejecución de prueba", "singleRun.testRunLoop": "Bucle de prueba", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "predeterminado", "tabs.addAll": "Agregar todo", "tabs.agent": "Estrategia del agente", diff --git a/web/i18n/fa-IR/workflow.json b/web/i18n/fa-IR/workflow.json index 901cea2cb0..fdd7e94fdf 100644 --- a/web/i18n/fa-IR/workflow.json +++ b/web/i18n/fa-IR/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "اجرای آزمایشی", "singleRun.testRunIteration": "تکرار اجرای آزمایشی", "singleRun.testRunLoop": "اجرای آزمایشی حلقه", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "پیش‌فرض", "tabs.addAll": "همه را اضافه کنید", "tabs.agent": "استراتژی نمایندگی", diff --git a/web/i18n/fr-FR/workflow.json b/web/i18n/fr-FR/workflow.json index be32d265a9..ea151ec8b5 100644 --- a/web/i18n/fr-FR/workflow.json +++ b/web/i18n/fr-FR/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Exécution de test", "singleRun.testRunIteration": "Itération de l'exécution de test", "singleRun.testRunLoop": "Boucle d'exécution de test", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Par défaut", "tabs.addAll": "Ajouter tout", "tabs.agent": "Stratégie d’agent", diff --git a/web/i18n/hi-IN/workflow.json b/web/i18n/hi-IN/workflow.json index 0e3fcc5234..3e5fad67f3 100644 --- a/web/i18n/hi-IN/workflow.json +++ b/web/i18n/hi-IN/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "परीक्षण रन", "singleRun.testRunIteration": "परीक्षण रन पुनरावृत्ति", "singleRun.testRunLoop": "परीक्षण रन लूप", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "डिफ़ॉल्ट", "tabs.addAll": "सभी जोड़ें", "tabs.agent": "एजेंट रणनीति", diff --git a/web/i18n/id-ID/workflow.json b/web/i18n/id-ID/workflow.json index 2edf9a34e4..db70965c9d 100644 --- a/web/i18n/id-ID/workflow.json +++ b/web/i18n/id-ID/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Uji Coba", "singleRun.testRunIteration": "Iterasi Uji Coba", "singleRun.testRunLoop": "Uji Jalankan Loop", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Default", "tabs.addAll": "Tambahkan semua", "tabs.agent": "Strategi Agen", diff --git a/web/i18n/it-IT/workflow.json b/web/i18n/it-IT/workflow.json index aa8afd3ddf..f9ff14637c 100644 --- a/web/i18n/it-IT/workflow.json +++ b/web/i18n/it-IT/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Esecuzione Test ", "singleRun.testRunIteration": "Iterazione Esecuzione Test", "singleRun.testRunLoop": "Esegui ciclo di prova", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Predefinito", "tabs.addAll": "Aggiungi tutto", "tabs.agent": "Strategia dell'agente", diff --git a/web/i18n/ja-JP/workflow.json b/web/i18n/ja-JP/workflow.json index 8e8226e1bb..445fcf54be 100644 --- a/web/i18n/ja-JP/workflow.json +++ b/web/i18n/ja-JP/workflow.json @@ -1142,6 +1142,9 @@ "singleRun.testRun": "テスト実行", "singleRun.testRunIteration": "テスト実行(イテレーション)", "singleRun.testRunLoop": "テスト実行ループ", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "subGraphModal.canvasPlaceholder": "クリックして内部構造を設定", "subGraphModal.defaultValueHint": "以下の値を返す", "subGraphModal.internalStructure": "内部構造", diff --git a/web/i18n/ko-KR/workflow.json b/web/i18n/ko-KR/workflow.json index f6b9247763..30e05d55f1 100644 --- a/web/i18n/ko-KR/workflow.json +++ b/web/i18n/ko-KR/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "테스트 실행", "singleRun.testRunIteration": "테스트 실행 반복", "singleRun.testRunLoop": "테스트 실행 루프", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "기본", "tabs.addAll": "모두 추가", "tabs.agent": "에이전트 전략", diff --git a/web/i18n/pl-PL/workflow.json b/web/i18n/pl-PL/workflow.json index 8c5b1cbf73..0b932c7432 100644 --- a/web/i18n/pl-PL/workflow.json +++ b/web/i18n/pl-PL/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Testowe uruchomienie ", "singleRun.testRunIteration": "Iteracja testowego uruchomienia", "singleRun.testRunLoop": "Pętla testowa", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Domyślny", "tabs.addAll": "Dodaj wszystko", "tabs.agent": "Strategia agenta", diff --git a/web/i18n/pt-BR/workflow.json b/web/i18n/pt-BR/workflow.json index 975af1a387..5c6fd30db2 100644 --- a/web/i18n/pt-BR/workflow.json +++ b/web/i18n/pt-BR/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Execução de teste ", "singleRun.testRunIteration": "Iteração de execução de teste", "singleRun.testRunLoop": "Loop de Teste", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Padrão", "tabs.addAll": "Adicionar tudo", "tabs.agent": "Estratégia do agente", diff --git a/web/i18n/ro-RO/workflow.json b/web/i18n/ro-RO/workflow.json index 099bc083cb..c2ba16f65a 100644 --- a/web/i18n/ro-RO/workflow.json +++ b/web/i18n/ro-RO/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Rulare de test ", "singleRun.testRunIteration": "Iterație rulare de test", "singleRun.testRunLoop": "Bucle de testare", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Implicit", "tabs.addAll": "Adaugă tot", "tabs.agent": "Strategia agentului", diff --git a/web/i18n/ru-RU/workflow.json b/web/i18n/ru-RU/workflow.json index 4cf5cea594..bd9943f5d3 100644 --- a/web/i18n/ru-RU/workflow.json +++ b/web/i18n/ru-RU/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Тестовый запуск ", "singleRun.testRunIteration": "Итерация тестового запуска", "singleRun.testRunLoop": "Тестовый цикл запуска", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "По умолчанию", "tabs.addAll": "Добавить всё", "tabs.agent": "Агентская стратегия", diff --git a/web/i18n/sl-SI/workflow.json b/web/i18n/sl-SI/workflow.json index 49ba689da5..19934c6bea 100644 --- a/web/i18n/sl-SI/workflow.json +++ b/web/i18n/sl-SI/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Testna vožnja", "singleRun.testRunIteration": "Testiranje ponovitve", "singleRun.testRunLoop": "Testni zagon zanke", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Privzeto", "tabs.addAll": "Dodaj vse", "tabs.agent": "Agentska strategija", diff --git a/web/i18n/th-TH/workflow.json b/web/i18n/th-TH/workflow.json index 820dba5d42..7c94dad896 100644 --- a/web/i18n/th-TH/workflow.json +++ b/web/i18n/th-TH/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "ทดสอบการทํางาน", "singleRun.testRunIteration": "การทดสอบการทําซ้ํา", "singleRun.testRunLoop": "รันลูปทดสอบ", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "ค่าเริ่มต้น", "tabs.addAll": "เพิ่มทั้งหมด", "tabs.agent": "กลยุทธ์ตัวแทน", diff --git a/web/i18n/tr-TR/workflow.json b/web/i18n/tr-TR/workflow.json index f217792e52..36a6155481 100644 --- a/web/i18n/tr-TR/workflow.json +++ b/web/i18n/tr-TR/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Test Çalıştırma", "singleRun.testRunIteration": "Test Çalıştırma Yineleme", "singleRun.testRunLoop": "Test Çalıştırma Döngüsü", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Varsayılan", "tabs.addAll": "Hepsini ekle", "tabs.agent": "Temsilci Stratejisi", diff --git a/web/i18n/uk-UA/workflow.json b/web/i18n/uk-UA/workflow.json index f98321a5ed..ae1432c7e0 100644 --- a/web/i18n/uk-UA/workflow.json +++ b/web/i18n/uk-UA/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Тестовий запуск", "singleRun.testRunIteration": "Ітерація тестового запуску", "singleRun.testRunLoop": "Тестовий цикл виконання", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "За замовчуванням", "tabs.addAll": "Додати все", "tabs.agent": "Стратегія агента", diff --git a/web/i18n/vi-VN/workflow.json b/web/i18n/vi-VN/workflow.json index 09adfbccdc..8b04d83a13 100644 --- a/web/i18n/vi-VN/workflow.json +++ b/web/i18n/vi-VN/workflow.json @@ -1105,6 +1105,9 @@ "singleRun.testRun": "Chạy thử nghiệm ", "singleRun.testRunIteration": "Lặp chạy thử nghiệm", "singleRun.testRunLoop": "Chạy thử vòng lặp", + "skillEditor.addFiles": "Add files", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "tabs.-": "Mặc định", "tabs.addAll": "Thêm tất cả", "tabs.agent": "Chiến lược đại lý", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 4ecbcea2e4..1e93a7748f 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -1205,6 +1205,7 @@ "skill.startTab.templatesDesc": "选择模板来快速构建你的 Agent 能力", "skill.startTab.templatesTitle": "Skill 模板", "skill.startTab.useThisSkill": "使用此 Skill", + "skillEditor.addFiles": "Add files", "skillEditor.authorizationBadge": "Auth", "skillEditor.authorizationRequired": "使用前需要授权。", "skillEditor.fileNotFound": "文件不存在", @@ -1215,6 +1216,8 @@ "skillEditor.toolMissing": "工具缺失", "skillEditor.toolMissingDesc": "前往 插件 安装", "skillEditor.unsupportedPreview": "该文件类型不支持预览", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "skillSidebar.addFile": "上传文件", "skillSidebar.addFolder": "新建文件夹", "skillSidebar.artifacts.emptyState": "代理在测试运行期间生成的文件。这些文件可能会在稍后自动清除。", diff --git a/web/i18n/zh-Hant/workflow.json b/web/i18n/zh-Hant/workflow.json index 6b6fbeceaf..264339a7a3 100644 --- a/web/i18n/zh-Hant/workflow.json +++ b/web/i18n/zh-Hant/workflow.json @@ -1152,9 +1152,12 @@ "singleRun.testRun": "測試運行", "singleRun.testRunIteration": "測試運行迭代", "singleRun.testRunLoop": "測試運行循環", + "skillEditor.addFiles": "Add files", "skillEditor.referenceFiles": "參考檔案", "skillEditor.toolMissing": "工具遺失", "skillEditor.toolMissingDesc": "前往 外掛 安裝", + "skillEditor.uploadFiles": "Upload files", + "skillEditor.uploadIn": "Upload in", "subGraphModal.canvasPlaceholder": "點擊配置內部結構", "subGraphModal.defaultValueHint": "返回以下值", "subGraphModal.internalStructure": "內部結構",