feat: Added partial prompt messages (#7900)
Some checks failed
SonarCloud Scan / SonarCloud (push) Failing after -6s

This commit is contained in:
zhengkunwang 2025-02-18 18:08:52 +08:00 committed by GitHub
parent 0c68f16a66
commit ea1261b48e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 101 additions and 25 deletions

View file

@ -92,9 +92,10 @@ type AppInstalledDTO struct {
}
type AppDetail struct {
Website string `json:"website"`
Document string `json:"document"`
Github string `json:"github"`
Website string `json:"website"`
Document string `json:"document"`
Github string `json:"github"`
GpuSupport bool `json:"gpuSupport"`
}
type AppInstallDTO struct {

View file

@ -750,6 +750,7 @@ func (a *AppInstallService) GetParams(id uint) (*response.AppConfig, error) {
}
res.AppContainerConfig = config
res.HostMode = isHostModel(install.DockerCompose)
res.GpuConfig = isGpuConfig(install.DockerCompose)
return &res, nil
}

View file

@ -1338,9 +1338,10 @@ func handleInstalled(appInstallList []model.AppInstall, updated bool, sync bool)
Path: installed.GetPath(),
CreatedAt: installed.CreatedAt,
App: response.AppDetail{
Github: installed.App.Github,
Website: installed.App.Website,
Document: installed.App.Document,
Github: installed.App.Github,
Website: installed.App.Website,
Document: installed.App.Document,
GpuSupport: installed.App.GpuSupport,
},
}
if updated {
@ -1509,6 +1510,8 @@ func addDockerComposeCommonParam(composeMap map[string]interface{}, serviceName
},
},
}
} else {
delete(resource, "reservations")
}
ports, ok := serviceValue["ports"].([]interface{})
@ -1612,6 +1615,33 @@ func isHostModel(dockerCompose string) bool {
return false
}
func isGpuConfig(dockerCompose string) bool {
composeMap := make(map[string]interface{})
_ = yaml.Unmarshal([]byte(dockerCompose), &composeMap)
services, serviceValid := composeMap["services"].(map[string]interface{})
if !serviceValid {
return false
}
for _, service := range services {
serviceValue := service.(map[string]interface{})
deploy := map[string]interface{}{}
if de, ok := serviceValue["deploy"]; ok {
deploy = de.(map[string]interface{})
}
resource := map[string]interface{}{}
if res, ok := deploy["resources"]; ok {
resource = res.(map[string]interface{})
}
if reservations, ok := resource["reservations"]; ok {
reservationsMap := reservations.(map[string]interface{})
if _, dOk := reservationsMap["devices"]; dOk {
return true
}
}
}
return false
}
func RequestDownloadCallBack(downloadCallBackUrl string) {
if downloadCallBackUrl == "" {
return

View file

@ -242,6 +242,7 @@ export namespace App {
allowPort: boolean;
dockerCompose: string;
hostMode?: boolean;
gpuConfig?: boolean;
}
export interface IgnoredApp {

View file

@ -1979,8 +1979,7 @@ const message = {
pullImage: 'Pull Image',
pullImageHelper: 'Execute docker pull to pull the image before the application starts',
gpuConfig: 'GPU Acceleration',
gpuConfigHelper:
'Please ensure that the server has NVIDIA drivers and NVIDIA Container Toolkit installed',
gpuConfigHelper: 'Please ensure that the server has NVIDIA drivers and NVIDIA Container Toolkit installed',
},
website: {
website: 'Website | Websites',
@ -2591,6 +2590,7 @@ const message = {
proxyHelper4: 'Once created, you can view and manage it in the website list',
proxyHelper5:
'After enabling, you can disable external access to the port in the App Store - Installed - Ollama - Parameters to improve security.',
proxyHelper6: 'To disable proxy configuration, you can delete it from the website list.',
},
};

View file

@ -2559,6 +2559,7 @@ const message = {
proxyHelper4: '作成後ウェブサイトリストで確認および管理できます',
proxyHelper5:
'有効にするとアプリストア - インストール済み - Ollama - パラメータでポートの外部アクセスを無効にしセキュリティを向上させることができます',
proxyHelper6: 'プロキシ設定を無効にするにはウェブサイトリストから削除できます',
},
};
export default {

View file

@ -1920,8 +1920,7 @@ const message = {
pullImage: '이미지 ',
pullImageHelper: '애플리케이션 시작 전에 docker pull 실행하여 이미지를 다운로드하세요.',
gpuConfig: 'GPU 가속',
gpuConfigHelper:
'서버에 NVIDIA 드라이버와 NVIDIA Container Toolkit이 설치되어 있는지 확인하십시오',
gpuConfigHelper: '서버에 NVIDIA 드라이버와 NVIDIA Container Toolkit이 설치되어 있는지 확인하십시오',
},
website: {
website: '웹사이트 | 웹사이트들',
@ -2521,6 +2520,7 @@ const message = {
proxyHelper4: '생성 , 웹사이트 목록에서 이를 보고 관리할 있습니다',
proxyHelper5:
'활성화한 , 스토어 - 설치됨 - Ollama - 매개변수에서 포트 외부 접근을 비활성화하여 보안을 강화할 있습니다.',
proxyHelper6: '프록시 구성을 비활성화하려면 웹사이트 목록에서 삭제할 있습니다.',
},
};

View file

@ -2004,8 +2004,7 @@ const message = {
pullImage: 'Tarik Imej',
pullImageHelper: 'Laksanakan docker pull untuk menarik imej sebelum aplikasi dimulakan.',
gpuConfig: 'Pecutan GPU',
gpuConfigHelper:
'Sila pastikan bahawa pelayan telah dipasang pemacu NVIDIA dan NVIDIA Container Toolkit',
gpuConfigHelper: 'Sila pastikan bahawa pelayan telah dipasang pemacu NVIDIA dan NVIDIA Container Toolkit',
},
website: {
website: 'Laman Web | Laman Web',
@ -2620,6 +2619,7 @@ const message = {
proxyHelper4: 'Setelah selesai, anda boleh melihat dan mengurusnya dalam senarai laman web',
proxyHelper5:
'Selepas diaktifkan, anda boleh melumpuhkan akses luaran ke port dalam App Store - Dipasang - Ollama - Parameter untuk meningkatkan keselamatan.',
proxyHelper6: 'Untuk melumpuhkan konfigurasi proksi, anda boleh memadamnya dari senarai laman web.',
},
};

View file

@ -2614,6 +2614,7 @@ const message = {
proxyHelper2: 'Limite o acesso por IP para evitar exposição na internet pública',
proxyHelper3: 'Habilite a transmissão em fluxo',
proxyHelper4: 'Após a criação, você pode visualizar e gerenciar no lista de sites',
proxyHelper6: 'Para desativar a configuração de proxy, você pode excluí-la da lista de sites.',
},
};

View file

@ -1997,8 +1997,7 @@ const message = {
pullImage: 'Загрузить образ',
pullImageHelper: 'Выполнить docker pull для загрузки образа перед запуском приложения',
gpuConfig: 'GPU Hızlandırma',
gpuConfigHelper:
'Пожалуйста, убедитесь, что на сервере установлены драйверы NVIDIA и NVIDIA Container Toolkit',
gpuConfigHelper: 'Пожалуйста, убедитесь, что на сервере установлены драйверы NVIDIA и NVIDIA Container Toolkit',
},
website: {
website: 'Веб-сайт | Веб-сайты',
@ -2613,6 +2612,7 @@ const message = {
proxyHelper4: 'После создания вы можете просматривать и управлять этим в списке сайтов',
proxyHelper5:
'После включения вы можете отключить внешний доступ к порту в Магазине приложений - Установленные - Ollama - Параметры для повышения безопасности.',
proxyHelper6: 'Чтобы отключить настройку прокси, вы можете удалить её из списка сайтов.',
},
};

View file

@ -2427,6 +2427,7 @@ const message = {
proxyHelper3: '啟用流式傳輸',
proxyHelper4: '創建後您可以在網站列表中查看並管理',
proxyHelper5: '啟用後您可以在應用商店 - 已安裝 - Ollama - 參數中取消端口外部訪問以提高安全性',
proxyHelper6: '如需關閉代理配置可以在網站列表中刪除',
},
};
export default {

View file

@ -2066,7 +2066,7 @@ const message = {
ipv6: '监听 IPV6',
leechReturnError: '请填写 HTTP 状态码',
selectAcme: '选择 acme 账号',
imported: '手动创建',
imported: '存量/自签证书',
importType: '导入方式',
pasteSSL: '粘贴代码',
localSSL: '选择服务器文件',
@ -2424,11 +2424,12 @@ const message = {
},
aitool: {
proxy: 'AI 代理增强',
proxyHelper1: '绑定域名并开启 HTTPS增强传输安全性',
proxyHelper1: '绑定域名并开启 HTTPS增强传输安全性',
proxyHelper2: '限制 IP 访问防止在公网暴露',
proxyHelper3: '开启流式传输',
proxyHelper4: '创建完成之后可以在网站列表中查看并管理',
proxyHelper5: '开启之后可以在应用商店 - 已安装 - ollama - 参数中取消端口外部访问以提高安全性',
proxyHelper5: '创建完成之后可以在应用商店 - 已安装 - ollama - 参数中取消端口外部访问以提高安全性',
proxyHelper6: '如需关闭代理配置可以在网站列表中删除',
},
};
export default {

View file

@ -25,7 +25,18 @@
<el-form-item :label="$t('website.domain')" prop="domain">
<el-input v-model.trim="req.domain" :disabled="operate === 'update'" />
<span class="input-help">
{{ $t('aitool.proxyHelper4') }}
{{ $t('aitool.proxyHelper4') + ' ' }}
<el-link
class="pageRoute"
icon="Position"
@click="toWebsite(req.websiteID)"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
<span class="input-help">
{{ $t('aitool.proxyHelper6') }}
</span>
</el-form-item>
<el-form-item :label="$t('firewall.address')" prop="ipList">
@ -52,6 +63,7 @@
:placeholder="$t('website.selectAcme')"
@change="listSSL"
>
<el-option :key="0" :label="$t('website.imported')" :value="0"></el-option>
<el-option
v-for="(acme, index) in acmeAccounts"
:key="index"
@ -190,8 +202,8 @@ const listAcmeAccount = () => {
acmeAccounts.value = res.data.items || [];
if (acmeAccounts.value.length > 0) {
req.value.acmeAccountID = acmeAccounts.value[0].id;
listSSL();
}
listSSL();
});
};
@ -230,7 +242,22 @@ const search = async (appInstallID: number) => {
} catch (e) {}
};
const toWebsite = (websiteID: number) => {
if (websiteID != undefined && websiteID > 0) {
window.location.href = `/websites/${websiteID}/config/basic`;
} else {
window.location.href = '/websites';
}
};
defineExpose({
acceptParams,
});
</script>
<style lang="scss" scoped>
.pageRoute {
font-size: 12px;
margin-left: 5px;
}
</style>

