From e81040a39cdff3317e72fe160f5cfefcfff8c721 Mon Sep 17 00:00:00 2001
From: zhengkunwang223 <1paneldev@sina.com>
Date: Mon, 30 Mar 2026 11:12:39 +0800
Subject: [PATCH] feat: support remark for openclaw
---
agent/app/api/v2/agents.go | 20 +++++++++++++++++++
agent/app/dto/agents.go | 7 +++++++
agent/app/model/agent.go | 1 +
agent/app/service/agents.go | 11 ++++++++++
agent/app/service/agents_utils.go | 1 +
agent/init/migration/migrate.go | 1 +
agent/init/migration/migrations/init.go | 7 +++++++
agent/router/ro_ai.go | 1 +
frontend/src/api/interface/ai.ts | 7 +++++++
frontend/src/api/modules/ai.ts | 4 ++++
.../src/views/ai/agents/agent/add/index.vue | 6 ++++++
frontend/src/views/ai/agents/agent/index.vue | 20 ++++++++++++++++++-
12 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/agent/app/api/v2/agents.go b/agent/app/api/v2/agents.go
index a06e849223af..fc2cc117c786 100644
--- a/agent/app/api/v2/agents.go
+++ b/agent/app/api/v2/agents.go
@@ -91,6 +91,26 @@ func (b *BaseApi) ResetAgentToken(c *gin.Context) {
helper.Success(c)
}
+// @Tags AI
+// @Summary Update Agent remark
+// @Accept json
+// @Param request body dto.AgentRemarkUpdateReq true "request"
+// @Success 200
+// @Security ApiKeyAuth
+// @Security Timestamp
+// @Router /ai/agents/remark [post]
+func (b *BaseApi) UpdateAgentRemark(c *gin.Context) {
+ var req dto.AgentRemarkUpdateReq
+ if err := helper.CheckBindAndValidate(&req, c); err != nil {
+ return
+ }
+ if err := agentService.UpdateRemark(req); err != nil {
+ helper.BadRequest(c, err)
+ return
+ }
+ helper.Success(c)
+}
+
// @Tags AI
// @Summary Update Agent model config
// @Accept json
diff --git a/agent/app/dto/agents.go b/agent/app/dto/agents.go
index 4a6b3bb4835f..e23522723275 100644
--- a/agent/app/dto/agents.go
+++ b/agent/app/dto/agents.go
@@ -4,6 +4,7 @@ import "time"
type AgentCreateReq struct {
Name string `json:"name" validate:"required"`
+ Remark string `json:"remark"`
AppVersion string `json:"appVersion" validate:"required"`
WebUIPort int `json:"webUIPort" validate:"required"`
BridgePort int `json:"bridgePort"`
@@ -29,6 +30,7 @@ type AgentCreateReq struct {
type AgentItem struct {
ID uint `json:"id"`
Name string `json:"name"`
+ Remark string `json:"remark"`
AgentType string `json:"agentType"`
Provider string `json:"provider"`
ProviderName string `json:"providerName"`
@@ -63,6 +65,11 @@ type AgentTokenResetReq struct {
ID uint `json:"id" validate:"required"`
}
+type AgentRemarkUpdateReq struct {
+ ID uint `json:"id" validate:"required"`
+ Remark string `json:"remark"`
+}
+
type AgentModelConfigUpdateReq struct {
AgentID uint `json:"agentId" validate:"required"`
AccountID uint `json:"accountId" validate:"required"`
diff --git a/agent/app/model/agent.go b/agent/app/model/agent.go
index fa382e7084d9..f0aa923c1a40 100644
--- a/agent/app/model/agent.go
+++ b/agent/app/model/agent.go
@@ -3,6 +3,7 @@ package model
type Agent struct {
BaseModel
Name string `json:"name" gorm:"not null;unique"`
+ Remark string `json:"remark"`
AgentType string `json:"agentType" gorm:"default:openclaw"`
Provider string `json:"provider"`
Model string `json:"model"`
diff --git a/agent/app/service/agents.go b/agent/app/service/agents.go
index 2aa2273258f1..3164ee550d4c 100644
--- a/agent/app/service/agents.go
+++ b/agent/app/service/agents.go
@@ -29,6 +29,7 @@ type IAgentService interface {
Page(req dto.SearchWithPage) (int64, []dto.AgentItem, error)
Delete(req dto.AgentDeleteReq) error
ResetToken(req dto.AgentTokenResetReq) error
+ UpdateRemark(req dto.AgentRemarkUpdateReq) error
UpdateModelConfig(req dto.AgentModelConfigUpdateReq) error
GetOverview(req dto.AgentOverviewReq) (*dto.AgentOverview, error)
GetProviders() ([]dto.ProviderInfo, error)
@@ -234,6 +235,7 @@ func (a AgentService) Create(req dto.AgentCreateReq) (*dto.AgentItem, error) {
}
agent := &model.Agent{
Name: req.Name,
+ Remark: req.Remark,
AgentType: agentType,
Provider: provider,
Model: storedModel,
@@ -323,6 +325,15 @@ func (a AgentService) ResetToken(req dto.AgentTokenResetReq) error {
return agentRepo.Save(agent)
}
+func (a AgentService) UpdateRemark(req dto.AgentRemarkUpdateReq) error {
+ agent, err := agentRepo.GetFirst(repo.WithByID(req.ID))
+ if err != nil {
+ return err
+ }
+ agent.Remark = req.Remark
+ return agentRepo.Save(agent)
+}
+
func (a AgentService) UpdateModelConfig(req dto.AgentModelConfigUpdateReq) error {
agent, err := loadOpenclawAgentByID(req.AgentID)
if err != nil {
diff --git a/agent/app/service/agents_utils.go b/agent/app/service/agents_utils.go
index 7d5c2f5635ce..6a13fa82400e 100644
--- a/agent/app/service/agents_utils.go
+++ b/agent/app/service/agents_utils.go
@@ -340,6 +340,7 @@ func buildAgentItem(agent *model.Agent, appInstall *model.AppInstall, envMap map
item := dto.AgentItem{
ID: agent.ID,
Name: agent.Name,
+ Remark: agent.Remark,
AgentType: agentType,
Provider: agent.Provider,
ProviderName: providercatalog.DisplayName(agent.Provider),
diff --git a/agent/init/migration/migrate.go b/agent/init/migration/migrate.go
index 5dc97f3f4145..920f58a9ca0b 100644
--- a/agent/init/migration/migrate.go
+++ b/agent/init/migration/migrate.go
@@ -77,6 +77,7 @@ func InitAgentDB() {
migrations.AddAITerminalSettings,
migrations.UpdateAgentQuickJumpTitle,
migrations.FixOpenclaw20260323HTTPPort,
+ migrations.AddAgentRemarkColumn,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
diff --git a/agent/init/migration/migrations/init.go b/agent/init/migration/migrations/init.go
index 0cbfed26faba..4ee55a676540 100644
--- a/agent/init/migration/migrations/init.go
+++ b/agent/init/migration/migrations/init.go
@@ -1151,3 +1151,10 @@ WHERE version = ?
).Error
},
}
+
+var AddAgentRemarkColumn = &gormigrate.Migration{
+ ID: "20260330-add-agent-remark-column",
+ Migrate: func(tx *gorm.DB) error {
+ return tx.AutoMigrate(&model.Agent{})
+ },
+}
diff --git a/agent/router/ro_ai.go b/agent/router/ro_ai.go
index 5aade3056e3a..0230b51fc599 100644
--- a/agent/router/ro_ai.go
+++ b/agent/router/ro_ai.go
@@ -44,6 +44,7 @@ func (a *AIToolsRouter) InitRouter(Router *gin.RouterGroup) {
aiToolsRouter.POST("/agents/search", baseApi.PageAgents)
aiToolsRouter.POST("/agents/delete", baseApi.DeleteAgent)
aiToolsRouter.POST("/agents/token/reset", baseApi.ResetAgentToken)
+ aiToolsRouter.POST("/agents/remark", baseApi.UpdateAgentRemark)
aiToolsRouter.POST("/agents/model/update", baseApi.UpdateAgentModelConfig)
aiToolsRouter.POST("/agents/overview", baseApi.GetAgentOverview)
aiToolsRouter.GET("/agents/providers", baseApi.GetAgentProviders)
diff --git a/frontend/src/api/interface/ai.ts b/frontend/src/api/interface/ai.ts
index aafaf4bc8028..70ec1459233b 100644
--- a/frontend/src/api/interface/ai.ts
+++ b/frontend/src/api/interface/ai.ts
@@ -238,6 +238,7 @@ export namespace AI {
export interface AgentCreateReq {
name: string;
+ remark: string;
appVersion: string;
webUIPort: number;
bridgePort?: number;
@@ -263,6 +264,7 @@ export namespace AI {
export interface AgentItem {
id: number;
name: string;
+ remark: string;
agentType: 'openclaw' | 'copaw';
provider: string;
providerName: string;
@@ -297,6 +299,11 @@ export namespace AI {
id: number;
}
+ export interface AgentRemarkUpdateReq {
+ id: number;
+ remark: string;
+ }
+
export interface AgentModelConfigUpdateReq {
agentId: number;
accountId: number;
diff --git a/frontend/src/api/modules/ai.ts b/frontend/src/api/modules/ai.ts
index 5c8c37125eb8..fdd6d50daf40 100644
--- a/frontend/src/api/modules/ai.ts
+++ b/frontend/src/api/modules/ai.ts
@@ -109,6 +109,10 @@ export const resetAgentToken = (req: AI.AgentTokenResetReq) => {
return http.post(`/ai/agents/token/reset`, req);
};
+export const updateAgentRemark = (req: AI.AgentRemarkUpdateReq) => {
+ return http.post(`/ai/agents/remark`, req);
+};
+
export const updateAgentModelConfig = (req: AI.AgentModelConfigUpdateReq) => {
return http.post(`/ai/agents/model/update`, req);
};
diff --git a/frontend/src/views/ai/agents/agent/add/index.vue b/frontend/src/views/ai/agents/agent/add/index.vue
index cb86fef34661..3cf09d6e19be 100644
--- a/frontend/src/views/ai/agents/agent/add/index.vue
+++ b/frontend/src/views/ai/agents/agent/add/index.vue
@@ -5,6 +5,9 @@
+
+
+
@@ -136,6 +139,7 @@ const { isIntl } = useGlobalStore();
const form = reactive({
name: '',
+ remark: '',
agentType: 'openclaw' as 'openclaw' | 'copaw',
appVersion: '',
webUIPort: 18789,
@@ -382,6 +386,7 @@ const submit = async () => {
try {
const res = await createAgent({
name: form.name,
+ remark: form.remark,
appVersion: form.appVersion,
webUIPort: form.webUIPort,
allowedOrigins: form.agentType === 'openclaw' ? parseAllowedOriginsInput(form.allowedOrigins) : undefined,
@@ -419,6 +424,7 @@ const submit = async () => {
const handleClose = () => {
formRef.value?.resetFields();
form.token = '';
+ form.remark = '';
form.allowedOrigins = '';
form.dockerCompose = '';
lastAutoAllowedOrigins.value = '';
diff --git a/frontend/src/views/ai/agents/agent/index.vue b/frontend/src/views/ai/agents/agent/index.vue
index 0ebceb5bdfdb..ea93bfcb0818 100644
--- a/frontend/src/views/ai/agents/agent/index.vue
+++ b/frontend/src/views/ai/agents/agent/index.vue
@@ -101,6 +101,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -153,7 +165,7 @@