diff --git a/backend/app/api/v1/ai_tool.go b/backend/app/api/v1/ai_tool.go index bb961722e..b36ed4fdd 100644 --- a/backend/app/api/v1/ai_tool.go +++ b/backend/app/api/v1/ai_tool.go @@ -58,6 +58,29 @@ func (b *BaseApi) SearchOllamaModel(c *gin.Context) { }) } +// @Tags AITools +// @Summary Page Ollama models +// @Accept json +// @Param request body dto.OllamaModelName true "request" +// @Success 200 {string} details +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /aitools/ollama/model/load [post] +func (b *BaseApi) LoadOllamaModelDetail(c *gin.Context) { + var req dto.OllamaModelName + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + detail, err := AIToolService.LoadDetail(req.Name) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, detail) +} + // @Tags AITools // @Summary Delete Ollama model // @Accept json @@ -66,6 +89,7 @@ func (b *BaseApi) SearchOllamaModel(c *gin.Context) { // @Security ApiKeyAuth // @Security Timestamp // @Router /aitool/ollama/model/del [post] +// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除模型 [name]","formatEN":"remove Ollama model [name]"} func (b *BaseApi) DeleteOllamaModel(c *gin.Context) { var req dto.OllamaModelName if err := helper.CheckBindAndValidate(&req, c); err != nil { diff --git a/backend/app/service/ai_tool.go b/backend/app/service/ai_tool.go index 405906a33..7dbe18ca9 100644 --- a/backend/app/service/ai_tool.go +++ b/backend/app/service/ai_tool.go @@ -21,6 +21,7 @@ type IAIToolService interface { Search(search dto.SearchWithPage) (int64, []dto.OllamaModelInfo, error) Create(name string) error Delete(name string) error + LoadDetail(name string) (string, error) } func NewIAIToolService() IAIToolService { @@ -32,6 +33,9 @@ func (u *AIToolService) Search(req dto.SearchWithPage) (int64, []dto.OllamaModel if err != nil { return 0, nil, err } + if ollamaBaseInfo.Status != constant.Running { + return 0, nil, nil + } stdout, err := cmd.Execf("docker exec %s ollama list", ollamaBaseInfo.ContainerName) if err != nil { return 0, nil, err @@ -85,6 +89,24 @@ func (u *AIToolService) Search(req dto.SearchWithPage) (int64, []dto.OllamaModel return int64(total), records, err } +func (u *AIToolService) LoadDetail(name string) (string, error) { + if cmd.CheckIllegal(name) { + return "", buserr.New(constant.ErrCmdIllegal) + } + ollamaBaseInfo, err := appInstallRepo.LoadBaseInfo("ollama", "") + if err != nil { + return "", err + } + if ollamaBaseInfo.Status != constant.Running { + return "", nil + } + stdout, err := cmd.Execf("docker exec %s ollama show %s", ollamaBaseInfo.ContainerName, name) + if err != nil { + return "", err + } + return stdout, err +} + func (u *AIToolService) Create(name string) error { if cmd.CheckIllegal(name) { return buserr.New(constant.ErrCmdIllegal) @@ -93,6 +115,9 @@ func (u *AIToolService) Create(name string) error { if err != nil { return err } + if ollamaBaseInfo.Status != constant.Running { + return nil + } fileName := strings.ReplaceAll(name, ":", "-") logItem := path.Join(global.CONF.System.DataDir, "log", "AITools", fileName) if _, err := os.Stat(path.Dir(logItem)); err != nil && os.IsNotExist(err) { @@ -130,6 +155,9 @@ func (u *AIToolService) Delete(name string) error { if err != nil { return err } + if ollamaBaseInfo.Status != constant.Running { + return nil + } stdout, err := cmd.Execf("docker exec %s ollama list", ollamaBaseInfo.ContainerName) if err != nil { return err diff --git a/backend/app/service/auth.go b/backend/app/service/auth.go index cf5c02355..c80c80e72 100644 --- a/backend/app/service/auth.go +++ b/backend/app/service/auth.go @@ -3,6 +3,8 @@ package service import ( "crypto/hmac" "encoding/base64" + "strconv" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" @@ -13,7 +15,6 @@ import ( "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/pkg/errors" - "strconv" ) type AuthService struct{} @@ -203,10 +204,7 @@ func (u *AuthService) GetSecurityEntrance() string { func (u *AuthService) IsLogin(c *gin.Context) bool { sID, _ := c.Cookie(constant.SessionName) _, err := global.SESSION.Get(sID) - if err != nil { - return false - } - return true + return err == nil } func checkPassword(password string) error { diff --git a/backend/router/ro_aitool.go b/backend/router/ro_aitool.go index 4c0efcceb..63ca06c75 100644 --- a/backend/router/ro_aitool.go +++ b/backend/router/ro_aitool.go @@ -17,6 +17,7 @@ func (a *AIToolsRouter) InitRouter(Router *gin.RouterGroup) { { aiToolsRouter.POST("/ollama/model", baseApi.CreateOllamaModel) aiToolsRouter.POST("/ollama/model/search", baseApi.SearchOllamaModel) + aiToolsRouter.POST("/ollama/model/load", baseApi.LoadOllamaModelDetail) aiToolsRouter.POST("/ollama/model/del", baseApi.DeleteOllamaModel) aiToolsRouter.GET("/gpu/load", baseApi.LoadGpuInfo) } diff --git a/frontend/src/api/modules/ai-tool.ts b/frontend/src/api/modules/ai-tool.ts index 6825d4992..1f8878004 100644 --- a/frontend/src/api/modules/ai-tool.ts +++ b/frontend/src/api/modules/ai-tool.ts @@ -11,6 +11,9 @@ export const deleteOllamaModel = (name: string) => { export const searchOllamaModel = (params: AITool.OllamaModelSearch) => { return http.post>(`/aitools/ollama/model/search`, params); }; +export const loadOllamaModel = (name: string) => { + return http.post(`/aitools/ollama/model/load`, { name: name }); +}; export const loadGPUInfo = () => { return http.get(`/aitools/gpu/load`); diff --git a/frontend/src/assets/iconfont/iconfont.css b/frontend/src/assets/iconfont/iconfont.css index d574d033c..ff285ec15 100644 --- a/frontend/src/assets/iconfont/iconfont.css +++ b/frontend/src/assets/iconfont/iconfont.css @@ -1,9 +1,9 @@ @font-face { font-family: "panel"; /* Project id 3575356 */ - src: url('iconfont.woff2?t=1732681110788') format('woff2'), - url('iconfont.woff?t=1732681110788') format('woff'), - url('iconfont.ttf?t=1732681110788') format('truetype'), - url('iconfont.svg?t=1732681110788#panel') format('svg'); + src: url('iconfont.woff2?t=1739443302730') format('woff2'), + url('iconfont.woff?t=1739443302730') format('woff'), + url('iconfont.ttf?t=1739443302730') format('truetype'), + url('iconfont.svg?t=1739443302730#panel') format('svg'); } .panel { @@ -14,6 +14,10 @@ -moz-osx-font-smoothing: grayscale; } +.p-jiqiren2:before { + content: "\e613"; +} + .p-alert-3:before { content: "\e728"; } @@ -170,14 +174,6 @@ content: "\e604"; } -.p-gpu-2:before { - content: "\e6d8"; -} - -.p-gpu-1:before { - content: "\e623"; -} - .p-monitor-4:before { content: "\ec4e"; } diff --git a/frontend/src/assets/iconfont/iconfont.js b/frontend/src/assets/iconfont/iconfont.js index 7bf31d135..a78d93dc1 100644 --- a/frontend/src/assets/iconfont/iconfont.js +++ b/frontend/src/assets/iconfont/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_3575356='',(h=>{var l=(a=(a=document.getElementsByTagName("script"))[a.length-1]).getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var c,t,p,z,v,i=function(l,a){a.parentNode.insertBefore(l,a)};if(l&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}c=function(){var l,a=document.createElement("div");a.innerHTML=h._iconfont_svg_string_3575356,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?i(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),c()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(p=c,z=h.document,v=!1,d(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,m())})}function m(){v||(v=!0,p())}function d(){try{z.documentElement.doScroll("left")}catch(l){return void setTimeout(d,50)}m()}})(window); \ No newline at end of file +window._iconfont_svg_string_3575356='',(h=>{var l=(a=(a=document.getElementsByTagName("script"))[a.length-1]).getAttribute("data-injectcss"),a=a.getAttribute("data-disable-injectsvg");if(!a){var c,t,p,z,v,i=function(l,a){a.parentNode.insertBefore(l,a)};if(l&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}c=function(){var l,a=document.createElement("div");a.innerHTML=h._iconfont_svg_string_3575356,(a=a.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",a=a,(l=document.body).firstChild?i(a,l.firstChild):l.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),c()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(p=c,z=h.document,v=!1,d(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,m())})}function m(){v||(v=!0,p())}function d(){try{z.documentElement.doScroll("left")}catch(l){return void setTimeout(d,50)}m()}})(window); \ No newline at end of file diff --git a/frontend/src/assets/iconfont/iconfont.json b/frontend/src/assets/iconfont/iconfont.json index c103186a2..195dd08ca 100644 --- a/frontend/src/assets/iconfont/iconfont.json +++ b/frontend/src/assets/iconfont/iconfont.json @@ -5,6 +5,13 @@ "css_prefix_text": "p-", "description": "", "glyphs": [ + { + "icon_id": "10505865", + "name": "机器人", + "font_class": "jiqiren2", + "unicode": "e613", + "unicode_decimal": 58899 + }, { "icon_id": "4472516", "name": "告警设置", @@ -278,20 +285,6 @@ "unicode": "e604", "unicode_decimal": 58884 }, - { - "icon_id": "640495", - "name": "详细信息", - "font_class": "gpu-2", - "unicode": "e6d8", - "unicode_decimal": 59096 - }, - { - "icon_id": "6176565", - "name": "监控", - "font_class": "gpu-1", - "unicode": "e623", - "unicode_decimal": 58915 - }, { "icon_id": "40398413", "name": "监控", diff --git a/frontend/src/assets/iconfont/iconfont.svg b/frontend/src/assets/iconfont/iconfont.svg index 3b66d7d4c..789ceedd1 100644 --- a/frontend/src/assets/iconfont/iconfont.svg +++ b/frontend/src/assets/iconfont/iconfont.svg @@ -14,6 +14,8 @@ /> + + @@ -92,10 +94,6 @@ - - - - diff --git a/frontend/src/assets/iconfont/iconfont.ttf b/frontend/src/assets/iconfont/iconfont.ttf index 64b579b1b..fad72d2d8 100644 Binary files a/frontend/src/assets/iconfont/iconfont.ttf and b/frontend/src/assets/iconfont/iconfont.ttf differ diff --git a/frontend/src/assets/iconfont/iconfont.woff b/frontend/src/assets/iconfont/iconfont.woff index 1761727e4..e7d21b365 100644 Binary files a/frontend/src/assets/iconfont/iconfont.woff and b/frontend/src/assets/iconfont/iconfont.woff differ diff --git a/frontend/src/assets/iconfont/iconfont.woff2 b/frontend/src/assets/iconfont/iconfont.woff2 index 584b8b220..7a213fc34 100644 Binary files a/frontend/src/assets/iconfont/iconfont.woff2 and b/frontend/src/assets/iconfont/iconfont.woff2 differ diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 30390f359..203662fc1 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -330,6 +330,7 @@ const message = { firewall: 'Firewall', ssl: 'Certificate | Certificates', database: 'Database | Databases', + ai_tools: 'AI', container: 'Container | Containers', cronjob: 'Cron Job | Cron Jobs', host: 'Host | Hosts', @@ -592,6 +593,53 @@ const message = { 'This connnection address can be used by applications running on non-container or external applications.', localIP: 'Local IP', }, + ai_tools: { + model: { + model: 'Model', + create: 'Add Model', + create_helper: 'Pull "{0}" from Ollama.com', + ollama_doc: 'You can visit the Ollama official website to search and find more models.', + container_conn_helper: 'Use this address for inter-container access or connection', + }, + gpu: { + gpu: 'GPU Monitor', + base: 'Basic Information', + gpuHelper: 'NVIDIA-SMI or XPU-SMI command not detected on the current system. Please check and try again!', + driverVersion: 'Driver Version', + cudaVersion: 'CUDA Version', + process: 'Process Information', + type: 'Type', + typeG: 'Graphics', + typeC: 'Compute', + typeCG: 'Compute + Graphics', + processName: 'Process Name', + processMemoryUsage: 'Memory Usage', + temperatureHelper: 'High GPU temperature can cause GPU frequency throttling', + performanceStateHelper: 'From P0 (maximum performance) to P12 (minimum performance)', + busID: 'Bus ID', + persistenceMode: 'Persistence Mode', + enabled: 'Enabled', + disabled: 'Disabled', + persistenceModeHelper: + 'Persistence mode allows quicker task responses but increases standby power consumption.', + displayActive: 'Graphics Card Initialized', + displayActiveT: 'Yes', + displayActiveF: 'No', + ecc: 'Error Correction and Check Technology', + computeMode: 'Compute Mode', + default: 'Default', + exclusiveProcess: 'Exclusive Process', + exclusiveThread: 'Exclusive Thread', + prohibited: 'Prohibited', + defaultHelper: 'Default: Processes can execute concurrently', + exclusiveProcessHelper: + 'Exclusive Process: Only one CUDA context can use the GPU, but can be shared by multiple threads', + exclusiveThreadHelper: 'Exclusive Thread: Only one thread in a CUDA context can use the GPU', + prohibitedHelper: 'Prohibited: Processes are not allowed to execute simultaneously', + migModeHelper: 'Used to create MIG instances for physical isolation of the GPU at the user level.', + migModeNA: 'Not Supported', + }, + }, container: { create: 'Create container', edit: 'Edit container', @@ -1749,7 +1797,6 @@ const message = { introduce: 'Feature Introduction', waf: 'Upgrading to the professional version can provide features such as interception map, logs, block records, geographical location blocking, custom rules, custom interception pages, etc.', tamper: 'Upgrading to the professional version can protect websites from unauthorized modifications or tampering.', - gpu: 'Upgrading to the professional version can help users visually monitor important parameters of GPU such as workload, temperature, memory usage in real time.', setting: 'Upgrading to the professional version allows customization of panel logo, welcome message, and other information.', monitor: diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 4657021d3..d3d9dc9b5 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -330,6 +330,7 @@ const message = { firewall: 'ファイアウォール', ssl: '証明書|証明書', database: 'データベース|データベース', + ai_tools: 'AI', container: 'コンテナ|コンテナ', cronjob: 'クロンジョブ|クロンの仕事', host: 'ホスト|ホスト', @@ -592,6 +593,53 @@ const message = { 'この接続アドレスは、非コンテナまたは外部アプリケーションで実行されているアプリケーションで使用できます。', localIP: 'ローカルIP', }, + ai_tools: { + model: { + model: 'モデル', + create: 'モデルを追加', + create_helper: 'Ollama.com から "{0}" を取得', + ollama_doc: 'Ollama の公式ウェブサイトを訪れて、さらに多くのモデルを検索して見つけることができます。', + container_conn_helper: 'コンテナ間のアクセスまたは接続にこのアドレスを使用', + }, + gpu: { + gpu: 'GPUモニター', + base: '基本情報', + gpuHelper: + '現在のシステムでNVIDIA-SMIまたはXPU-SMIコマンドが検出されませんでした。確認して再試行してください!', + driverVersion: 'ドライバーバージョン', + cudaVersion: 'CUDAバージョン', + process: 'プロセス情報', + type: 'タイプ', + typeG: 'グラフィックス', + typeC: 'コンピュート', + typeCG: 'コンピュート + グラフィックス', + processName: 'プロセス名', + processMemoryUsage: 'メモリ使用量', + temperatureHelper: '高いGPU温度はGPUの周波数制限を引き起こす可能性があります', + performanceStateHelper: 'P0(最大性能)からP12(最小性能)まで', + busID: 'バスID', + persistenceMode: '永続モード', + enabled: '有効', + disabled: '無効', + persistenceModeHelper: '永続モードはタスクの応答速度を速くしますが、待機時の消費電力が増加します。', + displayActive: 'グラフィックカード初期化済み', + displayActiveT: 'はい', + displayActiveF: 'いいえ', + ecc: 'エラー訂正およびチェック技術', + computeMode: 'コンピュートモード', + default: 'デフォルト', + exclusiveProcess: '専用プロセス', + exclusiveThread: '専用スレッド', + prohibited: '禁止', + defaultHelper: 'デフォルト:プロセスは並行して実行できます', + exclusiveProcessHelper: + '専用プロセス:1つのCUDAコンテキストのみがGPUを使用できますが、複数のスレッドで共有できます', + exclusiveThreadHelper: '専用スレッド:CUDAコンテキスト内の1つのスレッドのみがGPUを使用できます', + prohibitedHelper: '禁止:プロセスは同時に実行できません', + migModeHelper: 'ユーザーレベルでGPUの物理的分離を行うためのMIGインスタンスを作成するために使用されます。', + migModeNA: 'サポートされていません', + }, + }, container: { create: 'コンテナを作成します', edit: 'コンテナを編集します', @@ -1722,7 +1770,6 @@ const message = { introduce: '機能の紹介', waf: 'プロフェッショナルバージョンにアップグレードすると、インターセプトマップ、ログ、ブロックレコード、地理的位置ブロッキング、カスタムルール、カスタムインターセプトページなどの機能を提供できます。', tamper: 'プロのバージョンにアップグレードすると、不正な変更や改ざんからWebサイトを保護できます。', - gpu: 'プロのバージョンにアップグレードすることで、ユーザーはワークロード、温度、メモリ使用量などのGPUの重要なパラメーターをリアルタイムで視覚的に監視するのに役立ちます。', setting: 'プロのバージョンにアップグレードすることで、パネルロゴ、ウェルカムメッセージ、その他の情報のカスタマイズが可能になります。', monitor: diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index c7a6a7067..2d02d0cee 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -331,6 +331,7 @@ const message = { firewall: '방화벽', ssl: '인증서 | 인증서들', database: '데이터베이스 | 데이터베이스들', + ai_tools: 'AI', container: '컨테이너 | 컨테이너들', cronjob: '크론 작업 | 크론 작업들', host: '호스트 | 호스트들', @@ -588,6 +589,52 @@ const message = { '이 연결 주소는 컨테이너 외부 또는 외부 애플리케이션에서 실행 중인 애플리케이션에서 사용할 수 있습니다.', localIP: '로컬 IP', }, + ai_tools: { + model: { + model: '모델', + create: '모델 추가', + create_helper: 'Ollama.com에서 "{0}" 가져오기', + ollama_doc: 'Ollama 공식 웹사이트를 방문하여 더 많은 모델을 검색하고 찾을 수 있습니다.', + container_conn_helper: '컨테이너 간 접근 또는 연결에 이 주소를 사용', + }, + gpu: { + gpu: 'GPU 모니터', + base: '기본 정보', + gpuHelper: '현재 시스템에서 NVIDIA-SMI 또는 XPU-SMI 명령이 감지되지 않았습니다. 확인 후 다시 시도하세요!', + driverVersion: '드라이버 버전', + cudaVersion: 'CUDA 버전', + process: '프로세스 정보', + type: '유형', + typeG: '그래픽', + typeC: '연산', + typeCG: '연산 + 그래픽', + processName: '프로세스 이름', + processMemoryUsage: '메모리 사용량', + temperatureHelper: 'GPU 온도가 높으면 GPU 주파수 제한이 발생할 수 있습니다.', + performanceStateHelper: 'P0(최대 성능)부터 P12(최소 성능)까지', + busID: '버스 ID', + persistenceMode: '지속 모드', + enabled: '활성화됨', + disabled: '비활성화됨', + persistenceModeHelper: '지속 모드는 작업 응답 속도를 빠르게 하지만 대기 전력 소비를 증가시킵니다.', + displayActive: '그래픽 카드 초기화됨', + displayActiveT: '예', + displayActiveF: '아니요', + ecc: '오류 감지 및 수정 기술', + computeMode: '연산 모드', + default: '기본값', + exclusiveProcess: '단독 프로세스', + exclusiveThread: '단독 스레드', + prohibited: '금지됨', + defaultHelper: '기본값: 프로세스가 동시에 실행될 수 있음', + exclusiveProcessHelper: + '단독 프로세스: 하나의 CUDA 컨텍스트만 GPU 를 사용할 수 있지만, 여러 스레드에서 공유 가능', + exclusiveThreadHelper: '단독 스레드: CUDA 컨텍스트의 하나의 스레드만 GPU 를 사용할 수 있음', + prohibitedHelper: '금지됨: 프로세스가 동시에 실행되는 것이 허용되지 않음', + migModeHelper: '사용자 수준에서 GPU 를 물리적으로 분리하는 MIG 인스턴스를 생성하는 데 사용됩니다.', + migModeNA: '지원되지 않음', + }, + }, container: { create: '컨테이너 만들기', edit: '컨테이너 편집', @@ -1694,7 +1741,6 @@ const message = { introduce: '기능 소개', waf: '전문 버전으로 업그레이드하면 차단 맵, 로그, 차단 기록, 지리적 위치 차단, 사용자 정의 규칙, 사용자 정의 차단 페이지 등의 기능을 제공받을 수 있습니다.', tamper: '전문 버전으로 업그레이드하면 웹사이트를 무단 수정이나 변조로부터 보호할 수 있습니다.', - gpu: '전문 버전으로 업그레이드하면 GPU 의 작업 부하, 온도, 메모리 사용량 등 중요한 매개변수를 실시간으로 시각적으로 모니터링할 수 있습니다.', setting: '전문 버전으로 업그레이드하면 패널 로고, 환영 메시지 등 정보를 사용자 정의할 수 있습니다.', monitor: '전문 버전으로 업그레이드하면 웹사이트의 실시간 상태, 방문자 트렌드, 방문자 출처, 요청 로그 등 정보를 확인할 수 있습니다.', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index 61221938e..d641cdf3a 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -337,6 +337,7 @@ const message = { firewall: 'Firewall', ssl: 'Certificate | Certificates', database: 'Database | Databases', + ai_tools: 'AI', container: 'Container | Containers', cronjob: 'Cron Job | Cron Jobs', host: 'Host | Hosts', @@ -603,6 +604,53 @@ const message = { 'Alamat sambungan ini boleh digunakan oleh aplikasi yang berjalan di luar kontena atau aplikasi luaran.', localIP: 'IP Tempatan', }, + ai_tools: { + model: { + model: 'Model', + create: 'Tambah Model', + create_helper: 'Tarik "{0}" dari Ollama.com', + ollama_doc: 'Anda boleh melawat laman web rasmi Ollama untuk mencari dan menemui lebih banyak model.', + container_conn_helper: 'Gunakan alamat ini untuk akses atau sambungan antara kontena', + }, + gpu: { + gpu: 'Monitor GPU', + base: 'Maklumat Asas', + gpuHelper: 'Perintah NVIDIA-SMI atau XPU-SMI tidak dikesan pada sistem semasa. Sila periksa dan cuba lagi!', + driverVersion: 'Versi Pemacu', + cudaVersion: 'Versi CUDA', + process: 'Maklumat Proses', + type: 'Jenis', + typeG: 'Grafik', + typeC: 'Pengiraan', + typeCG: 'Pengiraan + Grafik', + processName: 'Nama Proses', + processMemoryUsage: 'Penggunaan Memori', + temperatureHelper: 'Suhu GPU yang tinggi boleh menyebabkan pelambatan frekuensi GPU', + performanceStateHelper: 'Dari P0 (prestasi maksimum) hingga P12 (prestasi minimum)', + busID: 'ID Bas', + persistenceMode: 'Mod Ketekalan', + enabled: 'Diaktifkan', + disabled: 'Dilumpuhkan', + persistenceModeHelper: + 'Mod ketekalan membolehkan respons tugas lebih cepat tetapi meningkatkan penggunaan kuasa sedia.', + displayActive: 'Kad Grafik Dimulakan', + displayActiveT: 'Ya', + displayActiveF: 'Tidak', + ecc: 'Teknologi Pemeriksaan dan Pembetulan Ralat', + computeMode: 'Mod Pengiraan', + default: 'Asal', + exclusiveProcess: 'Proses Eksklusif', + exclusiveThread: 'Thread Eksklusif', + prohibited: 'Dilarang', + defaultHelper: 'Asal: Proses boleh dilaksanakan secara serentak', + exclusiveProcessHelper: + 'Proses Eksklusif: Hanya satu konteks CUDA boleh menggunakan GPU, tetapi boleh dikongsi oleh berbilang thread', + exclusiveThreadHelper: 'Thread Eksklusif: Hanya satu thread dalam konteks CUDA boleh menggunakan GPU', + prohibitedHelper: 'Dilarang: Proses tidak dibenarkan dilaksanakan serentak', + migModeHelper: 'Digunakan untuk membuat contoh MIG bagi pengasingan fizikal GPU pada tahap pengguna.', + migModeNA: 'Tidak Disokong', + }, + }, container: { create: 'Cipta kontena', edit: 'Sunting kontena', @@ -1777,7 +1825,6 @@ const message = { introduce: 'Pengenalan Ciri', waf: 'Menaik taraf ke versi profesional boleh menyediakan ciri seperti peta pencegahan, log, rekod blok, sekatan lokasi geografi, peraturan tersuai, halaman pencegahan tersuai, dan sebagainya.', tamper: 'Menaik taraf ke versi profesional boleh melindungi laman web daripada pengubahsuaian atau manipulasi tanpa kebenaran.', - gpu: 'Menaik taraf ke versi profesional boleh membantu pengguna memantau parameter penting GPU secara visual seperti beban kerja, suhu, penggunaan memori secara masa nyata.', setting: 'Menaik taraf ke versi profesional membolehkan penyesuaian logo panel, mesej selamat datang, dan maklumat lain.', monitor: diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 124ba3d36..fd101a607 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -335,6 +335,7 @@ const message = { firewall: 'Firewall', ssl: 'Certificado | Certificados', database: 'Banco de Dados | Bancos de Dados', + ai_tools: 'AI', container: 'Container | Containers', cronjob: 'Tarefa Cron | Tarefas Cron', host: 'Host | Hosts', @@ -600,6 +601,54 @@ const message = { 'Este endereço de conexão pode ser utilizado por aplicações que estão fora do contêiner ou por aplicações externas.', localIP: 'IP local', }, + ai_tools: { + model: { + model: 'Modelo', + create: 'Adicionar Modelo', + create_helper: 'Puxar "{0}" do Ollama.com', + ollama_doc: 'Você pode visitar o site oficial da Ollama para pesquisar e encontrar mais modelos.', + container_conn_helper: 'Use este endereço para acesso ou conexão entre contêineres', + }, + gpu: { + gpu: 'Monitor de GPU', + base: 'Informações Básicas', + gpuHelper: + 'Comando NVIDIA-SMI ou XPU-SMI não detectado no sistema atual. Por favor, verifique e tente novamente!', + driverVersion: 'Versão do Driver', + cudaVersion: 'Versão do CUDA', + process: 'Informações do Processo', + type: 'Tipo', + typeG: 'Gráficos', + typeC: 'Cálculo', + typeCG: 'Cálculo + Gráficos', + processName: 'Nome do Processo', + processMemoryUsage: 'Uso de Memória', + temperatureHelper: 'Temperaturas altas da GPU podem causar limitação de frequência da GPU.', + performanceStateHelper: 'De P0 (máximo desempenho) a P12 (mínimo desempenho).', + busID: 'ID do Barramento', + persistenceMode: 'Modo de Persistência', + enabled: 'Ativado', + disabled: 'Desativado', + persistenceModeHelper: + 'O modo de persistência permite respostas mais rápidas às tarefas, mas aumenta o consumo de energia em standby.', + displayActive: 'Placa Gráfica Inicializada', + displayActiveT: 'Sim', + displayActiveF: 'Não', + ecc: 'Tecnologia de Correção e Verificação de Erros', + computeMode: 'Modo de Cálculo', + default: 'Padrão', + exclusiveProcess: 'Processo Exclusivo', + exclusiveThread: 'Thread Exclusivo', + prohibited: 'Proibido', + defaultHelper: 'Padrão: Processos podem ser executados simultaneamente.', + exclusiveProcessHelper: + 'Processo Exclusivo: Apenas um contexto CUDA pode usar a GPU, mas pode ser compartilhado por múltiplas threads.', + exclusiveThreadHelper: 'Thread Exclusivo: Apenas uma thread em um contexto CUDA pode usar a GPU.', + prohibitedHelper: 'Proibido: Não é permitido que processos sejam executados simultaneamente.', + migModeHelper: 'Usado para criar instâncias MIG para isolamento físico da GPU no nível do usuário.', + migModeNA: 'Não Suportado', + }, + }, container: { create: 'Criar contêiner', edit: 'Editar contêiner', @@ -1763,7 +1812,6 @@ const message = { introduce: 'Introdução de recursos', waf: 'O upgrade para a versão profissional pode fornecer recursos como mapa de intercepção, logs, registros de bloqueio, bloqueio por localização geográfica, regras personalizadas, páginas de intercepção personalizadas, etc.', tamper: 'O upgrade para a versão profissional pode proteger sites contra modificações ou adulterações não autorizadas.', - gpu: 'O upgrade para a versão profissional pode ajudar os usuários a monitorar visualmente parâmetros importantes da GPU, como carga de trabalho, temperatura e uso de memória em tempo real.', setting: 'O upgrade para a versão profissional permite a personalização do logo do painel, mensagem de boas-vindas e outras informações.', monitor: diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 24b266d84..9b147cdc4 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -332,6 +332,7 @@ const message = { firewall: 'Firewall', ssl: 'Сертификат | Сертификаты', database: 'База данных | Базы данных', + ai_tools: 'AI', container: 'Контейнер | Контейнеры', cronjob: 'Cron | Задачи Cron', host: 'Хост | Хосты', @@ -598,6 +599,54 @@ const message = { 'Этот адрес подключения может использоваться приложениями, работающими вне контейнера или внешними приложениями.', localIP: 'Локальный IP', }, + ai_tools: { + model: { + model: 'Модель', + create: 'Добавить модель', + create_helper: 'Загрузить "{0}" с Ollama.com', + ollama_doc: 'Вы можете посетить официальный сайт Ollama, чтобы искать и находить больше моделей.', + container_conn_helper: 'Используйте этот адрес для доступа или подключения между контейнерами', + }, + gpu: { + gpu: 'Мониторинг GPU', + base: 'Основная информация', + gpuHelper: 'Команда NVIDIA-SMI или XPU-SMI не обнаружена в текущей системе. Проверьте и попробуйте снова!', + driverVersion: 'Версия драйвера', + cudaVersion: 'Версия CUDA', + process: 'Информация о процессе', + type: 'Тип', + typeG: 'Графика', + typeC: 'Вычисления', + typeCG: 'Вычисления + Графика', + processName: 'Имя процесса', + processMemoryUsage: 'Использование памяти', + temperatureHelper: 'Высокая температура GPU может вызвать снижение частоты GPU', + performanceStateHelper: 'От P0 (максимальная производительность) до P12 (минимальная производительность)', + busID: 'ID шины', + persistenceMode: 'Режим постоянства', + enabled: 'Включен', + disabled: 'Выключен', + persistenceModeHelper: + 'Режим постоянства позволяет быстрее реагировать на задачи, но увеличивает потребление энергии в режиме ожидания.', + displayActive: 'Инициализация видеокарты', + displayActiveT: 'Да', + displayActiveF: 'Нет', + ecc: 'Технология проверки и коррекции ошибок (ECC)', + computeMode: 'Режим вычислений', + default: 'По умолчанию', + exclusiveProcess: 'Исключительный процесс', + exclusiveThread: 'Исключительный поток', + prohibited: 'Запрещено', + defaultHelper: 'По умолчанию: процессы могут выполняться одновременно', + exclusiveProcessHelper: + 'Исключительный процесс: только один контекст CUDA может использовать GPU, но его могут разделять несколько потоков', + exclusiveThreadHelper: 'Исключительный поток: только один поток в контексте CUDA может использовать GPU', + prohibitedHelper: 'Запрещено: процессам не разрешено выполняться одновременно', + migModeHelper: + 'Используется для создания MIG-инстансов для физической изоляции GPU на уровне пользователя.', + migModeNA: 'Не поддерживается', + }, + }, container: { create: 'Создать контейнер', edit: 'Редактировать контейнер', @@ -1762,7 +1811,6 @@ const message = { introduce: 'Описание функций', waf: 'Обновление до профессиональной версии предоставляет такие функции, как карта перехватов, логи, записи блокировок, блокировка по географическому положению, пользовательские правила, пользовательские страницы перехвата и т.д.', tamper: 'Обновление до профессиональной версии может защитить веб-сайты от несанкционированных изменений или подделок.', - gpu: 'Обновление до профессиональной версии помогает пользователям визуально отслеживать важные параметры GPU, такие как нагрузка, температура, использование памяти в реальном времени.', setting: 'Обновление до профессиональной версии позволяет настраивать логотип панели, приветственное сообщение и другую информацию.', monitor: diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 0a2772e24..1b8155548 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -324,6 +324,7 @@ const message = { firewall: '防火牆', ssl: '證書', database: '資料庫', + ai_tools: 'AI', container: '容器', cronjob: '計劃任務', host: '主機', @@ -573,6 +574,51 @@ const message = { remoteConnHelper2: '非容器或外部連接使用此地址', localIP: '本機 IP', }, + ai_tools: { + model: { + model: '模型', + create: '添加模型', + create_helper: '從 Ollama.com 拉取 "{0}"', + ollama_doc: '您可以訪問 Ollama 官方網站,搜索並查找更多模型。', + container_conn_helper: '容器間訪問或連接使用此地址', + }, + gpu: { + gpu: 'GPU 监控', + base: '基礎資訊', + gpuHelper: '目前系統未檢測到 NVIDIA-SMI或者XPU-SMI 指令,請檢查後重試!', + driverVersion: '驅動版本', + cudaVersion: 'CUDA 版本', + process: '行程資訊', + type: '類型', + typeG: '圖形', + typeC: '計算', + typeCG: '計算+圖形', + processName: '行程名稱', + processMemoryUsage: '顯存使用', + temperatureHelper: 'GPU 溫度過高會導致 GPU 頻率下降', + performanceStateHelper: '從 P0 (最大性能) 到 P12 (最小性能)', + busID: '總線地址', + persistenceMode: '持續模式', + enabled: '開啟', + disabled: '關閉', + persistenceModeHelper: '持續模式能更加快速地響應任務,但相應待機功耗也會增加', + displayActive: '顯卡初始化', + displayActiveT: '是', + displayActiveF: '否', + ecc: '是否開啟錯誤檢查和紀正技術', + computeMode: '計算模式', + default: '預設', + exclusiveProcess: '行程排他', + exclusiveThread: '線程排他', + prohibited: '禁止', + defaultHelper: '預設: 行程可以並發執行', + exclusiveProcessHelper: '行程排他: 只有一個 CUDA 上下文可以使用 GPU, 但可以由多個線程共享', + exclusiveThreadHelper: '線程排他: 只有一個線程在 CUDA 上下文中可以使用 GPU', + prohibitedHelper: '禁止: 不允許行程同時執行', + migModeHelper: '用於建立 MIG 實例,在用戶層實現 GPU 的物理隔離。', + migModeNA: '不支援', + }, + }, container: { create: '建立容器', edit: '編輯容器', @@ -1636,7 +1682,6 @@ const message = { introduce: '功能介紹', waf: '升級專業版可以獲得攔截地圖、日誌、封鎖記錄、地理位置封禁、自訂規則、自訂攔截頁面等功能。', tamper: '升級專業版可以保護網站免受未經授權的修改或篡改。', - gpu: '升級專業版可以幫助用戶即時直觀查看到 GPU 的工作負載、溫度、記憶體等重要參數。', setting: '升級專業版可以自訂面板 Logo、歡迎簡介等資訊。', monitor: '升級專業版可以查看網站的即時狀態、訪客趨勢、訪客來源、請求日誌等資訊。 ', alert: '升級專業版可透過簡訊接收告警資訊,並查看告警日誌,全面掌控各類關鍵事件,確保系統執行無憂。', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 4c064936f..cd79a4ddc 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -579,7 +579,9 @@ const message = { model: { model: '模型', create: '添加模型', - create_helper: '查找需要添加的模型', + create_helper: '从 Ollama.com 拉取 "{0}"', + ollama_doc: '您可以访问 Ollama 官网,搜索并查找更多模型。', + container_conn_helper: '容器间访问或连接使用此地址', }, gpu: { gpu: 'GPU 监控', @@ -1681,7 +1683,6 @@ const message = { introduce: '功能介绍', waf: '升级专业版可以获得拦截地图、日志、封锁记录、地理位置封禁、自定义规则、自定义拦截页面等功能。', tamper: '升级专业版可以保护网站免受未经授权的修改或篡改。', - gpu: '升级专业版可以帮助用户实时直观查看到 GPU 的工作负载、温度、显存等重要参数。', setting: '升级专业版可以自定义面板 Logo、欢迎简介等信息。', monitor: '升级专业版可以查看网站的实时状态、访客趋势、访客来源、请求日志等信息。', alert: '升级专业版可通过短信接收告警信息,并查看告警日志,全面掌控各类关键事件,确保系统运行无忧。', diff --git a/frontend/src/routers/modules/ai-tool.ts b/frontend/src/routers/modules/ai-tool.ts index 5183eb0ae..4875402c0 100644 --- a/frontend/src/routers/modules/ai-tool.ts +++ b/frontend/src/routers/modules/ai-tool.ts @@ -6,7 +6,7 @@ const databaseRouter = { component: Layout, redirect: '/ai-tools/model', meta: { - icon: 'p-database', + icon: 'p-jiqiren2', title: 'menu.ai_tools', }, children: [ diff --git a/frontend/src/views/ai-tools/model/add/index.vue b/frontend/src/views/ai-tools/model/add/index.vue index 15640e758..9583837a2 100644 --- a/frontend/src/views/ai-tools/model/add/index.vue +++ b/frontend/src/views/ai-tools/model/add/index.vue @@ -4,7 +4,7 @@ :destroy-on-close="true" :close-on-click-modal="false" :close-on-press-escape="false" - size="30%" + size="40%" > -