From b07afd378545a37e275052d39a8624cf4a270609 Mon Sep 17 00:00:00 2001 From: ssongliu Date: Wed, 4 Nov 2026 16:11:16 +0800 Subject: [PATCH] feat(ai): improve model preparation and download progress refresh (#14297) --- agent/app/dto/model_downloader.go | 1 + agent/app/service/app_utils.go | 10 +- agent/app/service/model_downloader.go | 41 +- .../src/api/interface/model-downloader.ts | 1 + frontend/src/lang/modules/en.ts | 44 +- frontend/src/lang/modules/es-es.ts | 45 +- frontend/src/lang/modules/fa.ts | 45 +- frontend/src/lang/modules/ja.ts | 45 +- frontend/src/lang/modules/ko.ts | 44 +- frontend/src/lang/modules/lo.ts | 43 +- frontend/src/lang/modules/ms.ts | 46 +- frontend/src/lang/modules/pt-br.ts | 45 +- frontend/src/lang/modules/ru.ts | 44 +- frontend/src/lang/modules/tr.ts | 45 +- frontend/src/lang/modules/zh-Hant.ts | 41 +- frontend/src/lang/modules/zh.ts | 41 +- frontend/src/views/ai/model/deployment.ts | 10 + frontend/src/views/ai/model/index.vue | 7 + .../src/views/ai/model/ollama/add/index.vue | 45 +- .../views/ai/model/ollama/models/index.vue | 14 +- frontend/src/views/model-downloader/index.vue | 454 +++++++++++++----- .../views/model-downloader/source-select.vue | 38 +- 22 files changed, 880 insertions(+), 269 deletions(-) diff --git a/agent/app/dto/model_downloader.go b/agent/app/dto/model_downloader.go index fd45058d5..2964a39a1 100644 --- a/agent/app/dto/model_downloader.go +++ b/agent/app/dto/model_downloader.go @@ -54,6 +54,7 @@ type ModelInfo struct { } type ModelDownloadTaskSearch struct { + IDs []uint `json:"ids"` IncludeLocal bool `json:"includeLocal"` DownloadType string `json:"downloadType" validate:"omitempty,oneof=all tokenizer"` PageInfo diff --git a/agent/app/service/app_utils.go b/agent/app/service/app_utils.go index 77bfa5422..d0637d5d1 100644 --- a/agent/app/service/app_utils.go +++ b/agent/app/service/app_utils.go @@ -1238,13 +1238,19 @@ func rebuildApp(appInstall model.AppInstall) error { return handleErr(appInstall, err, "") } buildTask.AddSubTaskWithOps(buildTask.Name, func(t *task.Task) error { + t.Log(task.GetTaskName(appInstall.Name, "Stop", task.TaskScopeApp)) out, err := compose.Down(appInstall.GetComposePath()) - t.Log(out) + if strings.TrimSpace(out) != "" { + t.Log(out) + } if err != nil { return handleErr(appInstall, err, out) } + t.Log(task.GetTaskName(appInstall.Name, "Run", task.TaskScopeApp)) out, err = compose.Up(appInstall.GetComposePath()) - t.Log(out) + if strings.TrimSpace(out) != "" { + t.Log(out) + } if err != nil { return handleErr(appInstall, err, out) } diff --git a/agent/app/service/model_downloader.go b/agent/app/service/model_downloader.go index 0c602de2f..a35c54045 100644 --- a/agent/app/service/model_downloader.go +++ b/agent/app/service/model_downloader.go @@ -268,6 +268,9 @@ func (m *ModelDownloaderService) PageTasks(req dto.ModelDownloadTaskSearch) (int return pageModelDownloads(req) } var opts []repo.DBOption + if len(req.IDs) > 0 { + opts = append(opts, repo.WithByIDs(req.IDs)) + } if req.DownloadType != "" { opts = append(opts, modelDownloadTaskRepo.WithByDownloadType(req.DownloadType)) } @@ -469,6 +472,9 @@ func (m *ModelDownloaderService) deleteLocalModel(target, downloadType string, w func pageModelDownloads(req dto.ModelDownloadTaskSearch) (int64, []dto.ModelDownloadTaskItem, error) { var opts []repo.DBOption + if len(req.IDs) > 0 { + opts = append(opts, repo.WithByIDs(req.IDs)) + } if req.DownloadType != "" { opts = append(opts, modelDownloadTaskRepo.WithByDownloadType(req.DownloadType)) } @@ -502,24 +508,27 @@ func pageModelDownloads(req dto.ModelDownloadTaskSearch) (int64, []dto.ModelDown } items = append(items, item) } - for _, local := range localByPath { - repoID := local.RepoID - if repoID == "" { - repoID = local.Name + if len(req.IDs) == 0 { + for _, local := range localByPath { + repoID := local.RepoID + if repoID == "" { + repoID = local.Name + } + items = append(items, dto.ModelDownloadTaskItem{ + DownloadType: local.DownloadType, + Source: local.Source, + RepoID: repoID, + TargetDir: local.Path, + Status: constant.StatusSuccess, + Progress: 100, + TotalSize: local.Size, + DownloadedSize: local.Size, + CreatedAt: local.CreatedAt, + LocalModel: &local, + }) } - items = append(items, dto.ModelDownloadTaskItem{ - DownloadType: local.DownloadType, - Source: local.Source, - RepoID: repoID, - TargetDir: local.Path, - Status: constant.StatusSuccess, - Progress: 100, - TotalSize: local.Size, - DownloadedSize: local.Size, - CreatedAt: local.CreatedAt, - LocalModel: &local, - }) } + filtered := items[:0] for _, item := range items { if req.Status != "" && item.Status != req.Status { diff --git a/frontend/src/api/interface/model-downloader.ts b/frontend/src/api/interface/model-downloader.ts index cf88e4167..24322acad 100644 --- a/frontend/src/api/interface/model-downloader.ts +++ b/frontend/src/api/interface/model-downloader.ts @@ -76,6 +76,7 @@ export namespace ModelDownloader { } export interface TaskSearch extends ReqPage { + ids?: number[]; includeLocal?: boolean; downloadType?: DownloadType | ''; info: string; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 4103be847..7c4364d67 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1041,6 +1041,29 @@ const message = { validateImageAvailabilityHelper: 'Generates one minimal image before saving and may incur charges', }, model: { + searchTitle: 'Search and download models', + searchHelper: + 'Find models on ModelScope or Hugging Face, then deploy them or create a Recipe in Model Preparation.', + modelScopeSearchHelper: 'Reliable access in mainland China', + huggingFaceSearchHelper: 'Extensive model collection', + searchPlaceholder: 'Enter a model name or repository ID, e.g. Qwen/Qwen3-8B', + popularSearches: 'Popular searches', + searchSort: 'Sort by', + onlyTokenizer: 'Tokenizer only', + downloadStatus: 'Download Status', + downloaded: 'Downloaded', + alreadyExists: 'Already exists', + downloadCompleted: 'Download completed', + localFilesMissing: 'Local files not found', + ollamaNameHelper: + 'Enter the full model name from the Ollama library. If no tag is specified, latest is used.', + downloadHelper: 'Click “Search” to find and download models from ModelScope and Hugging Face.', + serviceHelper: + 'Connect model services from public clouds, local inference engines, and AI gateways for use by built-in 1Panel agents and external agents such as WorkBuddy.', + gpuType: 'GPU Type', + vllmVersion: 'vLLM Version', + vllmImage: 'vLLM Image', + servicePort: 'Service Port', gpuAcceleration: 'GPU acceleration', gpuMode: 'Accelerator selection', gpuAll: 'All accelerators', @@ -1072,7 +1095,13 @@ const message = { approxWeightSize: 'Approx. {0} GB', services: 'Model services', addInstance: 'Add instance', - addService: 'Add model service', + modelScopeEndpointHelper: 'Used to search and download ModelScope models. Defaults to the official URL.', + modelTokenHelper: 'Optional. Use a token with access permissions for private or restricted models.', + modelDirHelper: 'Directory for model downloads and the local model list.', + featuredModelsHelper: + 'Official 1Panel featured model catalog. Refresh manually or enable auto-sync every 24 hours. Sync updates only the catalog, without downloading model files.', + addInstanceHelper: 'Create a vLLM instance to serve downloaded models.', + addService: 'Add', onlineModel: 'Online models', instanceDeployment: 'Deploy by instance', engines: 'Local inference engines', @@ -1094,11 +1123,11 @@ const message = { recipeArguments: 'Launch arguments', recipeImportCommand: 'Import command', recipeImportPlaceholder: - 'Paste a pip/uv or Docker launch command here. 1Panel will automatically parse it and fill in the Recipe.', + 'Paste a pip/uv or docker launch command here. 1Panel will automatically parse it and fill in the form.', recipeVariablesNotSupported: 'Variable references are not supported in commands. Use explicit values; configure environment variables in the environment field.', recipeImportError: - 'Unable to convert. Include a Docker or vllm serve launch command with a model; paste pip/uv installation commands together with the launch command.', + 'No valid launch command detected. Paste a pip/uv or docker command that includes a model.', engineProvider: 'Engine / Provider', endpoint: 'Endpoint', cloudAccount: 'Cloud account', @@ -1109,7 +1138,8 @@ const message = { model: 'Models', localModel: 'Local Models', create_helper: 'Pull "{0}"', - ollama_doc: 'You can visit the Ollama official website to search and find more models.', + ollama_doc: + 'Find models at {link}. The model will be pulled automatically after adding it. Make sure Ollama is running and sufficient disk space is available.', container_conn_helper: 'Use this address for inter-container access or connection', from_remote: 'This model was not downloaded via 1Panel, no related pull logs.', no_logs: 'The pull logs for this model have been deleted and cannot be viewed.', @@ -1129,7 +1159,7 @@ const message = { 'Container address is for agent containers; 127.0.0.1, system IP, or custom address is for AI Gateway or external services.', containerAddress: 'Container address', customAddress: 'Custom address', - downloader: 'Downloads', + downloader: 'Model Downloads', modelDirectoryHelper: 'The model list defaults to the model directory configured in Model Preparation > Settings and shows models downloaded to that directory.', modelDirectoryPlaceholder: 'Search models or enter a full path', @@ -1140,8 +1170,7 @@ const message = { endpointLabel: '{0} endpoint', acceleratedEndpointLabel: '{0} acceleration endpoint', tokenLabel: '{0} Token', - hfEndpointHelper: - 'Configure an acceleration endpoint when HuggingFace access is unstable. Search, details, and downloads will use it.', + hfEndpointHelper: 'Optional mirror URL for HuggingFace model searches, details, and downloads.', sortDefault: 'Default sort', sortMostParameters: 'Most parameters', sortLeastParameters: 'Least parameters', @@ -5046,7 +5075,6 @@ const message = { customScriptHelper: 'Enter the complete startup command, for example: npm run start. For PM2 startup commands, please replace with pm2-runtime, otherwise it will fail to start.', portError: "Don't repeat the same port.", - systemRestartHelper: 'Status description: Interruption - status acquisition failed due to system restart', javaScriptHelper: 'Provide a full startup command. For example, "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'The directory must contain jar files, subdirectories are also acceptable', goHelper: 'Provide a full startup command. For example, "go run main.go" or "./main".', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index e458b3f49..33fab6884 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -1043,6 +1043,29 @@ const message = { validateImageAvailabilityHelper: 'Genera una imagen mínima antes de guardar y puede generar costes', }, model: { + searchTitle: 'Buscar y descargar modelos', + searchHelper: + 'Busca modelos en ModelScope o Hugging Face y luego despliégalos o crea una Recipe en Preparación de modelos.', + modelScopeSearchHelper: 'Acceso estable en China continental', + huggingFaceSearchHelper: 'Amplia colección de modelos', + searchPlaceholder: 'Introduce el nombre o ID del repositorio, p. ej. Qwen/Qwen3-8B', + popularSearches: 'Búsquedas populares', + searchSort: 'Ordenar por', + onlyTokenizer: 'Solo tokenizador', + downloadStatus: 'Estado de descarga', + downloaded: 'Descargado', + alreadyExists: 'Ya existe', + downloadCompleted: 'Descarga completada', + localFilesMissing: 'No se encontraron los archivos locales', + ollamaNameHelper: + 'Introduzca el nombre completo del modelo de la biblioteca de Ollama. Si no especifica una etiqueta, se usará latest.', + downloadHelper: 'Haga clic en «Buscar» para encontrar y descargar modelos de ModelScope y Hugging Face.', + serviceHelper: + 'Conecte servicios de modelos de nubes públicas, motores de inferencia locales y puertas de enlace de IA para que los utilicen los agentes integrados de 1Panel y agentes externos como WorkBuddy.', + gpuType: 'Tipo de GPU', + vllmVersion: 'Versión de vLLM', + vllmImage: 'Imagen de vLLM', + servicePort: 'Puerto del servicio', gpuAcceleration: 'Aceleración GPU', gpuMode: 'Selección de aceleradores', gpuAll: 'Todos los aceleradores', @@ -1074,7 +1097,13 @@ const message = { approxWeightSize: 'Aprox. {0} GB', services: 'Servicios de modelos', addInstance: 'Añadir instancia', - addService: 'Añadir servicio de modelo', + modelScopeEndpointHelper: 'Para buscar y descargar modelos de ModelScope. Usa la URL oficial por defecto.', + modelTokenHelper: 'Opcional. Use un token con permisos para acceder a modelos privados o restringidos.', + modelDirHelper: 'Directorio de descarga y listado de modelos locales.', + featuredModelsHelper: + 'Catálogo oficial de modelos destacados de 1Panel. Actualícelo manualmente o active la sincronización automática cada 24 horas. Solo se actualiza el catálogo, sin descargar modelos.', + addInstanceHelper: 'Cree una instancia de vLLM para servir los modelos descargados.', + addService: 'Añadir', onlineModel: 'Modelos en línea', instanceDeployment: 'Despliegue por instancia', engines: 'Motores de inferencia locales', @@ -1096,11 +1125,11 @@ const message = { recipeArguments: 'Argumentos de inicio', recipeImportCommand: 'Importar comando', recipeImportPlaceholder: - 'Pegue aquí un comando de inicio en formato pip/uv o Docker. 1Panel lo analizará y completará la Recipe automáticamente.', + 'Pegue aquí un comando de inicio en formato pip/uv o docker. 1Panel lo analizará y completará el formulario automáticamente.', recipeVariablesNotSupported: 'No se admiten referencias a variables en los comandos. Use valores concretos; configure las variables de entorno en su campo correspondiente.', recipeImportError: - 'No se puede convertir. Incluya un comando de inicio Docker o vllm serve con un modelo; pegue los comandos de instalación pip/uv junto con el comando de inicio.', + 'No se detectó un comando de inicio válido. Pegue un comando pip/uv o docker que incluya un modelo.', engineProvider: 'Motor / Proveedor', endpoint: 'Punto de conexión', cloudAccount: 'Cuenta en la nube', @@ -1111,7 +1140,8 @@ const message = { model: 'Modelo', localModel: 'Modelos locales', create_helper: 'Descargar "{0}"', - ollama_doc: 'Puede visitar el sitio oficial de Ollama para buscar y encontrar más modelos.', + ollama_doc: + 'Busque modelos en {link}. El modelo se descargará automáticamente al añadirlo. Asegúrese de que Ollama esté funcionando y de que haya suficiente espacio en disco.', container_conn_helper: 'Utilice esta dirección para el acceso o conexión entre contenedores', from_remote: 'Este modelo no fue descargado vía 1Panel, no hay registros de descarga relacionados.', no_logs: 'Los registros de descarga de este modelo han sido eliminados y no se pueden consultar.', @@ -1132,7 +1162,7 @@ const message = { 'La dirección del contenedor es para contenedores de agentes; 127.0.0.1, IP del sistema o dirección personalizada es para AI Gateway o servicios externos.', containerAddress: 'Dirección del contenedor', customAddress: 'Dirección personalizada', - downloader: 'Gestión de descargas', + downloader: 'Descarga de modelos', modelDirectoryHelper: 'La lista muestra de forma predeterminada los modelos descargados en el directorio configurado en Preparación de modelos > Configuración.', modelDirectoryPlaceholder: 'Buscar modelos o introducir una ruta completa', @@ -1143,8 +1173,7 @@ const message = { endpointLabel: 'Endpoint de {0}', acceleratedEndpointLabel: 'Endpoint de aceleración de {0}', tokenLabel: 'Token de {0}', - hfEndpointHelper: - 'Configure un endpoint de aceleración cuando el acceso a HuggingFace sea inestable. La búsqueda, los detalles y las descargas lo utilizarán.', + hfEndpointHelper: 'URL de espejo opcional para búsquedas, detalles y descargas de modelos de HuggingFace.', sortDefault: 'Orden predeterminado', sortMostParameters: 'Más parámetros', sortLeastParameters: 'Menos parámetros', @@ -5114,8 +5143,6 @@ const message = { customScriptHelper: 'Por favor, ingresa el comando de inicio completo, por ejemplo: npm run start. Para comandos de inicio de PM2, por favor reemplaza con pm2-runtime, de lo contrario fallará al iniciar.', portError: 'No repitas el mismo puerto.', - systemRestartHelper: - 'Descripción de estado: Interrupción - fallo al obtener estado debido a reinicio del sistema', javaScriptHelper: 'Proporciona un comando de inicio completo. Ejemplo: "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'El directorio debe contener archivos .jar, se permiten subdirectorios', diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts index d90271aa8..ecd853444 100644 --- a/frontend/src/lang/modules/fa.ts +++ b/frontend/src/lang/modules/fa.ts @@ -1025,6 +1025,29 @@ const message = { validateImageAvailabilityHelper: 'پیش از ذخیره یک تصویر حداقلی تولید می‌شود و ممکن است هزینه داشته باشد', }, model: { + searchTitle: 'جستجو و دانلود مدل‌ها', + searchHelper: + 'مدل‌ها را در ModelScope یا Hugging Face پیدا کنید، سپس در آماده‌سازی مدل آن‌ها را مستقر کنید یا یک Recipe بسازید.', + modelScopeSearchHelper: 'دسترسی پایدار در سرزمین اصلی چین', + huggingFaceSearchHelper: 'مجموعه گسترده مدل‌ها', + searchPlaceholder: 'نام مدل یا شناسه مخزن را وارد کنید، مانند Qwen/Qwen3-8B', + popularSearches: 'جستجوهای محبوب', + searchSort: 'مرتب‌سازی', + onlyTokenizer: 'فقط توکن‌ساز', + downloadStatus: 'وضعیت دانلود', + downloaded: 'دانلود شده', + alreadyExists: 'از قبل موجود', + downloadCompleted: 'دانلود تکمیل شد', + localFilesMissing: 'فایل‌های محلی یافت نشد', + ollamaNameHelper: + 'نام کامل مدل را از کتابخانه Ollama وارد کنید. اگر برچسب مشخص نشود، latest استفاده می‌شود.', + downloadHelper: 'برای یافتن و دانلود مدل‌ها از ModelScope و Hugging Face روی «جستجو» کلیک کنید.', + serviceHelper: + 'سرویس‌های مدل از ابرهای عمومی، موتورهای استنتاج محلی و درگاه‌های هوش مصنوعی را برای استفاده عامل‌های داخلی 1Panel و عامل‌های خارجی مانند WorkBuddy متصل کنید.', + gpuType: 'نوع GPU', + vllmVersion: 'نسخه vLLM', + vllmImage: 'ایمیج vLLM', + servicePort: 'پورت سرویس', gpuAcceleration: 'شتاب‌دهی GPU', gpuMode: 'انتخاب شتاب‌دهنده', gpuAll: 'همه شتاب‌دهنده‌ها', @@ -1055,7 +1078,13 @@ const message = { approxWeightSize: 'حدود {0} گیگابایت', services: 'سرویس‌های مدل', addInstance: 'افزودن نمونه', - addService: 'افزودن سرویس مدل', + modelScopeEndpointHelper: 'برای جستجو و دانلود مدل‌های ModelScope؛ پیش‌فرض، نشانی رسمی است.', + modelTokenHelper: 'اختیاری. برای مدل‌های خصوصی یا محدود از توکن دارای مجوز دسترسی استفاده کنید.', + modelDirHelper: 'پوشهٔ دانلود مدل‌ها و منبع فهرست مدل‌های محلی.', + featuredModelsHelper: + 'فهرست رسمی مدل‌های منتخب 1Panel. به‌صورت دستی به‌روز کنید یا همگام‌سازی خودکار هر ۲۴ ساعت را فعال کنید. فقط فهرست به‌روز می‌شود و فایل مدل‌ها دانلود نمی‌شود.', + addInstanceHelper: 'برای ارائهٔ مدل‌های دانلودشده، یک نمونهٔ vLLM ایجاد کنید.', + addService: 'افزودن', onlineModel: 'مدل‌های آنلاین', instanceDeployment: 'استقرار بر اساس نمونه', engines: 'موتورهای استنتاج محلی', @@ -1077,11 +1106,10 @@ const message = { recipeArguments: 'آرگومان‌های راه‌اندازی', recipeImportCommand: 'وارد کردن فرمان', recipeImportPlaceholder: - 'فرمان اجرا را با قالب pip/uv یا Docker اینجا جای‌گذاری کنید تا 1Panel آن را به‌طور خودکار تحلیل و Recipe را تکمیل کند.', + 'فرمان اجرا را با قالب pip/uv یا docker اینجا جای‌گذاری کنید تا 1Panel آن را به‌طور خودکار تحلیل و فرم را تکمیل کند.', recipeVariablesNotSupported: 'ارجاع به متغیرها در دستور پشتیبانی نمی‌شود. مقادیر مشخص وارد کنید؛ متغیرهای محیطی را در بخش مربوط به آن‌ها تنظیم کنید.', - recipeImportError: - 'تبدیل ممکن نیست. فرمان راه‌اندازی Docker یا vllm serve همراه با مدل را وارد کنید؛ فرمان‌های نصب pip/uv را همراه با فرمان راه‌اندازی جای‌گذاری کنید.', + recipeImportError: 'فرمان اجرای معتبری شناسایی نشد. یک فرمان pip/uv یا docker شامل مدل را جای‌گذاری کنید.', engineProvider: 'موتور / ارائه‌دهنده', endpoint: 'نقطه پایانی', cloudAccount: 'حساب ابری', @@ -1092,7 +1120,8 @@ const message = { model: 'مدل‌ها', localModel: 'مدل‌های محلی', create_helper: 'دریافت "{0}"', - ollama_doc: 'می‌توانید از وب‌سایت رسمی Ollama دیدن کنید و مدل‌های بیشتری را جستجو کنید.', + ollama_doc: + 'مدل‌ها را در {link} بیابید. مدل پس از افزودن به‌طور خودکار دانلود می‌شود. مطمئن شوید سرویس Ollama در حال اجرا است و فضای دیسک کافی وجود دارد.', container_conn_helper: 'از این آدرس برای دسترسی بین کانتینرها یا اتصال استفاده کنید', from_remote: 'این مدل از طریق 1Panel دانلود نشده است، لاگ مربوط به دریافت وجود ندارد.', no_logs: 'لاگ دریافت این مدل حذف شده است و قابل مشاهده نیست.', @@ -1112,7 +1141,7 @@ const message = { 'آدرس کانتینر برای کانتینرهای عامل است؛ 127.0.0.1، IP سیستم یا آدرس سفارشی برای دروازه AI یا خدمات خارجی است.', containerAddress: 'آدرس کانتینر', customAddress: 'آدرس سفارشی', - downloader: 'مدیریت دانلودها', + downloader: 'دانلود مدل', modelDirectoryHelper: 'فهرست مدل‌ها به‌طور پیش‌فرض مدل‌های دانلودشده در پوشه تنظیم‌شده در «آماده‌سازی مدل > تنظیمات» را نمایش می‌دهد.', modelDirectoryPlaceholder: 'جستجوی مدل یا وارد کردن مسیر کامل', @@ -1123,8 +1152,7 @@ const message = { endpointLabel: 'نقطه پایانی {0}', acceleratedEndpointLabel: 'نقطه پایانی شتاب‌دهنده {0}', tokenLabel: 'توکن {0}', - hfEndpointHelper: - 'هنگامی که دسترسی به HuggingFace ناپایدار است، یک نقطه پایانی شتاب‌دهنده پیکربندی کنید. جستجو، جزئیات و دانلود از آن استفاده خواهند کرد.', + hfEndpointHelper: 'نشانی آینهٔ اختیاری برای جستجو، دریافت جزئیات و دانلود مدل‌های HuggingFace.', sortDefault: 'مرتب‌سازی پیش‌فرض', sortMostParameters: 'بیشترین پارامتر', sortLeastParameters: 'کمترین پارامتر', @@ -5007,7 +5035,6 @@ const message = { customScriptHelper: 'دستور راه‌اندازی کامل را وارد کنید، مثلاً: npm run start. برای دستورات راه‌اندازی PM2، لطفاً با pm2-runtime جایگزین کنید، در غیر این صورت راه‌اندازی ناموفق خواهد بود.', portError: 'پورت تکراری نباشد.', - systemRestartHelper: 'توضیح وضعیت: وقفه - به دلیل راه‌اندازی مجدد سیستم، وضعیت قابل دریافت نیست', javaScriptHelper: 'یک دستور راه‌اندازی کامل ارائه دهید. مثلاً "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'دایرکتوری باید شامل فایل‌های jar باشد، زیردایرکتوری‌ها نیز مجاز هستند', goHelper: 'یک دستور راه‌اندازی کامل ارائه دهید. مثلاً "go run main.go" یا "./main".', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 9ffa3b0ad..5040a9f65 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -1029,6 +1029,30 @@ const message = { validateImageAvailabilityHelper: '保存前に最小画像を1枚生成するため、料金が発生する場合があります', }, model: { + searchTitle: 'モデルを検索してダウンロード', + searchHelper: + 'ModelScope または Hugging Face でモデルを検索し、ダウンロード後にモデル準備でデプロイまたは Recipe を作成できます。', + modelScopeSearchHelper: '中国本土から安定したアクセス', + huggingFaceSearchHelper: '豊富なモデル', + searchPlaceholder: 'モデル名またはリポジトリ ID を入力(例:Qwen/Qwen3-8B)', + popularSearches: '人気の検索', + searchSort: '並び順', + onlyTokenizer: 'トークナイザーのみ', + downloadStatus: 'ダウンロード状態', + downloaded: 'ダウンロード済み', + alreadyExists: '既存', + downloadCompleted: 'ダウンロード完了', + localFilesMissing: 'ローカルファイルが見つかりません', + ollamaNameHelper: + 'Ollama ライブラリの完全なモデル名を入力してください。タグを省略すると latest が使用されます。', + downloadHelper: + '「検索」をクリックすると、ModelScope や Hugging Face のモデルを検索してダウンロードできます。', + serviceHelper: + 'パブリッククラウド、ローカル推論エンジン、AI ゲートウェイなどのモデルサービスを統合し、1Panel 内蔵エージェントや WorkBuddy などの外部エージェントから利用できます。', + gpuType: 'GPU タイプ', + vllmVersion: 'vLLM バージョン', + vllmImage: 'vLLM イメージ', + servicePort: 'サービスポート', gpuAcceleration: 'GPU アクセラレーション', gpuMode: 'アクセラレーターの選択', gpuAll: 'すべてのアクセラレーター', @@ -1059,7 +1083,13 @@ const message = { approxWeightSize: '約 {0} GB', services: 'モデルサービス', addInstance: 'インスタンスを追加', - addService: 'モデルサービスを追加', + modelScopeEndpointHelper: 'ModelScope モデルの検索とダウンロードに使用します。既定は公式 URL です。', + modelTokenHelper: '任意。非公開・制限付きモデルにはアクセス権のあるトークンが必要です。', + modelDirHelper: 'モデルの保存先とローカルモデル一覧の読み込み先です。', + featuredModelsHelper: + '1Panel 公式のおすすめモデル一覧です。手動更新または 24 時間ごとの自動同期が可能です。同期は一覧のみを更新し、モデルファイルはダウンロードしません。', + addInstanceHelper: 'vLLM インスタンスを作成し、ダウンロード済みモデルをモデルサービスとして公開します。', + addService: '追加', onlineModel: 'オンラインモデル', instanceDeployment: 'インスタンス単位でデプロイ', engines: 'ローカル推論エンジン', @@ -1081,11 +1111,11 @@ const message = { recipeArguments: '起動引数', recipeImportCommand: 'コマンドをインポート', recipeImportPlaceholder: - 'ここに pip/uv または Docker 形式の起動コマンドを貼り付けると、1Panel が自動的に解析し、Recipe に入力します。', + 'ここに pip/uv または docker 形式の起動コマンドを貼り付けると、1Panel が自動的に解析し、フォームに入力します。', recipeVariablesNotSupported: 'コマンド内の変数参照はサポートされていません。具体的な値を入力し、環境変数は環境変数欄で設定してください。', recipeImportError: - '変換できません。モデルを含む Docker または vllm serve の起動コマンドを入力してください。pip/uv のインストールコマンドは起動コマンドと一緒に貼り付けてください。', + '有効な起動コマンドが見つかりません。モデルを含む pip/uv または docker コマンドを貼り付けてください。', engineProvider: 'エンジン / プロバイダー', endpoint: 'エンドポイント', cloudAccount: 'クラウドアカウント', @@ -1096,7 +1126,8 @@ const message = { model: 'モデル', localModel: 'ローカルモデル', create_helper: 'を取得 "{0}"', - ollama_doc: 'Ollama の公式ウェブサイトを訪れて、さらに多くのモデルを検索して見つけることができます。', + ollama_doc: + '{link} でモデルを検索できます。追加後、モデルは自動的に取得されます。Ollama が正常に動作し、十分なディスク容量があることを確認してください。', container_conn_helper: 'コンテナ間のアクセスまたは接続にこのアドレスを使用', from_remote: 'このモデルは1Panelを介してダウンロードされておらず、関連するプルログはありません。', no_logs: 'このモデルのプルログは削除されており、関連するログを表示できません。', @@ -1117,7 +1148,7 @@ const message = { 'コンテナアドレスはエージェントコンテナ向けです。127.0.0.1、システム IP、カスタムアドレスは AI Gateway または外部サービス向けです。', containerAddress: 'コンテナアドレス', customAddress: 'カスタムアドレス', - downloader: 'ダウンロード管理', + downloader: 'モデルのダウンロード', modelDirectoryHelper: 'モデル一覧には、デフォルトで「モデル準備 > 設定」で指定したモデルディレクトリにダウンロード済みのモデルが表示されます。', modelDirectoryPlaceholder: 'モデルを検索するかフルパスを入力', @@ -1128,8 +1159,7 @@ const message = { endpointLabel: '{0} エンドポイント', acceleratedEndpointLabel: '{0} アクセラレーションエンドポイント', tokenLabel: '{0} Token', - hfEndpointHelper: - 'HuggingFace へのアクセスが不安定な場合はアクセラレーションエンドポイントを設定してください。検索、詳細、ダウンロードで使用されます。', + hfEndpointHelper: '任意。HuggingFace モデルの検索・詳細取得・ダウンロード用のミラー URL です。', sortDefault: '標準の並び順', sortMostParameters: 'パラメータ数が多い順', sortLeastParameters: 'パラメータ数が少ない順', @@ -5027,7 +5057,6 @@ const message = { customScriptHelper: '完全な起動コマンドを入力してください。例:npm run start。PM2の起動コマンドはpm2-runtimeに置き換えてください。そうしないと起動に失敗します。', portError: '同じポートを繰り返さないでください。', - systemRestartHelper: 'ステータスの説明:中断 - システムの再起動によりステータスの取得が失敗しました', javaScriptHelper: '完全な起動コマンドを提供します。たとえば、「Java -Jar Halo.Jar -XMX1024M -XMS256M」。', javaDirHelper: 'ディレクトリにはjarファイルが含まれている必要があり、サブディレクトリも受け入れられます', goHelper: '完全な起動コマンドを提供します。たとえば、「Go Run Main.go」または「./Main」。', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index fabef61fe..fe33d8600 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -1019,6 +1019,29 @@ const message = { validateImageAvailabilityHelper: '저장 전에 최소 이미지 한 장을 생성하며 비용이 발생할 수 있습니다', }, model: { + searchTitle: '모델 검색 및 다운로드', + searchHelper: + 'ModelScope 또는 Hugging Face에서 모델을 찾아 다운로드한 후 모델 준비에서 배포하거나 Recipe를 만들 수 있습니다.', + modelScopeSearchHelper: '중국 본토에서 안정적인 접속', + huggingFaceSearchHelper: '풍부한 모델 컬렉션', + searchPlaceholder: '모델 이름 또는 저장소 ID 입력, 예: Qwen/Qwen3-8B', + popularSearches: '인기 검색어', + searchSort: '정렬', + onlyTokenizer: '토크나이저만 다운로드', + downloadStatus: '다운로드 상태', + downloaded: '다운로드됨', + alreadyExists: '이미 존재함', + downloadCompleted: '다운로드 완료', + localFilesMissing: '로컬 파일을 찾을 수 없습니다', + ollamaNameHelper: 'Ollama 라이브러리의 전체 모델 이름을 입력하세요. 태그를 생략하면 latest가 사용됩니다.', + downloadHelper: + '“검색” 버튼을 클릭하여 ModelScope 및 Hugging Face의 모델을 검색하고 다운로드할 수 있습니다.', + serviceHelper: + '퍼블릭 클라우드, 로컬 추론 엔진, AI 게이트웨이 등의 모델 서비스를 통합하여 1Panel 내장 에이전트와 WorkBuddy 같은 외부 에이전트에서 사용할 수 있습니다.', + gpuType: 'GPU 유형', + vllmVersion: 'vLLM 버전', + vllmImage: 'vLLM 이미지', + servicePort: '서비스 포트', gpuAcceleration: 'GPU 가속', gpuMode: '가속기 선택', gpuAll: '모든 가속기', @@ -1049,7 +1072,13 @@ const message = { approxWeightSize: '약 {0} GB', services: '모델 서비스', addInstance: '인스턴스 추가', - addService: '모델 서비스 추가', + modelScopeEndpointHelper: 'ModelScope 모델 검색 및 다운로드에 사용하며, 기본값은 공식 URL입니다.', + modelTokenHelper: '선택 사항. 비공개 또는 제한된 모델에는 접근 권한이 있는 토큰이 필요합니다.', + modelDirHelper: '모델 다운로드 저장 경로이자 로컬 모델 목록을 읽는 경로입니다.', + featuredModelsHelper: + '1Panel 공식 추천 모델 목록입니다. 수동으로 새로 고치거나 24시간마다 자동 동기화를 설정할 수 있습니다. 목록만 갱신하며 모델 파일은 다운로드하지 않습니다.', + addInstanceHelper: 'vLLM 인스턴스를 생성하여 다운로드한 모델을 모델 서비스로 배포합니다.', + addService: '추가', onlineModel: '온라인 모델', instanceDeployment: '인스턴스별 배포', engines: '로컬 추론 엔진', @@ -1071,11 +1100,11 @@ const message = { recipeArguments: '시작 인수', recipeImportCommand: '명령 가져오기', recipeImportPlaceholder: - '여기에 pip/uv 또는 Docker 형식의 실행 명령을 붙여넣으면 1Panel이 자동으로 분석하여 Recipe를 채웁니다.', + '여기에 pip/uv 또는 docker 형식의 실행 명령을 붙여넣으면 1Panel이 자동으로 분석하여 양식을 채웁니다.', recipeVariablesNotSupported: '명령에서 변수 참조는 지원되지 않습니다. 구체적인 값을 입력하고 환경 변수는 환경 변수 필드에서 설정하세요.', recipeImportError: - '변환할 수 없습니다. 모델이 포함된 Docker 또는 vllm serve 시작 명령을 입력하세요. pip/uv 설치 명령은 시작 명령과 함께 붙여넣으세요.', + '유효한 실행 명령을 찾지 못했습니다. 모델이 포함된 pip/uv 또는 docker 명령을 붙여넣으세요.', engineProvider: '엔진 / 공급자', endpoint: '엔드포인트', cloudAccount: '클라우드 계정', @@ -1086,7 +1115,8 @@ const message = { model: '모델', localModel: '로컬 모델', create_helper: '가져오기 "{0}"', - ollama_doc: 'Ollama 공식 웹사이트를 방문하여 더 많은 모델을 검색하고 찾을 수 있습니다.', + ollama_doc: + '{link}에서 모델을 검색하세요. 추가 후 모델을 자동으로 가져옵니다. Ollama 서비스가 정상적으로 실행 중이고 디스크 공간이 충분한지 확인하세요.', container_conn_helper: '컨테이너 간 접근 또는 연결에 이 주소를 사용', from_remote: '이 모델은 1Panel을 통해 다운로드되지 않았으며 관련 풀 로그가 없습니다.', no_logs: '이 모델의 풀 로그가 삭제되어 관련 로그를 볼 수 없습니다.', @@ -1106,7 +1136,7 @@ const message = { '컨테이너 주소는 에이전트 컨테이너 호출에 적합합니다. 127.0.0.1, 시스템 IP 또는 사용자 지정 주소는 AI Gateway 또는 외부 서비스 호출에 적합합니다.', containerAddress: '컨테이너 주소', customAddress: '사용자 지정 주소', - downloader: '다운로드 관리', + downloader: '모델 다운로드', modelDirectoryHelper: '모델 목록은 기본적으로 “모델 준비 > 설정”에서 구성한 모델 디렉터리에 다운로드된 모델을 표시합니다.', modelDirectoryPlaceholder: '모델 검색 또는 전체 경로 입력', @@ -1117,8 +1147,7 @@ const message = { endpointLabel: '{0} 엔드포인트', acceleratedEndpointLabel: '{0} 가속 엔드포인트', tokenLabel: '{0} Token', - hfEndpointHelper: - 'HuggingFace 접속이 불안정할 때 가속 엔드포인트를 설정하세요. 검색, 상세 정보, 다운로드에 사용됩니다.', + hfEndpointHelper: '선택 사항. HuggingFace 모델 검색, 상세 정보 조회 및 다운로드용 미러 URL입니다.', sortDefault: '기본 정렬', sortMostParameters: '매개변수 많은 순', sortLeastParameters: '매개변수 적은 순', @@ -4937,7 +4966,6 @@ const message = { customScriptHelper: '전체 시작 명령어를 입력해 주세요. 예: npm run start. PM2 시작 명령어는 pm2-runtime로 변경해 주세요. 그렇지 않으면 시작에 실패합니다.', portError: '포트를 중복 사용하지 마세요.', - systemRestartHelper: '상태 설명: 중단 - 시스템 재시작으로 인해 상태 가져오기가 실패했습니다.', javaScriptHelper: '전체 시작 명령을 제공하세요. 예: "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: '디렉터리는 jar 파일을 포함해야 하며, 하위 디렉터리도 허용됩니다.', goHelper: '전체 시작 명령을 제공하세요. 예: "go run main.go" 또는 "./main".', diff --git a/frontend/src/lang/modules/lo.ts b/frontend/src/lang/modules/lo.ts index ac6ea67f4..386d0452a 100644 --- a/frontend/src/lang/modules/lo.ts +++ b/frontend/src/lang/modules/lo.ts @@ -1016,6 +1016,27 @@ const message = { validateImageAvailabilityHelper: 'ສ້າງຮູບຂະໜາດນ້ອຍໜຶ່ງຮູບກ່ອນບັນທຶກ ແລະ ອາດມີຄ່າໃຊ້ຈ່າຍ', }, model: { + searchTitle: 'ຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວ', + searchHelper: 'ຄົ້ນຫາໂມເດວໃນ ModelScope ຫຼື Hugging Face ແລ້ວນຳໃຊ້ ຫຼື ສ້າງ Recipe ໃນການກະກຽມໂມເດວ.', + modelScopeSearchHelper: 'ເຂົ້າເຖິງໄດ້ສະຖຽນໃນຈີນແຜ່ນດິນໃຫຍ່', + huggingFaceSearchHelper: 'ມີໂມເດວໃຫ້ເລືອກຫຼາກຫຼາຍ', + searchPlaceholder: 'ປ້ອນຊື່ໂມເດວ ຫຼື ID ຄັງ, ເຊັ່ນ Qwen/Qwen3-8B', + popularSearches: 'ການຄົ້ນຫາຍອດນິຍົມ', + searchSort: 'ຈັດລຽງ', + onlyTokenizer: 'ດາວໂຫຼດສະເພາະຕົວແບ່ງໂທເຄັນ', + downloadStatus: 'ສະຖານະດາວໂຫຼດ', + downloaded: 'ດາວໂຫຼດແລ້ວ', + alreadyExists: 'ມີຢູ່ແລ້ວ', + downloadCompleted: 'ດາວໂຫຼດສຳເລັດ', + localFilesMissing: 'ບໍ່ພົບໄຟລ໌ພາຍໃນ', + ollamaNameHelper: 'ກະລຸນາໃສ່ຊື່ໂມເດວເຕັມຈາກຄັງ Ollama. ຖ້າບໍ່ລະບຸແທັກ ຈະໃຊ້ latest.', + downloadHelper: 'ຄລິກ “ຄົ້ນຫາ” ເພື່ອຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວຈາກ ModelScope ແລະ Hugging Face.', + serviceHelper: + 'ເຊື່ອມຕໍ່ບໍລິການໂມເດວຈາກຄລາວສາທາລະນະ, ເຄື່ອງຈັກອະນຸມານພາຍໃນ ແລະ ເກດເວ AI ເພື່ອໃຫ້ຕົວແທນໃນ 1Panel ແລະ ຕົວແທນພາຍນອກເຊັ່ນ WorkBuddy ໃຊ້ງານ.', + gpuType: 'ປະເພດ GPU', + vllmVersion: 'ເວີຊັນ vLLM', + vllmImage: 'ອິມເມຈ vLLM', + servicePort: 'ພອດບໍລິການ', gpuAcceleration: 'ການເລັ່ງ GPU', gpuMode: 'ເລືອກຕົວເລັ່ງ', gpuAll: 'ຕົວເລັ່ງທັງໝົດ', @@ -1046,7 +1067,13 @@ const message = { approxWeightSize: 'ປະມານ {0} GB', services: 'ບໍລິການໂມເດວ', addInstance: 'ເພີ່ມອິນສະແຕນ', - addService: 'ເພີ່ມບໍລິການໂມເດວ', + modelScopeEndpointHelper: 'ໃຊ້ຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວ ModelScope. ຄ່າເລີ່ມຕົ້ນແມ່ນ URL ທາງການ.', + modelTokenHelper: 'ບໍ່ບັງຄັບ. ໂມເດວສ່ວນຕົວ ຫຼື ທີ່ຈຳກັດຕ້ອງໃຊ້ Token ທີ່ມີສິດເຂົ້າເຖິງ.', + modelDirHelper: 'ໂຟນເດີດາວໂຫຼດໂມເດວ ແລະ ແຫຼ່ງລາຍການໂມເດວພາຍໃນເຄື່ອງ.', + featuredModelsHelper: + 'ລາຍການໂມເດວແນະນຳທາງການຂອງ 1Panel. ສາມາດໂຫຼດຄືນດ້ວຍຕົນເອງ ຫຼື ເປີດການຊິງຄ໌ອັດຕະໂນມັດທຸກ 24 ຊົ່ວໂມງ. ອັບເດດສະເພາະລາຍການ ໂດຍບໍ່ດາວໂຫຼດໄຟລ໌ໂມເດວ.', + addInstanceHelper: 'ສ້າງອິນສະແຕນ vLLM ເພື່ອໃຫ້ບໍລິການໂມເດວທີ່ດາວໂຫຼດແລ້ວ.', + addService: 'ເພີ່ມ', onlineModel: 'ໂມເດວອອນລາຍ', instanceDeployment: 'ນຳໃຊ້ຕາມອິນສະແຕນ', engines: 'ເຄື່ອງຈັກອະນຸມານພາຍໃນ', @@ -1068,11 +1095,10 @@ const message = { recipeArguments: 'ພາລາມິເຕີເລີ່ມຕົ້ນ', recipeImportCommand: 'ນຳເຂົ້າຄຳສັ່ງ', recipeImportPlaceholder: - 'ວາງຄຳສັ່ງເລີ່ມຕົ້ນໃນຮູບແບບ pip/uv ຫຼື Docker ທີ່ນີ້. 1Panel ຈະວິເຄາະແລະຕື່ມ Recipe ອັດຕະໂນມັດ.', + 'ວາງຄຳສັ່ງເລີ່ມຕົ້ນໃນຮູບແບບ pip/uv ຫຼື docker ທີ່ນີ້. 1Panel ຈະວິເຄາະ ແລະ ຕື່ມແບບຟອມອັດຕະໂນມັດ.', recipeVariablesNotSupported: 'ຄຳສັ່ງບໍ່ຮອງຮັບການອ້າງອີງຕົວແປ. ກະລຸນາປ້ອນຄ່າໂດຍກົງ ແລະຕັ້ງຄ່າຕົວແປສະພາບແວດລ້ອມໃນຊ່ອງທີ່ກ່ຽວຂ້ອງ.', - recipeImportError: - 'ບໍ່ສາມາດແປງໄດ້. ກະລຸນາໃສ່ຄຳສັ່ງເລີ່ມຕົ້ນ Docker ຫຼື vllm serve ທີ່ມີໂມເດວ; ວາງຄຳສັ່ງຕິດຕັ້ງ pip/uv ພ້ອມກັບຄຳສັ່ງເລີ່ມຕົ້ນ.', + recipeImportError: 'ບໍ່ພົບຄຳສັ່ງເລີ່ມຕົ້ນທີ່ຖືກຕ້ອງ. ກະລຸນາວາງຄຳສັ່ງ pip/uv ຫຼື docker ທີ່ມີໂມເດວ.', engineProvider: 'ເຄື່ອງຈັກ / ຜູ້ໃຫ້ບໍລິການ', endpoint: 'ຈຸດເຊື່ອມຕໍ່', cloudAccount: 'ບັນຊີຄລາວ', @@ -1083,7 +1109,8 @@ const message = { model: 'ໂມເດວ', localModel: 'ໂມເດວໃນເຄື່ອງ', create_helper: 'ດຶງ (Pull) "{0}"', - ollama_doc: 'ທ່ານສາມາດຢ້ຽມຊົມເວັບໄຊທ໌ທາງການຂອງ Ollama ເພື່ອຄົ້ນຫາໂມເດວເພີ່ມເຕີມ.', + ollama_doc: + 'ຄົ້ນຫາໂມເດວທີ່ {link}. ລະບົບຈະດາວໂຫຼດໂມເດວອັດຕະໂນມັດຫຼັງຈາກເພີ່ມ. ກະລຸນາກວດສອບວ່າ Ollama ເຮັດວຽກປົກກະຕິ ແລະ ມີພື້ນທີ່ດິສກ໌ພຽງພໍ.', container_conn_helper: 'ໃຊ້ທີ່ຢູ່ນີ້ສຳລັບການເຂົ້າເຖິງ ຫຼື ເຊື່ອມຕໍ່ລະຫວ່າງຄອນເທນເນີ', from_remote: 'ໂມເດວນີ້ບໍ່ໄດ້ດາວໂຫຼດຜ່ານ 1Panel, ບໍ່ມີລັອກການດຶງຂໍ້ມູນທີ່ກ່ຽວຂ້ອງ.', no_logs: 'ລັອກການດຶງຂໍ້ມູນຂອງໂມເດວນີ້ຖືກລຶບແລ້ວ ແລະ ບໍ່ສາມາດເບິ່ງໄດ້.', @@ -1103,7 +1130,7 @@ const message = { 'ທີ່ຢູ່ຄອນເທນເນີແມ່ນສຳລັບຄອນເທນເນີຕົວແທນ; 127.0.0.1, IP ລະບົບ, ຫຼື ທີ່ຢູ່ກຳນົດເອງແມ່ນສຳລັບ AI Gateway ຫຼື ບໍລິການພາຍນອກ.', containerAddress: 'ທີ່ຢູ່ຄອນເທນເນີ', customAddress: 'ທີ່ຢູ່ກຳນົດເອງ', - downloader: 'ຈັດການການດາວໂຫຼດ', + downloader: 'ດາວໂຫຼດໂມເດວ', modelDirectoryHelper: 'ໂດຍຄ່າເລີ່ມຕົ້ນ ລາຍຊື່ໂມເດວຈະສະແດງໂມເດວທີ່ດາວໂຫຼດໄວ້ໃນໄດເຣັກທໍຣີທີ່ກຳນົດໃນ “ການກະກຽມໂມເດວ > ການຕັ້ງຄ່າ”.', modelDirectoryPlaceholder: 'ຄົ້ນຫາໂມເດວ ຫຼື ປ້ອນເສັ້ນທາງເຕັມ', @@ -1114,8 +1141,7 @@ const message = { endpointLabel: 'ຈຸດເຊື່ອມຕໍ່ (Endpoint) {0}', acceleratedEndpointLabel: 'ຈຸດເຊື່ອມຕໍ່ເລັ່ງຄວາມໄວ {0}', tokenLabel: '{0} Token', - hfEndpointHelper: - 'ຕັ້ງຄ່າຈຸດເຊື່ອມຕໍ່ເລັ່ງຄວາມໄວເມື່ອການເຂົ້າເຖິງ HuggingFace ບໍ່ຄົງທີ່. ການຄົ້ນຫາ, ລາຍລະອຽດ ແລະ ການດາວໂຫຼດຈະໃຊ້ທີ່ຢູ່ນີ້.', + hfEndpointHelper: 'URL ມິເຣີທາງເລືອກສຳລັບຄົ້ນຫາ, ເບິ່ງລາຍລະອຽດ ແລະ ດາວໂຫຼດໂມເດວ HuggingFace.', sortDefault: 'ການຈັດລຽງເລີ່ມຕົ້ນ', sortMostParameters: 'ພາລາມິເຕີຫຼາຍທີ່ສຸດ', sortLeastParameters: 'ພາລາມິເຕີໜ້ອຍທີ່ສຸດ', @@ -4895,7 +4921,6 @@ const message = { customScriptHelper: 'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: npm run start. ສຳລັບຄຳສັ່ງ PM2, ໃຫ້ປ່ຽນເປັນ pm2-runtime.', portError: 'ຫ້າມໃຊ້ພອດຊ້ຳກັນ.', - systemRestartHelper: 'ລາຍລະອຽດ: ຖືກຂັດຈັງຫວະ - ບໍ່ສາມາດດຶງສະຖານະໄດ້ເນື່ອງຈາກລະບົບເລີ່ມຕົ້ນໃໝ່', javaScriptHelper: 'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'ໂຟນເດີຕ້ອງມີໄຟລ໌ jar, ໂຟນເດີ່ຍ່ອຍກໍສາມາດໃຊ້ໄດ້', goHelper: 'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: "go run main.go" ຫຼື "./main".', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index 50479cc4e..ce56ad66a 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -1052,6 +1052,29 @@ const message = { validateImageAvailabilityHelper: 'Menjana satu imej minimum sebelum menyimpan dan mungkin dikenakan caj', }, model: { + searchTitle: 'Cari dan muat turun model', + searchHelper: + 'Cari model di ModelScope atau Hugging Face, kemudian gunakan model atau cipta Recipe dalam Persediaan Model.', + modelScopeSearchHelper: 'Akses stabil di tanah besar China', + huggingFaceSearchHelper: 'Koleksi model yang luas', + searchPlaceholder: 'Masukkan nama model atau ID repositori, cth. Qwen/Qwen3-8B', + popularSearches: 'Carian popular', + searchSort: 'Susun mengikut', + onlyTokenizer: 'Pentoken sahaja', + downloadStatus: 'Status muat turun', + downloaded: 'Telah dimuat turun', + alreadyExists: 'Sudah wujud', + downloadCompleted: 'Muat turun selesai', + localFilesMissing: 'Fail setempat tidak ditemui', + ollamaNameHelper: + 'Masukkan nama model penuh daripada pustaka Ollama. Jika tag tidak dinyatakan, latest akan digunakan.', + downloadHelper: 'Klik “Cari” untuk mencari dan memuat turun model daripada ModelScope dan Hugging Face.', + serviceHelper: + 'Sambungkan perkhidmatan model daripada awan awam, enjin inferens setempat dan gerbang AI untuk digunakan oleh ejen terbina dalam 1Panel serta ejen luaran seperti WorkBuddy.', + gpuType: 'Jenis GPU', + vllmVersion: 'Versi vLLM', + vllmImage: 'Imej vLLM', + servicePort: 'Port perkhidmatan', gpuAcceleration: 'Pecutan GPU', gpuMode: 'Pemilihan pemecut', gpuAll: 'Semua pemecut', @@ -1082,7 +1105,15 @@ const message = { approxWeightSize: 'Kira-kira {0} GB', services: 'Perkhidmatan model', addInstance: 'Tambah instans', - addService: 'Tambah perkhidmatan model', + modelScopeEndpointHelper: + 'Untuk mencari dan memuat turun model ModelScope. Menggunakan URL rasmi secara lalai.', + modelTokenHelper: 'Pilihan. Gunakan token dengan kebenaran akses untuk model peribadi atau terhad.', + modelDirHelper: 'Direktori muat turun model dan sumber senarai model setempat.', + featuredModelsHelper: + 'Katalog model pilihan rasmi 1Panel. Muat semula secara manual atau aktifkan penyegerakan automatik setiap 24 jam. Hanya katalog dikemas kini, tanpa memuat turun fail model.', + addInstanceHelper: + 'Cipta instans vLLM untuk menyediakan model yang dimuat turun sebagai perkhidmatan model.', + addService: 'Tambah', onlineModel: 'Model dalam talian', instanceDeployment: 'Pengerahan mengikut instans', engines: 'Enjin inferens setempat', @@ -1104,11 +1135,11 @@ const message = { recipeArguments: 'Argumen pelancaran', recipeImportCommand: 'Import arahan', recipeImportPlaceholder: - 'Tampal arahan pelancaran dalam format pip/uv atau Docker di sini. 1Panel akan menghuraikan dan mengisi Recipe secara automatik.', + 'Tampal arahan pelancaran dalam format pip/uv atau docker di sini. 1Panel akan menghuraikan dan mengisi borang secara automatik.', recipeVariablesNotSupported: 'Rujukan pemboleh ubah tidak disokong dalam arahan. Masukkan nilai khusus; tetapkan pemboleh ubah persekitaran dalam medan yang berkenaan.', recipeImportError: - 'Tidak dapat menukar. Sertakan arahan pelancaran Docker atau vllm serve dengan model; tampal arahan pemasangan pip/uv bersama arahan pelancaran.', + 'Tiada arahan pelancaran yang sah dikesan. Tampal arahan pip/uv atau docker yang mengandungi model.', engineProvider: 'Enjin / Pembekal', endpoint: 'Titik akhir', cloudAccount: 'Akaun awan', @@ -1119,7 +1150,8 @@ const message = { model: 'Model', localModel: 'Model Tempatan', create_helper: 'Tarik "{0}"', - ollama_doc: 'Anda boleh melawat laman web rasmi Ollama untuk mencari dan menemui lebih banyak model.', + ollama_doc: + 'Cari model di {link}. Model akan dimuat turun secara automatik selepas ditambah. Pastikan perkhidmatan Ollama berjalan dan ruang cakera mencukupi.', container_conn_helper: 'Gunakan alamat ini untuk akses atau sambungan antara kontena', from_remote: 'Model ini tidak dimuat turun melalui 1Panel; tiada log muat turun berkaitan.', no_logs: 'Log muat turun model ini telah dipadam dan tidak boleh dilihat.', @@ -1139,7 +1171,7 @@ const message = { 'Alamat kontena sesuai untuk kontena agen; 127.0.0.1, IP sistem, atau alamat tersuai sesuai untuk AI Gateway atau perkhidmatan luaran.', containerAddress: 'Alamat kontena', customAddress: 'Alamat tersuai', - downloader: 'Pengurusan muat turun', + downloader: 'Muat turun model', modelDirectoryHelper: 'Secara lalai, senarai model memaparkan model yang dimuat turun dalam direktori yang dikonfigurasi di Persediaan Model > Tetapan.', modelDirectoryPlaceholder: 'Cari model atau masukkan laluan penuh', @@ -1150,8 +1182,7 @@ const message = { endpointLabel: 'Endpoint {0}', acceleratedEndpointLabel: 'Titik akhir pecutan {0}', tokenLabel: 'Token {0}', - hfEndpointHelper: - 'Konfigurasikan titik akhir pecutan apabila akses HuggingFace tidak stabil. Carian, butiran dan muat turun akan menggunakannya.', + hfEndpointHelper: 'URL cermin pilihan untuk carian, butiran dan muat turun model HuggingFace.', sortDefault: 'Isihan lalai', sortMostParameters: 'Parameter terbanyak', sortLeastParameters: 'Parameter paling sedikit', @@ -5120,7 +5151,6 @@ const message = { customScriptHelper: 'Sila masukkan arahan permulaan penuh, contoh: npm run start. Untuk arahan permulaan PM2, sila gantikan dengan pm2-runtime, jika tidak ia akan gagal bermula.', portError: 'Jangan ulangi port yang sama.', - systemRestartHelper: 'Huraian status: Gangguan - status gagal diperoleh kerana sistem dimulakan semula', javaScriptHelper: 'Sediakan arahan permulaan penuh. Contohnya, "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'Direktori mesti mengandungi fail jar, subdirektori juga diterima', goHelper: 'Sediakan arahan permulaan penuh. Contohnya, "go run main.go" atau "./main".', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 706d43d92..3e8fe25f9 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -1047,6 +1047,29 @@ const message = { validateImageAvailabilityHelper: 'Gera uma imagem mínima antes de salvar e pode gerar custos', }, model: { + searchTitle: 'Pesquisar e baixar modelos', + searchHelper: + 'Encontre modelos no ModelScope ou Hugging Face e depois implante-os ou crie uma Recipe em Preparação de modelos.', + modelScopeSearchHelper: 'Acesso estável na China continental', + huggingFaceSearchHelper: 'Ampla coleção de modelos', + searchPlaceholder: 'Digite o nome ou ID do repositório, ex.: Qwen/Qwen3-8B', + popularSearches: 'Buscas populares', + searchSort: 'Ordenar por', + onlyTokenizer: 'Somente tokenizador', + downloadStatus: 'Status do download', + downloaded: 'Baixado', + alreadyExists: 'Já existe', + downloadCompleted: 'Download concluído', + localFilesMissing: 'Arquivos locais não encontrados', + ollamaNameHelper: + 'Insira o nome completo do modelo da biblioteca do Ollama. Se nenhuma tag for especificada, será usada latest.', + downloadHelper: 'Clique em “Pesquisar” para encontrar e baixar modelos do ModelScope e do Hugging Face.', + serviceHelper: + 'Conecte serviços de modelos de nuvens públicas, mecanismos de inferência locais e gateways de IA para uso pelos agentes integrados do 1Panel e agentes externos, como o WorkBuddy.', + gpuType: 'Tipo de GPU', + vllmVersion: 'Versão do vLLM', + vllmImage: 'Imagem do vLLM', + servicePort: 'Porta do serviço', gpuAcceleration: 'Aceleração de GPU', gpuMode: 'Seleção de aceleradores', gpuAll: 'Todos os aceleradores', @@ -1078,7 +1101,13 @@ const message = { approxWeightSize: 'Aprox. {0} GB', services: 'Serviços de modelos', addInstance: 'Adicionar instância', - addService: 'Adicionar serviço de modelo', + modelScopeEndpointHelper: 'Para buscar e baixar modelos do ModelScope. Usa a URL oficial por padrão.', + modelTokenHelper: 'Opcional. Use um token com permissão para acessar modelos privados ou restritos.', + modelDirHelper: 'Diretório de download e listagem dos modelos locais.', + featuredModelsHelper: + 'Catálogo oficial de modelos em destaque do 1Panel. Atualize manualmente ou ative a sincronização automática a cada 24 horas. Apenas o catálogo é atualizado, sem baixar modelos.', + addInstanceHelper: 'Crie uma instância do vLLM para servir os modelos baixados.', + addService: 'Adicionar', onlineModel: 'Modelos online', instanceDeployment: 'Implantação por instância', engines: 'Mecanismos de inferência locais', @@ -1100,11 +1129,11 @@ const message = { recipeArguments: 'Argumentos de inicialização', recipeImportCommand: 'Importar comando', recipeImportPlaceholder: - 'Cole um comando de inicialização no formato pip/uv ou Docker aqui. O 1Panel irá analisar e preencher a Recipe automaticamente.', + 'Cole um comando de inicialização no formato pip/uv ou docker aqui. O 1Panel irá analisar e preencher o formulário automaticamente.', recipeVariablesNotSupported: 'Referências a variáveis não são aceitas nos comandos. Use valores explícitos; configure as variáveis de ambiente no campo correspondente.', recipeImportError: - 'Não foi possível converter. Inclua um comando de inicialização Docker ou vllm serve com um modelo; cole os comandos de instalação pip/uv junto com o comando de inicialização.', + 'Nenhum comando de inicialização válido foi detectado. Cole um comando pip/uv ou docker que inclua um modelo.', engineProvider: 'Mecanismo / Provedor', endpoint: 'Endpoint', cloudAccount: 'Conta na nuvem', @@ -1115,7 +1144,8 @@ const message = { model: 'Modelo', localModel: 'Modelos locais', create_helper: 'Puxar "{0}"', - ollama_doc: 'Você pode visitar o site oficial da Ollama para pesquisar e encontrar mais modelos.', + ollama_doc: + 'Busque modelos em {link}. O modelo será baixado automaticamente após ser adicionado. Verifique se o Ollama está em execução e se há espaço suficiente em disco.', container_conn_helper: 'Use este endereço para acesso ou conexão entre contêineres', from_remote: 'Este modelo não foi baixado pelo 1Panel; não há logs de download relacionados.', no_logs: 'Os logs de download deste modelo foram excluídos e não podem ser visualizados.', @@ -1135,7 +1165,7 @@ const message = { 'Use o endereço do contêiner para agentes; 127.0.0.1, IP do sistema ou endereço personalizado para AI Gateway ou serviços externos.', containerAddress: 'Endereço do contêiner', customAddress: 'Endereço personalizado', - downloader: 'Gerenciamento de downloads', + downloader: 'Download de modelos', modelDirectoryHelper: 'Por padrão, a lista exibe os modelos baixados no diretório configurado em Preparação de modelos > Configurações.', modelDirectoryPlaceholder: 'Buscar modelos ou inserir um caminho completo', @@ -1146,8 +1176,7 @@ const message = { endpointLabel: 'Endpoint do {0}', acceleratedEndpointLabel: 'Endpoint de aceleração do {0}', tokenLabel: 'Token do {0}', - hfEndpointHelper: - 'Configure um endpoint de aceleração quando o acesso ao HuggingFace estiver instável. A pesquisa, os detalhes e os downloads usarão esse endereço.', + hfEndpointHelper: 'URL de espelho opcional para buscas, detalhes e downloads de modelos do HuggingFace.', sortDefault: 'Ordenação padrão', sortMostParameters: 'Mais parâmetros', sortLeastParameters: 'Menos parâmetros', @@ -5145,8 +5174,6 @@ const message = { customScriptHelper: 'Por favor, insira o comando de inicialização completo, por exemplo: npm run start. Para comandos de inicialização do PM2, substitua por pm2-runtime, caso contrário irá falhar ao iniciar.', portError: 'Evite repetir a mesma porta.', - systemRestartHelper: - 'Descrição do status: Interrupção - falha ao adquirir status devido à reinicialização do sistema.', javaScriptHelper: 'Forneça um comando completo de inicialização. Por exemplo, "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'O diretório deve conter arquivos jar, subdiretórios também são aceitos.', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 7bf3b899e..835a57c21 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -1040,6 +1040,29 @@ const message = { 'Перед сохранением создаётся одно минимальное изображение; возможна оплата', }, model: { + searchTitle: 'Поиск и загрузка моделей', + searchHelper: + 'Найдите модели в ModelScope или Hugging Face, затем разверните их или создайте Recipe в разделе подготовки моделей.', + modelScopeSearchHelper: 'Стабильный доступ в материковом Китае', + huggingFaceSearchHelper: 'Большой выбор моделей', + searchPlaceholder: 'Введите имя модели или ID репозитория, например Qwen/Qwen3-8B', + popularSearches: 'Популярные запросы', + searchSort: 'Сортировка', + onlyTokenizer: 'Только токенизатор', + downloadStatus: 'Статус загрузки', + downloaded: 'Загружено', + alreadyExists: 'Уже существует', + downloadCompleted: 'Загрузка завершена', + localFilesMissing: 'Локальные файлы не найдены', + ollamaNameHelper: + 'Введите полное имя модели из библиотеки Ollama. Если тег не указан, используется latest.', + downloadHelper: 'Нажмите «Поиск», чтобы найти и загрузить модели из ModelScope и Hugging Face.', + serviceHelper: + 'Подключайте сервисы моделей из публичных облаков, локальных движков инференса и шлюзов ИИ для встроенных агентов 1Panel и внешних агентов, таких как WorkBuddy.', + gpuType: 'Тип GPU', + vllmVersion: 'Версия vLLM', + vllmImage: 'Образ vLLM', + servicePort: 'Порт сервиса', gpuAcceleration: 'Ускорение GPU', gpuMode: 'Выбор ускорителей', gpuAll: 'Все ускорители', @@ -1071,7 +1094,14 @@ const message = { approxWeightSize: 'Около {0} ГБ', services: 'Сервисы моделей', addInstance: 'Добавить экземпляр', - addService: 'Добавить сервис модели', + modelScopeEndpointHelper: + 'Для поиска и загрузки моделей ModelScope. По умолчанию используется официальный URL.', + modelTokenHelper: 'Необязательно. Для закрытых моделей нужен токен с правами доступа.', + modelDirHelper: 'Каталог загрузки моделей и источник списка локальных моделей.', + featuredModelsHelper: + 'Официальный каталог рекомендуемых моделей 1Panel. Обновляйте вручную или включите автоматическую синхронизацию каждые 24 часа. Обновляется только каталог, без загрузки файлов моделей.', + addInstanceHelper: 'Создайте экземпляр vLLM для обслуживания загруженных моделей.', + addService: 'Добавить', onlineModel: 'Онлайн-модели', instanceDeployment: 'Развертывание по экземплярам', engines: 'Локальные движки инференса', @@ -1093,11 +1123,11 @@ const message = { recipeArguments: 'Параметры запуска', recipeImportCommand: 'Импорт команды', recipeImportPlaceholder: - 'Вставьте сюда команду запуска в формате pip/uv или Docker. 1Panel автоматически разберёт её и заполнит Recipe.', + 'Вставьте сюда команду запуска в формате pip/uv или docker. 1Panel автоматически разберёт её и заполнит форму.', recipeVariablesNotSupported: 'Ссылки на переменные в командах не поддерживаются. Укажите конкретные значения; переменные окружения настройте в соответствующем поле.', recipeImportError: - 'Не удалось преобразовать. Добавьте команду запуска Docker или vllm serve с моделью; вставляйте команды установки pip/uv вместе с командой запуска.', + 'Допустимая команда запуска не найдена. Вставьте команду pip/uv или docker, содержащую модель.', engineProvider: 'Движок / Поставщик', endpoint: 'Конечная точка', cloudAccount: 'Облачная учетная запись', @@ -1108,7 +1138,8 @@ const message = { model: 'Модель', localModel: 'Локальные модели', create_helper: 'Загрузить "{0}"', - ollama_doc: 'Вы можете посетить официальный сайт Ollama, чтобы искать и находить больше моделей.', + ollama_doc: + 'Найдите модели на {link}. После добавления модель будет загружена автоматически. Убедитесь, что Ollama работает и на диске достаточно места.', container_conn_helper: 'Используйте этот адрес для доступа или подключения между контейнерами', from_remote: 'Эта модель не была загружена через 1Panel, нет связанных журналов извлечения.', no_logs: 'Журналы извлечения для этой модели были удалены и не могут быть просмотрены.', @@ -1129,7 +1160,7 @@ const message = { 'Адрес контейнера подходит для контейнеров агентов; 127.0.0.1, системный IP или пользовательский адрес подходит для AI Gateway или внешних сервисов.', containerAddress: 'Адрес контейнера', customAddress: 'Пользовательский адрес', - downloader: 'Управление загрузками', + downloader: 'Загрузка моделей', modelDirectoryHelper: 'По умолчанию список показывает модели, загруженные в каталог, указанный в разделе «Подготовка моделей > Настройки».', modelDirectoryPlaceholder: 'Найти модель или ввести полный путь', @@ -1141,7 +1172,7 @@ const message = { acceleratedEndpointLabel: 'Endpoint ускорения {0}', tokenLabel: '{0} Token', hfEndpointHelper: - 'Настройте endpoint ускорения, если доступ к HuggingFace нестабилен. Он будет использоваться для поиска, деталей и загрузок.', + 'Необязательный URL зеркала для поиска, просмотра сведений и загрузки моделей HuggingFace.', sortDefault: 'Сортировка по умолчанию', sortMostParameters: 'Больше всего параметров', sortLeastParameters: 'Меньше всего параметров', @@ -5115,7 +5146,6 @@ const message = { customScriptHelper: 'Пожалуйста, введите полную команду запуска, например: npm run start. Для команд запуска PM2 замените на pm2-runtime, иначе запуск завершится ошибкой.', portError: 'Не повторяйте один и тот же порт.', - systemRestartHelper: 'Описание статуса: Прерывание - получение статуса не удалось из-за перезагрузки системы', javaScriptHelper: 'Укажите полную команду запуска. Например, "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'Директория должна содержать jar файлы, поддиректории также допустимы', goHelper: 'Укажите полную команду запуска. Например, "go run main.go" или "./main".', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index f16a4bd02..e9848a469 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -1050,6 +1050,29 @@ const message = { validateImageAvailabilityHelper: 'Kaydetmeden önce bir küçük görsel üretir ve ücret doğurabilir', }, model: { + searchTitle: 'Model ara ve indir', + searchHelper: + 'ModelScope veya Hugging Face üzerinde model bulun, ardından Model Hazırlığı bölümünde dağıtın veya bir Recipe oluşturun.', + modelScopeSearchHelper: 'Çin ana karasında kararlı erişim', + huggingFaceSearchHelper: 'Geniş model koleksiyonu', + searchPlaceholder: 'Model adı veya depo kimliği girin, ör. Qwen/Qwen3-8B', + popularSearches: 'Popüler aramalar', + searchSort: 'Sırala', + onlyTokenizer: 'Yalnızca belirteç ayırıcı', + downloadStatus: 'İndirme durumu', + downloaded: 'İndirildi', + alreadyExists: 'Zaten mevcut', + downloadCompleted: 'İndirme tamamlandı', + localFilesMissing: 'Yerel dosyalar bulunamadı', + ollamaNameHelper: 'Ollama kütüphanesindeki tam model adını girin. Etiket belirtilmezse latest kullanılır.', + downloadHelper: + 'ModelScope ve Hugging Face üzerindeki modelleri bulup indirmek için “Ara” düğmesine tıklayın.', + serviceHelper: + 'Genel bulutlardan, yerel çıkarım motorlarından ve AI ağ geçitlerinden model hizmetlerini bağlayarak yerleşik 1Panel ajanları ve WorkBuddy gibi harici ajanlar için kullanıma sunun.', + gpuType: 'GPU türü', + vllmVersion: 'vLLM sürümü', + vllmImage: 'vLLM imajı', + servicePort: 'Hizmet portu', gpuAcceleration: 'GPU hızlandırma', gpuMode: 'Hızlandırıcı seçimi', gpuAll: 'Tüm hızlandırıcılar', @@ -1080,7 +1103,14 @@ const message = { approxWeightSize: 'Yaklaşık {0} GB', services: 'Model hizmetleri', addInstance: 'Örnek ekle', - addService: 'Model hizmeti ekle', + modelScopeEndpointHelper: + 'ModelScope modellerini aramak ve indirmek için kullanılır. Varsayılan, resmî URL adresidir.', + modelTokenHelper: 'İsteğe bağlı. Özel veya kısıtlı modeller için erişim yetkili bir token kullanın.', + modelDirHelper: 'Modellerin indirildiği ve yerel model listesinin okunduğu dizin.', + featuredModelsHelper: + '1Panel resmî öne çıkan model kataloğu. Elle yenileyin veya 24 saatte bir otomatik eşitlemeyi etkinleştirin. Yalnızca katalog güncellenir; model dosyaları indirilmez.', + addInstanceHelper: 'İndirilen modelleri sunmak için bir vLLM örneği oluşturun.', + addService: 'Ekle', onlineModel: 'Çevrimiçi modeller', instanceDeployment: 'Örnek bazında dağıtım', engines: 'Yerel çıkarım motorları', @@ -1102,11 +1132,11 @@ const message = { recipeArguments: 'Başlatma parametreleri', recipeImportCommand: 'Komut içe aktar', recipeImportPlaceholder: - 'pip/uv veya Docker biçimindeki başlatma komutunu buraya yapıştırın. 1Panel komutu otomatik olarak ayrıştırıp Recipe alanlarını doldurur.', + 'pip/uv veya docker biçimindeki başlatma komutunu buraya yapıştırın. 1Panel komutu otomatik olarak ayrıştırıp form alanlarını doldurur.', recipeVariablesNotSupported: 'Komutlarda değişken başvuruları desteklenmez. Açık değerler girin; ortam değişkenlerini ilgili alanda yapılandırın.', recipeImportError: - 'Dönüştürülemedi. Model içeren bir Docker veya vllm serve başlatma komutu ekleyin; pip/uv kurulum komutlarını başlatma komutuyla birlikte yapıştırın.', + 'Geçerli bir başlatma komutu algılanmadı. Model içeren bir pip/uv veya docker komutu yapıştırın.', engineProvider: 'Motor / Sağlayıcı', endpoint: 'Uç nokta', cloudAccount: 'Bulut hesabı', @@ -1117,7 +1147,8 @@ const message = { model: 'Model', localModel: 'Yerel Modeller', create_helper: '"{0}" çek', - ollama_doc: 'Daha fazla model aramak ve bulmak için Ollama resmi web sitesini ziyaret edebilirsiniz.', + ollama_doc: + 'Modelleri {link} adresinde bulun. Model eklendikten sonra otomatik olarak indirilir. Ollama hizmetinin çalıştığından ve yeterli disk alanı olduğundan emin olun.', container_conn_helper: 'Konteynerler arası erişim veya bağlantı için bu adresi kullanın', from_remote: 'Bu model 1Panel aracılığıyla indirilmedi, ilgili çekme logları yok.', no_logs: 'Bu modelin çekme logları silindi ve görüntülenemiyor.', @@ -1137,7 +1168,7 @@ const message = { 'Konteyner adresi ajan konteynerleri içindir; 127.0.0.1, sistem IP veya özel adres AI Gateway ya da harici servisler içindir.', containerAddress: 'Konteyner adresi', customAddress: 'Özel adres', - downloader: 'İndirme yönetimi', + downloader: 'Model indirme', modelDirectoryHelper: 'Model listesi varsayılan olarak Model Hazırlığı > Ayarlar bölümünde yapılandırılan dizine indirilen modelleri gösterir.', modelDirectoryPlaceholder: 'Model arayın veya tam yol girin', @@ -1149,7 +1180,7 @@ const message = { acceleratedEndpointLabel: '{0} hızlandırma endpointi', tokenLabel: '{0} Token', hfEndpointHelper: - 'HuggingFace erişimi kararsız olduğunda bir hızlandırma endpointi yapılandırın. Arama, ayrıntılar ve indirmeler bunu kullanır.', + 'HuggingFace model aramaları, ayrıntıları ve indirmeleri için isteğe bağlı ayna URL adresi.', sortDefault: 'Varsayılan sıralama', sortMostParameters: 'En çok parametre', sortLeastParameters: 'En az parametre', @@ -5127,8 +5158,6 @@ const message = { customScriptHelper: 'Lütfen tam başlatma komutunu girin, örneğin: npm run start. PM2 başlatma komutları için lütfen pm2-runtime ile değiştirin, aksi takdirde başlatma başarısız olacaktır.', portError: 'Aynı portu tekrarlamayın.', - systemRestartHelper: - 'Durum açıklaması: Kesinti - sistem yeniden başlatılması nedeniyle durum alımı başarısız oldu', javaScriptHelper: 'Tam bir başlatma komutu sağlayın. Örneğin, "java -jar halo.jar -Xmx1024M -Xms256M".', javaDirHelper: 'Dizin, jar dosyalarını içermeli, alt dizinler de kabul edilir', goHelper: 'Tam bir başlatma komutu sağlayın. Örneğin, "go run main.go" veya "./main".', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 9449cff43..003c209dd 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -980,6 +980,27 @@ const message = { validateImageAvailabilityHelper: '儲存前會實際產生一張最小圖片,可能產生費用', }, model: { + searchTitle: '搜尋並下載模型', + searchHelper: '從 ModelScope 或 Hugging Face 尋找模型,下載後可在模型準備中部署或建立 Recipe。', + modelScopeSearchHelper: '中國大陸存取穩定', + huggingFaceSearchHelper: '模型資源豐富', + searchPlaceholder: '輸入模型名稱或儲存庫 ID,例如 Qwen/Qwen3-8B', + popularSearches: '熱門搜尋', + searchSort: '排序', + onlyTokenizer: '僅下載分詞器', + downloadStatus: '下載狀態', + downloaded: '已下載', + alreadyExists: '已存在', + downloadCompleted: '下載完成', + localFilesMissing: '找不到本機檔案', + ollamaNameHelper: '請填寫 Ollama 模型庫中的完整模型名稱,未指定標籤時預設使用 latest。', + downloadHelper: '點擊「搜尋」按鈕,即可查找並下載 ModelScope、Hugging Face 上的模型。', + serviceHelper: + '統一接入公有雲、本機推論引擎和 AI 閘道等模型服務,供 1Panel 內建智慧體及 WorkBuddy 等外部智慧體呼叫。', + gpuType: 'GPU 類型', + vllmVersion: 'vLLM 版本', + vllmImage: 'vLLM 映像檔', + servicePort: '服務連接埠', gpuAcceleration: 'GPU 加速', gpuMode: '加速卡選擇', gpuAll: '全部加速卡', @@ -1010,7 +1031,13 @@ const message = { approxWeightSize: '約 {0} GB', services: '模型服務', addInstance: '新增實例', - addService: '新增模型服務', + modelScopeEndpointHelper: '用於搜尋和下載 ModelScope 模型,預設使用官方位址。', + modelTokenHelper: '選填,存取私人或受限模型時需填寫具備權限的 Token。', + modelDirHelper: '模型下載儲存目錄,也用於讀取本機模型清單。', + featuredModelsHelper: + '1Panel 官方精選模型目錄,可手動重新整理或開啟每 24 小時自動同步,僅更新目錄,不下載模型檔案。', + addInstanceHelper: '建立 vLLM 執行個體,將已下載的模型部署為模型服務。', + addService: '新增', onlineModel: '線上模型', instanceDeployment: '按執行個體部署', engines: '本機推理引擎', @@ -1031,10 +1058,9 @@ const message = { '前往 {link},依序選擇模型提供商和目標模型,再根據硬體、量化版本及部署策略等選項產生啟動命令。', recipeArguments: '啟動參數', recipeImportCommand: '匯入命令', - recipeImportPlaceholder: '貼上 pip/uv 或 Docker 格式的啟動命令,1Panel 將自動解析並填入 Recipe。', + recipeImportPlaceholder: '貼上 pip/uv 或 docker 格式的啟動命令,1Panel 將自動解析並填入。', recipeVariablesNotSupported: '命令中不支援變數引用,請填寫具體值;環境變數請在環境變數欄設定。', - recipeImportError: - '無法轉換,請提供包含模型的 Docker 或 vllm serve 啟動命令;pip/uv 安裝命令需要與啟動命令一起貼上。', + recipeImportError: '未識別到有效的啟動命令,請貼上包含模型的 pip/uv 或 docker 命令。', engineProvider: '引擎 / 供應商', endpoint: '端點', cloudAccount: '雲端帳號', @@ -1045,7 +1071,7 @@ const message = { model: '模型', localModel: '本地模型', create_helper: '拉取 "{0}"', - ollama_doc: '您可以瀏覽 Ollama 官方網站,搜尋並尋找更多模型。', + ollama_doc: '前往 {link} 查找模型,新增後會自動拉取模型,請確保 Ollama 服務正常運作且磁碟空間充足。', container_conn_helper: '容器間瀏覽或連接使用此地址', from_remote: '該模型並非透過 1Panel 下載,無相關拉取日誌。', no_logs: '該模型的拉取日誌已被刪除,無法檢視相關日誌。', @@ -1065,7 +1091,7 @@ const message = { '容器地址適合智能體容器呼叫;127.0.0.1、本機 IP 或自訂地址適合 AI 閘道或外部服務呼叫。', containerAddress: '容器地址', customAddress: '自訂地址', - downloader: '下載管理', + downloader: '模型下載', modelDirectoryHelper: '模型列表預設來自「模型準備 > 設定」中配置的模型目錄,顯示該目錄下已下載的模型。', modelDirectoryPlaceholder: '搜尋模型或輸入完整路徑', selectModelDirectory: '選擇目錄', @@ -1075,7 +1101,7 @@ const message = { endpointLabel: '{0} 地址', acceleratedEndpointLabel: '{0} 加速地址', tokenLabel: '{0} Token', - hfEndpointHelper: '國內存取 HuggingFace 不穩定時可設定加速地址,搜尋、詳情和下載都會使用該地址。', + hfEndpointHelper: '選填,用於加速 HuggingFace 模型的搜尋、詳細資訊查詢和下載。', sortDefault: '綜合排序', sortMostParameters: '參數最多', sortLeastParameters: '參數最少', @@ -4695,7 +4721,6 @@ const message = { customScript: '自訂啟動指令', customScriptHelper: '請填寫完整的啟動指令,例:npm run start,pm2 啟動指令請換為 pm2-runtime,否則會啟動失敗', portError: '不能填寫相同連接埠', - systemRestartHelper: '狀態說明:中斷-系統重新啟動導致狀態取得失敗', javaScriptHelper: '請填寫完整啟動指令,例:java -jar halo.jar -Xmx1024M -Xms256M', javaDirHelper: '目錄中要包含 jar 包,子目錄中包含也可', goHelper: '請填寫完整啟動指令,例:go run main.go 或 ./main', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index fe1a28cf8..6b37039bf 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -993,6 +993,27 @@ const message = { validateImageAvailabilityHelper: '保存前会真实生成一张最小图片,可能产生费用', }, model: { + searchTitle: '搜索并下载模型', + searchHelper: '从 ModelScope 或 Hugging Face 查找模型,下载后可在模型准备中部署或创建 Recipe。', + modelScopeSearchHelper: '国内访问稳定', + huggingFaceSearchHelper: '模型资源丰富', + searchPlaceholder: '输入模型名称或仓库 ID,例如 Qwen/Qwen3-8B', + popularSearches: '热门搜索', + searchSort: '排序', + onlyTokenizer: '仅下载分词器', + downloadStatus: '下载状态', + downloaded: '已下载', + alreadyExists: '已存在', + downloadCompleted: '下载完成', + localFilesMissing: '本地文件未找到', + ollamaNameHelper: '请填写 Ollama 模型库中的完整模型名称,未指定标签时默认使用 latest。', + downloadHelper: '点击“搜索”按钮,即可查找并下载 ModelScope、Hugging Face 上的模型。', + serviceHelper: + '统一接入公有云、本地推理引擎和 AI 网关等模型服务,供 1Panel 内置智能体及 WorkBuddy 等外部智能体调用。', + gpuType: 'GPU 类型', + vllmVersion: 'vLLM 版本', + vllmImage: 'vLLM 镜像', + servicePort: '服务端口', gpuAcceleration: 'GPU 加速', gpuMode: '加速卡选择', gpuAll: '全部加速卡', @@ -1023,7 +1044,13 @@ const message = { approxWeightSize: '约 {0} GB', services: '模型服务', addInstance: '新增实例', - addService: '添加模型服务', + modelScopeEndpointHelper: '用于搜索和下载 ModelScope 模型,默认使用官方地址。', + modelTokenHelper: '选填,访问私有或受限模型时需填写有权限的 Token。', + modelDirHelper: '模型下载保存目录,也用于读取本地模型列表。', + featuredModelsHelper: + '1Panel 官方精选模型目录,可手动刷新或开启每 24 小时自动同步,仅更新目录,不下载模型文件。', + addInstanceHelper: '创建 vLLM 实例,将已下载的模型部署为模型服务。', + addService: '添加', onlineModel: '在线模型', instanceDeployment: '按实例部署', engines: '本地推理引擎', @@ -1044,10 +1071,9 @@ const message = { '前往 {link},依次选择模型提供商和目标模型,再根据硬件、量化版本及部署策略等选项生成启动命令。', recipeArguments: '启动参数', recipeImportCommand: '导入命令', - recipeImportPlaceholder: '粘贴 pip/uv 或 Docker 格式的启动命令,1Panel 将自动解析并填充 Recipe。', + recipeImportPlaceholder: '粘贴 pip/uv 或 docker 格式的启动命令,1Panel 将自动解析并填充。', recipeVariablesNotSupported: '命令中不支持变量引用,请填写具体值;环境变量请在环境变量栏配置。', - recipeImportError: - '无法转换,请提供包含模型的 Docker 或 vllm serve 启动命令;pip/uv 安装命令需要与启动命令一起粘贴。', + recipeImportError: '未识别到有效的启动命令,请粘贴包含模型的 pip/uv 或 docker 命令。', engineProvider: '引擎 / 供应商', endpoint: '端点', cloudAccount: '云端账号', @@ -1058,7 +1084,7 @@ const message = { model: '模型', localModel: '本地模型', create_helper: '拉取 "{0}"', - ollama_doc: '您可以访问 Ollama 官网,搜索并查找更多模型。', + ollama_doc: '前往 {link} 查找模型,添加后会自动拉取模型,请确保 Ollama 服务正常运行且磁盘空间充足。', container_conn_helper: '容器间访问或连接使用此地址', from_remote: '该模型并非通过 1Panel 下载,无相关拉取日志。', no_logs: '该模型的拉取日志已被删除,无法查看相关日志。', @@ -1078,7 +1104,7 @@ const message = { '容器地址适合智能体容器调用;127.0.0.1、本机 IP 或自定义地址适合 AI 网关或外部服务调用。', containerAddress: '容器地址', customAddress: '自定义地址', - downloader: '下载管理', + downloader: '模型下载', modelDirectoryHelper: '模型列表默认来自“模型准备 > 设置”中配置的模型目录,展示该目录下已下载的模型。', modelDirectoryPlaceholder: '搜索模型或输入完整路径', selectModelDirectory: '选择目录', @@ -1088,7 +1114,7 @@ const message = { endpointLabel: '{0} 地址', acceleratedEndpointLabel: '{0} 加速地址', tokenLabel: '{0} Token', - hfEndpointHelper: '国内访问 HuggingFace 不稳定时可配置加速地址,搜索、详情和下载都会使用该地址。', + hfEndpointHelper: '选填,用于加速 HuggingFace 模型的搜索、详情查询和下载。', sortDefault: '综合排序', sortMostParameters: '参数最多', sortLeastParameters: '参数最少', @@ -4737,7 +4763,6 @@ const message = { customScript: '自定义启动命令', customScriptHelper: '请填写完整的启动命令,例如:npm run start,pm2 启动命令请换为 pm2-runtime,否则会启动失败', portError: '不能填写相同端口', - systemRestartHelper: '状态说明:中断-系统重启导致状态获取失败', javaScriptHelper: '请填写完整启动命令,例如:java -jar halo.jar -Xmx1024M -Xms256M', javaDirHelper: '目录中要包含 jar 包,子目录中包含也可', goHelper: '请填写完整启动命令,例如:go run main.go 或 ./main', diff --git a/frontend/src/views/ai/model/deployment.ts b/frontend/src/views/ai/model/deployment.ts index 86b9574f6..ac81080bb 100644 --- a/frontend/src/views/ai/model/deployment.ts +++ b/frontend/src/views/ai/model/deployment.ts @@ -22,6 +22,7 @@ export interface Deployment { } interface VllmAPI { + listVllmCommandTemplates: () => Promise>>; pageVllm: (req: ReqPage & { info: string }) => Promise>>; operateVllm: ( req: { id: number; operate: string; taskID: string; forceDelete?: boolean } & Partial, @@ -52,3 +53,12 @@ export async function readPages(search: (page: ReqPage) => Promise + - + + + + - + @@ -524,6 +588,7 @@ import { updateFeaturedModelsSync, } from '@/api/modules/model-downloader'; import { useGlobalStore } from '@/composables/useGlobalStore'; +import { loadVllmAPI, matchesModelRecipe } from '@/views/ai/model/deployment'; const emit = defineEmits<{ deploy: [modelDir: string] }>(); const { currentNode, isMobile, isOffline, language, isProductPro } = useGlobalStore(); @@ -579,7 +644,7 @@ const featuredFields = [ ] as const; const currentSource = ref('modelscope'); const models = ref([]); -const downloads = ref([]); +const downloads = ref>([]); const searchOpen = ref(false); watch( [currentSource, currentNode, searchOpen], @@ -629,7 +694,7 @@ const searchForm = reactive({ const searchPagination = reactive({ currentPage: 1, - pageSize: 50, + pageSize: 10, total: 0, }); @@ -751,9 +816,58 @@ const changeDownloadType = async () => { }; let downloadRequest = 0; +let refreshingProgress = false; +const refreshDownloadProgress = async () => { + if (refreshingProgress || currentTab.value !== 'downloader') return; + const ids = downloads.value + .filter((row) => row.id && ['Waiting', 'Downloading'].includes(row.status)) + .map((row) => row.id); + if (!ids.length) return; + const request = downloadRequest; + const node = currentNode.value; + refreshingProgress = true; + try { + const { data } = await pageModelDownloadTasks({ + ids, + page: 1, + pageSize: ids.length, + info: '', + status: '', + includeLocal: true, + }); + if (node !== currentNode.value || request !== downloadRequest || currentTab.value !== 'downloader') return; + const tasks = new Map((data.items || []).map((item) => [item.id, item])); + for (const row of downloads.value) { + const task = tasks.get(row.id); + if (!task) continue; + row.status = task.status; + row.progress = task.progress; + row.totalSize = task.totalSize; + row.downloadedSize = task.downloadedSize; + row.errorMessage = task.errorMessage; + row.startedAt = task.startedAt; + row.completedAt = task.completedAt; + row.canCancel = task.canCancel; + row.canRetry = task.canRetry; + row.canRemoveRecord = task.canRemoveRecord; + row.localModel = task.localModel; + } + } finally { + refreshingProgress = false; + } +}; + const loadDownloads = async () => { const request = ++downloadRequest; const node = currentNode.value; + const recipeResult = Promise.allSettled([ + recipesView && isProductPro.value + ? loadVllmAPI().then((api) => { + if (node !== currentNode.value || request !== downloadRequest) return; + return api.listVllmCommandTemplates(); + }) + : Promise.resolve(undefined), + ]); const res = await pageModelDownloadTasks({ page: downloadPagination.currentPage, pageSize: downloadPagination.pageSize, @@ -769,6 +883,16 @@ const loadDownloads = async () => { if (downloadPagination.currentPage > lastPage) { downloadPagination.currentPage = lastPage; await loadDownloads(); + return; + } + const [result] = await recipeResult; + if (node !== currentNode.value || request !== downloadRequest) return; + const recipes = result.status === 'fulfilled' ? result.value?.data : undefined; + for (const row of downloads.value) { + row.recipeCount = + row.downloadType === 'tokenizer' + ? 0 + : recipes?.filter((recipe) => matchesModelRecipe(recipe.model, row.targetDir, row.repoID)).length; } }; @@ -861,34 +985,32 @@ const refreshCurrent = async () => { } }; -const statusTagType = (status: string) => { - switch (status) { - case 'Success': - return 'success'; +const statusText = (row: ModelDownloader.TaskItem, withDetail = false) => { + let key = 'commons.status.waiting'; + switch (row.status) { case 'Downloading': - return 'primary'; + key = 'aiTools.model.downloading'; + break; + case 'Success': + key = !row.localModel + ? 'aiTools.model.downloadCompleted' + : row.id + ? 'aiTools.model.downloaded' + : 'aiTools.model.alreadyExists'; + break; case 'Failed': + key = 'commons.status.failed'; + break; case 'Canceled': - return 'danger'; - default: - return 'info'; + key = 'aiTools.model.canceled'; + break; } -}; - -const statusText = (status: string) => { - if (status === 'Downloading') { - return i18n.global.t('aiTools.model.downloading'); - } - if (status === 'Success') { - return i18n.global.t('commons.status.success'); - } - if (status === 'Failed') { - return i18n.global.t('commons.status.failed'); - } - if (status === 'Canceled') { - return i18n.global.t('aiTools.model.canceled'); - } - return i18n.global.t('commons.status.waiting'); + if (!withDetail) return i18n.global.t(key); + const detail = + row.status === 'Success' && !row.localModel + ? i18n.global.t('aiTools.model.localFilesMissing') + : row.errorMessage; + return [i18n.global.t(key), detail].filter(Boolean).join(':'); }; const sourceLabel = (source: string) => { @@ -903,7 +1025,7 @@ const sourceLabel = (source: string) => { const formatBytes = (value: number) => { if (!value) { - return '-'; + return '0 B'; } if (value < 1024 * 1024) { return `${(value / 1024).toFixed(1)} KB`; @@ -945,6 +1067,8 @@ watch(currentTab, async (value) => { }); watch(currentNode, async () => { + downloadRequest++; + downloads.value = []; recipeModelPath.value = ''; featuredRequest++; featuredLoading.value = false; @@ -1062,6 +1186,10 @@ onMounted(() => { overflow-wrap: anywhere; } +.search-intro { + margin-bottom: 20px; +} + .source-switch { margin-bottom: 16px; } @@ -1075,63 +1203,123 @@ onMounted(() => { .search-input { flex: 1; min-width: 0; +} - :deep(.search-button) { - width: 100%; +.popular-searches { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 8px 16px; + margin-top: 12px; + color: var(--el-text-color-secondary); + font-size: 12px; + + .el-button { + margin-left: 0; + font-size: 12px; } } +.search-results-toolbar { + display: flex; + align-items: center; + justify-content: flex-end; + margin-top: 16px; +} + .sort-select { - flex: 0 0 160px; - width: 160px; + width: 220px; +} + +.download-repo-id { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + line-height: 20px; +} + +.download-source { + display: flex; + align-items: center; + gap: 4px; + margin-top: 6px; + color: var(--el-text-color-secondary); + font-size: 12px; + line-height: 16px; +} + +.download-source-icon { + width: 14px; + height: 14px; + padding: 0; + flex-shrink: 0; } .progress-cell { - display: flex; - flex-direction: column; - align-items: stretch; + display: grid; + grid-template-rows: 16px 16px; gap: 2px; width: 100%; } -.status-tag-content { +.progress-track { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; + + :deep(.el-progress) { + flex: 1; + min-width: 0; + } +} + +.progress-percentage { + flex-shrink: 0; + width: 42px; + text-align: right; + color: var(--el-text-color-secondary); + font-size: 12px; + line-height: 16px; +} + +.download-size-row { + display: flex; + align-items: center; + gap: 6px; + min-width: 0; +} + +.download-status { display: inline-flex; align-items: center; gap: 4px; + margin-left: auto; + min-width: 0; + color: var(--el-text-color-secondary); + font-size: 12px; + line-height: 16px; } -.progress-bar { - flex: 1; - min-width: 110px; +.download-status-text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} - :deep(.el-progress__text) { - min-width: 36px; - margin-left: 6px; - font-size: 12px !important; - } +.download-status-icon { + flex-shrink: 0; + color: var(--el-text-color-secondary); + font-size: 14px; } .progress-size { min-width: 0; color: var(--el-text-color-secondary); font-size: 12px; - line-height: 14px; + line-height: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } - -.model-path-link { - max-width: 100%; - justify-content: flex-start; - - :deep(> span) { - display: block; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - text-align: left; - } -} diff --git a/frontend/src/views/model-downloader/source-select.vue b/frontend/src/views/model-downloader/source-select.vue index b3b474659..f5e7d50e1 100644 --- a/frontend/src/views/model-downloader/source-select.vue +++ b/frontend/src/views/model-downloader/source-select.vue @@ -10,7 +10,22 @@ @click="modelValue = source" > - {{ source === 'modelscope' ? 'ModelScope' : 'HuggingFace' }} + + + {{ source === 'modelscope' ? 'ModelScope' : 'Hugging Face' }} + + {{ $t('home.recommend') }} + + + + {{ + $t( + 'aiTools.model.' + + (source === 'modelscope' ? 'modelScopeSearchHelper' : 'huggingFaceSearchHelper'), + ) + }} + + @@ -18,7 +33,7 @@ @@ -68,4 +83,23 @@ const modelValue = defineModel({ required: true }); text-overflow: ellipsis; white-space: nowrap; } + +.source-content { + min-width: 0; +} + +.source-heading { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 8px; +} + +.source-description { + display: block; + margin-top: 6px; + color: var(--el-text-color-secondary); + font-size: 12px; + line-height: 1.5; +}