From b72e7f0854c933b3ffdb12a2ce78ae77a45194e5 Mon Sep 17 00:00:00 2001 From: jakub961241 <144362244+jakub961241@users.noreply.github.com> Date: Sun, 22 Mar 2026 01:00:16 +0100 Subject: [PATCH] feat: add remark field to AI agent list (#12191) Add a remark/note field to AI agents so users can annotate what each agent is used for. This helps when managing many agents. Changes: - Model: add Remark field to Agent - DTO: add AgentRemarkUpdateReq, Remark to AgentItem - Service: add UpdateRemark method - API: POST /ai/agents/remark/update endpoint - Frontend: inline editable remark column in agent table - Migration: auto-migrate to add remark column - i18n: commons.table.remark key (en + zh) Closes #12191 --- agent/app/api/v2/agents.go | 20 ++++++++++++++++++++ agent/app/dto/agents.go | 6 ++++++ agent/app/model/agent.go | 1 + agent/app/service/agents.go | 10 ++++++++++ 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 | 6 ++++++ frontend/src/api/modules/ai.ts | 4 ++++ frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + frontend/src/views/ai/agents/agent/index.vue | 20 +++++++++++++++++++- 13 files changed, 78 insertions(+), 1 deletion(-) diff --git a/agent/app/api/v2/agents.go b/agent/app/api/v2/agents.go index 7eb90c6cf05f..97ab57e9c1ac 100644 --- a/agent/app/api/v2/agents.go +++ b/agent/app/api/v2/agents.go @@ -71,6 +71,26 @@ func (b *BaseApi) DeleteAgent(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/update [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.InternalServer(c, err) + return + } + helper.Success(c) +} + // @Tags AI // @Summary Reset Agent token // @Accept json diff --git a/agent/app/dto/agents.go b/agent/app/dto/agents.go index fcf358a485cf..d5aef2a5b568 100644 --- a/agent/app/dto/agents.go +++ b/agent/app/dto/agents.go @@ -50,6 +50,7 @@ type AgentItem struct { Path string `json:"path"` ConfigPath string `json:"configPath"` Upgradable bool `json:"upgradable"` + Remark string `json:"remark"` CreatedAt time.Time `json:"createdAt"` } @@ -63,6 +64,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..be1e19675734 100644 --- a/agent/app/model/agent.go +++ b/agent/app/model/agent.go @@ -17,4 +17,5 @@ type Agent struct { AppInstallID uint `json:"appInstallId"` AccountID uint `json:"accountId"` ConfigPath string `json:"configPath"` + Remark string `json:"remark"` } diff --git a/agent/app/service/agents.go b/agent/app/service/agents.go index 49db550635dc..b0d78c964d0c 100644 --- a/agent/app/service/agents.go +++ b/agent/app/service/agents.go @@ -26,6 +26,7 @@ type IAgentService interface { Delete(req dto.AgentDeleteReq) error ResetToken(req dto.AgentTokenResetReq) error UpdateModelConfig(req dto.AgentModelConfigUpdateReq) error + UpdateRemark(req dto.AgentRemarkUpdateReq) error GetProviders() ([]dto.ProviderInfo, error) GetSecurityConfig(req dto.AgentSecurityConfigReq) (*dto.AgentSecurityConfig, error) UpdateSecurityConfig(req dto.AgentSecurityConfigUpdateReq) error @@ -277,6 +278,15 @@ func (a AgentService) Delete(req dto.AgentDeleteReq) error { return nil } +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) ResetToken(req dto.AgentTokenResetReq) error { agent, err := agentRepo.GetFirst(repo.WithByID(req.ID)) if err != nil { diff --git a/agent/app/service/agents_utils.go b/agent/app/service/agents_utils.go index 080ad90f2fb0..78eaeae29906 100644 --- a/agent/app/service/agents_utils.go +++ b/agent/app/service/agents_utils.go @@ -336,6 +336,7 @@ func buildAgentItem(agent *model.Agent, appInstall *model.AppInstall, envMap map AppInstallID: agent.AppInstallID, AccountID: agent.AccountID, ConfigPath: agent.ConfigPath, + Remark: agent.Remark, CreatedAt: agent.CreatedAt, } if appInstall != nil && appInstall.ID > 0 { diff --git a/agent/init/migration/migrate.go b/agent/init/migration/migrate.go index 8616c6330ca2..e7d108e6e808 100644 --- a/agent/init/migration/migrate.go +++ b/agent/init/migration/migrate.go @@ -76,6 +76,7 @@ func InitAgentDB() { migrations.InitAgentAccountModelPool, migrations.AddHostTable, migrations.AddAITerminalSettings, + migrations.AddAgentRemark, }) 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 3fbddca436b2..dd7eb5a638c2 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -1133,3 +1133,10 @@ var AddAITerminalSettings = &gormigrate.Migration{ }).Error }, } + +var AddAgentRemark = &gormigrate.Migration{ + ID: "20260322-add-agent-remark", + 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 9a92f5534d4c..0b2e23af4e7d 100644 --- a/agent/router/ro_ai.go +++ b/agent/router/ro_ai.go @@ -45,6 +45,7 @@ func (a *AIToolsRouter) InitRouter(Router *gin.RouterGroup) { aiToolsRouter.POST("/agents/delete", baseApi.DeleteAgent) aiToolsRouter.POST("/agents/token/reset", baseApi.ResetAgentToken) aiToolsRouter.POST("/agents/model/update", baseApi.UpdateAgentModelConfig) + aiToolsRouter.POST("/agents/remark/update", baseApi.UpdateAgentRemark) aiToolsRouter.GET("/agents/providers", baseApi.GetAgentProviders) aiToolsRouter.POST("/agents/accounts", baseApi.CreateAgentAccount) aiToolsRouter.POST("/agents/accounts/update", baseApi.UpdateAgentAccount) diff --git a/frontend/src/api/interface/ai.ts b/frontend/src/api/interface/ai.ts index 74a50655ac6d..7ab17f38bd5c 100644 --- a/frontend/src/api/interface/ai.ts +++ b/frontend/src/api/interface/ai.ts @@ -284,9 +284,15 @@ export namespace AI { path: string; configPath: string; upgradable: boolean; + remark: string; createdAt: string; } + export interface AgentRemarkUpdateReq { + id: number; + remark: string; + } + export interface AgentDeleteReq { id: number; taskID: string; diff --git a/frontend/src/api/modules/ai.ts b/frontend/src/api/modules/ai.ts index 6641dd0317cf..ecf7b11b231a 100644 --- a/frontend/src/api/modules/ai.ts +++ b/frontend/src/api/modules/ai.ts @@ -113,6 +113,10 @@ export const updateAgentModelConfig = (req: AI.AgentModelConfigUpdateReq) => { return http.post(`/ai/agents/model/update`, req); }; +export const updateAgentRemark = (req: AI.AgentRemarkUpdateReq) => { + return http.post(`/ai/agents/remark/update`, req); +}; + export const getAgentProviders = () => { return http.get(`/ai/agents/providers`); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 1b235bb83d83..be79b2210e44 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -127,6 +127,7 @@ const message = { operate: 'Actions', message: 'Message', description: 'Description', + remark: 'Remark', interval: 'Interval', user: 'Owner', title: 'Title', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 1125086779d7..ed4a6b1e5cef 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -118,6 +118,7 @@ const message = { operate: '操作', message: '信息', description: '描述', + remark: '备注', interval: '耗时', user: '用户', title: '标题', diff --git a/frontend/src/views/ai/agents/agent/index.vue b/frontend/src/views/ai/agents/agent/index.vue index c2781f9dfb71..645ba5de928c 100644 --- a/frontend/src/views/ai/agents/agent/index.vue +++ b/frontend/src/views/ai/agents/agent/index.vue @@ -97,6 +97,16 @@ - + + + import { onMounted, reactive, ref } from 'vue'; import { useRoute, useRouter } from 'vue-router'; -import { pageAgents, resetAgentToken } from '@/api/modules/ai'; +import { pageAgents, resetAgentToken, updateAgentRemark } from '@/api/modules/ai'; import { installedOp, searchApp, searchAppInstalled } from '@/api/modules/app'; import { AI } from '@/api/interface/ai'; import { App } from '@/api/interface/app'; @@ -350,6 +360,14 @@ const onDelete = (row: AI.AgentItem) => { deleteRef.value?.acceptParams(row.id, row.name); }; +const onRemarkChange = async (row: AI.AgentItem) => { + try { + await updateAgentRemark({ id: row.id, remark: row.remark }); + } catch (e) { + /* silent */ + } +}; + const onResetToken = async (row: AI.AgentItem) => { await ElMessageBox.confirm( i18n.global.t('aiTools.mcp.operatorHelper', ['token', i18n.global.t('commons.button.reset')]),