Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions agent/app/api/v2/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ func (b *BaseApi) BindAgentWebsite(c *gin.Context) {
helper.Success(c)
}

// @Tags AI
// @Summary Unbind Agent website
// @Accept json
// @Param request body dto.AgentIDReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /ai/agents/website/unbind [post]
func (b *BaseApi) UnbindAgentWebsite(c *gin.Context) {
var req dto.AgentIDReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := agentService.UnbindWebsite(req); err != nil {
helper.BadRequest(c, err)
return
}
helper.Success(c)
}

// @Tags AI
// @Summary Get Agent model config
// @Accept json
Expand Down
1 change: 1 addition & 0 deletions agent/app/dto/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type AgentItem struct {
AppInstallID uint `json:"appInstallId"`
WebsiteID uint `json:"websiteId"`
WebsitePrimaryDomain string `json:"websitePrimaryDomain"`
WebsiteType string `json:"websiteType"`
WebsiteProtocol string `json:"websiteProtocol"`
AccountID uint `json:"accountId"`
AppVersion string `json:"appVersion"`
Expand Down
1 change: 1 addition & 0 deletions agent/app/service/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type IAgentService interface {
ResetToken(req dto.AgentTokenResetReq) error
UpdateRemark(req dto.AgentRemarkUpdateReq) error
BindWebsite(req dto.AgentWebsiteBindReq) error
UnbindWebsite(req dto.AgentIDReq) error
GetModelConfig(req dto.AgentIDReq) (*dto.AgentModelConfig, error)
UpdateModelConfig(req dto.AgentModelConfigUpdateReq) error
GetHermesChatSessions(req dto.AgentIDReq) ([]dto.AgentHermesChatSessionItem, error)
Expand Down
23 changes: 23 additions & 0 deletions agent/app/service/agents_website.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ func (a AgentService) BindWebsite(req dto.AgentWebsiteBindReq) error {
return ensureOpenclawWebsiteAllowedOrigin(agent, &website)
}

func (a AgentService) UnbindWebsite(req dto.AgentIDReq) error {
agent, err := agentRepo.GetFirst(repo.WithByID(req.AgentID))
if err != nil {
return err
}
if agent.WebsiteID == 0 {
return nil
}

website, err := websiteRepo.GetFirst(repo.WithByID(agent.WebsiteID))
if err != nil {
return err
}
if website.Type == constant.Deployment {
return buserr.New("ErrAgentWebsiteUnbindUnsupported")
}

agent.WebsiteID = 0
return agentRepo.Save(agent)
Comment thread
zhengkunwang223 marked this conversation as resolved.
}

func hydrateAgentWebsiteItems(items []dto.AgentItem) error {
explicitWebsiteMap, err := loadAgentWebsiteMapByID(items)
if err != nil {
Expand Down Expand Up @@ -126,9 +147,11 @@ func fillAgentWebsiteItems(items []dto.AgentItem, explicitWebsiteMap map[uint]mo
if !ok {
items[index].WebsiteID = 0
items[index].WebsitePrimaryDomain = ""
items[index].WebsiteType = ""
items[index].WebsiteProtocol = ""
continue
}
items[index].WebsiteType = website.Type
items[index].WebsiteProtocol = website.Protocol
websiteDomains := websiteDomainMap[items[index].WebsiteID]
if len(websiteDomains) == 0 {
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ErrAgentLimitReached: 'Community Edition supports up to {{ .max }} AI agents. Up
ErrAgentWebsiteBound: 'This agent is already bound to a website'
ErrAgentWebsiteTypeUnsupported: 'Only proxy or static websites can be bound'
ErrAgentWebsiteInUse: 'This website is already bound to another agent'
ErrAgentWebsiteUnbindUnsupported: 'Deployment websites cannot be unbound manually'

#backup
Localhost: 'Local'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/es-ES.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'La edición Community admite hasta {{ .max }} agentes de
ErrAgentWebsiteBound: 'Este agente ya está vinculado a un sitio web'
ErrAgentWebsiteTypeUnsupported: 'Solo se pueden vincular sitios proxy o estáticos'
ErrAgentWebsiteInUse: 'Este sitio web ya está vinculado a otro agente'
ErrAgentWebsiteUnbindUnsupported: 'Los sitios web de despliegue no se pueden desvincular manualmente'
Localhost: 'Máquina local'
ErrBackupInUsed: 'Cuenta de respaldo en uso por tarea programada'
ErrBackupCheck: 'Conexión de respaldo falló: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/ja.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'Community Edition では AI エージェントを最大 {
ErrAgentWebsiteBound: 'このエージェントはすでにサイトに関連付けられています'
ErrAgentWebsiteTypeUnsupported: '関連付けできるのはプロキシサイトまたは静的サイトのみです'
ErrAgentWebsiteInUse: 'このサイトはすでに別のエージェントに関連付けられています'
ErrAgentWebsiteUnbindUnsupported: 'ワンクリックデプロイのサイトは手動で関連解除できません'
Localhost: 'ローカルマシン'
ErrBackupInUsed: 'バックアップアカウントがスケジュールで使用中'
ErrBackupCheck: '接続テストに失敗しました: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/ko.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: '커뮤니티 에디션에서는 AI 에이전트를 최대
ErrAgentWebsiteBound: '이 에이전트는 이미 웹사이트에 연결되어 있습니다'
ErrAgentWebsiteTypeUnsupported: '프록시 또는 정적 웹사이트만 연결할 수 있습니다'
ErrAgentWebsiteInUse: '이 웹사이트는 이미 다른 에이전트에 연결되어 있습니다'
ErrAgentWebsiteUnbindUnsupported: '원클릭 배포 웹사이트는 수동으로 연결 해제할 수 없습니다'
Localhost: '로컬 머신'
ErrBackupInUsed: '백업 계정이 예약에 사용 중'
ErrBackupCheck: '연결 테스트 실패: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/ms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'Edisi Community menyokong sehingga {{ .max }} ejen AI. Na
ErrAgentWebsiteBound: 'Ejen ini sudah dipautkan ke laman web'
ErrAgentWebsiteTypeUnsupported: 'Hanya laman web proxy atau statik boleh dipautkan'
ErrAgentWebsiteInUse: 'Laman web ini sudah dipautkan ke ejen lain'
ErrAgentWebsiteUnbindUnsupported: 'Laman web one-click deployment tidak menyokong nyahikat manual'
Localhost: 'Mesin Tempatan'
ErrBackupInUsed: 'Akaun sandaran sedang digunakan oleh tugas'
ErrBackupCheck: 'Ujian sambungan gagal: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/pt-BR.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'A edição Community suporta até {{ .max }} agentes de I
ErrAgentWebsiteBound: 'Este agente já está vinculado a um site'
ErrAgentWebsiteTypeUnsupported: 'Somente sites proxy ou estáticos podem ser vinculados'
ErrAgentWebsiteInUse: 'Este site já está vinculado a outro agente'
ErrAgentWebsiteUnbindUnsupported: 'Sites implantados em um clique não podem ser desvinculados manualmente'
Localhost: 'Máquina Local'
ErrBackupInUsed: 'Conta de backup em uso por tarefa'
ErrBackupCheck: 'Teste de conexão falhou: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/ru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'Community Edition поддерживает до {{ .max }
ErrAgentWebsiteBound: 'Этот агент уже связан с сайтом'
ErrAgentWebsiteTypeUnsupported: 'Можно связывать только proxy- или static-сайты'
ErrAgentWebsiteInUse: 'Этот сайт уже связан с другим агентом'
ErrAgentWebsiteUnbindUnsupported: 'Сайты one-click deployment нельзя отвязать вручную'
Localhost: 'Локальная машина'
ErrBackupInUsed: 'Аккаунт бэкапа занят задачей'
ErrBackupCheck: 'Проверка подключения не удалась: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/tr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: 'Community sürümü en fazla {{ .max }} AI ajanını dest
ErrAgentWebsiteBound: 'Bu ajan zaten bir web sitesine bağlı'
ErrAgentWebsiteTypeUnsupported: 'Yalnızca proxy veya statik web siteleri bağlanabilir'
ErrAgentWebsiteInUse: 'Bu web sitesi zaten başka bir ajana bağlı'
ErrAgentWebsiteUnbindUnsupported: 'Tek tıkla dağıtılan web sitelerinin bağlantısı manuel olarak kaldırılamaz'
Localhost: 'Yerel Makine'
ErrBackupInUsed: 'Yedek hesabı görevde kullanılıyor'
ErrBackupCheck: 'Bağlantı testi başarısız: {{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/zh-Hant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ErrAgentLimitReached: '社群版最多支援建立 {{ .max }} 個 AI 智能體
ErrAgentWebsiteBound: '該智能體已關聯網站'
ErrAgentWebsiteTypeUnsupported: '只能關聯反向代理或靜態網站'
ErrAgentWebsiteInUse: '該網站已被其他智能體關聯'
ErrAgentWebsiteUnbindUnsupported: '一鍵部署網站不支援手動解綁'
Localhost: '本機'
ErrBackupInUsed: '此備份帳號已在排程任務中使用,無法刪除'
ErrBackupCheck: '備份帳號測試連線失敗{{ .err }}'
Expand Down
1 change: 1 addition & 0 deletions agent/i18n/lang/zh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ErrAgentLimitReached: "社区版最多支持创建 {{ .max }} 个智能体,升
ErrAgentWebsiteBound: "该智能体已关联网站"
ErrAgentWebsiteTypeUnsupported: "只能关联反向代理或静态网站"
ErrAgentWebsiteInUse: "该网站已被其他智能体关联"
ErrAgentWebsiteUnbindUnsupported: "一键部署网站不支持手动解绑"

#backup
Localhost: '本机'
Expand Down
1 change: 1 addition & 0 deletions agent/router/ro_ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (a *AIToolsRouter) InitRouter(Router *gin.RouterGroup) {
aiToolsRouter.POST("/agents/token/reset", baseApi.ResetAgentToken)
aiToolsRouter.POST("/agents/remark", baseApi.UpdateAgentRemark)
aiToolsRouter.POST("/agents/website/bind", baseApi.BindAgentWebsite)
aiToolsRouter.POST("/agents/website/unbind", baseApi.UnbindAgentWebsite)
aiToolsRouter.POST("/agents/model/get", baseApi.GetAgentModelConfig)
aiToolsRouter.POST("/agents/model/update", baseApi.UpdateAgentModelConfig)
aiToolsRouter.POST("/agents/hermes/chat/sessions", baseApi.GetHermesChatSessions)
Expand Down
1 change: 1 addition & 0 deletions frontend/src/api/interface/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ export namespace AI {
appInstallId: number;
websiteId: number;
websitePrimaryDomain: string;
websiteType: string;
websiteProtocol: string;
accountId: number;
appVersion: string;
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/api/modules/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ export const bindAgentWebsite = (req: AI.AgentWebsiteBindReq) => {
return http.post(`/ai/agents/website/bind`, req);
};

export const unbindAgentWebsite = (req: AI.AgentIDReq) => {
return http.post(`/ai/agents/website/unbind`, req);
};

export const getAgentModelConfig = (req: AI.AgentIDReq) => {
return http.post<AI.AgentModelConfig>(`/ai/agents/model/get`, req);
};
Expand Down
32 changes: 31 additions & 1 deletion frontend/src/views/ai/agents/agent/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@
</table>
<el-empty v-else :image-size="48" :description="$t('commons.msg.noneData')" />
</el-popover>
<el-button
v-if="canUnbindWebsite(row)"
link
type="primary"
@click="onUnbindWebsite(row)"
>
{{ $t('commons.button.unbind') }}
</el-button>
</div>
<el-button v-else link type="primary" @click="openBindWebsite(row)">
{{ $t('commons.button.bind') }}
Expand Down Expand Up @@ -204,7 +212,7 @@
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { deleteAgentCheck, pageAgents, resetAgentToken, updateAgentRemark } from '@/api/modules/ai';
import { deleteAgentCheck, pageAgents, resetAgentToken, unbindAgentWebsite, updateAgentRemark } from '@/api/modules/ai';
import { checkAppInstalled, installedOp, searchApp, searchAppInstalled } from '@/api/modules/app';
import { AI } from '@/api/interface/ai';
import { App } from '@/api/interface/app';
Expand Down Expand Up @@ -573,6 +581,28 @@ const openBindWebsite = (row: AI.AgentItem) => {
bindWebsiteRef.value?.acceptParams(row);
};

const canUnbindWebsite = (row: AI.AgentItem) => {
return row.websiteType === 'proxy' || row.websiteType === 'static';
};

const onUnbindWebsite = async (row: AI.AgentItem) => {
await ElMessageBox.confirm(
i18n.global.t('aiTools.mcp.operatorHelper', [
i18n.global.t('menu.website'),
i18n.global.t('commons.button.unbind'),
]),
i18n.global.t('commons.button.unbind'),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
);
await unbindAgentWebsite({ agentId: row.id });
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
await search();
};

const loadOpenrestyHttpsPort = async () => {
if (openrestyPortLoaded.value) {
return;
Expand Down
60 changes: 47 additions & 13 deletions frontend/src/views/setting/alert/index.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
<template>
<div>
<el-card class="router_card p-2 sm:p-3 mt-2">
<div class="flex w-full justify-start items-center">
<el-button type="primary" :plain="index !== '0'" @click="changeTab('0')">
{{ $t('xpack.alert.list') }}
</el-button>
<el-button type="primary" :plain="index !== '1'" @click="changeTab('1')">
{{ $t('xpack.alert.logs') }}
</el-button>
<el-button type="primary" :plain="index !== '2'" @click="changeTab('2')">
{{ $t('commons.button.set') }}
</el-button>
</div>
</el-card>
<div class="content-container__search">
<el-card>
<div>
<el-button
class="tag-button"
:class="index === '0' ? '' : 'no-active'"
:type="index === '0' ? 'primary' : ''"
@click="changeTab('0')"
>
{{ $t('xpack.alert.list') }}
</el-button>
<el-button
class="tag-button"
:class="index === '1' ? '' : 'no-active'"
:type="index === '1' ? 'primary' : ''"
@click="changeTab('1')"
>
{{ $t('xpack.alert.logs') }}
</el-button>
<el-button
class="tag-button"
:class="index === '2' ? '' : 'no-active'"
:type="index === '2' ? 'primary' : ''"
@click="changeTab('2')"
>
{{ $t('commons.button.set') }}
</el-button>
</div>
</el-card>
</div>
<AlertDash v-if="index == '0'" />
<AlertLogs v-if="index == '1'" />
<AlertSetting v-if="index == '2'" />
Expand All @@ -37,3 +54,20 @@ onMounted(async () => {
}
});
</script>

<style scoped lang="scss">
.content-container__search {
margin-top: 7px;

:deep(.el-card) {
--el-card-padding: 12px;
}
}

.tag-button {
&.no-active {
background: none;
border: none;
}
}
</style>
Loading