View file

@ -33,6 +33,9 @@
<el-button :disabled="modelInfo.status !== 'Running'" type="primary" @click="onCreate()">
{{ $t('ai_tools.model.create') }}
</el-button>
<el-button plain type="primary" :disabled="modelInfo.status !== 'Running'" @click="bindDomain">
{{ $t('aitool.proxy') }}
</el-button>
<el-button :disabled="modelInfo.status !== 'Running'" @click="onLoadConn" type="primary" plain>
{{ $t('database.databaseConnInfo') }}
</el-button>
@ -48,9 +51,7 @@
>
OpenWebUI
</el-button>
<el-button plain type="primary" :disabled="modelInfo.status !== 'Running'" @click="bindDomain">
{{ $t('aitool.proxy') }}
</el-button>
<el-button plain :disabled="selects.length === 0" type="primary" @click="onDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>

View file

@ -107,7 +107,10 @@
{{ $t('container.limitHelper', [limits.memory]) }} {{ paramModel.memoryUnit }}B
</span>
</el-form-item>
<el-form-item pro="gpuConfig" v-if="gpuSupport">
<el-checkbox v-model="paramModel.gpuConfig" :label="$t('app.gpuConfig')" size="large" />
<span class="input-help">{{ $t('app.gpuConfigHelper') }}</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="paramModel.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
@ -162,10 +165,12 @@ const extensions = [yaml(), oneDark];
interface ParamProps {
id: Number;
app: any;
gpuSupport?: boolean;
}
const paramData = ref<ParamProps>({
id: 0,
app: {},
gpuSupport: false,
});
interface EditForm extends App.InstallParams {
@ -190,6 +195,8 @@ const limits = ref<Container.ResourceLimit>({
cpu: null as number,
memory: null as number,
});
const gpuSupport = ref(false);
const em = defineEmits(['close']);
const changeUnit = () => {
if (paramModel.value.memoryUnit == 'M') {
@ -212,6 +219,7 @@ const acceptParams = async (props: ParamProps) => {
params.value = [];
paramData.value.id = props.id;
paramModel.value.params = {};
gpuSupport.value = props.gpuSupport;
edit.value = false;
await get();
open.value = true;
@ -219,6 +227,7 @@ const acceptParams = async (props: ParamProps) => {
const handleClose = () => {
open.value = false;
em('close', open);
};
const editParam = () => {
params.value.forEach((param: EditForm) => {
@ -265,6 +274,7 @@ const get = async () => {
paramModel.value.advanced = false;
paramModel.value.dockerCompose = res.data.dockerCompose;
paramModel.value.isHostMode = res.data.hostMode;
paramModel.value.gpuConfig = res.data.gpuConfig;
} catch (error) {
} finally {
loading.value = false;
@ -303,6 +313,7 @@ const submit = async (formEl: FormInstance) => {
submitModel.value.editCompose = paramModel.value.editCompose;
submitModel.value.dockerCompose = paramModel.value.dockerCompose;
}
submitModel.value.gpuConfig = paramModel.value.gpuConfig;
}
try {
loading.value = true;

View file

@ -302,7 +302,7 @@
<Uploads ref="uploadRef" />
<AppResources ref="checkRef" @close="search" />
<AppDelete ref="deleteRef" @close="search" />
<AppParams ref="appParamRef" />
<AppParams ref="appParamRef" @close="search" />
<AppUpgrade ref="upgradeRef" @close="search" />
<PortJumpDialog ref="dialogPortJumpRef" />
<AppIgnore ref="ignoreRef" @close="search" />
@ -605,7 +605,7 @@ const openUploads = (key: string, name: string) => {
};
const openParam = (row: any) => {
appParamRef.value.acceptParams({ id: row.id });
appParamRef.value.acceptParams({ id: row.id, gpuSupport: row.app.gpuSupport });
};
const isAppErr = (row: any) => {