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 @@ -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
Expand Down
7 changes: 7 additions & 0 deletions agent/app/dto/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -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"`
Expand Down Expand Up @@ -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"`
Expand Down
1 change: 1 addition & 0 deletions agent/app/model/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
11 changes: 11 additions & 0 deletions agent/app/service/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions agent/app/service/agents_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions agent/init/migration/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func InitAgentDB() {
migrations.AddAITerminalSettings,
migrations.UpdateAgentQuickJumpTitle,
migrations.FixOpenclaw20260323HTTPPort,
migrations.AddAgentRemarkColumn,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
Expand Down
7 changes: 7 additions & 0 deletions agent/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
},
}
1 change: 1 addition & 0 deletions agent/router/ro_ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/api/interface/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ export namespace AI {

export interface AgentCreateReq {
name: string;
remark: string;
appVersion: string;
webUIPort: number;
bridgePort?: number;
Expand All @@ -263,6 +264,7 @@ export namespace AI {
export interface AgentItem {
id: number;
name: string;
remark: string;
agentType: 'openclaw' | 'copaw';
provider: string;
providerName: string;
Expand Down Expand Up @@ -297,6 +299,11 @@ export namespace AI {
id: number;
}

export interface AgentRemarkUpdateReq {
id: number;
remark: string;
}

export interface AgentModelConfigUpdateReq {
agentId: number;
accountId: number;
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 @@ -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);
};
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/views/ai/agents/agent/add/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item :label="$t('website.remark')" prop="remark">
<el-input v-model="form.remark" />
</el-form-item>
<el-form-item :label="`${$t('aiTools.agents.agent')}${$t('commons.table.type')}`" prop="agentType">
<el-select v-model="form.agentType" @change="handleAgentTypeChange">
<el-option :label="$t('aiTools.agents.openclawType')" value="openclaw" />
Expand Down Expand Up @@ -136,6 +139,7 @@ const { isIntl } = useGlobalStore();

const form = reactive({
name: '',
remark: '',
agentType: 'openclaw' as 'openclaw' | 'copaw',
appVersion: '',
webUIPort: 18789,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -419,6 +424,7 @@ const submit = async () => {
const handleClose = () => {
formRef.value?.resetFields();
form.token = '';
form.remark = '';
form.allowedOrigins = '';
form.dockerCompose = '';
lastAutoAllowedOrigins.value = '';
Expand Down
20 changes: 19 additions & 1 deletion frontend/src/views/ai/agents/agent/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark" min-width="150">
<template #default="{ row }">
<fu-read-write-switch>
<template #read>
<MsgInfo :info="row.remark" :width="'150'" />
</template>
<template #default="{ read }">
<el-input v-model="row.remark" @blur="handleUpdateRemark(row, read)" />
</template>
</fu-read-write-switch>
</template>
</el-table-column>
<el-table-column :label="$t('runtime.workDir')" min-width="90">
<template #default="{ row }">
<el-button type="primary" link @click="openWorkDir(row)">
Expand Down Expand Up @@ -153,7 +165,7 @@
<script setup lang="ts">
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';
Expand Down Expand Up @@ -397,6 +409,12 @@ const onResetToken = async (row: AI.AgentItem) => {
await search();
};

const handleUpdateRemark = async (row: AI.AgentItem, read: Function) => {
read();
await updateAgentRemark({ id: row.id, remark: row.remark });
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
};

const openConfig = (row: AI.AgentItem) => {
configRef.value?.open(row);
};
Expand Down
Loading