feat: support load ollama model details (#7867)

This commit is contained in:
ssongliu
2025-02-13 14:56:24 +00:00
committed by GitHub
parent 0741f60896
commit c709e48ceb
24 changed files with 589 additions and 77 deletions
+24
View File
@@ -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 {
+28
View File
@@ -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
+3 -5
View File
@@ -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 {
+1
View File
@@ -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)
}
+3
View File
@@ -11,6 +11,9 @@ export const deleteOllamaModel = (name: string) => {
export const searchOllamaModel = (params: AITool.OllamaModelSearch) => {
return http.post<ResPage<AITool.OllamaModelInfo>>(`/aitools/ollama/model/search`, params);
};
export const loadOllamaModel = (name: string) => {
return http.post<string>(`/aitools/ollama/model/load`, { name: name });
};
export const loadGPUInfo = () => {
return http.get<any>(`/aitools/gpu/load`);
+8 -12
View File
@@ -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";
}
File diff suppressed because one or more lines are too long
+7 -14
View File
@@ -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": "监控",
+2 -4
View File
@@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="jiqiren2" unicode="&#58899;" d="M554.667 533.333h-320V64h554.666V533.333H554.667z m-85.334 85.334V704H448a21.333 21.333 0 0 0-21.333 21.333V810.667A21.333 21.333 0 0 0 448 832h128a21.333 21.333 0 0 0 21.333-21.333v-85.334A21.333 21.333 0 0 0 576 704h-21.333v-85.333H832A42.667 42.667 0 0 0 874.667 576v-554.667A42.667 42.667 0 0 0 832-21.333H192a42.667 42.667 0 0 0-42.667 42.666V576A42.667 42.667 0 0 0 192 618.667h277.333zM21.333 384H64a21.333 21.333 0 0 0 21.333-21.333v-128A21.333 21.333 0 0 0 64 213.333H21.333A21.333 21.333 0 0 0 0 234.667v128A21.333 21.333 0 0 0 21.333 384zM320 362.667h128v-128H320v128z m256 0h128v-128H576v128zM960 384h42.667A21.333 21.333 0 0 0 1024 362.667v-128a21.333 21.333 0 0 0-21.333-21.334H960a21.333 21.333 0 0 0-21.333 21.334v128A21.333 21.333 0 0 0 960 384z" horiz-adv-x="1024" />
<glyph glyph-name="alert-3" unicode="&#59176;" d="M334.506667 364.495238a97.562819 97.562819 0 1 0 0 39.009524H863.085714a19.504762 19.504762 0 1 0 0-39.009524H334.506667z m354.986666-273.066666H160.914286a19.504762 19.504762 0 1 0 0 39.009523h528.579047a97.523809 97.523809 0 1 0 0-39.009523z m0 546.133333H160.914286a19.504762 19.504762 0 0 0 0 39.009523h528.579047a97.523809 97.523809 0 1 0 0-39.009523zM843.580953 657.066667a58.514286 58.514286 0 1 1-117.028572 0 58.514286 58.514286 0 0 1 117.028572 0z m0-546.133334a58.514286 58.514286 0 1 1-117.028572 0 58.514286 58.514286 0 0 1 117.028572 0z m-546.133334 273.066667a58.514286 58.514286 0 1 1-117.028572 0 58.514286 58.514286 0 0 1 117.028572 0z" horiz-adv-x="1024" />
<glyph glyph-name="tongyijiancha" unicode="&#58905;" d="M464 704a270.95 270.95 0 1 0-105.85-21.35A270.24 270.24 0 0 0 464 704m0 64c-185.57 0-336-150.43-336-336s150.43-336 336-336 336 150.43 336 336-150.43 336-336 336zM710.63 230.63l-45.26-45.26L850.75 0 896 45.25 710.63 230.63zM604.97 569.94L419.6 384.57l-96.57 96.57-45.26-45.26 96.57-96.57 45.26-45.25 45.25 45.25 185.38 185.38-45.26 45.25z" horiz-adv-x="1024" />
@@ -92,10 +94,6 @@
<glyph glyph-name="xpack" unicode="&#58884;" d="M971.527 503.922L839.149 726.406c-5.729 11.652-17.836 20.114-32.248 20.114H217.227v-0.442c-12.134 0-24.007-5.962-30.647-17.394L54.201 506.903c-10.077-14.177-8.931-33.836 3.645-46.178l428.043-428.499 1.133-0.456c13.943-13.722 36.362-13.722 50.306 0l428.707 428.955h-0.222c11.43 11.431 14.412 29.267 5.714 43.197zM760.032 674.968l-85.743-140.632a47.989 47.989 0 0 1-3.789 0.164c-2.771 0-5.48-0.25-8.12-0.706l-98.988 141.174h196.64z m-132.05-166.793c-0.136-0.271-0.273-0.541-0.404-0.815H401.421a47.213 47.213 0 0 1-2.563 4.683l113.537 161.311 115.587-165.179zM460.736 674.968l-98.403-140.636a48.105 48.105 0 0 1-3.833 0.167c-2.775 0-5.49-0.251-8.135-0.708l-86.504 141.176h196.875z m-234.605-19.45l89.842-147.361c-0.132-0.265-0.267-0.528-0.394-0.796h-178.16l88.712 148.157zM154.799 464.37h161.928c6.511-11.994 18.04-20.861 31.767-23.805l98.051-267.719L154.799 464.37z m357.597-345.475L390.021 451.478a47.675 47.675 0 0 1 10.252 12.892h228.454a47.625 47.625 0 0 1 6.843-9.55L512.396 118.89499999999998z m64.939 53.951l97.977 266.896c15.992 1.609 29.644 11.149 36.962 24.628h156.364L577.335 172.846zM713.422 507.36a47.323 47.323 0 0 1-2.727 4.938l87.756 143.22 88.022-148.158H713.422z" horiz-adv-x="1024" />
<glyph glyph-name="gpu-2" unicode="&#59096;" d="M392.585795 223.71443399999998l-93.230358 0c-14.145162 0-25.611308-11.466146-25.611308-25.611308s11.467169-25.611308 25.611308-25.611308l93.230358 0c14.145162 0 25.611308 11.466146 25.611308 25.611308S406.729933 223.71443399999998 392.585795 223.71443399999998zM392.585795 103.84434599999997l-93.230358 0c-14.145162 0-25.611308-11.466146-25.611308-25.611308s11.467169-25.611308 25.611308-25.611308l93.230358 0c14.145162 0 25.611308 11.466146 25.611308 25.611308S406.729933 103.84434599999997 392.585795 103.84434599999997zM392.585795 330.26312199999995l-93.230358 0c-14.145162 0-25.611308-11.466146-25.611308-25.611308s11.467169-25.611308 25.611308-25.611308l93.230358 0c14.145162 0 25.611308 11.466146 25.611308 25.611308S406.729933 330.26312199999995 392.585795 330.26312199999995zM473.523175 304.65181399999994c0-14.145162 11.467169-25.611308 25.611308-25.611308l226.416729 0c14.145162 0 25.611308 11.466146 25.611308 25.611308s-11.466146 25.611308-25.611308 25.611308l-226.416729 0C484.990345 330.26312199999995 473.523175 318.796976 473.523175 304.65181399999994zM852.245729 471.110987c-54.019311 71.51887-226.167043 271.164886-294.330492 347.954807-2.820232 3.175319-6.088672 5.656837-9.639544 7.385201l-2.437515 2.849908-9.704013 0c-0.049119 0-0.097214 0.004093-0.146333 0.004093-0.039909 0-0.079818-0.004093-0.12075-0.004093L213.635123 829.300902c-15.878642 0-32.363082-6.886851-45.228087-18.896372-13.467733-12.571317-21.190625-29.167297-21.190625-45.533033L147.216411 5.710303999999951c0-16.116049 7.467065-32.885991 20.48659-46.007847 13.072737-13.175067 29.815049-20.732184 45.933145-20.732184l602.350774 0c16.676821 0 33.07428 8.121981 44.989657 22.281469 10.622942 12.624529 16.714683 28.828582 16.714683 44.457538L877.691261 441.366545 852.245729 471.110987zM559.654858 734.350366l239.987816-280.545534L563.927161 453.804832c-2.067079 3.163039-4.272303 9.214872-4.272303 13.115716L559.654858 734.350366zM826.467623 5.710303999999951c0-7.726985-7.185656-15.516392-10.480702-15.516392L213.635123-9.806087000000048c-5.396917 0-15.196097 10.005888-15.196097 15.516392L198.439026 764.87252c0 4.66423 8.933463 13.205766 15.196097 13.205766l294.79712 0 0-311.158762c0-26.295899 18.24555-64.339354 51.235918-64.339354l266.799462 0L826.467623 5.710303999999951zM430.875866 634.92696L297.690518 634.92696c-14.145162 0-25.611308-11.467169-25.611308-25.611308l0-133.186372c0-14.145162 11.467169-25.612331 25.611308-25.612331l133.185348 0c14.145162 0 25.611308 11.467169 25.611308 25.612331L456.487174 609.314629C456.487174 623.45979 445.021028 634.92696 430.875866 634.92696zM405.264559 501.739565l-81.962733 0 0 81.963757 81.962733 0L405.264559 501.739565zM725.551212 223.71443399999998l-226.416729 0c-14.145162 0-25.611308-11.466146-25.611308-25.611308s11.467169-25.611308 25.611308-25.611308l226.416729 0c14.145162 0 25.611308 11.466146 25.611308 25.611308S739.697397 223.71443399999998 725.551212 223.71443399999998zM725.551212 103.84434599999997l-226.416729 0c-14.145162 0-25.611308-11.466146-25.611308-25.611308s11.467169-25.611308 25.611308-25.611308l226.416729 0c14.145162 0 25.611308 11.466146 25.611308 25.611308S739.697397 103.84434599999997 725.551212 103.84434599999997z" horiz-adv-x="1024" />
<glyph glyph-name="gpu-1" unicode="&#58915;" d="M838.22 139.59000000000003H187.78a89.1 89.1 0 0 0-89.1 89.1V697.46a89.1 89.1 0 0 0 89.1 89.1h650.44a89.1 89.1 0 0 0 89.1-89.1v-468.77a89.1 89.1 0 0 0-89.1-89.1zM852 224.64999999999998V701.5a9 9 0 0 1-9 8.95H183a9 9 0 0 1-9-8.95v-476.85a9 9 0 0 1 9-8.94h660a9 9 0 0 1 9 8.94zM287.01 63.48000000000002m37.86 0l376.26 0q37.86 0 37.86-37.86l0-0.39q0-37.86-37.86-37.86l-376.26 0q-37.86 0-37.86 37.86l0 0.39q0 37.86 37.86 37.86ZM249.34 558.22m31.68 0l11.97 0q31.68 0 31.68-31.68l0-203.04q0-31.68-31.68-31.68l-11.97 0q-31.68 0-31.68 31.68l0 203.04q0 31.68 31.68 31.68ZM400 444.05m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-76.89q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 76.89q0 37.67 37.67 37.67ZM550.67 634.3299999999999m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-267.17q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 267.17q0 37.67 37.67 37.67ZM701.33 482.11m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-114.94q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 114.94q0 37.67 37.67 37.67Z" horiz-adv-x="1024" />
<glyph glyph-name="monitor-4" unicode="&#60494;" d="M838.22 139.59000000000003H187.78a89.1 89.1 0 0 0-89.1 89.1V697.46a89.1 89.1 0 0 0 89.1 89.1h650.44a89.1 89.1 0 0 0 89.1-89.1v-468.77a89.1 89.1 0 0 0-89.1-89.1zM852 224.64999999999998V701.5a9 9 0 0 1-9 8.95H183a9 9 0 0 1-9-8.95v-476.85a9 9 0 0 1 9-8.94h660a9 9 0 0 1 9 8.94zM287.01 63.48000000000002m37.86 0l376.26 0q37.86 0 37.86-37.86l0-0.39q0-37.86-37.86-37.86l-376.26 0q-37.86 0-37.86 37.86l0 0.39q0 37.86 37.86 37.86ZM249.34 558.22m31.68 0l11.97 0q31.68 0 31.68-31.68l0-203.04q0-31.68-31.68-31.68l-11.97 0q-31.68 0-31.68 31.68l0 203.04q0 31.68 31.68 31.68ZM400 444.05m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-76.89q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 76.89q0 37.67 37.67 37.67ZM550.67 634.3299999999999m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-267.17q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 267.17q0 37.67 37.67 37.67ZM701.33 482.11m37.67 0l-0.01 0q37.67 0 37.67-37.67l0-114.94q0-37.67-37.67-37.67l0.01 0q-37.67 0-37.67 37.67l0 114.94q0 37.67 37.67 37.67Z" horiz-adv-x="1024" />
<glyph glyph-name="waf-4" unicode="&#58888;" d="M136.533333 759.466667h546.133334v-68.266667H136.533333zM136.533333 622.933333h546.133334v-68.266666H136.533333zM136.533333 486.4h546.133334v-68.266667H136.533333zM136.533333 349.866667h68.266667v-68.266667H136.533333zM136.533333 213.33333300000004h68.266667v-68.266666H136.533333zM466.261333 55.63733300000001h68.266667L546.133333 8.53333299999997h43.690667l-68.266667 204.8H477.866667l-68.266667-204.8h43.008z m30.037334 105.130667a81.92 81.92 0 0 1 0 17.066667 84.650667 84.650667 0 0 1 0-17.749334l21.162666-68.266666H477.866667zM691.541333 8.53333299999997a115.370667 115.370667 0 0 1 53.248 10.922667v38.912a84.650667 84.650667 0 0 0-45.738666-12.970667 53.248 53.248 0 0 0-42.325334 17.749334 68.266667 68.266667 0 0 0-15.701333 47.104 68.266667 68.266667 0 0 0 16.384 48.469333 55.296 55.296 0 0 0 43.690667 18.432 79.872 79.872 0 0 0 43.008-11.605333v40.96a121.514667 121.514667 0 0 1-45.738667 7.509333 92.842667 92.842667 0 0 1-68.266667-30.037333 108.544 108.544 0 0 1-27.989333-76.458667 101.034667 101.034667 0 0 1 24.576-68.266667 86.698667 86.698667 0 0 1 64.853333-30.72zM887.466667 44.03200000000004h-69.632V213.33333300000004h-40.277334v-204.8H887.466667v35.498667zM819.2 349.866667V896H0v-1024h1024V349.866667zM68.266667-59.733333000000016V827.733333h682.666666v-477.866666H273.066667v-409.6z m887.466666 0H341.333333V281.6h614.4z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+48 -1
View File
@@ -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:
+48 -1
View File
@@ -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:
+47 -1
View File
@@ -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:
'전문 버전으로 업그레이드하면 웹사이트의 실시간 상태, 방문자 트렌드, 방문자 출처, 요청 로그 등 정보를 확인할 수 있습니다.',
+48 -1
View File
@@ -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:
+49 -1
View File
@@ -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:
+49 -1
View File
@@ -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:
+46 -1
View File
@@ -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: '升級專業版可透過簡訊接收告警資訊並查看告警日誌全面掌控各類關鍵事件確保系統執行無憂',
+3 -2
View File
@@ -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: '升级专业版可通过短信接收告警信息并查看告警日志全面掌控各类关键事件确保系统运行无忧',
+1 -1
View File
@@ -6,7 +6,7 @@ const databaseRouter = {
component: Layout,
redirect: '/ai-tools/model',
meta: {
icon: 'p-database',
icon: 'p-jiqiren2',
title: 'menu.ai_tools',
},
children: [
@@ -4,7 +4,7 @@
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
size="40%"
>
<template #header>
<DrawerHeader :header="$t('ai_tools.model.create')" :back="handleClose" />
@@ -14,18 +14,22 @@
<el-alert type="info" :closable="false">
<template #title>
<span class="flx-align-center">
{{ $t('ai_tools.model.create_helper') }}
{{ $t('ai_tools.model.ollama_doc') }}
<el-link class="ml-5" icon="Position" @click="goSearch()" type="primary">
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</template>
</el-alert>
<el-form ref="formRef" label-position="top" :model="form">
<el-form ref="formRef" label-position="top" class="mt-5" :model="form">
<el-form-item :label="$t('commons.table.name')" :rules="Rules.requiredInput" prop="name">
<el-input v-model.trim="form.name" />
<span class="input-help" v-if="form.name">
ollama pull {{ form.name.replaceAll('ollama run ', '').replaceAll('ollama pull ', '') }}
{{
$t('ai_tools.model.create_helper', [
form.name.replaceAll('ollama run ', '').replaceAll('ollama pull ', ''),
])
}}
</span>
</el-form-item>
</el-form>
@@ -0,0 +1,116 @@
<template>
<el-drawer
v-model="dialogVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="30%"
>
<template #header>
<DrawerHeader :header="$t('database.databaseConnInfo')" :back="handleClose" />
</template>
<el-form @submit.prevent v-loading="loading" :model="form" label-position="top">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('database.containerConn')">
<el-card class="mini-border-card">
<el-descriptions :column="1">
<el-descriptions-item :label="$t('database.connAddress')">
{{ form.containerName }}
<CopyButton :content="form.containerName" type="icon" />
</el-descriptions-item>
<el-descriptions-item :label="$t('database.connPort')">
11434
<CopyButton content="11434" type="icon" />
</el-descriptions-item>
</el-descriptions>
</el-card>
<span class="input-help">
{{ $t('ai_tools.model.container_conn_helper') }}
</span>
</el-form-item>
<el-form-item :label="$t('database.remoteConn')">
<el-card class="mini-border-card">
<el-descriptions :column="1">
<el-descriptions-item :label="$t('database.connAddress')">
{{ form.systemIP }}
<CopyButton :content="form.systemIP" type="icon" />
</el-descriptions-item>
<el-descriptions-item :label="$t('database.connPort')">
{{ form.port }}
<CopyButton :content="form.port + ''" type="icon" />
</el-descriptions-item>
</el-descriptions>
</el-card>
<span class="input-help">
{{ $t('database.remoteConnHelper2') }}
</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="dialogVisible = false">
{{ $t('commons.button.cancel') }}
</el-button>
</span>
</template>
</el-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { getSettingInfo } from '@/api/modules/setting';
const loading = ref(false);
const dialogVisible = ref(false);
const form = reactive({
systemIP: '',
containerName: '',
port: 0,
remoteIP: '',
});
interface DialogProps {
port: number;
containerName: string;
}
const acceptParams = (param: DialogProps): void => {
form.containerName = param.containerName;
form.port = param.port;
loadSystemIP();
dialogVisible.value = true;
};
const handleClose = () => {
dialogVisible.value = false;
};
const loadSystemIP = async () => {
const res = await getSettingInfo();
form.systemIP = res.data.systemIP || i18n.global.t('database.localIP');
};
defineExpose({
acceptParams,
});
</script>
<style lang="scss" scoped>
.copy_button {
border-radius: 0px;
border-left-width: 0px;
}
:deep(.el-input__wrapper) {
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
</style>
+49 -27
View File
@@ -19,23 +19,31 @@
ref="appStatusRef"
></AppStatus>
</template>
<template #toolbar>
<template #toolbar v-if="modelInfo.isExist">
<div class="flex justify-between gap-2 flex-wrap sm:flex-row">
<div class="flex flex-wrap gap-3">
<el-button v-if="modelInfo.status === 'Running'" type="primary" @click="onCreate()">
<el-button :disabled="modelInfo.status !== 'Running'" type="primary" @click="onCreate()">
{{ $t('ai_tools.model.create') }}
</el-button>
<!-- <el-button @click="onLoadConn" type="primary" plain>
<el-button :disabled="modelInfo.status !== 'Running'" @click="onLoadConn" type="primary" plain>
{{ $t('database.databaseConnInfo') }}
</el-button> -->
<el-button icon="Position" @click="goDashboard()" type="primary" plain>OpenWebUI</el-button>
</el-button>
<el-button
:disabled="modelInfo.status !== 'Running'"
icon="Position"
@click="goDashboard()"
type="primary"
plain
>
OpenWebUI
</el-button>
</div>
<div>
<TableSearch @search="search()" v-model:searchName="searchName" />
</div>
</div>
</template>
<template #main>
<template #main v-if="modelInfo.isExist">
<ComplexTable
:pagination-config="paginationConfig"
:class="{ mask: maskShow }"
@@ -43,7 +51,13 @@
@search="search"
:data="data"
>
<el-table-column :label="$t('commons.table.name')" prop="name" min-width="90" />
<el-table-column :label="$t('commons.table.name')" prop="name" min-width="90">
<template #default="{ row }">
<el-text type="primary" class="cursor-pointer" @click="onLoad(row.name)">
{{ row.name }}
</el-text>
</template>
</el-table-column>
<el-table-column :label="$t('file.size')" prop="size" />
<el-table-column :label="$t('commons.button.log')">
<template #default="{ row }">
@@ -65,29 +79,12 @@
</template>
</LayoutContent>
<el-card v-if="modelInfo.status != 'Running' && !loading && maskShow" class="mask-prompt">
<el-card v-if="modelInfo.isExist && modelInfo.status != 'Running' && !loading && maskShow" class="mask-prompt">
<span>
{{ $t('commons.service.serviceNotStarted', ['Ollama']) }}
</span>
</el-card>
<LayoutContent v-if="!modelInfo.isExist && !loading" title="Ollama" :divider="true">
<template #main>
<div class="app-warn">
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
<span>{{ $t('app.checkInstalledWarn', [$t('database.noMysql')]) }}</span>
<span @click="goInstall('ollama')" class="flex items-center justify-center gap-0.5">
<el-icon><Position /></el-icon>
{{ $t('database.goInstall') }}
</span>
</div>
<div>
<img src="@/assets/images/no_app.svg" />
</div>
</div>
</template>
</LayoutContent>
<el-dialog
v-model="dashboardVisible"
:title="$t('app.checkTitle')"
@@ -110,6 +107,8 @@
<AddDialog ref="addRef" @search="search" @log="onLoadLog" />
<Log ref="logRef" @close="search" />
<Conn ref="connRef" />
<CodemirrorDialog ref="detailRef" />
<PortJumpDialog ref="dialogPortJumpRef" />
</div>
</template>
@@ -117,13 +116,15 @@
<script lang="ts" setup>
import AppStatus from '@/components/app-status/index.vue';
import AddDialog from '@/views/ai-tools/model/add/index.vue';
import Conn from '@/views/ai-tools/model/conn/index.vue';
import Log from '@/components/log-dialog/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
import { computed, onMounted, reactive, ref } from 'vue';
import i18n from '@/lang';
import { App } from '@/api/interface/app';
import { GlobalStore } from '@/store';
import { deleteOllamaModel, searchOllamaModel } from '@/api/modules/ai-tool';
import { deleteOllamaModel, loadOllamaModel, searchOllamaModel } from '@/api/modules/ai-tool';
import { AITool } from '@/api/interface/ai-tool';
import { GetAppPort } from '@/api/modules/app';
import router from '@/routers';
@@ -135,6 +136,8 @@ const maskShow = ref(true);
const addRef = ref();
const logRef = ref();
const detailRef = ref();
const connRef = ref();
const openWebUIPort = ref();
const dashboardVisible = ref(false);
const dialogPortJumpRef = ref();
@@ -155,6 +158,7 @@ const modelInfo = reactive({
container: '',
isExist: null,
version: '',
port: 11434,
});
const mobile = computed(() => {
@@ -183,6 +187,20 @@ const onCreate = async () => {
addRef.value.acceptParams();
};
const onLoadConn = async () => {
connRef.value.acceptParams({ port: modelInfo.port, containerName: modelInfo.container });
};
const onLoad = async (name: string) => {
const res = await loadOllamaModel(name);
let detailInfo = res.data;
let param = {
header: i18n.global.t('commons.button.view'),
detailInfo: detailInfo,
};
detailRef.value!.acceptParams(param);
};
const goDashboard = async () => {
if (openWebUIPort.value === 0) {
dashboardVisible.value = true;
@@ -205,6 +223,11 @@ const checkExist = (data: App.CheckInstalled) => {
modelInfo.status = data.status;
modelInfo.version = data.version;
modelInfo.container = data.containerName;
modelInfo.port = data.httpPort;
if (modelInfo.isExist && modelInfo.status === 'Running') {
search();
}
};
const onDelete = async (row: AITool.OllamaModelInfo) => {
@@ -240,7 +263,6 @@ const buttons = [
];
onMounted(() => {
search();
loadWebUIPort();
});
</script>